OSDN Git Service

(init_optabs): Delete all uses of undocumented TImode and
[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) != VOIDmode
1516           && GET_MODE (op0) != mode)
1517         op0 = convert_to_mode (mode, op0, unsignedp);
1518
1519       /* Pass 1 for NO_QUEUE so we don't lose any increments
1520          if the libcall is cse'd or moved.  */
1521       value = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
1522                                        NULL_RTX, 1, mode, 2,
1523                                        op0, mode, op1x, op1_mode);
1524
1525       insns = get_insns ();
1526       end_sequence ();
1527
1528       target = gen_reg_rtx (mode);
1529       emit_libcall_block (insns, target, value,
1530                           gen_rtx (binoptab->code, mode, op0, op1));
1531
1532       return target;
1533     }
1534
1535   delete_insns_since (last);
1536
1537   /* It can't be done in this mode.  Can we do it in a wider mode?  */
1538
1539   if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1540          || methods == OPTAB_MUST_WIDEN))
1541     {
1542       /* Caller says, don't even try.  */
1543       delete_insns_since (entry_last);
1544       return 0;
1545     }
1546
1547   /* Compute the value of METHODS to pass to recursive calls.
1548      Don't allow widening to be tried recursively.  */
1549
1550   methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1551
1552   /* Look for a wider mode of the same class for which it appears we can do
1553      the operation.  */
1554
1555   if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1556     {
1557       for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1558            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1559         {
1560           if ((binoptab->handlers[(int) wider_mode].insn_code
1561                != CODE_FOR_nothing)
1562               || (methods == OPTAB_LIB
1563                   && binoptab->handlers[(int) wider_mode].libfunc))
1564             {
1565               rtx xop0 = op0, xop1 = op1;
1566               int no_extend = 0;
1567
1568               /* For certain integer operations, we need not actually extend
1569                  the narrow operands, as long as we will truncate
1570                  the results to the same narrowness.  */
1571
1572               if ((binoptab == ior_optab || binoptab == and_optab
1573                    || binoptab == xor_optab
1574                    || binoptab == add_optab || binoptab == sub_optab
1575                    || binoptab == smul_optab || binoptab == ashl_optab)
1576                   && class == MODE_INT)
1577                 no_extend = 1;
1578
1579               xop0 = widen_operand (xop0, wider_mode, mode,
1580                                     unsignedp, no_extend);
1581
1582               /* The second operand of a shift must always be extended.  */
1583               xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1584                                     no_extend && binoptab != ashl_optab);
1585
1586               temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1587                                    unsignedp, methods);
1588               if (temp)
1589                 {
1590                   if (class != MODE_INT)
1591                     {
1592                       if (target == 0)
1593                         target = gen_reg_rtx (mode);
1594                       convert_move (target, temp, 0);
1595                       return target;
1596                     }
1597                   else
1598                     return gen_lowpart (mode, temp);
1599                 }
1600               else
1601                 delete_insns_since (last);
1602             }
1603         }
1604     }
1605
1606   delete_insns_since (entry_last);
1607   return 0;
1608 }
1609 \f
1610 /* Expand a binary operator which has both signed and unsigned forms.
1611    UOPTAB is the optab for unsigned operations, and SOPTAB is for
1612    signed operations.
1613
1614    If we widen unsigned operands, we may use a signed wider operation instead
1615    of an unsigned wider operation, since the result would be the same.  */
1616
1617 rtx
1618 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
1619     enum machine_mode mode;
1620     optab uoptab, soptab;
1621     rtx op0, op1, target;
1622     int unsignedp;
1623     enum optab_methods methods;
1624 {
1625   register rtx temp;
1626   optab direct_optab = unsignedp ? uoptab : soptab;
1627   struct optab wide_soptab;
1628
1629   /* Do it without widening, if possible.  */
1630   temp = expand_binop (mode, direct_optab, op0, op1, target,
1631                        unsignedp, OPTAB_DIRECT);
1632   if (temp || methods == OPTAB_DIRECT)
1633     return temp;
1634
1635   /* Try widening to a signed int.  Make a fake signed optab that
1636      hides any signed insn for direct use.  */
1637   wide_soptab = *soptab;
1638   wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
1639   wide_soptab.handlers[(int) mode].libfunc = 0;
1640
1641   temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1642                        unsignedp, OPTAB_WIDEN);
1643
1644   /* For unsigned operands, try widening to an unsigned int.  */
1645   if (temp == 0 && unsignedp)
1646     temp = expand_binop (mode, uoptab, op0, op1, target,
1647                          unsignedp, OPTAB_WIDEN);
1648   if (temp || methods == OPTAB_WIDEN)
1649     return temp;
1650
1651   /* Use the right width lib call if that exists.  */
1652   temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
1653   if (temp || methods == OPTAB_LIB)
1654     return temp;
1655
1656   /* Must widen and use a lib call, use either signed or unsigned.  */
1657   temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1658                        unsignedp, methods);
1659   if (temp != 0)
1660     return temp;
1661   if (unsignedp)
1662     return expand_binop (mode, uoptab, op0, op1, target,
1663                          unsignedp, methods);
1664   return 0;
1665 }
1666 \f
1667 /* Generate code to perform an operation specified by BINOPTAB
1668    on operands OP0 and OP1, with two results to TARG1 and TARG2.
1669    We assume that the order of the operands for the instruction
1670    is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1671    [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1672
1673    Either TARG0 or TARG1 may be zero, but what that means is that
1674    that result is not actually wanted.  We will generate it into
1675    a dummy pseudo-reg and discard it.  They may not both be zero.
1676
1677    Returns 1 if this operation can be performed; 0 if not.  */
1678
1679 int
1680 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
1681      optab binoptab;
1682      rtx op0, op1;
1683      rtx targ0, targ1;
1684      int unsignedp;
1685 {
1686   enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1687   enum mode_class class;
1688   enum machine_mode wider_mode;
1689   rtx entry_last = get_last_insn ();
1690   rtx last;
1691
1692   class = GET_MODE_CLASS (mode);
1693
1694   op0 = protect_from_queue (op0, 0);
1695   op1 = protect_from_queue (op1, 0);
1696
1697   if (flag_force_mem)
1698     {
1699       op0 = force_not_mem (op0);
1700       op1 = force_not_mem (op1);
1701     }
1702
1703   /* If we are inside an appropriately-short loop and one operand is an
1704      expensive constant, force it into a register.  */
1705   if (CONSTANT_P (op0) && preserve_subexpressions_p ()
1706       && rtx_cost (op0, binoptab->code) > 2)
1707     op0 = force_reg (mode, op0);
1708
1709   if (CONSTANT_P (op1) && preserve_subexpressions_p ()
1710       && rtx_cost (op1, binoptab->code) > 2)
1711     op1 = force_reg (mode, op1);
1712
1713   if (targ0)
1714     targ0 = protect_from_queue (targ0, 1);
1715   else
1716     targ0 = gen_reg_rtx (mode);
1717   if (targ1)
1718     targ1 = protect_from_queue (targ1, 1);
1719   else
1720     targ1 = gen_reg_rtx (mode);
1721
1722   /* Record where to go back to if we fail.  */
1723   last = get_last_insn ();
1724
1725   if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1726     {
1727       int icode = (int) binoptab->handlers[(int) mode].insn_code;
1728       enum machine_mode mode0 = insn_operand_mode[icode][1];
1729       enum machine_mode mode1 = insn_operand_mode[icode][2];
1730       rtx pat;
1731       rtx xop0 = op0, xop1 = op1;
1732
1733       /* In case this insn wants input operands in modes different from the
1734          result, convert the operands.  */
1735       if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
1736         xop0 = convert_to_mode (mode0, xop0, unsignedp);
1737
1738       if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
1739         xop1 = convert_to_mode (mode1, xop1, unsignedp);
1740
1741       /* Now, if insn doesn't accept these operands, put them into pseudos.  */
1742       if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1743         xop0 = copy_to_mode_reg (mode0, xop0);
1744
1745       if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
1746         xop1 = copy_to_mode_reg (mode1, xop1);
1747
1748       /* We could handle this, but we should always be called with a pseudo
1749          for our targets and all insns should take them as outputs.  */
1750       if (! (*insn_operand_predicate[icode][0]) (targ0, mode)
1751           || ! (*insn_operand_predicate[icode][3]) (targ1, mode))
1752         abort ();
1753         
1754       pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
1755       if (pat)
1756         {
1757           emit_insn (pat);
1758           return 1;
1759         }
1760       else
1761         delete_insns_since (last);
1762     }
1763
1764   /* It can't be done in this mode.  Can we do it in a wider mode?  */
1765
1766   if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1767     {
1768       for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1769            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1770         {
1771           if (binoptab->handlers[(int) wider_mode].insn_code
1772               != CODE_FOR_nothing)
1773             {
1774               register rtx t0 = gen_reg_rtx (wider_mode);
1775               register rtx t1 = gen_reg_rtx (wider_mode);
1776
1777               if (expand_twoval_binop (binoptab,
1778                                        convert_modes (wider_mode, mode, op0,
1779                                                       unsignedp),
1780                                        convert_modes (wider_mode, mode, op1,
1781                                                       unsignedp),
1782                                        t0, t1, unsignedp))
1783                 {
1784                   convert_move (targ0, t0, unsignedp);
1785                   convert_move (targ1, t1, unsignedp);
1786                   return 1;
1787                 }
1788               else
1789                 delete_insns_since (last);
1790             }
1791         }
1792     }
1793
1794   delete_insns_since (entry_last);
1795   return 0;
1796 }
1797 \f
1798 /* Generate code to perform an operation specified by UNOPTAB
1799    on operand OP0, with result having machine-mode MODE.
1800
1801    UNSIGNEDP is for the case where we have to widen the operands
1802    to perform the operation.  It says to use zero-extension.
1803
1804    If TARGET is nonzero, the value
1805    is generated there, if it is convenient to do so.
1806    In all cases an rtx is returned for the locus of the value;
1807    this may or may not be TARGET.  */
1808
1809 rtx
1810 expand_unop (mode, unoptab, op0, target, unsignedp)
1811      enum machine_mode mode;
1812      optab unoptab;
1813      rtx op0;
1814      rtx target;
1815      int unsignedp;
1816 {
1817   enum mode_class class;
1818   enum machine_mode wider_mode;
1819   register rtx temp;
1820   rtx last = get_last_insn ();
1821   rtx pat;
1822
1823   class = GET_MODE_CLASS (mode);
1824
1825   op0 = protect_from_queue (op0, 0);
1826
1827   if (flag_force_mem)
1828     {
1829       op0 = force_not_mem (op0);
1830     }
1831
1832   if (target)
1833     target = protect_from_queue (target, 1);
1834
1835   if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1836     {
1837       int icode = (int) unoptab->handlers[(int) mode].insn_code;
1838       enum machine_mode mode0 = insn_operand_mode[icode][1];
1839       rtx xop0 = op0;
1840
1841       if (target)
1842         temp = target;
1843       else
1844         temp = gen_reg_rtx (mode);
1845
1846       if (GET_MODE (xop0) != VOIDmode
1847           && GET_MODE (xop0) != mode0)
1848         xop0 = convert_to_mode (mode0, xop0, unsignedp);
1849
1850       /* Now, if insn doesn't accept our operand, put it into a pseudo.  */
1851
1852       if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1853         xop0 = copy_to_mode_reg (mode0, xop0);
1854
1855       if (! (*insn_operand_predicate[icode][0]) (temp, mode))
1856         temp = gen_reg_rtx (mode);
1857
1858       pat = GEN_FCN (icode) (temp, xop0);
1859       if (pat)
1860         {
1861           if (GET_CODE (pat) == SEQUENCE
1862               && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
1863             {
1864               delete_insns_since (last);
1865               return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
1866             }
1867
1868           emit_insn (pat);
1869           
1870           return temp;
1871         }
1872       else
1873         delete_insns_since (last);
1874     }
1875
1876   /* It can't be done in this mode.  Can we open-code it in a wider mode?  */
1877
1878   if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1879     for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1880          wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1881       {
1882         if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
1883           {
1884             rtx xop0 = op0;
1885
1886             /* For certain operations, we need not actually extend
1887                the narrow operand, as long as we will truncate the
1888                results to the same narrowness.  */
1889
1890             xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
1891                                   (unoptab == neg_optab
1892                                    || unoptab == one_cmpl_optab)
1893                                   && class == MODE_INT);
1894               
1895             temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1896                                 unsignedp);
1897
1898             if (temp)
1899               {
1900                 if (class != MODE_INT)
1901                   {
1902                     if (target == 0)
1903                       target = gen_reg_rtx (mode);
1904                     convert_move (target, temp, 0);
1905                     return target;
1906                   }
1907                 else
1908                   return gen_lowpart (mode, temp);
1909               }
1910             else
1911               delete_insns_since (last);
1912           }
1913       }
1914
1915   /* These can be done a word at a time.  */
1916   if (unoptab == one_cmpl_optab
1917       && class == MODE_INT
1918       && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1919       && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1920     {
1921       int i;
1922       rtx insns;
1923
1924       if (target == 0 || target == op0)
1925         target = gen_reg_rtx (mode);
1926
1927       start_sequence ();
1928
1929       /* Do the actual arithmetic.  */
1930       for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1931         {
1932           rtx target_piece = operand_subword (target, i, 1, mode);
1933           rtx x = expand_unop (word_mode, unoptab,
1934                                operand_subword_force (op0, i, mode),
1935                                target_piece, unsignedp);
1936           if (target_piece != x)
1937             emit_move_insn (target_piece, x);
1938         }
1939
1940       insns = get_insns ();
1941       end_sequence ();
1942
1943       emit_no_conflict_block (insns, target, op0, NULL_RTX,
1944                               gen_rtx (unoptab->code, mode, copy_rtx (op0)));
1945       return target;
1946     }
1947
1948   /* Open-code the complex negation operation.  */
1949   else if (unoptab == neg_optab
1950            && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT))
1951     {
1952       rtx target_piece;
1953       rtx x;
1954       rtx seq;
1955
1956       /* Find the correct mode for the real and imaginary parts */
1957       enum machine_mode submode
1958         = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1959                          class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1960                          0);
1961
1962       if (submode == BLKmode)
1963         abort ();
1964
1965       if (target == 0)
1966         target = gen_reg_rtx (mode);
1967       
1968       start_sequence ();
1969
1970       target_piece = gen_imagpart (submode, target);
1971       x = expand_unop (submode, unoptab,
1972                        gen_imagpart (submode, op0),
1973                        target_piece, unsignedp);
1974       if (target_piece != x)
1975         emit_move_insn (target_piece, x);
1976
1977       target_piece = gen_realpart (submode, target);
1978       x = expand_unop (submode, unoptab,
1979                        gen_realpart (submode, op0),
1980                        target_piece, unsignedp);
1981       if (target_piece != x)
1982         emit_move_insn (target_piece, x);
1983
1984       seq = get_insns ();
1985       end_sequence ();
1986
1987       emit_no_conflict_block (seq, target, op0, 0,
1988                               gen_rtx (unoptab->code, mode, copy_rtx (op0)));
1989       return target;
1990     }
1991
1992   /* Now try a library call in this mode.  */
1993   if (unoptab->handlers[(int) mode].libfunc)
1994     {
1995       rtx insns;
1996       rtx funexp = unoptab->handlers[(int) mode].libfunc;
1997       rtx value;
1998
1999       start_sequence ();
2000
2001       /* Pass 1 for NO_QUEUE so we don't lose any increments
2002          if the libcall is cse'd or moved.  */
2003       value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
2004                                        NULL_RTX, 1, mode, 1, op0, mode);
2005       insns = get_insns ();
2006       end_sequence ();
2007
2008       target = gen_reg_rtx (mode);
2009       emit_libcall_block (insns, target, value,
2010                           gen_rtx (unoptab->code, mode, op0));
2011
2012       return target;
2013     }
2014
2015   /* It can't be done in this mode.  Can we do it in a wider mode?  */
2016
2017   if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2018     {
2019       for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2020            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2021         {
2022           if ((unoptab->handlers[(int) wider_mode].insn_code
2023                != CODE_FOR_nothing)
2024               || unoptab->handlers[(int) wider_mode].libfunc)
2025             {
2026               rtx xop0 = op0;
2027
2028               /* For certain operations, we need not actually extend
2029                  the narrow operand, as long as we will truncate the
2030                  results to the same narrowness.  */
2031
2032               xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2033                                     (unoptab == neg_optab
2034                                      || unoptab == one_cmpl_optab)
2035                                     && class == MODE_INT);
2036               
2037               temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2038                                   unsignedp);
2039
2040               if (temp)
2041                 {
2042                   if (class != MODE_INT)
2043                     {
2044                       if (target == 0)
2045                         target = gen_reg_rtx (mode);
2046                       convert_move (target, temp, 0);
2047                       return target;
2048                     }
2049                   else
2050                     return gen_lowpart (mode, temp);
2051                 }
2052               else
2053                 delete_insns_since (last);
2054             }
2055         }
2056     }
2057
2058   /* If there is no negate operation, try doing a subtract from zero.
2059      The US Software GOFAST library needs this.  */
2060   if (unoptab == neg_optab)
2061     {    
2062       rtx temp;
2063       temp = expand_binop (mode, sub_optab, CONST0_RTX (mode), op0,
2064                            target, unsignedp, OPTAB_LIB_WIDEN);
2065       if (temp)
2066         return temp;
2067     }
2068       
2069   return 0;
2070 }
2071 \f
2072 /* Emit code to compute the absolute value of OP0, with result to
2073    TARGET if convenient.  (TARGET may be 0.)  The return value says
2074    where the result actually is to be found.
2075
2076    MODE is the mode of the operand; the mode of the result is
2077    different but can be deduced from MODE.
2078
2079    UNSIGNEDP is relevant if extension is needed.  */
2080
2081 rtx
2082 expand_abs (mode, op0, target, unsignedp, safe)
2083      enum machine_mode mode;
2084      rtx op0;
2085      rtx target;
2086      int unsignedp;
2087      int safe;
2088 {
2089   rtx temp, op1;
2090
2091   /* First try to do it with a special abs instruction.  */
2092   temp = expand_unop (mode, abs_optab, op0, target, 0);
2093   if (temp != 0)
2094     return temp;
2095
2096   /* If this machine has expensive jumps, we can do integer absolute
2097      value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2098      where W is the width of MODE.  */
2099
2100   if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
2101     {
2102       rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
2103                                    size_int (GET_MODE_BITSIZE (mode) - 1),
2104                                    NULL_RTX, 0);
2105
2106       temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
2107                            OPTAB_LIB_WIDEN);
2108       if (temp != 0)
2109         temp = expand_binop (mode, sub_optab, temp, extended, target, 0,
2110                              OPTAB_LIB_WIDEN);
2111
2112       if (temp != 0)
2113         return temp;
2114     }
2115
2116   /* If that does not win, use conditional jump and negate.  */
2117   op1 = gen_label_rtx ();
2118   if (target == 0 || ! safe
2119       || GET_MODE (target) != mode
2120       || (GET_CODE (target) == MEM && MEM_VOLATILE_P (target))
2121       || (GET_CODE (target) == REG
2122           && REGNO (target) < FIRST_PSEUDO_REGISTER))
2123     target = gen_reg_rtx (mode);
2124
2125   emit_move_insn (target, op0);
2126   NO_DEFER_POP;
2127
2128   /* If this mode is an integer too wide to compare properly,
2129      compare word by word.  Rely on CSE to optimize constant cases.  */
2130   if (GET_MODE_CLASS (mode) == MODE_INT && ! can_compare_p (mode))
2131     do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx, 
2132                                   NULL_RTX, op1);
2133   else
2134     {
2135       temp = compare_from_rtx (target, CONST0_RTX (mode), GE, 0, mode,
2136                                NULL_RTX, 0);
2137       if (temp == const1_rtx)
2138         return target;
2139       else if (temp != const0_rtx)
2140         {
2141           if (bcc_gen_fctn[(int) GET_CODE (temp)] != 0)
2142             emit_jump_insn ((*bcc_gen_fctn[(int) GET_CODE (temp)]) (op1));
2143           else
2144             abort ();
2145         }
2146     }
2147
2148   op0 = expand_unop (mode, neg_optab, target, target, 0);
2149   if (op0 != target)
2150     emit_move_insn (target, op0);
2151   emit_label (op1);
2152   OK_DEFER_POP;
2153   return target;
2154 }
2155 \f
2156 /* Emit code to compute the absolute value of OP0, with result to
2157    TARGET if convenient.  (TARGET may be 0.)  The return value says
2158    where the result actually is to be found.
2159
2160    MODE is the mode of the operand; the mode of the result is
2161    different but can be deduced from MODE.
2162
2163    UNSIGNEDP is relevant for complex integer modes.  */
2164
2165 rtx
2166 expand_complex_abs (mode, op0, target, unsignedp)
2167      enum machine_mode mode;
2168      rtx op0;
2169      rtx target;
2170      int unsignedp;
2171 {
2172   enum mode_class class = GET_MODE_CLASS (mode);
2173   enum machine_mode wider_mode;
2174   register rtx temp;
2175   rtx entry_last = get_last_insn ();
2176   rtx last;
2177   rtx pat;
2178
2179   /* Find the correct mode for the real and imaginary parts.  */
2180   enum machine_mode submode
2181     = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
2182                      class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
2183                      0);
2184
2185   if (submode == BLKmode)
2186     abort ();
2187
2188   op0 = protect_from_queue (op0, 0);
2189
2190   if (flag_force_mem)
2191     {
2192       op0 = force_not_mem (op0);
2193     }
2194
2195   last = get_last_insn ();
2196
2197   if (target)
2198     target = protect_from_queue (target, 1);
2199
2200   if (abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2201     {
2202       int icode = (int) abs_optab->handlers[(int) mode].insn_code;
2203       enum machine_mode mode0 = insn_operand_mode[icode][1];
2204       rtx xop0 = op0;
2205
2206       if (target)
2207         temp = target;
2208       else
2209         temp = gen_reg_rtx (submode);
2210
2211       if (GET_MODE (xop0) != VOIDmode
2212           && GET_MODE (xop0) != mode0)
2213         xop0 = convert_to_mode (mode0, xop0, unsignedp);
2214
2215       /* Now, if insn doesn't accept our operand, put it into a pseudo.  */
2216
2217       if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
2218         xop0 = copy_to_mode_reg (mode0, xop0);
2219
2220       if (! (*insn_operand_predicate[icode][0]) (temp, submode))
2221         temp = gen_reg_rtx (submode);
2222
2223       pat = GEN_FCN (icode) (temp, xop0);
2224       if (pat)
2225         {
2226           if (GET_CODE (pat) == SEQUENCE
2227               && ! add_equal_note (pat, temp, abs_optab->code, xop0, NULL_RTX))
2228             {
2229               delete_insns_since (last);
2230               return expand_unop (mode, abs_optab, op0, NULL_RTX, unsignedp);
2231             }
2232
2233           emit_insn (pat);
2234           
2235           return temp;
2236         }
2237       else
2238         delete_insns_since (last);
2239     }
2240
2241   /* It can't be done in this mode.  Can we open-code it in a wider mode?  */
2242
2243   for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2244        wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2245     {
2246       if (abs_optab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2247         {
2248           rtx xop0 = op0;
2249
2250           xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2251           temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2252
2253           if (temp)
2254             {
2255               if (class != MODE_COMPLEX_INT)
2256                 {
2257                   if (target == 0)
2258                     target = gen_reg_rtx (submode);
2259                   convert_move (target, temp, 0);
2260                   return target;
2261                 }
2262               else
2263                 return gen_lowpart (submode, temp);
2264             }
2265           else
2266             delete_insns_since (last);
2267         }
2268     }
2269
2270   /* Open-code the complex absolute-value operation
2271      if we can open-code sqrt.  Otherwise it's not worth while.  */
2272   if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing)
2273     {
2274       rtx real, imag, total;
2275
2276       real = gen_realpart (submode, op0);
2277       imag = gen_imagpart (submode, op0);
2278
2279       /* Square both parts.  */
2280       real = expand_mult (submode, real, real, NULL_RTX, 0);
2281       imag = expand_mult (submode, imag, imag, NULL_RTX, 0);
2282
2283       /* Sum the parts.  */
2284       total = expand_binop (submode, add_optab, real, imag, NULL_RTX,
2285                             0, OPTAB_LIB_WIDEN);
2286
2287       /* Get sqrt in TARGET.  Set TARGET to where the result is.  */
2288       target = expand_unop (submode, sqrt_optab, total, target, 0);
2289       if (target == 0)
2290         delete_insns_since (last);
2291       else
2292         return target;
2293     }
2294
2295   /* Now try a library call in this mode.  */
2296   if (abs_optab->handlers[(int) mode].libfunc)
2297     {
2298       rtx insns;
2299       rtx funexp = abs_optab->handlers[(int) mode].libfunc;
2300       rtx value;
2301
2302       start_sequence ();
2303
2304       /* Pass 1 for NO_QUEUE so we don't lose any increments
2305          if the libcall is cse'd or moved.  */
2306       value = emit_library_call_value (abs_optab->handlers[(int) mode].libfunc,
2307                                        NULL_RTX, 1, submode, 1, op0, mode);
2308       insns = get_insns ();
2309       end_sequence ();
2310
2311       target = gen_reg_rtx (submode);
2312       emit_libcall_block (insns, target, value,
2313                           gen_rtx (abs_optab->code, mode, op0));
2314
2315       return target;
2316     }
2317
2318   /* It can't be done in this mode.  Can we do it in a wider mode?  */
2319
2320   for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2321        wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2322     {
2323       if ((abs_optab->handlers[(int) wider_mode].insn_code
2324            != CODE_FOR_nothing)
2325           || abs_optab->handlers[(int) wider_mode].libfunc)
2326         {
2327           rtx xop0 = op0;
2328
2329           xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2330
2331           temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2332
2333           if (temp)
2334             {
2335               if (class != MODE_COMPLEX_INT)
2336                 {
2337                   if (target == 0)
2338                     target = gen_reg_rtx (submode);
2339                   convert_move (target, temp, 0);
2340                   return target;
2341                 }
2342               else
2343                 return gen_lowpart (submode, temp);
2344             }
2345           else
2346             delete_insns_since (last);
2347         }
2348     }
2349
2350   delete_insns_since (entry_last);
2351   return 0;
2352 }
2353 \f
2354 /* Generate an instruction whose insn-code is INSN_CODE,
2355    with two operands: an output TARGET and an input OP0.
2356    TARGET *must* be nonzero, and the output is always stored there.
2357    CODE is an rtx code such that (CODE OP0) is an rtx that describes
2358    the value that is stored into TARGET.  */
2359
2360 void
2361 emit_unop_insn (icode, target, op0, code)
2362      int icode;
2363      rtx target;
2364      rtx op0;
2365      enum rtx_code code;
2366 {
2367   register rtx temp;
2368   enum machine_mode mode0 = insn_operand_mode[icode][1];
2369   rtx pat;
2370
2371   temp = target = protect_from_queue (target, 1);
2372
2373   op0 = protect_from_queue (op0, 0);
2374
2375   if (flag_force_mem)
2376     op0 = force_not_mem (op0);
2377
2378   /* Now, if insn does not accept our operands, put them into pseudos.  */
2379
2380   if (! (*insn_operand_predicate[icode][1]) (op0, mode0))
2381     op0 = copy_to_mode_reg (mode0, op0);
2382
2383   if (! (*insn_operand_predicate[icode][0]) (temp, GET_MODE (temp))
2384       || (flag_force_mem && GET_CODE (temp) == MEM))
2385     temp = gen_reg_rtx (GET_MODE (temp));
2386
2387   pat = GEN_FCN (icode) (temp, op0);
2388
2389   if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
2390     add_equal_note (pat, temp, code, op0, NULL_RTX);
2391   
2392   emit_insn (pat);
2393
2394   if (temp != target)
2395     emit_move_insn (target, temp);
2396 }
2397 \f
2398 /* Emit code to perform a series of operations on a multi-word quantity, one
2399    word at a time.
2400
2401    Such a block is preceded by a CLOBBER of the output, consists of multiple
2402    insns, each setting one word of the output, and followed by a SET copying
2403    the output to itself.
2404
2405    Each of the insns setting words of the output receives a REG_NO_CONFLICT
2406    note indicating that it doesn't conflict with the (also multi-word)
2407    inputs.  The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2408    notes.
2409
2410    INSNS is a block of code generated to perform the operation, not including
2411    the CLOBBER and final copy.  All insns that compute intermediate values
2412    are first emitted, followed by the block as described above.  
2413
2414    TARGET, OP0, and OP1 are the output and inputs of the operations,
2415    respectively.  OP1 may be zero for a unary operation.
2416
2417    EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
2418    on the last insn.
2419
2420    If TARGET is not a register, INSNS is simply emitted with no special
2421    processing.  Likewise if anything in INSNS is not an INSN or if
2422    there is a libcall block inside INSNS.
2423
2424    The final insn emitted is returned.  */
2425
2426 rtx
2427 emit_no_conflict_block (insns, target, op0, op1, equiv)
2428      rtx insns;
2429      rtx target;
2430      rtx op0, op1;
2431      rtx equiv;
2432 {
2433   rtx prev, next, first, last, insn;
2434
2435   if (GET_CODE (target) != REG || reload_in_progress)
2436     return emit_insns (insns);
2437   else
2438     for (insn = insns; insn; insn = NEXT_INSN (insn))
2439       if (GET_CODE (insn) != INSN
2440           || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
2441         return emit_insns (insns);
2442
2443   /* First emit all insns that do not store into words of the output and remove
2444      these from the list.  */
2445   for (insn = insns; insn; insn = next)
2446     {
2447       rtx set = 0;
2448       int i;
2449
2450       next = NEXT_INSN (insn);
2451
2452       if (GET_CODE (PATTERN (insn)) == SET)
2453         set = PATTERN (insn);
2454       else if (GET_CODE (PATTERN (insn)) == PARALLEL)
2455         {
2456           for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
2457             if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
2458               {
2459                 set = XVECEXP (PATTERN (insn), 0, i);
2460                 break;
2461               }
2462         }
2463
2464       if (set == 0)
2465         abort ();
2466
2467       if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
2468         {
2469           if (PREV_INSN (insn))
2470             NEXT_INSN (PREV_INSN (insn)) = next;
2471           else
2472             insns = next;
2473
2474           if (next)
2475             PREV_INSN (next) = PREV_INSN (insn);
2476
2477           add_insn (insn);
2478         }
2479     }
2480
2481   prev = get_last_insn ();
2482
2483   /* Now write the CLOBBER of the output, followed by the setting of each
2484      of the words, followed by the final copy.  */
2485   if (target != op0 && target != op1)
2486     emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
2487
2488   for (insn = insns; insn; insn = next)
2489     {
2490       next = NEXT_INSN (insn);
2491       add_insn (insn);
2492
2493       if (op1 && GET_CODE (op1) == REG)
2494         REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op1,
2495                                     REG_NOTES (insn));
2496
2497       if (op0 && GET_CODE (op0) == REG)
2498         REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op0,
2499                                     REG_NOTES (insn));
2500     }
2501
2502   if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2503       != CODE_FOR_nothing)
2504     {
2505       last = emit_move_insn (target, target);
2506       if (equiv)
2507         REG_NOTES (last)
2508           = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
2509     }
2510   else
2511     last = get_last_insn ();
2512
2513   if (prev == 0)
2514     first = get_insns ();
2515   else
2516     first = NEXT_INSN (prev);
2517
2518   /* Encapsulate the block so it gets manipulated as a unit.  */
2519   REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
2520                                REG_NOTES (first));
2521   REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
2522
2523   return last;
2524 }
2525 \f
2526 /* Emit code to make a call to a constant function or a library call.
2527
2528    INSNS is a list containing all insns emitted in the call.
2529    These insns leave the result in RESULT.  Our block is to copy RESULT
2530    to TARGET, which is logically equivalent to EQUIV.
2531
2532    We first emit any insns that set a pseudo on the assumption that these are
2533    loading constants into registers; doing so allows them to be safely cse'ed
2534    between blocks.  Then we emit all the other insns in the block, followed by
2535    an insn to move RESULT to TARGET.  This last insn will have a REQ_EQUAL
2536    note with an operand of EQUIV.
2537
2538    Moving assignments to pseudos outside of the block is done to improve
2539    the generated code, but is not required to generate correct code,
2540    hence being unable to move an assignment is not grounds for not making
2541    a libcall block.  There are two reasons why it is safe to leave these
2542    insns inside the block: First, we know that these pseudos cannot be
2543    used in generated RTL outside the block since they are created for
2544    temporary purposes within the block.  Second, CSE will not record the
2545    values of anything set inside a libcall block, so we know they must
2546    be dead at the end of the block.
2547
2548    Except for the first group of insns (the ones setting pseudos), the
2549    block is delimited by REG_RETVAL and REG_LIBCALL notes.  */
2550
2551 void
2552 emit_libcall_block (insns, target, result, equiv)
2553      rtx insns;
2554      rtx target;
2555      rtx result;
2556      rtx equiv;
2557 {
2558   rtx prev, next, first, last, insn;
2559
2560   /* First emit all insns that set pseudos.  Remove them from the list as
2561      we go.  Avoid insns that set pseudos which were referenced in previous
2562      insns.  These can be generated by move_by_pieces, for example,
2563      to update an address.  Similarly, avoid insns that reference things
2564      set in previous insns.  */
2565
2566   for (insn = insns; insn; insn = next)
2567     {
2568       rtx set = single_set (insn);
2569
2570       next = NEXT_INSN (insn);
2571
2572       if (set != 0 && GET_CODE (SET_DEST (set)) == REG
2573           && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
2574           && (insn == insns
2575               || (! reg_mentioned_p (SET_DEST (set), PATTERN (insns))
2576                   && ! reg_used_between_p (SET_DEST (set), insns, insn)
2577                   && ! modified_in_p (SET_SRC (set), insns)
2578                   && ! modified_between_p (SET_SRC (set), insns, insn))))
2579         {
2580           if (PREV_INSN (insn))
2581             NEXT_INSN (PREV_INSN (insn)) = next;
2582           else
2583             insns = next;
2584
2585           if (next)
2586             PREV_INSN (next) = PREV_INSN (insn);
2587
2588           add_insn (insn);
2589         }
2590     }
2591
2592   prev = get_last_insn ();
2593
2594   /* Write the remaining insns followed by the final copy.  */
2595
2596   for (insn = insns; insn; insn = next)
2597     {
2598       next = NEXT_INSN (insn);
2599
2600       add_insn (insn);
2601     }
2602
2603   last = emit_move_insn (target, result);
2604   REG_NOTES (last) = gen_rtx (EXPR_LIST,
2605                               REG_EQUAL, copy_rtx (equiv), REG_NOTES (last));
2606
2607   if (prev == 0)
2608     first = get_insns ();
2609   else
2610     first = NEXT_INSN (prev);
2611
2612   /* Encapsulate the block so it gets manipulated as a unit.  */
2613   REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
2614                                REG_NOTES (first));
2615   REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
2616 }
2617 \f
2618 /* Generate code to store zero in X.  */
2619
2620 void
2621 emit_clr_insn (x)
2622      rtx x;
2623 {
2624   emit_move_insn (x, const0_rtx);
2625 }
2626
2627 /* Generate code to store 1 in X
2628    assuming it contains zero beforehand.  */
2629
2630 void
2631 emit_0_to_1_insn (x)
2632      rtx x;
2633 {
2634   emit_move_insn (x, const1_rtx);
2635 }
2636
2637 /* Generate code to compare X with Y
2638    so that the condition codes are set.
2639
2640    MODE is the mode of the inputs (in case they are const_int).
2641    UNSIGNEDP nonzero says that X and Y are unsigned;
2642    this matters if they need to be widened.
2643
2644    If they have mode BLKmode, then SIZE specifies the size of both X and Y,
2645    and ALIGN specifies the known shared alignment of X and Y.
2646
2647    COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
2648    It is ignored for fixed-point and block comparisons;
2649    it is used only for floating-point comparisons.  */
2650
2651 void
2652 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
2653      rtx x, y;
2654      enum rtx_code comparison;
2655      rtx size;
2656      enum machine_mode mode;
2657      int unsignedp;
2658      int align;
2659 {
2660   enum mode_class class;
2661   enum machine_mode wider_mode;
2662
2663   class = GET_MODE_CLASS (mode);
2664
2665   /* They could both be VOIDmode if both args are immediate constants,
2666      but we should fold that at an earlier stage.
2667      With no special code here, this will call abort,
2668      reminding the programmer to implement such folding.  */
2669
2670   if (mode != BLKmode && flag_force_mem)
2671     {
2672       x = force_not_mem (x);
2673       y = force_not_mem (y);
2674     }
2675
2676   /* If we are inside an appropriately-short loop and one operand is an
2677      expensive constant, force it into a register.  */
2678   if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x, COMPARE) > 2)
2679     x = force_reg (mode, x);
2680
2681   if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
2682     y = force_reg (mode, y);
2683
2684   /* Don't let both operands fail to indicate the mode.  */
2685   if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
2686     x = force_reg (mode, x);
2687
2688   /* Handle all BLKmode compares.  */
2689
2690   if (mode == BLKmode)
2691     {
2692       emit_queue ();
2693       x = protect_from_queue (x, 0);
2694       y = protect_from_queue (y, 0);
2695
2696       if (size == 0)
2697         abort ();
2698 #ifdef HAVE_cmpstrqi
2699       if (HAVE_cmpstrqi
2700           && GET_CODE (size) == CONST_INT
2701           && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
2702         {
2703           enum machine_mode result_mode
2704             = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
2705           rtx result = gen_reg_rtx (result_mode);
2706           emit_insn (gen_cmpstrqi (result, x, y, size, GEN_INT (align)));
2707           emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2708                          result_mode, 0, 0);
2709         }
2710       else
2711 #endif
2712 #ifdef HAVE_cmpstrhi
2713       if (HAVE_cmpstrhi
2714           && GET_CODE (size) == CONST_INT
2715           && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
2716         {
2717           enum machine_mode result_mode
2718             = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
2719           rtx result = gen_reg_rtx (result_mode);
2720           emit_insn (gen_cmpstrhi (result, x, y, size, GEN_INT (align)));
2721           emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2722                          result_mode, 0, 0);
2723         }
2724       else
2725 #endif
2726 #ifdef HAVE_cmpstrsi
2727       if (HAVE_cmpstrsi)
2728         {
2729           enum machine_mode result_mode
2730             = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
2731           rtx result = gen_reg_rtx (result_mode);
2732           size = protect_from_queue (size, 0);
2733           emit_insn (gen_cmpstrsi (result, x, y,
2734                                    convert_to_mode (SImode, size, 1),
2735                                    GEN_INT (align)));
2736           emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2737                          result_mode, 0, 0);
2738         }
2739       else
2740 #endif
2741         {
2742 #ifdef TARGET_MEM_FUNCTIONS
2743           emit_library_call (memcmp_libfunc, 0,
2744                              TYPE_MODE (integer_type_node), 3,
2745                              XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2746                              size, Pmode);
2747 #else
2748           emit_library_call (bcmp_libfunc, 0,
2749                              TYPE_MODE (integer_type_node), 3,
2750                              XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2751                              size, Pmode);
2752 #endif
2753           emit_cmp_insn (hard_libcall_value (TYPE_MODE (integer_type_node)),
2754                          const0_rtx, comparison, NULL_RTX,
2755                          TYPE_MODE (integer_type_node), 0, 0);
2756         }
2757       return;
2758     }
2759
2760   /* Handle some compares against zero.  */
2761
2762   if (y == CONST0_RTX (mode)
2763       && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2764     {
2765       int icode = (int) tst_optab->handlers[(int) mode].insn_code;
2766
2767       emit_queue ();
2768       x = protect_from_queue (x, 0);
2769       y = protect_from_queue (y, 0);
2770
2771       /* Now, if insn does accept these operands, put them into pseudos.  */
2772       if (! (*insn_operand_predicate[icode][0])
2773           (x, insn_operand_mode[icode][0]))
2774         x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2775
2776       emit_insn (GEN_FCN (icode) (x));
2777       return;
2778     }
2779
2780   /* Handle compares for which there is a directly suitable insn.  */
2781
2782   if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2783     {
2784       int icode = (int) cmp_optab->handlers[(int) mode].insn_code;
2785
2786       emit_queue ();
2787       x = protect_from_queue (x, 0);
2788       y = protect_from_queue (y, 0);
2789
2790       /* Now, if insn doesn't accept these operands, put them into pseudos.  */
2791       if (! (*insn_operand_predicate[icode][0])
2792           (x, insn_operand_mode[icode][0]))
2793         x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2794
2795       if (! (*insn_operand_predicate[icode][1])
2796           (y, insn_operand_mode[icode][1]))
2797         y = copy_to_mode_reg (insn_operand_mode[icode][1], y);
2798
2799       emit_insn (GEN_FCN (icode) (x, y));
2800       return;
2801     }
2802
2803   /* Try widening if we can find a direct insn that way.  */
2804
2805   if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2806     {
2807       for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2808            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2809         {
2810           if (cmp_optab->handlers[(int) wider_mode].insn_code
2811               != CODE_FOR_nothing)
2812             {
2813               x = protect_from_queue (x, 0);
2814               y = protect_from_queue (y, 0);
2815               x = convert_modes (wider_mode, mode, x, unsignedp);
2816               y = convert_modes (wider_mode, mode, y, unsignedp);
2817               emit_cmp_insn (x, y, comparison, NULL_RTX,
2818                              wider_mode, unsignedp, align);
2819               return;
2820             }
2821         }
2822     }
2823
2824   /* Handle a lib call just for the mode we are using.  */
2825
2826   if (cmp_optab->handlers[(int) mode].libfunc
2827       && class != MODE_FLOAT)
2828     {
2829       rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
2830       /* If we want unsigned, and this mode has a distinct unsigned
2831          comparison routine, use that.  */
2832       if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
2833         libfunc = ucmp_optab->handlers[(int) mode].libfunc;
2834
2835       emit_library_call (libfunc, 1,
2836                          word_mode, 2, x, mode, y, mode);
2837
2838       /* Integer comparison returns a result that must be compared against 1,
2839          so that even if we do an unsigned compare afterward,
2840          there is still a value that can represent the result "less than".  */
2841
2842       emit_cmp_insn (hard_libcall_value (word_mode), const1_rtx,
2843                      comparison, NULL_RTX, word_mode, unsignedp, 0);
2844       return;
2845     }
2846
2847   if (class == MODE_FLOAT)
2848     emit_float_lib_cmp (x, y, comparison);
2849
2850   else
2851     abort ();
2852 }
2853
2854 /* Nonzero if a compare of mode MODE can be done straightforwardly
2855    (without splitting it into pieces).  */
2856
2857 int
2858 can_compare_p (mode)
2859      enum machine_mode mode;
2860 {
2861   do
2862     {
2863       if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2864         return 1;
2865       mode = GET_MODE_WIDER_MODE (mode);
2866     } while (mode != VOIDmode);
2867
2868   return 0;
2869 }
2870 \f
2871 /* Emit a library call comparison between floating point X and Y.
2872    COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  */
2873
2874 void
2875 emit_float_lib_cmp (x, y, comparison)
2876      rtx x, y;
2877      enum rtx_code comparison;
2878 {
2879   enum machine_mode mode = GET_MODE (x);
2880   rtx libfunc = 0;
2881
2882   if (mode == HFmode)
2883     switch (comparison)
2884       {
2885       case EQ:
2886         libfunc = eqhf2_libfunc;
2887         break;
2888
2889       case NE:
2890         libfunc = nehf2_libfunc;
2891         break;
2892
2893       case GT:
2894         libfunc = gthf2_libfunc;
2895         break;
2896
2897       case GE:
2898         libfunc = gehf2_libfunc;
2899         break;
2900
2901       case LT:
2902         libfunc = lthf2_libfunc;
2903         break;
2904
2905       case LE:
2906         libfunc = lehf2_libfunc;
2907         break;
2908       }
2909   else if (mode == SFmode)
2910     switch (comparison)
2911       {
2912       case EQ:
2913         libfunc = eqsf2_libfunc;
2914         break;
2915
2916       case NE:
2917         libfunc = nesf2_libfunc;
2918         break;
2919
2920       case GT:
2921         libfunc = gtsf2_libfunc;
2922         break;
2923
2924       case GE:
2925         libfunc = gesf2_libfunc;
2926         break;
2927
2928       case LT:
2929         libfunc = ltsf2_libfunc;
2930         break;
2931
2932       case LE:
2933         libfunc = lesf2_libfunc;
2934         break;
2935       }
2936   else if (mode == DFmode)
2937     switch (comparison)
2938       {
2939       case EQ:
2940         libfunc = eqdf2_libfunc;
2941         break;
2942
2943       case NE:
2944         libfunc = nedf2_libfunc;
2945         break;
2946
2947       case GT:
2948         libfunc = gtdf2_libfunc;
2949         break;
2950
2951       case GE:
2952         libfunc = gedf2_libfunc;
2953         break;
2954
2955       case LT:
2956         libfunc = ltdf2_libfunc;
2957         break;
2958
2959       case LE:
2960         libfunc = ledf2_libfunc;
2961         break;
2962       }
2963   else if (mode == XFmode)
2964     switch (comparison)
2965       {
2966       case EQ:
2967         libfunc = eqxf2_libfunc;
2968         break;
2969
2970       case NE:
2971         libfunc = nexf2_libfunc;
2972         break;
2973
2974       case GT:
2975         libfunc = gtxf2_libfunc;
2976         break;
2977
2978       case GE:
2979         libfunc = gexf2_libfunc;
2980         break;
2981
2982       case LT:
2983         libfunc = ltxf2_libfunc;
2984         break;
2985
2986       case LE:
2987         libfunc = lexf2_libfunc;
2988         break;
2989       }
2990   else if (mode == TFmode)
2991     switch (comparison)
2992       {
2993       case EQ:
2994         libfunc = eqtf2_libfunc;
2995         break;
2996
2997       case NE:
2998         libfunc = netf2_libfunc;
2999         break;
3000
3001       case GT:
3002         libfunc = gttf2_libfunc;
3003         break;
3004
3005       case GE:
3006         libfunc = getf2_libfunc;
3007         break;
3008
3009       case LT:
3010         libfunc = lttf2_libfunc;
3011         break;
3012
3013       case LE:
3014         libfunc = letf2_libfunc;
3015         break;
3016       }
3017   else
3018     {
3019       enum machine_mode wider_mode;
3020
3021       for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3022            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3023         {
3024           if ((cmp_optab->handlers[(int) wider_mode].insn_code
3025                != CODE_FOR_nothing)
3026               || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
3027             {
3028               x = protect_from_queue (x, 0);
3029               y = protect_from_queue (y, 0);
3030               x = convert_to_mode (wider_mode, x, 0);
3031               y = convert_to_mode (wider_mode, y, 0);
3032               emit_float_lib_cmp (x, y, comparison);
3033               return;
3034             }
3035         }
3036       abort ();
3037     }
3038
3039   if (libfunc == 0)
3040     abort ();
3041
3042   emit_library_call (libfunc, 1,
3043                      word_mode, 2, x, mode, y, mode);
3044
3045   emit_cmp_insn (hard_libcall_value (word_mode), const0_rtx, comparison,
3046                  NULL_RTX, word_mode, 0, 0);
3047 }
3048 \f
3049 /* Generate code to indirectly jump to a location given in the rtx LOC.  */
3050
3051 void
3052 emit_indirect_jump (loc)
3053      rtx loc;
3054 {
3055   if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
3056          (loc, Pmode)))
3057     loc = copy_to_mode_reg (Pmode, loc);
3058
3059   emit_jump_insn (gen_indirect_jump (loc));
3060   emit_barrier ();
3061 }
3062 \f
3063 #ifdef HAVE_conditional_move
3064
3065 /* Emit a conditional move instruction if the machine supports one for that
3066    condition and machine mode.
3067
3068    OP0 and OP1 are the operands that should be compared using CODE.  CMODE is
3069    the mode to use should they be constants.  If it is VOIDmode, they cannot
3070    both be constants.
3071
3072    OP2 should be stored in TARGET if the comparison is true, otherwise OP3
3073    should be stored there.  MODE is the mode to use should they be constants.
3074    If it is VOIDmode, they cannot both be constants.
3075
3076    The result is either TARGET (perhaps modified) or NULL_RTX if the operation
3077    is not supported.  */
3078
3079 rtx
3080 emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
3081                        unsignedp)
3082      rtx target;
3083      enum rtx_code code;
3084      rtx op0, op1;
3085      enum machine_mode cmode;
3086      rtx op2, op3;
3087      enum machine_mode mode;
3088      int unsignedp;
3089 {
3090   rtx tem, subtarget, comparison, insn;
3091   enum insn_code icode;
3092
3093   /* If one operand is constant, make it the second one.  Only do this
3094      if the other operand is not constant as well.  */
3095
3096   if ((CONSTANT_P (op0) && ! CONSTANT_P (op1))
3097       || (GET_CODE (op0) == CONST_INT && GET_CODE (op1) != CONST_INT))
3098     {
3099       tem = op0;
3100       op0 = op1;
3101       op1 = tem;
3102       code = swap_condition (code);
3103     }
3104
3105   if (cmode == VOIDmode)
3106     cmode = GET_MODE (op0);
3107
3108   if ((CONSTANT_P (op2) && ! CONSTANT_P (op3))
3109       || (GET_CODE (op2) == CONST_INT && GET_CODE (op3) != CONST_INT))
3110     {
3111       tem = op2;
3112       op2 = op3;
3113       op3 = tem;
3114       /* ??? This may not be appropriate (consider IEEE).  Perhaps we should
3115          call can_reverse_comparison_p here and bail out if necessary.
3116          It's not clear whether we need to do this canonicalization though.  */
3117       code = reverse_condition (code);
3118     }
3119
3120   if (mode == VOIDmode)
3121     mode = GET_MODE (op2);
3122
3123   icode = movcc_gen_code[mode];
3124
3125   if (icode == CODE_FOR_nothing)
3126     return 0;
3127
3128   if (flag_force_mem)
3129     {
3130       op2 = force_not_mem (op2);
3131       op3 = force_not_mem (op3);
3132     }
3133
3134   if (target)
3135     target = protect_from_queue (target, 1);
3136   else
3137     target = gen_reg_rtx (mode);
3138
3139   subtarget = target;
3140
3141   emit_queue ();
3142
3143   op2 = protect_from_queue (op2, 0);
3144   op3 = protect_from_queue (op3, 0);
3145
3146   /* If the insn doesn't accept these operands, put them in pseudos.  */
3147
3148   if (! (*insn_operand_predicate[icode][0])
3149       (subtarget, insn_operand_mode[icode][0]))
3150     subtarget = gen_reg_rtx (insn_operand_mode[icode][0]);
3151
3152   if (! (*insn_operand_predicate[icode][2])
3153       (op2, insn_operand_mode[icode][2]))
3154     op2 = copy_to_mode_reg (insn_operand_mode[icode][2], op2);
3155
3156   if (! (*insn_operand_predicate[icode][3])
3157       (op3, insn_operand_mode[icode][3]))
3158     op3 = copy_to_mode_reg (insn_operand_mode[icode][3], op3);
3159
3160   /* Everything should now be in the suitable form, so emit the compare insn
3161      and then the conditional move.  */
3162
3163   comparison 
3164     = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX, 0);
3165
3166   /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)?  */
3167   if (GET_CODE (comparison) != code)
3168     /* This shouldn't happen.  */
3169     abort ();
3170   
3171   insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
3172
3173   /* If that failed, then give up.  */
3174   if (insn == 0)
3175     return 0;
3176
3177   emit_insn (insn);
3178
3179   if (subtarget != target)
3180     convert_move (target, subtarget, 0);
3181
3182   return target;
3183 }
3184
3185 /* Return non-zero if a conditional move of mode MODE is supported.
3186
3187    This function is for combine so it can tell whether an insn that looks
3188    like a conditional move is actually supported by the hardware.  If we
3189    guess wrong we lose a bit on optimization, but that's it.  */
3190 /* ??? sparc64 supports conditionally moving integers values based on fp
3191    comparisons, and vice versa.  How do we handle them?  */
3192
3193 int
3194 can_conditionally_move_p (mode)
3195      enum machine_mode mode;
3196 {
3197   if (movcc_gen_code[mode] != CODE_FOR_nothing)
3198     return 1;
3199
3200   return 0;
3201 }
3202
3203 #endif /* HAVE_conditional_move */
3204 \f
3205 /* These three functions generate an insn body and return it
3206    rather than emitting the insn.
3207
3208    They do not protect from queued increments,
3209    because they may be used 1) in protect_from_queue itself
3210    and 2) in other passes where there is no queue.  */
3211
3212 /* Generate and return an insn body to add Y to X.  */
3213
3214 rtx
3215 gen_add2_insn (x, y)
3216      rtx x, y;
3217 {
3218   int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code; 
3219
3220   if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
3221       || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
3222       || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
3223     abort ();
3224
3225   return (GEN_FCN (icode) (x, x, y));
3226 }
3227
3228 int
3229 have_add2_insn (mode)
3230      enum machine_mode mode;
3231 {
3232   return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3233 }
3234
3235 /* Generate and return an insn body to subtract Y from X.  */
3236
3237 rtx
3238 gen_sub2_insn (x, y)
3239      rtx x, y;
3240 {
3241   int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code; 
3242
3243   if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
3244       || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
3245       || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
3246     abort ();
3247
3248   return (GEN_FCN (icode) (x, x, y));
3249 }
3250
3251 int
3252 have_sub2_insn (mode)
3253      enum machine_mode mode;
3254 {
3255   return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3256 }
3257
3258 /* Generate the body of an instruction to copy Y into X.
3259    It may be a SEQUENCE, if one insn isn't enough.  */
3260
3261 rtx
3262 gen_move_insn (x, y)
3263      rtx x, y;
3264 {
3265   register enum machine_mode mode = GET_MODE (x);
3266   enum insn_code insn_code;
3267   rtx seq;
3268
3269   if (mode == VOIDmode)
3270     mode = GET_MODE (y); 
3271
3272   insn_code = mov_optab->handlers[(int) mode].insn_code;
3273
3274   /* Handle MODE_CC modes:  If we don't have a special move insn for this mode,
3275      find a mode to do it in.  If we have a movcc, use it.  Otherwise,
3276      find the MODE_INT mode of the same width.  */
3277
3278   if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
3279     {
3280       enum machine_mode tmode = VOIDmode;
3281       rtx x1 = x, y1 = y;
3282
3283       if (mode != CCmode
3284           && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
3285         tmode = CCmode;
3286       else
3287         for (tmode = QImode; tmode != VOIDmode;
3288              tmode = GET_MODE_WIDER_MODE (tmode))
3289           if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
3290             break;
3291
3292       if (tmode == VOIDmode)
3293         abort ();
3294
3295       /* Get X and Y in TMODE.  We can't use gen_lowpart here because it
3296          may call change_address which is not appropriate if we were
3297          called when a reload was in progress.  We don't have to worry
3298          about changing the address since the size in bytes is supposed to
3299          be the same.  Copy the MEM to change the mode and move any
3300          substitutions from the old MEM to the new one.  */
3301
3302       if (reload_in_progress)
3303         {
3304           x = gen_lowpart_common (tmode, x1);
3305           if (x == 0 && GET_CODE (x1) == MEM)
3306             {
3307               x = gen_rtx (MEM, tmode, XEXP (x1, 0));
3308               RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
3309               MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (x1);
3310               MEM_VOLATILE_P (x) = MEM_VOLATILE_P (x1);
3311               copy_replacements (x1, x);
3312             }
3313
3314           y = gen_lowpart_common (tmode, y1);
3315           if (y == 0 && GET_CODE (y1) == MEM)
3316             {
3317               y = gen_rtx (MEM, tmode, XEXP (y1, 0));
3318               RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
3319               MEM_IN_STRUCT_P (y) = MEM_IN_STRUCT_P (y1);
3320               MEM_VOLATILE_P (y) = MEM_VOLATILE_P (y1);
3321               copy_replacements (y1, y);
3322             }
3323         }
3324       else
3325         {
3326           x = gen_lowpart (tmode, x);
3327           y = gen_lowpart (tmode, y);
3328         }
3329           
3330       insn_code = mov_optab->handlers[(int) tmode].insn_code;
3331       return (GEN_FCN (insn_code) (x, y));
3332     }
3333
3334   start_sequence ();
3335   emit_move_insn_1 (x, y);
3336   seq = gen_sequence ();
3337   end_sequence ();
3338   return seq;
3339 }
3340 \f
3341 /* Return the insn code used to extend FROM_MODE to TO_MODE.
3342    UNSIGNEDP specifies zero-extension instead of sign-extension.  If
3343    no such operation exists, CODE_FOR_nothing will be returned.  */
3344
3345 enum insn_code
3346 can_extend_p (to_mode, from_mode, unsignedp)
3347      enum machine_mode to_mode, from_mode;
3348      int unsignedp;
3349 {
3350   return extendtab[(int) to_mode][(int) from_mode][unsignedp];
3351 }
3352
3353 /* Generate the body of an insn to extend Y (with mode MFROM)
3354    into X (with mode MTO).  Do zero-extension if UNSIGNEDP is nonzero.  */
3355
3356 rtx
3357 gen_extend_insn (x, y, mto, mfrom, unsignedp)
3358      rtx x, y;
3359      enum machine_mode mto, mfrom;
3360      int unsignedp;
3361 {
3362   return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
3363 }
3364 \f
3365 /* can_fix_p and can_float_p say whether the target machine
3366    can directly convert a given fixed point type to
3367    a given floating point type, or vice versa.
3368    The returned value is the CODE_FOR_... value to use,
3369    or CODE_FOR_nothing if these modes cannot be directly converted.
3370
3371    *TRUNCP_PTR is set to 1 if it is necessary to output
3372    an explicit FTRUNC insn before the fix insn; otherwise 0.  */
3373
3374 static enum insn_code
3375 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
3376      enum machine_mode fltmode, fixmode;
3377      int unsignedp;
3378      int *truncp_ptr;
3379 {
3380   *truncp_ptr = 0;
3381   if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
3382     return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
3383
3384   if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
3385     {
3386       *truncp_ptr = 1;
3387       return fixtab[(int) fltmode][(int) fixmode][unsignedp];
3388     }
3389   return CODE_FOR_nothing;
3390 }
3391
3392 static enum insn_code
3393 can_float_p (fltmode, fixmode, unsignedp)
3394      enum machine_mode fixmode, fltmode;
3395      int unsignedp;
3396 {
3397   return floattab[(int) fltmode][(int) fixmode][unsignedp];
3398 }
3399 \f
3400 /* Generate code to convert FROM to floating point
3401    and store in TO.  FROM must be fixed point and not VOIDmode.
3402    UNSIGNEDP nonzero means regard FROM as unsigned.
3403    Normally this is done by correcting the final value
3404    if it is negative.  */
3405
3406 void
3407 expand_float (to, from, unsignedp)
3408      rtx to, from;
3409      int unsignedp;
3410 {
3411   enum insn_code icode;
3412   register rtx target = to;
3413   enum machine_mode fmode, imode;
3414
3415   /* Crash now, because we won't be able to decide which mode to use.  */
3416   if (GET_MODE (from) == VOIDmode)
3417     abort ();
3418
3419   /* Look for an insn to do the conversion.  Do it in the specified
3420      modes if possible; otherwise convert either input, output or both to
3421      wider mode.  If the integer mode is wider than the mode of FROM,
3422      we can do the conversion signed even if the input is unsigned.  */
3423
3424   for (imode = GET_MODE (from); imode != VOIDmode;
3425        imode = GET_MODE_WIDER_MODE (imode))
3426     for (fmode = GET_MODE (to); fmode != VOIDmode;
3427          fmode = GET_MODE_WIDER_MODE (fmode))
3428       {
3429         int doing_unsigned = unsignedp;
3430
3431         icode = can_float_p (fmode, imode, unsignedp);
3432         if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
3433           icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
3434
3435         if (icode != CODE_FOR_nothing)
3436           {
3437             to = protect_from_queue (to, 1);
3438             from = protect_from_queue (from, 0);
3439
3440             if (imode != GET_MODE (from))
3441               from = convert_to_mode (imode, from, unsignedp);
3442
3443             if (fmode != GET_MODE (to))
3444               target = gen_reg_rtx (fmode);
3445
3446             emit_unop_insn (icode, target, from,
3447                             doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
3448
3449             if (target != to)
3450               convert_move (to, target, 0);
3451             return;
3452           }
3453     }
3454
3455 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3456
3457   /* Unsigned integer, and no way to convert directly.
3458      Convert as signed, then conditionally adjust the result.  */
3459   if (unsignedp)
3460     {
3461       rtx label = gen_label_rtx ();
3462       rtx temp;
3463       REAL_VALUE_TYPE offset;
3464
3465       emit_queue ();
3466
3467       to = protect_from_queue (to, 1);
3468       from = protect_from_queue (from, 0);
3469
3470       if (flag_force_mem)
3471         from = force_not_mem (from);
3472
3473       /* Look for a usable floating mode FMODE wider than the source and at
3474          least as wide as the target.  Using FMODE will avoid rounding woes
3475          with unsigned values greater than the signed maximum value.  */
3476
3477       for (fmode = GET_MODE (to);  fmode != VOIDmode;
3478            fmode = GET_MODE_WIDER_MODE (fmode))
3479         if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
3480             && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
3481           break;
3482
3483       if (fmode == VOIDmode)
3484         {
3485           /* There is no such mode.  Pretend the target is wide enough.  */
3486           fmode = GET_MODE (to);
3487
3488           /* Avoid double-rounding when TO is narrower than FROM. */
3489           if ((significand_size (fmode) + 1)
3490               < GET_MODE_BITSIZE (GET_MODE (from)))
3491             {
3492               rtx temp1;
3493               rtx neglabel = gen_label_rtx ();
3494
3495               /* Don't use TARGET if it isn't a register, is a hard register, 
3496                  or is the wrong mode.  */
3497               if (GET_CODE (target) != REG
3498                   || REGNO (target) < FIRST_PSEUDO_REGISTER
3499                   || GET_MODE (target) != fmode)
3500                 target = gen_reg_rtx (fmode);
3501
3502               imode = GET_MODE (from);
3503               do_pending_stack_adjust ();
3504
3505               /* Test whether the sign bit is set.  */
3506               emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, imode, 0, 0);
3507               emit_jump_insn (gen_blt (neglabel));
3508
3509               /* The sign bit is not set.  Convert as signed.  */
3510               expand_float (target, from, 0);
3511               emit_jump_insn (gen_jump (label));
3512
3513               /* The sign bit is set.
3514                  Convert to a usable (positive signed) value by shifting right
3515                  one bit, while remembering if a nonzero bit was shifted
3516                  out; i.e., compute  (from & 1) | (from >> 1).  */
3517
3518               emit_label (neglabel);
3519               temp = expand_binop (imode, and_optab, from, const1_rtx,
3520                                    NULL_RTX, 1, OPTAB_LIB_WIDEN);
3521               temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
3522                                     NULL_RTX, 1);
3523               temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1, 
3524                                    OPTAB_LIB_WIDEN);
3525               expand_float (target, temp, 0);
3526
3527               /* Multiply by 2 to undo the shift above.  */
3528               temp = expand_binop (fmode, add_optab, target, target,
3529                                      target, 0, OPTAB_LIB_WIDEN);
3530               if (temp != target)
3531                 emit_move_insn (target, temp);
3532
3533               do_pending_stack_adjust ();
3534               emit_label (label);
3535               goto done;
3536             }
3537         }
3538
3539       /* If we are about to do some arithmetic to correct for an
3540          unsigned operand, do it in a pseudo-register.  */
3541
3542       if (GET_MODE (to) != fmode
3543           || GET_CODE (to) != REG || REGNO (to) < FIRST_PSEUDO_REGISTER)
3544         target = gen_reg_rtx (fmode);
3545
3546       /* Convert as signed integer to floating.  */
3547       expand_float (target, from, 0);
3548
3549       /* If FROM is negative (and therefore TO is negative),
3550          correct its value by 2**bitwidth.  */
3551
3552       do_pending_stack_adjust ();
3553       emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, GET_MODE (from), 0, 0);
3554       emit_jump_insn (gen_bge (label));
3555
3556       /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
3557          Rather than setting up a dconst_dot_5, let's hope SCO
3558          fixes the bug.  */
3559       offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
3560       temp = expand_binop (fmode, add_optab, target,
3561                            CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
3562                            target, 0, OPTAB_LIB_WIDEN);
3563       if (temp != target)
3564         emit_move_insn (target, temp);
3565
3566       do_pending_stack_adjust ();
3567       emit_label (label);
3568       goto done;
3569     }
3570 #endif
3571
3572   /* No hardware instruction available; call a library routine to convert from
3573      SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode.  */
3574     {
3575       rtx libfcn;
3576       rtx insns;
3577       rtx value;
3578
3579       to = protect_from_queue (to, 1);
3580       from = protect_from_queue (from, 0);
3581
3582       if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
3583         from = convert_to_mode (SImode, from, unsignedp);
3584
3585       if (flag_force_mem)
3586         from = force_not_mem (from);
3587
3588       if (GET_MODE (to) == SFmode)
3589         {
3590           if (GET_MODE (from) == SImode)
3591             libfcn = floatsisf_libfunc;
3592           else if (GET_MODE (from) == DImode)
3593             libfcn = floatdisf_libfunc;
3594           else if (GET_MODE (from) == TImode)
3595             libfcn = floattisf_libfunc;
3596           else
3597             abort ();
3598         }
3599       else if (GET_MODE (to) == DFmode)
3600         {
3601           if (GET_MODE (from) == SImode)
3602             libfcn = floatsidf_libfunc;
3603           else if (GET_MODE (from) == DImode)
3604             libfcn = floatdidf_libfunc;
3605           else if (GET_MODE (from) == TImode)
3606             libfcn = floattidf_libfunc;
3607           else
3608             abort ();
3609         }
3610       else if (GET_MODE (to) == XFmode)
3611         {
3612           if (GET_MODE (from) == SImode)
3613             libfcn = floatsixf_libfunc;
3614           else if (GET_MODE (from) == DImode)
3615             libfcn = floatdixf_libfunc;
3616           else if (GET_MODE (from) == TImode)
3617             libfcn = floattixf_libfunc;
3618           else
3619             abort ();
3620         }
3621       else if (GET_MODE (to) == TFmode)
3622         {
3623           if (GET_MODE (from) == SImode)
3624             libfcn = floatsitf_libfunc;
3625           else if (GET_MODE (from) == DImode)
3626             libfcn = floatditf_libfunc;
3627           else if (GET_MODE (from) == TImode)
3628             libfcn = floattitf_libfunc;
3629           else
3630             abort ();
3631         }
3632       else
3633         abort ();
3634
3635       start_sequence ();
3636
3637       value = emit_library_call_value (libfcn, NULL_RTX, 1,
3638                                        GET_MODE (to),
3639                                        1, from, GET_MODE (from));
3640       insns = get_insns ();
3641       end_sequence ();
3642
3643       emit_libcall_block (insns, target, value,
3644                           gen_rtx (FLOAT, GET_MODE (to), from));
3645     }
3646
3647  done:
3648
3649   /* Copy result to requested destination
3650      if we have been computing in a temp location.  */
3651
3652   if (target != to)
3653     {
3654       if (GET_MODE (target) == GET_MODE (to))
3655         emit_move_insn (to, target);
3656       else
3657         convert_move (to, target, 0);
3658     }
3659 }
3660 \f
3661 /* expand_fix: generate code to convert FROM to fixed point
3662    and store in TO.  FROM must be floating point.  */
3663
3664 static rtx
3665 ftruncify (x)
3666      rtx x;
3667 {
3668   rtx temp = gen_reg_rtx (GET_MODE (x));
3669   return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
3670 }
3671
3672 void
3673 expand_fix (to, from, unsignedp)
3674      register rtx to, from;
3675      int unsignedp;
3676 {
3677   enum insn_code icode;
3678   register rtx target = to;
3679   enum machine_mode fmode, imode;
3680   int must_trunc = 0;
3681   rtx libfcn = 0;
3682
3683   /* We first try to find a pair of modes, one real and one integer, at
3684      least as wide as FROM and TO, respectively, in which we can open-code
3685      this conversion.  If the integer mode is wider than the mode of TO,
3686      we can do the conversion either signed or unsigned.  */
3687
3688   for (imode = GET_MODE (to); imode != VOIDmode;
3689        imode = GET_MODE_WIDER_MODE (imode))
3690     for (fmode = GET_MODE (from); fmode != VOIDmode;
3691          fmode = GET_MODE_WIDER_MODE (fmode))
3692       {
3693         int doing_unsigned = unsignedp;
3694
3695         icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
3696         if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
3697           icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
3698
3699         if (icode != CODE_FOR_nothing)
3700           {
3701             to = protect_from_queue (to, 1);
3702             from = protect_from_queue (from, 0);
3703
3704             if (fmode != GET_MODE (from))
3705               from = convert_to_mode (fmode, from, 0);
3706
3707             if (must_trunc)
3708               from = ftruncify (from);
3709
3710             if (imode != GET_MODE (to))
3711               target = gen_reg_rtx (imode);
3712
3713             emit_unop_insn (icode, target, from,
3714                             doing_unsigned ? UNSIGNED_FIX : FIX);
3715             if (target != to)
3716               convert_move (to, target, unsignedp);
3717             return;
3718           }
3719       }
3720
3721 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3722   /* For an unsigned conversion, there is one more way to do it.
3723      If we have a signed conversion, we generate code that compares
3724      the real value to the largest representable positive number.  If if
3725      is smaller, the conversion is done normally.  Otherwise, subtract
3726      one plus the highest signed number, convert, and add it back.
3727
3728      We only need to check all real modes, since we know we didn't find
3729      anything with a wider integer mode.  */
3730
3731   if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
3732     for (fmode = GET_MODE (from); fmode != VOIDmode;
3733          fmode = GET_MODE_WIDER_MODE (fmode))
3734       /* Make sure we won't lose significant bits doing this.  */
3735       if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
3736           && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
3737                                             &must_trunc))
3738         {
3739           int bitsize;
3740           REAL_VALUE_TYPE offset;
3741           rtx limit, lab1, lab2, insn;
3742
3743           bitsize = GET_MODE_BITSIZE (GET_MODE (to));
3744           offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
3745           limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
3746           lab1 = gen_label_rtx ();
3747           lab2 = gen_label_rtx ();
3748
3749           emit_queue ();
3750           to = protect_from_queue (to, 1);
3751           from = protect_from_queue (from, 0);
3752
3753           if (flag_force_mem)
3754             from = force_not_mem (from);
3755
3756           if (fmode != GET_MODE (from))
3757             from = convert_to_mode (fmode, from, 0);
3758
3759           /* See if we need to do the subtraction.  */
3760           do_pending_stack_adjust ();
3761           emit_cmp_insn (from, limit, GE, NULL_RTX, GET_MODE (from), 0, 0);
3762           emit_jump_insn (gen_bge (lab1));
3763
3764           /* If not, do the signed "fix" and branch around fixup code.  */
3765           expand_fix (to, from, 0);
3766           emit_jump_insn (gen_jump (lab2));
3767           emit_barrier ();
3768
3769           /* Otherwise, subtract 2**(N-1), convert to signed number,
3770              then add 2**(N-1).  Do the addition using XOR since this
3771              will often generate better code.  */
3772           emit_label (lab1);
3773           target = expand_binop (GET_MODE (from), sub_optab, from, limit,
3774                                  NULL_RTX, 0, OPTAB_LIB_WIDEN);
3775           expand_fix (to, target, 0);
3776           target = expand_binop (GET_MODE (to), xor_optab, to,
3777                                  GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
3778                                  to, 1, OPTAB_LIB_WIDEN);
3779
3780           if (target != to)
3781             emit_move_insn (to, target);
3782
3783           emit_label (lab2);
3784
3785           /* Make a place for a REG_NOTE and add it.  */
3786           insn = emit_move_insn (to, to);
3787           REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
3788                                       gen_rtx (UNSIGNED_FIX, GET_MODE (to),
3789                                                copy_rtx (from)),
3790                                       REG_NOTES (insn));
3791
3792           return;
3793         }
3794 #endif
3795
3796   /* We can't do it with an insn, so use a library call.  But first ensure
3797      that the mode of TO is at least as wide as SImode, since those are the
3798      only library calls we know about.  */
3799
3800   if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
3801     {
3802       target = gen_reg_rtx (SImode);
3803
3804       expand_fix (target, from, unsignedp);
3805     }
3806   else if (GET_MODE (from) == SFmode)
3807     {
3808       if (GET_MODE (to) == SImode)
3809         libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
3810       else if (GET_MODE (to) == DImode)
3811         libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
3812       else if (GET_MODE (to) == TImode)
3813         libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
3814       else
3815         abort ();
3816     }
3817   else if (GET_MODE (from) == DFmode)
3818     {
3819       if (GET_MODE (to) == SImode)
3820         libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
3821       else if (GET_MODE (to) == DImode)
3822         libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
3823       else if (GET_MODE (to) == TImode)
3824         libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
3825       else
3826         abort ();
3827     }
3828   else if (GET_MODE (from) == XFmode)
3829     {
3830       if (GET_MODE (to) == SImode)
3831         libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
3832       else if (GET_MODE (to) == DImode)
3833         libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
3834       else if (GET_MODE (to) == TImode)
3835         libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
3836       else
3837         abort ();
3838     }
3839   else if (GET_MODE (from) == TFmode)
3840     {
3841       if (GET_MODE (to) == SImode)
3842         libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
3843       else if (GET_MODE (to) == DImode)
3844         libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
3845       else if (GET_MODE (to) == TImode)
3846         libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
3847       else
3848         abort ();
3849     }
3850   else
3851     abort ();
3852
3853   if (libfcn)
3854     {
3855       rtx insns;
3856       rtx value;
3857
3858       to = protect_from_queue (to, 1);
3859       from = protect_from_queue (from, 0);
3860
3861       if (flag_force_mem)
3862         from = force_not_mem (from);
3863
3864       start_sequence ();
3865
3866       value = emit_library_call_value (libfcn, NULL_RTX, 1, GET_MODE (to),
3867
3868                                        1, from, GET_MODE (from));
3869       insns = get_insns ();
3870       end_sequence ();
3871
3872       emit_libcall_block (insns, target, value,
3873                           gen_rtx (unsignedp ? UNSIGNED_FIX : FIX,
3874                                    GET_MODE (to), from));
3875     }
3876       
3877   if (GET_MODE (to) == GET_MODE (target))
3878     emit_move_insn (to, target);
3879   else
3880     convert_move (to, target, 0);
3881 }
3882 \f
3883 static optab
3884 init_optab (code)
3885      enum rtx_code code;
3886 {
3887   int i;
3888   optab op = (optab) xmalloc (sizeof (struct optab));
3889   op->code = code;
3890   for (i = 0; i < NUM_MACHINE_MODES; i++)
3891     {
3892       op->handlers[i].insn_code = CODE_FOR_nothing;
3893       op->handlers[i].libfunc = 0;
3894     }
3895
3896   if (code != UNKNOWN)
3897     code_to_optab[(int) code] = op;
3898
3899   return op;
3900 }
3901
3902 /* Initialize the libfunc fields of an entire group of entries in some
3903    optab.  Each entry is set equal to a string consisting of a leading
3904    pair of underscores followed by a generic operation name followed by
3905    a mode name (downshifted to lower case) followed by a single character
3906    representing the number of operands for the given operation (which is
3907    usually one of the characters '2', '3', or '4').
3908
3909    OPTABLE is the table in which libfunc fields are to be initialized.
3910    FIRST_MODE is the first machine mode index in the given optab to
3911      initialize.
3912    LAST_MODE is the last machine mode index in the given optab to
3913      initialize.
3914    OPNAME is the generic (string) name of the operation.
3915    SUFFIX is the character which specifies the number of operands for
3916      the given generic operation.
3917 */
3918
3919 static void
3920 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
3921     register optab optable;
3922     register int first_mode;
3923     register int last_mode;
3924     register char *opname;
3925     register int suffix;
3926 {
3927   register int mode;
3928   register unsigned opname_len = strlen (opname);
3929
3930   for (mode = first_mode; (int) mode <= (int) last_mode;
3931        mode = (enum machine_mode) ((int) mode + 1))
3932     {
3933       register char *mname = mode_name[(int) mode];
3934       register unsigned mname_len = strlen (mname);
3935       register char *libfunc_name
3936         = (char *) xmalloc (2 + opname_len + mname_len + 1 + 1);
3937       register char *p;
3938       register char *q;
3939
3940       p = libfunc_name;
3941       *p++ = '_';
3942       *p++ = '_';
3943       for (q = opname; *q; )
3944         *p++ = *q++;
3945       for (q = mname; *q; q++)
3946         *p++ = tolower (*q);
3947       *p++ = suffix;
3948       *p++ = '\0';
3949       optable->handlers[(int) mode].libfunc
3950         = gen_rtx (SYMBOL_REF, Pmode, libfunc_name);
3951     }
3952 }
3953
3954 /* Initialize the libfunc fields of an entire group of entries in some
3955    optab which correspond to all integer mode operations.  The parameters
3956    have the same meaning as similarly named ones for the `init_libfuncs'
3957    routine.  (See above).  */
3958
3959 static void
3960 init_integral_libfuncs (optable, opname, suffix)
3961     register optab optable;
3962     register char *opname;
3963     register int suffix;
3964 {
3965   init_libfuncs (optable, SImode, TImode, opname, suffix);
3966 }
3967
3968 /* Initialize the libfunc fields of an entire group of entries in some
3969    optab which correspond to all real mode operations.  The parameters
3970    have the same meaning as similarly named ones for the `init_libfuncs'
3971    routine.  (See above).  */
3972
3973 static void
3974 init_floating_libfuncs (optable, opname, suffix)
3975     register optab optable;
3976     register char *opname;
3977     register int suffix;
3978 {
3979   init_libfuncs (optable, SFmode, TFmode, opname, suffix);
3980 }
3981
3982 /* Initialize the libfunc fields of an entire group of entries in some
3983    optab which correspond to all complex floating modes.  The parameters
3984    have the same meaning as similarly named ones for the `init_libfuncs'
3985    routine.  (See above).  */
3986
3987 static void
3988 init_complex_libfuncs (optable, opname, suffix)
3989     register optab optable;
3990     register char *opname;
3991     register int suffix;
3992 {
3993   init_libfuncs (optable, SCmode, TCmode, opname, suffix);
3994 }
3995
3996 /* Call this once to initialize the contents of the optabs
3997    appropriately for the current target machine.  */
3998
3999 void
4000 init_optabs ()
4001 {
4002   int i, j;
4003   enum insn_code *p;
4004
4005   /* Start by initializing all tables to contain CODE_FOR_nothing.  */
4006
4007   for (p = fixtab[0][0];
4008        p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]); 
4009        p++)
4010     *p = CODE_FOR_nothing;
4011
4012   for (p = fixtrunctab[0][0];
4013        p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]); 
4014        p++)
4015     *p = CODE_FOR_nothing;
4016
4017   for (p = floattab[0][0];
4018        p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]); 
4019        p++)
4020     *p = CODE_FOR_nothing;
4021
4022   for (p = extendtab[0][0];
4023        p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
4024        p++)
4025     *p = CODE_FOR_nothing;
4026
4027   for (i = 0; i < NUM_RTX_CODE; i++)
4028     setcc_gen_code[i] = CODE_FOR_nothing;
4029
4030 #ifdef HAVE_conditional_move
4031   for (i = 0; i < NUM_MACHINE_MODES; i++)
4032     movcc_gen_code[i] = CODE_FOR_nothing;
4033 #endif
4034
4035   add_optab = init_optab (PLUS);
4036   sub_optab = init_optab (MINUS);
4037   smul_optab = init_optab (MULT);
4038   smul_highpart_optab = init_optab (UNKNOWN);
4039   umul_highpart_optab = init_optab (UNKNOWN);
4040   smul_widen_optab = init_optab (UNKNOWN);
4041   umul_widen_optab = init_optab (UNKNOWN);
4042   sdiv_optab = init_optab (DIV);
4043   sdivmod_optab = init_optab (UNKNOWN);
4044   udiv_optab = init_optab (UDIV);
4045   udivmod_optab = init_optab (UNKNOWN);
4046   smod_optab = init_optab (MOD);
4047   umod_optab = init_optab (UMOD);
4048   flodiv_optab = init_optab (DIV);
4049   ftrunc_optab = init_optab (UNKNOWN);
4050   and_optab = init_optab (AND);
4051   ior_optab = init_optab (IOR);
4052   xor_optab = init_optab (XOR);
4053   ashl_optab = init_optab (ASHIFT);
4054   ashr_optab = init_optab (ASHIFTRT);
4055   lshr_optab = init_optab (LSHIFTRT);
4056   rotl_optab = init_optab (ROTATE);
4057   rotr_optab = init_optab (ROTATERT);
4058   smin_optab = init_optab (SMIN);
4059   smax_optab = init_optab (SMAX);
4060   umin_optab = init_optab (UMIN);
4061   umax_optab = init_optab (UMAX);
4062   mov_optab = init_optab (UNKNOWN);
4063   movstrict_optab = init_optab (UNKNOWN);
4064   cmp_optab = init_optab (UNKNOWN);
4065   ucmp_optab = init_optab (UNKNOWN);
4066   tst_optab = init_optab (UNKNOWN);
4067   neg_optab = init_optab (NEG);
4068   abs_optab = init_optab (ABS);
4069   one_cmpl_optab = init_optab (NOT);
4070   ffs_optab = init_optab (FFS);
4071   sqrt_optab = init_optab (SQRT);
4072   sin_optab = init_optab (UNKNOWN);
4073   cos_optab = init_optab (UNKNOWN);
4074   strlen_optab = init_optab (UNKNOWN);
4075
4076   for (i = 0; i < NUM_MACHINE_MODES; i++)
4077     {
4078       movstr_optab[i] = CODE_FOR_nothing;
4079
4080 #ifdef HAVE_SECONDARY_RELOADS
4081       reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
4082 #endif
4083     }
4084
4085   /* Fill in the optabs with the insns we support.  */
4086   init_all_optabs ();
4087
4088 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4089   /* This flag says the same insns that convert to a signed fixnum
4090      also convert validly to an unsigned one.  */
4091   for (i = 0; i < NUM_MACHINE_MODES; i++)
4092     for (j = 0; j < NUM_MACHINE_MODES; j++)
4093       fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
4094 #endif
4095
4096 #ifdef EXTRA_CC_MODES
4097   init_mov_optab ();
4098 #endif
4099
4100   /* Initialize the optabs with the names of the library functions.  */
4101   init_integral_libfuncs (add_optab, "add", '3');
4102   init_floating_libfuncs (add_optab, "add", '3');
4103   init_integral_libfuncs (sub_optab, "sub", '3');
4104   init_floating_libfuncs (sub_optab, "sub", '3');
4105   init_integral_libfuncs (smul_optab, "mul", '3');
4106   init_floating_libfuncs (smul_optab, "mul", '3');
4107   init_integral_libfuncs (sdiv_optab, "div", '3');
4108   init_integral_libfuncs (udiv_optab, "udiv", '3');
4109   init_integral_libfuncs (sdivmod_optab, "divmod", '4');
4110   init_integral_libfuncs (udivmod_optab, "udivmod", '4');
4111   init_integral_libfuncs (smod_optab, "mod", '3');
4112   init_integral_libfuncs (umod_optab, "umod", '3');
4113   init_floating_libfuncs (flodiv_optab, "div", '3');
4114   init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
4115   init_integral_libfuncs (and_optab, "and", '3');
4116   init_integral_libfuncs (ior_optab, "ior", '3');
4117   init_integral_libfuncs (xor_optab, "xor", '3');
4118   init_integral_libfuncs (ashl_optab, "ashl", '3');
4119   init_integral_libfuncs (ashr_optab, "ashr", '3');
4120   init_integral_libfuncs (lshr_optab, "lshr", '3');
4121   init_integral_libfuncs (smin_optab, "min", '3');
4122   init_floating_libfuncs (smin_optab, "min", '3');
4123   init_integral_libfuncs (smax_optab, "max", '3');
4124   init_floating_libfuncs (smax_optab, "max", '3');
4125   init_integral_libfuncs (umin_optab, "umin", '3');
4126   init_integral_libfuncs (umax_optab, "umax", '3');
4127   init_integral_libfuncs (neg_optab, "neg", '2');
4128   init_floating_libfuncs (neg_optab, "neg", '2');
4129   init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
4130   init_integral_libfuncs (ffs_optab, "ffs", '2');
4131
4132   /* Comparison libcalls for integers MUST come in pairs, signed/unsigned.  */
4133   init_integral_libfuncs (cmp_optab, "cmp", '2');
4134   init_integral_libfuncs (ucmp_optab, "ucmp", '2');
4135   init_floating_libfuncs (cmp_optab, "cmp", '2');
4136
4137 #ifdef MULSI3_LIBCALL
4138   smul_optab->handlers[(int) SImode].libfunc
4139     = gen_rtx (SYMBOL_REF, Pmode, MULSI3_LIBCALL);
4140 #endif
4141 #ifdef MULDI3_LIBCALL
4142   smul_optab->handlers[(int) DImode].libfunc
4143     = gen_rtx (SYMBOL_REF, Pmode, MULDI3_LIBCALL);
4144 #endif
4145
4146 #ifdef DIVSI3_LIBCALL
4147   sdiv_optab->handlers[(int) SImode].libfunc
4148     = gen_rtx (SYMBOL_REF, Pmode, DIVSI3_LIBCALL);
4149 #endif
4150 #ifdef DIVDI3_LIBCALL
4151   sdiv_optab->handlers[(int) DImode].libfunc
4152     = gen_rtx (SYMBOL_REF, Pmode, DIVDI3_LIBCALL);
4153 #endif
4154
4155 #ifdef UDIVSI3_LIBCALL
4156   udiv_optab->handlers[(int) SImode].libfunc
4157     = gen_rtx (SYMBOL_REF, Pmode, UDIVSI3_LIBCALL);
4158 #endif
4159 #ifdef UDIVDI3_LIBCALL
4160   udiv_optab->handlers[(int) DImode].libfunc
4161     = gen_rtx (SYMBOL_REF, Pmode, UDIVDI3_LIBCALL);
4162 #endif
4163
4164 #ifdef MODSI3_LIBCALL
4165   smod_optab->handlers[(int) SImode].libfunc
4166     = gen_rtx (SYMBOL_REF, Pmode, MODSI3_LIBCALL);
4167 #endif
4168 #ifdef MODDI3_LIBCALL
4169   smod_optab->handlers[(int) DImode].libfunc
4170     = gen_rtx (SYMBOL_REF, Pmode, MODDI3_LIBCALL);
4171 #endif
4172
4173 #ifdef UMODSI3_LIBCALL
4174   umod_optab->handlers[(int) SImode].libfunc
4175     = gen_rtx (SYMBOL_REF, Pmode, UMODSI3_LIBCALL);
4176 #endif
4177 #ifdef UMODDI3_LIBCALL
4178   umod_optab->handlers[(int) DImode].libfunc
4179     = gen_rtx (SYMBOL_REF, Pmode, UMODDI3_LIBCALL);
4180 #endif
4181
4182   /* Use cabs for DC complex abs, since systems generally have cabs.
4183      Don't define any libcall for SCmode, so that cabs will be used.  */
4184   abs_optab->handlers[(int) DCmode].libfunc
4185     = gen_rtx (SYMBOL_REF, Pmode, "cabs");
4186
4187   /* The ffs function operates on `int'.  */
4188 #ifndef INT_TYPE_SIZE
4189 #define INT_TYPE_SIZE BITS_PER_WORD
4190 #endif
4191   ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)] .libfunc
4192     = gen_rtx (SYMBOL_REF, Pmode, "ffs");
4193
4194   extendsfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfdf2");
4195   extendsfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfxf2");
4196   extendsftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsftf2");
4197   extenddfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddfxf2");
4198   extenddftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddftf2");
4199
4200   truncdfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncdfsf2");
4201   truncxfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfsf2");
4202   trunctfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfsf2");
4203   truncxfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfdf2");
4204   trunctfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfdf2");
4205
4206   memcpy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcpy");
4207   bcopy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcopy");
4208   memcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcmp");
4209   bcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gcc_bcmp");
4210   memset_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memset");
4211   bzero_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bzero");
4212
4213   eqhf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqhf2");
4214   nehf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nehf2");
4215   gthf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gthf2");
4216   gehf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gehf2");
4217   lthf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lthf2");
4218   lehf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lehf2");
4219
4220   eqsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqsf2");
4221   nesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nesf2");
4222   gtsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtsf2");
4223   gesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gesf2");
4224   ltsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltsf2");
4225   lesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lesf2");
4226
4227   eqdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqdf2");
4228   nedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nedf2");
4229   gtdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtdf2");
4230   gedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gedf2");
4231   ltdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltdf2");
4232   ledf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ledf2");
4233
4234   eqxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqxf2");
4235   nexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nexf2");
4236   gtxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtxf2");
4237   gexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gexf2");
4238   ltxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltxf2");
4239   lexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lexf2");
4240
4241   eqtf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqtf2");
4242   netf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__netf2");
4243   gttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gttf2");
4244   getf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__getf2");
4245   lttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lttf2");
4246   letf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__letf2");
4247
4248   floatsisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsisf");
4249   floatdisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdisf");
4250   floattisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattisf");
4251
4252   floatsidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsidf");
4253   floatdidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdidf");
4254   floattidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattidf");
4255
4256   floatsixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsixf");
4257   floatdixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdixf");
4258   floattixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattixf");
4259
4260   floatsitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsitf");
4261   floatditf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatditf");
4262   floattitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattitf");
4263
4264   fixsfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfsi");
4265   fixsfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfdi");
4266   fixsfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfti");
4267
4268   fixdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfsi");
4269   fixdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfdi");
4270   fixdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfti");
4271
4272   fixxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfsi");
4273   fixxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfdi");
4274   fixxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfti");
4275
4276   fixtfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfsi");
4277   fixtfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfdi");
4278   fixtfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfti");
4279
4280   fixunssfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfsi");
4281   fixunssfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfdi");
4282   fixunssfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfti");
4283
4284   fixunsdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfsi");
4285   fixunsdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfdi");
4286   fixunsdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfti");
4287
4288   fixunsxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfsi");
4289   fixunsxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfdi");
4290   fixunsxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfti");
4291
4292   fixunstfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfsi");
4293   fixunstfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfdi");
4294   fixunstfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfti");
4295
4296 #ifdef INIT_TARGET_OPTABS
4297   /* Allow the target to add more libcalls or rename some, etc.  */
4298   INIT_TARGET_OPTABS;
4299 #endif
4300 }
4301 \f
4302 #ifdef BROKEN_LDEXP
4303
4304 /* SCO 3.2 apparently has a broken ldexp. */
4305
4306 double
4307 ldexp(x,n)
4308      double x;
4309      int n;
4310 {
4311   if (n > 0)
4312     while (n--)
4313       x *= 2;
4314
4315   return x;
4316 }
4317 #endif /* BROKEN_LDEXP */