OSDN Git Service

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