OSDN Git Service

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