OSDN Git Service

2003-02-01 Richard Henderson <rth@redhat.com>
[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 = word_mode;
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 (temp)
2726                 {
2727                   if (class != MODE_INT)
2728                     {
2729                       if (target == 0)
2730                         target = gen_reg_rtx (mode);
2731                       convert_move (target, temp, 0);
2732                       return target;
2733                     }
2734                   else
2735                     return gen_lowpart (mode, temp);
2736                 }
2737               else
2738                 delete_insns_since (last);
2739             }
2740         }
2741     }
2742
2743   /* If there is no negate operation, try doing a subtract from zero.
2744      The US Software GOFAST library needs this.  */
2745   if (unoptab->code == NEG)
2746     {    
2747       rtx temp;
2748       temp = expand_binop (mode,
2749                            unoptab == negv_optab ? subv_optab : sub_optab,
2750                            CONST0_RTX (mode), op0,
2751                            target, unsignedp, OPTAB_LIB_WIDEN);
2752       if (temp)
2753         return temp;
2754     }
2755       
2756   return 0;
2757 }
2758 \f
2759 /* Emit code to compute the absolute value of OP0, with result to
2760    TARGET if convenient.  (TARGET may be 0.)  The return value says
2761    where the result actually is to be found.
2762
2763    MODE is the mode of the operand; the mode of the result is
2764    different but can be deduced from MODE.
2765
2766  */
2767
2768 rtx
2769 expand_abs (mode, op0, target, result_unsignedp, safe)
2770      enum machine_mode mode;
2771      rtx op0;
2772      rtx target;
2773      int result_unsignedp;
2774      int safe;
2775 {
2776   rtx temp, op1;
2777
2778   if (! flag_trapv)
2779     result_unsignedp = 1;
2780
2781   /* First try to do it with a special abs instruction.  */
2782   temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
2783                       op0, target, 0);
2784   if (temp != 0)
2785     return temp;
2786
2787   /* For floating point modes, try clearing the sign bit.  */
2788   if (GET_MODE_CLASS (mode) == MODE_FLOAT
2789       && GET_MODE_BITSIZE (mode) <= 2 * HOST_BITS_PER_WIDE_INT)
2790     {
2791       const struct real_format *fmt = real_format_for_mode[mode - QFmode];
2792       enum machine_mode imode = int_mode_for_mode (mode);
2793       int bitpos = (fmt != 0) ? fmt->signbit : -1;
2794
2795       if (imode != BLKmode && bitpos >= 0)
2796         {
2797           HOST_WIDE_INT hi, lo;
2798           rtx last = get_last_insn ();
2799
2800           /* Handle targets with different FP word orders.  */
2801           if (FLOAT_WORDS_BIG_ENDIAN != WORDS_BIG_ENDIAN)
2802             {
2803               int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
2804               int word = nwords - (bitpos / BITS_PER_WORD) - 1;
2805               bitpos = word * BITS_PER_WORD + bitpos % BITS_PER_WORD;
2806             }
2807
2808           if (bitpos < HOST_BITS_PER_WIDE_INT)
2809             {
2810               hi = 0;
2811               lo = (HOST_WIDE_INT) 1 << bitpos;
2812             }
2813           else
2814             {
2815               hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
2816               lo = 0;
2817             }
2818           temp = expand_binop (imode, and_optab,
2819                                gen_lowpart (imode, op0),
2820                                immed_double_const (~lo, ~hi, imode),
2821                                NULL_RTX, 1, OPTAB_LIB_WIDEN);
2822           if (temp != 0)
2823             return gen_lowpart (mode, temp);
2824           delete_insns_since (last);
2825         }
2826     }
2827
2828   /* If we have a MAX insn, we can do this as MAX (x, -x).  */
2829   if (smax_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2830     {
2831       rtx last = get_last_insn ();
2832
2833       temp = expand_unop (mode, neg_optab, op0, NULL_RTX, 0);
2834       if (temp != 0)
2835         temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
2836                              OPTAB_WIDEN);
2837
2838       if (temp != 0)
2839         return temp;
2840
2841       delete_insns_since (last);
2842     }
2843
2844   /* If this machine has expensive jumps, we can do integer absolute
2845      value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2846      where W is the width of MODE.  */
2847
2848   if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
2849     {
2850       rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
2851                                    size_int (GET_MODE_BITSIZE (mode) - 1),
2852                                    NULL_RTX, 0);
2853
2854       temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
2855                            OPTAB_LIB_WIDEN);
2856       if (temp != 0)
2857         temp = expand_binop (mode, result_unsignedp ? sub_optab : subv_optab,
2858                              temp, extended, target, 0, OPTAB_LIB_WIDEN);
2859
2860       if (temp != 0)
2861         return temp;
2862     }
2863
2864   /* If that does not win, use conditional jump and negate.  */
2865
2866   /* It is safe to use the target if it is the same
2867      as the source if this is also a pseudo register */
2868   if (op0 == target && GET_CODE (op0) == REG
2869       && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
2870     safe = 1;
2871
2872   op1 = gen_label_rtx ();
2873   if (target == 0 || ! safe
2874       || GET_MODE (target) != mode
2875       || (GET_CODE (target) == MEM && MEM_VOLATILE_P (target))
2876       || (GET_CODE (target) == REG
2877           && REGNO (target) < FIRST_PSEUDO_REGISTER))
2878     target = gen_reg_rtx (mode);
2879
2880   emit_move_insn (target, op0);
2881   NO_DEFER_POP;
2882
2883   /* If this mode is an integer too wide to compare properly,
2884      compare word by word.  Rely on CSE to optimize constant cases.  */
2885   if (GET_MODE_CLASS (mode) == MODE_INT
2886       && ! can_compare_p (GE, mode, ccp_jump))
2887     do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx, 
2888                                   NULL_RTX, op1);
2889   else
2890     do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
2891                              NULL_RTX, NULL_RTX, op1);
2892
2893   op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
2894                      target, target, 0);
2895   if (op0 != target)
2896     emit_move_insn (target, op0);
2897   emit_label (op1);
2898   OK_DEFER_POP;
2899   return target;
2900 }
2901 \f
2902 /* Emit code to compute the absolute value of OP0, with result to
2903    TARGET if convenient.  (TARGET may be 0.)  The return value says
2904    where the result actually is to be found.
2905
2906    MODE is the mode of the operand; the mode of the result is
2907    different but can be deduced from MODE.
2908
2909    UNSIGNEDP is relevant for complex integer modes.  */
2910
2911 rtx
2912 expand_complex_abs (mode, op0, target, unsignedp)
2913      enum machine_mode mode;
2914      rtx op0;
2915      rtx target;
2916      int unsignedp;
2917 {
2918   enum mode_class class = GET_MODE_CLASS (mode);
2919   enum machine_mode wider_mode;
2920   rtx temp;
2921   rtx entry_last = get_last_insn ();
2922   rtx last;
2923   rtx pat;
2924   optab this_abs_optab;
2925
2926   /* Find the correct mode for the real and imaginary parts.  */
2927   enum machine_mode submode = GET_MODE_INNER (mode);
2928
2929   if (submode == BLKmode)
2930     abort ();
2931
2932   op0 = protect_from_queue (op0, 0);
2933
2934   if (flag_force_mem)
2935     {
2936       op0 = force_not_mem (op0);
2937     }
2938
2939   last = get_last_insn ();
2940
2941   if (target)
2942     target = protect_from_queue (target, 1);
2943
2944   this_abs_optab = ! unsignedp && flag_trapv
2945                    && (GET_MODE_CLASS(mode) == MODE_INT)
2946                    ? absv_optab : abs_optab;
2947
2948   if (this_abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2949     {
2950       int icode = (int) this_abs_optab->handlers[(int) mode].insn_code;
2951       enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2952       rtx xop0 = op0;
2953
2954       if (target)
2955         temp = target;
2956       else
2957         temp = gen_reg_rtx (submode);
2958
2959       if (GET_MODE (xop0) != VOIDmode
2960           && GET_MODE (xop0) != mode0)
2961         xop0 = convert_to_mode (mode0, xop0, unsignedp);
2962
2963       /* Now, if insn doesn't accept our operand, put it into a pseudo.  */
2964
2965       if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
2966         xop0 = copy_to_mode_reg (mode0, xop0);
2967
2968       if (! (*insn_data[icode].operand[0].predicate) (temp, submode))
2969         temp = gen_reg_rtx (submode);
2970
2971       pat = GEN_FCN (icode) (temp, xop0);
2972       if (pat)
2973         {
2974           if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
2975               && ! add_equal_note (pat, temp, this_abs_optab->code, xop0, 
2976                                    NULL_RTX))
2977             {
2978               delete_insns_since (last);
2979               return expand_unop (mode, this_abs_optab, op0, NULL_RTX, 
2980                                   unsignedp);
2981             }
2982
2983           emit_insn (pat);
2984           
2985           return temp;
2986         }
2987       else
2988         delete_insns_since (last);
2989     }
2990
2991   /* It can't be done in this mode.  Can we open-code it in a wider mode?  */
2992
2993   for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2994        wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2995     {
2996       if (this_abs_optab->handlers[(int) wider_mode].insn_code 
2997           != CODE_FOR_nothing)
2998         {
2999           rtx xop0 = op0;
3000
3001           xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
3002           temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
3003
3004           if (temp)
3005             {
3006               if (class != MODE_COMPLEX_INT)
3007                 {
3008                   if (target == 0)
3009                     target = gen_reg_rtx (submode);
3010                   convert_move (target, temp, 0);
3011                   return target;
3012                 }
3013               else
3014                 return gen_lowpart (submode, temp);
3015             }
3016           else
3017             delete_insns_since (last);
3018         }
3019     }
3020
3021   /* Open-code the complex absolute-value operation
3022      if we can open-code sqrt.  Otherwise it's not worth while.  */
3023   if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing
3024       && ! flag_trapv)
3025     {
3026       rtx real, imag, total;
3027
3028       real = gen_realpart (submode, op0);
3029       imag = gen_imagpart (submode, op0);
3030
3031       /* Square both parts.  */
3032       real = expand_mult (submode, real, real, NULL_RTX, 0);
3033       imag = expand_mult (submode, imag, imag, NULL_RTX, 0);
3034
3035       /* Sum the parts.  */
3036       total = expand_binop (submode, add_optab, real, imag, NULL_RTX,
3037                             0, OPTAB_LIB_WIDEN);
3038
3039       /* Get sqrt in TARGET.  Set TARGET to where the result is.  */
3040       target = expand_unop (submode, sqrt_optab, total, target, 0);
3041       if (target == 0)
3042         delete_insns_since (last);
3043       else
3044         return target;
3045     }
3046
3047   /* Now try a library call in this mode.  */
3048   if (this_abs_optab->handlers[(int) mode].libfunc)
3049     {
3050       rtx insns;
3051       rtx value;
3052
3053       start_sequence ();
3054
3055       /* Pass 1 for NO_QUEUE so we don't lose any increments
3056          if the libcall is cse'd or moved.  */
3057       value = emit_library_call_value (abs_optab->handlers[(int) mode].libfunc,
3058                                        NULL_RTX, LCT_CONST, submode, 1, op0, mode);
3059       insns = get_insns ();
3060       end_sequence ();
3061
3062       target = gen_reg_rtx (submode);
3063       emit_libcall_block (insns, target, value,
3064                           gen_rtx_fmt_e (this_abs_optab->code, mode, op0));
3065
3066       return target;
3067     }
3068
3069   /* It can't be done in this mode.  Can we do it in a wider mode?  */
3070
3071   for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3072        wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3073     {
3074       if ((this_abs_optab->handlers[(int) wider_mode].insn_code
3075            != CODE_FOR_nothing)
3076           || this_abs_optab->handlers[(int) wider_mode].libfunc)
3077         {
3078           rtx xop0 = op0;
3079
3080           xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
3081
3082           temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
3083
3084           if (temp)
3085             {
3086               if (class != MODE_COMPLEX_INT)
3087                 {
3088                   if (target == 0)
3089                     target = gen_reg_rtx (submode);
3090                   convert_move (target, temp, 0);
3091                   return target;
3092                 }
3093               else
3094                 return gen_lowpart (submode, temp);
3095             }
3096           else
3097             delete_insns_since (last);
3098         }
3099     }
3100
3101   delete_insns_since (entry_last);
3102   return 0;
3103 }
3104 \f
3105 /* Generate an instruction whose insn-code is INSN_CODE,
3106    with two operands: an output TARGET and an input OP0.
3107    TARGET *must* be nonzero, and the output is always stored there.
3108    CODE is an rtx code such that (CODE OP0) is an rtx that describes
3109    the value that is stored into TARGET.  */
3110
3111 void
3112 emit_unop_insn (icode, target, op0, code)
3113      int icode;
3114      rtx target;
3115      rtx op0;
3116      enum rtx_code code;
3117 {
3118   rtx temp;
3119   enum machine_mode mode0 = insn_data[icode].operand[1].mode;
3120   rtx pat;
3121
3122   temp = target = protect_from_queue (target, 1);
3123
3124   op0 = protect_from_queue (op0, 0);
3125
3126   /* Sign and zero extension from memory is often done specially on
3127      RISC machines, so forcing into a register here can pessimize
3128      code.  */
3129   if (flag_force_mem && code != SIGN_EXTEND && code != ZERO_EXTEND)
3130     op0 = force_not_mem (op0);
3131
3132   /* Now, if insn does not accept our operands, put them into pseudos.  */
3133
3134   if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
3135     op0 = copy_to_mode_reg (mode0, op0);
3136
3137   if (! (*insn_data[icode].operand[0].predicate) (temp, GET_MODE (temp))
3138       || (flag_force_mem && GET_CODE (temp) == MEM))
3139     temp = gen_reg_rtx (GET_MODE (temp));
3140
3141   pat = GEN_FCN (icode) (temp, op0);
3142
3143   if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX && code != UNKNOWN)
3144     add_equal_note (pat, temp, code, op0, NULL_RTX);
3145   
3146   emit_insn (pat);
3147
3148   if (temp != target)
3149     emit_move_insn (target, temp);
3150 }
3151 \f
3152 /* Emit code to perform a series of operations on a multi-word quantity, one
3153    word at a time.
3154
3155    Such a block is preceded by a CLOBBER of the output, consists of multiple
3156    insns, each setting one word of the output, and followed by a SET copying
3157    the output to itself.
3158
3159    Each of the insns setting words of the output receives a REG_NO_CONFLICT
3160    note indicating that it doesn't conflict with the (also multi-word)
3161    inputs.  The entire block is surrounded by REG_LIBCALL and REG_RETVAL
3162    notes.
3163
3164    INSNS is a block of code generated to perform the operation, not including
3165    the CLOBBER and final copy.  All insns that compute intermediate values
3166    are first emitted, followed by the block as described above.  
3167
3168    TARGET, OP0, and OP1 are the output and inputs of the operations,
3169    respectively.  OP1 may be zero for a unary operation.
3170
3171    EQUIV, if nonzero, is an expression to be placed into a REG_EQUAL note
3172    on the last insn.
3173
3174    If TARGET is not a register, INSNS is simply emitted with no special
3175    processing.  Likewise if anything in INSNS is not an INSN or if
3176    there is a libcall block inside INSNS.
3177
3178    The final insn emitted is returned.  */
3179
3180 rtx
3181 emit_no_conflict_block (insns, target, op0, op1, equiv)
3182      rtx insns;
3183      rtx target;
3184      rtx op0, op1;
3185      rtx equiv;
3186 {
3187   rtx prev, next, first, last, insn;
3188
3189   if (GET_CODE (target) != REG || reload_in_progress)
3190     return emit_insn (insns);
3191   else
3192     for (insn = insns; insn; insn = NEXT_INSN (insn))
3193       if (GET_CODE (insn) != INSN
3194           || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
3195         return emit_insn (insns);
3196
3197   /* First emit all insns that do not store into words of the output and remove
3198      these from the list.  */
3199   for (insn = insns; insn; insn = next)
3200     {
3201       rtx set = 0, note;
3202       int i;
3203
3204       next = NEXT_INSN (insn);
3205
3206       /* Some ports (cris) create an libcall regions at their own.  We must
3207          avoid any potential nesting of LIBCALLs.  */
3208       if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
3209         remove_note (insn, note);
3210       if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
3211         remove_note (insn, note);
3212
3213       if (GET_CODE (PATTERN (insn)) == SET || GET_CODE (PATTERN (insn)) == USE
3214           || GET_CODE (PATTERN (insn)) == CLOBBER)
3215         set = PATTERN (insn);
3216       else if (GET_CODE (PATTERN (insn)) == PARALLEL)
3217         {
3218           for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
3219             if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
3220               {
3221                 set = XVECEXP (PATTERN (insn), 0, i);
3222                 break;
3223               }
3224         }
3225
3226       if (set == 0)
3227         abort ();
3228
3229       if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
3230         {
3231           if (PREV_INSN (insn))
3232             NEXT_INSN (PREV_INSN (insn)) = next;
3233           else
3234             insns = next;
3235
3236           if (next)
3237             PREV_INSN (next) = PREV_INSN (insn);
3238
3239           add_insn (insn);
3240         }
3241     }
3242
3243   prev = get_last_insn ();
3244
3245   /* Now write the CLOBBER of the output, followed by the setting of each
3246      of the words, followed by the final copy.  */
3247   if (target != op0 && target != op1)
3248     emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
3249
3250   for (insn = insns; insn; insn = next)
3251     {
3252       next = NEXT_INSN (insn);
3253       add_insn (insn);
3254
3255       if (op1 && GET_CODE (op1) == REG)
3256         REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op1,
3257                                               REG_NOTES (insn));
3258
3259       if (op0 && GET_CODE (op0) == REG)
3260         REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op0,
3261                                               REG_NOTES (insn));
3262     }
3263
3264   if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
3265       != CODE_FOR_nothing)
3266     {
3267       last = emit_move_insn (target, target);
3268       if (equiv)
3269         set_unique_reg_note (last, REG_EQUAL, equiv);
3270     }
3271   else
3272     {
3273       last = get_last_insn ();
3274
3275       /* Remove any existing REG_EQUAL note from "last", or else it will
3276          be mistaken for a note referring to the full contents of the
3277          alleged libcall value when found together with the REG_RETVAL
3278          note added below.  An existing note can come from an insn
3279          expansion at "last".  */
3280       remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
3281     }
3282
3283   if (prev == 0)
3284     first = get_insns ();
3285   else
3286     first = NEXT_INSN (prev);
3287
3288   /* Encapsulate the block so it gets manipulated as a unit.  */
3289   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
3290                                          REG_NOTES (first));
3291   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
3292
3293   return last;
3294 }
3295 \f
3296 /* Emit code to make a call to a constant function or a library call.
3297
3298    INSNS is a list containing all insns emitted in the call.
3299    These insns leave the result in RESULT.  Our block is to copy RESULT
3300    to TARGET, which is logically equivalent to EQUIV.
3301
3302    We first emit any insns that set a pseudo on the assumption that these are
3303    loading constants into registers; doing so allows them to be safely cse'ed
3304    between blocks.  Then we emit all the other insns in the block, followed by
3305    an insn to move RESULT to TARGET.  This last insn will have a REQ_EQUAL
3306    note with an operand of EQUIV.
3307
3308    Moving assignments to pseudos outside of the block is done to improve
3309    the generated code, but is not required to generate correct code,
3310    hence being unable to move an assignment is not grounds for not making
3311    a libcall block.  There are two reasons why it is safe to leave these
3312    insns inside the block: First, we know that these pseudos cannot be
3313    used in generated RTL outside the block since they are created for
3314    temporary purposes within the block.  Second, CSE will not record the
3315    values of anything set inside a libcall block, so we know they must
3316    be dead at the end of the block.
3317
3318    Except for the first group of insns (the ones setting pseudos), the
3319    block is delimited by REG_RETVAL and REG_LIBCALL notes.  */
3320
3321 void
3322 emit_libcall_block (insns, target, result, equiv)
3323      rtx insns;
3324      rtx target;
3325      rtx result;
3326      rtx equiv;
3327 {
3328   rtx final_dest = target;
3329   rtx prev, next, first, last, insn;
3330
3331   /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3332      into a MEM later.  Protect the libcall block from this change.  */
3333   if (! REG_P (target) || REG_USERVAR_P (target))
3334     target = gen_reg_rtx (GET_MODE (target));
3335   
3336   /* If we're using non-call exceptions, a libcall corresponding to an
3337      operation that may trap may also trap.  */
3338   if (flag_non_call_exceptions && may_trap_p (equiv))
3339     {
3340       for (insn = insns; insn; insn = NEXT_INSN (insn))
3341         if (GET_CODE (insn) == CALL_INSN)
3342           {
3343             rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3344             
3345             if (note != 0 && INTVAL (XEXP (note, 0)) <= 0)
3346               remove_note (insn, note);
3347           }
3348     }
3349   else
3350   /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
3351      reg note to indicate that this call cannot throw or execute a nonlocal
3352      goto (unless there is already a REG_EH_REGION note, in which case
3353      we update it).  */
3354     for (insn = insns; insn; insn = NEXT_INSN (insn))
3355       if (GET_CODE (insn) == CALL_INSN)
3356         {
3357           rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3358         
3359           if (note != 0)
3360             XEXP (note, 0) = GEN_INT (-1);
3361           else
3362             REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, GEN_INT (-1),
3363                                                   REG_NOTES (insn));
3364         }
3365
3366   /* First emit all insns that set pseudos.  Remove them from the list as
3367      we go.  Avoid insns that set pseudos which were referenced in previous
3368      insns.  These can be generated by move_by_pieces, for example,
3369      to update an address.  Similarly, avoid insns that reference things
3370      set in previous insns.  */
3371
3372   for (insn = insns; insn; insn = next)
3373     {
3374       rtx set = single_set (insn);
3375       rtx note;
3376
3377       /* Some ports (cris) create an libcall regions at their own.  We must
3378          avoid any potential nesting of LIBCALLs.  */
3379       if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
3380         remove_note (insn, note);
3381       if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
3382         remove_note (insn, note);
3383
3384       next = NEXT_INSN (insn);
3385
3386       if (set != 0 && GET_CODE (SET_DEST (set)) == REG
3387           && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
3388           && (insn == insns
3389               || ((! INSN_P(insns)
3390                    || ! reg_mentioned_p (SET_DEST (set), PATTERN (insns)))
3391                   && ! reg_used_between_p (SET_DEST (set), insns, insn)
3392                   && ! modified_in_p (SET_SRC (set), insns)
3393                   && ! modified_between_p (SET_SRC (set), insns, insn))))
3394         {
3395           if (PREV_INSN (insn))
3396             NEXT_INSN (PREV_INSN (insn)) = next;
3397           else
3398             insns = next;
3399
3400           if (next)
3401             PREV_INSN (next) = PREV_INSN (insn);
3402
3403           add_insn (insn);
3404         }
3405     }
3406
3407   prev = get_last_insn ();
3408
3409   /* Write the remaining insns followed by the final copy.  */
3410
3411   for (insn = insns; insn; insn = next)
3412     {
3413       next = NEXT_INSN (insn);
3414
3415       add_insn (insn);
3416     }
3417
3418   last = emit_move_insn (target, result);
3419   if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
3420       != CODE_FOR_nothing)
3421     set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
3422   else
3423     {
3424       /* Remove any existing REG_EQUAL note from "last", or else it will
3425          be mistaken for a note referring to the full contents of the
3426          libcall value when found together with the REG_RETVAL note added
3427          below.  An existing note can come from an insn expansion at
3428          "last".  */
3429       remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
3430     }
3431
3432   if (final_dest != target)
3433     emit_move_insn (final_dest, target);
3434
3435   if (prev == 0)
3436     first = get_insns ();
3437   else
3438     first = NEXT_INSN (prev);
3439
3440   /* Encapsulate the block so it gets manipulated as a unit.  */
3441   if (!flag_non_call_exceptions || !may_trap_p (equiv))
3442     {
3443       /* We can't attach the REG_LIBCALL and REG_RETVAL notes
3444          when the encapsulated region would not be in one basic block,
3445          i.e. when there is a control_flow_insn_p insn between FIRST and LAST.
3446        */
3447       bool attach_libcall_retval_notes = true;
3448       next = NEXT_INSN (last);
3449       for (insn = first; insn != next; insn = NEXT_INSN (insn))
3450         if (control_flow_insn_p (insn))
3451           {
3452             attach_libcall_retval_notes = false;
3453             break;
3454           }
3455
3456       if (attach_libcall_retval_notes)
3457         {
3458           REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
3459                                                  REG_NOTES (first));
3460           REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first,
3461                                                 REG_NOTES (last));
3462         }
3463     }
3464 }
3465 \f
3466 /* Generate code to store zero in X.  */
3467
3468 void
3469 emit_clr_insn (x)
3470      rtx x;
3471 {
3472   emit_move_insn (x, const0_rtx);
3473 }
3474
3475 /* Generate code to store 1 in X
3476    assuming it contains zero beforehand.  */
3477
3478 void
3479 emit_0_to_1_insn (x)
3480      rtx x;
3481 {
3482   emit_move_insn (x, const1_rtx);
3483 }
3484
3485 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
3486    PURPOSE describes how this comparison will be used.  CODE is the rtx
3487    comparison code we will be using.
3488
3489    ??? Actually, CODE is slightly weaker than that.  A target is still
3490    required to implement all of the normal bcc operations, but not 
3491    required to implement all (or any) of the unordered bcc operations.  */
3492   
3493 int
3494 can_compare_p (code, mode, purpose)
3495      enum rtx_code code;
3496      enum machine_mode mode;
3497      enum can_compare_purpose purpose;
3498 {
3499   do
3500     {
3501       if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3502         {
3503           if (purpose == ccp_jump)
3504             return bcc_gen_fctn[(int) code] != NULL;
3505           else if (purpose == ccp_store_flag)
3506             return setcc_gen_code[(int) code] != CODE_FOR_nothing;
3507           else
3508             /* There's only one cmov entry point, and it's allowed to fail.  */
3509             return 1;
3510         }
3511       if (purpose == ccp_jump
3512           && cbranch_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3513         return 1;
3514       if (purpose == ccp_cmov
3515           && cmov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3516         return 1;
3517       if (purpose == ccp_store_flag
3518           && cstore_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3519         return 1;
3520
3521       mode = GET_MODE_WIDER_MODE (mode);
3522     }
3523   while (mode != VOIDmode);
3524
3525   return 0;
3526 }
3527
3528 /* This function is called when we are going to emit a compare instruction that
3529    compares the values found in *PX and *PY, using the rtl operator COMPARISON.
3530
3531    *PMODE is the mode of the inputs (in case they are const_int).
3532    *PUNSIGNEDP nonzero says that the operands are unsigned;
3533    this matters if they need to be widened.
3534
3535    If they have mode BLKmode, then SIZE specifies the size of both operands.
3536
3537    This function performs all the setup necessary so that the caller only has
3538    to emit a single comparison insn.  This setup can involve doing a BLKmode
3539    comparison or emitting a library call to perform the comparison if no insn
3540    is available to handle it.
3541    The values which are passed in through pointers can be modified; the caller
3542    should perform the comparison on the modified values.  */
3543
3544 static void
3545 prepare_cmp_insn (px, py, pcomparison, size, pmode, punsignedp, purpose)
3546      rtx *px, *py;
3547      enum rtx_code *pcomparison;
3548      rtx size;
3549      enum machine_mode *pmode;
3550      int *punsignedp;
3551      enum can_compare_purpose purpose;
3552 {
3553   enum machine_mode mode = *pmode;
3554   rtx x = *px, y = *py;
3555   int unsignedp = *punsignedp;
3556   enum mode_class class;
3557
3558   class = GET_MODE_CLASS (mode);
3559
3560   /* They could both be VOIDmode if both args are immediate constants,
3561      but we should fold that at an earlier stage.
3562      With no special code here, this will call abort,
3563      reminding the programmer to implement such folding.  */
3564
3565   if (mode != BLKmode && flag_force_mem)
3566     {
3567       x = force_not_mem (x);
3568       y = force_not_mem (y);
3569     }
3570
3571   /* If we are inside an appropriately-short loop and one operand is an
3572      expensive constant, force it into a register.  */
3573   if (CONSTANT_P (x) && preserve_subexpressions_p ()
3574       && rtx_cost (x, COMPARE) > COSTS_N_INSNS (1))
3575     x = force_reg (mode, x);
3576
3577   if (CONSTANT_P (y) && preserve_subexpressions_p ()
3578       && rtx_cost (y, COMPARE) > COSTS_N_INSNS (1))
3579     y = force_reg (mode, y);
3580
3581 #ifdef HAVE_cc0
3582   /* Abort if we have a non-canonical comparison.  The RTL documentation
3583      states that canonical comparisons are required only for targets which
3584      have cc0.  */
3585   if (CONSTANT_P (x) && ! CONSTANT_P (y))
3586     abort ();
3587 #endif
3588
3589   /* Don't let both operands fail to indicate the mode.  */
3590   if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
3591     x = force_reg (mode, x);
3592
3593   /* Handle all BLKmode compares.  */
3594
3595   if (mode == BLKmode)
3596     {
3597       rtx result;
3598       enum machine_mode result_mode;
3599       rtx opalign ATTRIBUTE_UNUSED
3600         = GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
3601
3602       emit_queue ();
3603       x = protect_from_queue (x, 0);
3604       y = protect_from_queue (y, 0);
3605
3606       if (size == 0)
3607         abort ();
3608 #ifdef HAVE_cmpstrqi
3609       if (HAVE_cmpstrqi
3610           && GET_CODE (size) == CONST_INT
3611           && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
3612         {
3613           result_mode = insn_data[(int) CODE_FOR_cmpstrqi].operand[0].mode;
3614           result = gen_reg_rtx (result_mode);
3615           emit_insn (gen_cmpstrqi (result, x, y, size, opalign));
3616         }
3617       else
3618 #endif
3619 #ifdef HAVE_cmpstrhi
3620       if (HAVE_cmpstrhi
3621           && GET_CODE (size) == CONST_INT
3622           && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
3623         {
3624           result_mode = insn_data[(int) CODE_FOR_cmpstrhi].operand[0].mode;
3625           result = gen_reg_rtx (result_mode);
3626           emit_insn (gen_cmpstrhi (result, x, y, size, opalign));
3627         }
3628       else
3629 #endif
3630 #ifdef HAVE_cmpstrsi
3631       if (HAVE_cmpstrsi)
3632         {
3633           result_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3634           result = gen_reg_rtx (result_mode);
3635           size = protect_from_queue (size, 0);
3636           emit_insn (gen_cmpstrsi (result, x, y,
3637                                    convert_to_mode (SImode, size, 1),
3638                                    opalign));
3639         }
3640       else
3641 #endif
3642         {
3643 #ifdef TARGET_MEM_FUNCTIONS
3644           result = emit_library_call_value (memcmp_libfunc, NULL_RTX, LCT_PURE_MAKE_BLOCK,
3645                                             TYPE_MODE (integer_type_node), 3,
3646                                             XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
3647                                             convert_to_mode (TYPE_MODE (sizetype), size,
3648                                                              TREE_UNSIGNED (sizetype)),
3649                                             TYPE_MODE (sizetype));
3650 #else
3651           result = emit_library_call_value (bcmp_libfunc, NULL_RTX, LCT_PURE_MAKE_BLOCK,
3652                                             TYPE_MODE (integer_type_node), 3,
3653                                             XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
3654                                             convert_to_mode (TYPE_MODE (integer_type_node),
3655                                                              size,
3656                                                              TREE_UNSIGNED (integer_type_node)),
3657                                             TYPE_MODE (integer_type_node));
3658 #endif
3659
3660           result_mode = TYPE_MODE (integer_type_node);
3661         }
3662       *px = result;
3663       *py = const0_rtx;
3664       *pmode = result_mode;
3665       return;
3666     }
3667
3668   *px = x;
3669   *py = y;
3670   if (can_compare_p (*pcomparison, mode, purpose))
3671     return;
3672
3673   /* Handle a lib call just for the mode we are using.  */
3674
3675   if (cmp_optab->handlers[(int) mode].libfunc && class != MODE_FLOAT)
3676     {
3677       rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
3678       rtx result;
3679
3680       /* If we want unsigned, and this mode has a distinct unsigned
3681          comparison routine, use that.  */
3682       if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
3683         libfunc = ucmp_optab->handlers[(int) mode].libfunc;
3684
3685       result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST_MAKE_BLOCK,
3686                                         word_mode, 2, x, mode, y, mode);
3687
3688       /* Integer comparison returns a result that must be compared against 1,
3689          so that even if we do an unsigned compare afterward,
3690          there is still a value that can represent the result "less than".  */
3691       *px = result;
3692       *py = const1_rtx;
3693       *pmode = word_mode;
3694       return;
3695     }
3696
3697   if (class == MODE_FLOAT)
3698     prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
3699
3700   else
3701     abort ();
3702 }
3703
3704 /* Before emitting an insn with code ICODE, make sure that X, which is going
3705    to be used for operand OPNUM of the insn, is converted from mode MODE to
3706    WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
3707    that it is accepted by the operand predicate.  Return the new value.  */
3708
3709 rtx
3710 prepare_operand (icode, x, opnum, mode, wider_mode, unsignedp)
3711      int icode;
3712      rtx x;
3713      int opnum;
3714      enum machine_mode mode, wider_mode;
3715      int unsignedp;
3716 {
3717   x = protect_from_queue (x, 0);
3718
3719   if (mode != wider_mode)
3720     x = convert_modes (wider_mode, mode, x, unsignedp);
3721
3722   if (! (*insn_data[icode].operand[opnum].predicate)
3723       (x, insn_data[icode].operand[opnum].mode))
3724     x = copy_to_mode_reg (insn_data[icode].operand[opnum].mode, x);
3725   return x;
3726 }
3727
3728 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
3729    we can do the comparison.
3730    The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may
3731    be NULL_RTX which indicates that only a comparison is to be generated.  */
3732
3733 static void
3734 emit_cmp_and_jump_insn_1 (x, y, mode, comparison, unsignedp, label)
3735      rtx x, y;
3736      enum machine_mode mode;
3737      enum rtx_code comparison;
3738      int unsignedp;
3739      rtx label;
3740 {
3741   rtx test = gen_rtx_fmt_ee (comparison, mode, x, y);
3742   enum mode_class class = GET_MODE_CLASS (mode);
3743   enum machine_mode wider_mode = mode;
3744
3745   /* Try combined insns first.  */
3746   do
3747     {
3748       enum insn_code icode;
3749       PUT_MODE (test, wider_mode);
3750
3751       if (label)
3752         {         
3753           icode = cbranch_optab->handlers[(int) wider_mode].insn_code;
3754           
3755           if (icode != CODE_FOR_nothing
3756               && (*insn_data[icode].operand[0].predicate) (test, wider_mode))
3757             {
3758               x = prepare_operand (icode, x, 1, mode, wider_mode, unsignedp);
3759               y = prepare_operand (icode, y, 2, mode, wider_mode, unsignedp);
3760               emit_jump_insn (GEN_FCN (icode) (test, x, y, label));
3761               return;
3762             }
3763         }
3764
3765       /* Handle some compares against zero.  */
3766       icode = (int) tst_optab->handlers[(int) wider_mode].insn_code;
3767       if (y == CONST0_RTX (mode) && icode != CODE_FOR_nothing)
3768         {
3769           x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3770           emit_insn (GEN_FCN (icode) (x));
3771           if (label)
3772             emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
3773           return;
3774         }
3775
3776       /* Handle compares for which there is a directly suitable insn.  */
3777
3778       icode = (int) cmp_optab->handlers[(int) wider_mode].insn_code;
3779       if (icode != CODE_FOR_nothing)
3780         {
3781           x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3782           y = prepare_operand (icode, y, 1, mode, wider_mode, unsignedp);
3783           emit_insn (GEN_FCN (icode) (x, y));
3784           if (label)
3785             emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
3786           return;
3787         }
3788
3789       if (class != MODE_INT && class != MODE_FLOAT
3790           && class != MODE_COMPLEX_FLOAT)
3791         break;
3792
3793       wider_mode = GET_MODE_WIDER_MODE (wider_mode);
3794     }
3795   while (wider_mode != VOIDmode);
3796
3797   abort ();
3798 }
3799
3800 /* Generate code to compare X with Y so that the condition codes are
3801    set and to jump to LABEL if the condition is true.  If X is a
3802    constant and Y is not a constant, then the comparison is swapped to
3803    ensure that the comparison RTL has the canonical form.
3804
3805    UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
3806    need to be widened by emit_cmp_insn.  UNSIGNEDP is also used to select
3807    the proper branch condition code.
3808
3809    If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
3810
3811    MODE is the mode of the inputs (in case they are const_int).
3812
3813    COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  It will
3814    be passed unchanged to emit_cmp_insn, then potentially converted into an
3815    unsigned variant based on UNSIGNEDP to select a proper jump instruction.  */
3816
3817 void
3818 emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, label)
3819      rtx x, y;
3820      enum rtx_code comparison;
3821      rtx size;
3822      enum machine_mode mode;
3823      int unsignedp;
3824      rtx label;
3825 {
3826   rtx op0 = x, op1 = y;
3827
3828   /* Swap operands and condition to ensure canonical RTL.  */
3829   if (swap_commutative_operands_p (x, y))
3830     {
3831       /* If we're not emitting a branch, this means some caller
3832          is out of sync.  */
3833       if (! label)
3834         abort ();
3835
3836       op0 = y, op1 = x;
3837       comparison = swap_condition (comparison);
3838     }
3839
3840 #ifdef HAVE_cc0
3841   /* If OP0 is still a constant, then both X and Y must be constants.  Force
3842      X into a register to avoid aborting in emit_cmp_insn due to non-canonical
3843      RTL.  */
3844   if (CONSTANT_P (op0))
3845     op0 = force_reg (mode, op0);
3846 #endif
3847
3848   emit_queue ();
3849   if (unsignedp)
3850     comparison = unsigned_condition (comparison);
3851
3852   prepare_cmp_insn (&op0, &op1, &comparison, size, &mode, &unsignedp,
3853                     ccp_jump);
3854   emit_cmp_and_jump_insn_1 (op0, op1, mode, comparison, unsignedp, label);
3855 }
3856
3857 /* Like emit_cmp_and_jump_insns, but generate only the comparison.  */
3858
3859 void
3860 emit_cmp_insn (x, y, comparison, size, mode, unsignedp)
3861      rtx x, y;
3862      enum rtx_code comparison;
3863      rtx size;
3864      enum machine_mode mode;
3865      int unsignedp;
3866 {
3867   emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, 0);
3868 }
3869 \f
3870 /* Emit a library call comparison between floating point X and Y.
3871    COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  */
3872
3873 static void
3874 prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp)
3875      rtx *px, *py;
3876      enum rtx_code *pcomparison;
3877      enum machine_mode *pmode;
3878      int *punsignedp;
3879 {
3880   enum rtx_code comparison = *pcomparison;
3881   rtx tmp;
3882   rtx x = *px = protect_from_queue (*px, 0);
3883   rtx y = *py = protect_from_queue (*py, 0);
3884   enum machine_mode mode = GET_MODE (x);
3885   rtx libfunc = 0;
3886   rtx result;
3887
3888   if (mode == HFmode)
3889     switch (comparison)
3890       {
3891       case EQ:
3892         libfunc = eqhf2_libfunc;
3893         break;
3894
3895       case NE:
3896         libfunc = nehf2_libfunc;
3897         break;
3898
3899       case GT:
3900         libfunc = gthf2_libfunc;
3901         if (libfunc == NULL_RTX)
3902           {
3903             tmp = x; x = y; y = tmp;
3904             *pcomparison = LT;
3905             libfunc = lthf2_libfunc;
3906           }
3907         break;
3908
3909       case GE:
3910         libfunc = gehf2_libfunc;
3911         if (libfunc == NULL_RTX)
3912           {
3913             tmp = x; x = y; y = tmp;
3914             *pcomparison = LE;
3915             libfunc = lehf2_libfunc;
3916           }
3917         break;
3918
3919       case LT:
3920         libfunc = lthf2_libfunc;
3921         if (libfunc == NULL_RTX)
3922           {
3923             tmp = x; x = y; y = tmp;
3924             *pcomparison = GT;
3925             libfunc = gthf2_libfunc;
3926           }
3927         break;
3928
3929       case LE:
3930         libfunc = lehf2_libfunc;
3931         if (libfunc == NULL_RTX)
3932           {
3933             tmp = x; x = y; y = tmp;
3934             *pcomparison = GE;
3935             libfunc = gehf2_libfunc;
3936           }
3937         break;
3938
3939       case UNORDERED:
3940         libfunc = unordhf2_libfunc;
3941         break;
3942
3943       default:
3944         break;
3945       }
3946   else if (mode == SFmode)
3947     switch (comparison)
3948       {
3949       case EQ:
3950         libfunc = eqsf2_libfunc;
3951         break;
3952
3953       case NE:
3954         libfunc = nesf2_libfunc;
3955         break;
3956
3957       case GT:
3958         libfunc = gtsf2_libfunc;
3959         if (libfunc == NULL_RTX)
3960           {
3961             tmp = x; x = y; y = tmp;
3962             *pcomparison = LT;
3963             libfunc = ltsf2_libfunc;
3964           }
3965         break;
3966
3967       case GE:
3968         libfunc = gesf2_libfunc;
3969         if (libfunc == NULL_RTX)
3970           {
3971             tmp = x; x = y; y = tmp;
3972             *pcomparison = LE;
3973             libfunc = lesf2_libfunc;
3974           }
3975         break;
3976
3977       case LT:
3978         libfunc = ltsf2_libfunc;
3979         if (libfunc == NULL_RTX)
3980           {
3981             tmp = x; x = y; y = tmp;
3982             *pcomparison = GT;
3983             libfunc = gtsf2_libfunc;
3984           }
3985         break;
3986
3987       case LE:
3988         libfunc = lesf2_libfunc;
3989         if (libfunc == NULL_RTX)
3990           {
3991             tmp = x; x = y; y = tmp;
3992             *pcomparison = GE;
3993             libfunc = gesf2_libfunc;
3994           }
3995         break;
3996
3997       case UNORDERED:
3998         libfunc = unordsf2_libfunc;
3999         break;
4000
4001       default:
4002         break;
4003       }
4004   else if (mode == DFmode)
4005     switch (comparison)
4006       {
4007       case EQ:
4008         libfunc = eqdf2_libfunc;
4009         break;
4010
4011       case NE:
4012         libfunc = nedf2_libfunc;
4013         break;
4014
4015       case GT:
4016         libfunc = gtdf2_libfunc;
4017         if (libfunc == NULL_RTX)
4018           {
4019             tmp = x; x = y; y = tmp;
4020             *pcomparison = LT;
4021             libfunc = ltdf2_libfunc;
4022           }
4023         break;
4024
4025       case GE:
4026         libfunc = gedf2_libfunc;
4027         if (libfunc == NULL_RTX)
4028           {
4029             tmp = x; x = y; y = tmp;
4030             *pcomparison = LE;
4031             libfunc = ledf2_libfunc;
4032           }
4033         break;
4034
4035       case LT:
4036         libfunc = ltdf2_libfunc;
4037         if (libfunc == NULL_RTX)
4038           {
4039             tmp = x; x = y; y = tmp;
4040             *pcomparison = GT;
4041             libfunc = gtdf2_libfunc;
4042           }
4043         break;
4044
4045       case LE:
4046         libfunc = ledf2_libfunc;
4047         if (libfunc == NULL_RTX)
4048           {
4049             tmp = x; x = y; y = tmp;
4050             *pcomparison = GE;
4051             libfunc = gedf2_libfunc;
4052           }
4053         break;
4054
4055       case UNORDERED:
4056         libfunc = unorddf2_libfunc;
4057         break;
4058
4059       default:
4060         break;
4061       }
4062   else if (mode == XFmode)
4063     switch (comparison)
4064       {
4065       case EQ:
4066         libfunc = eqxf2_libfunc;
4067         break;
4068
4069       case NE:
4070         libfunc = nexf2_libfunc;
4071         break;
4072
4073       case GT:
4074         libfunc = gtxf2_libfunc;
4075         if (libfunc == NULL_RTX)
4076           {
4077             tmp = x; x = y; y = tmp;
4078             *pcomparison = LT;
4079             libfunc = ltxf2_libfunc;
4080           }
4081         break;
4082
4083       case GE:
4084         libfunc = gexf2_libfunc;
4085         if (libfunc == NULL_RTX)
4086           {
4087             tmp = x; x = y; y = tmp;
4088             *pcomparison = LE;
4089             libfunc = lexf2_libfunc;
4090           }
4091         break;
4092
4093       case LT:
4094         libfunc = ltxf2_libfunc;
4095         if (libfunc == NULL_RTX)
4096           {
4097             tmp = x; x = y; y = tmp;
4098             *pcomparison = GT;
4099             libfunc = gtxf2_libfunc;
4100           }
4101         break;
4102
4103       case LE:
4104         libfunc = lexf2_libfunc;
4105         if (libfunc == NULL_RTX)
4106           {
4107             tmp = x; x = y; y = tmp;
4108             *pcomparison = GE;
4109             libfunc = gexf2_libfunc;
4110           }
4111         break;
4112
4113       case UNORDERED:
4114         libfunc = unordxf2_libfunc;
4115         break;
4116
4117       default:
4118         break;
4119       }
4120   else if (mode == TFmode)
4121     switch (comparison)
4122       {
4123       case EQ:
4124         libfunc = eqtf2_libfunc;
4125         break;
4126
4127       case NE:
4128         libfunc = netf2_libfunc;
4129         break;
4130
4131       case GT:
4132         libfunc = gttf2_libfunc;
4133         if (libfunc == NULL_RTX)
4134           {
4135             tmp = x; x = y; y = tmp;
4136             *pcomparison = LT;
4137             libfunc = lttf2_libfunc;
4138           }
4139         break;
4140
4141       case GE:
4142         libfunc = getf2_libfunc;
4143         if (libfunc == NULL_RTX)
4144           {
4145             tmp = x; x = y; y = tmp;
4146             *pcomparison = LE;
4147             libfunc = letf2_libfunc;
4148           }
4149         break;
4150
4151       case LT:
4152         libfunc = lttf2_libfunc;
4153         if (libfunc == NULL_RTX)
4154           {
4155             tmp = x; x = y; y = tmp;
4156             *pcomparison = GT;
4157             libfunc = gttf2_libfunc;
4158           }
4159         break;
4160
4161       case LE:
4162         libfunc = letf2_libfunc;
4163         if (libfunc == NULL_RTX)
4164           {
4165             tmp = x; x = y; y = tmp;
4166             *pcomparison = GE;
4167             libfunc = getf2_libfunc;
4168           }
4169         break;
4170
4171       case UNORDERED:
4172         libfunc = unordtf2_libfunc;
4173         break;
4174
4175       default:
4176         break;
4177       }
4178   else
4179     {
4180       enum machine_mode wider_mode;
4181
4182       for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
4183            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
4184         {
4185           if ((cmp_optab->handlers[(int) wider_mode].insn_code
4186                != CODE_FOR_nothing)
4187               || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
4188             {
4189               x = protect_from_queue (x, 0);
4190               y = protect_from_queue (y, 0);
4191               *px = convert_to_mode (wider_mode, x, 0);
4192               *py = convert_to_mode (wider_mode, y, 0);
4193               prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
4194               return;
4195             }
4196         }
4197       abort ();
4198     }
4199
4200   if (libfunc == 0)
4201     abort ();
4202
4203   result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST_MAKE_BLOCK,
4204                                     word_mode, 2, x, mode, y, mode);
4205   *px = result;
4206   *py = const0_rtx;
4207   *pmode = word_mode;
4208   if (comparison == UNORDERED)
4209     *pcomparison = NE;
4210 #ifdef FLOAT_LIB_COMPARE_RETURNS_BOOL
4211   else if (FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4212     *pcomparison = NE;
4213 #endif
4214   *punsignedp = 0;
4215 }
4216 \f
4217 /* Generate code to indirectly jump to a location given in the rtx LOC.  */
4218
4219 void
4220 emit_indirect_jump (loc)
4221      rtx loc;
4222 {
4223   if (! ((*insn_data[(int) CODE_FOR_indirect_jump].operand[0].predicate)
4224          (loc, Pmode)))
4225     loc = copy_to_mode_reg (Pmode, loc);
4226
4227   emit_jump_insn (gen_indirect_jump (loc));
4228   emit_barrier ();
4229 }
4230 \f
4231 #ifdef HAVE_conditional_move
4232
4233 /* Emit a conditional move instruction if the machine supports one for that
4234    condition and machine mode.
4235
4236    OP0 and OP1 are the operands that should be compared using CODE.  CMODE is
4237    the mode to use should they be constants.  If it is VOIDmode, they cannot
4238    both be constants.
4239
4240    OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4241    should be stored there.  MODE is the mode to use should they be constants.
4242    If it is VOIDmode, they cannot both be constants.
4243
4244    The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4245    is not supported.  */
4246
4247 rtx
4248 emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
4249                        unsignedp)
4250      rtx target;
4251      enum rtx_code code;
4252      rtx op0, op1;
4253      enum machine_mode cmode;
4254      rtx op2, op3;
4255      enum machine_mode mode;
4256      int unsignedp;
4257 {
4258   rtx tem, subtarget, comparison, insn;
4259   enum insn_code icode;
4260   enum rtx_code reversed;
4261
4262   /* If one operand is constant, make it the second one.  Only do this
4263      if the other operand is not constant as well.  */
4264
4265   if (swap_commutative_operands_p (op0, op1))
4266     {
4267       tem = op0;
4268       op0 = op1;
4269       op1 = tem;
4270       code = swap_condition (code);
4271     }
4272
4273   /* get_condition will prefer to generate LT and GT even if the old
4274      comparison was against zero, so undo that canonicalization here since
4275      comparisons against zero are cheaper.  */
4276   if (code == LT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == 1)
4277     code = LE, op1 = const0_rtx;
4278   else if (code == GT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == -1)
4279     code = GE, op1 = const0_rtx;
4280
4281   if (cmode == VOIDmode)
4282     cmode = GET_MODE (op0);
4283
4284   if (swap_commutative_operands_p (op2, op3)
4285       && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4286           != UNKNOWN))
4287     {
4288       tem = op2;
4289       op2 = op3;
4290       op3 = tem;
4291       code = reversed;
4292     }
4293
4294   if (mode == VOIDmode)
4295     mode = GET_MODE (op2);
4296
4297   icode = movcc_gen_code[mode];
4298
4299   if (icode == CODE_FOR_nothing)
4300     return 0;
4301
4302   if (flag_force_mem)
4303     {
4304       op2 = force_not_mem (op2);
4305       op3 = force_not_mem (op3);
4306     }
4307
4308   if (target)
4309     target = protect_from_queue (target, 1);
4310   else
4311     target = gen_reg_rtx (mode);
4312
4313   subtarget = target;
4314
4315   emit_queue ();
4316
4317   op2 = protect_from_queue (op2, 0);
4318   op3 = protect_from_queue (op3, 0);
4319
4320   /* If the insn doesn't accept these operands, put them in pseudos.  */
4321
4322   if (! (*insn_data[icode].operand[0].predicate)
4323       (subtarget, insn_data[icode].operand[0].mode))
4324     subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
4325
4326   if (! (*insn_data[icode].operand[2].predicate)
4327       (op2, insn_data[icode].operand[2].mode))
4328     op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
4329
4330   if (! (*insn_data[icode].operand[3].predicate)
4331       (op3, insn_data[icode].operand[3].mode))
4332     op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
4333
4334   /* Everything should now be in the suitable form, so emit the compare insn
4335      and then the conditional move.  */
4336
4337   comparison 
4338     = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
4339
4340   /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)?  */
4341   /* We can get const0_rtx or const_true_rtx in some circumstances.  Just
4342      return NULL and let the caller figure out how best to deal with this
4343      situation.  */
4344   if (GET_CODE (comparison) != code)
4345     return NULL_RTX;
4346   
4347   insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
4348
4349   /* If that failed, then give up.  */
4350   if (insn == 0)
4351     return 0;
4352
4353   emit_insn (insn);
4354
4355   if (subtarget != target)
4356     convert_move (target, subtarget, 0);
4357
4358   return target;
4359 }
4360
4361 /* Return nonzero if a conditional move of mode MODE is supported.
4362
4363    This function is for combine so it can tell whether an insn that looks
4364    like a conditional move is actually supported by the hardware.  If we
4365    guess wrong we lose a bit on optimization, but that's it.  */
4366 /* ??? sparc64 supports conditionally moving integers values based on fp
4367    comparisons, and vice versa.  How do we handle them?  */
4368
4369 int
4370 can_conditionally_move_p (mode)
4371      enum machine_mode mode;
4372 {
4373   if (movcc_gen_code[mode] != CODE_FOR_nothing)
4374     return 1;
4375
4376   return 0;
4377 }
4378
4379 #endif /* HAVE_conditional_move */
4380
4381 /* Emit a conditional addition instruction if the machine supports one for that
4382    condition and machine mode.
4383
4384    OP0 and OP1 are the operands that should be compared using CODE.  CMODE is
4385    the mode to use should they be constants.  If it is VOIDmode, they cannot
4386    both be constants.
4387
4388    OP2 should be stored in TARGET if the comparison is true, otherwise OP2+OP3
4389    should be stored there.  MODE is the mode to use should they be constants.
4390    If it is VOIDmode, they cannot both be constants.
4391
4392    The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4393    is not supported.  */
4394
4395 rtx
4396 emit_conditional_add (target, code, op0, op1, cmode, op2, op3, mode,
4397                       unsignedp)
4398      rtx target;
4399      enum rtx_code code;
4400      rtx op0, op1;
4401      enum machine_mode cmode;
4402      rtx op2, op3;
4403      enum machine_mode mode;
4404      int unsignedp;
4405 {
4406   rtx tem, subtarget, comparison, insn;
4407   enum insn_code icode;
4408   enum rtx_code reversed;
4409
4410   /* If one operand is constant, make it the second one.  Only do this
4411      if the other operand is not constant as well.  */
4412
4413   if (swap_commutative_operands_p (op0, op1))
4414     {
4415       tem = op0;
4416       op0 = op1;
4417       op1 = tem;
4418       code = swap_condition (code);
4419     }
4420
4421   /* get_condition will prefer to generate LT and GT even if the old
4422      comparison was against zero, so undo that canonicalization here since
4423      comparisons against zero are cheaper.  */
4424   if (code == LT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == 1)
4425     code = LE, op1 = const0_rtx;
4426   else if (code == GT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == -1)
4427     code = GE, op1 = const0_rtx;
4428
4429   if (cmode == VOIDmode)
4430     cmode = GET_MODE (op0);
4431
4432   if (swap_commutative_operands_p (op2, op3)
4433       && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4434           != UNKNOWN))
4435     {
4436       tem = op2;
4437       op2 = op3;
4438       op3 = tem;
4439       code = reversed;
4440     }
4441
4442   if (mode == VOIDmode)
4443     mode = GET_MODE (op2);
4444
4445   icode = addcc_optab->handlers[(int) mode].insn_code;
4446
4447   if (icode == CODE_FOR_nothing)
4448     return 0;
4449
4450   if (flag_force_mem)
4451     {
4452       op2 = force_not_mem (op2);
4453       op3 = force_not_mem (op3);
4454     }
4455
4456   if (target)
4457     target = protect_from_queue (target, 1);
4458   else
4459     target = gen_reg_rtx (mode);
4460
4461   subtarget = target;
4462
4463   emit_queue ();
4464
4465   op2 = protect_from_queue (op2, 0);
4466   op3 = protect_from_queue (op3, 0);
4467
4468   /* If the insn doesn't accept these operands, put them in pseudos.  */
4469
4470   if (! (*insn_data[icode].operand[0].predicate)
4471       (subtarget, insn_data[icode].operand[0].mode))
4472     subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
4473
4474   if (! (*insn_data[icode].operand[2].predicate)
4475       (op2, insn_data[icode].operand[2].mode))
4476     op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
4477
4478   if (! (*insn_data[icode].operand[3].predicate)
4479       (op3, insn_data[icode].operand[3].mode))
4480     op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
4481
4482   /* Everything should now be in the suitable form, so emit the compare insn
4483      and then the conditional move.  */
4484
4485   comparison 
4486     = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
4487
4488   /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)?  */
4489   /* We can get const0_rtx or const_true_rtx in some circumstances.  Just
4490      return NULL and let the caller figure out how best to deal with this
4491      situation.  */
4492   if (GET_CODE (comparison) != code)
4493     return NULL_RTX;
4494   
4495   insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
4496
4497   /* If that failed, then give up.  */
4498   if (insn == 0)
4499     return 0;
4500
4501   emit_insn (insn);
4502
4503   if (subtarget != target)
4504     convert_move (target, subtarget, 0);
4505
4506   return target;
4507 }
4508 \f
4509 /* These functions generate an insn body and return it
4510    rather than emitting the insn.
4511
4512    They do not protect from queued increments,
4513    because they may be used 1) in protect_from_queue itself
4514    and 2) in other passes where there is no queue.  */
4515
4516 /* Generate and return an insn body to add Y to X.  */
4517
4518 rtx
4519 gen_add2_insn (x, y)
4520      rtx x, y;
4521 {
4522   int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code; 
4523
4524   if (! ((*insn_data[icode].operand[0].predicate)
4525          (x, insn_data[icode].operand[0].mode))
4526       || ! ((*insn_data[icode].operand[1].predicate)
4527             (x, insn_data[icode].operand[1].mode))
4528       || ! ((*insn_data[icode].operand[2].predicate)
4529             (y, insn_data[icode].operand[2].mode)))
4530     abort ();
4531
4532   return (GEN_FCN (icode) (x, x, y));
4533 }
4534
4535 /* Generate and return an insn body to add r1 and c,
4536    storing the result in r0.  */
4537 rtx
4538 gen_add3_insn (r0, r1, c)
4539      rtx r0, r1, c;
4540 {
4541   int icode = (int) add_optab->handlers[(int) GET_MODE (r0)].insn_code;
4542
4543   if (icode == CODE_FOR_nothing
4544       || ! ((*insn_data[icode].operand[0].predicate)
4545             (r0, insn_data[icode].operand[0].mode))
4546       || ! ((*insn_data[icode].operand[1].predicate)
4547             (r1, insn_data[icode].operand[1].mode))
4548       || ! ((*insn_data[icode].operand[2].predicate)
4549             (c, insn_data[icode].operand[2].mode)))
4550     return NULL_RTX;
4551
4552   return (GEN_FCN (icode) (r0, r1, c));
4553 }
4554
4555 int
4556 have_add2_insn (x, y)
4557      rtx x, y;
4558 {
4559   int icode;
4560
4561   if (GET_MODE (x) == VOIDmode)
4562     abort ();
4563
4564   icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code; 
4565
4566   if (icode == CODE_FOR_nothing)
4567     return 0;
4568
4569   if (! ((*insn_data[icode].operand[0].predicate)
4570          (x, insn_data[icode].operand[0].mode))
4571       || ! ((*insn_data[icode].operand[1].predicate)
4572             (x, insn_data[icode].operand[1].mode))
4573       || ! ((*insn_data[icode].operand[2].predicate)
4574             (y, insn_data[icode].operand[2].mode)))
4575     return 0;
4576
4577   return 1;
4578 }
4579
4580 /* Generate and return an insn body to subtract Y from X.  */
4581
4582 rtx
4583 gen_sub2_insn (x, y)
4584      rtx x, y;
4585 {
4586   int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code; 
4587
4588   if (! ((*insn_data[icode].operand[0].predicate)
4589          (x, insn_data[icode].operand[0].mode))
4590       || ! ((*insn_data[icode].operand[1].predicate)
4591             (x, insn_data[icode].operand[1].mode))
4592       || ! ((*insn_data[icode].operand[2].predicate)
4593             (y, insn_data[icode].operand[2].mode)))
4594     abort ();
4595
4596   return (GEN_FCN (icode) (x, x, y));
4597 }
4598
4599 /* Generate and return an insn body to subtract r1 and c,
4600    storing the result in r0.  */
4601 rtx
4602 gen_sub3_insn (r0, r1, c)
4603      rtx r0, r1, c;
4604 {
4605   int icode = (int) sub_optab->handlers[(int) GET_MODE (r0)].insn_code;
4606
4607   if (icode == CODE_FOR_nothing
4608       || ! ((*insn_data[icode].operand[0].predicate)
4609             (r0, insn_data[icode].operand[0].mode))
4610       || ! ((*insn_data[icode].operand[1].predicate)
4611             (r1, insn_data[icode].operand[1].mode))
4612       || ! ((*insn_data[icode].operand[2].predicate)
4613             (c, insn_data[icode].operand[2].mode)))
4614     return NULL_RTX;
4615
4616   return (GEN_FCN (icode) (r0, r1, c));
4617 }
4618
4619 int
4620 have_sub2_insn (x, y)
4621      rtx x, y;
4622 {
4623   int icode;
4624
4625   if (GET_MODE (x) == VOIDmode)
4626     abort ();
4627
4628   icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code; 
4629
4630   if (icode == CODE_FOR_nothing)
4631     return 0;
4632
4633   if (! ((*insn_data[icode].operand[0].predicate)
4634          (x, insn_data[icode].operand[0].mode))
4635       || ! ((*insn_data[icode].operand[1].predicate)
4636             (x, insn_data[icode].operand[1].mode))
4637       || ! ((*insn_data[icode].operand[2].predicate)
4638             (y, insn_data[icode].operand[2].mode)))
4639     return 0;
4640
4641   return 1;
4642 }
4643
4644 /* Generate the body of an instruction to copy Y into X.
4645    It may be a list of insns, if one insn isn't enough.  */
4646
4647 rtx
4648 gen_move_insn (x, y)
4649      rtx x, y;
4650 {
4651   enum machine_mode mode = GET_MODE (x);
4652   enum insn_code insn_code;
4653   rtx seq;
4654
4655   if (mode == VOIDmode)
4656     mode = GET_MODE (y); 
4657
4658   insn_code = mov_optab->handlers[(int) mode].insn_code;
4659
4660   /* Handle MODE_CC modes:  If we don't have a special move insn for this mode,
4661      find a mode to do it in.  If we have a movcc, use it.  Otherwise,
4662      find the MODE_INT mode of the same width.  */
4663
4664   if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
4665     {
4666       enum machine_mode tmode = VOIDmode;
4667       rtx x1 = x, y1 = y;
4668
4669       if (mode != CCmode
4670           && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
4671         tmode = CCmode;
4672       else
4673         for (tmode = QImode; tmode != VOIDmode;
4674              tmode = GET_MODE_WIDER_MODE (tmode))
4675           if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
4676             break;
4677
4678       if (tmode == VOIDmode)
4679         abort ();
4680
4681       /* Get X and Y in TMODE.  We can't use gen_lowpart here because it
4682          may call change_address which is not appropriate if we were
4683          called when a reload was in progress.  We don't have to worry
4684          about changing the address since the size in bytes is supposed to
4685          be the same.  Copy the MEM to change the mode and move any
4686          substitutions from the old MEM to the new one.  */
4687
4688       if (reload_in_progress)
4689         {
4690           x = gen_lowpart_common (tmode, x1);
4691           if (x == 0 && GET_CODE (x1) == MEM)
4692             {
4693               x = adjust_address_nv (x1, tmode, 0);
4694               copy_replacements (x1, x);
4695             }
4696
4697           y = gen_lowpart_common (tmode, y1);
4698           if (y == 0 && GET_CODE (y1) == MEM)
4699             {
4700               y = adjust_address_nv (y1, tmode, 0);
4701               copy_replacements (y1, y);
4702             }
4703         }
4704       else
4705         {
4706           x = gen_lowpart (tmode, x);
4707           y = gen_lowpart (tmode, y);
4708         }
4709           
4710       insn_code = mov_optab->handlers[(int) tmode].insn_code;
4711       return (GEN_FCN (insn_code) (x, y));
4712     }
4713
4714   start_sequence ();
4715   emit_move_insn_1 (x, y);
4716   seq = get_insns ();
4717   end_sequence ();
4718   return seq;
4719 }
4720 \f
4721 /* Return the insn code used to extend FROM_MODE to TO_MODE.
4722    UNSIGNEDP specifies zero-extension instead of sign-extension.  If
4723    no such operation exists, CODE_FOR_nothing will be returned.  */
4724
4725 enum insn_code
4726 can_extend_p (to_mode, from_mode, unsignedp)
4727      enum machine_mode to_mode, from_mode;
4728      int unsignedp;
4729 {
4730 #ifdef HAVE_ptr_extend
4731   if (unsignedp < 0)
4732     return CODE_FOR_ptr_extend;
4733   else
4734 #endif
4735     return extendtab[(int) to_mode][(int) from_mode][unsignedp != 0];
4736 }
4737
4738 /* Generate the body of an insn to extend Y (with mode MFROM)
4739    into X (with mode MTO).  Do zero-extension if UNSIGNEDP is nonzero.  */
4740
4741 rtx
4742 gen_extend_insn (x, y, mto, mfrom, unsignedp)
4743      rtx x, y;
4744      enum machine_mode mto, mfrom;
4745      int unsignedp;
4746 {
4747   return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp != 0]) (x, y));
4748 }
4749 \f
4750 /* can_fix_p and can_float_p say whether the target machine
4751    can directly convert a given fixed point type to
4752    a given floating point type, or vice versa.
4753    The returned value is the CODE_FOR_... value to use,
4754    or CODE_FOR_nothing if these modes cannot be directly converted.
4755
4756    *TRUNCP_PTR is set to 1 if it is necessary to output
4757    an explicit FTRUNC insn before the fix insn; otherwise 0.  */
4758
4759 static enum insn_code
4760 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
4761      enum machine_mode fltmode, fixmode;
4762      int unsignedp;
4763      int *truncp_ptr;
4764 {
4765   *truncp_ptr = 0;
4766   if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp != 0]
4767       != CODE_FOR_nothing)
4768     return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp != 0];
4769
4770   if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
4771     {
4772       *truncp_ptr = 1;
4773       return fixtab[(int) fltmode][(int) fixmode][unsignedp != 0];
4774     }
4775   return CODE_FOR_nothing;
4776 }
4777
4778 static enum insn_code
4779 can_float_p (fltmode, fixmode, unsignedp)
4780      enum machine_mode fixmode, fltmode;
4781      int unsignedp;
4782 {
4783   return floattab[(int) fltmode][(int) fixmode][unsignedp != 0];
4784 }
4785 \f
4786 /* Generate code to convert FROM to floating point
4787    and store in TO.  FROM must be fixed point and not VOIDmode.
4788    UNSIGNEDP nonzero means regard FROM as unsigned.
4789    Normally this is done by correcting the final value
4790    if it is negative.  */
4791
4792 void
4793 expand_float (to, from, unsignedp)
4794      rtx to, from;
4795      int unsignedp;
4796 {
4797   enum insn_code icode;
4798   rtx target = to;
4799   enum machine_mode fmode, imode;
4800
4801   /* Crash now, because we won't be able to decide which mode to use.  */
4802   if (GET_MODE (from) == VOIDmode)
4803     abort ();
4804
4805   /* Look for an insn to do the conversion.  Do it in the specified
4806      modes if possible; otherwise convert either input, output or both to
4807      wider mode.  If the integer mode is wider than the mode of FROM,
4808      we can do the conversion signed even if the input is unsigned.  */
4809
4810   for (imode = GET_MODE (from); imode != VOIDmode;
4811        imode = GET_MODE_WIDER_MODE (imode))
4812     for (fmode = GET_MODE (to); fmode != VOIDmode;
4813          fmode = GET_MODE_WIDER_MODE (fmode))
4814       {
4815         int doing_unsigned = unsignedp;
4816
4817         if (fmode != GET_MODE (to)
4818             && significand_size (fmode) < GET_MODE_BITSIZE (GET_MODE (from)))
4819           continue;
4820
4821         icode = can_float_p (fmode, imode, unsignedp);
4822         if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
4823           icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
4824
4825         if (icode != CODE_FOR_nothing)
4826           {
4827             to = protect_from_queue (to, 1);
4828             from = protect_from_queue (from, 0);
4829
4830             if (imode != GET_MODE (from))
4831               from = convert_to_mode (imode, from, unsignedp);
4832
4833             if (fmode != GET_MODE (to))
4834               target = gen_reg_rtx (fmode);
4835
4836             emit_unop_insn (icode, target, from,
4837                             doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
4838
4839             if (target != to)
4840               convert_move (to, target, 0);
4841             return;
4842           }
4843       }
4844
4845   /* Unsigned integer, and no way to convert directly.
4846      Convert as signed, then conditionally adjust the result.  */
4847   if (unsignedp)
4848     {
4849       rtx label = gen_label_rtx ();
4850       rtx temp;
4851       REAL_VALUE_TYPE offset;
4852
4853       emit_queue ();
4854
4855       to = protect_from_queue (to, 1);
4856       from = protect_from_queue (from, 0);
4857
4858       if (flag_force_mem)
4859         from = force_not_mem (from);
4860
4861       /* Look for a usable floating mode FMODE wider than the source and at
4862          least as wide as the target.  Using FMODE will avoid rounding woes
4863          with unsigned values greater than the signed maximum value.  */
4864
4865       for (fmode = GET_MODE (to);  fmode != VOIDmode;
4866            fmode = GET_MODE_WIDER_MODE (fmode))
4867         if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
4868             && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
4869           break;
4870
4871       if (fmode == VOIDmode)
4872         {
4873           /* There is no such mode.  Pretend the target is wide enough.  */
4874           fmode = GET_MODE (to);
4875
4876           /* Avoid double-rounding when TO is narrower than FROM.  */
4877           if ((significand_size (fmode) + 1)
4878               < GET_MODE_BITSIZE (GET_MODE (from)))
4879             {
4880               rtx temp1;
4881               rtx neglabel = gen_label_rtx ();
4882
4883               /* Don't use TARGET if it isn't a register, is a hard register, 
4884                  or is the wrong mode.  */
4885               if (GET_CODE (target) != REG
4886                   || REGNO (target) < FIRST_PSEUDO_REGISTER
4887                   || GET_MODE (target) != fmode)
4888                 target = gen_reg_rtx (fmode);
4889
4890               imode = GET_MODE (from);
4891               do_pending_stack_adjust ();
4892
4893               /* Test whether the sign bit is set.  */
4894               emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
4895                                        0, neglabel);
4896
4897               /* The sign bit is not set.  Convert as signed.  */
4898               expand_float (target, from, 0);
4899               emit_jump_insn (gen_jump (label));
4900               emit_barrier ();
4901
4902               /* The sign bit is set.
4903                  Convert to a usable (positive signed) value by shifting right
4904                  one bit, while remembering if a nonzero bit was shifted
4905                  out; i.e., compute  (from & 1) | (from >> 1).  */
4906
4907               emit_label (neglabel);
4908               temp = expand_binop (imode, and_optab, from, const1_rtx,
4909                                    NULL_RTX, 1, OPTAB_LIB_WIDEN);
4910               temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
4911                                     NULL_RTX, 1);
4912               temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1, 
4913                                    OPTAB_LIB_WIDEN);
4914               expand_float (target, temp, 0);
4915
4916               /* Multiply by 2 to undo the shift above.  */
4917               temp = expand_binop (fmode, add_optab, target, target,
4918                                    target, 0, OPTAB_LIB_WIDEN);
4919               if (temp != target)
4920                 emit_move_insn (target, temp);
4921
4922               do_pending_stack_adjust ();
4923               emit_label (label);
4924               goto done;
4925             }
4926         }
4927
4928       /* If we are about to do some arithmetic to correct for an
4929          unsigned operand, do it in a pseudo-register.  */
4930
4931       if (GET_MODE (to) != fmode
4932           || GET_CODE (to) != REG || REGNO (to) < FIRST_PSEUDO_REGISTER)
4933         target = gen_reg_rtx (fmode);
4934
4935       /* Convert as signed integer to floating.  */
4936       expand_float (target, from, 0);
4937
4938       /* If FROM is negative (and therefore TO is negative),
4939          correct its value by 2**bitwidth.  */
4940
4941       do_pending_stack_adjust ();
4942       emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
4943                                0, label);
4944
4945       
4946       real_2expN (&offset, GET_MODE_BITSIZE (GET_MODE (from)));
4947       temp = expand_binop (fmode, add_optab, target,
4948                            CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
4949                            target, 0, OPTAB_LIB_WIDEN);
4950       if (temp != target)
4951         emit_move_insn (target, temp);
4952
4953       do_pending_stack_adjust ();
4954       emit_label (label);
4955       goto done;
4956     }
4957
4958   /* No hardware instruction available; call a library routine to convert from
4959      SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode.  */
4960     {
4961       rtx libfcn;
4962       rtx insns;
4963       rtx value;
4964
4965       to = protect_from_queue (to, 1);
4966       from = protect_from_queue (from, 0);
4967
4968       if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
4969         from = convert_to_mode (SImode, from, unsignedp);
4970
4971       if (flag_force_mem)
4972         from = force_not_mem (from);
4973
4974       if (GET_MODE (to) == SFmode)
4975         {
4976           if (GET_MODE (from) == SImode)
4977             libfcn = floatsisf_libfunc;
4978           else if (GET_MODE (from) == DImode)
4979             libfcn = floatdisf_libfunc;
4980           else if (GET_MODE (from) == TImode)
4981             libfcn = floattisf_libfunc;
4982           else
4983             abort ();
4984         }
4985       else if (GET_MODE (to) == DFmode)
4986         {
4987           if (GET_MODE (from) == SImode)
4988             libfcn = floatsidf_libfunc;
4989           else if (GET_MODE (from) == DImode)
4990             libfcn = floatdidf_libfunc;
4991           else if (GET_MODE (from) == TImode)
4992             libfcn = floattidf_libfunc;
4993           else
4994             abort ();
4995         }
4996       else if (GET_MODE (to) == XFmode)
4997         {
4998           if (GET_MODE (from) == SImode)
4999             libfcn = floatsixf_libfunc;
5000           else if (GET_MODE (from) == DImode)
5001             libfcn = floatdixf_libfunc;
5002           else if (GET_MODE (from) == TImode)
5003             libfcn = floattixf_libfunc;
5004           else
5005             abort ();
5006         }
5007       else if (GET_MODE (to) == TFmode)
5008         {
5009           if (GET_MODE (from) == SImode)
5010             libfcn = floatsitf_libfunc;
5011           else if (GET_MODE (from) == DImode)
5012             libfcn = floatditf_libfunc;
5013           else if (GET_MODE (from) == TImode)
5014             libfcn = floattitf_libfunc;
5015           else
5016             abort ();
5017         }
5018       else
5019         abort ();
5020
5021       start_sequence ();
5022
5023       value = emit_library_call_value (libfcn, NULL_RTX, LCT_CONST,
5024                                        GET_MODE (to), 1, from,
5025                                        GET_MODE (from));
5026       insns = get_insns ();
5027       end_sequence ();
5028
5029       emit_libcall_block (insns, target, value,
5030                           gen_rtx_FLOAT (GET_MODE (to), from));
5031     }
5032
5033  done:
5034
5035   /* Copy result to requested destination
5036      if we have been computing in a temp location.  */
5037
5038   if (target != to)
5039     {
5040       if (GET_MODE (target) == GET_MODE (to))
5041         emit_move_insn (to, target);
5042       else
5043         convert_move (to, target, 0);
5044     }
5045 }
5046 \f
5047 /* expand_fix: generate code to convert FROM to fixed point
5048    and store in TO.  FROM must be floating point.  */
5049
5050 static rtx
5051 ftruncify (x)
5052      rtx x;
5053 {
5054   rtx temp = gen_reg_rtx (GET_MODE (x));
5055   return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
5056 }
5057
5058 void
5059 expand_fix (to, from, unsignedp)
5060      rtx to, from;
5061      int unsignedp;
5062 {
5063   enum insn_code icode;
5064   rtx target = to;
5065   enum machine_mode fmode, imode;
5066   int must_trunc = 0;
5067   rtx libfcn = 0;
5068
5069   /* We first try to find a pair of modes, one real and one integer, at
5070      least as wide as FROM and TO, respectively, in which we can open-code
5071      this conversion.  If the integer mode is wider than the mode of TO,
5072      we can do the conversion either signed or unsigned.  */
5073
5074   for (fmode = GET_MODE (from); fmode != VOIDmode;
5075        fmode = GET_MODE_WIDER_MODE (fmode))
5076     for (imode = GET_MODE (to); imode != VOIDmode;
5077          imode = GET_MODE_WIDER_MODE (imode))
5078       {
5079         int doing_unsigned = unsignedp;
5080
5081         icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
5082         if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
5083           icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
5084
5085         if (icode != CODE_FOR_nothing)
5086           {
5087             to = protect_from_queue (to, 1);
5088             from = protect_from_queue (from, 0);
5089
5090             if (fmode != GET_MODE (from))
5091               from = convert_to_mode (fmode, from, 0);
5092
5093             if (must_trunc)
5094               from = ftruncify (from);
5095
5096             if (imode != GET_MODE (to))
5097               target = gen_reg_rtx (imode);
5098
5099             emit_unop_insn (icode, target, from,
5100                             doing_unsigned ? UNSIGNED_FIX : FIX);
5101             if (target != to)
5102               convert_move (to, target, unsignedp);
5103             return;
5104           }
5105       }
5106
5107   /* For an unsigned conversion, there is one more way to do it.
5108      If we have a signed conversion, we generate code that compares
5109      the real value to the largest representable positive number.  If if
5110      is smaller, the conversion is done normally.  Otherwise, subtract
5111      one plus the highest signed number, convert, and add it back.
5112
5113      We only need to check all real modes, since we know we didn't find
5114      anything with a wider integer mode.  */
5115
5116   if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
5117     for (fmode = GET_MODE (from); fmode != VOIDmode;
5118          fmode = GET_MODE_WIDER_MODE (fmode))
5119       /* Make sure we won't lose significant bits doing this.  */
5120       if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
5121           && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
5122                                             &must_trunc))
5123         {
5124           int bitsize;
5125           REAL_VALUE_TYPE offset;
5126           rtx limit, lab1, lab2, insn;
5127
5128           bitsize = GET_MODE_BITSIZE (GET_MODE (to));
5129           real_2expN (&offset, bitsize - 1);
5130           limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
5131           lab1 = gen_label_rtx ();
5132           lab2 = gen_label_rtx ();
5133
5134           emit_queue ();
5135           to = protect_from_queue (to, 1);
5136           from = protect_from_queue (from, 0);
5137
5138           if (flag_force_mem)
5139             from = force_not_mem (from);
5140
5141           if (fmode != GET_MODE (from))
5142             from = convert_to_mode (fmode, from, 0);
5143
5144           /* See if we need to do the subtraction.  */
5145           do_pending_stack_adjust ();
5146           emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
5147                                    0, lab1);
5148
5149           /* If not, do the signed "fix" and branch around fixup code.  */
5150           expand_fix (to, from, 0);
5151           emit_jump_insn (gen_jump (lab2));
5152           emit_barrier ();
5153
5154           /* Otherwise, subtract 2**(N-1), convert to signed number,
5155              then add 2**(N-1).  Do the addition using XOR since this
5156              will often generate better code.  */
5157           emit_label (lab1);
5158           target = expand_binop (GET_MODE (from), sub_optab, from, limit,
5159                                  NULL_RTX, 0, OPTAB_LIB_WIDEN);
5160           expand_fix (to, target, 0);
5161           target = expand_binop (GET_MODE (to), xor_optab, to,
5162                                  gen_int_mode
5163                                  ((HOST_WIDE_INT) 1 << (bitsize - 1),
5164                                   GET_MODE (to)),
5165                                  to, 1, OPTAB_LIB_WIDEN);
5166
5167           if (target != to)
5168             emit_move_insn (to, target);
5169
5170           emit_label (lab2);
5171
5172           if (mov_optab->handlers[(int) GET_MODE (to)].insn_code
5173               != CODE_FOR_nothing)
5174             {
5175               /* Make a place for a REG_NOTE and add it.  */
5176               insn = emit_move_insn (to, to);
5177               set_unique_reg_note (insn,
5178                                    REG_EQUAL,
5179                                    gen_rtx_fmt_e (UNSIGNED_FIX,
5180                                                   GET_MODE (to),
5181                                                   copy_rtx (from)));
5182             }
5183
5184           return;
5185         }
5186
5187   /* We can't do it with an insn, so use a library call.  But first ensure
5188      that the mode of TO is at least as wide as SImode, since those are the
5189      only library calls we know about.  */
5190
5191   if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
5192     {
5193       target = gen_reg_rtx (SImode);
5194
5195       expand_fix (target, from, unsignedp);
5196     }
5197   else if (GET_MODE (from) == SFmode)
5198     {
5199       if (GET_MODE (to) == SImode)
5200         libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
5201       else if (GET_MODE (to) == DImode)
5202         libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
5203       else if (GET_MODE (to) == TImode)
5204         libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
5205       else
5206         abort ();
5207     }
5208   else if (GET_MODE (from) == DFmode)
5209     {
5210       if (GET_MODE (to) == SImode)
5211         libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
5212       else if (GET_MODE (to) == DImode)
5213         libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
5214       else if (GET_MODE (to) == TImode)
5215         libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
5216       else
5217         abort ();
5218     }
5219   else if (GET_MODE (from) == XFmode)
5220     {
5221       if (GET_MODE (to) == SImode)
5222         libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
5223       else if (GET_MODE (to) == DImode)
5224         libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
5225       else if (GET_MODE (to) == TImode)
5226         libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
5227       else
5228         abort ();
5229     }
5230   else if (GET_MODE (from) == TFmode)
5231     {
5232       if (GET_MODE (to) == SImode)
5233         libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
5234       else if (GET_MODE (to) == DImode)
5235         libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
5236       else if (GET_MODE (to) == TImode)
5237         libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
5238       else
5239         abort ();
5240     }
5241   else
5242     abort ();
5243
5244   if (libfcn)
5245     {
5246       rtx insns;
5247       rtx value;
5248
5249       to = protect_from_queue (to, 1);
5250       from = protect_from_queue (from, 0);
5251
5252       if (flag_force_mem)
5253         from = force_not_mem (from);
5254
5255       start_sequence ();
5256
5257       value = emit_library_call_value (libfcn, NULL_RTX, LCT_CONST,
5258                                        GET_MODE (to), 1, from,
5259                                        GET_MODE (from));
5260       insns = get_insns ();
5261       end_sequence ();
5262
5263       emit_libcall_block (insns, target, value,
5264                           gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
5265                                          GET_MODE (to), from));
5266     }
5267       
5268   if (target != to)
5269     {
5270       if (GET_MODE (to) == GET_MODE (target))
5271         emit_move_insn (to, target);
5272       else
5273         convert_move (to, target, 0);
5274     }
5275 }
5276 \f
5277 /* Report whether we have an instruction to perform the operation
5278    specified by CODE on operands of mode MODE.  */
5279 int
5280 have_insn_for (code, mode)
5281      enum rtx_code code;
5282      enum machine_mode mode;
5283 {
5284   return (code_to_optab[(int) code] != 0
5285           && (code_to_optab[(int) code]->handlers[(int) mode].insn_code
5286               != CODE_FOR_nothing));
5287 }
5288
5289 /* Create a blank optab.  */
5290 static optab
5291 new_optab ()
5292 {
5293   int i;
5294   optab op = (optab) ggc_alloc (sizeof (struct optab));
5295   for (i = 0; i < NUM_MACHINE_MODES; i++)
5296     {
5297       op->handlers[i].insn_code = CODE_FOR_nothing;
5298       op->handlers[i].libfunc = 0;
5299     }
5300
5301   return op;
5302 }
5303
5304 /* Same, but fill in its code as CODE, and write it into the
5305    code_to_optab table.  */
5306 static inline optab
5307 init_optab (code)
5308      enum rtx_code code;
5309 {
5310   optab op = new_optab ();
5311   op->code = code;
5312   code_to_optab[(int) code] = op;
5313   return op;
5314 }
5315
5316 /* Same, but fill in its code as CODE, and do _not_ write it into
5317    the code_to_optab table.  */
5318 static inline optab
5319 init_optabv (code)
5320      enum rtx_code code;
5321 {
5322   optab op = new_optab ();
5323   op->code = code;
5324   return op;
5325 }
5326
5327 /* Initialize the libfunc fields of an entire group of entries in some
5328    optab.  Each entry is set equal to a string consisting of a leading
5329    pair of underscores followed by a generic operation name followed by
5330    a mode name (downshifted to lower case) followed by a single character
5331    representing the number of operands for the given operation (which is
5332    usually one of the characters '2', '3', or '4').
5333
5334    OPTABLE is the table in which libfunc fields are to be initialized.
5335    FIRST_MODE is the first machine mode index in the given optab to
5336      initialize.
5337    LAST_MODE is the last machine mode index in the given optab to
5338      initialize.
5339    OPNAME is the generic (string) name of the operation.
5340    SUFFIX is the character which specifies the number of operands for
5341      the given generic operation.
5342 */
5343
5344 static void
5345 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
5346      optab optable;
5347      int first_mode;
5348      int last_mode;
5349      const char *opname;
5350      int suffix;
5351 {
5352   int mode;
5353   unsigned opname_len = strlen (opname);
5354
5355   for (mode = first_mode; (int) mode <= (int) last_mode;
5356        mode = (enum machine_mode) ((int) mode + 1))
5357     {
5358       const char *mname = GET_MODE_NAME (mode);
5359       unsigned mname_len = strlen (mname);
5360       char *libfunc_name = alloca (2 + opname_len + mname_len + 1 + 1);
5361       char *p;
5362       const char *q;
5363
5364       p = libfunc_name;
5365       *p++ = '_';
5366       *p++ = '_';
5367       for (q = opname; *q; )
5368         *p++ = *q++;
5369       for (q = mname; *q; q++)
5370         *p++ = TOLOWER (*q);
5371       *p++ = suffix;
5372       *p = '\0';
5373
5374       optable->handlers[(int) mode].libfunc
5375         = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (libfunc_name,
5376                                                        p - libfunc_name));
5377     }
5378 }
5379
5380 /* Initialize the libfunc fields of an entire group of entries in some
5381    optab which correspond to all integer mode operations.  The parameters
5382    have the same meaning as similarly named ones for the `init_libfuncs'
5383    routine.  (See above).  */
5384
5385 static void
5386 init_integral_libfuncs (optable, opname, suffix)
5387      optab optable;
5388      const char *opname;
5389      int suffix;
5390 {
5391   init_libfuncs (optable, SImode, TImode, opname, suffix);
5392 }
5393
5394 /* Initialize the libfunc fields of an entire group of entries in some
5395    optab which correspond to all real mode operations.  The parameters
5396    have the same meaning as similarly named ones for the `init_libfuncs'
5397    routine.  (See above).  */
5398
5399 static void
5400 init_floating_libfuncs (optable, opname, suffix)
5401      optab optable;
5402      const char *opname;
5403      int suffix;
5404 {
5405   init_libfuncs (optable, SFmode, TFmode, opname, suffix);
5406 }
5407
5408 rtx
5409 init_one_libfunc (name)
5410      const char *name;
5411 {
5412   /* Create a FUNCTION_DECL that can be passed to
5413      targetm.encode_section_info.  */
5414   /* ??? We don't have any type information except for this is
5415      a function.  Pretend this is "int foo()".  */
5416   tree decl = build_decl (FUNCTION_DECL, get_identifier (name),
5417                           build_function_type (integer_type_node, NULL_TREE));
5418   DECL_ARTIFICIAL (decl) = 1;
5419   DECL_EXTERNAL (decl) = 1;
5420   TREE_PUBLIC (decl) = 1;
5421
5422   /* Return the symbol_ref from the mem rtx.  */
5423   return XEXP (DECL_RTL (decl), 0);
5424 }
5425
5426 /* Call this once to initialize the contents of the optabs
5427    appropriately for the current target machine.  */
5428
5429 void
5430 init_optabs ()
5431 {
5432   unsigned int i, j, k;
5433
5434   /* Start by initializing all tables to contain CODE_FOR_nothing.  */
5435
5436   for (i = 0; i < ARRAY_SIZE (fixtab); i++)
5437     for (j = 0; j < ARRAY_SIZE (fixtab[0]); j++)
5438       for (k = 0; k < ARRAY_SIZE (fixtab[0][0]); k++)
5439         fixtab[i][j][k] = CODE_FOR_nothing;
5440
5441   for (i = 0; i < ARRAY_SIZE (fixtrunctab); i++)
5442     for (j = 0; j < ARRAY_SIZE (fixtrunctab[0]); j++)
5443       for (k = 0; k < ARRAY_SIZE (fixtrunctab[0][0]); k++)
5444         fixtrunctab[i][j][k] = CODE_FOR_nothing;
5445
5446   for (i = 0; i < ARRAY_SIZE (floattab); i++)
5447     for (j = 0; j < ARRAY_SIZE (floattab[0]); j++)
5448       for (k = 0; k < ARRAY_SIZE (floattab[0][0]); k++)
5449         floattab[i][j][k] = CODE_FOR_nothing;
5450
5451   for (i = 0; i < ARRAY_SIZE (extendtab); i++)
5452     for (j = 0; j < ARRAY_SIZE (extendtab[0]); j++)
5453       for (k = 0; k < ARRAY_SIZE (extendtab[0][0]); k++)
5454         extendtab[i][j][k] = CODE_FOR_nothing;
5455
5456   for (i = 0; i < NUM_RTX_CODE; i++)
5457     setcc_gen_code[i] = CODE_FOR_nothing;
5458
5459 #ifdef HAVE_conditional_move
5460   for (i = 0; i < NUM_MACHINE_MODES; i++)
5461     movcc_gen_code[i] = CODE_FOR_nothing;
5462 #endif
5463
5464   add_optab = init_optab (PLUS);
5465   addv_optab = init_optabv (PLUS);
5466   sub_optab = init_optab (MINUS);
5467   subv_optab = init_optabv (MINUS);
5468   smul_optab = init_optab (MULT);
5469   smulv_optab = init_optabv (MULT);
5470   smul_highpart_optab = init_optab (UNKNOWN);
5471   umul_highpart_optab = init_optab (UNKNOWN);
5472   smul_widen_optab = init_optab (UNKNOWN);
5473   umul_widen_optab = init_optab (UNKNOWN);
5474   sdiv_optab = init_optab (DIV);
5475   sdivv_optab = init_optabv (DIV);
5476   sdivmod_optab = init_optab (UNKNOWN);
5477   udiv_optab = init_optab (UDIV);
5478   udivmod_optab = init_optab (UNKNOWN);
5479   smod_optab = init_optab (MOD);
5480   umod_optab = init_optab (UMOD);
5481   ftrunc_optab = init_optab (UNKNOWN);
5482   and_optab = init_optab (AND);
5483   ior_optab = init_optab (IOR);
5484   xor_optab = init_optab (XOR);
5485   ashl_optab = init_optab (ASHIFT);
5486   ashr_optab = init_optab (ASHIFTRT);
5487   lshr_optab = init_optab (LSHIFTRT);
5488   rotl_optab = init_optab (ROTATE);
5489   rotr_optab = init_optab (ROTATERT);
5490   smin_optab = init_optab (SMIN);
5491   smax_optab = init_optab (SMAX);
5492   umin_optab = init_optab (UMIN);
5493   umax_optab = init_optab (UMAX);
5494
5495   /* These three have codes assigned exclusively for the sake of
5496      have_insn_for.  */
5497   mov_optab = init_optab (SET);
5498   movstrict_optab = init_optab (STRICT_LOW_PART);
5499   cmp_optab = init_optab (COMPARE);
5500
5501   ucmp_optab = init_optab (UNKNOWN);
5502   tst_optab = init_optab (UNKNOWN);
5503   neg_optab = init_optab (NEG);
5504   negv_optab = init_optabv (NEG);
5505   abs_optab = init_optab (ABS);
5506   absv_optab = init_optabv (ABS);
5507   addcc_optab = init_optab (UNKNOWN);
5508   one_cmpl_optab = init_optab (NOT);
5509   ffs_optab = init_optab (FFS);
5510   clz_optab = init_optab (CLZ);
5511   ctz_optab = init_optab (CTZ);
5512   popcount_optab = init_optab (POPCOUNT);
5513   parity_optab = init_optab (PARITY);
5514   sqrt_optab = init_optab (SQRT);
5515   floor_optab = init_optab (UNKNOWN);
5516   ceil_optab = init_optab (UNKNOWN);
5517   round_optab = init_optab (UNKNOWN);
5518   trunc_optab = init_optab (UNKNOWN);
5519   nearbyint_optab = init_optab (UNKNOWN);
5520   sin_optab = init_optab (UNKNOWN);
5521   cos_optab = init_optab (UNKNOWN);
5522   exp_optab = init_optab (UNKNOWN);
5523   log_optab = init_optab (UNKNOWN);
5524   strlen_optab = init_optab (UNKNOWN);
5525   cbranch_optab = init_optab (UNKNOWN);
5526   cmov_optab = init_optab (UNKNOWN);
5527   cstore_optab = init_optab (UNKNOWN);
5528   push_optab = init_optab (UNKNOWN);
5529
5530   for (i = 0; i < NUM_MACHINE_MODES; i++)
5531     {
5532       movstr_optab[i] = CODE_FOR_nothing;
5533       clrstr_optab[i] = CODE_FOR_nothing;
5534
5535 #ifdef HAVE_SECONDARY_RELOADS
5536       reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
5537 #endif
5538     }
5539
5540   /* Fill in the optabs with the insns we support.  */
5541   init_all_optabs ();
5542
5543 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
5544   /* This flag says the same insns that convert to a signed fixnum
5545      also convert validly to an unsigned one.  */
5546   for (i = 0; i < NUM_MACHINE_MODES; i++)
5547     for (j = 0; j < NUM_MACHINE_MODES; j++)
5548       fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
5549 #endif
5550
5551   /* Initialize the optabs with the names of the library functions.  */
5552   init_integral_libfuncs (add_optab, "add", '3');
5553   init_floating_libfuncs (add_optab, "add", '3');
5554   init_integral_libfuncs (addv_optab, "addv", '3');
5555   init_floating_libfuncs (addv_optab, "add", '3');
5556   init_integral_libfuncs (sub_optab, "sub", '3');
5557   init_floating_libfuncs (sub_optab, "sub", '3');
5558   init_integral_libfuncs (subv_optab, "subv", '3');
5559   init_floating_libfuncs (subv_optab, "sub", '3');
5560   init_integral_libfuncs (smul_optab, "mul", '3');
5561   init_floating_libfuncs (smul_optab, "mul", '3');
5562   init_integral_libfuncs (smulv_optab, "mulv", '3');
5563   init_floating_libfuncs (smulv_optab, "mul", '3');
5564   init_integral_libfuncs (sdiv_optab, "div", '3');
5565   init_floating_libfuncs (sdiv_optab, "div", '3');
5566   init_integral_libfuncs (sdivv_optab, "divv", '3');
5567   init_integral_libfuncs (udiv_optab, "udiv", '3');
5568   init_integral_libfuncs (sdivmod_optab, "divmod", '4');
5569   init_integral_libfuncs (udivmod_optab, "udivmod", '4');
5570   init_integral_libfuncs (smod_optab, "mod", '3');
5571   init_integral_libfuncs (umod_optab, "umod", '3');
5572   init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
5573   init_integral_libfuncs (and_optab, "and", '3');
5574   init_integral_libfuncs (ior_optab, "ior", '3');
5575   init_integral_libfuncs (xor_optab, "xor", '3');
5576   init_integral_libfuncs (ashl_optab, "ashl", '3');
5577   init_integral_libfuncs (ashr_optab, "ashr", '3');
5578   init_integral_libfuncs (lshr_optab, "lshr", '3');
5579   init_integral_libfuncs (smin_optab, "min", '3');
5580   init_floating_libfuncs (smin_optab, "min", '3');
5581   init_integral_libfuncs (smax_optab, "max", '3');
5582   init_floating_libfuncs (smax_optab, "max", '3');
5583   init_integral_libfuncs (umin_optab, "umin", '3');
5584   init_integral_libfuncs (umax_optab, "umax", '3');
5585   init_integral_libfuncs (neg_optab, "neg", '2');
5586   init_floating_libfuncs (neg_optab, "neg", '2');
5587   init_integral_libfuncs (negv_optab, "negv", '2');
5588   init_floating_libfuncs (negv_optab, "neg", '2');
5589   init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
5590   init_integral_libfuncs (ffs_optab, "ffs", '2');
5591   init_integral_libfuncs (clz_optab, "clz", '2');
5592   init_integral_libfuncs (ctz_optab, "ctz", '2');
5593   init_integral_libfuncs (popcount_optab, "popcount", '2');
5594   init_integral_libfuncs (parity_optab, "parity", '2');
5595
5596   /* Comparison libcalls for integers MUST come in pairs, signed/unsigned.  */
5597   init_integral_libfuncs (cmp_optab, "cmp", '2');
5598   init_integral_libfuncs (ucmp_optab, "ucmp", '2');
5599   init_floating_libfuncs (cmp_optab, "cmp", '2');
5600
5601 #ifdef MULSI3_LIBCALL
5602   smul_optab->handlers[(int) SImode].libfunc
5603     = init_one_libfunc (MULSI3_LIBCALL);
5604 #endif
5605 #ifdef MULDI3_LIBCALL
5606   smul_optab->handlers[(int) DImode].libfunc
5607     = init_one_libfunc (MULDI3_LIBCALL);
5608 #endif
5609
5610 #ifdef DIVSI3_LIBCALL
5611   sdiv_optab->handlers[(int) SImode].libfunc
5612     = init_one_libfunc (DIVSI3_LIBCALL);
5613 #endif
5614 #ifdef DIVDI3_LIBCALL
5615   sdiv_optab->handlers[(int) DImode].libfunc
5616     = init_one_libfunc (DIVDI3_LIBCALL);
5617 #endif
5618
5619 #ifdef UDIVSI3_LIBCALL
5620   udiv_optab->handlers[(int) SImode].libfunc
5621     = init_one_libfunc (UDIVSI3_LIBCALL);
5622 #endif
5623 #ifdef UDIVDI3_LIBCALL
5624   udiv_optab->handlers[(int) DImode].libfunc
5625     = init_one_libfunc (UDIVDI3_LIBCALL);
5626 #endif
5627
5628 #ifdef MODSI3_LIBCALL
5629   smod_optab->handlers[(int) SImode].libfunc
5630     = init_one_libfunc (MODSI3_LIBCALL);
5631 #endif
5632 #ifdef MODDI3_LIBCALL
5633   smod_optab->handlers[(int) DImode].libfunc
5634     = init_one_libfunc (MODDI3_LIBCALL);
5635 #endif
5636
5637 #ifdef UMODSI3_LIBCALL
5638   umod_optab->handlers[(int) SImode].libfunc
5639     = init_one_libfunc (UMODSI3_LIBCALL);
5640 #endif
5641 #ifdef UMODDI3_LIBCALL
5642   umod_optab->handlers[(int) DImode].libfunc
5643     = init_one_libfunc (UMODDI3_LIBCALL);
5644 #endif
5645
5646   /* Use cabs for DC complex abs, since systems generally have cabs.
5647      Don't define any libcall for SCmode, so that cabs will be used.  */
5648   abs_optab->handlers[(int) DCmode].libfunc
5649     = init_one_libfunc ("cabs");
5650
5651   /* The ffs function operates on `int'.  */
5652   ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)].libfunc
5653     = init_one_libfunc ("ffs");
5654   ffs_optab->handlers[(int) DImode].libfunc = init_one_libfunc ("__ffsdi2");
5655   clz_optab->handlers[(int) SImode].libfunc = init_one_libfunc ("__clzsi2");
5656   clz_optab->handlers[(int) DImode].libfunc = init_one_libfunc ("__clzdi2");
5657   ctz_optab->handlers[(int) SImode].libfunc = init_one_libfunc ("__ctzsi2");
5658   ctz_optab->handlers[(int) DImode].libfunc = init_one_libfunc ("__ctzdi2");
5659   popcount_optab->handlers[(int) SImode].libfunc
5660       = init_one_libfunc ("__popcountsi2");
5661   popcount_optab->handlers[(int) DImode].libfunc
5662       = init_one_libfunc ("__popcountdi2");
5663   parity_optab->handlers[(int) SImode].libfunc = init_one_libfunc ("__paritysi2");
5664   parity_optab->handlers[(int) DImode].libfunc = init_one_libfunc ("__paritydi2");
5665
5666   extendsfdf2_libfunc = init_one_libfunc ("__extendsfdf2");
5667   extendsfxf2_libfunc = init_one_libfunc ("__extendsfxf2");
5668   extendsftf2_libfunc = init_one_libfunc ("__extendsftf2");
5669   extenddfxf2_libfunc = init_one_libfunc ("__extenddfxf2");
5670   extenddftf2_libfunc = init_one_libfunc ("__extenddftf2");
5671
5672   truncdfsf2_libfunc = init_one_libfunc ("__truncdfsf2");
5673   truncxfsf2_libfunc = init_one_libfunc ("__truncxfsf2");
5674   trunctfsf2_libfunc = init_one_libfunc ("__trunctfsf2");
5675   truncxfdf2_libfunc = init_one_libfunc ("__truncxfdf2");
5676   trunctfdf2_libfunc = init_one_libfunc ("__trunctfdf2");
5677
5678   abort_libfunc = init_one_libfunc ("abort");
5679   memcpy_libfunc = init_one_libfunc ("memcpy");
5680   memmove_libfunc = init_one_libfunc ("memmove");
5681   bcopy_libfunc = init_one_libfunc ("bcopy");
5682   memcmp_libfunc = init_one_libfunc ("memcmp");
5683   bcmp_libfunc = init_one_libfunc ("__gcc_bcmp");
5684   memset_libfunc = init_one_libfunc ("memset");
5685   bzero_libfunc = init_one_libfunc ("bzero");
5686
5687   unwind_resume_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
5688                                             ? "_Unwind_SjLj_Resume"
5689                                             : "_Unwind_Resume");
5690 #ifndef DONT_USE_BUILTIN_SETJMP
5691   setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
5692   longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
5693 #else
5694   setjmp_libfunc = init_one_libfunc ("setjmp");
5695   longjmp_libfunc = init_one_libfunc ("longjmp");
5696 #endif
5697   unwind_sjlj_register_libfunc = init_one_libfunc ("_Unwind_SjLj_Register");
5698   unwind_sjlj_unregister_libfunc
5699     = init_one_libfunc ("_Unwind_SjLj_Unregister");
5700
5701   eqhf2_libfunc = init_one_libfunc ("__eqhf2");
5702   nehf2_libfunc = init_one_libfunc ("__nehf2");
5703   gthf2_libfunc = init_one_libfunc ("__gthf2");
5704   gehf2_libfunc = init_one_libfunc ("__gehf2");
5705   lthf2_libfunc = init_one_libfunc ("__lthf2");
5706   lehf2_libfunc = init_one_libfunc ("__lehf2");
5707   unordhf2_libfunc = init_one_libfunc ("__unordhf2");
5708
5709   eqsf2_libfunc = init_one_libfunc ("__eqsf2");
5710   nesf2_libfunc = init_one_libfunc ("__nesf2");
5711   gtsf2_libfunc = init_one_libfunc ("__gtsf2");
5712   gesf2_libfunc = init_one_libfunc ("__gesf2");
5713   ltsf2_libfunc = init_one_libfunc ("__ltsf2");
5714   lesf2_libfunc = init_one_libfunc ("__lesf2");
5715   unordsf2_libfunc = init_one_libfunc ("__unordsf2");
5716
5717   eqdf2_libfunc = init_one_libfunc ("__eqdf2");
5718   nedf2_libfunc = init_one_libfunc ("__nedf2");
5719   gtdf2_libfunc = init_one_libfunc ("__gtdf2");
5720   gedf2_libfunc = init_one_libfunc ("__gedf2");
5721   ltdf2_libfunc = init_one_libfunc ("__ltdf2");
5722   ledf2_libfunc = init_one_libfunc ("__ledf2");
5723   unorddf2_libfunc = init_one_libfunc ("__unorddf2");
5724
5725   eqxf2_libfunc = init_one_libfunc ("__eqxf2");
5726   nexf2_libfunc = init_one_libfunc ("__nexf2");
5727   gtxf2_libfunc = init_one_libfunc ("__gtxf2");
5728   gexf2_libfunc = init_one_libfunc ("__gexf2");
5729   ltxf2_libfunc = init_one_libfunc ("__ltxf2");
5730   lexf2_libfunc = init_one_libfunc ("__lexf2");
5731   unordxf2_libfunc = init_one_libfunc ("__unordxf2");
5732
5733   eqtf2_libfunc = init_one_libfunc ("__eqtf2");
5734   netf2_libfunc = init_one_libfunc ("__netf2");
5735   gttf2_libfunc = init_one_libfunc ("__gttf2");
5736   getf2_libfunc = init_one_libfunc ("__getf2");
5737   lttf2_libfunc = init_one_libfunc ("__lttf2");
5738   letf2_libfunc = init_one_libfunc ("__letf2");
5739   unordtf2_libfunc = init_one_libfunc ("__unordtf2");
5740
5741   floatsisf_libfunc = init_one_libfunc ("__floatsisf");
5742   floatdisf_libfunc = init_one_libfunc ("__floatdisf");
5743   floattisf_libfunc = init_one_libfunc ("__floattisf");
5744
5745   floatsidf_libfunc = init_one_libfunc ("__floatsidf");
5746   floatdidf_libfunc = init_one_libfunc ("__floatdidf");
5747   floattidf_libfunc = init_one_libfunc ("__floattidf");
5748
5749   floatsixf_libfunc = init_one_libfunc ("__floatsixf");
5750   floatdixf_libfunc = init_one_libfunc ("__floatdixf");
5751   floattixf_libfunc = init_one_libfunc ("__floattixf");
5752
5753   floatsitf_libfunc = init_one_libfunc ("__floatsitf");
5754   floatditf_libfunc = init_one_libfunc ("__floatditf");
5755   floattitf_libfunc = init_one_libfunc ("__floattitf");
5756
5757   fixsfsi_libfunc = init_one_libfunc ("__fixsfsi");
5758   fixsfdi_libfunc = init_one_libfunc ("__fixsfdi");
5759   fixsfti_libfunc = init_one_libfunc ("__fixsfti");
5760
5761   fixdfsi_libfunc = init_one_libfunc ("__fixdfsi");
5762   fixdfdi_libfunc = init_one_libfunc ("__fixdfdi");
5763   fixdfti_libfunc = init_one_libfunc ("__fixdfti");
5764
5765   fixxfsi_libfunc = init_one_libfunc ("__fixxfsi");
5766   fixxfdi_libfunc = init_one_libfunc ("__fixxfdi");
5767   fixxfti_libfunc = init_one_libfunc ("__fixxfti");
5768
5769   fixtfsi_libfunc = init_one_libfunc ("__fixtfsi");
5770   fixtfdi_libfunc = init_one_libfunc ("__fixtfdi");
5771   fixtfti_libfunc = init_one_libfunc ("__fixtfti");
5772
5773   fixunssfsi_libfunc = init_one_libfunc ("__fixunssfsi");
5774   fixunssfdi_libfunc = init_one_libfunc ("__fixunssfdi");
5775   fixunssfti_libfunc = init_one_libfunc ("__fixunssfti");
5776
5777   fixunsdfsi_libfunc = init_one_libfunc ("__fixunsdfsi");
5778   fixunsdfdi_libfunc = init_one_libfunc ("__fixunsdfdi");
5779   fixunsdfti_libfunc = init_one_libfunc ("__fixunsdfti");
5780
5781   fixunsxfsi_libfunc = init_one_libfunc ("__fixunsxfsi");
5782   fixunsxfdi_libfunc = init_one_libfunc ("__fixunsxfdi");
5783   fixunsxfti_libfunc = init_one_libfunc ("__fixunsxfti");
5784
5785   fixunstfsi_libfunc = init_one_libfunc ("__fixunstfsi");
5786   fixunstfdi_libfunc = init_one_libfunc ("__fixunstfdi");
5787   fixunstfti_libfunc = init_one_libfunc ("__fixunstfti");
5788
5789   /* For function entry/exit instrumentation.  */
5790   profile_function_entry_libfunc
5791     = init_one_libfunc ("__cyg_profile_func_enter");
5792   profile_function_exit_libfunc
5793     = init_one_libfunc ("__cyg_profile_func_exit");
5794
5795 #ifdef HAVE_conditional_trap
5796   init_traps ();
5797 #endif
5798
5799 #ifdef INIT_TARGET_OPTABS
5800   /* Allow the target to add more libcalls or rename some, etc.  */
5801   INIT_TARGET_OPTABS;
5802 #endif
5803 }
5804 \f
5805 static GTY(()) rtx trap_rtx;
5806
5807 #ifdef HAVE_conditional_trap
5808 /* The insn generating function can not take an rtx_code argument.
5809    TRAP_RTX is used as an rtx argument.  Its code is replaced with
5810    the code to be used in the trap insn and all other fields are
5811    ignored.  */
5812
5813 static void
5814 init_traps ()
5815 {
5816   if (HAVE_conditional_trap)
5817     {
5818       trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
5819     }
5820 }
5821 #endif
5822
5823 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
5824    CODE.  Return 0 on failure.  */
5825
5826 rtx
5827 gen_cond_trap (code, op1, op2, tcode)
5828      enum rtx_code code ATTRIBUTE_UNUSED;
5829      rtx op1, op2 ATTRIBUTE_UNUSED, tcode ATTRIBUTE_UNUSED;
5830 {
5831   enum machine_mode mode = GET_MODE (op1);
5832
5833   if (mode == VOIDmode)
5834     return 0;
5835
5836 #ifdef HAVE_conditional_trap
5837   if (HAVE_conditional_trap
5838       && cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
5839     {
5840       rtx insn;
5841       start_sequence ();
5842       emit_insn (GEN_FCN (cmp_optab->handlers[(int) mode].insn_code) (op1, op2));
5843       PUT_CODE (trap_rtx, code);
5844       insn = gen_conditional_trap (trap_rtx, tcode);
5845       if (insn)
5846         {
5847           emit_insn (insn);
5848           insn = get_insns ();
5849         }
5850       end_sequence ();
5851       return insn;
5852     }
5853 #endif
5854
5855   return 0;
5856 }
5857
5858 #include "gt-optabs.h"