OSDN Git Service

2002-07-10 Toon Moene <toon@moene.indiv.nluug.nl>
[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       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     {    
2054       rtx temp;
2055       temp = expand_binop (mode, sub_optab, CONST0_RTX (mode), op0,
2056                            target, unsignedp, OPTAB_DIRECT);
2057       if (temp)
2058         return temp;
2059     }
2060
2061   if (unoptab == one_cmpl_optab)
2062     {
2063       tmode = int_mode_for_mode (mode);
2064       if (tmode != BLKmode)
2065         submode = tmode;
2066     }
2067
2068   subsize = GET_MODE_SIZE (submode);
2069   subbitsize = GET_MODE_BITSIZE (submode);
2070   elts = size / subsize;
2071
2072   /* Errors can leave us with a const0_rtx as operand.  */
2073   if (GET_MODE (op0) != mode)
2074     op0 = copy_to_mode_reg (mode, op0);
2075
2076   if (!target)
2077     target = gen_reg_rtx (mode);
2078
2079   start_sequence ();
2080
2081   for (i = 0; i < elts; ++i)
2082     {
2083       /* If this is part of a register, and not the first item in the
2084          word, we can't store using a SUBREG - that would clobber
2085          previous results.
2086          And storing with a SUBREG is only possible for the least
2087          significant part, hence we can't do it for big endian
2088          (unless we want to permute the evaluation order.  */
2089       if (GET_CODE (target) == REG
2090           && (BYTES_BIG_ENDIAN
2091               ?  subsize < UNITS_PER_WORD
2092               : ((i * subsize) % UNITS_PER_WORD) != 0))
2093         t = NULL_RTX;
2094       else
2095         t = simplify_gen_subreg (submode, target, mode, i * subsize);
2096       if (CONSTANT_P (op0))
2097         a = simplify_gen_subreg (submode, op0, mode, i * subsize);
2098       else
2099         a = extract_bit_field (op0, subbitsize, i * subbitsize, unsignedp,
2100                                t, submode, submode, size);
2101
2102       res = expand_unop (submode, unoptab, a, t, unsignedp);
2103
2104       if (t)
2105         emit_move_insn (t, res);
2106       else
2107         store_bit_field (target, subbitsize, i * subbitsize, submode, res,
2108                          size);
2109     }
2110
2111   seq = get_insns ();
2112   end_sequence ();
2113   emit_insn (seq);
2114
2115   return target;
2116 }
2117 \f
2118 /* Expand a binary operator which has both signed and unsigned forms.
2119    UOPTAB is the optab for unsigned operations, and SOPTAB is for
2120    signed operations.
2121
2122    If we widen unsigned operands, we may use a signed wider operation instead
2123    of an unsigned wider operation, since the result would be the same.  */
2124
2125 rtx
2126 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
2127     enum machine_mode mode;
2128     optab uoptab, soptab;
2129     rtx op0, op1, target;
2130     int unsignedp;
2131     enum optab_methods methods;
2132 {
2133   rtx temp;
2134   optab direct_optab = unsignedp ? uoptab : soptab;
2135   struct optab wide_soptab;
2136
2137   /* Do it without widening, if possible.  */
2138   temp = expand_binop (mode, direct_optab, op0, op1, target,
2139                        unsignedp, OPTAB_DIRECT);
2140   if (temp || methods == OPTAB_DIRECT)
2141     return temp;
2142
2143   /* Try widening to a signed int.  Make a fake signed optab that
2144      hides any signed insn for direct use.  */
2145   wide_soptab = *soptab;
2146   wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
2147   wide_soptab.handlers[(int) mode].libfunc = 0;
2148
2149   temp = expand_binop (mode, &wide_soptab, op0, op1, target,
2150                        unsignedp, OPTAB_WIDEN);
2151
2152   /* For unsigned operands, try widening to an unsigned int.  */
2153   if (temp == 0 && unsignedp)
2154     temp = expand_binop (mode, uoptab, op0, op1, target,
2155                          unsignedp, OPTAB_WIDEN);
2156   if (temp || methods == OPTAB_WIDEN)
2157     return temp;
2158
2159   /* Use the right width lib call if that exists.  */
2160   temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
2161   if (temp || methods == OPTAB_LIB)
2162     return temp;
2163
2164   /* Must widen and use a lib call, use either signed or unsigned.  */
2165   temp = expand_binop (mode, &wide_soptab, op0, op1, target,
2166                        unsignedp, methods);
2167   if (temp != 0)
2168     return temp;
2169   if (unsignedp)
2170     return expand_binop (mode, uoptab, op0, op1, target,
2171                          unsignedp, methods);
2172   return 0;
2173 }
2174 \f
2175 /* Generate code to perform an operation specified by BINOPTAB
2176    on operands OP0 and OP1, with two results to TARG1 and TARG2.
2177    We assume that the order of the operands for the instruction
2178    is TARG0, OP0, OP1, TARG1, which would fit a pattern like
2179    [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
2180
2181    Either TARG0 or TARG1 may be zero, but what that means is that
2182    the result is not actually wanted.  We will generate it into
2183    a dummy pseudo-reg and discard it.  They may not both be zero.
2184
2185    Returns 1 if this operation can be performed; 0 if not.  */
2186
2187 int
2188 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
2189      optab binoptab;
2190      rtx op0, op1;
2191      rtx targ0, targ1;
2192      int unsignedp;
2193 {
2194   enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2195   enum mode_class class;
2196   enum machine_mode wider_mode;
2197   rtx entry_last = get_last_insn ();
2198   rtx last;
2199
2200   class = GET_MODE_CLASS (mode);
2201
2202   op0 = protect_from_queue (op0, 0);
2203   op1 = protect_from_queue (op1, 0);
2204
2205   if (flag_force_mem)
2206     {
2207       op0 = force_not_mem (op0);
2208       op1 = force_not_mem (op1);
2209     }
2210
2211   /* If we are inside an appropriately-short loop and one operand is an
2212      expensive constant, force it into a register.  */
2213   if (CONSTANT_P (op0) && preserve_subexpressions_p ()
2214       && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
2215     op0 = force_reg (mode, op0);
2216
2217   if (CONSTANT_P (op1) && preserve_subexpressions_p ()
2218       && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1))
2219     op1 = force_reg (mode, op1);
2220
2221   if (targ0)
2222     targ0 = protect_from_queue (targ0, 1);
2223   else
2224     targ0 = gen_reg_rtx (mode);
2225   if (targ1)
2226     targ1 = protect_from_queue (targ1, 1);
2227   else
2228     targ1 = gen_reg_rtx (mode);
2229
2230   /* Record where to go back to if we fail.  */
2231   last = get_last_insn ();
2232
2233   if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2234     {
2235       int icode = (int) binoptab->handlers[(int) mode].insn_code;
2236       enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2237       enum machine_mode mode1 = insn_data[icode].operand[2].mode;
2238       rtx pat;
2239       rtx xop0 = op0, xop1 = op1;
2240
2241       /* In case this insn wants input operands in modes different from the
2242          result, convert the operands.  */
2243       if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
2244         xop0 = convert_to_mode (mode0, xop0, unsignedp);
2245
2246       if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
2247         xop1 = convert_to_mode (mode1, xop1, unsignedp);
2248
2249       /* Now, if insn doesn't accept these operands, put them into pseudos.  */
2250       if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
2251         xop0 = copy_to_mode_reg (mode0, xop0);
2252
2253       if (! (*insn_data[icode].operand[2].predicate) (xop1, mode1))
2254         xop1 = copy_to_mode_reg (mode1, xop1);
2255
2256       /* We could handle this, but we should always be called with a pseudo
2257          for our targets and all insns should take them as outputs.  */
2258       if (! (*insn_data[icode].operand[0].predicate) (targ0, mode)
2259           || ! (*insn_data[icode].operand[3].predicate) (targ1, mode))
2260         abort ();
2261         
2262       pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
2263       if (pat)
2264         {
2265           emit_insn (pat);
2266           return 1;
2267         }
2268       else
2269         delete_insns_since (last);
2270     }
2271
2272   /* It can't be done in this mode.  Can we do it in a wider mode?  */
2273
2274   if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2275     {
2276       for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2277            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2278         {
2279           if (binoptab->handlers[(int) wider_mode].insn_code
2280               != CODE_FOR_nothing)
2281             {
2282               rtx t0 = gen_reg_rtx (wider_mode);
2283               rtx t1 = gen_reg_rtx (wider_mode);
2284               rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2285               rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp);
2286
2287               if (expand_twoval_binop (binoptab, cop0, cop1,
2288                                        t0, t1, unsignedp))
2289                 {
2290                   convert_move (targ0, t0, unsignedp);
2291                   convert_move (targ1, t1, unsignedp);
2292                   return 1;
2293                 }
2294               else
2295                 delete_insns_since (last);
2296             }
2297         }
2298     }
2299
2300   delete_insns_since (entry_last);
2301   return 0;
2302 }
2303 \f
2304 /* Wrapper around expand_unop which takes an rtx code to specify
2305    the operation to perform, not an optab pointer.  All other
2306    arguments are the same.  */
2307 rtx
2308 expand_simple_unop (mode, code, op0, target, unsignedp)
2309      enum machine_mode mode;
2310      enum rtx_code code;
2311      rtx op0;
2312      rtx target;
2313      int unsignedp;
2314 {
2315   optab unop = code_to_optab [(int) code];
2316   if (unop == 0)
2317     abort ();
2318
2319   return expand_unop (mode, unop, op0, target, unsignedp);
2320 }
2321
2322 /* Generate code to perform an operation specified by UNOPTAB
2323    on operand OP0, with result having machine-mode MODE.
2324
2325    UNSIGNEDP is for the case where we have to widen the operands
2326    to perform the operation.  It says to use zero-extension.
2327
2328    If TARGET is nonzero, the value
2329    is generated there, if it is convenient to do so.
2330    In all cases an rtx is returned for the locus of the value;
2331    this may or may not be TARGET.  */
2332
2333 rtx
2334 expand_unop (mode, unoptab, op0, target, unsignedp)
2335      enum machine_mode mode;
2336      optab unoptab;
2337      rtx op0;
2338      rtx target;
2339      int unsignedp;
2340 {
2341   enum mode_class class;
2342   enum machine_mode wider_mode;
2343   rtx temp;
2344   rtx last = get_last_insn ();
2345   rtx pat;
2346
2347   class = GET_MODE_CLASS (mode);
2348
2349   op0 = protect_from_queue (op0, 0);
2350
2351   if (flag_force_mem)
2352     {
2353       op0 = force_not_mem (op0);
2354     }
2355
2356   if (target)
2357     target = protect_from_queue (target, 1);
2358
2359   if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2360     {
2361       int icode = (int) unoptab->handlers[(int) mode].insn_code;
2362       enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2363       rtx xop0 = op0;
2364
2365       if (target)
2366         temp = target;
2367       else
2368         temp = gen_reg_rtx (mode);
2369
2370       if (GET_MODE (xop0) != VOIDmode
2371           && GET_MODE (xop0) != mode0)
2372         xop0 = convert_to_mode (mode0, xop0, unsignedp);
2373
2374       /* Now, if insn doesn't accept our operand, put it into a pseudo.  */
2375
2376       if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
2377         xop0 = copy_to_mode_reg (mode0, xop0);
2378
2379       if (! (*insn_data[icode].operand[0].predicate) (temp, mode))
2380         temp = gen_reg_rtx (mode);
2381
2382       pat = GEN_FCN (icode) (temp, xop0);
2383       if (pat)
2384         {
2385           if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
2386               && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
2387             {
2388               delete_insns_since (last);
2389               return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
2390             }
2391
2392           emit_insn (pat);
2393           
2394           return temp;
2395         }
2396       else
2397         delete_insns_since (last);
2398     }
2399
2400   /* It can't be done in this mode.  Can we open-code it in a wider mode?  */
2401
2402   if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2403     for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2404          wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2405       {
2406         if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2407           {
2408             rtx xop0 = op0;
2409
2410             /* For certain operations, we need not actually extend
2411                the narrow operand, as long as we will truncate the
2412                results to the same narrowness.  */
2413
2414             xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2415                                   (unoptab == neg_optab
2416                                    || unoptab == one_cmpl_optab)
2417                                   && class == MODE_INT);
2418               
2419             temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2420                                 unsignedp);
2421
2422             if (temp)
2423               {
2424                 if (class != MODE_INT)
2425                   {
2426                     if (target == 0)
2427                       target = gen_reg_rtx (mode);
2428                     convert_move (target, temp, 0);
2429                     return target;
2430                   }
2431                 else
2432                   return gen_lowpart (mode, temp);
2433               }
2434             else
2435               delete_insns_since (last);
2436           }
2437       }
2438
2439   /* These can be done a word at a time.  */
2440   if (unoptab == one_cmpl_optab
2441       && class == MODE_INT
2442       && GET_MODE_SIZE (mode) > UNITS_PER_WORD
2443       && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
2444     {
2445       int i;
2446       rtx insns;
2447
2448       if (target == 0 || target == op0)
2449         target = gen_reg_rtx (mode);
2450
2451       start_sequence ();
2452
2453       /* Do the actual arithmetic.  */
2454       for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
2455         {
2456           rtx target_piece = operand_subword (target, i, 1, mode);
2457           rtx x = expand_unop (word_mode, unoptab,
2458                                operand_subword_force (op0, i, mode),
2459                                target_piece, unsignedp);
2460
2461           if (target_piece != x)
2462             emit_move_insn (target_piece, x);
2463         }
2464
2465       insns = get_insns ();
2466       end_sequence ();
2467
2468       emit_no_conflict_block (insns, target, op0, NULL_RTX,
2469                               gen_rtx_fmt_e (unoptab->code, mode,
2470                                              copy_rtx (op0)));
2471       return target;
2472     }
2473
2474   /* Open-code the complex negation operation.  */
2475   else if (unoptab->code == NEG
2476            && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT))
2477     {
2478       rtx target_piece;
2479       rtx x;
2480       rtx seq;
2481
2482       /* Find the correct mode for the real and imaginary parts */
2483       enum machine_mode submode
2484         = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
2485                          class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
2486                          0);
2487
2488       if (submode == BLKmode)
2489         abort ();
2490
2491       if (target == 0)
2492         target = gen_reg_rtx (mode);
2493       
2494       start_sequence ();
2495
2496       target_piece = gen_imagpart (submode, target);
2497       x = expand_unop (submode, unoptab,
2498                        gen_imagpart (submode, op0),
2499                        target_piece, unsignedp);
2500       if (target_piece != x)
2501         emit_move_insn (target_piece, x);
2502
2503       target_piece = gen_realpart (submode, target);
2504       x = expand_unop (submode, unoptab,
2505                        gen_realpart (submode, op0),
2506                        target_piece, unsignedp);
2507       if (target_piece != x)
2508         emit_move_insn (target_piece, x);
2509
2510       seq = get_insns ();
2511       end_sequence ();
2512
2513       emit_no_conflict_block (seq, target, op0, 0,
2514                               gen_rtx_fmt_e (unoptab->code, mode,
2515                                              copy_rtx (op0)));
2516       return target;
2517     }
2518
2519   /* Now try a library call in this mode.  */
2520   if (unoptab->handlers[(int) mode].libfunc)
2521     {
2522       rtx insns;
2523       rtx value;
2524
2525       start_sequence ();
2526
2527       /* Pass 1 for NO_QUEUE so we don't lose any increments
2528          if the libcall is cse'd or moved.  */
2529       value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
2530                                        NULL_RTX, LCT_CONST, mode, 1, op0, mode);
2531       insns = get_insns ();
2532       end_sequence ();
2533
2534       target = gen_reg_rtx (mode);
2535       emit_libcall_block (insns, target, value,
2536                           gen_rtx_fmt_e (unoptab->code, mode, op0));
2537
2538       return target;
2539     }
2540
2541   if (class == MODE_VECTOR_FLOAT || class == MODE_VECTOR_INT)
2542     return expand_vector_unop (mode, unoptab, op0, target, unsignedp);
2543
2544   /* It can't be done in this mode.  Can we do it in a wider mode?  */
2545
2546   if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2547     {
2548       for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2549            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2550         {
2551           if ((unoptab->handlers[(int) wider_mode].insn_code
2552                != CODE_FOR_nothing)
2553               || unoptab->handlers[(int) wider_mode].libfunc)
2554             {
2555               rtx xop0 = op0;
2556
2557               /* For certain operations, we need not actually extend
2558                  the narrow operand, as long as we will truncate the
2559                  results to the same narrowness.  */
2560
2561               xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2562                                     (unoptab == neg_optab
2563                                      || unoptab == one_cmpl_optab)
2564                                     && class == MODE_INT);
2565               
2566               temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2567                                   unsignedp);
2568
2569               if (temp)
2570                 {
2571                   if (class != MODE_INT)
2572                     {
2573                       if (target == 0)
2574                         target = gen_reg_rtx (mode);
2575                       convert_move (target, temp, 0);
2576                       return target;
2577                     }
2578                   else
2579                     return gen_lowpart (mode, temp);
2580                 }
2581               else
2582                 delete_insns_since (last);
2583             }
2584         }
2585     }
2586
2587   /* If there is no negate operation, try doing a subtract from zero.
2588      The US Software GOFAST library needs this.  */
2589   if (unoptab->code == NEG)
2590     {    
2591       rtx temp;
2592       temp = expand_binop (mode,
2593                            unoptab == negv_optab ? subv_optab : sub_optab,
2594                            CONST0_RTX (mode), op0,
2595                            target, unsignedp, OPTAB_LIB_WIDEN);
2596       if (temp)
2597         return temp;
2598     }
2599       
2600   return 0;
2601 }
2602 \f
2603 /* Emit code to compute the absolute value of OP0, with result to
2604    TARGET if convenient.  (TARGET may be 0.)  The return value says
2605    where the result actually is to be found.
2606
2607    MODE is the mode of the operand; the mode of the result is
2608    different but can be deduced from MODE.
2609
2610  */
2611
2612 rtx
2613 expand_abs (mode, op0, target, result_unsignedp, safe)
2614      enum machine_mode mode;
2615      rtx op0;
2616      rtx target;
2617      int result_unsignedp;
2618      int safe;
2619 {
2620   rtx temp, op1;
2621
2622   if (! flag_trapv)
2623     result_unsignedp = 1;
2624
2625   /* First try to do it with a special abs instruction.  */
2626   temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
2627                       op0, target, 0);
2628   if (temp != 0)
2629     return temp;
2630
2631   /* If we have a MAX insn, we can do this as MAX (x, -x).  */
2632   if (smax_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2633     {
2634       rtx last = get_last_insn ();
2635
2636       temp = expand_unop (mode, neg_optab, op0, NULL_RTX, 0);
2637       if (temp != 0)
2638         temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
2639                              OPTAB_WIDEN);
2640
2641       if (temp != 0)
2642         return temp;
2643
2644       delete_insns_since (last);
2645     }
2646
2647   /* If this machine has expensive jumps, we can do integer absolute
2648      value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2649      where W is the width of MODE.  */
2650
2651   if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
2652     {
2653       rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
2654                                    size_int (GET_MODE_BITSIZE (mode) - 1),
2655                                    NULL_RTX, 0);
2656
2657       temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
2658                            OPTAB_LIB_WIDEN);
2659       if (temp != 0)
2660         temp = expand_binop (mode, result_unsignedp ? sub_optab : subv_optab,
2661                              temp, extended, target, 0, OPTAB_LIB_WIDEN);
2662
2663       if (temp != 0)
2664         return temp;
2665     }
2666
2667   /* If that does not win, use conditional jump and negate.  */
2668
2669   /* It is safe to use the target if it is the same
2670      as the source if this is also a pseudo register */
2671   if (op0 == target && GET_CODE (op0) == REG
2672       && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
2673     safe = 1;
2674
2675   op1 = gen_label_rtx ();
2676   if (target == 0 || ! safe
2677       || GET_MODE (target) != mode
2678       || (GET_CODE (target) == MEM && MEM_VOLATILE_P (target))
2679       || (GET_CODE (target) == REG
2680           && REGNO (target) < FIRST_PSEUDO_REGISTER))
2681     target = gen_reg_rtx (mode);
2682
2683   emit_move_insn (target, op0);
2684   NO_DEFER_POP;
2685
2686   /* If this mode is an integer too wide to compare properly,
2687      compare word by word.  Rely on CSE to optimize constant cases.  */
2688   if (GET_MODE_CLASS (mode) == MODE_INT
2689       && ! can_compare_p (GE, mode, ccp_jump))
2690     do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx, 
2691                                   NULL_RTX, op1);
2692   else
2693     do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
2694                              NULL_RTX, NULL_RTX, op1);
2695
2696   op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
2697                      target, target, 0);
2698   if (op0 != target)
2699     emit_move_insn (target, op0);
2700   emit_label (op1);
2701   OK_DEFER_POP;
2702   return target;
2703 }
2704 \f
2705 /* Emit code to compute the absolute value of OP0, with result to
2706    TARGET if convenient.  (TARGET may be 0.)  The return value says
2707    where the result actually is to be found.
2708
2709    MODE is the mode of the operand; the mode of the result is
2710    different but can be deduced from MODE.
2711
2712    UNSIGNEDP is relevant for complex integer modes.  */
2713
2714 rtx
2715 expand_complex_abs (mode, op0, target, unsignedp)
2716      enum machine_mode mode;
2717      rtx op0;
2718      rtx target;
2719      int unsignedp;
2720 {
2721   enum mode_class class = GET_MODE_CLASS (mode);
2722   enum machine_mode wider_mode;
2723   rtx temp;
2724   rtx entry_last = get_last_insn ();
2725   rtx last;
2726   rtx pat;
2727   optab this_abs_optab;
2728
2729   /* Find the correct mode for the real and imaginary parts.  */
2730   enum machine_mode submode
2731     = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
2732                      class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
2733                      0);
2734
2735   if (submode == BLKmode)
2736     abort ();
2737
2738   op0 = protect_from_queue (op0, 0);
2739
2740   if (flag_force_mem)
2741     {
2742       op0 = force_not_mem (op0);
2743     }
2744
2745   last = get_last_insn ();
2746
2747   if (target)
2748     target = protect_from_queue (target, 1);
2749
2750   this_abs_optab = ! unsignedp && flag_trapv
2751                    && (GET_MODE_CLASS(mode) == MODE_INT)
2752                    ? absv_optab : abs_optab;
2753
2754   if (this_abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2755     {
2756       int icode = (int) this_abs_optab->handlers[(int) mode].insn_code;
2757       enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2758       rtx xop0 = op0;
2759
2760       if (target)
2761         temp = target;
2762       else
2763         temp = gen_reg_rtx (submode);
2764
2765       if (GET_MODE (xop0) != VOIDmode
2766           && GET_MODE (xop0) != mode0)
2767         xop0 = convert_to_mode (mode0, xop0, unsignedp);
2768
2769       /* Now, if insn doesn't accept our operand, put it into a pseudo.  */
2770
2771       if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
2772         xop0 = copy_to_mode_reg (mode0, xop0);
2773
2774       if (! (*insn_data[icode].operand[0].predicate) (temp, submode))
2775         temp = gen_reg_rtx (submode);
2776
2777       pat = GEN_FCN (icode) (temp, xop0);
2778       if (pat)
2779         {
2780           if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
2781               && ! add_equal_note (pat, temp, this_abs_optab->code, xop0, 
2782                                    NULL_RTX))
2783             {
2784               delete_insns_since (last);
2785               return expand_unop (mode, this_abs_optab, op0, NULL_RTX, 
2786                                   unsignedp);
2787             }
2788
2789           emit_insn (pat);
2790           
2791           return temp;
2792         }
2793       else
2794         delete_insns_since (last);
2795     }
2796
2797   /* It can't be done in this mode.  Can we open-code it in a wider mode?  */
2798
2799   for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2800        wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2801     {
2802       if (this_abs_optab->handlers[(int) wider_mode].insn_code 
2803           != CODE_FOR_nothing)
2804         {
2805           rtx xop0 = op0;
2806
2807           xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2808           temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2809
2810           if (temp)
2811             {
2812               if (class != MODE_COMPLEX_INT)
2813                 {
2814                   if (target == 0)
2815                     target = gen_reg_rtx (submode);
2816                   convert_move (target, temp, 0);
2817                   return target;
2818                 }
2819               else
2820                 return gen_lowpart (submode, temp);
2821             }
2822           else
2823             delete_insns_since (last);
2824         }
2825     }
2826
2827   /* Open-code the complex absolute-value operation
2828      if we can open-code sqrt.  Otherwise it's not worth while.  */
2829   if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing
2830       && ! flag_trapv)
2831     {
2832       rtx real, imag, total;
2833
2834       real = gen_realpart (submode, op0);
2835       imag = gen_imagpart (submode, op0);
2836
2837       /* Square both parts.  */
2838       real = expand_mult (submode, real, real, NULL_RTX, 0);
2839       imag = expand_mult (submode, imag, imag, NULL_RTX, 0);
2840
2841       /* Sum the parts.  */
2842       total = expand_binop (submode, add_optab, real, imag, NULL_RTX,
2843                             0, OPTAB_LIB_WIDEN);
2844
2845       /* Get sqrt in TARGET.  Set TARGET to where the result is.  */
2846       target = expand_unop (submode, sqrt_optab, total, target, 0);
2847       if (target == 0)
2848         delete_insns_since (last);
2849       else
2850         return target;
2851     }
2852
2853   /* Now try a library call in this mode.  */
2854   if (this_abs_optab->handlers[(int) mode].libfunc)
2855     {
2856       rtx insns;
2857       rtx value;
2858
2859       start_sequence ();
2860
2861       /* Pass 1 for NO_QUEUE so we don't lose any increments
2862          if the libcall is cse'd or moved.  */
2863       value = emit_library_call_value (abs_optab->handlers[(int) mode].libfunc,
2864                                        NULL_RTX, LCT_CONST, submode, 1, op0, mode);
2865       insns = get_insns ();
2866       end_sequence ();
2867
2868       target = gen_reg_rtx (submode);
2869       emit_libcall_block (insns, target, value,
2870                           gen_rtx_fmt_e (this_abs_optab->code, mode, op0));
2871
2872       return target;
2873     }
2874
2875   /* It can't be done in this mode.  Can we do it in a wider mode?  */
2876
2877   for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2878        wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2879     {
2880       if ((this_abs_optab->handlers[(int) wider_mode].insn_code
2881            != CODE_FOR_nothing)
2882           || this_abs_optab->handlers[(int) wider_mode].libfunc)
2883         {
2884           rtx xop0 = op0;
2885
2886           xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2887
2888           temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2889
2890           if (temp)
2891             {
2892               if (class != MODE_COMPLEX_INT)
2893                 {
2894                   if (target == 0)
2895                     target = gen_reg_rtx (submode);
2896                   convert_move (target, temp, 0);
2897                   return target;
2898                 }
2899               else
2900                 return gen_lowpart (submode, temp);
2901             }
2902           else
2903             delete_insns_since (last);
2904         }
2905     }
2906
2907   delete_insns_since (entry_last);
2908   return 0;
2909 }
2910 \f
2911 /* Generate an instruction whose insn-code is INSN_CODE,
2912    with two operands: an output TARGET and an input OP0.
2913    TARGET *must* be nonzero, and the output is always stored there.
2914    CODE is an rtx code such that (CODE OP0) is an rtx that describes
2915    the value that is stored into TARGET.  */
2916
2917 void
2918 emit_unop_insn (icode, target, op0, code)
2919      int icode;
2920      rtx target;
2921      rtx op0;
2922      enum rtx_code code;
2923 {
2924   rtx temp;
2925   enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2926   rtx pat;
2927
2928   temp = target = protect_from_queue (target, 1);
2929
2930   op0 = protect_from_queue (op0, 0);
2931
2932   /* Sign and zero extension from memory is often done specially on
2933      RISC machines, so forcing into a register here can pessimize
2934      code.  */
2935   if (flag_force_mem && code != SIGN_EXTEND && code != ZERO_EXTEND)
2936     op0 = force_not_mem (op0);
2937
2938   /* Now, if insn does not accept our operands, put them into pseudos.  */
2939
2940   if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
2941     op0 = copy_to_mode_reg (mode0, op0);
2942
2943   if (! (*insn_data[icode].operand[0].predicate) (temp, GET_MODE (temp))
2944       || (flag_force_mem && GET_CODE (temp) == MEM))
2945     temp = gen_reg_rtx (GET_MODE (temp));
2946
2947   pat = GEN_FCN (icode) (temp, op0);
2948
2949   if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX && code != UNKNOWN)
2950     add_equal_note (pat, temp, code, op0, NULL_RTX);
2951   
2952   emit_insn (pat);
2953
2954   if (temp != target)
2955     emit_move_insn (target, temp);
2956 }
2957 \f
2958 /* Emit code to perform a series of operations on a multi-word quantity, one
2959    word at a time.
2960
2961    Such a block is preceded by a CLOBBER of the output, consists of multiple
2962    insns, each setting one word of the output, and followed by a SET copying
2963    the output to itself.
2964
2965    Each of the insns setting words of the output receives a REG_NO_CONFLICT
2966    note indicating that it doesn't conflict with the (also multi-word)
2967    inputs.  The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2968    notes.
2969
2970    INSNS is a block of code generated to perform the operation, not including
2971    the CLOBBER and final copy.  All insns that compute intermediate values
2972    are first emitted, followed by the block as described above.  
2973
2974    TARGET, OP0, and OP1 are the output and inputs of the operations,
2975    respectively.  OP1 may be zero for a unary operation.
2976
2977    EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
2978    on the last insn.
2979
2980    If TARGET is not a register, INSNS is simply emitted with no special
2981    processing.  Likewise if anything in INSNS is not an INSN or if
2982    there is a libcall block inside INSNS.
2983
2984    The final insn emitted is returned.  */
2985
2986 rtx
2987 emit_no_conflict_block (insns, target, op0, op1, equiv)
2988      rtx insns;
2989      rtx target;
2990      rtx op0, op1;
2991      rtx equiv;
2992 {
2993   rtx prev, next, first, last, insn;
2994
2995   if (GET_CODE (target) != REG || reload_in_progress)
2996     return emit_insn (insns);
2997   else
2998     for (insn = insns; insn; insn = NEXT_INSN (insn))
2999       if (GET_CODE (insn) != INSN
3000           || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
3001         return emit_insn (insns);
3002
3003   /* First emit all insns that do not store into words of the output and remove
3004      these from the list.  */
3005   for (insn = insns; insn; insn = next)
3006     {
3007       rtx set = 0, note;
3008       int i;
3009
3010       next = NEXT_INSN (insn);
3011
3012       /* Some ports (cris) create an libcall regions at their own.  We must
3013          avoid any potential nesting of LIBCALLs.  */
3014       if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
3015         remove_note (insn, note);
3016       if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
3017         remove_note (insn, note);
3018
3019       if (GET_CODE (PATTERN (insn)) == SET || GET_CODE (PATTERN (insn)) == USE
3020           || GET_CODE (PATTERN (insn)) == CLOBBER)
3021         set = PATTERN (insn);
3022       else if (GET_CODE (PATTERN (insn)) == PARALLEL)
3023         {
3024           for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
3025             if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
3026               {
3027                 set = XVECEXP (PATTERN (insn), 0, i);
3028                 break;
3029               }
3030         }
3031
3032       if (set == 0)
3033         abort ();
3034
3035       if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
3036         {
3037           if (PREV_INSN (insn))
3038             NEXT_INSN (PREV_INSN (insn)) = next;
3039           else
3040             insns = next;
3041
3042           if (next)
3043             PREV_INSN (next) = PREV_INSN (insn);
3044
3045           add_insn (insn);
3046         }
3047     }
3048
3049   prev = get_last_insn ();
3050
3051   /* Now write the CLOBBER of the output, followed by the setting of each
3052      of the words, followed by the final copy.  */
3053   if (target != op0 && target != op1)
3054     emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
3055
3056   for (insn = insns; insn; insn = next)
3057     {
3058       next = NEXT_INSN (insn);
3059       add_insn (insn);
3060
3061       if (op1 && GET_CODE (op1) == REG)
3062         REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op1,
3063                                               REG_NOTES (insn));
3064
3065       if (op0 && GET_CODE (op0) == REG)
3066         REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op0,
3067                                               REG_NOTES (insn));
3068     }
3069
3070   if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
3071       != CODE_FOR_nothing)
3072     {
3073       last = emit_move_insn (target, target);
3074       if (equiv)
3075         set_unique_reg_note (last, REG_EQUAL, equiv);
3076     }
3077   else
3078     {
3079       last = get_last_insn ();
3080
3081       /* Remove any existing REG_EQUAL note from "last", or else it will
3082          be mistaken for a note referring to the full contents of the
3083          alleged libcall value when found together with the REG_RETVAL
3084          note added below.  An existing note can come from an insn
3085          expansion at "last".  */
3086       remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
3087     }
3088
3089   if (prev == 0)
3090     first = get_insns ();
3091   else
3092     first = NEXT_INSN (prev);
3093
3094   /* Encapsulate the block so it gets manipulated as a unit.  */
3095   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
3096                                          REG_NOTES (first));
3097   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
3098
3099   return last;
3100 }
3101 \f
3102 /* Emit code to make a call to a constant function or a library call.
3103
3104    INSNS is a list containing all insns emitted in the call.
3105    These insns leave the result in RESULT.  Our block is to copy RESULT
3106    to TARGET, which is logically equivalent to EQUIV.
3107
3108    We first emit any insns that set a pseudo on the assumption that these are
3109    loading constants into registers; doing so allows them to be safely cse'ed
3110    between blocks.  Then we emit all the other insns in the block, followed by
3111    an insn to move RESULT to TARGET.  This last insn will have a REQ_EQUAL
3112    note with an operand of EQUIV.
3113
3114    Moving assignments to pseudos outside of the block is done to improve
3115    the generated code, but is not required to generate correct code,
3116    hence being unable to move an assignment is not grounds for not making
3117    a libcall block.  There are two reasons why it is safe to leave these
3118    insns inside the block: First, we know that these pseudos cannot be
3119    used in generated RTL outside the block since they are created for
3120    temporary purposes within the block.  Second, CSE will not record the
3121    values of anything set inside a libcall block, so we know they must
3122    be dead at the end of the block.
3123
3124    Except for the first group of insns (the ones setting pseudos), the
3125    block is delimited by REG_RETVAL and REG_LIBCALL notes.  */
3126
3127 void
3128 emit_libcall_block (insns, target, result, equiv)
3129      rtx insns;
3130      rtx target;
3131      rtx result;
3132      rtx equiv;
3133 {
3134   rtx final_dest = target;
3135   rtx prev, next, first, last, insn;
3136
3137   /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3138      into a MEM later.  Protect the libcall block from this change.  */
3139   if (! REG_P (target) || REG_USERVAR_P (target))
3140     target = gen_reg_rtx (GET_MODE (target));
3141   
3142   /* If we're using non-call exceptions, a libcall corresponding to an
3143      operation that may trap may also trap.  */
3144   if (flag_non_call_exceptions && may_trap_p (equiv))
3145     {
3146       for (insn = insns; insn; insn = NEXT_INSN (insn))
3147         if (GET_CODE (insn) == CALL_INSN)
3148           {
3149             rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3150             
3151             if (note != 0 && INTVAL (XEXP (note, 0)) <= 0)
3152               remove_note (insn, note);
3153           }
3154     }
3155   else
3156   /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
3157      reg note to indicate that this call cannot throw or execute a nonlocal
3158      goto (unless there is already a REG_EH_REGION note, in which case
3159      we update it).  */
3160     for (insn = insns; insn; insn = NEXT_INSN (insn))
3161       if (GET_CODE (insn) == CALL_INSN)
3162         {
3163           rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3164         
3165           if (note != 0)
3166             XEXP (note, 0) = GEN_INT (-1);
3167           else
3168             REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, GEN_INT (-1),
3169                                                   REG_NOTES (insn));
3170         }
3171
3172   /* First emit all insns that set pseudos.  Remove them from the list as
3173      we go.  Avoid insns that set pseudos which were referenced in previous
3174      insns.  These can be generated by move_by_pieces, for example,
3175      to update an address.  Similarly, avoid insns that reference things
3176      set in previous insns.  */
3177
3178   for (insn = insns; insn; insn = next)
3179     {
3180       rtx set = single_set (insn);
3181       rtx note;
3182
3183       /* Some ports (cris) create an libcall regions at their own.  We must
3184          avoid any potential nesting of LIBCALLs.  */
3185       if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
3186         remove_note (insn, note);
3187       if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
3188         remove_note (insn, note);
3189
3190       next = NEXT_INSN (insn);
3191
3192       if (set != 0 && GET_CODE (SET_DEST (set)) == REG
3193           && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
3194           && (insn == insns
3195               || ((! INSN_P(insns)
3196                    || ! reg_mentioned_p (SET_DEST (set), PATTERN (insns)))
3197                   && ! reg_used_between_p (SET_DEST (set), insns, insn)
3198                   && ! modified_in_p (SET_SRC (set), insns)
3199                   && ! modified_between_p (SET_SRC (set), insns, insn))))
3200         {
3201           if (PREV_INSN (insn))
3202             NEXT_INSN (PREV_INSN (insn)) = next;
3203           else
3204             insns = next;
3205
3206           if (next)
3207             PREV_INSN (next) = PREV_INSN (insn);
3208
3209           add_insn (insn);
3210         }
3211     }
3212
3213   prev = get_last_insn ();
3214
3215   /* Write the remaining insns followed by the final copy.  */
3216
3217   for (insn = insns; insn; insn = next)
3218     {
3219       next = NEXT_INSN (insn);
3220
3221       add_insn (insn);
3222     }
3223
3224   last = emit_move_insn (target, result);
3225   if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
3226       != CODE_FOR_nothing)
3227     set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
3228   else
3229     {
3230       /* Remove any existing REG_EQUAL note from "last", or else it will
3231          be mistaken for a note referring to the full contents of the
3232          libcall value when found together with the REG_RETVAL note added
3233          below.  An existing note can come from an insn expansion at
3234          "last".  */
3235       remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
3236     }
3237
3238   if (final_dest != target)
3239     emit_move_insn (final_dest, target);
3240
3241   if (prev == 0)
3242     first = get_insns ();
3243   else
3244     first = NEXT_INSN (prev);
3245
3246   /* Encapsulate the block so it gets manipulated as a unit.  */
3247   if (!flag_non_call_exceptions || !may_trap_p (equiv))
3248     {
3249       REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
3250                                              REG_NOTES (first));
3251       REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first,
3252                                             REG_NOTES (last));
3253     }
3254 }
3255 \f
3256 /* Generate code to store zero in X.  */
3257
3258 void
3259 emit_clr_insn (x)
3260      rtx x;
3261 {
3262   emit_move_insn (x, const0_rtx);
3263 }
3264
3265 /* Generate code to store 1 in X
3266    assuming it contains zero beforehand.  */
3267
3268 void
3269 emit_0_to_1_insn (x)
3270      rtx x;
3271 {
3272   emit_move_insn (x, const1_rtx);
3273 }
3274
3275 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
3276    PURPOSE describes how this comparison will be used.  CODE is the rtx
3277    comparison code we will be using.
3278
3279    ??? Actually, CODE is slightly weaker than that.  A target is still
3280    required to implement all of the normal bcc operations, but not 
3281    required to implement all (or any) of the unordered bcc operations.  */
3282   
3283 int
3284 can_compare_p (code, mode, purpose)
3285      enum rtx_code code;
3286      enum machine_mode mode;
3287      enum can_compare_purpose purpose;
3288 {
3289   do
3290     {
3291       if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
3292         {
3293           if (purpose == ccp_jump)
3294             return bcc_gen_fctn[(int)code] != NULL;
3295           else if (purpose == ccp_store_flag)
3296             return setcc_gen_code[(int)code] != CODE_FOR_nothing;
3297           else
3298             /* There's only one cmov entry point, and it's allowed to fail.  */
3299             return 1;
3300         }
3301       if (purpose == ccp_jump
3302           && cbranch_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
3303         return 1;
3304       if (purpose == ccp_cmov
3305           && cmov_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
3306         return 1;
3307       if (purpose == ccp_store_flag
3308           && cstore_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
3309         return 1;
3310
3311       mode = GET_MODE_WIDER_MODE (mode);
3312     }
3313   while (mode != VOIDmode);
3314
3315   return 0;
3316 }
3317
3318 /* This function is called when we are going to emit a compare instruction that
3319    compares the values found in *PX and *PY, using the rtl operator COMPARISON.
3320
3321    *PMODE is the mode of the inputs (in case they are const_int).
3322    *PUNSIGNEDP nonzero says that the operands are unsigned;
3323    this matters if they need to be widened.
3324
3325    If they have mode BLKmode, then SIZE specifies the size of both operands.
3326
3327    This function performs all the setup necessary so that the caller only has
3328    to emit a single comparison insn.  This setup can involve doing a BLKmode
3329    comparison or emitting a library call to perform the comparison if no insn
3330    is available to handle it.
3331    The values which are passed in through pointers can be modified; the caller
3332    should perform the comparison on the modified values.  */
3333
3334 static void
3335 prepare_cmp_insn (px, py, pcomparison, size, pmode, punsignedp, purpose)
3336      rtx *px, *py;
3337      enum rtx_code *pcomparison;
3338      rtx size;
3339      enum machine_mode *pmode;
3340      int *punsignedp;
3341      enum can_compare_purpose purpose;
3342 {
3343   enum machine_mode mode = *pmode;
3344   rtx x = *px, y = *py;
3345   int unsignedp = *punsignedp;
3346   enum mode_class class;
3347
3348   class = GET_MODE_CLASS (mode);
3349
3350   /* They could both be VOIDmode if both args are immediate constants,
3351      but we should fold that at an earlier stage.
3352      With no special code here, this will call abort,
3353      reminding the programmer to implement such folding.  */
3354
3355   if (mode != BLKmode && flag_force_mem)
3356     {
3357       x = force_not_mem (x);
3358       y = force_not_mem (y);
3359     }
3360
3361   /* If we are inside an appropriately-short loop and one operand is an
3362      expensive constant, force it into a register.  */
3363   if (CONSTANT_P (x) && preserve_subexpressions_p ()
3364       && rtx_cost (x, COMPARE) > COSTS_N_INSNS (1))
3365     x = force_reg (mode, x);
3366
3367   if (CONSTANT_P (y) && preserve_subexpressions_p ()
3368       && rtx_cost (y, COMPARE) > COSTS_N_INSNS (1))
3369     y = force_reg (mode, y);
3370
3371 #ifdef HAVE_cc0
3372   /* Abort if we have a non-canonical comparison.  The RTL documentation
3373      states that canonical comparisons are required only for targets which
3374      have cc0.  */
3375   if (CONSTANT_P (x) && ! CONSTANT_P (y))
3376     abort();
3377 #endif
3378
3379   /* Don't let both operands fail to indicate the mode.  */
3380   if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
3381     x = force_reg (mode, x);
3382
3383   /* Handle all BLKmode compares.  */
3384
3385   if (mode == BLKmode)
3386     {
3387       rtx result;
3388       enum machine_mode result_mode;
3389       rtx opalign ATTRIBUTE_UNUSED
3390         = GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
3391
3392       emit_queue ();
3393       x = protect_from_queue (x, 0);
3394       y = protect_from_queue (y, 0);
3395
3396       if (size == 0)
3397         abort ();
3398 #ifdef HAVE_cmpstrqi
3399       if (HAVE_cmpstrqi
3400           && GET_CODE (size) == CONST_INT
3401           && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
3402         {
3403           result_mode = insn_data[(int) CODE_FOR_cmpstrqi].operand[0].mode;
3404           result = gen_reg_rtx (result_mode);
3405           emit_insn (gen_cmpstrqi (result, x, y, size, opalign));
3406         }
3407       else
3408 #endif
3409 #ifdef HAVE_cmpstrhi
3410       if (HAVE_cmpstrhi
3411           && GET_CODE (size) == CONST_INT
3412           && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
3413         {
3414           result_mode = insn_data[(int) CODE_FOR_cmpstrhi].operand[0].mode;
3415           result = gen_reg_rtx (result_mode);
3416           emit_insn (gen_cmpstrhi (result, x, y, size, opalign));
3417         }
3418       else
3419 #endif
3420 #ifdef HAVE_cmpstrsi
3421       if (HAVE_cmpstrsi)
3422         {
3423           result_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3424           result = gen_reg_rtx (result_mode);
3425           size = protect_from_queue (size, 0);
3426           emit_insn (gen_cmpstrsi (result, x, y,
3427                                    convert_to_mode (SImode, size, 1),
3428                                    opalign));
3429         }
3430       else
3431 #endif
3432         {
3433 #ifdef TARGET_MEM_FUNCTIONS
3434           emit_library_call (memcmp_libfunc, LCT_PURE_MAKE_BLOCK,
3435                              TYPE_MODE (integer_type_node), 3,
3436                              XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
3437                              convert_to_mode (TYPE_MODE (sizetype), size,
3438                                               TREE_UNSIGNED (sizetype)),
3439                              TYPE_MODE (sizetype));
3440 #else
3441           emit_library_call (bcmp_libfunc, LCT_PURE_MAKE_BLOCK,
3442                              TYPE_MODE (integer_type_node), 3,
3443                              XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
3444                              convert_to_mode (TYPE_MODE (integer_type_node),
3445                                               size,
3446                                               TREE_UNSIGNED (integer_type_node)),
3447                              TYPE_MODE (integer_type_node));
3448 #endif
3449
3450           /* Immediately move the result of the libcall into a pseudo
3451              register so reload doesn't clobber the value if it needs
3452              the return register for a spill reg.  */
3453           result = gen_reg_rtx (TYPE_MODE (integer_type_node));
3454           result_mode = TYPE_MODE (integer_type_node);
3455           emit_move_insn (result,
3456                           hard_libcall_value (result_mode));
3457         }
3458       *px = result;
3459       *py = const0_rtx;
3460       *pmode = result_mode;
3461       return;
3462     }
3463
3464   *px = x;
3465   *py = y;
3466   if (can_compare_p (*pcomparison, mode, purpose))
3467     return;
3468
3469   /* Handle a lib call just for the mode we are using.  */
3470
3471   if (cmp_optab->handlers[(int) mode].libfunc && class != MODE_FLOAT)
3472     {
3473       rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
3474       rtx result;
3475
3476       /* If we want unsigned, and this mode has a distinct unsigned
3477          comparison routine, use that.  */
3478       if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
3479         libfunc = ucmp_optab->handlers[(int) mode].libfunc;
3480
3481       emit_library_call (libfunc, LCT_CONST_MAKE_BLOCK, word_mode, 2, x, mode,
3482                          y, mode);
3483
3484       /* Immediately move the result of the libcall into a pseudo
3485          register so reload doesn't clobber the value if it needs
3486          the return register for a spill reg.  */
3487       result = gen_reg_rtx (word_mode);
3488       emit_move_insn (result, hard_libcall_value (word_mode));
3489
3490       /* Integer comparison returns a result that must be compared against 1,
3491          so that even if we do an unsigned compare afterward,
3492          there is still a value that can represent the result "less than".  */
3493       *px = result;
3494       *py = const1_rtx;
3495       *pmode = word_mode;
3496       return;
3497     }
3498
3499   if (class == MODE_FLOAT)
3500     prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
3501
3502   else
3503     abort ();
3504 }
3505
3506 /* Before emitting an insn with code ICODE, make sure that X, which is going
3507    to be used for operand OPNUM of the insn, is converted from mode MODE to
3508    WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
3509    that it is accepted by the operand predicate.  Return the new value.  */
3510
3511 rtx
3512 prepare_operand (icode, x, opnum, mode, wider_mode, unsignedp)
3513      int icode;
3514      rtx x;
3515      int opnum;
3516      enum machine_mode mode, wider_mode;
3517      int unsignedp;
3518 {
3519   x = protect_from_queue (x, 0);
3520
3521   if (mode != wider_mode)
3522     x = convert_modes (wider_mode, mode, x, unsignedp);
3523
3524   if (! (*insn_data[icode].operand[opnum].predicate)
3525       (x, insn_data[icode].operand[opnum].mode))
3526     x = copy_to_mode_reg (insn_data[icode].operand[opnum].mode, x);
3527   return x;
3528 }
3529
3530 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
3531    we can do the comparison.
3532    The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may
3533    be NULL_RTX which indicates that only a comparison is to be generated.  */
3534
3535 static void
3536 emit_cmp_and_jump_insn_1 (x, y, mode, comparison, unsignedp, label)
3537      rtx x, y;
3538      enum machine_mode mode;
3539      enum rtx_code comparison;
3540      int unsignedp;
3541      rtx label;
3542 {
3543   rtx test = gen_rtx_fmt_ee (comparison, mode, x, y);
3544   enum mode_class class = GET_MODE_CLASS (mode);
3545   enum machine_mode wider_mode = mode;
3546
3547   /* Try combined insns first.  */
3548   do
3549     {
3550       enum insn_code icode;
3551       PUT_MODE (test, wider_mode);
3552
3553       if (label)
3554         {         
3555           icode = cbranch_optab->handlers[(int)wider_mode].insn_code;
3556           
3557           if (icode != CODE_FOR_nothing
3558               && (*insn_data[icode].operand[0].predicate) (test, wider_mode))
3559             {
3560               x = prepare_operand (icode, x, 1, mode, wider_mode, unsignedp);
3561               y = prepare_operand (icode, y, 2, mode, wider_mode, unsignedp);
3562               emit_jump_insn (GEN_FCN (icode) (test, x, y, label));
3563               return;
3564             }
3565         }
3566
3567       /* Handle some compares against zero.  */
3568       icode = (int) tst_optab->handlers[(int) wider_mode].insn_code;
3569       if (y == CONST0_RTX (mode) && icode != CODE_FOR_nothing)
3570         {
3571           x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3572           emit_insn (GEN_FCN (icode) (x));
3573           if (label)
3574             emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
3575           return;
3576         }
3577
3578       /* Handle compares for which there is a directly suitable insn.  */
3579
3580       icode = (int) cmp_optab->handlers[(int) wider_mode].insn_code;
3581       if (icode != CODE_FOR_nothing)
3582         {
3583           x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3584           y = prepare_operand (icode, y, 1, mode, wider_mode, unsignedp);
3585           emit_insn (GEN_FCN (icode) (x, y));
3586           if (label)
3587             emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
3588           return;
3589         }
3590
3591       if (class != MODE_INT && class != MODE_FLOAT
3592           && class != MODE_COMPLEX_FLOAT)
3593         break;
3594
3595       wider_mode = GET_MODE_WIDER_MODE (wider_mode);
3596     } while (wider_mode != VOIDmode);
3597
3598   abort ();
3599 }
3600
3601 /* Generate code to compare X with Y so that the condition codes are
3602    set and to jump to LABEL if the condition is true.  If X is a
3603    constant and Y is not a constant, then the comparison is swapped to
3604    ensure that the comparison RTL has the canonical form.
3605
3606    UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
3607    need to be widened by emit_cmp_insn.  UNSIGNEDP is also used to select
3608    the proper branch condition code.
3609
3610    If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
3611
3612    MODE is the mode of the inputs (in case they are const_int).
3613
3614    COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  It will
3615    be passed unchanged to emit_cmp_insn, then potentially converted into an
3616    unsigned variant based on UNSIGNEDP to select a proper jump instruction.  */
3617
3618 void
3619 emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, label)
3620      rtx x, y;
3621      enum rtx_code comparison;
3622      rtx size;
3623      enum machine_mode mode;
3624      int unsignedp;
3625      rtx label;
3626 {
3627   rtx op0 = x, op1 = y;
3628
3629   /* Swap operands and condition to ensure canonical RTL.  */
3630   if (swap_commutative_operands_p (x, y))
3631     {
3632       /* If we're not emitting a branch, this means some caller
3633          is out of sync.  */
3634       if (! label)
3635         abort ();
3636
3637       op0 = y, op1 = x;
3638       comparison = swap_condition (comparison);
3639     }
3640
3641 #ifdef HAVE_cc0
3642   /* If OP0 is still a constant, then both X and Y must be constants.  Force
3643      X into a register to avoid aborting in emit_cmp_insn due to non-canonical
3644      RTL.  */
3645   if (CONSTANT_P (op0))
3646     op0 = force_reg (mode, op0);
3647 #endif
3648
3649   emit_queue ();
3650   if (unsignedp)
3651     comparison = unsigned_condition (comparison);
3652
3653   prepare_cmp_insn (&op0, &op1, &comparison, size, &mode, &unsignedp,
3654                     ccp_jump);
3655   emit_cmp_and_jump_insn_1 (op0, op1, mode, comparison, unsignedp, label);
3656 }
3657
3658 /* Like emit_cmp_and_jump_insns, but generate only the comparison.  */
3659
3660 void
3661 emit_cmp_insn (x, y, comparison, size, mode, unsignedp)
3662      rtx x, y;
3663      enum rtx_code comparison;
3664      rtx size;
3665      enum machine_mode mode;
3666      int unsignedp;
3667 {
3668   emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, 0);
3669 }
3670 \f
3671 /* Emit a library call comparison between floating point X and Y.
3672    COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  */
3673
3674 static void
3675 prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp)
3676      rtx *px, *py;
3677      enum rtx_code *pcomparison;
3678      enum machine_mode *pmode;
3679      int *punsignedp;
3680 {
3681   enum rtx_code comparison = *pcomparison;
3682   rtx tmp;
3683   rtx x = *px = protect_from_queue (*px, 0);
3684   rtx y = *py = protect_from_queue (*py, 0);
3685   enum machine_mode mode = GET_MODE (x);
3686   rtx libfunc = 0;
3687   rtx result;
3688
3689   if (mode == HFmode)
3690     switch (comparison)
3691       {
3692       case EQ:
3693         libfunc = eqhf2_libfunc;
3694         break;
3695
3696       case NE:
3697         libfunc = nehf2_libfunc;
3698         break;
3699
3700       case GT:
3701         libfunc = gthf2_libfunc;
3702         if (libfunc == NULL_RTX)
3703           {
3704             tmp = x; x = y; y = tmp;
3705             *pcomparison = LT;
3706             libfunc = lthf2_libfunc;
3707           }
3708         break;
3709
3710       case GE:
3711         libfunc = gehf2_libfunc;
3712         if (libfunc == NULL_RTX)
3713           {
3714             tmp = x; x = y; y = tmp;
3715             *pcomparison = LE;
3716             libfunc = lehf2_libfunc;
3717           }
3718         break;
3719
3720       case LT:
3721         libfunc = lthf2_libfunc;
3722         if (libfunc == NULL_RTX)
3723           {
3724             tmp = x; x = y; y = tmp;
3725             *pcomparison = GT;
3726             libfunc = gthf2_libfunc;
3727           }
3728         break;
3729
3730       case LE:
3731         libfunc = lehf2_libfunc;
3732         if (libfunc == NULL_RTX)
3733           {
3734             tmp = x; x = y; y = tmp;
3735             *pcomparison = GE;
3736             libfunc = gehf2_libfunc;
3737           }
3738         break;
3739
3740       case UNORDERED:
3741         libfunc = unordhf2_libfunc;
3742         break;
3743
3744       default:
3745         break;
3746       }
3747   else if (mode == SFmode)
3748     switch (comparison)
3749       {
3750       case EQ:
3751         libfunc = eqsf2_libfunc;
3752         break;
3753
3754       case NE:
3755         libfunc = nesf2_libfunc;
3756         break;
3757
3758       case GT:
3759         libfunc = gtsf2_libfunc;
3760         if (libfunc == NULL_RTX)
3761           {
3762             tmp = x; x = y; y = tmp;
3763             *pcomparison = LT;
3764             libfunc = ltsf2_libfunc;
3765           }
3766         break;
3767
3768       case GE:
3769         libfunc = gesf2_libfunc;
3770         if (libfunc == NULL_RTX)
3771           {
3772             tmp = x; x = y; y = tmp;
3773             *pcomparison = LE;
3774             libfunc = lesf2_libfunc;
3775           }
3776         break;
3777
3778       case LT:
3779         libfunc = ltsf2_libfunc;
3780         if (libfunc == NULL_RTX)
3781           {
3782             tmp = x; x = y; y = tmp;
3783             *pcomparison = GT;
3784             libfunc = gtsf2_libfunc;
3785           }
3786         break;
3787
3788       case LE:
3789         libfunc = lesf2_libfunc;
3790         if (libfunc == NULL_RTX)
3791           {
3792             tmp = x; x = y; y = tmp;
3793             *pcomparison = GE;
3794             libfunc = gesf2_libfunc;
3795           }
3796         break;
3797
3798       case UNORDERED:
3799         libfunc = unordsf2_libfunc;
3800         break;
3801
3802       default:
3803         break;
3804       }
3805   else if (mode == DFmode)
3806     switch (comparison)
3807       {
3808       case EQ:
3809         libfunc = eqdf2_libfunc;
3810         break;
3811
3812       case NE:
3813         libfunc = nedf2_libfunc;
3814         break;
3815
3816       case GT:
3817         libfunc = gtdf2_libfunc;
3818         if (libfunc == NULL_RTX)
3819           {
3820             tmp = x; x = y; y = tmp;
3821             *pcomparison = LT;
3822             libfunc = ltdf2_libfunc;
3823           }
3824         break;
3825
3826       case GE:
3827         libfunc = gedf2_libfunc;
3828         if (libfunc == NULL_RTX)
3829           {
3830             tmp = x; x = y; y = tmp;
3831             *pcomparison = LE;
3832             libfunc = ledf2_libfunc;
3833           }
3834         break;
3835
3836       case LT:
3837         libfunc = ltdf2_libfunc;
3838         if (libfunc == NULL_RTX)
3839           {
3840             tmp = x; x = y; y = tmp;
3841             *pcomparison = GT;
3842             libfunc = gtdf2_libfunc;
3843           }
3844         break;
3845
3846       case LE:
3847         libfunc = ledf2_libfunc;
3848         if (libfunc == NULL_RTX)
3849           {
3850             tmp = x; x = y; y = tmp;
3851             *pcomparison = GE;
3852             libfunc = gedf2_libfunc;
3853           }
3854         break;
3855
3856       case UNORDERED:
3857         libfunc = unorddf2_libfunc;
3858         break;
3859
3860       default:
3861         break;
3862       }
3863   else if (mode == XFmode)
3864     switch (comparison)
3865       {
3866       case EQ:
3867         libfunc = eqxf2_libfunc;
3868         break;
3869
3870       case NE:
3871         libfunc = nexf2_libfunc;
3872         break;
3873
3874       case GT:
3875         libfunc = gtxf2_libfunc;
3876         if (libfunc == NULL_RTX)
3877           {
3878             tmp = x; x = y; y = tmp;
3879             *pcomparison = LT;
3880             libfunc = ltxf2_libfunc;
3881           }
3882         break;
3883
3884       case GE:
3885         libfunc = gexf2_libfunc;
3886         if (libfunc == NULL_RTX)
3887           {
3888             tmp = x; x = y; y = tmp;
3889             *pcomparison = LE;
3890             libfunc = lexf2_libfunc;
3891           }
3892         break;
3893
3894       case LT:
3895         libfunc = ltxf2_libfunc;
3896         if (libfunc == NULL_RTX)
3897           {
3898             tmp = x; x = y; y = tmp;
3899             *pcomparison = GT;
3900             libfunc = gtxf2_libfunc;
3901           }
3902         break;
3903
3904       case LE:
3905         libfunc = lexf2_libfunc;
3906         if (libfunc == NULL_RTX)
3907           {
3908             tmp = x; x = y; y = tmp;
3909             *pcomparison = GE;
3910             libfunc = gexf2_libfunc;
3911           }
3912         break;
3913
3914       case UNORDERED:
3915         libfunc = unordxf2_libfunc;
3916         break;
3917
3918       default:
3919         break;
3920       }
3921   else if (mode == TFmode)
3922     switch (comparison)
3923       {
3924       case EQ:
3925         libfunc = eqtf2_libfunc;
3926         break;
3927
3928       case NE:
3929         libfunc = netf2_libfunc;
3930         break;
3931
3932       case GT:
3933         libfunc = gttf2_libfunc;
3934         if (libfunc == NULL_RTX)
3935           {
3936             tmp = x; x = y; y = tmp;
3937             *pcomparison = LT;
3938             libfunc = lttf2_libfunc;
3939           }
3940         break;
3941
3942       case GE:
3943         libfunc = getf2_libfunc;
3944         if (libfunc == NULL_RTX)
3945           {
3946             tmp = x; x = y; y = tmp;
3947             *pcomparison = LE;
3948             libfunc = letf2_libfunc;
3949           }
3950         break;
3951
3952       case LT:
3953         libfunc = lttf2_libfunc;
3954         if (libfunc == NULL_RTX)
3955           {
3956             tmp = x; x = y; y = tmp;
3957             *pcomparison = GT;
3958             libfunc = gttf2_libfunc;
3959           }
3960         break;
3961
3962       case LE:
3963         libfunc = letf2_libfunc;
3964         if (libfunc == NULL_RTX)
3965           {
3966             tmp = x; x = y; y = tmp;
3967             *pcomparison = GE;
3968             libfunc = getf2_libfunc;
3969           }
3970         break;
3971
3972       case UNORDERED:
3973         libfunc = unordtf2_libfunc;
3974         break;
3975
3976       default:
3977         break;
3978       }
3979   else
3980     {
3981       enum machine_mode wider_mode;
3982
3983       for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3984            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3985         {
3986           if ((cmp_optab->handlers[(int) wider_mode].insn_code
3987                != CODE_FOR_nothing)
3988               || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
3989             {
3990               x = protect_from_queue (x, 0);
3991               y = protect_from_queue (y, 0);
3992               *px = convert_to_mode (wider_mode, x, 0);
3993               *py = convert_to_mode (wider_mode, y, 0);
3994               prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
3995               return;
3996             }
3997         }
3998       abort ();
3999     }
4000
4001   if (libfunc == 0)
4002     abort ();
4003
4004   emit_library_call (libfunc, LCT_CONST_MAKE_BLOCK, word_mode, 2, x, mode, y,
4005                      mode);
4006
4007   /* Immediately move the result of the libcall into a pseudo
4008      register so reload doesn't clobber the value if it needs
4009      the return register for a spill reg.  */
4010   result = gen_reg_rtx (word_mode);
4011   emit_move_insn (result, hard_libcall_value (word_mode));
4012   *px = result;
4013   *py = const0_rtx;
4014   *pmode = word_mode;
4015   if (comparison == UNORDERED)
4016     *pcomparison = NE;
4017 #ifdef FLOAT_LIB_COMPARE_RETURNS_BOOL
4018   else if (FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4019     *pcomparison = NE;
4020 #endif
4021   *punsignedp = 0;
4022 }
4023 \f
4024 /* Generate code to indirectly jump to a location given in the rtx LOC.  */
4025
4026 void
4027 emit_indirect_jump (loc)
4028      rtx loc;
4029 {
4030   if (! ((*insn_data[(int)CODE_FOR_indirect_jump].operand[0].predicate)
4031          (loc, Pmode)))
4032     loc = copy_to_mode_reg (Pmode, loc);
4033
4034   emit_jump_insn (gen_indirect_jump (loc));
4035   emit_barrier ();
4036 }
4037 \f
4038 #ifdef HAVE_conditional_move
4039
4040 /* Emit a conditional move instruction if the machine supports one for that
4041    condition and machine mode.
4042
4043    OP0 and OP1 are the operands that should be compared using CODE.  CMODE is
4044    the mode to use should they be constants.  If it is VOIDmode, they cannot
4045    both be constants.
4046
4047    OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4048    should be stored there.  MODE is the mode to use should they be constants.
4049    If it is VOIDmode, they cannot both be constants.
4050
4051    The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4052    is not supported.  */
4053
4054 rtx
4055 emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
4056                        unsignedp)
4057      rtx target;
4058      enum rtx_code code;
4059      rtx op0, op1;
4060      enum machine_mode cmode;
4061      rtx op2, op3;
4062      enum machine_mode mode;
4063      int unsignedp;
4064 {
4065   rtx tem, subtarget, comparison, insn;
4066   enum insn_code icode;
4067   enum rtx_code reversed;
4068
4069   /* If one operand is constant, make it the second one.  Only do this
4070      if the other operand is not constant as well.  */
4071
4072   if (swap_commutative_operands_p (op0, op1))
4073     {
4074       tem = op0;
4075       op0 = op1;
4076       op1 = tem;
4077       code = swap_condition (code);
4078     }
4079
4080   /* get_condition will prefer to generate LT and GT even if the old
4081      comparison was against zero, so undo that canonicalization here since
4082      comparisons against zero are cheaper.  */
4083   if (code == LT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == 1)
4084     code = LE, op1 = const0_rtx;
4085   else if (code == GT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == -1)
4086     code = GE, op1 = const0_rtx;
4087
4088   if (cmode == VOIDmode)
4089     cmode = GET_MODE (op0);
4090
4091   if (swap_commutative_operands_p (op2, op3)
4092       && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4093           != UNKNOWN))
4094     {
4095       tem = op2;
4096       op2 = op3;
4097       op3 = tem;
4098       code = reversed;
4099     }
4100
4101   if (mode == VOIDmode)
4102     mode = GET_MODE (op2);
4103
4104   icode = movcc_gen_code[mode];
4105
4106   if (icode == CODE_FOR_nothing)
4107     return 0;
4108
4109   if (flag_force_mem)
4110     {
4111       op2 = force_not_mem (op2);
4112       op3 = force_not_mem (op3);
4113     }
4114
4115   if (target)
4116     target = protect_from_queue (target, 1);
4117   else
4118     target = gen_reg_rtx (mode);
4119
4120   subtarget = target;
4121
4122   emit_queue ();
4123
4124   op2 = protect_from_queue (op2, 0);
4125   op3 = protect_from_queue (op3, 0);
4126
4127   /* If the insn doesn't accept these operands, put them in pseudos.  */
4128
4129   if (! (*insn_data[icode].operand[0].predicate)
4130       (subtarget, insn_data[icode].operand[0].mode))
4131     subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
4132
4133   if (! (*insn_data[icode].operand[2].predicate)
4134       (op2, insn_data[icode].operand[2].mode))
4135     op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
4136
4137   if (! (*insn_data[icode].operand[3].predicate)
4138       (op3, insn_data[icode].operand[3].mode))
4139     op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
4140
4141   /* Everything should now be in the suitable form, so emit the compare insn
4142      and then the conditional move.  */
4143
4144   comparison 
4145     = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
4146
4147   /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)?  */
4148   /* We can get const0_rtx or const_true_rtx in some circumstances.  Just
4149      return NULL and let the caller figure out how best to deal with this
4150      situation.  */
4151   if (GET_CODE (comparison) != code)
4152     return NULL_RTX;
4153   
4154   insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
4155
4156   /* If that failed, then give up.  */
4157   if (insn == 0)
4158     return 0;
4159
4160   emit_insn (insn);
4161
4162   if (subtarget != target)
4163     convert_move (target, subtarget, 0);
4164
4165   return target;
4166 }
4167
4168 /* Return non-zero if a conditional move of mode MODE is supported.
4169
4170    This function is for combine so it can tell whether an insn that looks
4171    like a conditional move is actually supported by the hardware.  If we
4172    guess wrong we lose a bit on optimization, but that's it.  */
4173 /* ??? sparc64 supports conditionally moving integers values based on fp
4174    comparisons, and vice versa.  How do we handle them?  */
4175
4176 int
4177 can_conditionally_move_p (mode)
4178      enum machine_mode mode;
4179 {
4180   if (movcc_gen_code[mode] != CODE_FOR_nothing)
4181     return 1;
4182
4183   return 0;
4184 }
4185
4186 #endif /* HAVE_conditional_move */
4187 \f
4188 /* These functions generate an insn body and return it
4189    rather than emitting the insn.
4190
4191    They do not protect from queued increments,
4192    because they may be used 1) in protect_from_queue itself
4193    and 2) in other passes where there is no queue.  */
4194
4195 /* Generate and return an insn body to add Y to X.  */
4196
4197 rtx
4198 gen_add2_insn (x, y)
4199      rtx x, y;
4200 {
4201   int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code; 
4202
4203   if (! ((*insn_data[icode].operand[0].predicate)
4204          (x, insn_data[icode].operand[0].mode))
4205       || ! ((*insn_data[icode].operand[1].predicate)
4206             (x, insn_data[icode].operand[1].mode))
4207       || ! ((*insn_data[icode].operand[2].predicate)
4208             (y, insn_data[icode].operand[2].mode)))
4209     abort ();
4210
4211   return (GEN_FCN (icode) (x, x, y));
4212 }
4213
4214 /* Generate and return an insn body to add r1 and c,
4215    storing the result in r0.  */
4216 rtx
4217 gen_add3_insn (r0, r1, c)
4218      rtx r0, r1, c;
4219 {
4220   int icode = (int) add_optab->handlers[(int) GET_MODE (r0)].insn_code;
4221
4222     if (icode == CODE_FOR_nothing
4223       || ! ((*insn_data[icode].operand[0].predicate)
4224             (r0, insn_data[icode].operand[0].mode))
4225       || ! ((*insn_data[icode].operand[1].predicate)
4226             (r1, insn_data[icode].operand[1].mode))
4227       || ! ((*insn_data[icode].operand[2].predicate)
4228             (c, insn_data[icode].operand[2].mode)))
4229     return NULL_RTX;
4230
4231   return (GEN_FCN (icode) (r0, r1, c));
4232 }
4233
4234 int
4235 have_add2_insn (x, y)
4236      rtx x, y;
4237 {
4238   int icode;
4239
4240   if (GET_MODE (x) == VOIDmode)
4241     abort ();
4242
4243   icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code; 
4244
4245   if (icode == CODE_FOR_nothing)
4246     return 0;
4247
4248   if (! ((*insn_data[icode].operand[0].predicate)
4249          (x, insn_data[icode].operand[0].mode))
4250       || ! ((*insn_data[icode].operand[1].predicate)
4251             (x, insn_data[icode].operand[1].mode))
4252       || ! ((*insn_data[icode].operand[2].predicate)
4253             (y, insn_data[icode].operand[2].mode)))
4254     return 0;
4255
4256   return 1;
4257 }
4258
4259 /* Generate and return an insn body to subtract Y from X.  */
4260
4261 rtx
4262 gen_sub2_insn (x, y)
4263      rtx x, y;
4264 {
4265   int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code; 
4266
4267   if (! ((*insn_data[icode].operand[0].predicate)
4268          (x, insn_data[icode].operand[0].mode))
4269       || ! ((*insn_data[icode].operand[1].predicate)
4270             (x, insn_data[icode].operand[1].mode))
4271       || ! ((*insn_data[icode].operand[2].predicate)
4272             (y, insn_data[icode].operand[2].mode)))
4273     abort ();
4274
4275   return (GEN_FCN (icode) (x, x, y));
4276 }
4277
4278 /* Generate and return an insn body to subtract r1 and c,
4279    storing the result in r0.  */
4280 rtx
4281 gen_sub3_insn (r0, r1, c)
4282      rtx r0, r1, c;
4283 {
4284   int icode = (int) sub_optab->handlers[(int) GET_MODE (r0)].insn_code;
4285
4286     if (icode == CODE_FOR_nothing
4287       || ! ((*insn_data[icode].operand[0].predicate)
4288             (r0, insn_data[icode].operand[0].mode))
4289       || ! ((*insn_data[icode].operand[1].predicate)
4290             (r1, insn_data[icode].operand[1].mode))
4291       || ! ((*insn_data[icode].operand[2].predicate)
4292             (c, insn_data[icode].operand[2].mode)))
4293     return NULL_RTX;
4294
4295   return (GEN_FCN (icode) (r0, r1, c));
4296 }
4297
4298 int
4299 have_sub2_insn (x, y)
4300      rtx x, y;
4301 {
4302   int icode;
4303
4304   if (GET_MODE (x) == VOIDmode)
4305     abort ();
4306
4307   icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code; 
4308
4309   if (icode == CODE_FOR_nothing)
4310     return 0;
4311
4312   if (! ((*insn_data[icode].operand[0].predicate)
4313          (x, insn_data[icode].operand[0].mode))
4314       || ! ((*insn_data[icode].operand[1].predicate)
4315             (x, insn_data[icode].operand[1].mode))
4316       || ! ((*insn_data[icode].operand[2].predicate)
4317             (y, insn_data[icode].operand[2].mode)))
4318     return 0;
4319
4320   return 1;
4321 }
4322
4323 /* Generate the body of an instruction to copy Y into X.
4324    It may be a list of insns, if one insn isn't enough.  */
4325
4326 rtx
4327 gen_move_insn (x, y)
4328      rtx x, y;
4329 {
4330   enum machine_mode mode = GET_MODE (x);
4331   enum insn_code insn_code;
4332   rtx seq;
4333
4334   if (mode == VOIDmode)
4335     mode = GET_MODE (y); 
4336
4337   insn_code = mov_optab->handlers[(int) mode].insn_code;
4338
4339   /* Handle MODE_CC modes:  If we don't have a special move insn for this mode,
4340      find a mode to do it in.  If we have a movcc, use it.  Otherwise,
4341      find the MODE_INT mode of the same width.  */
4342
4343   if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
4344     {
4345       enum machine_mode tmode = VOIDmode;
4346       rtx x1 = x, y1 = y;
4347
4348       if (mode != CCmode
4349           && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
4350         tmode = CCmode;
4351       else
4352         for (tmode = QImode; tmode != VOIDmode;
4353              tmode = GET_MODE_WIDER_MODE (tmode))
4354           if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
4355             break;
4356
4357       if (tmode == VOIDmode)
4358         abort ();
4359
4360       /* Get X and Y in TMODE.  We can't use gen_lowpart here because it
4361          may call change_address which is not appropriate if we were
4362          called when a reload was in progress.  We don't have to worry
4363          about changing the address since the size in bytes is supposed to
4364          be the same.  Copy the MEM to change the mode and move any
4365          substitutions from the old MEM to the new one.  */
4366
4367       if (reload_in_progress)
4368         {
4369           x = gen_lowpart_common (tmode, x1);
4370           if (x == 0 && GET_CODE (x1) == MEM)
4371             {
4372               x = adjust_address_nv (x1, tmode, 0);
4373               copy_replacements (x1, x);
4374             }
4375
4376           y = gen_lowpart_common (tmode, y1);
4377           if (y == 0 && GET_CODE (y1) == MEM)
4378             {
4379               y = adjust_address_nv (y1, tmode, 0);
4380               copy_replacements (y1, y);
4381             }
4382         }
4383       else
4384         {
4385           x = gen_lowpart (tmode, x);
4386           y = gen_lowpart (tmode, y);
4387         }
4388           
4389       insn_code = mov_optab->handlers[(int) tmode].insn_code;
4390       return (GEN_FCN (insn_code) (x, y));
4391     }
4392
4393   start_sequence ();
4394   emit_move_insn_1 (x, y);
4395   seq = get_insns ();
4396   end_sequence ();
4397   return seq;
4398 }
4399 \f
4400 /* Return the insn code used to extend FROM_MODE to TO_MODE.
4401    UNSIGNEDP specifies zero-extension instead of sign-extension.  If
4402    no such operation exists, CODE_FOR_nothing will be returned.  */
4403
4404 enum insn_code
4405 can_extend_p (to_mode, from_mode, unsignedp)
4406      enum machine_mode to_mode, from_mode;
4407      int unsignedp;
4408 {
4409 #ifdef HAVE_ptr_extend
4410   if (unsignedp < 0)
4411     return CODE_FOR_ptr_extend;
4412   else
4413 #endif
4414     return extendtab[(int) to_mode][(int) from_mode][unsignedp != 0];
4415 }
4416
4417 /* Generate the body of an insn to extend Y (with mode MFROM)
4418    into X (with mode MTO).  Do zero-extension if UNSIGNEDP is nonzero.  */
4419
4420 rtx
4421 gen_extend_insn (x, y, mto, mfrom, unsignedp)
4422      rtx x, y;
4423      enum machine_mode mto, mfrom;
4424      int unsignedp;
4425 {
4426   return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp != 0]) (x, y));
4427 }
4428 \f
4429 /* can_fix_p and can_float_p say whether the target machine
4430    can directly convert a given fixed point type to
4431    a given floating point type, or vice versa.
4432    The returned value is the CODE_FOR_... value to use,
4433    or CODE_FOR_nothing if these modes cannot be directly converted.
4434
4435    *TRUNCP_PTR is set to 1 if it is necessary to output
4436    an explicit FTRUNC insn before the fix insn; otherwise 0.  */
4437
4438 static enum insn_code
4439 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
4440      enum machine_mode fltmode, fixmode;
4441      int unsignedp;
4442      int *truncp_ptr;
4443 {
4444   *truncp_ptr = 0;
4445   if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp != 0]
4446       != CODE_FOR_nothing)
4447     return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp != 0];
4448
4449   if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
4450     {
4451       *truncp_ptr = 1;
4452       return fixtab[(int) fltmode][(int) fixmode][unsignedp != 0];
4453     }
4454   return CODE_FOR_nothing;
4455 }
4456
4457 static enum insn_code
4458 can_float_p (fltmode, fixmode, unsignedp)
4459      enum machine_mode fixmode, fltmode;
4460      int unsignedp;
4461 {
4462   return floattab[(int) fltmode][(int) fixmode][unsignedp != 0];
4463 }
4464 \f
4465 /* Generate code to convert FROM to floating point
4466    and store in TO.  FROM must be fixed point and not VOIDmode.
4467    UNSIGNEDP nonzero means regard FROM as unsigned.
4468    Normally this is done by correcting the final value
4469    if it is negative.  */
4470
4471 void
4472 expand_float (to, from, unsignedp)
4473      rtx to, from;
4474      int unsignedp;
4475 {
4476   enum insn_code icode;
4477   rtx target = to;
4478   enum machine_mode fmode, imode;
4479
4480   /* Crash now, because we won't be able to decide which mode to use.  */
4481   if (GET_MODE (from) == VOIDmode)
4482     abort ();
4483
4484   /* Look for an insn to do the conversion.  Do it in the specified
4485      modes if possible; otherwise convert either input, output or both to
4486      wider mode.  If the integer mode is wider than the mode of FROM,
4487      we can do the conversion signed even if the input is unsigned.  */
4488
4489   for (imode = GET_MODE (from); imode != VOIDmode;
4490        imode = GET_MODE_WIDER_MODE (imode))
4491     for (fmode = GET_MODE (to); fmode != VOIDmode;
4492          fmode = GET_MODE_WIDER_MODE (fmode))
4493       {
4494         int doing_unsigned = unsignedp;
4495
4496         if (fmode != GET_MODE (to)
4497             && significand_size (fmode) < GET_MODE_BITSIZE (GET_MODE (from)))
4498           continue;
4499
4500         icode = can_float_p (fmode, imode, unsignedp);
4501         if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
4502           icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
4503
4504         if (icode != CODE_FOR_nothing)
4505           {
4506             to = protect_from_queue (to, 1);
4507             from = protect_from_queue (from, 0);
4508
4509             if (imode != GET_MODE (from))
4510               from = convert_to_mode (imode, from, unsignedp);
4511
4512             if (fmode != GET_MODE (to))
4513               target = gen_reg_rtx (fmode);
4514
4515             emit_unop_insn (icode, target, from,
4516                             doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
4517
4518             if (target != to)
4519               convert_move (to, target, 0);
4520             return;
4521           }
4522     }
4523
4524   /* Unsigned integer, and no way to convert directly.
4525      Convert as signed, then conditionally adjust the result.  */
4526   if (unsignedp)
4527     {
4528       rtx label = gen_label_rtx ();
4529       rtx temp;
4530       REAL_VALUE_TYPE offset;
4531
4532       emit_queue ();
4533
4534       to = protect_from_queue (to, 1);
4535       from = protect_from_queue (from, 0);
4536
4537       if (flag_force_mem)
4538         from = force_not_mem (from);
4539
4540       /* Look for a usable floating mode FMODE wider than the source and at
4541          least as wide as the target.  Using FMODE will avoid rounding woes
4542          with unsigned values greater than the signed maximum value.  */
4543
4544       for (fmode = GET_MODE (to);  fmode != VOIDmode;
4545            fmode = GET_MODE_WIDER_MODE (fmode))
4546         if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
4547             && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
4548           break;
4549
4550       if (fmode == VOIDmode)
4551         {
4552           /* There is no such mode.  Pretend the target is wide enough.  */
4553           fmode = GET_MODE (to);
4554
4555           /* Avoid double-rounding when TO is narrower than FROM.  */
4556           if ((significand_size (fmode) + 1)
4557               < GET_MODE_BITSIZE (GET_MODE (from)))
4558             {
4559               rtx temp1;
4560               rtx neglabel = gen_label_rtx ();
4561
4562               /* Don't use TARGET if it isn't a register, is a hard register, 
4563                  or is the wrong mode.  */
4564               if (GET_CODE (target) != REG
4565                   || REGNO (target) < FIRST_PSEUDO_REGISTER
4566                   || GET_MODE (target) != fmode)
4567                 target = gen_reg_rtx (fmode);
4568
4569               imode = GET_MODE (from);
4570               do_pending_stack_adjust ();
4571
4572               /* Test whether the sign bit is set.  */
4573               emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
4574                                        0, neglabel);
4575
4576               /* The sign bit is not set.  Convert as signed.  */
4577               expand_float (target, from, 0);
4578               emit_jump_insn (gen_jump (label));
4579               emit_barrier ();
4580
4581               /* The sign bit is set.
4582                  Convert to a usable (positive signed) value by shifting right
4583                  one bit, while remembering if a nonzero bit was shifted
4584                  out; i.e., compute  (from & 1) | (from >> 1).  */
4585
4586               emit_label (neglabel);
4587               temp = expand_binop (imode, and_optab, from, const1_rtx,
4588                                    NULL_RTX, 1, OPTAB_LIB_WIDEN);
4589               temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
4590                                     NULL_RTX, 1);
4591               temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1, 
4592                                    OPTAB_LIB_WIDEN);
4593               expand_float (target, temp, 0);
4594
4595               /* Multiply by 2 to undo the shift above.  */
4596               temp = expand_binop (fmode, add_optab, target, target,
4597                                      target, 0, OPTAB_LIB_WIDEN);
4598               if (temp != target)
4599                 emit_move_insn (target, temp);
4600
4601               do_pending_stack_adjust ();
4602               emit_label (label);
4603               goto done;
4604             }
4605         }
4606
4607       /* If we are about to do some arithmetic to correct for an
4608          unsigned operand, do it in a pseudo-register.  */
4609
4610       if (GET_MODE (to) != fmode
4611           || GET_CODE (to) != REG || REGNO (to) < FIRST_PSEUDO_REGISTER)
4612         target = gen_reg_rtx (fmode);
4613
4614       /* Convert as signed integer to floating.  */
4615       expand_float (target, from, 0);
4616
4617       /* If FROM is negative (and therefore TO is negative),
4618          correct its value by 2**bitwidth.  */
4619
4620       do_pending_stack_adjust ();
4621       emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
4622                                0, label);
4623
4624       /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
4625          Rather than setting up a dconst_dot_5, let's hope SCO
4626          fixes the bug.  */
4627       offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
4628       temp = expand_binop (fmode, add_optab, target,
4629                            CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
4630                            target, 0, OPTAB_LIB_WIDEN);
4631       if (temp != target)
4632         emit_move_insn (target, temp);
4633
4634       do_pending_stack_adjust ();
4635       emit_label (label);
4636       goto done;
4637     }
4638
4639   /* No hardware instruction available; call a library routine to convert from
4640      SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode.  */
4641     {
4642       rtx libfcn;
4643       rtx insns;
4644       rtx value;
4645
4646       to = protect_from_queue (to, 1);
4647       from = protect_from_queue (from, 0);
4648
4649       if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
4650         from = convert_to_mode (SImode, from, unsignedp);
4651
4652       if (flag_force_mem)
4653         from = force_not_mem (from);
4654
4655       if (GET_MODE (to) == SFmode)
4656         {
4657           if (GET_MODE (from) == SImode)
4658             libfcn = floatsisf_libfunc;
4659           else if (GET_MODE (from) == DImode)
4660             libfcn = floatdisf_libfunc;
4661           else if (GET_MODE (from) == TImode)
4662             libfcn = floattisf_libfunc;
4663           else
4664             abort ();
4665         }
4666       else if (GET_MODE (to) == DFmode)
4667         {
4668           if (GET_MODE (from) == SImode)
4669             libfcn = floatsidf_libfunc;
4670           else if (GET_MODE (from) == DImode)
4671             libfcn = floatdidf_libfunc;
4672           else if (GET_MODE (from) == TImode)
4673             libfcn = floattidf_libfunc;
4674           else
4675             abort ();
4676         }
4677       else if (GET_MODE (to) == XFmode)
4678         {
4679           if (GET_MODE (from) == SImode)
4680             libfcn = floatsixf_libfunc;
4681           else if (GET_MODE (from) == DImode)
4682             libfcn = floatdixf_libfunc;
4683           else if (GET_MODE (from) == TImode)
4684             libfcn = floattixf_libfunc;
4685           else
4686             abort ();
4687         }
4688       else if (GET_MODE (to) == TFmode)
4689         {
4690           if (GET_MODE (from) == SImode)
4691             libfcn = floatsitf_libfunc;
4692           else if (GET_MODE (from) == DImode)
4693             libfcn = floatditf_libfunc;
4694           else if (GET_MODE (from) == TImode)
4695             libfcn = floattitf_libfunc;
4696           else
4697             abort ();
4698         }
4699       else
4700         abort ();
4701
4702       start_sequence ();
4703
4704       value = emit_library_call_value (libfcn, NULL_RTX, LCT_CONST,
4705                                        GET_MODE (to), 1, from,
4706                                        GET_MODE (from));
4707       insns = get_insns ();
4708       end_sequence ();
4709
4710       emit_libcall_block (insns, target, value,
4711                           gen_rtx_FLOAT (GET_MODE (to), from));
4712     }
4713
4714  done:
4715
4716   /* Copy result to requested destination
4717      if we have been computing in a temp location.  */
4718
4719   if (target != to)
4720     {
4721       if (GET_MODE (target) == GET_MODE (to))
4722         emit_move_insn (to, target);
4723       else
4724         convert_move (to, target, 0);
4725     }
4726 }
4727 \f
4728 /* expand_fix: generate code to convert FROM to fixed point
4729    and store in TO.  FROM must be floating point.  */
4730
4731 static rtx
4732 ftruncify (x)
4733      rtx x;
4734 {
4735   rtx temp = gen_reg_rtx (GET_MODE (x));
4736   return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
4737 }
4738
4739 void
4740 expand_fix (to, from, unsignedp)
4741      rtx to, from;
4742      int unsignedp;
4743 {
4744   enum insn_code icode;
4745   rtx target = to;
4746   enum machine_mode fmode, imode;
4747   int must_trunc = 0;
4748   rtx libfcn = 0;
4749
4750   /* We first try to find a pair of modes, one real and one integer, at
4751      least as wide as FROM and TO, respectively, in which we can open-code
4752      this conversion.  If the integer mode is wider than the mode of TO,
4753      we can do the conversion either signed or unsigned.  */
4754
4755   for (fmode = GET_MODE (from); fmode != VOIDmode;
4756        fmode = GET_MODE_WIDER_MODE (fmode))
4757     for (imode = GET_MODE (to); imode != VOIDmode;
4758          imode = GET_MODE_WIDER_MODE (imode))
4759       {
4760         int doing_unsigned = unsignedp;
4761
4762         icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
4763         if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
4764           icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
4765
4766         if (icode != CODE_FOR_nothing)
4767           {
4768             to = protect_from_queue (to, 1);
4769             from = protect_from_queue (from, 0);
4770
4771             if (fmode != GET_MODE (from))
4772               from = convert_to_mode (fmode, from, 0);
4773
4774             if (must_trunc)
4775               from = ftruncify (from);
4776
4777             if (imode != GET_MODE (to))
4778               target = gen_reg_rtx (imode);
4779
4780             emit_unop_insn (icode, target, from,
4781                             doing_unsigned ? UNSIGNED_FIX : FIX);
4782             if (target != to)
4783               convert_move (to, target, unsignedp);
4784             return;
4785           }
4786       }
4787
4788   /* For an unsigned conversion, there is one more way to do it.
4789      If we have a signed conversion, we generate code that compares
4790      the real value to the largest representable positive number.  If if
4791      is smaller, the conversion is done normally.  Otherwise, subtract
4792      one plus the highest signed number, convert, and add it back.
4793
4794      We only need to check all real modes, since we know we didn't find
4795      anything with a wider integer mode.  */
4796
4797   if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
4798     for (fmode = GET_MODE (from); fmode != VOIDmode;
4799          fmode = GET_MODE_WIDER_MODE (fmode))
4800       /* Make sure we won't lose significant bits doing this.  */
4801       if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
4802           && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
4803                                             &must_trunc))
4804         {
4805           int bitsize;
4806           REAL_VALUE_TYPE offset;
4807           rtx limit, lab1, lab2, insn;
4808
4809           bitsize = GET_MODE_BITSIZE (GET_MODE (to));
4810           offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
4811           limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
4812           lab1 = gen_label_rtx ();
4813           lab2 = gen_label_rtx ();
4814
4815           emit_queue ();
4816           to = protect_from_queue (to, 1);
4817           from = protect_from_queue (from, 0);
4818
4819           if (flag_force_mem)
4820             from = force_not_mem (from);
4821
4822           if (fmode != GET_MODE (from))
4823             from = convert_to_mode (fmode, from, 0);
4824
4825           /* See if we need to do the subtraction.  */
4826           do_pending_stack_adjust ();
4827           emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
4828                                    0, lab1);
4829
4830           /* If not, do the signed "fix" and branch around fixup code.  */
4831           expand_fix (to, from, 0);
4832           emit_jump_insn (gen_jump (lab2));
4833           emit_barrier ();
4834
4835           /* Otherwise, subtract 2**(N-1), convert to signed number,
4836              then add 2**(N-1).  Do the addition using XOR since this
4837              will often generate better code.  */
4838           emit_label (lab1);
4839           target = expand_binop (GET_MODE (from), sub_optab, from, limit,
4840                                  NULL_RTX, 0, OPTAB_LIB_WIDEN);
4841           expand_fix (to, target, 0);
4842           target = expand_binop (GET_MODE (to), xor_optab, to,
4843                                  gen_int_mode
4844                                  ((HOST_WIDE_INT) 1 << (bitsize - 1),
4845                                   GET_MODE (to)),
4846                                  to, 1, OPTAB_LIB_WIDEN);
4847
4848           if (target != to)
4849             emit_move_insn (to, target);
4850
4851           emit_label (lab2);
4852
4853           if (mov_optab->handlers[(int) GET_MODE (to)].insn_code
4854               != CODE_FOR_nothing)
4855             {
4856               /* Make a place for a REG_NOTE and add it.  */
4857               insn = emit_move_insn (to, to);
4858               set_unique_reg_note (insn,
4859                                    REG_EQUAL,
4860                                    gen_rtx_fmt_e (UNSIGNED_FIX,
4861                                                   GET_MODE (to),
4862                                                   copy_rtx (from)));
4863             }
4864
4865           return;
4866         }
4867
4868   /* We can't do it with an insn, so use a library call.  But first ensure
4869      that the mode of TO is at least as wide as SImode, since those are the
4870      only library calls we know about.  */
4871
4872   if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
4873     {
4874       target = gen_reg_rtx (SImode);
4875
4876       expand_fix (target, from, unsignedp);
4877     }
4878   else if (GET_MODE (from) == SFmode)
4879     {
4880       if (GET_MODE (to) == SImode)
4881         libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
4882       else if (GET_MODE (to) == DImode)
4883         libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
4884       else if (GET_MODE (to) == TImode)
4885         libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
4886       else
4887         abort ();
4888     }
4889   else if (GET_MODE (from) == DFmode)
4890     {
4891       if (GET_MODE (to) == SImode)
4892         libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
4893       else if (GET_MODE (to) == DImode)
4894         libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
4895       else if (GET_MODE (to) == TImode)
4896         libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
4897       else
4898         abort ();
4899     }
4900   else if (GET_MODE (from) == XFmode)
4901     {
4902       if (GET_MODE (to) == SImode)
4903         libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
4904       else if (GET_MODE (to) == DImode)
4905         libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
4906       else if (GET_MODE (to) == TImode)
4907         libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
4908       else
4909         abort ();
4910     }
4911   else if (GET_MODE (from) == TFmode)
4912     {
4913       if (GET_MODE (to) == SImode)
4914         libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
4915       else if (GET_MODE (to) == DImode)
4916         libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
4917       else if (GET_MODE (to) == TImode)
4918         libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
4919       else
4920         abort ();
4921     }
4922   else
4923     abort ();
4924
4925   if (libfcn)
4926     {
4927       rtx insns;
4928       rtx value;
4929
4930       to = protect_from_queue (to, 1);
4931       from = protect_from_queue (from, 0);
4932
4933       if (flag_force_mem)
4934         from = force_not_mem (from);
4935
4936       start_sequence ();
4937
4938       value = emit_library_call_value (libfcn, NULL_RTX, LCT_CONST,
4939                                        GET_MODE (to), 1, from,
4940                                        GET_MODE (from));
4941       insns = get_insns ();
4942       end_sequence ();
4943
4944       emit_libcall_block (insns, target, value,
4945                           gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
4946                                          GET_MODE (to), from));
4947     }
4948       
4949   if (target != to)
4950     {
4951       if (GET_MODE (to) == GET_MODE (target))
4952         emit_move_insn (to, target);
4953       else
4954         convert_move (to, target, 0);
4955     }
4956 }
4957 \f
4958 /* Report whether we have an instruction to perform the operation
4959    specified by CODE on operands of mode MODE.  */
4960 int
4961 have_insn_for (code, mode)
4962      enum rtx_code code;
4963      enum machine_mode mode;
4964 {
4965   return (code_to_optab[(int) code] != 0
4966           && (code_to_optab[(int) code]->handlers[(int) mode].insn_code
4967               != CODE_FOR_nothing));
4968 }
4969
4970 /* Create a blank optab.  */
4971 static optab
4972 new_optab ()
4973 {
4974   int i;
4975   optab op = (optab) ggc_alloc (sizeof (struct optab));
4976   for (i = 0; i < NUM_MACHINE_MODES; i++)
4977     {
4978       op->handlers[i].insn_code = CODE_FOR_nothing;
4979       op->handlers[i].libfunc = 0;
4980     }
4981
4982   return op;
4983 }
4984
4985 /* Same, but fill in its code as CODE, and write it into the
4986    code_to_optab table.  */
4987 static inline optab
4988 init_optab (code)
4989      enum rtx_code code;
4990 {
4991   optab op = new_optab ();
4992   op->code = code;
4993   code_to_optab[(int) code] = op;
4994   return op;
4995 }
4996
4997 /* Same, but fill in its code as CODE, and do _not_ write it into
4998    the code_to_optab table.  */
4999 static inline optab
5000 init_optabv (code)
5001      enum rtx_code code;
5002 {
5003   optab op = new_optab ();
5004   op->code = code;
5005   return op;
5006 }
5007
5008 /* Initialize the libfunc fields of an entire group of entries in some
5009    optab.  Each entry is set equal to a string consisting of a leading
5010    pair of underscores followed by a generic operation name followed by
5011    a mode name (downshifted to lower case) followed by a single character
5012    representing the number of operands for the given operation (which is
5013    usually one of the characters '2', '3', or '4').
5014
5015    OPTABLE is the table in which libfunc fields are to be initialized.
5016    FIRST_MODE is the first machine mode index in the given optab to
5017      initialize.
5018    LAST_MODE is the last machine mode index in the given optab to
5019      initialize.
5020    OPNAME is the generic (string) name of the operation.
5021    SUFFIX is the character which specifies the number of operands for
5022      the given generic operation.
5023 */
5024
5025 static void
5026 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
5027     optab optable;
5028     int first_mode;
5029     int last_mode;
5030     const char *opname;
5031     int suffix;
5032 {
5033   int mode;
5034   unsigned opname_len = strlen (opname);
5035
5036   for (mode = first_mode; (int) mode <= (int) last_mode;
5037        mode = (enum machine_mode) ((int) mode + 1))
5038     {
5039       const char *mname = GET_MODE_NAME(mode);
5040       unsigned mname_len = strlen (mname);
5041       char *libfunc_name = alloca (2 + opname_len + mname_len + 1 + 1);
5042       char *p;
5043       const char *q;
5044
5045       p = libfunc_name;
5046       *p++ = '_';
5047       *p++ = '_';
5048       for (q = opname; *q; )
5049         *p++ = *q++;
5050       for (q = mname; *q; q++)
5051         *p++ = TOLOWER (*q);
5052       *p++ = suffix;
5053       *p = '\0';
5054
5055       optable->handlers[(int) mode].libfunc
5056         = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (libfunc_name,
5057                                                        p - libfunc_name));
5058     }
5059 }
5060
5061 /* Initialize the libfunc fields of an entire group of entries in some
5062    optab which correspond to all integer mode operations.  The parameters
5063    have the same meaning as similarly named ones for the `init_libfuncs'
5064    routine.  (See above).  */
5065
5066 static void
5067 init_integral_libfuncs (optable, opname, suffix)
5068     optab optable;
5069     const char *opname;
5070     int suffix;
5071 {
5072   init_libfuncs (optable, SImode, TImode, opname, suffix);
5073 }
5074
5075 /* Initialize the libfunc fields of an entire group of entries in some
5076    optab which correspond to all real mode operations.  The parameters
5077    have the same meaning as similarly named ones for the `init_libfuncs'
5078    routine.  (See above).  */
5079
5080 static void
5081 init_floating_libfuncs (optable, opname, suffix)
5082     optab optable;
5083     const char *opname;
5084     int suffix;
5085 {
5086   init_libfuncs (optable, SFmode, TFmode, opname, suffix);
5087 }
5088
5089 rtx
5090 init_one_libfunc (name)
5091      const char *name;
5092 {
5093   /* Create a FUNCTION_DECL that can be passed to
5094      targetm.encode_section_info.  */
5095   /* ??? We don't have any type information except for this is
5096      a function.  Pretend this is "int foo()".  */
5097   tree decl = build_decl (FUNCTION_DECL, get_identifier (name),
5098                           build_function_type (integer_type_node, NULL_TREE));
5099   DECL_ARTIFICIAL (decl) = 1;
5100   DECL_EXTERNAL (decl) = 1;
5101   TREE_PUBLIC (decl) = 1;
5102
5103   /* Return the symbol_ref from the mem rtx.  */
5104   return XEXP (DECL_RTL (decl), 0);
5105 }
5106
5107 /* Call this once to initialize the contents of the optabs
5108    appropriately for the current target machine.  */
5109
5110 void
5111 init_optabs ()
5112 {
5113   unsigned int i, j, k;
5114
5115   /* Start by initializing all tables to contain CODE_FOR_nothing.  */
5116
5117   for (i = 0; i < ARRAY_SIZE (fixtab); i++)
5118     for (j = 0; j < ARRAY_SIZE (fixtab[0]); j++)
5119       for (k = 0; k < ARRAY_SIZE (fixtab[0][0]); k++)
5120         fixtab[i][j][k] = CODE_FOR_nothing;
5121
5122   for (i = 0; i < ARRAY_SIZE (fixtrunctab); i++)
5123     for (j = 0; j < ARRAY_SIZE (fixtrunctab[0]); j++)
5124       for (k = 0; k < ARRAY_SIZE (fixtrunctab[0][0]); k++)
5125         fixtrunctab[i][j][k] = CODE_FOR_nothing;
5126
5127   for (i = 0; i < ARRAY_SIZE (floattab); i++)
5128     for (j = 0; j < ARRAY_SIZE (floattab[0]); j++)
5129       for (k = 0; k < ARRAY_SIZE (floattab[0][0]); k++)
5130         floattab[i][j][k] = CODE_FOR_nothing;
5131
5132   for (i = 0; i < ARRAY_SIZE (extendtab); i++)
5133     for (j = 0; j < ARRAY_SIZE (extendtab[0]); j++)
5134       for (k = 0; k < ARRAY_SIZE (extendtab[0][0]); k++)
5135         extendtab[i][j][k] = CODE_FOR_nothing;
5136
5137   for (i = 0; i < NUM_RTX_CODE; i++)
5138     setcc_gen_code[i] = CODE_FOR_nothing;
5139
5140 #ifdef HAVE_conditional_move
5141   for (i = 0; i < NUM_MACHINE_MODES; i++)
5142     movcc_gen_code[i] = CODE_FOR_nothing;
5143 #endif
5144
5145   add_optab = init_optab (PLUS);
5146   addv_optab = init_optabv (PLUS);
5147   sub_optab = init_optab (MINUS);
5148   subv_optab = init_optabv (MINUS);
5149   smul_optab = init_optab (MULT);
5150   smulv_optab = init_optabv (MULT);
5151   smul_highpart_optab = init_optab (UNKNOWN);
5152   umul_highpart_optab = init_optab (UNKNOWN);
5153   smul_widen_optab = init_optab (UNKNOWN);
5154   umul_widen_optab = init_optab (UNKNOWN);
5155   sdiv_optab = init_optab (DIV);
5156   sdivv_optab = init_optabv (DIV);
5157   sdivmod_optab = init_optab (UNKNOWN);
5158   udiv_optab = init_optab (UDIV);
5159   udivmod_optab = init_optab (UNKNOWN);
5160   smod_optab = init_optab (MOD);
5161   umod_optab = init_optab (UMOD);
5162   ftrunc_optab = init_optab (UNKNOWN);
5163   and_optab = init_optab (AND);
5164   ior_optab = init_optab (IOR);
5165   xor_optab = init_optab (XOR);
5166   ashl_optab = init_optab (ASHIFT);
5167   ashr_optab = init_optab (ASHIFTRT);
5168   lshr_optab = init_optab (LSHIFTRT);
5169   rotl_optab = init_optab (ROTATE);
5170   rotr_optab = init_optab (ROTATERT);
5171   smin_optab = init_optab (SMIN);
5172   smax_optab = init_optab (SMAX);
5173   umin_optab = init_optab (UMIN);
5174   umax_optab = init_optab (UMAX);
5175
5176   /* These three have codes assigned exclusively for the sake of
5177      have_insn_for.  */
5178   mov_optab = init_optab (SET);
5179   movstrict_optab = init_optab (STRICT_LOW_PART);
5180   cmp_optab = init_optab (COMPARE);
5181
5182   ucmp_optab = init_optab (UNKNOWN);
5183   tst_optab = init_optab (UNKNOWN);
5184   neg_optab = init_optab (NEG);
5185   negv_optab = init_optabv (NEG);
5186   abs_optab = init_optab (ABS);
5187   absv_optab = init_optabv (ABS);
5188   one_cmpl_optab = init_optab (NOT);
5189   ffs_optab = init_optab (FFS);
5190   sqrt_optab = init_optab (SQRT);
5191   sin_optab = init_optab (UNKNOWN);
5192   cos_optab = init_optab (UNKNOWN);
5193   strlen_optab = init_optab (UNKNOWN);
5194   cbranch_optab = init_optab (UNKNOWN);
5195   cmov_optab = init_optab (UNKNOWN);
5196   cstore_optab = init_optab (UNKNOWN);
5197   push_optab = init_optab (UNKNOWN);
5198
5199   for (i = 0; i < NUM_MACHINE_MODES; i++)
5200     {
5201       movstr_optab[i] = CODE_FOR_nothing;
5202       clrstr_optab[i] = CODE_FOR_nothing;
5203
5204 #ifdef HAVE_SECONDARY_RELOADS
5205       reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
5206 #endif
5207     }
5208
5209   /* Fill in the optabs with the insns we support.  */
5210   init_all_optabs ();
5211
5212 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
5213   /* This flag says the same insns that convert to a signed fixnum
5214      also convert validly to an unsigned one.  */
5215   for (i = 0; i < NUM_MACHINE_MODES; i++)
5216     for (j = 0; j < NUM_MACHINE_MODES; j++)
5217       fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
5218 #endif
5219
5220   /* Initialize the optabs with the names of the library functions.  */
5221   init_integral_libfuncs (add_optab, "add", '3');
5222   init_floating_libfuncs (add_optab, "add", '3');
5223   init_integral_libfuncs (addv_optab, "addv", '3');
5224   init_floating_libfuncs (addv_optab, "add", '3');
5225   init_integral_libfuncs (sub_optab, "sub", '3');
5226   init_floating_libfuncs (sub_optab, "sub", '3');
5227   init_integral_libfuncs (subv_optab, "subv", '3');
5228   init_floating_libfuncs (subv_optab, "sub", '3');
5229   init_integral_libfuncs (smul_optab, "mul", '3');
5230   init_floating_libfuncs (smul_optab, "mul", '3');
5231   init_integral_libfuncs (smulv_optab, "mulv", '3');
5232   init_floating_libfuncs (smulv_optab, "mul", '3');
5233   init_integral_libfuncs (sdiv_optab, "div", '3');
5234   init_floating_libfuncs (sdiv_optab, "div", '3');
5235   init_integral_libfuncs (sdivv_optab, "divv", '3');
5236   init_integral_libfuncs (udiv_optab, "udiv", '3');
5237   init_integral_libfuncs (sdivmod_optab, "divmod", '4');
5238   init_integral_libfuncs (udivmod_optab, "udivmod", '4');
5239   init_integral_libfuncs (smod_optab, "mod", '3');
5240   init_integral_libfuncs (umod_optab, "umod", '3');
5241   init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
5242   init_integral_libfuncs (and_optab, "and", '3');
5243   init_integral_libfuncs (ior_optab, "ior", '3');
5244   init_integral_libfuncs (xor_optab, "xor", '3');
5245   init_integral_libfuncs (ashl_optab, "ashl", '3');
5246   init_integral_libfuncs (ashr_optab, "ashr", '3');
5247   init_integral_libfuncs (lshr_optab, "lshr", '3');
5248   init_integral_libfuncs (smin_optab, "min", '3');
5249   init_floating_libfuncs (smin_optab, "min", '3');
5250   init_integral_libfuncs (smax_optab, "max", '3');
5251   init_floating_libfuncs (smax_optab, "max", '3');
5252   init_integral_libfuncs (umin_optab, "umin", '3');
5253   init_integral_libfuncs (umax_optab, "umax", '3');
5254   init_integral_libfuncs (neg_optab, "neg", '2');
5255   init_floating_libfuncs (neg_optab, "neg", '2');
5256   init_integral_libfuncs (negv_optab, "negv", '2');
5257   init_floating_libfuncs (negv_optab, "neg", '2');
5258   init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
5259   init_integral_libfuncs (ffs_optab, "ffs", '2');
5260
5261   /* Comparison libcalls for integers MUST come in pairs, signed/unsigned.  */
5262   init_integral_libfuncs (cmp_optab, "cmp", '2');
5263   init_integral_libfuncs (ucmp_optab, "ucmp", '2');
5264   init_floating_libfuncs (cmp_optab, "cmp", '2');
5265
5266 #ifdef MULSI3_LIBCALL
5267   smul_optab->handlers[(int) SImode].libfunc
5268     = init_one_libfunc (MULSI3_LIBCALL);
5269 #endif
5270 #ifdef MULDI3_LIBCALL
5271   smul_optab->handlers[(int) DImode].libfunc
5272     = init_one_libfunc (MULDI3_LIBCALL);
5273 #endif
5274
5275 #ifdef DIVSI3_LIBCALL
5276   sdiv_optab->handlers[(int) SImode].libfunc
5277     = init_one_libfunc (DIVSI3_LIBCALL);
5278 #endif
5279 #ifdef DIVDI3_LIBCALL
5280   sdiv_optab->handlers[(int) DImode].libfunc
5281     = init_one_libfunc (DIVDI3_LIBCALL);
5282 #endif
5283
5284 #ifdef UDIVSI3_LIBCALL
5285   udiv_optab->handlers[(int) SImode].libfunc
5286     = init_one_libfunc (UDIVSI3_LIBCALL);
5287 #endif
5288 #ifdef UDIVDI3_LIBCALL
5289   udiv_optab->handlers[(int) DImode].libfunc
5290     = init_one_libfunc (UDIVDI3_LIBCALL);
5291 #endif
5292
5293 #ifdef MODSI3_LIBCALL
5294   smod_optab->handlers[(int) SImode].libfunc
5295     = init_one_libfunc (MODSI3_LIBCALL);
5296 #endif
5297 #ifdef MODDI3_LIBCALL
5298   smod_optab->handlers[(int) DImode].libfunc
5299     = init_one_libfunc (MODDI3_LIBCALL);
5300 #endif
5301
5302 #ifdef UMODSI3_LIBCALL
5303   umod_optab->handlers[(int) SImode].libfunc
5304     = init_one_libfunc (UMODSI3_LIBCALL);
5305 #endif
5306 #ifdef UMODDI3_LIBCALL
5307   umod_optab->handlers[(int) DImode].libfunc
5308     = init_one_libfunc (UMODDI3_LIBCALL);
5309 #endif
5310
5311   /* Use cabs for DC complex abs, since systems generally have cabs.
5312      Don't define any libcall for SCmode, so that cabs will be used.  */
5313   abs_optab->handlers[(int) DCmode].libfunc
5314     = init_one_libfunc ("cabs");
5315
5316   /* The ffs function operates on `int'.  */
5317   ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)].libfunc
5318     = init_one_libfunc ("ffs");
5319
5320   extendsfdf2_libfunc = init_one_libfunc ("__extendsfdf2");
5321   extendsfxf2_libfunc = init_one_libfunc ("__extendsfxf2");
5322   extendsftf2_libfunc = init_one_libfunc ("__extendsftf2");
5323   extenddfxf2_libfunc = init_one_libfunc ("__extenddfxf2");
5324   extenddftf2_libfunc = init_one_libfunc ("__extenddftf2");
5325
5326   truncdfsf2_libfunc = init_one_libfunc ("__truncdfsf2");
5327   truncxfsf2_libfunc = init_one_libfunc ("__truncxfsf2");
5328   trunctfsf2_libfunc = init_one_libfunc ("__trunctfsf2");
5329   truncxfdf2_libfunc = init_one_libfunc ("__truncxfdf2");
5330   trunctfdf2_libfunc = init_one_libfunc ("__trunctfdf2");
5331
5332   abort_libfunc = init_one_libfunc ("abort");
5333   memcpy_libfunc = init_one_libfunc ("memcpy");
5334   memmove_libfunc = init_one_libfunc ("memmove");
5335   bcopy_libfunc = init_one_libfunc ("bcopy");
5336   memcmp_libfunc = init_one_libfunc ("memcmp");
5337   bcmp_libfunc = init_one_libfunc ("__gcc_bcmp");
5338   memset_libfunc = init_one_libfunc ("memset");
5339   bzero_libfunc = init_one_libfunc ("bzero");
5340
5341   unwind_resume_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
5342                                             ? "_Unwind_SjLj_Resume"
5343                                             : "_Unwind_Resume");
5344 #ifndef DONT_USE_BUILTIN_SETJMP
5345   setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
5346   longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
5347 #else
5348   setjmp_libfunc = init_one_libfunc ("setjmp");
5349   longjmp_libfunc = init_one_libfunc ("longjmp");
5350 #endif
5351   unwind_sjlj_register_libfunc = init_one_libfunc ("_Unwind_SjLj_Register");
5352   unwind_sjlj_unregister_libfunc
5353     = init_one_libfunc ("_Unwind_SjLj_Unregister");
5354
5355   eqhf2_libfunc = init_one_libfunc ("__eqhf2");
5356   nehf2_libfunc = init_one_libfunc ("__nehf2");
5357   gthf2_libfunc = init_one_libfunc ("__gthf2");
5358   gehf2_libfunc = init_one_libfunc ("__gehf2");
5359   lthf2_libfunc = init_one_libfunc ("__lthf2");
5360   lehf2_libfunc = init_one_libfunc ("__lehf2");
5361   unordhf2_libfunc = init_one_libfunc ("__unordhf2");
5362
5363   eqsf2_libfunc = init_one_libfunc ("__eqsf2");
5364   nesf2_libfunc = init_one_libfunc ("__nesf2");
5365   gtsf2_libfunc = init_one_libfunc ("__gtsf2");
5366   gesf2_libfunc = init_one_libfunc ("__gesf2");
5367   ltsf2_libfunc = init_one_libfunc ("__ltsf2");
5368   lesf2_libfunc = init_one_libfunc ("__lesf2");
5369   unordsf2_libfunc = init_one_libfunc ("__unordsf2");
5370
5371   eqdf2_libfunc = init_one_libfunc ("__eqdf2");
5372   nedf2_libfunc = init_one_libfunc ("__nedf2");
5373   gtdf2_libfunc = init_one_libfunc ("__gtdf2");
5374   gedf2_libfunc = init_one_libfunc ("__gedf2");
5375   ltdf2_libfunc = init_one_libfunc ("__ltdf2");
5376   ledf2_libfunc = init_one_libfunc ("__ledf2");
5377   unorddf2_libfunc = init_one_libfunc ("__unorddf2");
5378
5379   eqxf2_libfunc = init_one_libfunc ("__eqxf2");
5380   nexf2_libfunc = init_one_libfunc ("__nexf2");
5381   gtxf2_libfunc = init_one_libfunc ("__gtxf2");
5382   gexf2_libfunc = init_one_libfunc ("__gexf2");
5383   ltxf2_libfunc = init_one_libfunc ("__ltxf2");
5384   lexf2_libfunc = init_one_libfunc ("__lexf2");
5385   unordxf2_libfunc = init_one_libfunc ("__unordxf2");
5386
5387   eqtf2_libfunc = init_one_libfunc ("__eqtf2");
5388   netf2_libfunc = init_one_libfunc ("__netf2");
5389   gttf2_libfunc = init_one_libfunc ("__gttf2");
5390   getf2_libfunc = init_one_libfunc ("__getf2");
5391   lttf2_libfunc = init_one_libfunc ("__lttf2");
5392   letf2_libfunc = init_one_libfunc ("__letf2");
5393   unordtf2_libfunc = init_one_libfunc ("__unordtf2");
5394
5395   floatsisf_libfunc = init_one_libfunc ("__floatsisf");
5396   floatdisf_libfunc = init_one_libfunc ("__floatdisf");
5397   floattisf_libfunc = init_one_libfunc ("__floattisf");
5398
5399   floatsidf_libfunc = init_one_libfunc ("__floatsidf");
5400   floatdidf_libfunc = init_one_libfunc ("__floatdidf");
5401   floattidf_libfunc = init_one_libfunc ("__floattidf");
5402
5403   floatsixf_libfunc = init_one_libfunc ("__floatsixf");
5404   floatdixf_libfunc = init_one_libfunc ("__floatdixf");
5405   floattixf_libfunc = init_one_libfunc ("__floattixf");
5406
5407   floatsitf_libfunc = init_one_libfunc ("__floatsitf");
5408   floatditf_libfunc = init_one_libfunc ("__floatditf");
5409   floattitf_libfunc = init_one_libfunc ("__floattitf");
5410
5411   fixsfsi_libfunc = init_one_libfunc ("__fixsfsi");
5412   fixsfdi_libfunc = init_one_libfunc ("__fixsfdi");
5413   fixsfti_libfunc = init_one_libfunc ("__fixsfti");
5414
5415   fixdfsi_libfunc = init_one_libfunc ("__fixdfsi");
5416   fixdfdi_libfunc = init_one_libfunc ("__fixdfdi");
5417   fixdfti_libfunc = init_one_libfunc ("__fixdfti");
5418
5419   fixxfsi_libfunc = init_one_libfunc ("__fixxfsi");
5420   fixxfdi_libfunc = init_one_libfunc ("__fixxfdi");
5421   fixxfti_libfunc = init_one_libfunc ("__fixxfti");
5422
5423   fixtfsi_libfunc = init_one_libfunc ("__fixtfsi");
5424   fixtfdi_libfunc = init_one_libfunc ("__fixtfdi");
5425   fixtfti_libfunc = init_one_libfunc ("__fixtfti");
5426
5427   fixunssfsi_libfunc = init_one_libfunc ("__fixunssfsi");
5428   fixunssfdi_libfunc = init_one_libfunc ("__fixunssfdi");
5429   fixunssfti_libfunc = init_one_libfunc ("__fixunssfti");
5430
5431   fixunsdfsi_libfunc = init_one_libfunc ("__fixunsdfsi");
5432   fixunsdfdi_libfunc = init_one_libfunc ("__fixunsdfdi");
5433   fixunsdfti_libfunc = init_one_libfunc ("__fixunsdfti");
5434
5435   fixunsxfsi_libfunc = init_one_libfunc ("__fixunsxfsi");
5436   fixunsxfdi_libfunc = init_one_libfunc ("__fixunsxfdi");
5437   fixunsxfti_libfunc = init_one_libfunc ("__fixunsxfti");
5438
5439   fixunstfsi_libfunc = init_one_libfunc ("__fixunstfsi");
5440   fixunstfdi_libfunc = init_one_libfunc ("__fixunstfdi");
5441   fixunstfti_libfunc = init_one_libfunc ("__fixunstfti");
5442
5443   /* For function entry/exit instrumentation.  */
5444   profile_function_entry_libfunc
5445     = init_one_libfunc ("__cyg_profile_func_enter");
5446   profile_function_exit_libfunc
5447     = init_one_libfunc ("__cyg_profile_func_exit");
5448
5449 #ifdef HAVE_conditional_trap
5450   init_traps ();
5451 #endif
5452
5453 #ifdef INIT_TARGET_OPTABS
5454   /* Allow the target to add more libcalls or rename some, etc.  */
5455   INIT_TARGET_OPTABS;
5456 #endif
5457 }
5458 \f
5459 static GTY(()) rtx trap_rtx;
5460
5461 #ifdef HAVE_conditional_trap
5462 /* The insn generating function can not take an rtx_code argument.
5463    TRAP_RTX is used as an rtx argument.  Its code is replaced with
5464    the code to be used in the trap insn and all other fields are
5465    ignored.  */
5466
5467 static void
5468 init_traps ()
5469 {
5470   if (HAVE_conditional_trap)
5471     {
5472       trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
5473     }
5474 }
5475 #endif
5476
5477 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
5478    CODE.  Return 0 on failure.  */
5479
5480 rtx
5481 gen_cond_trap (code, op1, op2, tcode)
5482   enum rtx_code code ATTRIBUTE_UNUSED;
5483   rtx op1, op2 ATTRIBUTE_UNUSED, tcode ATTRIBUTE_UNUSED;
5484 {
5485   enum machine_mode mode = GET_MODE (op1);
5486
5487   if (mode == VOIDmode)
5488     return 0;
5489
5490 #ifdef HAVE_conditional_trap
5491   if (HAVE_conditional_trap
5492       && cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
5493     {
5494       rtx insn;
5495       start_sequence();
5496       emit_insn (GEN_FCN (cmp_optab->handlers[(int) mode].insn_code) (op1, op2));
5497       PUT_CODE (trap_rtx, code);
5498       insn = gen_conditional_trap (trap_rtx, tcode);
5499       if (insn)
5500         {
5501           emit_insn (insn);
5502           insn = get_insns ();
5503         }
5504       end_sequence();
5505       return insn;
5506     }
5507 #endif
5508
5509   return 0;
5510 }
5511
5512 #include "gt-optabs.h"