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