OSDN Git Service

Major cutover to using system.h:
[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    that 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     {
3181       tem = op2;
3182       op2 = op3;
3183       op3 = tem;
3184       /* ??? This may not be appropriate (consider IEEE).  Perhaps we should
3185          call can_reverse_comparison_p here and bail out if necessary.
3186          It's not clear whether we need to do this canonicalization though.  */
3187       code = reverse_condition (code);
3188     }
3189
3190   if (mode == VOIDmode)
3191     mode = GET_MODE (op2);
3192
3193   icode = movcc_gen_code[mode];
3194
3195   if (icode == CODE_FOR_nothing)
3196     return 0;
3197
3198   if (flag_force_mem)
3199     {
3200       op2 = force_not_mem (op2);
3201       op3 = force_not_mem (op3);
3202     }
3203
3204   if (target)
3205     target = protect_from_queue (target, 1);
3206   else
3207     target = gen_reg_rtx (mode);
3208
3209   subtarget = target;
3210
3211   emit_queue ();
3212
3213   op2 = protect_from_queue (op2, 0);
3214   op3 = protect_from_queue (op3, 0);
3215
3216   /* If the insn doesn't accept these operands, put them in pseudos.  */
3217
3218   if (! (*insn_operand_predicate[icode][0])
3219       (subtarget, insn_operand_mode[icode][0]))
3220     subtarget = gen_reg_rtx (insn_operand_mode[icode][0]);
3221
3222   if (! (*insn_operand_predicate[icode][2])
3223       (op2, insn_operand_mode[icode][2]))
3224     op2 = copy_to_mode_reg (insn_operand_mode[icode][2], op2);
3225
3226   if (! (*insn_operand_predicate[icode][3])
3227       (op3, insn_operand_mode[icode][3]))
3228     op3 = copy_to_mode_reg (insn_operand_mode[icode][3], op3);
3229
3230   /* Everything should now be in the suitable form, so emit the compare insn
3231      and then the conditional move.  */
3232
3233   comparison 
3234     = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX, 0);
3235
3236   /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)?  */
3237   if (GET_CODE (comparison) != code)
3238     /* This shouldn't happen.  */
3239     abort ();
3240   
3241   insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
3242
3243   /* If that failed, then give up.  */
3244   if (insn == 0)
3245     return 0;
3246
3247   emit_insn (insn);
3248
3249   if (subtarget != target)
3250     convert_move (target, subtarget, 0);
3251
3252   return target;
3253 }
3254
3255 /* Return non-zero if a conditional move of mode MODE is supported.
3256
3257    This function is for combine so it can tell whether an insn that looks
3258    like a conditional move is actually supported by the hardware.  If we
3259    guess wrong we lose a bit on optimization, but that's it.  */
3260 /* ??? sparc64 supports conditionally moving integers values based on fp
3261    comparisons, and vice versa.  How do we handle them?  */
3262
3263 int
3264 can_conditionally_move_p (mode)
3265      enum machine_mode mode;
3266 {
3267   if (movcc_gen_code[mode] != CODE_FOR_nothing)
3268     return 1;
3269
3270   return 0;
3271 }
3272
3273 #endif /* HAVE_conditional_move */
3274 \f
3275 /* These three functions generate an insn body and return it
3276    rather than emitting the insn.
3277
3278    They do not protect from queued increments,
3279    because they may be used 1) in protect_from_queue itself
3280    and 2) in other passes where there is no queue.  */
3281
3282 /* Generate and return an insn body to add Y to X.  */
3283
3284 rtx
3285 gen_add2_insn (x, y)
3286      rtx x, y;
3287 {
3288   int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code; 
3289
3290   if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
3291       || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
3292       || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
3293     abort ();
3294
3295   return (GEN_FCN (icode) (x, x, y));
3296 }
3297
3298 int
3299 have_add2_insn (mode)
3300      enum machine_mode mode;
3301 {
3302   return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3303 }
3304
3305 /* Generate and return an insn body to subtract Y from X.  */
3306
3307 rtx
3308 gen_sub2_insn (x, y)
3309      rtx x, y;
3310 {
3311   int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code; 
3312
3313   if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
3314       || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
3315       || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
3316     abort ();
3317
3318   return (GEN_FCN (icode) (x, x, y));
3319 }
3320
3321 int
3322 have_sub2_insn (mode)
3323      enum machine_mode mode;
3324 {
3325   return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3326 }
3327
3328 /* Generate the body of an instruction to copy Y into X.
3329    It may be a SEQUENCE, if one insn isn't enough.  */
3330
3331 rtx
3332 gen_move_insn (x, y)
3333      rtx x, y;
3334 {
3335   register enum machine_mode mode = GET_MODE (x);
3336   enum insn_code insn_code;
3337   rtx seq;
3338
3339   if (mode == VOIDmode)
3340     mode = GET_MODE (y); 
3341
3342   insn_code = mov_optab->handlers[(int) mode].insn_code;
3343
3344   /* Handle MODE_CC modes:  If we don't have a special move insn for this mode,
3345      find a mode to do it in.  If we have a movcc, use it.  Otherwise,
3346      find the MODE_INT mode of the same width.  */
3347
3348   if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
3349     {
3350       enum machine_mode tmode = VOIDmode;
3351       rtx x1 = x, y1 = y;
3352
3353       if (mode != CCmode
3354           && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
3355         tmode = CCmode;
3356       else
3357         for (tmode = QImode; tmode != VOIDmode;
3358              tmode = GET_MODE_WIDER_MODE (tmode))
3359           if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
3360             break;
3361
3362       if (tmode == VOIDmode)
3363         abort ();
3364
3365       /* Get X and Y in TMODE.  We can't use gen_lowpart here because it
3366          may call change_address which is not appropriate if we were
3367          called when a reload was in progress.  We don't have to worry
3368          about changing the address since the size in bytes is supposed to
3369          be the same.  Copy the MEM to change the mode and move any
3370          substitutions from the old MEM to the new one.  */
3371
3372       if (reload_in_progress)
3373         {
3374           x = gen_lowpart_common (tmode, x1);
3375           if (x == 0 && GET_CODE (x1) == MEM)
3376             {
3377               x = gen_rtx (MEM, tmode, XEXP (x1, 0));
3378               RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
3379               MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (x1);
3380               MEM_VOLATILE_P (x) = MEM_VOLATILE_P (x1);
3381               copy_replacements (x1, x);
3382             }
3383
3384           y = gen_lowpart_common (tmode, y1);
3385           if (y == 0 && GET_CODE (y1) == MEM)
3386             {
3387               y = gen_rtx (MEM, tmode, XEXP (y1, 0));
3388               RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
3389               MEM_IN_STRUCT_P (y) = MEM_IN_STRUCT_P (y1);
3390               MEM_VOLATILE_P (y) = MEM_VOLATILE_P (y1);
3391               copy_replacements (y1, y);
3392             }
3393         }
3394       else
3395         {
3396           x = gen_lowpart (tmode, x);
3397           y = gen_lowpart (tmode, y);
3398         }
3399           
3400       insn_code = mov_optab->handlers[(int) tmode].insn_code;
3401       return (GEN_FCN (insn_code) (x, y));
3402     }
3403
3404   start_sequence ();
3405   emit_move_insn_1 (x, y);
3406   seq = gen_sequence ();
3407   end_sequence ();
3408   return seq;
3409 }
3410 \f
3411 /* Return the insn code used to extend FROM_MODE to TO_MODE.
3412    UNSIGNEDP specifies zero-extension instead of sign-extension.  If
3413    no such operation exists, CODE_FOR_nothing will be returned.  */
3414
3415 enum insn_code
3416 can_extend_p (to_mode, from_mode, unsignedp)
3417      enum machine_mode to_mode, from_mode;
3418      int unsignedp;
3419 {
3420   return extendtab[(int) to_mode][(int) from_mode][unsignedp];
3421 }
3422
3423 /* Generate the body of an insn to extend Y (with mode MFROM)
3424    into X (with mode MTO).  Do zero-extension if UNSIGNEDP is nonzero.  */
3425
3426 rtx
3427 gen_extend_insn (x, y, mto, mfrom, unsignedp)
3428      rtx x, y;
3429      enum machine_mode mto, mfrom;
3430      int unsignedp;
3431 {
3432   return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
3433 }
3434 \f
3435 /* can_fix_p and can_float_p say whether the target machine
3436    can directly convert a given fixed point type to
3437    a given floating point type, or vice versa.
3438    The returned value is the CODE_FOR_... value to use,
3439    or CODE_FOR_nothing if these modes cannot be directly converted.
3440
3441    *TRUNCP_PTR is set to 1 if it is necessary to output
3442    an explicit FTRUNC insn before the fix insn; otherwise 0.  */
3443
3444 static enum insn_code
3445 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
3446      enum machine_mode fltmode, fixmode;
3447      int unsignedp;
3448      int *truncp_ptr;
3449 {
3450   *truncp_ptr = 0;
3451   if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
3452     return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
3453
3454   if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
3455     {
3456       *truncp_ptr = 1;
3457       return fixtab[(int) fltmode][(int) fixmode][unsignedp];
3458     }
3459   return CODE_FOR_nothing;
3460 }
3461
3462 static enum insn_code
3463 can_float_p (fltmode, fixmode, unsignedp)
3464      enum machine_mode fixmode, fltmode;
3465      int unsignedp;
3466 {
3467   return floattab[(int) fltmode][(int) fixmode][unsignedp];
3468 }
3469 \f
3470 /* Generate code to convert FROM to floating point
3471    and store in TO.  FROM must be fixed point and not VOIDmode.
3472    UNSIGNEDP nonzero means regard FROM as unsigned.
3473    Normally this is done by correcting the final value
3474    if it is negative.  */
3475
3476 void
3477 expand_float (to, from, unsignedp)
3478      rtx to, from;
3479      int unsignedp;
3480 {
3481   enum insn_code icode;
3482   register rtx target = to;
3483   enum machine_mode fmode, imode;
3484
3485   /* Crash now, because we won't be able to decide which mode to use.  */
3486   if (GET_MODE (from) == VOIDmode)
3487     abort ();
3488
3489   /* Look for an insn to do the conversion.  Do it in the specified
3490      modes if possible; otherwise convert either input, output or both to
3491      wider mode.  If the integer mode is wider than the mode of FROM,
3492      we can do the conversion signed even if the input is unsigned.  */
3493
3494   for (imode = GET_MODE (from); imode != VOIDmode;
3495        imode = GET_MODE_WIDER_MODE (imode))
3496     for (fmode = GET_MODE (to); fmode != VOIDmode;
3497          fmode = GET_MODE_WIDER_MODE (fmode))
3498       {
3499         int doing_unsigned = unsignedp;
3500
3501         icode = can_float_p (fmode, imode, unsignedp);
3502         if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
3503           icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
3504
3505         if (icode != CODE_FOR_nothing)
3506           {
3507             to = protect_from_queue (to, 1);
3508             from = protect_from_queue (from, 0);
3509
3510             if (imode != GET_MODE (from))
3511               from = convert_to_mode (imode, from, unsignedp);
3512
3513             if (fmode != GET_MODE (to))
3514               target = gen_reg_rtx (fmode);
3515
3516             emit_unop_insn (icode, target, from,
3517                             doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
3518
3519             if (target != to)
3520               convert_move (to, target, 0);
3521             return;
3522           }
3523     }
3524
3525 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3526
3527   /* Unsigned integer, and no way to convert directly.
3528      Convert as signed, then conditionally adjust the result.  */
3529   if (unsignedp)
3530     {
3531       rtx label = gen_label_rtx ();
3532       rtx temp;
3533       REAL_VALUE_TYPE offset;
3534
3535       emit_queue ();
3536
3537       to = protect_from_queue (to, 1);
3538       from = protect_from_queue (from, 0);
3539
3540       if (flag_force_mem)
3541         from = force_not_mem (from);
3542
3543       /* Look for a usable floating mode FMODE wider than the source and at
3544          least as wide as the target.  Using FMODE will avoid rounding woes
3545          with unsigned values greater than the signed maximum value.  */
3546
3547       for (fmode = GET_MODE (to);  fmode != VOIDmode;
3548            fmode = GET_MODE_WIDER_MODE (fmode))
3549         if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
3550             && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
3551           break;
3552
3553       if (fmode == VOIDmode)
3554         {
3555           /* There is no such mode.  Pretend the target is wide enough.  */
3556           fmode = GET_MODE (to);
3557
3558           /* Avoid double-rounding when TO is narrower than FROM.  */
3559           if ((significand_size (fmode) + 1)
3560               < GET_MODE_BITSIZE (GET_MODE (from)))
3561             {
3562               rtx temp1;
3563               rtx neglabel = gen_label_rtx ();
3564
3565               /* Don't use TARGET if it isn't a register, is a hard register, 
3566                  or is the wrong mode.  */
3567               if (GET_CODE (target) != REG
3568                   || REGNO (target) < FIRST_PSEUDO_REGISTER
3569                   || GET_MODE (target) != fmode)
3570                 target = gen_reg_rtx (fmode);
3571
3572               imode = GET_MODE (from);
3573               do_pending_stack_adjust ();
3574
3575               /* Test whether the sign bit is set.  */
3576               emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, imode, 0, 0);
3577               emit_jump_insn (gen_blt (neglabel));
3578
3579               /* The sign bit is not set.  Convert as signed.  */
3580               expand_float (target, from, 0);
3581               emit_jump_insn (gen_jump (label));
3582               emit_barrier ();
3583
3584               /* The sign bit is set.
3585                  Convert to a usable (positive signed) value by shifting right
3586                  one bit, while remembering if a nonzero bit was shifted
3587                  out; i.e., compute  (from & 1) | (from >> 1).  */
3588
3589               emit_label (neglabel);
3590               temp = expand_binop (imode, and_optab, from, const1_rtx,
3591                                    NULL_RTX, 1, OPTAB_LIB_WIDEN);
3592               temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
3593                                     NULL_RTX, 1);
3594               temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1, 
3595                                    OPTAB_LIB_WIDEN);
3596               expand_float (target, temp, 0);
3597
3598               /* Multiply by 2 to undo the shift above.  */
3599               temp = expand_binop (fmode, add_optab, target, target,
3600                                      target, 0, OPTAB_LIB_WIDEN);
3601               if (temp != target)
3602                 emit_move_insn (target, temp);
3603
3604               do_pending_stack_adjust ();
3605               emit_label (label);
3606               goto done;
3607             }
3608         }
3609
3610       /* If we are about to do some arithmetic to correct for an
3611          unsigned operand, do it in a pseudo-register.  */
3612
3613       if (GET_MODE (to) != fmode
3614           || GET_CODE (to) != REG || REGNO (to) < FIRST_PSEUDO_REGISTER)
3615         target = gen_reg_rtx (fmode);
3616
3617       /* Convert as signed integer to floating.  */
3618       expand_float (target, from, 0);
3619
3620       /* If FROM is negative (and therefore TO is negative),
3621          correct its value by 2**bitwidth.  */
3622
3623       do_pending_stack_adjust ();
3624       emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, GET_MODE (from), 0, 0);
3625       emit_jump_insn (gen_bge (label));
3626
3627       /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
3628          Rather than setting up a dconst_dot_5, let's hope SCO
3629          fixes the bug.  */
3630       offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
3631       temp = expand_binop (fmode, add_optab, target,
3632                            CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
3633                            target, 0, OPTAB_LIB_WIDEN);
3634       if (temp != target)
3635         emit_move_insn (target, temp);
3636
3637       do_pending_stack_adjust ();
3638       emit_label (label);
3639       goto done;
3640     }
3641 #endif
3642
3643   /* No hardware instruction available; call a library routine to convert from
3644      SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode.  */
3645     {
3646       rtx libfcn;
3647       rtx insns;
3648       rtx value;
3649
3650       to = protect_from_queue (to, 1);
3651       from = protect_from_queue (from, 0);
3652
3653       if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
3654         from = convert_to_mode (SImode, from, unsignedp);
3655
3656       if (flag_force_mem)
3657         from = force_not_mem (from);
3658
3659       if (GET_MODE (to) == SFmode)
3660         {
3661           if (GET_MODE (from) == SImode)
3662             libfcn = floatsisf_libfunc;
3663           else if (GET_MODE (from) == DImode)
3664             libfcn = floatdisf_libfunc;
3665           else if (GET_MODE (from) == TImode)
3666             libfcn = floattisf_libfunc;
3667           else
3668             abort ();
3669         }
3670       else if (GET_MODE (to) == DFmode)
3671         {
3672           if (GET_MODE (from) == SImode)
3673             libfcn = floatsidf_libfunc;
3674           else if (GET_MODE (from) == DImode)
3675             libfcn = floatdidf_libfunc;
3676           else if (GET_MODE (from) == TImode)
3677             libfcn = floattidf_libfunc;
3678           else
3679             abort ();
3680         }
3681       else if (GET_MODE (to) == XFmode)
3682         {
3683           if (GET_MODE (from) == SImode)
3684             libfcn = floatsixf_libfunc;
3685           else if (GET_MODE (from) == DImode)
3686             libfcn = floatdixf_libfunc;
3687           else if (GET_MODE (from) == TImode)
3688             libfcn = floattixf_libfunc;
3689           else
3690             abort ();
3691         }
3692       else if (GET_MODE (to) == TFmode)
3693         {
3694           if (GET_MODE (from) == SImode)
3695             libfcn = floatsitf_libfunc;
3696           else if (GET_MODE (from) == DImode)
3697             libfcn = floatditf_libfunc;
3698           else if (GET_MODE (from) == TImode)
3699             libfcn = floattitf_libfunc;
3700           else
3701             abort ();
3702         }
3703       else
3704         abort ();
3705
3706       start_sequence ();
3707
3708       value = emit_library_call_value (libfcn, NULL_RTX, 1,
3709                                        GET_MODE (to),
3710                                        1, from, GET_MODE (from));
3711       insns = get_insns ();
3712       end_sequence ();
3713
3714       emit_libcall_block (insns, target, value,
3715                           gen_rtx (FLOAT, GET_MODE (to), from));
3716     }
3717
3718  done:
3719
3720   /* Copy result to requested destination
3721      if we have been computing in a temp location.  */
3722
3723   if (target != to)
3724     {
3725       if (GET_MODE (target) == GET_MODE (to))
3726         emit_move_insn (to, target);
3727       else
3728         convert_move (to, target, 0);
3729     }
3730 }
3731 \f
3732 /* expand_fix: generate code to convert FROM to fixed point
3733    and store in TO.  FROM must be floating point.  */
3734
3735 static rtx
3736 ftruncify (x)
3737      rtx x;
3738 {
3739   rtx temp = gen_reg_rtx (GET_MODE (x));
3740   return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
3741 }
3742
3743 void
3744 expand_fix (to, from, unsignedp)
3745      register rtx to, from;
3746      int unsignedp;
3747 {
3748   enum insn_code icode;
3749   register rtx target = to;
3750   enum machine_mode fmode, imode;
3751   int must_trunc = 0;
3752   rtx libfcn = 0;
3753
3754   /* We first try to find a pair of modes, one real and one integer, at
3755      least as wide as FROM and TO, respectively, in which we can open-code
3756      this conversion.  If the integer mode is wider than the mode of TO,
3757      we can do the conversion either signed or unsigned.  */
3758
3759   for (imode = GET_MODE (to); imode != VOIDmode;
3760        imode = GET_MODE_WIDER_MODE (imode))
3761     for (fmode = GET_MODE (from); fmode != VOIDmode;
3762          fmode = GET_MODE_WIDER_MODE (fmode))
3763       {
3764         int doing_unsigned = unsignedp;
3765
3766         icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
3767         if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
3768           icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
3769
3770         if (icode != CODE_FOR_nothing)
3771           {
3772             to = protect_from_queue (to, 1);
3773             from = protect_from_queue (from, 0);
3774
3775             if (fmode != GET_MODE (from))
3776               from = convert_to_mode (fmode, from, 0);
3777
3778             if (must_trunc)
3779               from = ftruncify (from);
3780
3781             if (imode != GET_MODE (to))
3782               target = gen_reg_rtx (imode);
3783
3784             emit_unop_insn (icode, target, from,
3785                             doing_unsigned ? UNSIGNED_FIX : FIX);
3786             if (target != to)
3787               convert_move (to, target, unsignedp);
3788             return;
3789           }
3790       }
3791
3792 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3793   /* For an unsigned conversion, there is one more way to do it.
3794      If we have a signed conversion, we generate code that compares
3795      the real value to the largest representable positive number.  If if
3796      is smaller, the conversion is done normally.  Otherwise, subtract
3797      one plus the highest signed number, convert, and add it back.
3798
3799      We only need to check all real modes, since we know we didn't find
3800      anything with a wider integer mode.  */
3801
3802   if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
3803     for (fmode = GET_MODE (from); fmode != VOIDmode;
3804          fmode = GET_MODE_WIDER_MODE (fmode))
3805       /* Make sure we won't lose significant bits doing this.  */
3806       if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
3807           && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
3808                                             &must_trunc))
3809         {
3810           int bitsize;
3811           REAL_VALUE_TYPE offset;
3812           rtx limit, lab1, lab2, insn;
3813
3814           bitsize = GET_MODE_BITSIZE (GET_MODE (to));
3815           offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
3816           limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
3817           lab1 = gen_label_rtx ();
3818           lab2 = gen_label_rtx ();
3819
3820           emit_queue ();
3821           to = protect_from_queue (to, 1);
3822           from = protect_from_queue (from, 0);
3823
3824           if (flag_force_mem)
3825             from = force_not_mem (from);
3826
3827           if (fmode != GET_MODE (from))
3828             from = convert_to_mode (fmode, from, 0);
3829
3830           /* See if we need to do the subtraction.  */
3831           do_pending_stack_adjust ();
3832           emit_cmp_insn (from, limit, GE, NULL_RTX, GET_MODE (from), 0, 0);
3833           emit_jump_insn (gen_bge (lab1));
3834
3835           /* If not, do the signed "fix" and branch around fixup code.  */
3836           expand_fix (to, from, 0);
3837           emit_jump_insn (gen_jump (lab2));
3838           emit_barrier ();
3839
3840           /* Otherwise, subtract 2**(N-1), convert to signed number,
3841              then add 2**(N-1).  Do the addition using XOR since this
3842              will often generate better code.  */
3843           emit_label (lab1);
3844           target = expand_binop (GET_MODE (from), sub_optab, from, limit,
3845                                  NULL_RTX, 0, OPTAB_LIB_WIDEN);
3846           expand_fix (to, target, 0);
3847           target = expand_binop (GET_MODE (to), xor_optab, to,
3848                                  GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
3849                                  to, 1, OPTAB_LIB_WIDEN);
3850
3851           if (target != to)
3852             emit_move_insn (to, target);
3853
3854           emit_label (lab2);
3855
3856           if (mov_optab->handlers[(int) GET_MODE (to)].insn_code
3857               != CODE_FOR_nothing)
3858             {
3859               /* Make a place for a REG_NOTE and add it.  */
3860               insn = emit_move_insn (to, to);
3861               REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
3862                                           gen_rtx (UNSIGNED_FIX, GET_MODE (to),
3863                                                    copy_rtx (from)),
3864                                           REG_NOTES (insn));
3865             }
3866           return;
3867         }
3868 #endif
3869
3870   /* We can't do it with an insn, so use a library call.  But first ensure
3871      that the mode of TO is at least as wide as SImode, since those are the
3872      only library calls we know about.  */
3873
3874   if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
3875     {
3876       target = gen_reg_rtx (SImode);
3877
3878       expand_fix (target, from, unsignedp);
3879     }
3880   else if (GET_MODE (from) == SFmode)
3881     {
3882       if (GET_MODE (to) == SImode)
3883         libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
3884       else if (GET_MODE (to) == DImode)
3885         libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
3886       else if (GET_MODE (to) == TImode)
3887         libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
3888       else
3889         abort ();
3890     }
3891   else if (GET_MODE (from) == DFmode)
3892     {
3893       if (GET_MODE (to) == SImode)
3894         libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
3895       else if (GET_MODE (to) == DImode)
3896         libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
3897       else if (GET_MODE (to) == TImode)
3898         libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
3899       else
3900         abort ();
3901     }
3902   else if (GET_MODE (from) == XFmode)
3903     {
3904       if (GET_MODE (to) == SImode)
3905         libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
3906       else if (GET_MODE (to) == DImode)
3907         libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
3908       else if (GET_MODE (to) == TImode)
3909         libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
3910       else
3911         abort ();
3912     }
3913   else if (GET_MODE (from) == TFmode)
3914     {
3915       if (GET_MODE (to) == SImode)
3916         libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
3917       else if (GET_MODE (to) == DImode)
3918         libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
3919       else if (GET_MODE (to) == TImode)
3920         libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
3921       else
3922         abort ();
3923     }
3924   else
3925     abort ();
3926
3927   if (libfcn)
3928     {
3929       rtx insns;
3930       rtx value;
3931
3932       to = protect_from_queue (to, 1);
3933       from = protect_from_queue (from, 0);
3934
3935       if (flag_force_mem)
3936         from = force_not_mem (from);
3937
3938       start_sequence ();
3939
3940       value = emit_library_call_value (libfcn, NULL_RTX, 1, GET_MODE (to),
3941
3942                                        1, from, GET_MODE (from));
3943       insns = get_insns ();
3944       end_sequence ();
3945
3946       emit_libcall_block (insns, target, value,
3947                           gen_rtx (unsignedp ? UNSIGNED_FIX : FIX,
3948                                    GET_MODE (to), from));
3949     }
3950       
3951   if (target != to)
3952     {
3953       if (GET_MODE (to) == GET_MODE (target))
3954         emit_move_insn (to, target);
3955       else
3956         convert_move (to, target, 0);
3957     }
3958 }
3959 \f
3960 static optab
3961 init_optab (code)
3962      enum rtx_code code;
3963 {
3964   int i;
3965   optab op = (optab) xmalloc (sizeof (struct optab));
3966   op->code = code;
3967   for (i = 0; i < NUM_MACHINE_MODES; i++)
3968     {
3969       op->handlers[i].insn_code = CODE_FOR_nothing;
3970       op->handlers[i].libfunc = 0;
3971     }
3972
3973   if (code != UNKNOWN)
3974     code_to_optab[(int) code] = op;
3975
3976   return op;
3977 }
3978
3979 /* Initialize the libfunc fields of an entire group of entries in some
3980    optab.  Each entry is set equal to a string consisting of a leading
3981    pair of underscores followed by a generic operation name followed by
3982    a mode name (downshifted to lower case) followed by a single character
3983    representing the number of operands for the given operation (which is
3984    usually one of the characters '2', '3', or '4').
3985
3986    OPTABLE is the table in which libfunc fields are to be initialized.
3987    FIRST_MODE is the first machine mode index in the given optab to
3988      initialize.
3989    LAST_MODE is the last machine mode index in the given optab to
3990      initialize.
3991    OPNAME is the generic (string) name of the operation.
3992    SUFFIX is the character which specifies the number of operands for
3993      the given generic operation.
3994 */
3995
3996 static void
3997 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
3998     register optab optable;
3999     register int first_mode;
4000     register int last_mode;
4001     register char *opname;
4002     register int suffix;
4003 {
4004   register int mode;
4005   register unsigned opname_len = strlen (opname);
4006
4007   for (mode = first_mode; (int) mode <= (int) last_mode;
4008        mode = (enum machine_mode) ((int) mode + 1))
4009     {
4010       register char *mname = mode_name[(int) mode];
4011       register unsigned mname_len = strlen (mname);
4012       register char *libfunc_name
4013         = (char *) xmalloc (2 + opname_len + mname_len + 1 + 1);
4014       register char *p;
4015       register char *q;
4016
4017       p = libfunc_name;
4018       *p++ = '_';
4019       *p++ = '_';
4020       for (q = opname; *q; )
4021         *p++ = *q++;
4022       for (q = mname; *q; q++)
4023         *p++ = tolower (*q);
4024       *p++ = suffix;
4025       *p++ = '\0';
4026       optable->handlers[(int) mode].libfunc
4027         = gen_rtx (SYMBOL_REF, Pmode, libfunc_name);
4028     }
4029 }
4030
4031 /* Initialize the libfunc fields of an entire group of entries in some
4032    optab which correspond to all integer mode operations.  The parameters
4033    have the same meaning as similarly named ones for the `init_libfuncs'
4034    routine.  (See above).  */
4035
4036 static void
4037 init_integral_libfuncs (optable, opname, suffix)
4038     register optab optable;
4039     register char *opname;
4040     register int suffix;
4041 {
4042   init_libfuncs (optable, SImode, TImode, opname, suffix);
4043 }
4044
4045 /* Initialize the libfunc fields of an entire group of entries in some
4046    optab which correspond to all real mode operations.  The parameters
4047    have the same meaning as similarly named ones for the `init_libfuncs'
4048    routine.  (See above).  */
4049
4050 static void
4051 init_floating_libfuncs (optable, opname, suffix)
4052     register optab optable;
4053     register char *opname;
4054     register int suffix;
4055 {
4056   init_libfuncs (optable, SFmode, TFmode, opname, suffix);
4057 }
4058
4059
4060 /* Call this once to initialize the contents of the optabs
4061    appropriately for the current target machine.  */
4062
4063 void
4064 init_optabs ()
4065 {
4066   int i;
4067 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4068   int j;
4069 #endif
4070
4071   enum insn_code *p;
4072
4073   /* Start by initializing all tables to contain CODE_FOR_nothing.  */
4074
4075   for (p = fixtab[0][0];
4076        p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]); 
4077        p++)
4078     *p = CODE_FOR_nothing;
4079
4080   for (p = fixtrunctab[0][0];
4081        p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]); 
4082        p++)
4083     *p = CODE_FOR_nothing;
4084
4085   for (p = floattab[0][0];
4086        p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]); 
4087        p++)
4088     *p = CODE_FOR_nothing;
4089
4090   for (p = extendtab[0][0];
4091        p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
4092        p++)
4093     *p = CODE_FOR_nothing;
4094
4095   for (i = 0; i < NUM_RTX_CODE; i++)
4096     setcc_gen_code[i] = CODE_FOR_nothing;
4097
4098 #ifdef HAVE_conditional_move
4099   for (i = 0; i < NUM_MACHINE_MODES; i++)
4100     movcc_gen_code[i] = CODE_FOR_nothing;
4101 #endif
4102
4103   add_optab = init_optab (PLUS);
4104   sub_optab = init_optab (MINUS);
4105   smul_optab = init_optab (MULT);
4106   smul_highpart_optab = init_optab (UNKNOWN);
4107   umul_highpart_optab = init_optab (UNKNOWN);
4108   smul_widen_optab = init_optab (UNKNOWN);
4109   umul_widen_optab = init_optab (UNKNOWN);
4110   sdiv_optab = init_optab (DIV);
4111   sdivmod_optab = init_optab (UNKNOWN);
4112   udiv_optab = init_optab (UDIV);
4113   udivmod_optab = init_optab (UNKNOWN);
4114   smod_optab = init_optab (MOD);
4115   umod_optab = init_optab (UMOD);
4116   flodiv_optab = init_optab (DIV);
4117   ftrunc_optab = init_optab (UNKNOWN);
4118   and_optab = init_optab (AND);
4119   ior_optab = init_optab (IOR);
4120   xor_optab = init_optab (XOR);
4121   ashl_optab = init_optab (ASHIFT);
4122   ashr_optab = init_optab (ASHIFTRT);
4123   lshr_optab = init_optab (LSHIFTRT);
4124   rotl_optab = init_optab (ROTATE);
4125   rotr_optab = init_optab (ROTATERT);
4126   smin_optab = init_optab (SMIN);
4127   smax_optab = init_optab (SMAX);
4128   umin_optab = init_optab (UMIN);
4129   umax_optab = init_optab (UMAX);
4130   mov_optab = init_optab (UNKNOWN);
4131   movstrict_optab = init_optab (UNKNOWN);
4132   cmp_optab = init_optab (UNKNOWN);
4133   ucmp_optab = init_optab (UNKNOWN);
4134   tst_optab = init_optab (UNKNOWN);
4135   neg_optab = init_optab (NEG);
4136   abs_optab = init_optab (ABS);
4137   one_cmpl_optab = init_optab (NOT);
4138   ffs_optab = init_optab (FFS);
4139   sqrt_optab = init_optab (SQRT);
4140   sin_optab = init_optab (UNKNOWN);
4141   cos_optab = init_optab (UNKNOWN);
4142   strlen_optab = init_optab (UNKNOWN);
4143
4144   for (i = 0; i < NUM_MACHINE_MODES; i++)
4145     {
4146       movstr_optab[i] = CODE_FOR_nothing;
4147       clrstr_optab[i] = CODE_FOR_nothing;
4148
4149 #ifdef HAVE_SECONDARY_RELOADS
4150       reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
4151 #endif
4152     }
4153
4154   /* Fill in the optabs with the insns we support.  */
4155   init_all_optabs ();
4156
4157 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4158   /* This flag says the same insns that convert to a signed fixnum
4159      also convert validly to an unsigned one.  */
4160   for (i = 0; i < NUM_MACHINE_MODES; i++)
4161     for (j = 0; j < NUM_MACHINE_MODES; j++)
4162       fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
4163 #endif
4164
4165 #ifdef EXTRA_CC_MODES
4166   init_mov_optab ();
4167 #endif
4168
4169   /* Initialize the optabs with the names of the library functions.  */
4170   init_integral_libfuncs (add_optab, "add", '3');
4171   init_floating_libfuncs (add_optab, "add", '3');
4172   init_integral_libfuncs (sub_optab, "sub", '3');
4173   init_floating_libfuncs (sub_optab, "sub", '3');
4174   init_integral_libfuncs (smul_optab, "mul", '3');
4175   init_floating_libfuncs (smul_optab, "mul", '3');
4176   init_integral_libfuncs (sdiv_optab, "div", '3');
4177   init_integral_libfuncs (udiv_optab, "udiv", '3');
4178   init_integral_libfuncs (sdivmod_optab, "divmod", '4');
4179   init_integral_libfuncs (udivmod_optab, "udivmod", '4');
4180   init_integral_libfuncs (smod_optab, "mod", '3');
4181   init_integral_libfuncs (umod_optab, "umod", '3');
4182   init_floating_libfuncs (flodiv_optab, "div", '3');
4183   init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
4184   init_integral_libfuncs (and_optab, "and", '3');
4185   init_integral_libfuncs (ior_optab, "ior", '3');
4186   init_integral_libfuncs (xor_optab, "xor", '3');
4187   init_integral_libfuncs (ashl_optab, "ashl", '3');
4188   init_integral_libfuncs (ashr_optab, "ashr", '3');
4189   init_integral_libfuncs (lshr_optab, "lshr", '3');
4190   init_integral_libfuncs (smin_optab, "min", '3');
4191   init_floating_libfuncs (smin_optab, "min", '3');
4192   init_integral_libfuncs (smax_optab, "max", '3');
4193   init_floating_libfuncs (smax_optab, "max", '3');
4194   init_integral_libfuncs (umin_optab, "umin", '3');
4195   init_integral_libfuncs (umax_optab, "umax", '3');
4196   init_integral_libfuncs (neg_optab, "neg", '2');
4197   init_floating_libfuncs (neg_optab, "neg", '2');
4198   init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
4199   init_integral_libfuncs (ffs_optab, "ffs", '2');
4200
4201   /* Comparison libcalls for integers MUST come in pairs, signed/unsigned.  */
4202   init_integral_libfuncs (cmp_optab, "cmp", '2');
4203   init_integral_libfuncs (ucmp_optab, "ucmp", '2');
4204   init_floating_libfuncs (cmp_optab, "cmp", '2');
4205
4206 #ifdef MULSI3_LIBCALL
4207   smul_optab->handlers[(int) SImode].libfunc
4208     = gen_rtx (SYMBOL_REF, Pmode, MULSI3_LIBCALL);
4209 #endif
4210 #ifdef MULDI3_LIBCALL
4211   smul_optab->handlers[(int) DImode].libfunc
4212     = gen_rtx (SYMBOL_REF, Pmode, MULDI3_LIBCALL);
4213 #endif
4214
4215 #ifdef DIVSI3_LIBCALL
4216   sdiv_optab->handlers[(int) SImode].libfunc
4217     = gen_rtx (SYMBOL_REF, Pmode, DIVSI3_LIBCALL);
4218 #endif
4219 #ifdef DIVDI3_LIBCALL
4220   sdiv_optab->handlers[(int) DImode].libfunc
4221     = gen_rtx (SYMBOL_REF, Pmode, DIVDI3_LIBCALL);
4222 #endif
4223
4224 #ifdef UDIVSI3_LIBCALL
4225   udiv_optab->handlers[(int) SImode].libfunc
4226     = gen_rtx (SYMBOL_REF, Pmode, UDIVSI3_LIBCALL);
4227 #endif
4228 #ifdef UDIVDI3_LIBCALL
4229   udiv_optab->handlers[(int) DImode].libfunc
4230     = gen_rtx (SYMBOL_REF, Pmode, UDIVDI3_LIBCALL);
4231 #endif
4232
4233 #ifdef MODSI3_LIBCALL
4234   smod_optab->handlers[(int) SImode].libfunc
4235     = gen_rtx (SYMBOL_REF, Pmode, MODSI3_LIBCALL);
4236 #endif
4237 #ifdef MODDI3_LIBCALL
4238   smod_optab->handlers[(int) DImode].libfunc
4239     = gen_rtx (SYMBOL_REF, Pmode, MODDI3_LIBCALL);
4240 #endif
4241
4242 #ifdef UMODSI3_LIBCALL
4243   umod_optab->handlers[(int) SImode].libfunc
4244     = gen_rtx (SYMBOL_REF, Pmode, UMODSI3_LIBCALL);
4245 #endif
4246 #ifdef UMODDI3_LIBCALL
4247   umod_optab->handlers[(int) DImode].libfunc
4248     = gen_rtx (SYMBOL_REF, Pmode, UMODDI3_LIBCALL);
4249 #endif
4250
4251   /* Use cabs for DC complex abs, since systems generally have cabs.
4252      Don't define any libcall for SCmode, so that cabs will be used.  */
4253   abs_optab->handlers[(int) DCmode].libfunc
4254     = gen_rtx (SYMBOL_REF, Pmode, "cabs");
4255
4256   /* The ffs function operates on `int'.  */
4257 #ifndef INT_TYPE_SIZE
4258 #define INT_TYPE_SIZE BITS_PER_WORD
4259 #endif
4260   ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)] .libfunc
4261     = gen_rtx (SYMBOL_REF, Pmode, "ffs");
4262
4263   extendsfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfdf2");
4264   extendsfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfxf2");
4265   extendsftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsftf2");
4266   extenddfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddfxf2");
4267   extenddftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddftf2");
4268
4269   truncdfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncdfsf2");
4270   truncxfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfsf2");
4271   trunctfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfsf2");
4272   truncxfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfdf2");
4273   trunctfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfdf2");
4274
4275   memcpy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcpy");
4276   bcopy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcopy");
4277   memcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcmp");
4278   bcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gcc_bcmp");
4279   memset_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memset");
4280   bzero_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bzero");
4281
4282   throw_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__throw");
4283   sjthrow_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__sjthrow");
4284   sjpopnthrow_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__sjpopnthrow");
4285   terminate_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__terminate");
4286 #ifndef DONT_USE_BUILTIN_SETJMP
4287   setjmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__builtin_setjmp");
4288   longjmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__builtin_longjmp");
4289 #else
4290   setjmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "setjmp");
4291   longjmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "longjmp");
4292 #endif
4293
4294   eqhf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqhf2");
4295   nehf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nehf2");
4296   gthf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gthf2");
4297   gehf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gehf2");
4298   lthf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lthf2");
4299   lehf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lehf2");
4300
4301   eqsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqsf2");
4302   nesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nesf2");
4303   gtsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtsf2");
4304   gesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gesf2");
4305   ltsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltsf2");
4306   lesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lesf2");
4307
4308   eqdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqdf2");
4309   nedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nedf2");
4310   gtdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtdf2");
4311   gedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gedf2");
4312   ltdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltdf2");
4313   ledf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ledf2");
4314
4315   eqxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqxf2");
4316   nexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nexf2");
4317   gtxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtxf2");
4318   gexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gexf2");
4319   ltxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltxf2");
4320   lexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lexf2");
4321
4322   eqtf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqtf2");
4323   netf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__netf2");
4324   gttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gttf2");
4325   getf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__getf2");
4326   lttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lttf2");
4327   letf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__letf2");
4328
4329   floatsisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsisf");
4330   floatdisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdisf");
4331   floattisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattisf");
4332
4333   floatsidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsidf");
4334   floatdidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdidf");
4335   floattidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattidf");
4336
4337   floatsixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsixf");
4338   floatdixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdixf");
4339   floattixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattixf");
4340
4341   floatsitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsitf");
4342   floatditf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatditf");
4343   floattitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattitf");
4344
4345   fixsfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfsi");
4346   fixsfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfdi");
4347   fixsfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfti");
4348
4349   fixdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfsi");
4350   fixdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfdi");
4351   fixdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfti");
4352
4353   fixxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfsi");
4354   fixxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfdi");
4355   fixxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfti");
4356
4357   fixtfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfsi");
4358   fixtfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfdi");
4359   fixtfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfti");
4360
4361   fixunssfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfsi");
4362   fixunssfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfdi");
4363   fixunssfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfti");
4364
4365   fixunsdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfsi");
4366   fixunsdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfdi");
4367   fixunsdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfti");
4368
4369   fixunsxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfsi");
4370   fixunsxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfdi");
4371   fixunsxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfti");
4372
4373   fixunstfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfsi");
4374   fixunstfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfdi");
4375   fixunstfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfti");
4376
4377   /* For check-memory-usage.  */
4378   chkr_check_addr_libfunc = gen_rtx (SYMBOL_REF, VOIDmode, "chkr_check_addr");
4379   chkr_set_right_libfunc = gen_rtx (SYMBOL_REF, VOIDmode, "chkr_set_right");
4380   chkr_copy_bitmap_libfunc = gen_rtx (SYMBOL_REF, VOIDmode, "chkr_copy_bitmap");
4381   chkr_check_exec_libfunc = gen_rtx (SYMBOL_REF, VOIDmode, "chkr_check_exec");
4382   chkr_check_str_libfunc = gen_rtx (SYMBOL_REF, VOIDmode, "chkr_check_str");
4383
4384 #ifdef INIT_TARGET_OPTABS
4385   /* Allow the target to add more libcalls or rename some, etc.  */
4386   INIT_TARGET_OPTABS;
4387 #endif
4388 }
4389 \f
4390 #ifdef BROKEN_LDEXP
4391
4392 /* SCO 3.2 apparently has a broken ldexp.  */
4393
4394 double
4395 ldexp(x,n)
4396      double x;
4397      int n;
4398 {
4399   if (n > 0)
4400     while (n--)
4401       x *= 2;
4402
4403   return x;
4404 }
4405 #endif /* BROKEN_LDEXP */