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