OSDN Git Service

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