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