OSDN Git Service

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