OSDN Git Service

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