OSDN Git Service

* init.c (build_new): Allow enumeration types for the array-bounds
[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.  But don't do this if the machine has
2324      conditional arithmetic since the branches will be converted into
2325      a conditional negation insn.  */
2326
2327 #ifndef HAVE_conditional_arithmetic
2328   if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
2329     {
2330       rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
2331                                    size_int (GET_MODE_BITSIZE (mode) - 1),
2332                                    NULL_RTX, 0);
2333
2334       temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
2335                            OPTAB_LIB_WIDEN);
2336       if (temp != 0)
2337         temp = expand_binop (mode, result_unsignedp ? sub_optab : subv_optab,
2338                              temp, extended, target, 0, OPTAB_LIB_WIDEN);
2339
2340       if (temp != 0)
2341         return temp;
2342     }
2343 #endif
2344
2345   /* If that does not win, use conditional jump and negate.  */
2346
2347   /* It is safe to use the target if it is the same
2348      as the source if this is also a pseudo register */
2349   if (op0 == target && GET_CODE (op0) == REG
2350       && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
2351     safe = 1;
2352
2353   op1 = gen_label_rtx ();
2354   if (target == 0 || ! safe
2355       || GET_MODE (target) != mode
2356       || (GET_CODE (target) == MEM && MEM_VOLATILE_P (target))
2357       || (GET_CODE (target) == REG
2358           && REGNO (target) < FIRST_PSEUDO_REGISTER))
2359     target = gen_reg_rtx (mode);
2360
2361   emit_move_insn (target, op0);
2362   NO_DEFER_POP;
2363
2364   /* If this mode is an integer too wide to compare properly,
2365      compare word by word.  Rely on CSE to optimize constant cases.  */
2366   if (GET_MODE_CLASS (mode) == MODE_INT
2367       && ! can_compare_p (GE, mode, ccp_jump))
2368     do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx, 
2369                                   NULL_RTX, op1);
2370   else
2371     do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
2372                              NULL_RTX, 0, NULL_RTX, op1);
2373
2374   op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
2375                      target, target, 0);
2376   if (op0 != target)
2377     emit_move_insn (target, op0);
2378   emit_label (op1);
2379   OK_DEFER_POP;
2380   return target;
2381 }
2382 \f
2383 /* Emit code to compute the absolute value of OP0, with result to
2384    TARGET if convenient.  (TARGET may be 0.)  The return value says
2385    where the result actually is to be found.
2386
2387    MODE is the mode of the operand; the mode of the result is
2388    different but can be deduced from MODE.
2389
2390    UNSIGNEDP is relevant for complex integer modes.  */
2391
2392 rtx
2393 expand_complex_abs (mode, op0, target, unsignedp)
2394      enum machine_mode mode;
2395      rtx op0;
2396      rtx target;
2397      int unsignedp;
2398 {
2399   enum mode_class class = GET_MODE_CLASS (mode);
2400   enum machine_mode wider_mode;
2401   register rtx temp;
2402   rtx entry_last = get_last_insn ();
2403   rtx last;
2404   rtx pat;
2405   optab this_abs_optab;
2406
2407   /* Find the correct mode for the real and imaginary parts.  */
2408   enum machine_mode submode
2409     = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
2410                      class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
2411                      0);
2412
2413   if (submode == BLKmode)
2414     abort ();
2415
2416   op0 = protect_from_queue (op0, 0);
2417
2418   if (flag_force_mem)
2419     {
2420       op0 = force_not_mem (op0);
2421     }
2422
2423   last = get_last_insn ();
2424
2425   if (target)
2426     target = protect_from_queue (target, 1);
2427
2428   this_abs_optab = ! unsignedp && flag_trapv
2429                    && (GET_MODE_CLASS(mode) == MODE_INT)
2430                    ? absv_optab : abs_optab;
2431
2432   if (this_abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2433     {
2434       int icode = (int) this_abs_optab->handlers[(int) mode].insn_code;
2435       enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2436       rtx xop0 = op0;
2437
2438       if (target)
2439         temp = target;
2440       else
2441         temp = gen_reg_rtx (submode);
2442
2443       if (GET_MODE (xop0) != VOIDmode
2444           && GET_MODE (xop0) != mode0)
2445         xop0 = convert_to_mode (mode0, xop0, unsignedp);
2446
2447       /* Now, if insn doesn't accept our operand, put it into a pseudo.  */
2448
2449       if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
2450         xop0 = copy_to_mode_reg (mode0, xop0);
2451
2452       if (! (*insn_data[icode].operand[0].predicate) (temp, submode))
2453         temp = gen_reg_rtx (submode);
2454
2455       pat = GEN_FCN (icode) (temp, xop0);
2456       if (pat)
2457         {
2458           if (GET_CODE (pat) == SEQUENCE
2459               && ! add_equal_note (pat, temp, this_abs_optab->code, xop0, 
2460                                    NULL_RTX))
2461             {
2462               delete_insns_since (last);
2463               return expand_unop (mode, this_abs_optab, op0, NULL_RTX, 
2464                                   unsignedp);
2465             }
2466
2467           emit_insn (pat);
2468           
2469           return temp;
2470         }
2471       else
2472         delete_insns_since (last);
2473     }
2474
2475   /* It can't be done in this mode.  Can we open-code it in a wider mode?  */
2476
2477   for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2478        wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2479     {
2480       if (this_abs_optab->handlers[(int) wider_mode].insn_code 
2481           != CODE_FOR_nothing)
2482         {
2483           rtx xop0 = op0;
2484
2485           xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2486           temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2487
2488           if (temp)
2489             {
2490               if (class != MODE_COMPLEX_INT)
2491                 {
2492                   if (target == 0)
2493                     target = gen_reg_rtx (submode);
2494                   convert_move (target, temp, 0);
2495                   return target;
2496                 }
2497               else
2498                 return gen_lowpart (submode, temp);
2499             }
2500           else
2501             delete_insns_since (last);
2502         }
2503     }
2504
2505   /* Open-code the complex absolute-value operation
2506      if we can open-code sqrt.  Otherwise it's not worth while.  */
2507   if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing
2508       && ! flag_trapv)
2509     {
2510       rtx real, imag, total;
2511
2512       real = gen_realpart (submode, op0);
2513       imag = gen_imagpart (submode, op0);
2514
2515       /* Square both parts.  */
2516       real = expand_mult (submode, real, real, NULL_RTX, 0);
2517       imag = expand_mult (submode, imag, imag, NULL_RTX, 0);
2518
2519       /* Sum the parts.  */
2520       total = expand_binop (submode, add_optab, real, imag, NULL_RTX,
2521                             0, OPTAB_LIB_WIDEN);
2522
2523       /* Get sqrt in TARGET.  Set TARGET to where the result is.  */
2524       target = expand_unop (submode, sqrt_optab, total, target, 0);
2525       if (target == 0)
2526         delete_insns_since (last);
2527       else
2528         return target;
2529     }
2530
2531   /* Now try a library call in this mode.  */
2532   if (this_abs_optab->handlers[(int) mode].libfunc)
2533     {
2534       rtx insns;
2535       rtx value;
2536
2537       start_sequence ();
2538
2539       /* Pass 1 for NO_QUEUE so we don't lose any increments
2540          if the libcall is cse'd or moved.  */
2541       value = emit_library_call_value (abs_optab->handlers[(int) mode].libfunc,
2542                                        NULL_RTX, LCT_CONST, submode, 1, op0, mode);
2543       insns = get_insns ();
2544       end_sequence ();
2545
2546       target = gen_reg_rtx (submode);
2547       emit_libcall_block (insns, target, value,
2548                           gen_rtx_fmt_e (this_abs_optab->code, mode, op0));
2549
2550       return target;
2551     }
2552
2553   /* It can't be done in this mode.  Can we do it in a wider mode?  */
2554
2555   for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2556        wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2557     {
2558       if ((this_abs_optab->handlers[(int) wider_mode].insn_code
2559            != CODE_FOR_nothing)
2560           || this_abs_optab->handlers[(int) wider_mode].libfunc)
2561         {
2562           rtx xop0 = op0;
2563
2564           xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2565
2566           temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2567
2568           if (temp)
2569             {
2570               if (class != MODE_COMPLEX_INT)
2571                 {
2572                   if (target == 0)
2573                     target = gen_reg_rtx (submode);
2574                   convert_move (target, temp, 0);
2575                   return target;
2576                 }
2577               else
2578                 return gen_lowpart (submode, temp);
2579             }
2580           else
2581             delete_insns_since (last);
2582         }
2583     }
2584
2585   delete_insns_since (entry_last);
2586   return 0;
2587 }
2588 \f
2589 /* Generate an instruction whose insn-code is INSN_CODE,
2590    with two operands: an output TARGET and an input OP0.
2591    TARGET *must* be nonzero, and the output is always stored there.
2592    CODE is an rtx code such that (CODE OP0) is an rtx that describes
2593    the value that is stored into TARGET.  */
2594
2595 void
2596 emit_unop_insn (icode, target, op0, code)
2597      int icode;
2598      rtx target;
2599      rtx op0;
2600      enum rtx_code code;
2601 {
2602   register rtx temp;
2603   enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2604   rtx pat;
2605
2606   temp = target = protect_from_queue (target, 1);
2607
2608   op0 = protect_from_queue (op0, 0);
2609
2610   /* Sign and zero extension from memory is often done specially on
2611      RISC machines, so forcing into a register here can pessimize
2612      code.  */
2613   if (flag_force_mem && code != SIGN_EXTEND && code != ZERO_EXTEND)
2614     op0 = force_not_mem (op0);
2615
2616   /* Now, if insn does not accept our operands, put them into pseudos.  */
2617
2618   if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
2619     op0 = copy_to_mode_reg (mode0, op0);
2620
2621   if (! (*insn_data[icode].operand[0].predicate) (temp, GET_MODE (temp))
2622       || (flag_force_mem && GET_CODE (temp) == MEM))
2623     temp = gen_reg_rtx (GET_MODE (temp));
2624
2625   pat = GEN_FCN (icode) (temp, op0);
2626
2627   if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
2628     add_equal_note (pat, temp, code, op0, NULL_RTX);
2629   
2630   emit_insn (pat);
2631
2632   if (temp != target)
2633     emit_move_insn (target, temp);
2634 }
2635 \f
2636 /* Emit code to perform a series of operations on a multi-word quantity, one
2637    word at a time.
2638
2639    Such a block is preceded by a CLOBBER of the output, consists of multiple
2640    insns, each setting one word of the output, and followed by a SET copying
2641    the output to itself.
2642
2643    Each of the insns setting words of the output receives a REG_NO_CONFLICT
2644    note indicating that it doesn't conflict with the (also multi-word)
2645    inputs.  The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2646    notes.
2647
2648    INSNS is a block of code generated to perform the operation, not including
2649    the CLOBBER and final copy.  All insns that compute intermediate values
2650    are first emitted, followed by the block as described above.  
2651
2652    TARGET, OP0, and OP1 are the output and inputs of the operations,
2653    respectively.  OP1 may be zero for a unary operation.
2654
2655    EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
2656    on the last insn.
2657
2658    If TARGET is not a register, INSNS is simply emitted with no special
2659    processing.  Likewise if anything in INSNS is not an INSN or if
2660    there is a libcall block inside INSNS.
2661
2662    The final insn emitted is returned.  */
2663
2664 rtx
2665 emit_no_conflict_block (insns, target, op0, op1, equiv)
2666      rtx insns;
2667      rtx target;
2668      rtx op0, op1;
2669      rtx equiv;
2670 {
2671   rtx prev, next, first, last, insn;
2672
2673   if (GET_CODE (target) != REG || reload_in_progress)
2674     return emit_insns (insns);
2675   else
2676     for (insn = insns; insn; insn = NEXT_INSN (insn))
2677       if (GET_CODE (insn) != INSN
2678           || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
2679         return emit_insns (insns);
2680
2681   /* First emit all insns that do not store into words of the output and remove
2682      these from the list.  */
2683   for (insn = insns; insn; insn = next)
2684     {
2685       rtx set = 0;
2686       int i;
2687
2688       next = NEXT_INSN (insn);
2689
2690       if (GET_CODE (PATTERN (insn)) == SET || GET_CODE (PATTERN (insn)) == USE
2691           || GET_CODE (PATTERN (insn)) == CLOBBER)
2692         set = PATTERN (insn);
2693       else if (GET_CODE (PATTERN (insn)) == PARALLEL)
2694         {
2695           for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
2696             if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
2697               {
2698                 set = XVECEXP (PATTERN (insn), 0, i);
2699                 break;
2700               }
2701         }
2702
2703       if (set == 0)
2704         abort ();
2705
2706       if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
2707         {
2708           if (PREV_INSN (insn))
2709             NEXT_INSN (PREV_INSN (insn)) = next;
2710           else
2711             insns = next;
2712
2713           if (next)
2714             PREV_INSN (next) = PREV_INSN (insn);
2715
2716           add_insn (insn);
2717         }
2718     }
2719
2720   prev = get_last_insn ();
2721
2722   /* Now write the CLOBBER of the output, followed by the setting of each
2723      of the words, followed by the final copy.  */
2724   if (target != op0 && target != op1)
2725     emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
2726
2727   for (insn = insns; insn; insn = next)
2728     {
2729       next = NEXT_INSN (insn);
2730       add_insn (insn);
2731
2732       if (op1 && GET_CODE (op1) == REG)
2733         REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op1,
2734                                               REG_NOTES (insn));
2735
2736       if (op0 && GET_CODE (op0) == REG)
2737         REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op0,
2738                                               REG_NOTES (insn));
2739     }
2740
2741   if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2742       != CODE_FOR_nothing)
2743     {
2744       last = emit_move_insn (target, target);
2745       if (equiv)
2746         set_unique_reg_note (last, REG_EQUAL, equiv);
2747     }
2748   else
2749     {
2750       last = get_last_insn ();
2751
2752       /* Remove any existing REG_EQUAL note from "last", or else it will
2753          be mistaken for a note referring to the full contents of the
2754          alleged libcall value when found together with the REG_RETVAL
2755          note added below.  An existing note can come from an insn
2756          expansion at "last".  */
2757       remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
2758     }
2759
2760   if (prev == 0)
2761     first = get_insns ();
2762   else
2763     first = NEXT_INSN (prev);
2764
2765   /* Encapsulate the block so it gets manipulated as a unit.  */
2766   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
2767                                          REG_NOTES (first));
2768   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2769
2770   return last;
2771 }
2772 \f
2773 /* Emit code to make a call to a constant function or a library call.
2774
2775    INSNS is a list containing all insns emitted in the call.
2776    These insns leave the result in RESULT.  Our block is to copy RESULT
2777    to TARGET, which is logically equivalent to EQUIV.
2778
2779    We first emit any insns that set a pseudo on the assumption that these are
2780    loading constants into registers; doing so allows them to be safely cse'ed
2781    between blocks.  Then we emit all the other insns in the block, followed by
2782    an insn to move RESULT to TARGET.  This last insn will have a REQ_EQUAL
2783    note with an operand of EQUIV.
2784
2785    Moving assignments to pseudos outside of the block is done to improve
2786    the generated code, but is not required to generate correct code,
2787    hence being unable to move an assignment is not grounds for not making
2788    a libcall block.  There are two reasons why it is safe to leave these
2789    insns inside the block: First, we know that these pseudos cannot be
2790    used in generated RTL outside the block since they are created for
2791    temporary purposes within the block.  Second, CSE will not record the
2792    values of anything set inside a libcall block, so we know they must
2793    be dead at the end of the block.
2794
2795    Except for the first group of insns (the ones setting pseudos), the
2796    block is delimited by REG_RETVAL and REG_LIBCALL notes.  */
2797
2798 void
2799 emit_libcall_block (insns, target, result, equiv)
2800      rtx insns;
2801      rtx target;
2802      rtx result;
2803      rtx equiv;
2804 {
2805   rtx final_dest = target;
2806   rtx prev, next, first, last, insn;
2807
2808   /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
2809      into a MEM later.  Protect the libcall block from this change.  */
2810   if (! REG_P (target) || REG_USERVAR_P (target))
2811     target = gen_reg_rtx (GET_MODE (target));
2812
2813   /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
2814      reg note to indicate that this call cannot throw or execute a nonlocal
2815      goto (unless there is already a REG_EH_REGION note, in which case
2816      we update it).  Also set the CONST_CALL_P flag.  */
2817
2818   for (insn = insns; insn; insn = NEXT_INSN (insn))
2819     if (GET_CODE (insn) == CALL_INSN)
2820       {
2821         rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2822
2823         CONST_CALL_P (insn) = 1;
2824         if (note != 0)
2825           XEXP (note, 0) = GEN_INT (-1);
2826         else
2827           REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, GEN_INT (-1),
2828                                                 REG_NOTES (insn));
2829       }
2830
2831   /* First emit all insns that set pseudos.  Remove them from the list as
2832      we go.  Avoid insns that set pseudos which were referenced in previous
2833      insns.  These can be generated by move_by_pieces, for example,
2834      to update an address.  Similarly, avoid insns that reference things
2835      set in previous insns.  */
2836
2837   for (insn = insns; insn; insn = next)
2838     {
2839       rtx set = single_set (insn);
2840
2841       next = NEXT_INSN (insn);
2842
2843       if (set != 0 && GET_CODE (SET_DEST (set)) == REG
2844           && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
2845           && (insn == insns
2846               || ((! INSN_P(insns)
2847                    || ! reg_mentioned_p (SET_DEST (set), PATTERN (insns)))
2848                   && ! reg_used_between_p (SET_DEST (set), insns, insn)
2849                   && ! modified_in_p (SET_SRC (set), insns)
2850                   && ! modified_between_p (SET_SRC (set), insns, insn))))
2851         {
2852           if (PREV_INSN (insn))
2853             NEXT_INSN (PREV_INSN (insn)) = next;
2854           else
2855             insns = next;
2856
2857           if (next)
2858             PREV_INSN (next) = PREV_INSN (insn);
2859
2860           add_insn (insn);
2861         }
2862     }
2863
2864   prev = get_last_insn ();
2865
2866   /* Write the remaining insns followed by the final copy.  */
2867
2868   for (insn = insns; insn; insn = next)
2869     {
2870       next = NEXT_INSN (insn);
2871
2872       add_insn (insn);
2873     }
2874
2875   last = emit_move_insn (target, result);
2876   if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2877       != CODE_FOR_nothing)
2878     set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
2879   else
2880     {
2881       /* Remove any existing REG_EQUAL note from "last", or else it will
2882          be mistaken for a note referring to the full contents of the
2883          libcall value when found together with the REG_RETVAL note added
2884          below.  An existing note can come from an insn expansion at
2885          "last".  */
2886       remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
2887     }
2888
2889   if (final_dest != target)
2890     emit_move_insn (final_dest, target);
2891
2892   if (prev == 0)
2893     first = get_insns ();
2894   else
2895     first = NEXT_INSN (prev);
2896
2897   /* Encapsulate the block so it gets manipulated as a unit.  */
2898   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
2899                                          REG_NOTES (first));
2900   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2901 }
2902 \f
2903 /* Generate code to store zero in X.  */
2904
2905 void
2906 emit_clr_insn (x)
2907      rtx x;
2908 {
2909   emit_move_insn (x, const0_rtx);
2910 }
2911
2912 /* Generate code to store 1 in X
2913    assuming it contains zero beforehand.  */
2914
2915 void
2916 emit_0_to_1_insn (x)
2917      rtx x;
2918 {
2919   emit_move_insn (x, const1_rtx);
2920 }
2921
2922 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
2923    PURPOSE describes how this comparison will be used.  CODE is the rtx
2924    comparison code we will be using.
2925
2926    ??? Actually, CODE is slightly weaker than that.  A target is still
2927    required to implement all of the normal bcc operations, but not 
2928    required to implement all (or any) of the unordered bcc operations.  */
2929   
2930 int
2931 can_compare_p (code, mode, purpose)
2932      enum rtx_code code;
2933      enum machine_mode mode;
2934      enum can_compare_purpose purpose;
2935 {
2936   do
2937     {
2938       if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2939         {
2940           if (purpose == ccp_jump)
2941             return bcc_gen_fctn[(int)code] != NULL;
2942           else if (purpose == ccp_store_flag)
2943             return setcc_gen_code[(int)code] != CODE_FOR_nothing;
2944           else
2945             /* There's only one cmov entry point, and it's allowed to fail.  */
2946             return 1;
2947         }
2948       if (purpose == ccp_jump
2949           && cbranch_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2950         return 1;
2951       if (purpose == ccp_cmov
2952           && cmov_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2953         return 1;
2954       if (purpose == ccp_store_flag
2955           && cstore_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2956         return 1;
2957
2958       mode = GET_MODE_WIDER_MODE (mode);
2959     }
2960   while (mode != VOIDmode);
2961
2962   return 0;
2963 }
2964
2965 /* This function is called when we are going to emit a compare instruction that
2966    compares the values found in *PX and *PY, using the rtl operator COMPARISON.
2967
2968    *PMODE is the mode of the inputs (in case they are const_int).
2969    *PUNSIGNEDP nonzero says that the operands are unsigned;
2970    this matters if they need to be widened.
2971
2972    If they have mode BLKmode, then SIZE specifies the size of both operands,
2973    and ALIGN specifies the known shared alignment of the operands.
2974
2975    This function performs all the setup necessary so that the caller only has
2976    to emit a single comparison insn.  This setup can involve doing a BLKmode
2977    comparison or emitting a library call to perform the comparison if no insn
2978    is available to handle it.
2979    The values which are passed in through pointers can be modified; the caller
2980    should perform the comparison on the modified values.  */
2981
2982 void
2983 prepare_cmp_insn (px, py, pcomparison, size, pmode, punsignedp, align,
2984                   purpose)
2985      rtx *px, *py;
2986      enum rtx_code *pcomparison;
2987      rtx size;
2988      enum machine_mode *pmode;
2989      int *punsignedp;
2990      int align ATTRIBUTE_UNUSED;
2991      enum can_compare_purpose purpose;
2992 {
2993   enum machine_mode mode = *pmode;
2994   rtx x = *px, y = *py;
2995   int unsignedp = *punsignedp;
2996   enum mode_class class;
2997   rtx opalign ATTRIBUTE_UNUSED = GEN_INT (align / BITS_PER_UNIT);;
2998
2999   class = GET_MODE_CLASS (mode);
3000
3001   /* They could both be VOIDmode if both args are immediate constants,
3002      but we should fold that at an earlier stage.
3003      With no special code here, this will call abort,
3004      reminding the programmer to implement such folding.  */
3005
3006   if (mode != BLKmode && flag_force_mem)
3007     {
3008       x = force_not_mem (x);
3009       y = force_not_mem (y);
3010     }
3011
3012   /* If we are inside an appropriately-short loop and one operand is an
3013      expensive constant, force it into a register.  */
3014   if (CONSTANT_P (x) && preserve_subexpressions_p ()
3015       && rtx_cost (x, COMPARE) > COSTS_N_INSNS (1))
3016     x = force_reg (mode, x);
3017
3018   if (CONSTANT_P (y) && preserve_subexpressions_p ()
3019       && rtx_cost (y, COMPARE) > COSTS_N_INSNS (1))
3020     y = force_reg (mode, y);
3021
3022 #ifdef HAVE_cc0
3023   /* Abort if we have a non-canonical comparison.  The RTL documentation
3024      states that canonical comparisons are required only for targets which
3025      have cc0.  */
3026   if (CONSTANT_P (x) && ! CONSTANT_P (y))
3027     abort();
3028 #endif
3029
3030   /* Don't let both operands fail to indicate the mode.  */
3031   if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
3032     x = force_reg (mode, x);
3033
3034   /* Handle all BLKmode compares.  */
3035
3036   if (mode == BLKmode)
3037     {
3038       rtx result;
3039       enum machine_mode result_mode;
3040
3041       emit_queue ();
3042       x = protect_from_queue (x, 0);
3043       y = protect_from_queue (y, 0);
3044
3045       if (size == 0)
3046         abort ();
3047 #ifdef HAVE_cmpstrqi
3048       if (HAVE_cmpstrqi
3049           && GET_CODE (size) == CONST_INT
3050           && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
3051         {
3052           result_mode = insn_data[(int) CODE_FOR_cmpstrqi].operand[0].mode;
3053           result = gen_reg_rtx (result_mode);
3054           emit_insn (gen_cmpstrqi (result, x, y, size, opalign));
3055         }
3056       else
3057 #endif
3058 #ifdef HAVE_cmpstrhi
3059       if (HAVE_cmpstrhi
3060           && GET_CODE (size) == CONST_INT
3061           && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
3062         {
3063           result_mode = insn_data[(int) CODE_FOR_cmpstrhi].operand[0].mode;
3064           result = gen_reg_rtx (result_mode);
3065           emit_insn (gen_cmpstrhi (result, x, y, size, opalign));
3066         }
3067       else
3068 #endif
3069 #ifdef HAVE_cmpstrsi
3070       if (HAVE_cmpstrsi)
3071         {
3072           result_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3073           result = gen_reg_rtx (result_mode);
3074           size = protect_from_queue (size, 0);
3075           emit_insn (gen_cmpstrsi (result, x, y,
3076                                    convert_to_mode (SImode, size, 1),
3077                                    opalign));
3078         }
3079       else
3080 #endif
3081         {
3082 #ifdef TARGET_MEM_FUNCTIONS
3083           emit_library_call (memcmp_libfunc, LCT_PURE_MAKE_BLOCK,
3084                              TYPE_MODE (integer_type_node), 3,
3085                              XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
3086                              convert_to_mode (TYPE_MODE (sizetype), size,
3087                                               TREE_UNSIGNED (sizetype)),
3088                              TYPE_MODE (sizetype));
3089 #else
3090           emit_library_call (bcmp_libfunc, LCT_PURE_MAKE_BLOCK,
3091                              TYPE_MODE (integer_type_node), 3,
3092                              XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
3093                              convert_to_mode (TYPE_MODE (integer_type_node),
3094                                               size,
3095                                               TREE_UNSIGNED (integer_type_node)),
3096                              TYPE_MODE (integer_type_node));
3097 #endif
3098
3099           /* Immediately move the result of the libcall into a pseudo
3100              register so reload doesn't clobber the value if it needs
3101              the return register for a spill reg.  */
3102           result = gen_reg_rtx (TYPE_MODE (integer_type_node));
3103           result_mode = TYPE_MODE (integer_type_node);
3104           emit_move_insn (result,
3105                           hard_libcall_value (result_mode));
3106         }
3107       *px = result;
3108       *py = const0_rtx;
3109       *pmode = result_mode;
3110       return;
3111     }
3112
3113   *px = x;
3114   *py = y;
3115   if (can_compare_p (*pcomparison, mode, purpose))
3116     return;
3117
3118   /* Handle a lib call just for the mode we are using.  */
3119
3120   if (cmp_optab->handlers[(int) mode].libfunc && class != MODE_FLOAT)
3121     {
3122       rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
3123       rtx result;
3124
3125       /* If we want unsigned, and this mode has a distinct unsigned
3126          comparison routine, use that.  */
3127       if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
3128         libfunc = ucmp_optab->handlers[(int) mode].libfunc;
3129
3130       emit_library_call (libfunc, 1,
3131                          word_mode, 2, x, mode, y, mode);
3132
3133       /* Immediately move the result of the libcall into a pseudo
3134          register so reload doesn't clobber the value if it needs
3135          the return register for a spill reg.  */
3136       result = gen_reg_rtx (word_mode);
3137       emit_move_insn (result, hard_libcall_value (word_mode));
3138
3139       /* Integer comparison returns a result that must be compared against 1,
3140          so that even if we do an unsigned compare afterward,
3141          there is still a value that can represent the result "less than".  */
3142       *px = result;
3143       *py = const1_rtx;
3144       *pmode = word_mode;
3145       return;
3146     }
3147
3148   if (class == MODE_FLOAT)
3149     prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
3150
3151   else
3152     abort ();
3153 }
3154
3155 /* Before emitting an insn with code ICODE, make sure that X, which is going
3156    to be used for operand OPNUM of the insn, is converted from mode MODE to
3157    WIDER_MODE (UNSIGNEDP determines whether it is a unsigned conversion), and
3158    that it is accepted by the operand predicate.  Return the new value.  */
3159
3160 rtx
3161 prepare_operand (icode, x, opnum, mode, wider_mode, unsignedp)
3162      int icode;
3163      rtx x;
3164      int opnum;
3165      enum machine_mode mode, wider_mode;
3166      int unsignedp;
3167 {
3168   x = protect_from_queue (x, 0);
3169
3170   if (mode != wider_mode)
3171     x = convert_modes (wider_mode, mode, x, unsignedp);
3172
3173   if (! (*insn_data[icode].operand[opnum].predicate)
3174       (x, insn_data[icode].operand[opnum].mode))
3175     x = copy_to_mode_reg (insn_data[icode].operand[opnum].mode, x);
3176   return x;
3177 }
3178
3179 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
3180    we can do the comparison.
3181    The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may
3182    be NULL_RTX which indicates that only a comparison is to be generated.  */
3183
3184 static void
3185 emit_cmp_and_jump_insn_1 (x, y, mode, comparison, unsignedp, label)
3186      rtx x, y;
3187      enum machine_mode mode;
3188      enum rtx_code comparison;
3189      int unsignedp;
3190      rtx label;
3191 {
3192   rtx test = gen_rtx_fmt_ee (comparison, mode, x, y);
3193   enum mode_class class = GET_MODE_CLASS (mode);
3194   enum machine_mode wider_mode = mode;
3195
3196   /* Try combined insns first.  */
3197   do
3198     {
3199       enum insn_code icode;
3200       PUT_MODE (test, wider_mode);
3201
3202       if (label)
3203         {         
3204           icode = cbranch_optab->handlers[(int)wider_mode].insn_code;
3205           
3206           if (icode != CODE_FOR_nothing
3207               && (*insn_data[icode].operand[0].predicate) (test, wider_mode))
3208             {
3209               x = prepare_operand (icode, x, 1, mode, wider_mode, unsignedp);
3210               y = prepare_operand (icode, y, 2, mode, wider_mode, unsignedp);
3211               emit_jump_insn (GEN_FCN (icode) (test, x, y, label));
3212               return;
3213             }
3214         }
3215
3216       /* Handle some compares against zero.  */
3217       icode = (int) tst_optab->handlers[(int) wider_mode].insn_code;
3218       if (y == CONST0_RTX (mode) && icode != CODE_FOR_nothing)
3219         {
3220           x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3221           emit_insn (GEN_FCN (icode) (x));
3222           if (label)
3223             emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
3224           return;
3225         }
3226
3227       /* Handle compares for which there is a directly suitable insn.  */
3228
3229       icode = (int) cmp_optab->handlers[(int) wider_mode].insn_code;
3230       if (icode != CODE_FOR_nothing)
3231         {
3232           x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3233           y = prepare_operand (icode, y, 1, mode, wider_mode, unsignedp);
3234           emit_insn (GEN_FCN (icode) (x, y));
3235           if (label)
3236             emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
3237           return;
3238         }
3239
3240       if (class != MODE_INT && class != MODE_FLOAT
3241           && class != MODE_COMPLEX_FLOAT)
3242         break;
3243
3244       wider_mode = GET_MODE_WIDER_MODE (wider_mode);
3245     } while (wider_mode != VOIDmode);
3246
3247   abort ();
3248 }
3249
3250 /* Generate code to compare X with Y so that the condition codes are
3251    set and to jump to LABEL if the condition is true.  If X is a
3252    constant and Y is not a constant, then the comparison is swapped to
3253    ensure that the comparison RTL has the canonical form.
3254
3255    UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
3256    need to be widened by emit_cmp_insn.  UNSIGNEDP is also used to select
3257    the proper branch condition code.
3258
3259    If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y,
3260    and ALIGN specifies the known shared alignment of X and Y. 
3261
3262    MODE is the mode of the inputs (in case they are const_int).
3263
3264    COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  It will
3265    be passed unchanged to emit_cmp_insn, then potentially converted into an
3266    unsigned variant based on UNSIGNEDP to select a proper jump instruction.  */
3267
3268 void
3269 emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, align, label)
3270      rtx x, y;
3271      enum rtx_code comparison;
3272      rtx size;
3273      enum machine_mode mode;
3274      int unsignedp;
3275      unsigned int align;
3276      rtx label;
3277 {
3278   rtx op0;
3279   rtx op1;
3280           
3281   if ((CONSTANT_P (x) && ! CONSTANT_P (y))
3282       || (GET_CODE (x) == CONST_INT && GET_CODE (y) != CONST_INT))
3283     {
3284       /* Swap operands and condition to ensure canonical RTL.  */
3285       op0 = y;
3286       op1 = x;
3287       comparison = swap_condition (comparison);
3288     }
3289   else
3290     {
3291       op0 = x;
3292       op1 = y;
3293     }
3294
3295 #ifdef HAVE_cc0
3296   /* If OP0 is still a constant, then both X and Y must be constants.  Force
3297      X into a register to avoid aborting in emit_cmp_insn due to non-canonical
3298      RTL.  */
3299   if (CONSTANT_P (op0))
3300     op0 = force_reg (mode, op0);
3301 #endif
3302
3303   emit_queue ();
3304   if (unsignedp)
3305     comparison = unsigned_condition (comparison);
3306   prepare_cmp_insn (&op0, &op1, &comparison, size, &mode, &unsignedp, align,
3307                     ccp_jump);
3308   emit_cmp_and_jump_insn_1 (op0, op1, mode, comparison, unsignedp, label);
3309 }
3310
3311 /* Like emit_cmp_and_jump_insns, but generate only the comparison.  */
3312
3313 void
3314 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
3315      rtx x, y;
3316      enum rtx_code comparison;
3317      rtx size;
3318      enum machine_mode mode;
3319      int unsignedp;
3320      unsigned int align;
3321 {
3322   emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, align, 0);
3323 }
3324 \f
3325 /* Emit a library call comparison between floating point X and Y.
3326    COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  */
3327
3328 static void
3329 prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp)
3330      rtx *px, *py;
3331      enum rtx_code *pcomparison;
3332      enum machine_mode *pmode;
3333      int *punsignedp;
3334 {
3335   enum rtx_code comparison = *pcomparison;
3336   rtx x = *px = protect_from_queue (*px, 0);
3337   rtx y = *py = protect_from_queue (*py, 0);
3338   enum machine_mode mode = GET_MODE (x);
3339   rtx libfunc = 0;
3340   rtx result;
3341
3342   if (mode == HFmode)
3343     switch (comparison)
3344       {
3345       case EQ:
3346         libfunc = eqhf2_libfunc;
3347         break;
3348
3349       case NE:
3350         libfunc = nehf2_libfunc;
3351         break;
3352
3353       case GT:
3354         libfunc = gthf2_libfunc;
3355         break;
3356
3357       case GE:
3358         libfunc = gehf2_libfunc;
3359         break;
3360
3361       case LT:
3362         libfunc = lthf2_libfunc;
3363         break;
3364
3365       case LE:
3366         libfunc = lehf2_libfunc;
3367         break;
3368
3369       case UNORDERED:
3370         libfunc = unordhf2_libfunc;
3371         break;
3372
3373       default:
3374         break;
3375       }
3376   else if (mode == SFmode)
3377     switch (comparison)
3378       {
3379       case EQ:
3380         libfunc = eqsf2_libfunc;
3381         break;
3382
3383       case NE:
3384         libfunc = nesf2_libfunc;
3385         break;
3386
3387       case GT:
3388         libfunc = gtsf2_libfunc;
3389         break;
3390
3391       case GE:
3392         libfunc = gesf2_libfunc;
3393         break;
3394
3395       case LT:
3396         libfunc = ltsf2_libfunc;
3397         break;
3398
3399       case LE:
3400         libfunc = lesf2_libfunc;
3401         break;
3402
3403       case UNORDERED:
3404         libfunc = unordsf2_libfunc;
3405         break;
3406
3407       default:
3408         break;
3409       }
3410   else if (mode == DFmode)
3411     switch (comparison)
3412       {
3413       case EQ:
3414         libfunc = eqdf2_libfunc;
3415         break;
3416
3417       case NE:
3418         libfunc = nedf2_libfunc;
3419         break;
3420
3421       case GT:
3422         libfunc = gtdf2_libfunc;
3423         break;
3424
3425       case GE:
3426         libfunc = gedf2_libfunc;
3427         break;
3428
3429       case LT:
3430         libfunc = ltdf2_libfunc;
3431         break;
3432
3433       case LE:
3434         libfunc = ledf2_libfunc;
3435         break;
3436
3437       case UNORDERED:
3438         libfunc = unorddf2_libfunc;
3439         break;
3440
3441       default:
3442         break;
3443       }
3444   else if (mode == XFmode)
3445     switch (comparison)
3446       {
3447       case EQ:
3448         libfunc = eqxf2_libfunc;
3449         break;
3450
3451       case NE:
3452         libfunc = nexf2_libfunc;
3453         break;
3454
3455       case GT:
3456         libfunc = gtxf2_libfunc;
3457         break;
3458
3459       case GE:
3460         libfunc = gexf2_libfunc;
3461         break;
3462
3463       case LT:
3464         libfunc = ltxf2_libfunc;
3465         break;
3466
3467       case LE:
3468         libfunc = lexf2_libfunc;
3469         break;
3470
3471       case UNORDERED:
3472         libfunc = unordxf2_libfunc;
3473         break;
3474
3475       default:
3476         break;
3477       }
3478   else if (mode == TFmode)
3479     switch (comparison)
3480       {
3481       case EQ:
3482         libfunc = eqtf2_libfunc;
3483         break;
3484
3485       case NE:
3486         libfunc = netf2_libfunc;
3487         break;
3488
3489       case GT:
3490         libfunc = gttf2_libfunc;
3491         break;
3492
3493       case GE:
3494         libfunc = getf2_libfunc;
3495         break;
3496
3497       case LT:
3498         libfunc = lttf2_libfunc;
3499         break;
3500
3501       case LE:
3502         libfunc = letf2_libfunc;
3503         break;
3504
3505       case UNORDERED:
3506         libfunc = unordtf2_libfunc;
3507         break;
3508
3509       default:
3510         break;
3511       }
3512   else
3513     {
3514       enum machine_mode wider_mode;
3515
3516       for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3517            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3518         {
3519           if ((cmp_optab->handlers[(int) wider_mode].insn_code
3520                != CODE_FOR_nothing)
3521               || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
3522             {
3523               x = protect_from_queue (x, 0);
3524               y = protect_from_queue (y, 0);
3525               *px = convert_to_mode (wider_mode, x, 0);
3526               *py = convert_to_mode (wider_mode, y, 0);
3527               prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
3528               return;
3529             }
3530         }
3531       abort ();
3532     }
3533
3534   if (libfunc == 0)
3535     abort ();
3536
3537   emit_library_call (libfunc, LCT_CONST_MAKE_BLOCK, word_mode, 2, x, mode, y,
3538                      mode);
3539
3540   /* Immediately move the result of the libcall into a pseudo
3541      register so reload doesn't clobber the value if it needs
3542      the return register for a spill reg.  */
3543   result = gen_reg_rtx (word_mode);
3544   emit_move_insn (result, hard_libcall_value (word_mode));
3545   *px = result;
3546   *py = const0_rtx;
3547   *pmode = word_mode;
3548   if (comparison == UNORDERED)
3549     *pcomparison = NE;
3550 #ifdef FLOAT_LIB_COMPARE_RETURNS_BOOL
3551   else if (FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
3552     *pcomparison = NE;
3553 #endif
3554   *punsignedp = 0;
3555 }
3556 \f
3557 /* Generate code to indirectly jump to a location given in the rtx LOC.  */
3558
3559 void
3560 emit_indirect_jump (loc)
3561      rtx loc;
3562 {
3563   if (! ((*insn_data[(int)CODE_FOR_indirect_jump].operand[0].predicate)
3564          (loc, Pmode)))
3565     loc = copy_to_mode_reg (Pmode, loc);
3566
3567   emit_jump_insn (gen_indirect_jump (loc));
3568   emit_barrier ();
3569 }
3570 \f
3571 #ifdef HAVE_conditional_move
3572
3573 /* Emit a conditional move instruction if the machine supports one for that
3574    condition and machine mode.
3575
3576    OP0 and OP1 are the operands that should be compared using CODE.  CMODE is
3577    the mode to use should they be constants.  If it is VOIDmode, they cannot
3578    both be constants.
3579
3580    OP2 should be stored in TARGET if the comparison is true, otherwise OP3
3581    should be stored there.  MODE is the mode to use should they be constants.
3582    If it is VOIDmode, they cannot both be constants.
3583
3584    The result is either TARGET (perhaps modified) or NULL_RTX if the operation
3585    is not supported.  */
3586
3587 rtx
3588 emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
3589                        unsignedp)
3590      rtx target;
3591      enum rtx_code code;
3592      rtx op0, op1;
3593      enum machine_mode cmode;
3594      rtx op2, op3;
3595      enum machine_mode mode;
3596      int unsignedp;
3597 {
3598   rtx tem, subtarget, comparison, insn;
3599   enum insn_code icode;
3600
3601   /* If one operand is constant, make it the second one.  Only do this
3602      if the other operand is not constant as well.  */
3603
3604   if ((CONSTANT_P (op0) && ! CONSTANT_P (op1))
3605       || (GET_CODE (op0) == CONST_INT && GET_CODE (op1) != CONST_INT))
3606     {
3607       tem = op0;
3608       op0 = op1;
3609       op1 = tem;
3610       code = swap_condition (code);
3611     }
3612
3613   /* get_condition will prefer to generate LT and GT even if the old
3614      comparison was against zero, so undo that canonicalization here since
3615      comparisons against zero are cheaper.  */
3616   if (code == LT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == 1)
3617     code = LE, op1 = const0_rtx;
3618   else if (code == GT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == -1)
3619     code = GE, op1 = const0_rtx;
3620
3621   if (cmode == VOIDmode)
3622     cmode = GET_MODE (op0);
3623
3624   if (((CONSTANT_P (op2) && ! CONSTANT_P (op3))
3625        || (GET_CODE (op2) == CONST_INT && GET_CODE (op3) != CONST_INT))
3626       && (GET_MODE_CLASS (GET_MODE (op1)) != MODE_FLOAT
3627           || TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT || flag_fast_math))
3628     {
3629       tem = op2;
3630       op2 = op3;
3631       op3 = tem;
3632       code = reverse_condition (code);
3633     }
3634
3635   if (mode == VOIDmode)
3636     mode = GET_MODE (op2);
3637
3638   icode = movcc_gen_code[mode];
3639
3640   if (icode == CODE_FOR_nothing)
3641     return 0;
3642
3643   if (flag_force_mem)
3644     {
3645       op2 = force_not_mem (op2);
3646       op3 = force_not_mem (op3);
3647     }
3648
3649   if (target)
3650     target = protect_from_queue (target, 1);
3651   else
3652     target = gen_reg_rtx (mode);
3653
3654   subtarget = target;
3655
3656   emit_queue ();
3657
3658   op2 = protect_from_queue (op2, 0);
3659   op3 = protect_from_queue (op3, 0);
3660
3661   /* If the insn doesn't accept these operands, put them in pseudos.  */
3662
3663   if (! (*insn_data[icode].operand[0].predicate)
3664       (subtarget, insn_data[icode].operand[0].mode))
3665     subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
3666
3667   if (! (*insn_data[icode].operand[2].predicate)
3668       (op2, insn_data[icode].operand[2].mode))
3669     op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
3670
3671   if (! (*insn_data[icode].operand[3].predicate)
3672       (op3, insn_data[icode].operand[3].mode))
3673     op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
3674
3675   /* Everything should now be in the suitable form, so emit the compare insn
3676      and then the conditional move.  */
3677
3678   comparison 
3679     = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX, 0);
3680
3681   /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)?  */
3682   /* We can get const0_rtx or const_true_rtx in some circumstances.  Just
3683      return NULL and let the caller figure out how best to deal with this
3684      situation.  */
3685   if (GET_CODE (comparison) != code)
3686     return NULL_RTX;
3687   
3688   insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
3689
3690   /* If that failed, then give up.  */
3691   if (insn == 0)
3692     return 0;
3693
3694   emit_insn (insn);
3695
3696   if (subtarget != target)
3697     convert_move (target, subtarget, 0);
3698
3699   return target;
3700 }
3701
3702 /* Return non-zero if a conditional move of mode MODE is supported.
3703
3704    This function is for combine so it can tell whether an insn that looks
3705    like a conditional move is actually supported by the hardware.  If we
3706    guess wrong we lose a bit on optimization, but that's it.  */
3707 /* ??? sparc64 supports conditionally moving integers values based on fp
3708    comparisons, and vice versa.  How do we handle them?  */
3709
3710 int
3711 can_conditionally_move_p (mode)
3712      enum machine_mode mode;
3713 {
3714   if (movcc_gen_code[mode] != CODE_FOR_nothing)
3715     return 1;
3716
3717   return 0;
3718 }
3719
3720 #endif /* HAVE_conditional_move */
3721 \f
3722 /* These three functions generate an insn body and return it
3723    rather than emitting the insn.
3724
3725    They do not protect from queued increments,
3726    because they may be used 1) in protect_from_queue itself
3727    and 2) in other passes where there is no queue.  */
3728
3729 /* Generate and return an insn body to add Y to X.  */
3730
3731 rtx
3732 gen_add2_insn (x, y)
3733      rtx x, y;
3734 {
3735   int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code; 
3736
3737   if (! ((*insn_data[icode].operand[0].predicate)
3738          (x, insn_data[icode].operand[0].mode))
3739       || ! ((*insn_data[icode].operand[1].predicate)
3740             (x, insn_data[icode].operand[1].mode))
3741       || ! ((*insn_data[icode].operand[2].predicate)
3742             (y, insn_data[icode].operand[2].mode)))
3743     abort ();
3744
3745   return (GEN_FCN (icode) (x, x, y));
3746 }
3747
3748 int
3749 have_add2_insn (mode)
3750      enum machine_mode mode;
3751 {
3752   return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3753 }
3754
3755 /* Generate and return an insn body to subtract Y from X.  */
3756
3757 rtx
3758 gen_sub2_insn (x, y)
3759      rtx x, y;
3760 {
3761   int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code; 
3762
3763   if (! ((*insn_data[icode].operand[0].predicate)
3764          (x, insn_data[icode].operand[0].mode))
3765       || ! ((*insn_data[icode].operand[1].predicate)
3766             (x, insn_data[icode].operand[1].mode))
3767       || ! ((*insn_data[icode].operand[2].predicate)
3768             (y, insn_data[icode].operand[2].mode)))
3769     abort ();
3770
3771   return (GEN_FCN (icode) (x, x, y));
3772 }
3773
3774 int
3775 have_sub2_insn (mode)
3776      enum machine_mode mode;
3777 {
3778   return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3779 }
3780
3781 /* Generate the body of an instruction to copy Y into X.
3782    It may be a SEQUENCE, if one insn isn't enough.  */
3783
3784 rtx
3785 gen_move_insn (x, y)
3786      rtx x, y;
3787 {
3788   register enum machine_mode mode = GET_MODE (x);
3789   enum insn_code insn_code;
3790   rtx seq;
3791
3792   if (mode == VOIDmode)
3793     mode = GET_MODE (y); 
3794
3795   insn_code = mov_optab->handlers[(int) mode].insn_code;
3796
3797   /* Handle MODE_CC modes:  If we don't have a special move insn for this mode,
3798      find a mode to do it in.  If we have a movcc, use it.  Otherwise,
3799      find the MODE_INT mode of the same width.  */
3800
3801   if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
3802     {
3803       enum machine_mode tmode = VOIDmode;
3804       rtx x1 = x, y1 = y;
3805
3806       if (mode != CCmode
3807           && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
3808         tmode = CCmode;
3809       else
3810         for (tmode = QImode; tmode != VOIDmode;
3811              tmode = GET_MODE_WIDER_MODE (tmode))
3812           if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
3813             break;
3814
3815       if (tmode == VOIDmode)
3816         abort ();
3817
3818       /* Get X and Y in TMODE.  We can't use gen_lowpart here because it
3819          may call change_address which is not appropriate if we were
3820          called when a reload was in progress.  We don't have to worry
3821          about changing the address since the size in bytes is supposed to
3822          be the same.  Copy the MEM to change the mode and move any
3823          substitutions from the old MEM to the new one.  */
3824
3825       if (reload_in_progress)
3826         {
3827           x = gen_lowpart_common (tmode, x1);
3828           if (x == 0 && GET_CODE (x1) == MEM)
3829             {
3830               x = gen_rtx_MEM (tmode, XEXP (x1, 0));
3831               MEM_COPY_ATTRIBUTES (x, x1);
3832               copy_replacements (x1, x);
3833             }
3834
3835           y = gen_lowpart_common (tmode, y1);
3836           if (y == 0 && GET_CODE (y1) == MEM)
3837             {
3838               y = gen_rtx_MEM (tmode, XEXP (y1, 0));
3839               MEM_COPY_ATTRIBUTES (y, y1);
3840               copy_replacements (y1, y);
3841             }
3842         }
3843       else
3844         {
3845           x = gen_lowpart (tmode, x);
3846           y = gen_lowpart (tmode, y);
3847         }
3848           
3849       insn_code = mov_optab->handlers[(int) tmode].insn_code;
3850       return (GEN_FCN (insn_code) (x, y));
3851     }
3852
3853   start_sequence ();
3854   emit_move_insn_1 (x, y);
3855   seq = gen_sequence ();
3856   end_sequence ();
3857   return seq;
3858 }
3859 \f
3860 /* Return the insn code used to extend FROM_MODE to TO_MODE.
3861    UNSIGNEDP specifies zero-extension instead of sign-extension.  If
3862    no such operation exists, CODE_FOR_nothing will be returned.  */
3863
3864 enum insn_code
3865 can_extend_p (to_mode, from_mode, unsignedp)
3866      enum machine_mode to_mode, from_mode;
3867      int unsignedp;
3868 {
3869   return extendtab[(int) to_mode][(int) from_mode][unsignedp != 0];
3870 }
3871
3872 /* Generate the body of an insn to extend Y (with mode MFROM)
3873    into X (with mode MTO).  Do zero-extension if UNSIGNEDP is nonzero.  */
3874
3875 rtx
3876 gen_extend_insn (x, y, mto, mfrom, unsignedp)
3877      rtx x, y;
3878      enum machine_mode mto, mfrom;
3879      int unsignedp;
3880 {
3881   return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp != 0]) (x, y));
3882 }
3883 \f
3884 /* can_fix_p and can_float_p say whether the target machine
3885    can directly convert a given fixed point type to
3886    a given floating point type, or vice versa.
3887    The returned value is the CODE_FOR_... value to use,
3888    or CODE_FOR_nothing if these modes cannot be directly converted.
3889
3890    *TRUNCP_PTR is set to 1 if it is necessary to output
3891    an explicit FTRUNC insn before the fix insn; otherwise 0.  */
3892
3893 static enum insn_code
3894 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
3895      enum machine_mode fltmode, fixmode;
3896      int unsignedp;
3897      int *truncp_ptr;
3898 {
3899   *truncp_ptr = 0;
3900   if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp != 0]
3901       != CODE_FOR_nothing)
3902     return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp != 0];
3903
3904   if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
3905     {
3906       *truncp_ptr = 1;
3907       return fixtab[(int) fltmode][(int) fixmode][unsignedp != 0];
3908     }
3909   return CODE_FOR_nothing;
3910 }
3911
3912 static enum insn_code
3913 can_float_p (fltmode, fixmode, unsignedp)
3914      enum machine_mode fixmode, fltmode;
3915      int unsignedp;
3916 {
3917   return floattab[(int) fltmode][(int) fixmode][unsignedp != 0];
3918 }
3919 \f
3920 /* Generate code to convert FROM to floating point
3921    and store in TO.  FROM must be fixed point and not VOIDmode.
3922    UNSIGNEDP nonzero means regard FROM as unsigned.
3923    Normally this is done by correcting the final value
3924    if it is negative.  */
3925
3926 void
3927 expand_float (to, from, unsignedp)
3928      rtx to, from;
3929      int unsignedp;
3930 {
3931   enum insn_code icode;
3932   register rtx target = to;
3933   enum machine_mode fmode, imode;
3934
3935   /* Crash now, because we won't be able to decide which mode to use.  */
3936   if (GET_MODE (from) == VOIDmode)
3937     abort ();
3938
3939   /* Look for an insn to do the conversion.  Do it in the specified
3940      modes if possible; otherwise convert either input, output or both to
3941      wider mode.  If the integer mode is wider than the mode of FROM,
3942      we can do the conversion signed even if the input is unsigned.  */
3943
3944   for (imode = GET_MODE (from); imode != VOIDmode;
3945        imode = GET_MODE_WIDER_MODE (imode))
3946     for (fmode = GET_MODE (to); fmode != VOIDmode;
3947          fmode = GET_MODE_WIDER_MODE (fmode))
3948       {
3949         int doing_unsigned = unsignedp;
3950
3951         if (fmode != GET_MODE (to)
3952             && significand_size (fmode) < GET_MODE_BITSIZE (GET_MODE (from)))
3953           continue;
3954
3955         icode = can_float_p (fmode, imode, unsignedp);
3956         if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
3957           icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
3958
3959         if (icode != CODE_FOR_nothing)
3960           {
3961             to = protect_from_queue (to, 1);
3962             from = protect_from_queue (from, 0);
3963
3964             if (imode != GET_MODE (from))
3965               from = convert_to_mode (imode, from, unsignedp);
3966
3967             if (fmode != GET_MODE (to))
3968               target = gen_reg_rtx (fmode);
3969
3970             emit_unop_insn (icode, target, from,
3971                             doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
3972
3973             if (target != to)
3974               convert_move (to, target, 0);
3975             return;
3976           }
3977     }
3978
3979 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3980
3981   /* Unsigned integer, and no way to convert directly.
3982      Convert as signed, then conditionally adjust the result.  */
3983   if (unsignedp)
3984     {
3985       rtx label = gen_label_rtx ();
3986       rtx temp;
3987       REAL_VALUE_TYPE offset;
3988
3989       emit_queue ();
3990
3991       to = protect_from_queue (to, 1);
3992       from = protect_from_queue (from, 0);
3993
3994       if (flag_force_mem)
3995         from = force_not_mem (from);
3996
3997       /* Look for a usable floating mode FMODE wider than the source and at
3998          least as wide as the target.  Using FMODE will avoid rounding woes
3999          with unsigned values greater than the signed maximum value.  */
4000
4001       for (fmode = GET_MODE (to);  fmode != VOIDmode;
4002            fmode = GET_MODE_WIDER_MODE (fmode))
4003         if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
4004             && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
4005           break;
4006
4007       if (fmode == VOIDmode)
4008         {
4009           /* There is no such mode.  Pretend the target is wide enough.  */
4010           fmode = GET_MODE (to);
4011
4012           /* Avoid double-rounding when TO is narrower than FROM.  */
4013           if ((significand_size (fmode) + 1)
4014               < GET_MODE_BITSIZE (GET_MODE (from)))
4015             {
4016               rtx temp1;
4017               rtx neglabel = gen_label_rtx ();
4018
4019               /* Don't use TARGET if it isn't a register, is a hard register, 
4020                  or is the wrong mode.  */
4021               if (GET_CODE (target) != REG
4022                   || REGNO (target) < FIRST_PSEUDO_REGISTER
4023                   || GET_MODE (target) != fmode)
4024                 target = gen_reg_rtx (fmode);
4025
4026               imode = GET_MODE (from);
4027               do_pending_stack_adjust ();
4028
4029               /* Test whether the sign bit is set.  */
4030               emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
4031                                        0, 0, neglabel);
4032
4033               /* The sign bit is not set.  Convert as signed.  */
4034               expand_float (target, from, 0);
4035               emit_jump_insn (gen_jump (label));
4036               emit_barrier ();
4037
4038               /* The sign bit is set.
4039                  Convert to a usable (positive signed) value by shifting right
4040                  one bit, while remembering if a nonzero bit was shifted
4041                  out; i.e., compute  (from & 1) | (from >> 1).  */
4042
4043               emit_label (neglabel);
4044               temp = expand_binop (imode, and_optab, from, const1_rtx,
4045                                    NULL_RTX, 1, OPTAB_LIB_WIDEN);
4046               temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
4047                                     NULL_RTX, 1);
4048               temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1, 
4049                                    OPTAB_LIB_WIDEN);
4050               expand_float (target, temp, 0);
4051
4052               /* Multiply by 2 to undo the shift above.  */
4053               temp = expand_binop (fmode, add_optab, target, target,
4054                                      target, 0, OPTAB_LIB_WIDEN);
4055               if (temp != target)
4056                 emit_move_insn (target, temp);
4057
4058               do_pending_stack_adjust ();
4059               emit_label (label);
4060               goto done;
4061             }
4062         }
4063
4064       /* If we are about to do some arithmetic to correct for an
4065          unsigned operand, do it in a pseudo-register.  */
4066
4067       if (GET_MODE (to) != fmode
4068           || GET_CODE (to) != REG || REGNO (to) < FIRST_PSEUDO_REGISTER)
4069         target = gen_reg_rtx (fmode);
4070
4071       /* Convert as signed integer to floating.  */
4072       expand_float (target, from, 0);
4073
4074       /* If FROM is negative (and therefore TO is negative),
4075          correct its value by 2**bitwidth.  */
4076
4077       do_pending_stack_adjust ();
4078       emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
4079                                 0, 0, label);
4080
4081       /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
4082          Rather than setting up a dconst_dot_5, let's hope SCO
4083          fixes the bug.  */
4084       offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
4085       temp = expand_binop (fmode, add_optab, target,
4086                            CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
4087                            target, 0, OPTAB_LIB_WIDEN);
4088       if (temp != target)
4089         emit_move_insn (target, temp);
4090
4091       do_pending_stack_adjust ();
4092       emit_label (label);
4093       goto done;
4094     }
4095 #endif
4096
4097   /* No hardware instruction available; call a library routine to convert from
4098      SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode.  */
4099     {
4100       rtx libfcn;
4101       rtx insns;
4102       rtx value;
4103
4104       to = protect_from_queue (to, 1);
4105       from = protect_from_queue (from, 0);
4106
4107       if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
4108         from = convert_to_mode (SImode, from, unsignedp);
4109
4110       if (flag_force_mem)
4111         from = force_not_mem (from);
4112
4113       if (GET_MODE (to) == SFmode)
4114         {
4115           if (GET_MODE (from) == SImode)
4116             libfcn = floatsisf_libfunc;
4117           else if (GET_MODE (from) == DImode)
4118             libfcn = floatdisf_libfunc;
4119           else if (GET_MODE (from) == TImode)
4120             libfcn = floattisf_libfunc;
4121           else
4122             abort ();
4123         }
4124       else if (GET_MODE (to) == DFmode)
4125         {
4126           if (GET_MODE (from) == SImode)
4127             libfcn = floatsidf_libfunc;
4128           else if (GET_MODE (from) == DImode)
4129             libfcn = floatdidf_libfunc;
4130           else if (GET_MODE (from) == TImode)
4131             libfcn = floattidf_libfunc;
4132           else
4133             abort ();
4134         }
4135       else if (GET_MODE (to) == XFmode)
4136         {
4137           if (GET_MODE (from) == SImode)
4138             libfcn = floatsixf_libfunc;
4139           else if (GET_MODE (from) == DImode)
4140             libfcn = floatdixf_libfunc;
4141           else if (GET_MODE (from) == TImode)
4142             libfcn = floattixf_libfunc;
4143           else
4144             abort ();
4145         }
4146       else if (GET_MODE (to) == TFmode)
4147         {
4148           if (GET_MODE (from) == SImode)
4149             libfcn = floatsitf_libfunc;
4150           else if (GET_MODE (from) == DImode)
4151             libfcn = floatditf_libfunc;
4152           else if (GET_MODE (from) == TImode)
4153             libfcn = floattitf_libfunc;
4154           else
4155             abort ();
4156         }
4157       else
4158         abort ();
4159
4160       start_sequence ();
4161
4162       value = emit_library_call_value (libfcn, NULL_RTX, LCT_CONST,
4163                                        GET_MODE (to), 1, from,
4164                                        GET_MODE (from));
4165       insns = get_insns ();
4166       end_sequence ();
4167
4168       emit_libcall_block (insns, target, value,
4169                           gen_rtx_FLOAT (GET_MODE (to), from));
4170     }
4171
4172  done:
4173
4174   /* Copy result to requested destination
4175      if we have been computing in a temp location.  */
4176
4177   if (target != to)
4178     {
4179       if (GET_MODE (target) == GET_MODE (to))
4180         emit_move_insn (to, target);
4181       else
4182         convert_move (to, target, 0);
4183     }
4184 }
4185 \f
4186 /* expand_fix: generate code to convert FROM to fixed point
4187    and store in TO.  FROM must be floating point.  */
4188
4189 static rtx
4190 ftruncify (x)
4191      rtx x;
4192 {
4193   rtx temp = gen_reg_rtx (GET_MODE (x));
4194   return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
4195 }
4196
4197 void
4198 expand_fix (to, from, unsignedp)
4199      register rtx to, from;
4200      int unsignedp;
4201 {
4202   enum insn_code icode;
4203   register rtx target = to;
4204   enum machine_mode fmode, imode;
4205   int must_trunc = 0;
4206   rtx libfcn = 0;
4207
4208   /* We first try to find a pair of modes, one real and one integer, at
4209      least as wide as FROM and TO, respectively, in which we can open-code
4210      this conversion.  If the integer mode is wider than the mode of TO,
4211      we can do the conversion either signed or unsigned.  */
4212
4213   for (imode = GET_MODE (to); imode != VOIDmode;
4214        imode = GET_MODE_WIDER_MODE (imode))
4215     for (fmode = GET_MODE (from); fmode != VOIDmode;
4216          fmode = GET_MODE_WIDER_MODE (fmode))
4217       {
4218         int doing_unsigned = unsignedp;
4219
4220         icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
4221         if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
4222           icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
4223
4224         if (icode != CODE_FOR_nothing)
4225           {
4226             to = protect_from_queue (to, 1);
4227             from = protect_from_queue (from, 0);
4228
4229             if (fmode != GET_MODE (from))
4230               from = convert_to_mode (fmode, from, 0);
4231
4232             if (must_trunc)
4233               from = ftruncify (from);
4234
4235             if (imode != GET_MODE (to))
4236               target = gen_reg_rtx (imode);
4237
4238             emit_unop_insn (icode, target, from,
4239                             doing_unsigned ? UNSIGNED_FIX : FIX);
4240             if (target != to)
4241               convert_move (to, target, unsignedp);
4242             return;
4243           }
4244       }
4245
4246 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
4247   /* For an unsigned conversion, there is one more way to do it.
4248      If we have a signed conversion, we generate code that compares
4249      the real value to the largest representable positive number.  If if
4250      is smaller, the conversion is done normally.  Otherwise, subtract
4251      one plus the highest signed number, convert, and add it back.
4252
4253      We only need to check all real modes, since we know we didn't find
4254      anything with a wider integer mode.  */
4255
4256   if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
4257     for (fmode = GET_MODE (from); fmode != VOIDmode;
4258          fmode = GET_MODE_WIDER_MODE (fmode))
4259       /* Make sure we won't lose significant bits doing this.  */
4260       if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
4261           && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
4262                                             &must_trunc))
4263         {
4264           int bitsize;
4265           REAL_VALUE_TYPE offset;
4266           rtx limit, lab1, lab2, insn;
4267
4268           bitsize = GET_MODE_BITSIZE (GET_MODE (to));
4269           offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
4270           limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
4271           lab1 = gen_label_rtx ();
4272           lab2 = gen_label_rtx ();
4273
4274           emit_queue ();
4275           to = protect_from_queue (to, 1);
4276           from = protect_from_queue (from, 0);
4277
4278           if (flag_force_mem)
4279             from = force_not_mem (from);
4280
4281           if (fmode != GET_MODE (from))
4282             from = convert_to_mode (fmode, from, 0);
4283
4284           /* See if we need to do the subtraction.  */
4285           do_pending_stack_adjust ();
4286           emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
4287                                    0, 0, lab1);
4288
4289           /* If not, do the signed "fix" and branch around fixup code.  */
4290           expand_fix (to, from, 0);
4291           emit_jump_insn (gen_jump (lab2));
4292           emit_barrier ();
4293
4294           /* Otherwise, subtract 2**(N-1), convert to signed number,
4295              then add 2**(N-1).  Do the addition using XOR since this
4296              will often generate better code.  */
4297           emit_label (lab1);
4298           target = expand_binop (GET_MODE (from), sub_optab, from, limit,
4299                                  NULL_RTX, 0, OPTAB_LIB_WIDEN);
4300           expand_fix (to, target, 0);
4301           target = expand_binop (GET_MODE (to), xor_optab, to,
4302                                  GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
4303                                  to, 1, OPTAB_LIB_WIDEN);
4304
4305           if (target != to)
4306             emit_move_insn (to, target);
4307
4308           emit_label (lab2);
4309
4310           if (mov_optab->handlers[(int) GET_MODE (to)].insn_code
4311               != CODE_FOR_nothing)
4312             {
4313               /* Make a place for a REG_NOTE and add it.  */
4314               insn = emit_move_insn (to, to);
4315               set_unique_reg_note (insn,
4316                                    REG_EQUAL,
4317                                    gen_rtx_fmt_e (UNSIGNED_FIX,
4318                                                   GET_MODE (to),
4319                                                   copy_rtx (from)));
4320             }
4321
4322           return;
4323         }
4324 #endif
4325
4326   /* We can't do it with an insn, so use a library call.  But first ensure
4327      that the mode of TO is at least as wide as SImode, since those are the
4328      only library calls we know about.  */
4329
4330   if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
4331     {
4332       target = gen_reg_rtx (SImode);
4333
4334       expand_fix (target, from, unsignedp);
4335     }
4336   else if (GET_MODE (from) == SFmode)
4337     {
4338       if (GET_MODE (to) == SImode)
4339         libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
4340       else if (GET_MODE (to) == DImode)
4341         libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
4342       else if (GET_MODE (to) == TImode)
4343         libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
4344       else
4345         abort ();
4346     }
4347   else if (GET_MODE (from) == DFmode)
4348     {
4349       if (GET_MODE (to) == SImode)
4350         libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
4351       else if (GET_MODE (to) == DImode)
4352         libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
4353       else if (GET_MODE (to) == TImode)
4354         libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
4355       else
4356         abort ();
4357     }
4358   else if (GET_MODE (from) == XFmode)
4359     {
4360       if (GET_MODE (to) == SImode)
4361         libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
4362       else if (GET_MODE (to) == DImode)
4363         libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
4364       else if (GET_MODE (to) == TImode)
4365         libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
4366       else
4367         abort ();
4368     }
4369   else if (GET_MODE (from) == TFmode)
4370     {
4371       if (GET_MODE (to) == SImode)
4372         libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
4373       else if (GET_MODE (to) == DImode)
4374         libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
4375       else if (GET_MODE (to) == TImode)
4376         libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
4377       else
4378         abort ();
4379     }
4380   else
4381     abort ();
4382
4383   if (libfcn)
4384     {
4385       rtx insns;
4386       rtx value;
4387
4388       to = protect_from_queue (to, 1);
4389       from = protect_from_queue (from, 0);
4390
4391       if (flag_force_mem)
4392         from = force_not_mem (from);
4393
4394       start_sequence ();
4395
4396       value = emit_library_call_value (libfcn, NULL_RTX, LCT_CONST,
4397                                        GET_MODE (to), 1, from,
4398                                        GET_MODE (from));
4399       insns = get_insns ();
4400       end_sequence ();
4401
4402       emit_libcall_block (insns, target, value,
4403                           gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
4404                                          GET_MODE (to), from));
4405     }
4406       
4407   if (target != to)
4408     {
4409       if (GET_MODE (to) == GET_MODE (target))
4410         emit_move_insn (to, target);
4411       else
4412         convert_move (to, target, 0);
4413     }
4414 }
4415 \f
4416 static optab
4417 init_optab (code)
4418      enum rtx_code code;
4419 {
4420   int i;
4421   optab op = (optab) xmalloc (sizeof (struct optab));
4422   op->code = code;
4423   for (i = 0; i < NUM_MACHINE_MODES; i++)
4424     {
4425       op->handlers[i].insn_code = CODE_FOR_nothing;
4426       op->handlers[i].libfunc = 0;
4427     }
4428
4429   if (code != UNKNOWN)
4430     code_to_optab[(int) code] = op;
4431
4432   return op;
4433 }
4434
4435 /* Initialize the libfunc fields of an entire group of entries in some
4436    optab.  Each entry is set equal to a string consisting of a leading
4437    pair of underscores followed by a generic operation name followed by
4438    a mode name (downshifted to lower case) followed by a single character
4439    representing the number of operands for the given operation (which is
4440    usually one of the characters '2', '3', or '4').
4441
4442    OPTABLE is the table in which libfunc fields are to be initialized.
4443    FIRST_MODE is the first machine mode index in the given optab to
4444      initialize.
4445    LAST_MODE is the last machine mode index in the given optab to
4446      initialize.
4447    OPNAME is the generic (string) name of the operation.
4448    SUFFIX is the character which specifies the number of operands for
4449      the given generic operation.
4450 */
4451
4452 static void
4453 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
4454     register optab optable;
4455     register int first_mode;
4456     register int last_mode;
4457     register const char *opname;
4458     register int suffix;
4459 {
4460   register int mode;
4461   register unsigned opname_len = strlen (opname);
4462
4463   for (mode = first_mode; (int) mode <= (int) last_mode;
4464        mode = (enum machine_mode) ((int) mode + 1))
4465     {
4466       register const char *mname = GET_MODE_NAME(mode);
4467       register unsigned mname_len = strlen (mname);
4468       register char *libfunc_name = alloca (2 + opname_len + mname_len + 1 + 1);
4469       register char *p;
4470       register const char *q;
4471
4472       p = libfunc_name;
4473       *p++ = '_';
4474       *p++ = '_';
4475       for (q = opname; *q; )
4476         *p++ = *q++;
4477       for (q = mname; *q; q++)
4478         *p++ = TOLOWER (*q);
4479       *p++ = suffix;
4480       *p = '\0';
4481
4482       optable->handlers[(int) mode].libfunc
4483         = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (libfunc_name,
4484                                                        p - libfunc_name));
4485     }
4486 }
4487
4488 /* Initialize the libfunc fields of an entire group of entries in some
4489    optab which correspond to all integer mode operations.  The parameters
4490    have the same meaning as similarly named ones for the `init_libfuncs'
4491    routine.  (See above).  */
4492
4493 static void
4494 init_integral_libfuncs (optable, opname, suffix)
4495     register optab optable;
4496     register const char *opname;
4497     register int suffix;
4498 {
4499   init_libfuncs (optable, SImode, TImode, opname, suffix);
4500 }
4501
4502 /* Initialize the libfunc fields of an entire group of entries in some
4503    optab which correspond to all real mode operations.  The parameters
4504    have the same meaning as similarly named ones for the `init_libfuncs'
4505    routine.  (See above).  */
4506
4507 static void
4508 init_floating_libfuncs (optable, opname, suffix)
4509     register optab optable;
4510     register const char *opname;
4511     register int suffix;
4512 {
4513   init_libfuncs (optable, SFmode, TFmode, opname, suffix);
4514 }
4515
4516 rtx
4517 init_one_libfunc (name)
4518      register const char *name;
4519 {
4520   name = ggc_strdup (name);
4521
4522   return gen_rtx_SYMBOL_REF (Pmode, name);
4523 }
4524
4525 /* Mark ARG (which is really an OPTAB *) for GC.  */
4526
4527 void
4528 mark_optab (arg)
4529      void *arg;
4530 {
4531   optab o = *(optab *) arg;
4532   int i;
4533
4534   for (i = 0; i < NUM_MACHINE_MODES; ++i)
4535     ggc_mark_rtx (o->handlers[i].libfunc);
4536 }
4537
4538 /* Call this once to initialize the contents of the optabs
4539    appropriately for the current target machine.  */
4540
4541 void
4542 init_optabs ()
4543 {
4544   unsigned int i, j, k;
4545
4546   /* Start by initializing all tables to contain CODE_FOR_nothing.  */
4547
4548   for (i = 0; i < ARRAY_SIZE (fixtab); i++)
4549     for (j = 0; j < ARRAY_SIZE (fixtab[0]); j++)
4550       for (k = 0; k < ARRAY_SIZE (fixtab[0][0]); k++)
4551         fixtab[i][j][k] = CODE_FOR_nothing;
4552
4553   for (i = 0; i < ARRAY_SIZE (fixtrunctab); i++)
4554     for (j = 0; j < ARRAY_SIZE (fixtrunctab[0]); j++)
4555       for (k = 0; k < ARRAY_SIZE (fixtrunctab[0][0]); k++)
4556         fixtrunctab[i][j][k] = CODE_FOR_nothing;
4557
4558   for (i = 0; i < ARRAY_SIZE (floattab); i++)
4559     for (j = 0; j < ARRAY_SIZE (floattab[0]); j++)
4560       for (k = 0; k < ARRAY_SIZE (floattab[0][0]); k++)
4561         floattab[i][j][k] = CODE_FOR_nothing;
4562
4563   for (i = 0; i < ARRAY_SIZE (extendtab); i++)
4564     for (j = 0; j < ARRAY_SIZE (extendtab[0]); j++)
4565       for (k = 0; k < ARRAY_SIZE (extendtab[0][0]); k++)
4566         extendtab[i][j][k] = CODE_FOR_nothing;
4567
4568   for (i = 0; i < NUM_RTX_CODE; i++)
4569     setcc_gen_code[i] = CODE_FOR_nothing;
4570
4571 #ifdef HAVE_conditional_move
4572   for (i = 0; i < NUM_MACHINE_MODES; i++)
4573     movcc_gen_code[i] = CODE_FOR_nothing;
4574 #endif
4575
4576   add_optab = init_optab (PLUS);
4577   addv_optab = init_optab (PLUS);
4578   sub_optab = init_optab (MINUS);
4579   subv_optab = init_optab (MINUS);
4580   smul_optab = init_optab (MULT);
4581   smulv_optab = init_optab (MULT);
4582   smul_highpart_optab = init_optab (UNKNOWN);
4583   umul_highpart_optab = init_optab (UNKNOWN);
4584   smul_widen_optab = init_optab (UNKNOWN);
4585   umul_widen_optab = init_optab (UNKNOWN);
4586   sdiv_optab = init_optab (DIV);
4587   sdivv_optab = init_optab (DIV);
4588   sdivmod_optab = init_optab (UNKNOWN);
4589   udiv_optab = init_optab (UDIV);
4590   udivmod_optab = init_optab (UNKNOWN);
4591   smod_optab = init_optab (MOD);
4592   umod_optab = init_optab (UMOD);
4593   flodiv_optab = init_optab (DIV);
4594   ftrunc_optab = init_optab (UNKNOWN);
4595   and_optab = init_optab (AND);
4596   ior_optab = init_optab (IOR);
4597   xor_optab = init_optab (XOR);
4598   ashl_optab = init_optab (ASHIFT);
4599   ashr_optab = init_optab (ASHIFTRT);
4600   lshr_optab = init_optab (LSHIFTRT);
4601   rotl_optab = init_optab (ROTATE);
4602   rotr_optab = init_optab (ROTATERT);
4603   smin_optab = init_optab (SMIN);
4604   smax_optab = init_optab (SMAX);
4605   umin_optab = init_optab (UMIN);
4606   umax_optab = init_optab (UMAX);
4607   mov_optab = init_optab (UNKNOWN);
4608   movstrict_optab = init_optab (UNKNOWN);
4609   cmp_optab = init_optab (UNKNOWN);
4610   ucmp_optab = init_optab (UNKNOWN);
4611   tst_optab = init_optab (UNKNOWN);
4612   neg_optab = init_optab (NEG);
4613   negv_optab = init_optab (NEG);
4614   abs_optab = init_optab (ABS);
4615   absv_optab = init_optab (ABS);
4616   one_cmpl_optab = init_optab (NOT);
4617   ffs_optab = init_optab (FFS);
4618   sqrt_optab = init_optab (SQRT);
4619   sin_optab = init_optab (UNKNOWN);
4620   cos_optab = init_optab (UNKNOWN);
4621   strlen_optab = init_optab (UNKNOWN);
4622   cbranch_optab = init_optab (UNKNOWN);
4623   cmov_optab = init_optab (UNKNOWN);
4624   cstore_optab = init_optab (UNKNOWN);
4625
4626   for (i = 0; i < NUM_MACHINE_MODES; i++)
4627     {
4628       movstr_optab[i] = CODE_FOR_nothing;
4629       clrstr_optab[i] = CODE_FOR_nothing;
4630
4631 #ifdef HAVE_SECONDARY_RELOADS
4632       reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
4633 #endif
4634     }
4635
4636   /* Fill in the optabs with the insns we support.  */
4637   init_all_optabs ();
4638
4639 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4640   /* This flag says the same insns that convert to a signed fixnum
4641      also convert validly to an unsigned one.  */
4642   for (i = 0; i < NUM_MACHINE_MODES; i++)
4643     for (j = 0; j < NUM_MACHINE_MODES; j++)
4644       fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
4645 #endif
4646
4647   /* Initialize the optabs with the names of the library functions.  */
4648   init_integral_libfuncs (add_optab, "add", '3');
4649   init_floating_libfuncs (add_optab, "add", '3');
4650   init_integral_libfuncs (addv_optab, "addv", '3');
4651   init_floating_libfuncs (addv_optab, "add", '3');
4652   init_integral_libfuncs (sub_optab, "sub", '3');
4653   init_floating_libfuncs (sub_optab, "sub", '3');
4654   init_integral_libfuncs (subv_optab, "subv", '3');
4655   init_floating_libfuncs (subv_optab, "sub", '3');
4656   init_integral_libfuncs (smul_optab, "mul", '3');
4657   init_floating_libfuncs (smul_optab, "mul", '3');
4658   init_integral_libfuncs (smulv_optab, "mulv", '3');
4659   init_floating_libfuncs (smulv_optab, "mul", '3');
4660   init_integral_libfuncs (sdiv_optab, "div", '3');
4661   init_integral_libfuncs (sdivv_optab, "divv", '3');
4662   init_integral_libfuncs (udiv_optab, "udiv", '3');
4663   init_integral_libfuncs (sdivmod_optab, "divmod", '4');
4664   init_integral_libfuncs (udivmod_optab, "udivmod", '4');
4665   init_integral_libfuncs (smod_optab, "mod", '3');
4666   init_integral_libfuncs (umod_optab, "umod", '3');
4667   init_floating_libfuncs (flodiv_optab, "div", '3');
4668   init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
4669   init_integral_libfuncs (and_optab, "and", '3');
4670   init_integral_libfuncs (ior_optab, "ior", '3');
4671   init_integral_libfuncs (xor_optab, "xor", '3');
4672   init_integral_libfuncs (ashl_optab, "ashl", '3');
4673   init_integral_libfuncs (ashr_optab, "ashr", '3');
4674   init_integral_libfuncs (lshr_optab, "lshr", '3');
4675   init_integral_libfuncs (smin_optab, "min", '3');
4676   init_floating_libfuncs (smin_optab, "min", '3');
4677   init_integral_libfuncs (smax_optab, "max", '3');
4678   init_floating_libfuncs (smax_optab, "max", '3');
4679   init_integral_libfuncs (umin_optab, "umin", '3');
4680   init_integral_libfuncs (umax_optab, "umax", '3');
4681   init_integral_libfuncs (neg_optab, "neg", '2');
4682   init_floating_libfuncs (neg_optab, "neg", '2');
4683   init_integral_libfuncs (negv_optab, "negv", '2');
4684   init_floating_libfuncs (negv_optab, "neg", '2');
4685   init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
4686   init_integral_libfuncs (ffs_optab, "ffs", '2');
4687
4688   /* Comparison libcalls for integers MUST come in pairs, signed/unsigned.  */
4689   init_integral_libfuncs (cmp_optab, "cmp", '2');
4690   init_integral_libfuncs (ucmp_optab, "ucmp", '2');
4691   init_floating_libfuncs (cmp_optab, "cmp", '2');
4692
4693 #ifdef MULSI3_LIBCALL
4694   smul_optab->handlers[(int) SImode].libfunc
4695     = init_one_libfunc (MULSI3_LIBCALL);
4696 #endif
4697 #ifdef MULDI3_LIBCALL
4698   smul_optab->handlers[(int) DImode].libfunc
4699     = init_one_libfunc (MULDI3_LIBCALL);
4700 #endif
4701
4702 #ifdef DIVSI3_LIBCALL
4703   sdiv_optab->handlers[(int) SImode].libfunc
4704     = init_one_libfunc (DIVSI3_LIBCALL);
4705 #endif
4706 #ifdef DIVDI3_LIBCALL
4707   sdiv_optab->handlers[(int) DImode].libfunc
4708     = init_one_libfunc (DIVDI3_LIBCALL);
4709 #endif
4710
4711 #ifdef UDIVSI3_LIBCALL
4712   udiv_optab->handlers[(int) SImode].libfunc
4713     = init_one_libfunc (UDIVSI3_LIBCALL);
4714 #endif
4715 #ifdef UDIVDI3_LIBCALL
4716   udiv_optab->handlers[(int) DImode].libfunc
4717     = init_one_libfunc (UDIVDI3_LIBCALL);
4718 #endif
4719
4720 #ifdef MODSI3_LIBCALL
4721   smod_optab->handlers[(int) SImode].libfunc
4722     = init_one_libfunc (MODSI3_LIBCALL);
4723 #endif
4724 #ifdef MODDI3_LIBCALL
4725   smod_optab->handlers[(int) DImode].libfunc
4726     = init_one_libfunc (MODDI3_LIBCALL);
4727 #endif
4728
4729 #ifdef UMODSI3_LIBCALL
4730   umod_optab->handlers[(int) SImode].libfunc
4731     = init_one_libfunc (UMODSI3_LIBCALL);
4732 #endif
4733 #ifdef UMODDI3_LIBCALL
4734   umod_optab->handlers[(int) DImode].libfunc
4735     = init_one_libfunc (UMODDI3_LIBCALL);
4736 #endif
4737
4738   /* Use cabs for DC complex abs, since systems generally have cabs.
4739      Don't define any libcall for SCmode, so that cabs will be used.  */
4740   abs_optab->handlers[(int) DCmode].libfunc
4741     = init_one_libfunc ("cabs");
4742
4743   /* The ffs function operates on `int'.  */
4744   ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)].libfunc
4745     = init_one_libfunc ("ffs");
4746
4747   extendsfdf2_libfunc = init_one_libfunc ("__extendsfdf2");
4748   extendsfxf2_libfunc = init_one_libfunc ("__extendsfxf2");
4749   extendsftf2_libfunc = init_one_libfunc ("__extendsftf2");
4750   extenddfxf2_libfunc = init_one_libfunc ("__extenddfxf2");
4751   extenddftf2_libfunc = init_one_libfunc ("__extenddftf2");
4752
4753   truncdfsf2_libfunc = init_one_libfunc ("__truncdfsf2");
4754   truncxfsf2_libfunc = init_one_libfunc ("__truncxfsf2");
4755   trunctfsf2_libfunc = init_one_libfunc ("__trunctfsf2");
4756   truncxfdf2_libfunc = init_one_libfunc ("__truncxfdf2");
4757   trunctfdf2_libfunc = init_one_libfunc ("__trunctfdf2");
4758
4759   memcpy_libfunc = init_one_libfunc ("memcpy");
4760   bcopy_libfunc = init_one_libfunc ("bcopy");
4761   memcmp_libfunc = init_one_libfunc ("memcmp");
4762   bcmp_libfunc = init_one_libfunc ("__gcc_bcmp");
4763   memset_libfunc = init_one_libfunc ("memset");
4764   bzero_libfunc = init_one_libfunc ("bzero");
4765
4766   throw_libfunc = init_one_libfunc ("__throw");
4767   rethrow_libfunc = init_one_libfunc ("__rethrow");
4768   sjthrow_libfunc = init_one_libfunc ("__sjthrow");
4769   sjpopnthrow_libfunc = init_one_libfunc ("__sjpopnthrow");
4770   terminate_libfunc = init_one_libfunc ("__terminate");
4771   eh_rtime_match_libfunc = init_one_libfunc ("__eh_rtime_match");
4772 #ifndef DONT_USE_BUILTIN_SETJMP
4773   setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
4774   longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
4775 #else
4776   setjmp_libfunc = init_one_libfunc ("setjmp");
4777   longjmp_libfunc = init_one_libfunc ("longjmp");
4778 #endif
4779
4780   eqhf2_libfunc = init_one_libfunc ("__eqhf2");
4781   nehf2_libfunc = init_one_libfunc ("__nehf2");
4782   gthf2_libfunc = init_one_libfunc ("__gthf2");
4783   gehf2_libfunc = init_one_libfunc ("__gehf2");
4784   lthf2_libfunc = init_one_libfunc ("__lthf2");
4785   lehf2_libfunc = init_one_libfunc ("__lehf2");
4786   unordhf2_libfunc = init_one_libfunc ("__unordhf2");
4787
4788   eqsf2_libfunc = init_one_libfunc ("__eqsf2");
4789   nesf2_libfunc = init_one_libfunc ("__nesf2");
4790   gtsf2_libfunc = init_one_libfunc ("__gtsf2");
4791   gesf2_libfunc = init_one_libfunc ("__gesf2");
4792   ltsf2_libfunc = init_one_libfunc ("__ltsf2");
4793   lesf2_libfunc = init_one_libfunc ("__lesf2");
4794   unordsf2_libfunc = init_one_libfunc ("__unordsf2");
4795
4796   eqdf2_libfunc = init_one_libfunc ("__eqdf2");
4797   nedf2_libfunc = init_one_libfunc ("__nedf2");
4798   gtdf2_libfunc = init_one_libfunc ("__gtdf2");
4799   gedf2_libfunc = init_one_libfunc ("__gedf2");
4800   ltdf2_libfunc = init_one_libfunc ("__ltdf2");
4801   ledf2_libfunc = init_one_libfunc ("__ledf2");
4802   unorddf2_libfunc = init_one_libfunc ("__unorddf2");
4803
4804   eqxf2_libfunc = init_one_libfunc ("__eqxf2");
4805   nexf2_libfunc = init_one_libfunc ("__nexf2");
4806   gtxf2_libfunc = init_one_libfunc ("__gtxf2");
4807   gexf2_libfunc = init_one_libfunc ("__gexf2");
4808   ltxf2_libfunc = init_one_libfunc ("__ltxf2");
4809   lexf2_libfunc = init_one_libfunc ("__lexf2");
4810   unordxf2_libfunc = init_one_libfunc ("__unordxf2");
4811
4812   eqtf2_libfunc = init_one_libfunc ("__eqtf2");
4813   netf2_libfunc = init_one_libfunc ("__netf2");
4814   gttf2_libfunc = init_one_libfunc ("__gttf2");
4815   getf2_libfunc = init_one_libfunc ("__getf2");
4816   lttf2_libfunc = init_one_libfunc ("__lttf2");
4817   letf2_libfunc = init_one_libfunc ("__letf2");
4818   unordtf2_libfunc = init_one_libfunc ("__unordtf2");
4819
4820   floatsisf_libfunc = init_one_libfunc ("__floatsisf");
4821   floatdisf_libfunc = init_one_libfunc ("__floatdisf");
4822   floattisf_libfunc = init_one_libfunc ("__floattisf");
4823
4824   floatsidf_libfunc = init_one_libfunc ("__floatsidf");
4825   floatdidf_libfunc = init_one_libfunc ("__floatdidf");
4826   floattidf_libfunc = init_one_libfunc ("__floattidf");
4827
4828   floatsixf_libfunc = init_one_libfunc ("__floatsixf");
4829   floatdixf_libfunc = init_one_libfunc ("__floatdixf");
4830   floattixf_libfunc = init_one_libfunc ("__floattixf");
4831
4832   floatsitf_libfunc = init_one_libfunc ("__floatsitf");
4833   floatditf_libfunc = init_one_libfunc ("__floatditf");
4834   floattitf_libfunc = init_one_libfunc ("__floattitf");
4835
4836   fixsfsi_libfunc = init_one_libfunc ("__fixsfsi");
4837   fixsfdi_libfunc = init_one_libfunc ("__fixsfdi");
4838   fixsfti_libfunc = init_one_libfunc ("__fixsfti");
4839
4840   fixdfsi_libfunc = init_one_libfunc ("__fixdfsi");
4841   fixdfdi_libfunc = init_one_libfunc ("__fixdfdi");
4842   fixdfti_libfunc = init_one_libfunc ("__fixdfti");
4843
4844   fixxfsi_libfunc = init_one_libfunc ("__fixxfsi");
4845   fixxfdi_libfunc = init_one_libfunc ("__fixxfdi");
4846   fixxfti_libfunc = init_one_libfunc ("__fixxfti");
4847
4848   fixtfsi_libfunc = init_one_libfunc ("__fixtfsi");
4849   fixtfdi_libfunc = init_one_libfunc ("__fixtfdi");
4850   fixtfti_libfunc = init_one_libfunc ("__fixtfti");
4851
4852   fixunssfsi_libfunc = init_one_libfunc ("__fixunssfsi");
4853   fixunssfdi_libfunc = init_one_libfunc ("__fixunssfdi");
4854   fixunssfti_libfunc = init_one_libfunc ("__fixunssfti");
4855
4856   fixunsdfsi_libfunc = init_one_libfunc ("__fixunsdfsi");
4857   fixunsdfdi_libfunc = init_one_libfunc ("__fixunsdfdi");
4858   fixunsdfti_libfunc = init_one_libfunc ("__fixunsdfti");
4859
4860   fixunsxfsi_libfunc = init_one_libfunc ("__fixunsxfsi");
4861   fixunsxfdi_libfunc = init_one_libfunc ("__fixunsxfdi");
4862   fixunsxfti_libfunc = init_one_libfunc ("__fixunsxfti");
4863
4864   fixunstfsi_libfunc = init_one_libfunc ("__fixunstfsi");
4865   fixunstfdi_libfunc = init_one_libfunc ("__fixunstfdi");
4866   fixunstfti_libfunc = init_one_libfunc ("__fixunstfti");
4867
4868   /* For check-memory-usage.  */
4869   chkr_check_addr_libfunc = init_one_libfunc ("chkr_check_addr");
4870   chkr_set_right_libfunc = init_one_libfunc ("chkr_set_right");
4871   chkr_copy_bitmap_libfunc = init_one_libfunc ("chkr_copy_bitmap");
4872   chkr_check_exec_libfunc = init_one_libfunc ("chkr_check_exec");
4873   chkr_check_str_libfunc = init_one_libfunc ("chkr_check_str");
4874
4875   /* For function entry/exit instrumentation.  */
4876   profile_function_entry_libfunc
4877     = init_one_libfunc ("__cyg_profile_func_enter");
4878   profile_function_exit_libfunc
4879     = init_one_libfunc ("__cyg_profile_func_exit");
4880
4881 #ifdef HAVE_conditional_trap
4882   init_traps ();
4883 #endif
4884
4885 #ifdef INIT_TARGET_OPTABS
4886   /* Allow the target to add more libcalls or rename some, etc.  */
4887   INIT_TARGET_OPTABS;
4888 #endif
4889
4890   /* Add these GC roots.  */
4891   ggc_add_root (optab_table, OTI_MAX, sizeof(optab), mark_optab);
4892   ggc_add_rtx_root (libfunc_table, LTI_MAX);
4893 }
4894 \f
4895 #ifdef BROKEN_LDEXP
4896
4897 /* SCO 3.2 apparently has a broken ldexp.  */
4898
4899 double
4900 ldexp(x,n)
4901      double x;
4902      int n;
4903 {
4904   if (n > 0)
4905     while (n--)
4906       x *= 2;
4907
4908   return x;
4909 }
4910 #endif /* BROKEN_LDEXP */
4911 \f
4912 #ifdef HAVE_conditional_trap
4913 /* The insn generating function can not take an rtx_code argument.
4914    TRAP_RTX is used as an rtx argument.  Its code is replaced with
4915    the code to be used in the trap insn and all other fields are
4916    ignored.  */
4917 static rtx trap_rtx;
4918
4919 static void
4920 init_traps ()
4921 {
4922   if (HAVE_conditional_trap)
4923     {
4924       trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
4925       ggc_add_rtx_root (&trap_rtx, 1);
4926     }
4927 }
4928 #endif
4929
4930 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
4931    CODE.  Return 0 on failure.  */
4932
4933 rtx
4934 gen_cond_trap (code, op1, op2, tcode)
4935   enum rtx_code code ATTRIBUTE_UNUSED;
4936   rtx op1, op2 ATTRIBUTE_UNUSED, tcode ATTRIBUTE_UNUSED;
4937 {
4938   enum machine_mode mode = GET_MODE (op1);
4939
4940   if (mode == VOIDmode)
4941     return 0;
4942
4943 #ifdef HAVE_conditional_trap
4944   if (HAVE_conditional_trap
4945       && cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
4946     {
4947       rtx insn;
4948       start_sequence();
4949       emit_insn (GEN_FCN (cmp_optab->handlers[(int) mode].insn_code) (op1, op2));
4950       PUT_CODE (trap_rtx, code);
4951       insn = gen_conditional_trap (trap_rtx, tcode);
4952       if (insn)
4953         {
4954           emit_insn (insn);
4955           insn = gen_sequence ();
4956         }
4957       end_sequence();
4958       return insn;
4959     }
4960 #endif
4961
4962   return 0;
4963 }