OSDN Git Service

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