optabs.c revision 70635
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 final_dest = target;
2891  rtx prev, next, first, last, insn;
2892
2893  /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
2894     into a MEM later.  Protect the libcall block from this change.  */
2895  if (! REG_P (target) || REG_USERVAR_P (target))
2896    target = gen_reg_rtx (GET_MODE (target));
2897
2898  /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
2899     reg note to indicate that this call cannot throw. (Unless there is
2900     already a REG_EH_REGION note.) */
2901
2902  for (insn = insns; insn; insn = NEXT_INSN (insn))
2903    {
2904      if (GET_CODE (insn) == CALL_INSN)
2905        {
2906          rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2907          if (note == NULL_RTX)
2908            REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, GEN_INT (-1),
2909                                                  REG_NOTES (insn));
2910        }
2911    }
2912
2913  /* First emit all insns that set pseudos.  Remove them from the list as
2914     we go.  Avoid insns that set pseudos which were referenced in previous
2915     insns.  These can be generated by move_by_pieces, for example,
2916     to update an address.  Similarly, avoid insns that reference things
2917     set in previous insns.  */
2918
2919  for (insn = insns; insn; insn = next)
2920    {
2921      rtx set = single_set (insn);
2922
2923      next = NEXT_INSN (insn);
2924
2925      if (set != 0 && GET_CODE (SET_DEST (set)) == REG
2926	  && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
2927	  && (insn == insns
2928	      || (! reg_mentioned_p (SET_DEST (set), PATTERN (insns))
2929		  && ! reg_used_between_p (SET_DEST (set), insns, insn)
2930		  && ! modified_in_p (SET_SRC (set), insns)
2931		  && ! modified_between_p (SET_SRC (set), insns, insn))))
2932	{
2933	  if (PREV_INSN (insn))
2934	    NEXT_INSN (PREV_INSN (insn)) = next;
2935	  else
2936	    insns = next;
2937
2938	  if (next)
2939	    PREV_INSN (next) = PREV_INSN (insn);
2940
2941	  add_insn (insn);
2942	}
2943    }
2944
2945  prev = get_last_insn ();
2946
2947  /* Write the remaining insns followed by the final copy.  */
2948
2949  for (insn = insns; insn; insn = next)
2950    {
2951      next = NEXT_INSN (insn);
2952
2953      add_insn (insn);
2954    }
2955
2956  last = emit_move_insn (target, result);
2957  if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2958      != CODE_FOR_nothing)
2959    set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
2960
2961  if (final_dest != target)
2962    emit_move_insn (final_dest, target);
2963
2964  if (prev == 0)
2965    first = get_insns ();
2966  else
2967    first = NEXT_INSN (prev);
2968
2969  /* Encapsulate the block so it gets manipulated as a unit.  */
2970  REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
2971					 REG_NOTES (first));
2972  REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2973}
2974
2975/* Generate code to store zero in X.  */
2976
2977void
2978emit_clr_insn (x)
2979     rtx x;
2980{
2981  emit_move_insn (x, const0_rtx);
2982}
2983
2984/* Generate code to store 1 in X
2985   assuming it contains zero beforehand.  */
2986
2987void
2988emit_0_to_1_insn (x)
2989     rtx x;
2990{
2991  emit_move_insn (x, const1_rtx);
2992}
2993
2994/* Generate code to compare X with Y
2995   so that the condition codes are set.
2996
2997   MODE is the mode of the inputs (in case they are const_int).
2998   UNSIGNEDP nonzero says that X and Y are unsigned;
2999   this matters if they need to be widened.
3000
3001   If they have mode BLKmode, then SIZE specifies the size of both X and Y,
3002   and ALIGN specifies the known shared alignment of X and Y.
3003
3004   COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
3005   It is ignored for fixed-point and block comparisons;
3006   it is used only for floating-point comparisons.  */
3007
3008void
3009emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
3010     rtx x, y;
3011     enum rtx_code comparison;
3012     rtx size;
3013     enum machine_mode mode;
3014     int unsignedp;
3015     int align;
3016{
3017  enum mode_class class;
3018  enum machine_mode wider_mode;
3019
3020  class = GET_MODE_CLASS (mode);
3021
3022  /* They could both be VOIDmode if both args are immediate constants,
3023     but we should fold that at an earlier stage.
3024     With no special code here, this will call abort,
3025     reminding the programmer to implement such folding.  */
3026
3027  if (mode != BLKmode && flag_force_mem)
3028    {
3029      x = force_not_mem (x);
3030      y = force_not_mem (y);
3031    }
3032
3033  /* If we are inside an appropriately-short loop and one operand is an
3034     expensive constant, force it into a register.  */
3035  if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x, COMPARE) > 2)
3036    x = force_reg (mode, x);
3037
3038  if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
3039    y = force_reg (mode, y);
3040
3041#ifdef HAVE_cc0
3042  /* Abort if we have a non-canonical comparison.  The RTL documentation
3043     states that canonical comparisons are required only for targets which
3044     have cc0.  */
3045  if (CONSTANT_P (x) && ! CONSTANT_P (y))
3046    abort();
3047#endif
3048
3049  /* Don't let both operands fail to indicate the mode.  */
3050  if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
3051    x = force_reg (mode, x);
3052
3053  /* Handle all BLKmode compares.  */
3054
3055  if (mode == BLKmode)
3056    {
3057      emit_queue ();
3058      x = protect_from_queue (x, 0);
3059      y = protect_from_queue (y, 0);
3060
3061      if (size == 0)
3062	abort ();
3063#ifdef HAVE_cmpstrqi
3064      if (HAVE_cmpstrqi
3065	  && GET_CODE (size) == CONST_INT
3066	  && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
3067	{
3068	  enum machine_mode result_mode
3069	    = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
3070	  rtx result = gen_reg_rtx (result_mode);
3071	  emit_insn (gen_cmpstrqi (result, x, y, size, GEN_INT (align)));
3072	  emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
3073			 result_mode, 0, 0);
3074	}
3075      else
3076#endif
3077#ifdef HAVE_cmpstrhi
3078      if (HAVE_cmpstrhi
3079	  && GET_CODE (size) == CONST_INT
3080	  && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
3081	{
3082	  enum machine_mode result_mode
3083	    = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
3084	  rtx result = gen_reg_rtx (result_mode);
3085	  emit_insn (gen_cmpstrhi (result, x, y, size, GEN_INT (align)));
3086	  emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
3087			 result_mode, 0, 0);
3088	}
3089      else
3090#endif
3091#ifdef HAVE_cmpstrsi
3092      if (HAVE_cmpstrsi)
3093	{
3094	  enum machine_mode result_mode
3095	    = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
3096	  rtx result = gen_reg_rtx (result_mode);
3097	  size = protect_from_queue (size, 0);
3098	  emit_insn (gen_cmpstrsi (result, x, y,
3099				   convert_to_mode (SImode, size, 1),
3100				   GEN_INT (align)));
3101	  emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
3102			 result_mode, 0, 0);
3103	}
3104      else
3105#endif
3106	{
3107	  rtx result;
3108
3109#ifdef TARGET_MEM_FUNCTIONS
3110	  emit_library_call (memcmp_libfunc, 0,
3111			     TYPE_MODE (integer_type_node), 3,
3112			     XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
3113			     convert_to_mode (TYPE_MODE (sizetype), size,
3114					      TREE_UNSIGNED (sizetype)),
3115			     TYPE_MODE (sizetype));
3116#else
3117	  emit_library_call (bcmp_libfunc, 0,
3118			     TYPE_MODE (integer_type_node), 3,
3119			     XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
3120			     convert_to_mode (TYPE_MODE (integer_type_node),
3121					      size,
3122					      TREE_UNSIGNED (integer_type_node)),
3123			     TYPE_MODE (integer_type_node));
3124#endif
3125
3126	  /* Immediately move the result of the libcall into a pseudo
3127	     register so reload doesn't clobber the value if it needs
3128	     the return register for a spill reg.  */
3129	  result = gen_reg_rtx (TYPE_MODE (integer_type_node));
3130	  emit_move_insn (result,
3131			  hard_libcall_value (TYPE_MODE (integer_type_node)));
3132	  emit_cmp_insn (result,
3133			 const0_rtx, comparison, NULL_RTX,
3134			 TYPE_MODE (integer_type_node), 0, 0);
3135	}
3136      return;
3137    }
3138
3139  /* Handle some compares against zero.  */
3140
3141  if (y == CONST0_RTX (mode)
3142      && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3143    {
3144      int icode = (int) tst_optab->handlers[(int) mode].insn_code;
3145
3146      emit_queue ();
3147      x = protect_from_queue (x, 0);
3148      y = protect_from_queue (y, 0);
3149
3150      /* Now, if insn does accept these operands, put them into pseudos.  */
3151      if (! (*insn_operand_predicate[icode][0])
3152	  (x, insn_operand_mode[icode][0]))
3153	x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
3154
3155      emit_insn (GEN_FCN (icode) (x));
3156      return;
3157    }
3158
3159  /* Handle compares for which there is a directly suitable insn.  */
3160
3161  if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3162    {
3163      int icode = (int) cmp_optab->handlers[(int) mode].insn_code;
3164
3165      emit_queue ();
3166      x = protect_from_queue (x, 0);
3167      y = protect_from_queue (y, 0);
3168
3169      /* Now, if insn doesn't accept these operands, put them into pseudos.  */
3170      if (! (*insn_operand_predicate[icode][0])
3171	  (x, insn_operand_mode[icode][0]))
3172	x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
3173
3174      if (! (*insn_operand_predicate[icode][1])
3175	  (y, insn_operand_mode[icode][1]))
3176	y = copy_to_mode_reg (insn_operand_mode[icode][1], y);
3177
3178      emit_insn (GEN_FCN (icode) (x, y));
3179      return;
3180    }
3181
3182  /* Try widening if we can find a direct insn that way.  */
3183
3184  if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
3185    {
3186      for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3187	   wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3188	{
3189	  if (cmp_optab->handlers[(int) wider_mode].insn_code
3190	      != CODE_FOR_nothing)
3191	    {
3192	      x = protect_from_queue (x, 0);
3193	      y = protect_from_queue (y, 0);
3194	      x = convert_modes (wider_mode, mode, x, unsignedp);
3195	      y = convert_modes (wider_mode, mode, y, unsignedp);
3196	      emit_cmp_insn (x, y, comparison, NULL_RTX,
3197			     wider_mode, unsignedp, align);
3198	      return;
3199	    }
3200	}
3201    }
3202
3203  /* Handle a lib call just for the mode we are using.  */
3204
3205  if (cmp_optab->handlers[(int) mode].libfunc
3206      && class != MODE_FLOAT)
3207    {
3208      rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
3209      rtx result;
3210
3211      /* If we want unsigned, and this mode has a distinct unsigned
3212	 comparison routine, use that.  */
3213      if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
3214	libfunc = ucmp_optab->handlers[(int) mode].libfunc;
3215
3216      emit_library_call (libfunc, 1,
3217			 word_mode, 2, x, mode, y, mode);
3218
3219      /* Immediately move the result of the libcall into a pseudo
3220	 register so reload doesn't clobber the value if it needs
3221	 the return register for a spill reg.  */
3222      result = gen_reg_rtx (word_mode);
3223      emit_move_insn (result, hard_libcall_value (word_mode));
3224
3225      /* Integer comparison returns a result that must be compared against 1,
3226	 so that even if we do an unsigned compare afterward,
3227	 there is still a value that can represent the result "less than".  */
3228      emit_cmp_insn (result, const1_rtx,
3229		     comparison, NULL_RTX, word_mode, unsignedp, 0);
3230      return;
3231    }
3232
3233  if (class == MODE_FLOAT)
3234    emit_float_lib_cmp (x, y, comparison);
3235
3236  else
3237    abort ();
3238}
3239
3240/* Generate code to compare X with Y so that the condition codes are
3241   set and to jump to LABEL if the condition is true.  If X is a
3242   constant and Y is not a constant, then the comparison is swapped to
3243   ensure that the comparison RTL has the canonical form.
3244
3245   UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
3246   need to be widened by emit_cmp_insn.  UNSIGNEDP is also used to select
3247   the proper branch condition code.
3248
3249   If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y,
3250   and ALIGN specifies the known shared alignment of X and Y.
3251
3252   MODE is the mode of the inputs (in case they are const_int).
3253
3254   COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  It will
3255   be passed unchanged to emit_cmp_insn, then potentially converted into an
3256   unsigned variant based on UNSIGNEDP to select a proper jump instruction.  */
3257
3258void
3259emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, align, label)
3260     rtx x, y;
3261     enum rtx_code comparison;
3262     rtx size;
3263     enum machine_mode mode;
3264     int unsignedp;
3265     int align;
3266     rtx label;
3267{
3268  rtx op0;
3269  rtx op1;
3270
3271  if (CONSTANT_P (x))
3272    {
3273      /* Swap operands and condition to ensure canonical RTL.  */
3274      op0 = y;
3275      op1 = x;
3276      comparison = swap_condition (comparison);
3277    }
3278  else
3279    {
3280      op0 = x;
3281      op1 = y;
3282    }
3283
3284#ifdef HAVE_cc0
3285  /* If OP0 is still a constant, then both X and Y must be constants.  Force
3286     X into a register to avoid aborting in emit_cmp_insn due to non-canonical
3287     RTL.  */
3288  if (CONSTANT_P (op0))
3289    op0 = force_reg (mode, op0);
3290#endif
3291
3292  emit_cmp_insn (op0, op1, comparison, size, mode, unsignedp, align);
3293
3294  if (unsignedp)
3295    comparison = unsigned_condition (comparison);
3296  emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
3297}
3298
3299
3300/* Nonzero if a compare of mode MODE can be done straightforwardly
3301   (without splitting it into pieces).  */
3302
3303int
3304can_compare_p (mode)
3305     enum machine_mode mode;
3306{
3307  do
3308    {
3309      if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
3310	return 1;
3311      mode = GET_MODE_WIDER_MODE (mode);
3312    } while (mode != VOIDmode);
3313
3314  return 0;
3315}
3316
3317/* Emit a library call comparison between floating point X and Y.
3318   COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  */
3319
3320void
3321emit_float_lib_cmp (x, y, comparison)
3322     rtx x, y;
3323     enum rtx_code comparison;
3324{
3325  enum machine_mode mode = GET_MODE (x);
3326  rtx libfunc = 0;
3327  rtx result;
3328
3329  if (mode == HFmode)
3330    switch (comparison)
3331      {
3332      case EQ:
3333	libfunc = eqhf2_libfunc;
3334	break;
3335
3336      case NE:
3337	libfunc = nehf2_libfunc;
3338	break;
3339
3340      case GT:
3341	libfunc = gthf2_libfunc;
3342	break;
3343
3344      case GE:
3345	libfunc = gehf2_libfunc;
3346	break;
3347
3348      case LT:
3349	libfunc = lthf2_libfunc;
3350	break;
3351
3352      case LE:
3353	libfunc = lehf2_libfunc;
3354	break;
3355
3356      default:
3357	break;
3358      }
3359  else if (mode == SFmode)
3360    switch (comparison)
3361      {
3362      case EQ:
3363	libfunc = eqsf2_libfunc;
3364	break;
3365
3366      case NE:
3367	libfunc = nesf2_libfunc;
3368	break;
3369
3370      case GT:
3371	libfunc = gtsf2_libfunc;
3372	break;
3373
3374      case GE:
3375	libfunc = gesf2_libfunc;
3376	break;
3377
3378      case LT:
3379	libfunc = ltsf2_libfunc;
3380	break;
3381
3382      case LE:
3383	libfunc = lesf2_libfunc;
3384	break;
3385
3386      default:
3387	break;
3388      }
3389  else if (mode == DFmode)
3390    switch (comparison)
3391      {
3392      case EQ:
3393	libfunc = eqdf2_libfunc;
3394	break;
3395
3396      case NE:
3397	libfunc = nedf2_libfunc;
3398	break;
3399
3400      case GT:
3401	libfunc = gtdf2_libfunc;
3402	break;
3403
3404      case GE:
3405	libfunc = gedf2_libfunc;
3406	break;
3407
3408      case LT:
3409	libfunc = ltdf2_libfunc;
3410	break;
3411
3412      case LE:
3413	libfunc = ledf2_libfunc;
3414	break;
3415
3416      default:
3417	break;
3418      }
3419  else if (mode == XFmode)
3420    switch (comparison)
3421      {
3422      case EQ:
3423	libfunc = eqxf2_libfunc;
3424	break;
3425
3426      case NE:
3427	libfunc = nexf2_libfunc;
3428	break;
3429
3430      case GT:
3431	libfunc = gtxf2_libfunc;
3432	break;
3433
3434      case GE:
3435	libfunc = gexf2_libfunc;
3436	break;
3437
3438      case LT:
3439	libfunc = ltxf2_libfunc;
3440	break;
3441
3442      case LE:
3443	libfunc = lexf2_libfunc;
3444	break;
3445
3446      default:
3447	break;
3448      }
3449  else if (mode == TFmode)
3450    switch (comparison)
3451      {
3452      case EQ:
3453	libfunc = eqtf2_libfunc;
3454	break;
3455
3456      case NE:
3457	libfunc = netf2_libfunc;
3458	break;
3459
3460      case GT:
3461	libfunc = gttf2_libfunc;
3462	break;
3463
3464      case GE:
3465	libfunc = getf2_libfunc;
3466	break;
3467
3468      case LT:
3469	libfunc = lttf2_libfunc;
3470	break;
3471
3472      case LE:
3473	libfunc = letf2_libfunc;
3474	break;
3475
3476      default:
3477	break;
3478      }
3479  else
3480    {
3481      enum machine_mode wider_mode;
3482
3483      for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3484	   wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3485	{
3486	  if ((cmp_optab->handlers[(int) wider_mode].insn_code
3487	       != CODE_FOR_nothing)
3488	      || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
3489	    {
3490	      x = protect_from_queue (x, 0);
3491	      y = protect_from_queue (y, 0);
3492	      x = convert_to_mode (wider_mode, x, 0);
3493	      y = convert_to_mode (wider_mode, y, 0);
3494	      emit_float_lib_cmp (x, y, comparison);
3495	      return;
3496	    }
3497	}
3498      abort ();
3499    }
3500
3501  if (libfunc == 0)
3502    abort ();
3503
3504  emit_library_call (libfunc, 1,
3505		     word_mode, 2, x, mode, y, mode);
3506
3507  /* Immediately move the result of the libcall into a pseudo
3508     register so reload doesn't clobber the value if it needs
3509     the return register for a spill reg.  */
3510  result = gen_reg_rtx (word_mode);
3511  emit_move_insn (result, hard_libcall_value (word_mode));
3512
3513  emit_cmp_insn (result, const0_rtx, comparison,
3514		 NULL_RTX, word_mode, 0, 0);
3515}
3516
3517/* Generate code to indirectly jump to a location given in the rtx LOC.  */
3518
3519void
3520emit_indirect_jump (loc)
3521     rtx loc;
3522{
3523  if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
3524	 (loc, Pmode)))
3525    loc = copy_to_mode_reg (Pmode, loc);
3526
3527  emit_jump_insn (gen_indirect_jump (loc));
3528  emit_barrier ();
3529}
3530
3531#ifdef HAVE_conditional_move
3532
3533/* Emit a conditional move instruction if the machine supports one for that
3534   condition and machine mode.
3535
3536   OP0 and OP1 are the operands that should be compared using CODE.  CMODE is
3537   the mode to use should they be constants.  If it is VOIDmode, they cannot
3538   both be constants.
3539
3540   OP2 should be stored in TARGET if the comparison is true, otherwise OP3
3541   should be stored there.  MODE is the mode to use should they be constants.
3542   If it is VOIDmode, they cannot both be constants.
3543
3544   The result is either TARGET (perhaps modified) or NULL_RTX if the operation
3545   is not supported.  */
3546
3547rtx
3548emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
3549		       unsignedp)
3550     rtx target;
3551     enum rtx_code code;
3552     rtx op0, op1;
3553     enum machine_mode cmode;
3554     rtx op2, op3;
3555     enum machine_mode mode;
3556     int unsignedp;
3557{
3558  rtx tem, subtarget, comparison, insn;
3559  enum insn_code icode;
3560
3561  /* If one operand is constant, make it the second one.  Only do this
3562     if the other operand is not constant as well.  */
3563
3564  if ((CONSTANT_P (op0) && ! CONSTANT_P (op1))
3565      || (GET_CODE (op0) == CONST_INT && GET_CODE (op1) != CONST_INT))
3566    {
3567      tem = op0;
3568      op0 = op1;
3569      op1 = tem;
3570      code = swap_condition (code);
3571    }
3572
3573  if (cmode == VOIDmode)
3574    cmode = GET_MODE (op0);
3575
3576  if (((CONSTANT_P (op2) && ! CONSTANT_P (op3))
3577       || (GET_CODE (op2) == CONST_INT && GET_CODE (op3) != CONST_INT))
3578      && (GET_MODE_CLASS (GET_MODE (op1)) != MODE_FLOAT
3579	  || TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT || flag_fast_math))
3580    {
3581      tem = op2;
3582      op2 = op3;
3583      op3 = tem;
3584      code = reverse_condition (code);
3585    }
3586
3587  if (mode == VOIDmode)
3588    mode = GET_MODE (op2);
3589
3590  icode = movcc_gen_code[mode];
3591
3592  if (icode == CODE_FOR_nothing)
3593    return 0;
3594
3595  if (flag_force_mem)
3596    {
3597      op2 = force_not_mem (op2);
3598      op3 = force_not_mem (op3);
3599    }
3600
3601  if (target)
3602    target = protect_from_queue (target, 1);
3603  else
3604    target = gen_reg_rtx (mode);
3605
3606  subtarget = target;
3607
3608  emit_queue ();
3609
3610  op2 = protect_from_queue (op2, 0);
3611  op3 = protect_from_queue (op3, 0);
3612
3613  /* If the insn doesn't accept these operands, put them in pseudos.  */
3614
3615  if (! (*insn_operand_predicate[icode][0])
3616      (subtarget, insn_operand_mode[icode][0]))
3617    subtarget = gen_reg_rtx (insn_operand_mode[icode][0]);
3618
3619  if (! (*insn_operand_predicate[icode][2])
3620      (op2, insn_operand_mode[icode][2]))
3621    op2 = copy_to_mode_reg (insn_operand_mode[icode][2], op2);
3622
3623  if (! (*insn_operand_predicate[icode][3])
3624      (op3, insn_operand_mode[icode][3]))
3625    op3 = copy_to_mode_reg (insn_operand_mode[icode][3], op3);
3626
3627  /* Everything should now be in the suitable form, so emit the compare insn
3628     and then the conditional move.  */
3629
3630  comparison
3631    = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX, 0);
3632
3633  /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)?  */
3634  if (GET_CODE (comparison) != code)
3635    /* This shouldn't happen.  */
3636    abort ();
3637
3638  insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
3639
3640  /* If that failed, then give up.  */
3641  if (insn == 0)
3642    return 0;
3643
3644  emit_insn (insn);
3645
3646  if (subtarget != target)
3647    convert_move (target, subtarget, 0);
3648
3649  return target;
3650}
3651
3652/* Return non-zero if a conditional move of mode MODE is supported.
3653
3654   This function is for combine so it can tell whether an insn that looks
3655   like a conditional move is actually supported by the hardware.  If we
3656   guess wrong we lose a bit on optimization, but that's it.  */
3657/* ??? sparc64 supports conditionally moving integers values based on fp
3658   comparisons, and vice versa.  How do we handle them?  */
3659
3660int
3661can_conditionally_move_p (mode)
3662     enum machine_mode mode;
3663{
3664  if (movcc_gen_code[mode] != CODE_FOR_nothing)
3665    return 1;
3666
3667  return 0;
3668}
3669
3670#endif /* HAVE_conditional_move */
3671
3672/* These three functions generate an insn body and return it
3673   rather than emitting the insn.
3674
3675   They do not protect from queued increments,
3676   because they may be used 1) in protect_from_queue itself
3677   and 2) in other passes where there is no queue.  */
3678
3679/* Generate and return an insn body to add Y to X.  */
3680
3681rtx
3682gen_add2_insn (x, y)
3683     rtx x, y;
3684{
3685  int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
3686
3687  if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
3688      || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
3689      || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
3690    abort ();
3691
3692  return (GEN_FCN (icode) (x, x, y));
3693}
3694
3695int
3696have_add2_insn (mode)
3697     enum machine_mode mode;
3698{
3699  return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3700}
3701
3702/* Generate and return an insn body to subtract Y from X.  */
3703
3704rtx
3705gen_sub2_insn (x, y)
3706     rtx x, y;
3707{
3708  int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
3709
3710  if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
3711      || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
3712      || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
3713    abort ();
3714
3715  return (GEN_FCN (icode) (x, x, y));
3716}
3717
3718int
3719have_sub2_insn (mode)
3720     enum machine_mode mode;
3721{
3722  return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3723}
3724
3725/* Generate the body of an instruction to copy Y into X.
3726   It may be a SEQUENCE, if one insn isn't enough.  */
3727
3728rtx
3729gen_move_insn (x, y)
3730     rtx x, y;
3731{
3732  register enum machine_mode mode = GET_MODE (x);
3733  enum insn_code insn_code;
3734  rtx seq;
3735
3736  if (mode == VOIDmode)
3737    mode = GET_MODE (y);
3738
3739  insn_code = mov_optab->handlers[(int) mode].insn_code;
3740
3741  /* Handle MODE_CC modes:  If we don't have a special move insn for this mode,
3742     find a mode to do it in.  If we have a movcc, use it.  Otherwise,
3743     find the MODE_INT mode of the same width.  */
3744
3745  if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
3746    {
3747      enum machine_mode tmode = VOIDmode;
3748      rtx x1 = x, y1 = y;
3749
3750      if (mode != CCmode
3751	  && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
3752	tmode = CCmode;
3753      else
3754	for (tmode = QImode; tmode != VOIDmode;
3755	     tmode = GET_MODE_WIDER_MODE (tmode))
3756	  if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
3757	    break;
3758
3759      if (tmode == VOIDmode)
3760	abort ();
3761
3762      /* Get X and Y in TMODE.  We can't use gen_lowpart here because it
3763	 may call change_address which is not appropriate if we were
3764	 called when a reload was in progress.  We don't have to worry
3765	 about changing the address since the size in bytes is supposed to
3766	 be the same.  Copy the MEM to change the mode and move any
3767	 substitutions from the old MEM to the new one.  */
3768
3769      if (reload_in_progress)
3770	{
3771	  x = gen_lowpart_common (tmode, x1);
3772	  if (x == 0 && GET_CODE (x1) == MEM)
3773	    {
3774	      x = gen_rtx_MEM (tmode, XEXP (x1, 0));
3775	      RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
3776	      MEM_COPY_ATTRIBUTES (x, x1);
3777	      copy_replacements (x1, x);
3778	    }
3779
3780	  y = gen_lowpart_common (tmode, y1);
3781	  if (y == 0 && GET_CODE (y1) == MEM)
3782	    {
3783	      y = gen_rtx_MEM (tmode, XEXP (y1, 0));
3784	      RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
3785	      MEM_COPY_ATTRIBUTES (y, y1);
3786	      copy_replacements (y1, y);
3787	    }
3788	}
3789      else
3790	{
3791	  x = gen_lowpart (tmode, x);
3792	  y = gen_lowpart (tmode, y);
3793	}
3794
3795      insn_code = mov_optab->handlers[(int) tmode].insn_code;
3796      return (GEN_FCN (insn_code) (x, y));
3797    }
3798
3799  start_sequence ();
3800  emit_move_insn_1 (x, y);
3801  seq = gen_sequence ();
3802  end_sequence ();
3803  return seq;
3804}
3805
3806/* Return the insn code used to extend FROM_MODE to TO_MODE.
3807   UNSIGNEDP specifies zero-extension instead of sign-extension.  If
3808   no such operation exists, CODE_FOR_nothing will be returned.  */
3809
3810enum insn_code
3811can_extend_p (to_mode, from_mode, unsignedp)
3812     enum machine_mode to_mode, from_mode;
3813     int unsignedp;
3814{
3815  return extendtab[(int) to_mode][(int) from_mode][unsignedp];
3816}
3817
3818/* Generate the body of an insn to extend Y (with mode MFROM)
3819   into X (with mode MTO).  Do zero-extension if UNSIGNEDP is nonzero.  */
3820
3821rtx
3822gen_extend_insn (x, y, mto, mfrom, unsignedp)
3823     rtx x, y;
3824     enum machine_mode mto, mfrom;
3825     int unsignedp;
3826{
3827  return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
3828}
3829
3830/* can_fix_p and can_float_p say whether the target machine
3831   can directly convert a given fixed point type to
3832   a given floating point type, or vice versa.
3833   The returned value is the CODE_FOR_... value to use,
3834   or CODE_FOR_nothing if these modes cannot be directly converted.
3835
3836   *TRUNCP_PTR is set to 1 if it is necessary to output
3837   an explicit FTRUNC insn before the fix insn; otherwise 0.  */
3838
3839static enum insn_code
3840can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
3841     enum machine_mode fltmode, fixmode;
3842     int unsignedp;
3843     int *truncp_ptr;
3844{
3845  *truncp_ptr = 0;
3846  if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
3847    return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
3848
3849  if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
3850    {
3851      *truncp_ptr = 1;
3852      return fixtab[(int) fltmode][(int) fixmode][unsignedp];
3853    }
3854  return CODE_FOR_nothing;
3855}
3856
3857static enum insn_code
3858can_float_p (fltmode, fixmode, unsignedp)
3859     enum machine_mode fixmode, fltmode;
3860     int unsignedp;
3861{
3862  return floattab[(int) fltmode][(int) fixmode][unsignedp];
3863}
3864
3865/* Generate code to convert FROM to floating point
3866   and store in TO.  FROM must be fixed point and not VOIDmode.
3867   UNSIGNEDP nonzero means regard FROM as unsigned.
3868   Normally this is done by correcting the final value
3869   if it is negative.  */
3870
3871void
3872expand_float (to, from, unsignedp)
3873     rtx to, from;
3874     int unsignedp;
3875{
3876  enum insn_code icode;
3877  register rtx target = to;
3878  enum machine_mode fmode, imode;
3879
3880  /* Crash now, because we won't be able to decide which mode to use.  */
3881  if (GET_MODE (from) == VOIDmode)
3882    abort ();
3883
3884  /* Look for an insn to do the conversion.  Do it in the specified
3885     modes if possible; otherwise convert either input, output or both to
3886     wider mode.  If the integer mode is wider than the mode of FROM,
3887     we can do the conversion signed even if the input is unsigned.  */
3888
3889  for (imode = GET_MODE (from); imode != VOIDmode;
3890       imode = GET_MODE_WIDER_MODE (imode))
3891    for (fmode = GET_MODE (to); fmode != VOIDmode;
3892	 fmode = GET_MODE_WIDER_MODE (fmode))
3893      {
3894	int doing_unsigned = unsignedp;
3895
3896	icode = can_float_p (fmode, imode, unsignedp);
3897	if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
3898	  icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
3899
3900	if (icode != CODE_FOR_nothing)
3901	  {
3902	    to = protect_from_queue (to, 1);
3903	    from = protect_from_queue (from, 0);
3904
3905	    if (imode != GET_MODE (from))
3906	      from = convert_to_mode (imode, from, unsignedp);
3907
3908	    if (fmode != GET_MODE (to))
3909	      target = gen_reg_rtx (fmode);
3910
3911	    emit_unop_insn (icode, target, from,
3912			    doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
3913
3914	    if (target != to)
3915	      convert_move (to, target, 0);
3916	    return;
3917	  }
3918    }
3919
3920#if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3921
3922  /* Unsigned integer, and no way to convert directly.
3923     Convert as signed, then conditionally adjust the result.  */
3924  if (unsignedp)
3925    {
3926      rtx label = gen_label_rtx ();
3927      rtx temp;
3928      REAL_VALUE_TYPE offset;
3929
3930      emit_queue ();
3931
3932      to = protect_from_queue (to, 1);
3933      from = protect_from_queue (from, 0);
3934
3935      if (flag_force_mem)
3936	from = force_not_mem (from);
3937
3938      /* Look for a usable floating mode FMODE wider than the source and at
3939	 least as wide as the target.  Using FMODE will avoid rounding woes
3940	 with unsigned values greater than the signed maximum value.  */
3941
3942      for (fmode = GET_MODE (to);  fmode != VOIDmode;
3943	   fmode = GET_MODE_WIDER_MODE (fmode))
3944	if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
3945	    && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
3946	  break;
3947
3948      if (fmode == VOIDmode)
3949	{
3950	  /* There is no such mode.  Pretend the target is wide enough.  */
3951	  fmode = GET_MODE (to);
3952
3953	  /* Avoid double-rounding when TO is narrower than FROM.  */
3954	  if ((significand_size (fmode) + 1)
3955	      < GET_MODE_BITSIZE (GET_MODE (from)))
3956	    {
3957	      rtx temp1;
3958	      rtx neglabel = gen_label_rtx ();
3959
3960	      /* Don't use TARGET if it isn't a register, is a hard register,
3961		 or is the wrong mode.  */
3962	      if (GET_CODE (target) != REG
3963		  || REGNO (target) < FIRST_PSEUDO_REGISTER
3964		  || GET_MODE (target) != fmode)
3965		target = gen_reg_rtx (fmode);
3966
3967	      imode = GET_MODE (from);
3968	      do_pending_stack_adjust ();
3969
3970	      /* Test whether the sign bit is set.  */
3971	      emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, imode, 0, 0);
3972	      emit_jump_insn (gen_blt (neglabel));
3973
3974	      /* The sign bit is not set.  Convert as signed.  */
3975	      expand_float (target, from, 0);
3976	      emit_jump_insn (gen_jump (label));
3977	      emit_barrier ();
3978
3979	      /* The sign bit is set.
3980		 Convert to a usable (positive signed) value by shifting right
3981		 one bit, while remembering if a nonzero bit was shifted
3982		 out; i.e., compute  (from & 1) | (from >> 1).  */
3983
3984	      emit_label (neglabel);
3985	      temp = expand_binop (imode, and_optab, from, const1_rtx,
3986				   NULL_RTX, 1, OPTAB_LIB_WIDEN);
3987	      temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
3988				    NULL_RTX, 1);
3989	      temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
3990				   OPTAB_LIB_WIDEN);
3991	      expand_float (target, temp, 0);
3992
3993	      /* Multiply by 2 to undo the shift above.  */
3994	      temp = expand_binop (fmode, add_optab, target, target,
3995				     target, 0, OPTAB_LIB_WIDEN);
3996	      if (temp != target)
3997		emit_move_insn (target, temp);
3998
3999	      do_pending_stack_adjust ();
4000	      emit_label (label);
4001	      goto done;
4002	    }
4003	}
4004
4005      /* If we are about to do some arithmetic to correct for an
4006	 unsigned operand, do it in a pseudo-register.  */
4007
4008      if (GET_MODE (to) != fmode
4009	  || GET_CODE (to) != REG || REGNO (to) < FIRST_PSEUDO_REGISTER)
4010	target = gen_reg_rtx (fmode);
4011
4012      /* Convert as signed integer to floating.  */
4013      expand_float (target, from, 0);
4014
4015      /* If FROM is negative (and therefore TO is negative),
4016	 correct its value by 2**bitwidth.  */
4017
4018      do_pending_stack_adjust ();
4019      emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
4020			        0, 0, label);
4021
4022      /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
4023	 Rather than setting up a dconst_dot_5, let's hope SCO
4024	 fixes the bug.  */
4025      offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
4026      temp = expand_binop (fmode, add_optab, target,
4027			   CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
4028			   target, 0, OPTAB_LIB_WIDEN);
4029      if (temp != target)
4030	emit_move_insn (target, temp);
4031
4032      do_pending_stack_adjust ();
4033      emit_label (label);
4034      goto done;
4035    }
4036#endif
4037
4038  /* No hardware instruction available; call a library routine to convert from
4039     SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode.  */
4040    {
4041      rtx libfcn;
4042      rtx insns;
4043      rtx value;
4044
4045      to = protect_from_queue (to, 1);
4046      from = protect_from_queue (from, 0);
4047
4048      if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
4049	from = convert_to_mode (SImode, from, unsignedp);
4050
4051      if (flag_force_mem)
4052	from = force_not_mem (from);
4053
4054      if (GET_MODE (to) == SFmode)
4055	{
4056	  if (GET_MODE (from) == SImode)
4057	    libfcn = floatsisf_libfunc;
4058	  else if (GET_MODE (from) == DImode)
4059	    libfcn = floatdisf_libfunc;
4060	  else if (GET_MODE (from) == TImode)
4061	    libfcn = floattisf_libfunc;
4062	  else
4063	    abort ();
4064	}
4065      else if (GET_MODE (to) == DFmode)
4066	{
4067	  if (GET_MODE (from) == SImode)
4068	    libfcn = floatsidf_libfunc;
4069	  else if (GET_MODE (from) == DImode)
4070	    libfcn = floatdidf_libfunc;
4071	  else if (GET_MODE (from) == TImode)
4072	    libfcn = floattidf_libfunc;
4073	  else
4074	    abort ();
4075	}
4076      else if (GET_MODE (to) == XFmode)
4077	{
4078	  if (GET_MODE (from) == SImode)
4079	    libfcn = floatsixf_libfunc;
4080	  else if (GET_MODE (from) == DImode)
4081	    libfcn = floatdixf_libfunc;
4082	  else if (GET_MODE (from) == TImode)
4083	    libfcn = floattixf_libfunc;
4084	  else
4085	    abort ();
4086	}
4087      else if (GET_MODE (to) == TFmode)
4088	{
4089	  if (GET_MODE (from) == SImode)
4090	    libfcn = floatsitf_libfunc;
4091	  else if (GET_MODE (from) == DImode)
4092	    libfcn = floatditf_libfunc;
4093	  else if (GET_MODE (from) == TImode)
4094	    libfcn = floattitf_libfunc;
4095	  else
4096	    abort ();
4097	}
4098      else
4099	abort ();
4100
4101      start_sequence ();
4102
4103      value = emit_library_call_value (libfcn, NULL_RTX, 1,
4104				       GET_MODE (to),
4105				       1, from, GET_MODE (from));
4106      insns = get_insns ();
4107      end_sequence ();
4108
4109      emit_libcall_block (insns, target, value,
4110			  gen_rtx_FLOAT (GET_MODE (to), from));
4111    }
4112
4113 done:
4114
4115  /* Copy result to requested destination
4116     if we have been computing in a temp location.  */
4117
4118  if (target != to)
4119    {
4120      if (GET_MODE (target) == GET_MODE (to))
4121	emit_move_insn (to, target);
4122      else
4123	convert_move (to, target, 0);
4124    }
4125}
4126
4127/* expand_fix: generate code to convert FROM to fixed point
4128   and store in TO.  FROM must be floating point.  */
4129
4130static rtx
4131ftruncify (x)
4132     rtx x;
4133{
4134  rtx temp = gen_reg_rtx (GET_MODE (x));
4135  return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
4136}
4137
4138void
4139expand_fix (to, from, unsignedp)
4140     register rtx to, from;
4141     int unsignedp;
4142{
4143  enum insn_code icode;
4144  register rtx target = to;
4145  enum machine_mode fmode, imode;
4146  int must_trunc = 0;
4147  rtx libfcn = 0;
4148
4149  /* We first try to find a pair of modes, one real and one integer, at
4150     least as wide as FROM and TO, respectively, in which we can open-code
4151     this conversion.  If the integer mode is wider than the mode of TO,
4152     we can do the conversion either signed or unsigned.  */
4153
4154  for (imode = GET_MODE (to); imode != VOIDmode;
4155       imode = GET_MODE_WIDER_MODE (imode))
4156    for (fmode = GET_MODE (from); fmode != VOIDmode;
4157	 fmode = GET_MODE_WIDER_MODE (fmode))
4158      {
4159	int doing_unsigned = unsignedp;
4160
4161	icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
4162	if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
4163	  icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
4164
4165	if (icode != CODE_FOR_nothing)
4166	  {
4167	    to = protect_from_queue (to, 1);
4168	    from = protect_from_queue (from, 0);
4169
4170	    if (fmode != GET_MODE (from))
4171	      from = convert_to_mode (fmode, from, 0);
4172
4173	    if (must_trunc)
4174	      from = ftruncify (from);
4175
4176	    if (imode != GET_MODE (to))
4177	      target = gen_reg_rtx (imode);
4178
4179	    emit_unop_insn (icode, target, from,
4180			    doing_unsigned ? UNSIGNED_FIX : FIX);
4181	    if (target != to)
4182	      convert_move (to, target, unsignedp);
4183	    return;
4184	  }
4185      }
4186
4187#if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
4188  /* For an unsigned conversion, there is one more way to do it.
4189     If we have a signed conversion, we generate code that compares
4190     the real value to the largest representable positive number.  If if
4191     is smaller, the conversion is done normally.  Otherwise, subtract
4192     one plus the highest signed number, convert, and add it back.
4193
4194     We only need to check all real modes, since we know we didn't find
4195     anything with a wider integer mode.  */
4196
4197  if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
4198    for (fmode = GET_MODE (from); fmode != VOIDmode;
4199	 fmode = GET_MODE_WIDER_MODE (fmode))
4200      /* Make sure we won't lose significant bits doing this.  */
4201      if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
4202	  && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
4203					    &must_trunc))
4204	{
4205	  int bitsize;
4206	  REAL_VALUE_TYPE offset;
4207	  rtx limit, lab1, lab2, insn;
4208
4209	  bitsize = GET_MODE_BITSIZE (GET_MODE (to));
4210	  offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
4211	  limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
4212	  lab1 = gen_label_rtx ();
4213	  lab2 = gen_label_rtx ();
4214
4215	  emit_queue ();
4216	  to = protect_from_queue (to, 1);
4217	  from = protect_from_queue (from, 0);
4218
4219	  if (flag_force_mem)
4220	    from = force_not_mem (from);
4221
4222	  if (fmode != GET_MODE (from))
4223	    from = convert_to_mode (fmode, from, 0);
4224
4225	  /* See if we need to do the subtraction.  */
4226	  do_pending_stack_adjust ();
4227	  emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
4228				   0, 0, lab1);
4229
4230	  /* If not, do the signed "fix" and branch around fixup code.  */
4231	  expand_fix (to, from, 0);
4232	  emit_jump_insn (gen_jump (lab2));
4233	  emit_barrier ();
4234
4235	  /* Otherwise, subtract 2**(N-1), convert to signed number,
4236	     then add 2**(N-1).  Do the addition using XOR since this
4237	     will often generate better code.  */
4238	  emit_label (lab1);
4239	  target = expand_binop (GET_MODE (from), sub_optab, from, limit,
4240				 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4241	  expand_fix (to, target, 0);
4242	  target = expand_binop (GET_MODE (to), xor_optab, to,
4243				 GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
4244				 to, 1, OPTAB_LIB_WIDEN);
4245
4246	  if (target != to)
4247	    emit_move_insn (to, target);
4248
4249	  emit_label (lab2);
4250
4251	  if (mov_optab->handlers[(int) GET_MODE (to)].insn_code
4252	      != CODE_FOR_nothing)
4253	    {
4254	      /* Make a place for a REG_NOTE and add it.  */
4255	      insn = emit_move_insn (to, to);
4256	      set_unique_reg_note (insn,
4257	                           REG_EQUAL,
4258				   gen_rtx_fmt_e (UNSIGNED_FIX,
4259						  GET_MODE (to),
4260						  copy_rtx (from)));
4261	    }
4262	  return;
4263	}
4264#endif
4265
4266  /* We can't do it with an insn, so use a library call.  But first ensure
4267     that the mode of TO is at least as wide as SImode, since those are the
4268     only library calls we know about.  */
4269
4270  if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
4271    {
4272      target = gen_reg_rtx (SImode);
4273
4274      expand_fix (target, from, unsignedp);
4275    }
4276  else if (GET_MODE (from) == SFmode)
4277    {
4278      if (GET_MODE (to) == SImode)
4279	libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
4280      else if (GET_MODE (to) == DImode)
4281	libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
4282      else if (GET_MODE (to) == TImode)
4283	libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
4284      else
4285	abort ();
4286    }
4287  else if (GET_MODE (from) == DFmode)
4288    {
4289      if (GET_MODE (to) == SImode)
4290	libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
4291      else if (GET_MODE (to) == DImode)
4292	libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
4293      else if (GET_MODE (to) == TImode)
4294	libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
4295      else
4296	abort ();
4297    }
4298  else if (GET_MODE (from) == XFmode)
4299    {
4300      if (GET_MODE (to) == SImode)
4301	libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
4302      else if (GET_MODE (to) == DImode)
4303	libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
4304      else if (GET_MODE (to) == TImode)
4305	libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
4306      else
4307	abort ();
4308    }
4309  else if (GET_MODE (from) == TFmode)
4310    {
4311      if (GET_MODE (to) == SImode)
4312	libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
4313      else if (GET_MODE (to) == DImode)
4314	libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
4315      else if (GET_MODE (to) == TImode)
4316	libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
4317      else
4318	abort ();
4319    }
4320  else
4321    abort ();
4322
4323  if (libfcn)
4324    {
4325      rtx insns;
4326      rtx value;
4327
4328      to = protect_from_queue (to, 1);
4329      from = protect_from_queue (from, 0);
4330
4331      if (flag_force_mem)
4332	from = force_not_mem (from);
4333
4334      start_sequence ();
4335
4336      value = emit_library_call_value (libfcn, NULL_RTX, 1, GET_MODE (to),
4337
4338				       1, from, GET_MODE (from));
4339      insns = get_insns ();
4340      end_sequence ();
4341
4342      emit_libcall_block (insns, target, value,
4343			  gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
4344					 GET_MODE (to), from));
4345    }
4346
4347  if (target != to)
4348    {
4349      if (GET_MODE (to) == GET_MODE (target))
4350        emit_move_insn (to, target);
4351      else
4352        convert_move (to, target, 0);
4353    }
4354}
4355
4356static optab
4357init_optab (code)
4358     enum rtx_code code;
4359{
4360  int i;
4361  optab op = (optab) xmalloc (sizeof (struct optab));
4362  op->code = code;
4363  for (i = 0; i < NUM_MACHINE_MODES; i++)
4364    {
4365      op->handlers[i].insn_code = CODE_FOR_nothing;
4366      op->handlers[i].libfunc = 0;
4367    }
4368
4369  if (code != UNKNOWN)
4370    code_to_optab[(int) code] = op;
4371
4372  return op;
4373}
4374
4375/* Initialize the libfunc fields of an entire group of entries in some
4376   optab.  Each entry is set equal to a string consisting of a leading
4377   pair of underscores followed by a generic operation name followed by
4378   a mode name (downshifted to lower case) followed by a single character
4379   representing the number of operands for the given operation (which is
4380   usually one of the characters '2', '3', or '4').
4381
4382   OPTABLE is the table in which libfunc fields are to be initialized.
4383   FIRST_MODE is the first machine mode index in the given optab to
4384     initialize.
4385   LAST_MODE is the last machine mode index in the given optab to
4386     initialize.
4387   OPNAME is the generic (string) name of the operation.
4388   SUFFIX is the character which specifies the number of operands for
4389     the given generic operation.
4390*/
4391
4392static void
4393init_libfuncs (optable, first_mode, last_mode, opname, suffix)
4394    register optab optable;
4395    register int first_mode;
4396    register int last_mode;
4397    register const char *opname;
4398    register int suffix;
4399{
4400  register int mode;
4401  register unsigned opname_len = strlen (opname);
4402
4403  for (mode = first_mode; (int) mode <= (int) last_mode;
4404       mode = (enum machine_mode) ((int) mode + 1))
4405    {
4406      register char *mname = mode_name[(int) mode];
4407      register unsigned mname_len = strlen (mname);
4408      register char *libfunc_name
4409	= (char *) xmalloc (2 + opname_len + mname_len + 1 + 1);
4410      register char *p;
4411      register const char *q;
4412
4413      p = libfunc_name;
4414      *p++ = '_';
4415      *p++ = '_';
4416      for (q = opname; *q; )
4417	*p++ = *q++;
4418      for (q = mname; *q; q++)
4419	*p++ = tolower ((unsigned char)*q);
4420      *p++ = suffix;
4421      *p++ = '\0';
4422      optable->handlers[(int) mode].libfunc
4423	= gen_rtx_SYMBOL_REF (Pmode, libfunc_name);
4424    }
4425}
4426
4427/* Initialize the libfunc fields of an entire group of entries in some
4428   optab which correspond to all integer mode operations.  The parameters
4429   have the same meaning as similarly named ones for the `init_libfuncs'
4430   routine.  (See above).  */
4431
4432static void
4433init_integral_libfuncs (optable, opname, suffix)
4434    register optab optable;
4435    register const char *opname;
4436    register int suffix;
4437{
4438  init_libfuncs (optable, SImode, TImode, opname, suffix);
4439}
4440
4441/* Initialize the libfunc fields of an entire group of entries in some
4442   optab which correspond to all real mode operations.  The parameters
4443   have the same meaning as similarly named ones for the `init_libfuncs'
4444   routine.  (See above).  */
4445
4446static void
4447init_floating_libfuncs (optable, opname, suffix)
4448    register optab optable;
4449    register const char *opname;
4450    register int suffix;
4451{
4452  init_libfuncs (optable, SFmode, TFmode, opname, suffix);
4453}
4454
4455
4456/* Call this once to initialize the contents of the optabs
4457   appropriately for the current target machine.  */
4458
4459void
4460init_optabs ()
4461{
4462  int i;
4463#ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4464  int j;
4465#endif
4466
4467  enum insn_code *p;
4468
4469  /* Start by initializing all tables to contain CODE_FOR_nothing.  */
4470
4471  for (p = fixtab[0][0];
4472       p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]);
4473       p++)
4474    *p = CODE_FOR_nothing;
4475
4476  for (p = fixtrunctab[0][0];
4477       p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]);
4478       p++)
4479    *p = CODE_FOR_nothing;
4480
4481  for (p = floattab[0][0];
4482       p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]);
4483       p++)
4484    *p = CODE_FOR_nothing;
4485
4486  for (p = extendtab[0][0];
4487       p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
4488       p++)
4489    *p = CODE_FOR_nothing;
4490
4491  for (i = 0; i < NUM_RTX_CODE; i++)
4492    setcc_gen_code[i] = CODE_FOR_nothing;
4493
4494#ifdef HAVE_conditional_move
4495  for (i = 0; i < NUM_MACHINE_MODES; i++)
4496    movcc_gen_code[i] = CODE_FOR_nothing;
4497#endif
4498
4499  add_optab = init_optab (PLUS);
4500  sub_optab = init_optab (MINUS);
4501  smul_optab = init_optab (MULT);
4502  smul_highpart_optab = init_optab (UNKNOWN);
4503  umul_highpart_optab = init_optab (UNKNOWN);
4504  smul_widen_optab = init_optab (UNKNOWN);
4505  umul_widen_optab = init_optab (UNKNOWN);
4506  sdiv_optab = init_optab (DIV);
4507  sdivmod_optab = init_optab (UNKNOWN);
4508  udiv_optab = init_optab (UDIV);
4509  udivmod_optab = init_optab (UNKNOWN);
4510  smod_optab = init_optab (MOD);
4511  umod_optab = init_optab (UMOD);
4512  flodiv_optab = init_optab (DIV);
4513  ftrunc_optab = init_optab (UNKNOWN);
4514  and_optab = init_optab (AND);
4515  ior_optab = init_optab (IOR);
4516  xor_optab = init_optab (XOR);
4517  ashl_optab = init_optab (ASHIFT);
4518  ashr_optab = init_optab (ASHIFTRT);
4519  lshr_optab = init_optab (LSHIFTRT);
4520  rotl_optab = init_optab (ROTATE);
4521  rotr_optab = init_optab (ROTATERT);
4522  smin_optab = init_optab (SMIN);
4523  smax_optab = init_optab (SMAX);
4524  umin_optab = init_optab (UMIN);
4525  umax_optab = init_optab (UMAX);
4526  mov_optab = init_optab (UNKNOWN);
4527  movstrict_optab = init_optab (UNKNOWN);
4528  cmp_optab = init_optab (UNKNOWN);
4529  ucmp_optab = init_optab (UNKNOWN);
4530  tst_optab = init_optab (UNKNOWN);
4531  neg_optab = init_optab (NEG);
4532  abs_optab = init_optab (ABS);
4533  one_cmpl_optab = init_optab (NOT);
4534  ffs_optab = init_optab (FFS);
4535  sqrt_optab = init_optab (SQRT);
4536  sin_optab = init_optab (UNKNOWN);
4537  cos_optab = init_optab (UNKNOWN);
4538  strlen_optab = init_optab (UNKNOWN);
4539
4540  for (i = 0; i < NUM_MACHINE_MODES; i++)
4541    {
4542      movstr_optab[i] = CODE_FOR_nothing;
4543      clrstr_optab[i] = CODE_FOR_nothing;
4544
4545#ifdef HAVE_SECONDARY_RELOADS
4546      reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
4547#endif
4548    }
4549
4550  /* Fill in the optabs with the insns we support.  */
4551  init_all_optabs ();
4552
4553#ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4554  /* This flag says the same insns that convert to a signed fixnum
4555     also convert validly to an unsigned one.  */
4556  for (i = 0; i < NUM_MACHINE_MODES; i++)
4557    for (j = 0; j < NUM_MACHINE_MODES; j++)
4558      fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
4559#endif
4560
4561#ifdef EXTRA_CC_MODES
4562  init_mov_optab ();
4563#endif
4564
4565  /* Initialize the optabs with the names of the library functions.  */
4566  init_integral_libfuncs (add_optab, "add", '3');
4567  init_floating_libfuncs (add_optab, "add", '3');
4568  init_integral_libfuncs (sub_optab, "sub", '3');
4569  init_floating_libfuncs (sub_optab, "sub", '3');
4570  init_integral_libfuncs (smul_optab, "mul", '3');
4571  init_floating_libfuncs (smul_optab, "mul", '3');
4572  init_integral_libfuncs (sdiv_optab, "div", '3');
4573  init_integral_libfuncs (udiv_optab, "udiv", '3');
4574  init_integral_libfuncs (sdivmod_optab, "divmod", '4');
4575  init_integral_libfuncs (udivmod_optab, "udivmod", '4');
4576  init_integral_libfuncs (smod_optab, "mod", '3');
4577  init_integral_libfuncs (umod_optab, "umod", '3');
4578  init_floating_libfuncs (flodiv_optab, "div", '3');
4579  init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
4580  init_integral_libfuncs (and_optab, "and", '3');
4581  init_integral_libfuncs (ior_optab, "ior", '3');
4582  init_integral_libfuncs (xor_optab, "xor", '3');
4583  init_integral_libfuncs (ashl_optab, "ashl", '3');
4584  init_integral_libfuncs (ashr_optab, "ashr", '3');
4585  init_integral_libfuncs (lshr_optab, "lshr", '3');
4586  init_integral_libfuncs (smin_optab, "min", '3');
4587  init_floating_libfuncs (smin_optab, "min", '3');
4588  init_integral_libfuncs (smax_optab, "max", '3');
4589  init_floating_libfuncs (smax_optab, "max", '3');
4590  init_integral_libfuncs (umin_optab, "umin", '3');
4591  init_integral_libfuncs (umax_optab, "umax", '3');
4592  init_integral_libfuncs (neg_optab, "neg", '2');
4593  init_floating_libfuncs (neg_optab, "neg", '2');
4594  init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
4595  init_integral_libfuncs (ffs_optab, "ffs", '2');
4596
4597  /* Comparison libcalls for integers MUST come in pairs, signed/unsigned.  */
4598  init_integral_libfuncs (cmp_optab, "cmp", '2');
4599  init_integral_libfuncs (ucmp_optab, "ucmp", '2');
4600  init_floating_libfuncs (cmp_optab, "cmp", '2');
4601
4602#ifdef MULSI3_LIBCALL
4603  smul_optab->handlers[(int) SImode].libfunc
4604    = gen_rtx_SYMBOL_REF (Pmode, MULSI3_LIBCALL);
4605#endif
4606#ifdef MULDI3_LIBCALL
4607  smul_optab->handlers[(int) DImode].libfunc
4608    = gen_rtx_SYMBOL_REF (Pmode, MULDI3_LIBCALL);
4609#endif
4610
4611#ifdef DIVSI3_LIBCALL
4612  sdiv_optab->handlers[(int) SImode].libfunc
4613    = gen_rtx_SYMBOL_REF (Pmode, DIVSI3_LIBCALL);
4614#endif
4615#ifdef DIVDI3_LIBCALL
4616  sdiv_optab->handlers[(int) DImode].libfunc
4617    = gen_rtx_SYMBOL_REF (Pmode, DIVDI3_LIBCALL);
4618#endif
4619
4620#ifdef UDIVSI3_LIBCALL
4621  udiv_optab->handlers[(int) SImode].libfunc
4622    = gen_rtx_SYMBOL_REF (Pmode, UDIVSI3_LIBCALL);
4623#endif
4624#ifdef UDIVDI3_LIBCALL
4625  udiv_optab->handlers[(int) DImode].libfunc
4626    = gen_rtx_SYMBOL_REF (Pmode, UDIVDI3_LIBCALL);
4627#endif
4628
4629#ifdef MODSI3_LIBCALL
4630  smod_optab->handlers[(int) SImode].libfunc
4631    = gen_rtx_SYMBOL_REF (Pmode, MODSI3_LIBCALL);
4632#endif
4633#ifdef MODDI3_LIBCALL
4634  smod_optab->handlers[(int) DImode].libfunc
4635    = gen_rtx_SYMBOL_REF (Pmode, MODDI3_LIBCALL);
4636#endif
4637
4638#ifdef UMODSI3_LIBCALL
4639  umod_optab->handlers[(int) SImode].libfunc
4640    = gen_rtx_SYMBOL_REF (Pmode, UMODSI3_LIBCALL);
4641#endif
4642#ifdef UMODDI3_LIBCALL
4643  umod_optab->handlers[(int) DImode].libfunc
4644    = gen_rtx_SYMBOL_REF (Pmode, UMODDI3_LIBCALL);
4645#endif
4646
4647  /* Use cabs for DC complex abs, since systems generally have cabs.
4648     Don't define any libcall for SCmode, so that cabs will be used.  */
4649  abs_optab->handlers[(int) DCmode].libfunc
4650    = gen_rtx_SYMBOL_REF (Pmode, "cabs");
4651
4652  /* The ffs function operates on `int'.  */
4653#ifndef INT_TYPE_SIZE
4654#define INT_TYPE_SIZE BITS_PER_WORD
4655#endif
4656  ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)] .libfunc
4657    = gen_rtx_SYMBOL_REF (Pmode, "ffs");
4658
4659  extendsfdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extendsfdf2");
4660  extendsfxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extendsfxf2");
4661  extendsftf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extendsftf2");
4662  extenddfxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extenddfxf2");
4663  extenddftf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extenddftf2");
4664
4665  truncdfsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__truncdfsf2");
4666  truncxfsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__truncxfsf2");
4667  trunctfsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__trunctfsf2");
4668  truncxfdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__truncxfdf2");
4669  trunctfdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__trunctfdf2");
4670
4671  memcpy_libfunc = gen_rtx_SYMBOL_REF (Pmode, "memcpy");
4672  bcopy_libfunc = gen_rtx_SYMBOL_REF (Pmode, "bcopy");
4673  memcmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "memcmp");
4674  bcmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gcc_bcmp");
4675  memset_libfunc = gen_rtx_SYMBOL_REF (Pmode, "memset");
4676  bzero_libfunc = gen_rtx_SYMBOL_REF (Pmode, "bzero");
4677
4678  throw_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__throw");
4679  rethrow_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__rethrow");
4680  sjthrow_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__sjthrow");
4681  sjpopnthrow_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__sjpopnthrow");
4682  terminate_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__terminate");
4683  eh_rtime_match_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eh_rtime_match");
4684#ifndef DONT_USE_BUILTIN_SETJMP
4685  setjmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__builtin_setjmp");
4686  longjmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__builtin_longjmp");
4687#else
4688  setjmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "setjmp");
4689  longjmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "longjmp");
4690#endif
4691
4692  eqhf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqhf2");
4693  nehf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__nehf2");
4694  gthf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gthf2");
4695  gehf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gehf2");
4696  lthf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lthf2");
4697  lehf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lehf2");
4698
4699  eqsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqsf2");
4700  nesf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__nesf2");
4701  gtsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gtsf2");
4702  gesf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gesf2");
4703  ltsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__ltsf2");
4704  lesf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lesf2");
4705
4706  eqdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqdf2");
4707  nedf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__nedf2");
4708  gtdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gtdf2");
4709  gedf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gedf2");
4710  ltdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__ltdf2");
4711  ledf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__ledf2");
4712
4713  eqxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqxf2");
4714  nexf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__nexf2");
4715  gtxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gtxf2");
4716  gexf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gexf2");
4717  ltxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__ltxf2");
4718  lexf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lexf2");
4719
4720  eqtf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqtf2");
4721  netf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__netf2");
4722  gttf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gttf2");
4723  getf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__getf2");
4724  lttf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lttf2");
4725  letf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__letf2");
4726
4727  floatsisf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatsisf");
4728  floatdisf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatdisf");
4729  floattisf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floattisf");
4730
4731  floatsidf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatsidf");
4732  floatdidf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatdidf");
4733  floattidf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floattidf");
4734
4735  floatsixf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatsixf");
4736  floatdixf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatdixf");
4737  floattixf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floattixf");
4738
4739  floatsitf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatsitf");
4740  floatditf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatditf");
4741  floattitf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floattitf");
4742
4743  fixsfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixsfsi");
4744  fixsfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixsfdi");
4745  fixsfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixsfti");
4746
4747  fixdfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixdfsi");
4748  fixdfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixdfdi");
4749  fixdfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixdfti");
4750
4751  fixxfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixxfsi");
4752  fixxfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixxfdi");
4753  fixxfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixxfti");
4754
4755  fixtfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixtfsi");
4756  fixtfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixtfdi");
4757  fixtfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixtfti");
4758
4759  fixunssfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunssfsi");
4760  fixunssfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunssfdi");
4761  fixunssfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunssfti");
4762
4763  fixunsdfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsdfsi");
4764  fixunsdfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsdfdi");
4765  fixunsdfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsdfti");
4766
4767  fixunsxfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsxfsi");
4768  fixunsxfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsxfdi");
4769  fixunsxfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsxfti");
4770
4771  fixunstfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunstfsi");
4772  fixunstfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunstfdi");
4773  fixunstfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunstfti");
4774
4775  /* For check-memory-usage.  */
4776  chkr_check_addr_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_check_addr");
4777  chkr_set_right_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_set_right");
4778  chkr_copy_bitmap_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_copy_bitmap");
4779  chkr_check_exec_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_check_exec");
4780  chkr_check_str_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_check_str");
4781
4782  /* For function entry/exit instrumentation.  */
4783  profile_function_entry_libfunc
4784    = gen_rtx_SYMBOL_REF (Pmode, "__cyg_profile_func_enter");
4785  profile_function_exit_libfunc
4786    = gen_rtx_SYMBOL_REF (Pmode, "__cyg_profile_func_exit");
4787
4788#ifdef HAVE_conditional_trap
4789  init_traps ();
4790#endif
4791
4792#ifdef INIT_TARGET_OPTABS
4793  /* Allow the target to add more libcalls or rename some, etc.  */
4794  INIT_TARGET_OPTABS;
4795#endif
4796}
4797
4798#ifdef BROKEN_LDEXP
4799
4800/* SCO 3.2 apparently has a broken ldexp.  */
4801
4802double
4803ldexp(x,n)
4804     double x;
4805     int n;
4806{
4807  if (n > 0)
4808    while (n--)
4809      x *= 2;
4810
4811  return x;
4812}
4813#endif /* BROKEN_LDEXP */
4814
4815#ifdef HAVE_conditional_trap
4816/* The insn generating function can not take an rtx_code argument.
4817   TRAP_RTX is used as an rtx argument.  Its code is replaced with
4818   the code to be used in the trap insn and all other fields are
4819   ignored.
4820
4821   ??? Will need to change to support garbage collection.  */
4822static rtx trap_rtx;
4823
4824static void
4825init_traps ()
4826{
4827  if (HAVE_conditional_trap)
4828    trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
4829}
4830#endif
4831
4832/* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
4833   CODE.  Return 0 on failure.  */
4834
4835rtx
4836gen_cond_trap (code, op1, op2, tcode)
4837  enum rtx_code code ATTRIBUTE_UNUSED;
4838  rtx op1, op2 ATTRIBUTE_UNUSED, tcode ATTRIBUTE_UNUSED;
4839{
4840  enum machine_mode mode = GET_MODE (op1);
4841
4842  if (mode == VOIDmode)
4843    return 0;
4844
4845#ifdef HAVE_conditional_trap
4846  if (HAVE_conditional_trap
4847      && cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
4848    {
4849      rtx insn;
4850      emit_insn (GEN_FCN (cmp_optab->handlers[(int) mode].insn_code) (op1, op2));
4851      PUT_CODE (trap_rtx, code);
4852      insn = gen_conditional_trap (trap_rtx, tcode);
4853      if (insn)
4854	return insn;
4855    }
4856#endif
4857
4858  return 0;
4859}
4860