OSDN Git Service

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