OSDN Git Service

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