OSDN Git Service

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