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