OSDN Git Service

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