OSDN Git Service

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