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