OSDN Git Service

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