OSDN Git Service

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