OSDN Git Service

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