OSDN Git Service

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