optabs.c revision 117395
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    x = copy_to_mode_reg (insn_data[icode].operand[opnum].mode, x);
3536  return x;
3537}
3538
3539/* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
3540   we can do the comparison.
3541   The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may
3542   be NULL_RTX which indicates that only a comparison is to be generated.  */
3543
3544static void
3545emit_cmp_and_jump_insn_1 (x, y, mode, comparison, unsignedp, label)
3546     rtx x, y;
3547     enum machine_mode mode;
3548     enum rtx_code comparison;
3549     int unsignedp;
3550     rtx label;
3551{
3552  rtx test = gen_rtx_fmt_ee (comparison, mode, x, y);
3553  enum mode_class class = GET_MODE_CLASS (mode);
3554  enum machine_mode wider_mode = mode;
3555
3556  /* Try combined insns first.  */
3557  do
3558    {
3559      enum insn_code icode;
3560      PUT_MODE (test, wider_mode);
3561
3562      if (label)
3563	{
3564	  icode = cbranch_optab->handlers[(int) wider_mode].insn_code;
3565
3566	  if (icode != CODE_FOR_nothing
3567	      && (*insn_data[icode].operand[0].predicate) (test, wider_mode))
3568	    {
3569	      x = prepare_operand (icode, x, 1, mode, wider_mode, unsignedp);
3570	      y = prepare_operand (icode, y, 2, mode, wider_mode, unsignedp);
3571	      emit_jump_insn (GEN_FCN (icode) (test, x, y, label));
3572	      return;
3573	    }
3574	}
3575
3576      /* Handle some compares against zero.  */
3577      icode = (int) tst_optab->handlers[(int) wider_mode].insn_code;
3578      if (y == CONST0_RTX (mode) && icode != CODE_FOR_nothing)
3579	{
3580	  x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3581	  emit_insn (GEN_FCN (icode) (x));
3582	  if (label)
3583	    emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
3584	  return;
3585	}
3586
3587      /* Handle compares for which there is a directly suitable insn.  */
3588
3589      icode = (int) cmp_optab->handlers[(int) wider_mode].insn_code;
3590      if (icode != CODE_FOR_nothing)
3591	{
3592	  x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3593	  y = prepare_operand (icode, y, 1, mode, wider_mode, unsignedp);
3594	  emit_insn (GEN_FCN (icode) (x, y));
3595	  if (label)
3596	    emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
3597	  return;
3598	}
3599
3600      if (class != MODE_INT && class != MODE_FLOAT
3601	  && class != MODE_COMPLEX_FLOAT)
3602	break;
3603
3604      wider_mode = GET_MODE_WIDER_MODE (wider_mode);
3605    }
3606  while (wider_mode != VOIDmode);
3607
3608  abort ();
3609}
3610
3611/* Generate code to compare X with Y so that the condition codes are
3612   set and to jump to LABEL if the condition is true.  If X is a
3613   constant and Y is not a constant, then the comparison is swapped to
3614   ensure that the comparison RTL has the canonical form.
3615
3616   UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
3617   need to be widened by emit_cmp_insn.  UNSIGNEDP is also used to select
3618   the proper branch condition code.
3619
3620   If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
3621
3622   MODE is the mode of the inputs (in case they are const_int).
3623
3624   COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  It will
3625   be passed unchanged to emit_cmp_insn, then potentially converted into an
3626   unsigned variant based on UNSIGNEDP to select a proper jump instruction.  */
3627
3628void
3629emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, label)
3630     rtx x, y;
3631     enum rtx_code comparison;
3632     rtx size;
3633     enum machine_mode mode;
3634     int unsignedp;
3635     rtx label;
3636{
3637  rtx op0 = x, op1 = y;
3638
3639  /* Swap operands and condition to ensure canonical RTL.  */
3640  if (swap_commutative_operands_p (x, y))
3641    {
3642      /* If we're not emitting a branch, this means some caller
3643         is out of sync.  */
3644      if (! label)
3645	abort ();
3646
3647      op0 = y, op1 = x;
3648      comparison = swap_condition (comparison);
3649    }
3650
3651#ifdef HAVE_cc0
3652  /* If OP0 is still a constant, then both X and Y must be constants.  Force
3653     X into a register to avoid aborting in emit_cmp_insn due to non-canonical
3654     RTL.  */
3655  if (CONSTANT_P (op0))
3656    op0 = force_reg (mode, op0);
3657#endif
3658
3659  emit_queue ();
3660  if (unsignedp)
3661    comparison = unsigned_condition (comparison);
3662
3663  prepare_cmp_insn (&op0, &op1, &comparison, size, &mode, &unsignedp,
3664		    ccp_jump);
3665  emit_cmp_and_jump_insn_1 (op0, op1, mode, comparison, unsignedp, label);
3666}
3667
3668/* Like emit_cmp_and_jump_insns, but generate only the comparison.  */
3669
3670void
3671emit_cmp_insn (x, y, comparison, size, mode, unsignedp)
3672     rtx x, y;
3673     enum rtx_code comparison;
3674     rtx size;
3675     enum machine_mode mode;
3676     int unsignedp;
3677{
3678  emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, 0);
3679}
3680
3681/* Emit a library call comparison between floating point X and Y.
3682   COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  */
3683
3684static void
3685prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp)
3686     rtx *px, *py;
3687     enum rtx_code *pcomparison;
3688     enum machine_mode *pmode;
3689     int *punsignedp;
3690{
3691  enum rtx_code comparison = *pcomparison;
3692  rtx tmp;
3693  rtx x = *px = protect_from_queue (*px, 0);
3694  rtx y = *py = protect_from_queue (*py, 0);
3695  enum machine_mode mode = GET_MODE (x);
3696  rtx libfunc = 0;
3697  rtx result;
3698
3699  if (mode == HFmode)
3700    switch (comparison)
3701      {
3702      case EQ:
3703	libfunc = eqhf2_libfunc;
3704	break;
3705
3706      case NE:
3707	libfunc = nehf2_libfunc;
3708	break;
3709
3710      case GT:
3711	libfunc = gthf2_libfunc;
3712	if (libfunc == NULL_RTX)
3713	  {
3714	    tmp = x; x = y; y = tmp;
3715	    *pcomparison = LT;
3716	    libfunc = lthf2_libfunc;
3717	  }
3718	break;
3719
3720      case GE:
3721	libfunc = gehf2_libfunc;
3722	if (libfunc == NULL_RTX)
3723	  {
3724	    tmp = x; x = y; y = tmp;
3725	    *pcomparison = LE;
3726	    libfunc = lehf2_libfunc;
3727	  }
3728	break;
3729
3730      case LT:
3731	libfunc = lthf2_libfunc;
3732	if (libfunc == NULL_RTX)
3733	  {
3734	    tmp = x; x = y; y = tmp;
3735	    *pcomparison = GT;
3736	    libfunc = gthf2_libfunc;
3737	  }
3738	break;
3739
3740      case LE:
3741	libfunc = lehf2_libfunc;
3742	if (libfunc == NULL_RTX)
3743	  {
3744	    tmp = x; x = y; y = tmp;
3745	    *pcomparison = GE;
3746	    libfunc = gehf2_libfunc;
3747	  }
3748	break;
3749
3750      case UNORDERED:
3751	libfunc = unordhf2_libfunc;
3752	break;
3753
3754      default:
3755	break;
3756      }
3757  else if (mode == SFmode)
3758    switch (comparison)
3759      {
3760      case EQ:
3761	libfunc = eqsf2_libfunc;
3762	break;
3763
3764      case NE:
3765	libfunc = nesf2_libfunc;
3766	break;
3767
3768      case GT:
3769	libfunc = gtsf2_libfunc;
3770	if (libfunc == NULL_RTX)
3771	  {
3772	    tmp = x; x = y; y = tmp;
3773	    *pcomparison = LT;
3774	    libfunc = ltsf2_libfunc;
3775	  }
3776	break;
3777
3778      case GE:
3779	libfunc = gesf2_libfunc;
3780	if (libfunc == NULL_RTX)
3781	  {
3782	    tmp = x; x = y; y = tmp;
3783	    *pcomparison = LE;
3784	    libfunc = lesf2_libfunc;
3785	  }
3786	break;
3787
3788      case LT:
3789	libfunc = ltsf2_libfunc;
3790	if (libfunc == NULL_RTX)
3791	  {
3792	    tmp = x; x = y; y = tmp;
3793	    *pcomparison = GT;
3794	    libfunc = gtsf2_libfunc;
3795	  }
3796	break;
3797
3798      case LE:
3799	libfunc = lesf2_libfunc;
3800	if (libfunc == NULL_RTX)
3801	  {
3802	    tmp = x; x = y; y = tmp;
3803	    *pcomparison = GE;
3804	    libfunc = gesf2_libfunc;
3805	  }
3806	break;
3807
3808      case UNORDERED:
3809	libfunc = unordsf2_libfunc;
3810	break;
3811
3812      default:
3813	break;
3814      }
3815  else if (mode == DFmode)
3816    switch (comparison)
3817      {
3818      case EQ:
3819	libfunc = eqdf2_libfunc;
3820	break;
3821
3822      case NE:
3823	libfunc = nedf2_libfunc;
3824	break;
3825
3826      case GT:
3827	libfunc = gtdf2_libfunc;
3828	if (libfunc == NULL_RTX)
3829	  {
3830	    tmp = x; x = y; y = tmp;
3831	    *pcomparison = LT;
3832	    libfunc = ltdf2_libfunc;
3833	  }
3834	break;
3835
3836      case GE:
3837	libfunc = gedf2_libfunc;
3838	if (libfunc == NULL_RTX)
3839	  {
3840	    tmp = x; x = y; y = tmp;
3841	    *pcomparison = LE;
3842	    libfunc = ledf2_libfunc;
3843	  }
3844	break;
3845
3846      case LT:
3847	libfunc = ltdf2_libfunc;
3848	if (libfunc == NULL_RTX)
3849	  {
3850	    tmp = x; x = y; y = tmp;
3851	    *pcomparison = GT;
3852	    libfunc = gtdf2_libfunc;
3853	  }
3854	break;
3855
3856      case LE:
3857	libfunc = ledf2_libfunc;
3858	if (libfunc == NULL_RTX)
3859	  {
3860	    tmp = x; x = y; y = tmp;
3861	    *pcomparison = GE;
3862	    libfunc = gedf2_libfunc;
3863	  }
3864	break;
3865
3866      case UNORDERED:
3867	libfunc = unorddf2_libfunc;
3868	break;
3869
3870      default:
3871	break;
3872      }
3873  else if (mode == XFmode)
3874    switch (comparison)
3875      {
3876      case EQ:
3877	libfunc = eqxf2_libfunc;
3878	break;
3879
3880      case NE:
3881	libfunc = nexf2_libfunc;
3882	break;
3883
3884      case GT:
3885	libfunc = gtxf2_libfunc;
3886	if (libfunc == NULL_RTX)
3887	  {
3888	    tmp = x; x = y; y = tmp;
3889	    *pcomparison = LT;
3890	    libfunc = ltxf2_libfunc;
3891	  }
3892	break;
3893
3894      case GE:
3895	libfunc = gexf2_libfunc;
3896	if (libfunc == NULL_RTX)
3897	  {
3898	    tmp = x; x = y; y = tmp;
3899	    *pcomparison = LE;
3900	    libfunc = lexf2_libfunc;
3901	  }
3902	break;
3903
3904      case LT:
3905	libfunc = ltxf2_libfunc;
3906	if (libfunc == NULL_RTX)
3907	  {
3908	    tmp = x; x = y; y = tmp;
3909	    *pcomparison = GT;
3910	    libfunc = gtxf2_libfunc;
3911	  }
3912	break;
3913
3914      case LE:
3915	libfunc = lexf2_libfunc;
3916	if (libfunc == NULL_RTX)
3917	  {
3918	    tmp = x; x = y; y = tmp;
3919	    *pcomparison = GE;
3920	    libfunc = gexf2_libfunc;
3921	  }
3922	break;
3923
3924      case UNORDERED:
3925	libfunc = unordxf2_libfunc;
3926	break;
3927
3928      default:
3929	break;
3930      }
3931  else if (mode == TFmode)
3932    switch (comparison)
3933      {
3934      case EQ:
3935	libfunc = eqtf2_libfunc;
3936	break;
3937
3938      case NE:
3939	libfunc = netf2_libfunc;
3940	break;
3941
3942      case GT:
3943	libfunc = gttf2_libfunc;
3944	if (libfunc == NULL_RTX)
3945	  {
3946	    tmp = x; x = y; y = tmp;
3947	    *pcomparison = LT;
3948	    libfunc = lttf2_libfunc;
3949	  }
3950	break;
3951
3952      case GE:
3953	libfunc = getf2_libfunc;
3954	if (libfunc == NULL_RTX)
3955	  {
3956	    tmp = x; x = y; y = tmp;
3957	    *pcomparison = LE;
3958	    libfunc = letf2_libfunc;
3959	  }
3960	break;
3961
3962      case LT:
3963	libfunc = lttf2_libfunc;
3964	if (libfunc == NULL_RTX)
3965	  {
3966	    tmp = x; x = y; y = tmp;
3967	    *pcomparison = GT;
3968	    libfunc = gttf2_libfunc;
3969	  }
3970	break;
3971
3972      case LE:
3973	libfunc = letf2_libfunc;
3974	if (libfunc == NULL_RTX)
3975	  {
3976	    tmp = x; x = y; y = tmp;
3977	    *pcomparison = GE;
3978	    libfunc = getf2_libfunc;
3979	  }
3980	break;
3981
3982      case UNORDERED:
3983	libfunc = unordtf2_libfunc;
3984	break;
3985
3986      default:
3987	break;
3988      }
3989  else
3990    {
3991      enum machine_mode wider_mode;
3992
3993      for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3994	   wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3995	{
3996	  if ((cmp_optab->handlers[(int) wider_mode].insn_code
3997	       != CODE_FOR_nothing)
3998	      || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
3999	    {
4000	      x = protect_from_queue (x, 0);
4001	      y = protect_from_queue (y, 0);
4002	      *px = convert_to_mode (wider_mode, x, 0);
4003	      *py = convert_to_mode (wider_mode, y, 0);
4004	      prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
4005	      return;
4006	    }
4007	}
4008      abort ();
4009    }
4010
4011  if (libfunc == 0)
4012    abort ();
4013
4014  result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST_MAKE_BLOCK,
4015				    word_mode, 2, x, mode, y, mode);
4016  *px = result;
4017  *py = const0_rtx;
4018  *pmode = word_mode;
4019  if (comparison == UNORDERED)
4020    *pcomparison = NE;
4021#ifdef FLOAT_LIB_COMPARE_RETURNS_BOOL
4022  else if (FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4023    *pcomparison = NE;
4024#endif
4025  *punsignedp = 0;
4026}
4027
4028/* Generate code to indirectly jump to a location given in the rtx LOC.  */
4029
4030void
4031emit_indirect_jump (loc)
4032     rtx loc;
4033{
4034  if (! ((*insn_data[(int) CODE_FOR_indirect_jump].operand[0].predicate)
4035	 (loc, Pmode)))
4036    loc = copy_to_mode_reg (Pmode, loc);
4037
4038  emit_jump_insn (gen_indirect_jump (loc));
4039  emit_barrier ();
4040}
4041
4042#ifdef HAVE_conditional_move
4043
4044/* Emit a conditional move instruction if the machine supports one for that
4045   condition and machine mode.
4046
4047   OP0 and OP1 are the operands that should be compared using CODE.  CMODE is
4048   the mode to use should they be constants.  If it is VOIDmode, they cannot
4049   both be constants.
4050
4051   OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4052   should be stored there.  MODE is the mode to use should they be constants.
4053   If it is VOIDmode, they cannot both be constants.
4054
4055   The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4056   is not supported.  */
4057
4058rtx
4059emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
4060		       unsignedp)
4061     rtx target;
4062     enum rtx_code code;
4063     rtx op0, op1;
4064     enum machine_mode cmode;
4065     rtx op2, op3;
4066     enum machine_mode mode;
4067     int unsignedp;
4068{
4069  rtx tem, subtarget, comparison, insn;
4070  enum insn_code icode;
4071  enum rtx_code reversed;
4072
4073  /* If one operand is constant, make it the second one.  Only do this
4074     if the other operand is not constant as well.  */
4075
4076  if (swap_commutative_operands_p (op0, op1))
4077    {
4078      tem = op0;
4079      op0 = op1;
4080      op1 = tem;
4081      code = swap_condition (code);
4082    }
4083
4084  /* get_condition will prefer to generate LT and GT even if the old
4085     comparison was against zero, so undo that canonicalization here since
4086     comparisons against zero are cheaper.  */
4087  if (code == LT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == 1)
4088    code = LE, op1 = const0_rtx;
4089  else if (code == GT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == -1)
4090    code = GE, op1 = const0_rtx;
4091
4092  if (cmode == VOIDmode)
4093    cmode = GET_MODE (op0);
4094
4095  if (swap_commutative_operands_p (op2, op3)
4096      && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4097          != UNKNOWN))
4098    {
4099      tem = op2;
4100      op2 = op3;
4101      op3 = tem;
4102      code = reversed;
4103    }
4104
4105  if (mode == VOIDmode)
4106    mode = GET_MODE (op2);
4107
4108  icode = movcc_gen_code[mode];
4109
4110  if (icode == CODE_FOR_nothing)
4111    return 0;
4112
4113  if (flag_force_mem)
4114    {
4115      op2 = force_not_mem (op2);
4116      op3 = force_not_mem (op3);
4117    }
4118
4119  if (target)
4120    target = protect_from_queue (target, 1);
4121  else
4122    target = gen_reg_rtx (mode);
4123
4124  subtarget = target;
4125
4126  emit_queue ();
4127
4128  op2 = protect_from_queue (op2, 0);
4129  op3 = protect_from_queue (op3, 0);
4130
4131  /* If the insn doesn't accept these operands, put them in pseudos.  */
4132
4133  if (! (*insn_data[icode].operand[0].predicate)
4134      (subtarget, insn_data[icode].operand[0].mode))
4135    subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
4136
4137  if (! (*insn_data[icode].operand[2].predicate)
4138      (op2, insn_data[icode].operand[2].mode))
4139    op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
4140
4141  if (! (*insn_data[icode].operand[3].predicate)
4142      (op3, insn_data[icode].operand[3].mode))
4143    op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
4144
4145  /* Everything should now be in the suitable form, so emit the compare insn
4146     and then the conditional move.  */
4147
4148  comparison
4149    = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
4150
4151  /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)?  */
4152  /* We can get const0_rtx or const_true_rtx in some circumstances.  Just
4153     return NULL and let the caller figure out how best to deal with this
4154     situation.  */
4155  if (GET_CODE (comparison) != code)
4156    return NULL_RTX;
4157
4158  insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
4159
4160  /* If that failed, then give up.  */
4161  if (insn == 0)
4162    return 0;
4163
4164  emit_insn (insn);
4165
4166  if (subtarget != target)
4167    convert_move (target, subtarget, 0);
4168
4169  return target;
4170}
4171
4172/* Return nonzero if a conditional move of mode MODE is supported.
4173
4174   This function is for combine so it can tell whether an insn that looks
4175   like a conditional move is actually supported by the hardware.  If we
4176   guess wrong we lose a bit on optimization, but that's it.  */
4177/* ??? sparc64 supports conditionally moving integers values based on fp
4178   comparisons, and vice versa.  How do we handle them?  */
4179
4180int
4181can_conditionally_move_p (mode)
4182     enum machine_mode mode;
4183{
4184  if (movcc_gen_code[mode] != CODE_FOR_nothing)
4185    return 1;
4186
4187  return 0;
4188}
4189
4190#endif /* HAVE_conditional_move */
4191
4192/* These functions generate an insn body and return it
4193   rather than emitting the insn.
4194
4195   They do not protect from queued increments,
4196   because they may be used 1) in protect_from_queue itself
4197   and 2) in other passes where there is no queue.  */
4198
4199/* Generate and return an insn body to add Y to X.  */
4200
4201rtx
4202gen_add2_insn (x, y)
4203     rtx x, y;
4204{
4205  int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
4206
4207  if (! ((*insn_data[icode].operand[0].predicate)
4208	 (x, insn_data[icode].operand[0].mode))
4209      || ! ((*insn_data[icode].operand[1].predicate)
4210	    (x, insn_data[icode].operand[1].mode))
4211      || ! ((*insn_data[icode].operand[2].predicate)
4212	    (y, insn_data[icode].operand[2].mode)))
4213    abort ();
4214
4215  return (GEN_FCN (icode) (x, x, y));
4216}
4217
4218/* Generate and return an insn body to add r1 and c,
4219   storing the result in r0.  */
4220rtx
4221gen_add3_insn (r0, r1, c)
4222     rtx r0, r1, c;
4223{
4224  int icode = (int) add_optab->handlers[(int) GET_MODE (r0)].insn_code;
4225
4226  if (icode == CODE_FOR_nothing
4227      || ! ((*insn_data[icode].operand[0].predicate)
4228	    (r0, insn_data[icode].operand[0].mode))
4229      || ! ((*insn_data[icode].operand[1].predicate)
4230	    (r1, insn_data[icode].operand[1].mode))
4231      || ! ((*insn_data[icode].operand[2].predicate)
4232	    (c, insn_data[icode].operand[2].mode)))
4233    return NULL_RTX;
4234
4235  return (GEN_FCN (icode) (r0, r1, c));
4236}
4237
4238int
4239have_add2_insn (x, y)
4240     rtx x, y;
4241{
4242  int icode;
4243
4244  if (GET_MODE (x) == VOIDmode)
4245    abort ();
4246
4247  icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
4248
4249  if (icode == CODE_FOR_nothing)
4250    return 0;
4251
4252  if (! ((*insn_data[icode].operand[0].predicate)
4253	 (x, insn_data[icode].operand[0].mode))
4254      || ! ((*insn_data[icode].operand[1].predicate)
4255	    (x, insn_data[icode].operand[1].mode))
4256      || ! ((*insn_data[icode].operand[2].predicate)
4257	    (y, insn_data[icode].operand[2].mode)))
4258    return 0;
4259
4260  return 1;
4261}
4262
4263/* Generate and return an insn body to subtract Y from X.  */
4264
4265rtx
4266gen_sub2_insn (x, y)
4267     rtx x, y;
4268{
4269  int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
4270
4271  if (! ((*insn_data[icode].operand[0].predicate)
4272	 (x, insn_data[icode].operand[0].mode))
4273      || ! ((*insn_data[icode].operand[1].predicate)
4274	    (x, insn_data[icode].operand[1].mode))
4275      || ! ((*insn_data[icode].operand[2].predicate)
4276	    (y, insn_data[icode].operand[2].mode)))
4277    abort ();
4278
4279  return (GEN_FCN (icode) (x, x, y));
4280}
4281
4282/* Generate and return an insn body to subtract r1 and c,
4283   storing the result in r0.  */
4284rtx
4285gen_sub3_insn (r0, r1, c)
4286     rtx r0, r1, c;
4287{
4288  int icode = (int) sub_optab->handlers[(int) GET_MODE (r0)].insn_code;
4289
4290  if (icode == CODE_FOR_nothing
4291      || ! ((*insn_data[icode].operand[0].predicate)
4292	    (r0, insn_data[icode].operand[0].mode))
4293      || ! ((*insn_data[icode].operand[1].predicate)
4294	    (r1, insn_data[icode].operand[1].mode))
4295      || ! ((*insn_data[icode].operand[2].predicate)
4296	    (c, insn_data[icode].operand[2].mode)))
4297    return NULL_RTX;
4298
4299  return (GEN_FCN (icode) (r0, r1, c));
4300}
4301
4302int
4303have_sub2_insn (x, y)
4304     rtx x, y;
4305{
4306  int icode;
4307
4308  if (GET_MODE (x) == VOIDmode)
4309    abort ();
4310
4311  icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
4312
4313  if (icode == CODE_FOR_nothing)
4314    return 0;
4315
4316  if (! ((*insn_data[icode].operand[0].predicate)
4317	 (x, insn_data[icode].operand[0].mode))
4318      || ! ((*insn_data[icode].operand[1].predicate)
4319	    (x, insn_data[icode].operand[1].mode))
4320      || ! ((*insn_data[icode].operand[2].predicate)
4321	    (y, insn_data[icode].operand[2].mode)))
4322    return 0;
4323
4324  return 1;
4325}
4326
4327/* Generate the body of an instruction to copy Y into X.
4328   It may be a list of insns, if one insn isn't enough.  */
4329
4330rtx
4331gen_move_insn (x, y)
4332     rtx x, y;
4333{
4334  enum machine_mode mode = GET_MODE (x);
4335  enum insn_code insn_code;
4336  rtx seq;
4337
4338  if (mode == VOIDmode)
4339    mode = GET_MODE (y);
4340
4341  insn_code = mov_optab->handlers[(int) mode].insn_code;
4342
4343  /* Handle MODE_CC modes:  If we don't have a special move insn for this mode,
4344     find a mode to do it in.  If we have a movcc, use it.  Otherwise,
4345     find the MODE_INT mode of the same width.  */
4346
4347  if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
4348    {
4349      enum machine_mode tmode = VOIDmode;
4350      rtx x1 = x, y1 = y;
4351
4352      if (mode != CCmode
4353	  && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
4354	tmode = CCmode;
4355      else
4356	for (tmode = QImode; tmode != VOIDmode;
4357	     tmode = GET_MODE_WIDER_MODE (tmode))
4358	  if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
4359	    break;
4360
4361      if (tmode == VOIDmode)
4362	abort ();
4363
4364      /* Get X and Y in TMODE.  We can't use gen_lowpart here because it
4365	 may call change_address which is not appropriate if we were
4366	 called when a reload was in progress.  We don't have to worry
4367	 about changing the address since the size in bytes is supposed to
4368	 be the same.  Copy the MEM to change the mode and move any
4369	 substitutions from the old MEM to the new one.  */
4370
4371      if (reload_in_progress)
4372	{
4373	  x = gen_lowpart_common (tmode, x1);
4374	  if (x == 0 && GET_CODE (x1) == MEM)
4375	    {
4376	      x = adjust_address_nv (x1, tmode, 0);
4377	      copy_replacements (x1, x);
4378	    }
4379
4380	  y = gen_lowpart_common (tmode, y1);
4381	  if (y == 0 && GET_CODE (y1) == MEM)
4382	    {
4383	      y = adjust_address_nv (y1, tmode, 0);
4384	      copy_replacements (y1, y);
4385	    }
4386	}
4387      else
4388	{
4389	  x = gen_lowpart (tmode, x);
4390	  y = gen_lowpart (tmode, y);
4391	}
4392
4393      insn_code = mov_optab->handlers[(int) tmode].insn_code;
4394      return (GEN_FCN (insn_code) (x, y));
4395    }
4396
4397  start_sequence ();
4398  emit_move_insn_1 (x, y);
4399  seq = get_insns ();
4400  end_sequence ();
4401  return seq;
4402}
4403
4404/* Return the insn code used to extend FROM_MODE to TO_MODE.
4405   UNSIGNEDP specifies zero-extension instead of sign-extension.  If
4406   no such operation exists, CODE_FOR_nothing will be returned.  */
4407
4408enum insn_code
4409can_extend_p (to_mode, from_mode, unsignedp)
4410     enum machine_mode to_mode, from_mode;
4411     int unsignedp;
4412{
4413#ifdef HAVE_ptr_extend
4414  if (unsignedp < 0)
4415    return CODE_FOR_ptr_extend;
4416  else
4417#endif
4418    return extendtab[(int) to_mode][(int) from_mode][unsignedp != 0];
4419}
4420
4421/* Generate the body of an insn to extend Y (with mode MFROM)
4422   into X (with mode MTO).  Do zero-extension if UNSIGNEDP is nonzero.  */
4423
4424rtx
4425gen_extend_insn (x, y, mto, mfrom, unsignedp)
4426     rtx x, y;
4427     enum machine_mode mto, mfrom;
4428     int unsignedp;
4429{
4430  return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp != 0]) (x, y));
4431}
4432
4433/* can_fix_p and can_float_p say whether the target machine
4434   can directly convert a given fixed point type to
4435   a given floating point type, or vice versa.
4436   The returned value is the CODE_FOR_... value to use,
4437   or CODE_FOR_nothing if these modes cannot be directly converted.
4438
4439   *TRUNCP_PTR is set to 1 if it is necessary to output
4440   an explicit FTRUNC insn before the fix insn; otherwise 0.  */
4441
4442static enum insn_code
4443can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
4444     enum machine_mode fltmode, fixmode;
4445     int unsignedp;
4446     int *truncp_ptr;
4447{
4448  *truncp_ptr = 0;
4449  if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp != 0]
4450      != CODE_FOR_nothing)
4451    return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp != 0];
4452
4453  if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
4454    {
4455      *truncp_ptr = 1;
4456      return fixtab[(int) fltmode][(int) fixmode][unsignedp != 0];
4457    }
4458  return CODE_FOR_nothing;
4459}
4460
4461static enum insn_code
4462can_float_p (fltmode, fixmode, unsignedp)
4463     enum machine_mode fixmode, fltmode;
4464     int unsignedp;
4465{
4466  return floattab[(int) fltmode][(int) fixmode][unsignedp != 0];
4467}
4468
4469/* Generate code to convert FROM to floating point
4470   and store in TO.  FROM must be fixed point and not VOIDmode.
4471   UNSIGNEDP nonzero means regard FROM as unsigned.
4472   Normally this is done by correcting the final value
4473   if it is negative.  */
4474
4475void
4476expand_float (to, from, unsignedp)
4477     rtx to, from;
4478     int unsignedp;
4479{
4480  enum insn_code icode;
4481  rtx target = to;
4482  enum machine_mode fmode, imode;
4483
4484  /* Crash now, because we won't be able to decide which mode to use.  */
4485  if (GET_MODE (from) == VOIDmode)
4486    abort ();
4487
4488  /* Look for an insn to do the conversion.  Do it in the specified
4489     modes if possible; otherwise convert either input, output or both to
4490     wider mode.  If the integer mode is wider than the mode of FROM,
4491     we can do the conversion signed even if the input is unsigned.  */
4492
4493  for (fmode = GET_MODE (to); fmode != VOIDmode;
4494       fmode = GET_MODE_WIDER_MODE (fmode))
4495    for (imode = GET_MODE (from); imode != VOIDmode;
4496	 imode = GET_MODE_WIDER_MODE (imode))
4497      {
4498	int doing_unsigned = unsignedp;
4499
4500	if (fmode != GET_MODE (to)
4501	    && significand_size (fmode) < GET_MODE_BITSIZE (GET_MODE (from)))
4502	  continue;
4503
4504	icode = can_float_p (fmode, imode, unsignedp);
4505	if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
4506	  icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
4507
4508	if (icode != CODE_FOR_nothing)
4509	  {
4510	    to = protect_from_queue (to, 1);
4511	    from = protect_from_queue (from, 0);
4512
4513	    if (imode != GET_MODE (from))
4514	      from = convert_to_mode (imode, from, unsignedp);
4515
4516	    if (fmode != GET_MODE (to))
4517	      target = gen_reg_rtx (fmode);
4518
4519	    emit_unop_insn (icode, target, from,
4520			    doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
4521
4522	    if (target != to)
4523	      convert_move (to, target, 0);
4524	    return;
4525	  }
4526      }
4527
4528  /* Unsigned integer, and no way to convert directly.
4529     Convert as signed, then conditionally adjust the result.  */
4530  if (unsignedp)
4531    {
4532      rtx label = gen_label_rtx ();
4533      rtx temp;
4534      REAL_VALUE_TYPE offset;
4535
4536      emit_queue ();
4537
4538      to = protect_from_queue (to, 1);
4539      from = protect_from_queue (from, 0);
4540
4541      if (flag_force_mem)
4542	from = force_not_mem (from);
4543
4544      /* Look for a usable floating mode FMODE wider than the source and at
4545	 least as wide as the target.  Using FMODE will avoid rounding woes
4546	 with unsigned values greater than the signed maximum value.  */
4547
4548      for (fmode = GET_MODE (to);  fmode != VOIDmode;
4549	   fmode = GET_MODE_WIDER_MODE (fmode))
4550	if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
4551	    && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
4552	  break;
4553
4554      if (fmode == VOIDmode)
4555	{
4556	  /* There is no such mode.  Pretend the target is wide enough.  */
4557	  fmode = GET_MODE (to);
4558
4559	  /* Avoid double-rounding when TO is narrower than FROM.  */
4560	  if ((significand_size (fmode) + 1)
4561	      < GET_MODE_BITSIZE (GET_MODE (from)))
4562	    {
4563	      rtx temp1;
4564	      rtx neglabel = gen_label_rtx ();
4565
4566	      /* Don't use TARGET if it isn't a register, is a hard register,
4567		 or is the wrong mode.  */
4568	      if (GET_CODE (target) != REG
4569		  || REGNO (target) < FIRST_PSEUDO_REGISTER
4570		  || GET_MODE (target) != fmode)
4571		target = gen_reg_rtx (fmode);
4572
4573	      imode = GET_MODE (from);
4574	      do_pending_stack_adjust ();
4575
4576	      /* Test whether the sign bit is set.  */
4577	      emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
4578				       0, neglabel);
4579
4580	      /* The sign bit is not set.  Convert as signed.  */
4581	      expand_float (target, from, 0);
4582	      emit_jump_insn (gen_jump (label));
4583	      emit_barrier ();
4584
4585	      /* The sign bit is set.
4586		 Convert to a usable (positive signed) value by shifting right
4587		 one bit, while remembering if a nonzero bit was shifted
4588		 out; i.e., compute  (from & 1) | (from >> 1).  */
4589
4590	      emit_label (neglabel);
4591	      temp = expand_binop (imode, and_optab, from, const1_rtx,
4592				   NULL_RTX, 1, OPTAB_LIB_WIDEN);
4593	      temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
4594				    NULL_RTX, 1);
4595	      temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
4596				   OPTAB_LIB_WIDEN);
4597	      expand_float (target, temp, 0);
4598
4599	      /* Multiply by 2 to undo the shift above.  */
4600	      temp = expand_binop (fmode, add_optab, target, target,
4601				   target, 0, OPTAB_LIB_WIDEN);
4602	      if (temp != target)
4603		emit_move_insn (target, temp);
4604
4605	      do_pending_stack_adjust ();
4606	      emit_label (label);
4607	      goto done;
4608	    }
4609	}
4610
4611      /* If we are about to do some arithmetic to correct for an
4612	 unsigned operand, do it in a pseudo-register.  */
4613
4614      if (GET_MODE (to) != fmode
4615	  || GET_CODE (to) != REG || REGNO (to) < FIRST_PSEUDO_REGISTER)
4616	target = gen_reg_rtx (fmode);
4617
4618      /* Convert as signed integer to floating.  */
4619      expand_float (target, from, 0);
4620
4621      /* If FROM is negative (and therefore TO is negative),
4622	 correct its value by 2**bitwidth.  */
4623
4624      do_pending_stack_adjust ();
4625      emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
4626			       0, label);
4627
4628
4629      real_2expN (&offset, GET_MODE_BITSIZE (GET_MODE (from)));
4630      temp = expand_binop (fmode, add_optab, target,
4631			   CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
4632			   target, 0, OPTAB_LIB_WIDEN);
4633      if (temp != target)
4634	emit_move_insn (target, temp);
4635
4636      do_pending_stack_adjust ();
4637      emit_label (label);
4638      goto done;
4639    }
4640
4641  /* No hardware instruction available; call a library routine to convert from
4642     SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode.  */
4643    {
4644      rtx libfcn;
4645      rtx insns;
4646      rtx value;
4647
4648      to = protect_from_queue (to, 1);
4649      from = protect_from_queue (from, 0);
4650
4651      if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
4652	from = convert_to_mode (SImode, from, unsignedp);
4653
4654      if (flag_force_mem)
4655	from = force_not_mem (from);
4656
4657      if (GET_MODE (to) == SFmode)
4658	{
4659	  if (GET_MODE (from) == SImode)
4660	    libfcn = floatsisf_libfunc;
4661	  else if (GET_MODE (from) == DImode)
4662	    libfcn = floatdisf_libfunc;
4663	  else if (GET_MODE (from) == TImode)
4664	    libfcn = floattisf_libfunc;
4665	  else
4666	    abort ();
4667	}
4668      else if (GET_MODE (to) == DFmode)
4669	{
4670	  if (GET_MODE (from) == SImode)
4671	    libfcn = floatsidf_libfunc;
4672	  else if (GET_MODE (from) == DImode)
4673	    libfcn = floatdidf_libfunc;
4674	  else if (GET_MODE (from) == TImode)
4675	    libfcn = floattidf_libfunc;
4676	  else
4677	    abort ();
4678	}
4679      else if (GET_MODE (to) == XFmode)
4680	{
4681	  if (GET_MODE (from) == SImode)
4682	    libfcn = floatsixf_libfunc;
4683	  else if (GET_MODE (from) == DImode)
4684	    libfcn = floatdixf_libfunc;
4685	  else if (GET_MODE (from) == TImode)
4686	    libfcn = floattixf_libfunc;
4687	  else
4688	    abort ();
4689	}
4690      else if (GET_MODE (to) == TFmode)
4691	{
4692	  if (GET_MODE (from) == SImode)
4693	    libfcn = floatsitf_libfunc;
4694	  else if (GET_MODE (from) == DImode)
4695	    libfcn = floatditf_libfunc;
4696	  else if (GET_MODE (from) == TImode)
4697	    libfcn = floattitf_libfunc;
4698	  else
4699	    abort ();
4700	}
4701      else
4702	abort ();
4703
4704      start_sequence ();
4705
4706      value = emit_library_call_value (libfcn, NULL_RTX, LCT_CONST,
4707				       GET_MODE (to), 1, from,
4708				       GET_MODE (from));
4709      insns = get_insns ();
4710      end_sequence ();
4711
4712      emit_libcall_block (insns, target, value,
4713			  gen_rtx_FLOAT (GET_MODE (to), from));
4714    }
4715
4716 done:
4717
4718  /* Copy result to requested destination
4719     if we have been computing in a temp location.  */
4720
4721  if (target != to)
4722    {
4723      if (GET_MODE (target) == GET_MODE (to))
4724	emit_move_insn (to, target);
4725      else
4726	convert_move (to, target, 0);
4727    }
4728}
4729
4730/* expand_fix: generate code to convert FROM to fixed point
4731   and store in TO.  FROM must be floating point.  */
4732
4733static rtx
4734ftruncify (x)
4735     rtx x;
4736{
4737  rtx temp = gen_reg_rtx (GET_MODE (x));
4738  return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
4739}
4740
4741void
4742expand_fix (to, from, unsignedp)
4743     rtx to, from;
4744     int unsignedp;
4745{
4746  enum insn_code icode;
4747  rtx target = to;
4748  enum machine_mode fmode, imode;
4749  int must_trunc = 0;
4750  rtx libfcn = 0;
4751
4752  /* We first try to find a pair of modes, one real and one integer, at
4753     least as wide as FROM and TO, respectively, in which we can open-code
4754     this conversion.  If the integer mode is wider than the mode of TO,
4755     we can do the conversion either signed or unsigned.  */
4756
4757  for (fmode = GET_MODE (from); fmode != VOIDmode;
4758       fmode = GET_MODE_WIDER_MODE (fmode))
4759    for (imode = GET_MODE (to); imode != VOIDmode;
4760	 imode = GET_MODE_WIDER_MODE (imode))
4761      {
4762	int doing_unsigned = unsignedp;
4763
4764	icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
4765	if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
4766	  icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
4767
4768	if (icode != CODE_FOR_nothing)
4769	  {
4770	    to = protect_from_queue (to, 1);
4771	    from = protect_from_queue (from, 0);
4772
4773	    if (fmode != GET_MODE (from))
4774	      from = convert_to_mode (fmode, from, 0);
4775
4776	    if (must_trunc)
4777	      from = ftruncify (from);
4778
4779	    if (imode != GET_MODE (to))
4780	      target = gen_reg_rtx (imode);
4781
4782	    emit_unop_insn (icode, target, from,
4783			    doing_unsigned ? UNSIGNED_FIX : FIX);
4784	    if (target != to)
4785	      convert_move (to, target, unsignedp);
4786	    return;
4787	  }
4788      }
4789
4790  /* For an unsigned conversion, there is one more way to do it.
4791     If we have a signed conversion, we generate code that compares
4792     the real value to the largest representable positive number.  If if
4793     is smaller, the conversion is done normally.  Otherwise, subtract
4794     one plus the highest signed number, convert, and add it back.
4795
4796     We only need to check all real modes, since we know we didn't find
4797     anything with a wider integer mode.  */
4798
4799  if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
4800    for (fmode = GET_MODE (from); fmode != VOIDmode;
4801	 fmode = GET_MODE_WIDER_MODE (fmode))
4802      /* Make sure we won't lose significant bits doing this.  */
4803      if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
4804	  && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
4805					    &must_trunc))
4806	{
4807	  int bitsize;
4808	  REAL_VALUE_TYPE offset;
4809	  rtx limit, lab1, lab2, insn;
4810
4811	  bitsize = GET_MODE_BITSIZE (GET_MODE (to));
4812	  real_2expN (&offset, bitsize - 1);
4813	  limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
4814	  lab1 = gen_label_rtx ();
4815	  lab2 = gen_label_rtx ();
4816
4817	  emit_queue ();
4818	  to = protect_from_queue (to, 1);
4819	  from = protect_from_queue (from, 0);
4820
4821	  if (flag_force_mem)
4822	    from = force_not_mem (from);
4823
4824	  if (fmode != GET_MODE (from))
4825	    from = convert_to_mode (fmode, from, 0);
4826
4827	  /* See if we need to do the subtraction.  */
4828	  do_pending_stack_adjust ();
4829	  emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
4830				   0, lab1);
4831
4832	  /* If not, do the signed "fix" and branch around fixup code.  */
4833	  expand_fix (to, from, 0);
4834	  emit_jump_insn (gen_jump (lab2));
4835	  emit_barrier ();
4836
4837	  /* Otherwise, subtract 2**(N-1), convert to signed number,
4838	     then add 2**(N-1).  Do the addition using XOR since this
4839	     will often generate better code.  */
4840	  emit_label (lab1);
4841	  target = expand_binop (GET_MODE (from), sub_optab, from, limit,
4842				 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4843	  expand_fix (to, target, 0);
4844	  target = expand_binop (GET_MODE (to), xor_optab, to,
4845				 gen_int_mode
4846				 ((HOST_WIDE_INT) 1 << (bitsize - 1),
4847				  GET_MODE (to)),
4848				 to, 1, OPTAB_LIB_WIDEN);
4849
4850	  if (target != to)
4851	    emit_move_insn (to, target);
4852
4853	  emit_label (lab2);
4854
4855	  if (mov_optab->handlers[(int) GET_MODE (to)].insn_code
4856	      != CODE_FOR_nothing)
4857	    {
4858	      /* Make a place for a REG_NOTE and add it.  */
4859	      insn = emit_move_insn (to, to);
4860	      set_unique_reg_note (insn,
4861	                           REG_EQUAL,
4862				   gen_rtx_fmt_e (UNSIGNED_FIX,
4863						  GET_MODE (to),
4864						  copy_rtx (from)));
4865	    }
4866
4867	  return;
4868	}
4869
4870  /* We can't do it with an insn, so use a library call.  But first ensure
4871     that the mode of TO is at least as wide as SImode, since those are the
4872     only library calls we know about.  */
4873
4874  if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
4875    {
4876      target = gen_reg_rtx (SImode);
4877
4878      expand_fix (target, from, unsignedp);
4879    }
4880  else if (GET_MODE (from) == SFmode)
4881    {
4882      if (GET_MODE (to) == SImode)
4883	libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
4884      else if (GET_MODE (to) == DImode)
4885	libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
4886      else if (GET_MODE (to) == TImode)
4887	libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
4888      else
4889	abort ();
4890    }
4891  else if (GET_MODE (from) == DFmode)
4892    {
4893      if (GET_MODE (to) == SImode)
4894	libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
4895      else if (GET_MODE (to) == DImode)
4896	libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
4897      else if (GET_MODE (to) == TImode)
4898	libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
4899      else
4900	abort ();
4901    }
4902  else if (GET_MODE (from) == XFmode)
4903    {
4904      if (GET_MODE (to) == SImode)
4905	libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
4906      else if (GET_MODE (to) == DImode)
4907	libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
4908      else if (GET_MODE (to) == TImode)
4909	libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
4910      else
4911	abort ();
4912    }
4913  else if (GET_MODE (from) == TFmode)
4914    {
4915      if (GET_MODE (to) == SImode)
4916	libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
4917      else if (GET_MODE (to) == DImode)
4918	libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
4919      else if (GET_MODE (to) == TImode)
4920	libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
4921      else
4922	abort ();
4923    }
4924  else
4925    abort ();
4926
4927  if (libfcn)
4928    {
4929      rtx insns;
4930      rtx value;
4931
4932      to = protect_from_queue (to, 1);
4933      from = protect_from_queue (from, 0);
4934
4935      if (flag_force_mem)
4936	from = force_not_mem (from);
4937
4938      start_sequence ();
4939
4940      value = emit_library_call_value (libfcn, NULL_RTX, LCT_CONST,
4941				       GET_MODE (to), 1, from,
4942				       GET_MODE (from));
4943      insns = get_insns ();
4944      end_sequence ();
4945
4946      emit_libcall_block (insns, target, value,
4947			  gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
4948					 GET_MODE (to), from));
4949    }
4950
4951  if (target != to)
4952    {
4953      if (GET_MODE (to) == GET_MODE (target))
4954        emit_move_insn (to, target);
4955      else
4956        convert_move (to, target, 0);
4957    }
4958}
4959
4960/* Report whether we have an instruction to perform the operation
4961   specified by CODE on operands of mode MODE.  */
4962int
4963have_insn_for (code, mode)
4964     enum rtx_code code;
4965     enum machine_mode mode;
4966{
4967  return (code_to_optab[(int) code] != 0
4968	  && (code_to_optab[(int) code]->handlers[(int) mode].insn_code
4969	      != CODE_FOR_nothing));
4970}
4971
4972/* Create a blank optab.  */
4973static optab
4974new_optab ()
4975{
4976  int i;
4977  optab op = (optab) ggc_alloc (sizeof (struct optab));
4978  for (i = 0; i < NUM_MACHINE_MODES; i++)
4979    {
4980      op->handlers[i].insn_code = CODE_FOR_nothing;
4981      op->handlers[i].libfunc = 0;
4982    }
4983
4984  return op;
4985}
4986
4987/* Same, but fill in its code as CODE, and write it into the
4988   code_to_optab table.  */
4989static inline optab
4990init_optab (code)
4991     enum rtx_code code;
4992{
4993  optab op = new_optab ();
4994  op->code = code;
4995  code_to_optab[(int) code] = op;
4996  return op;
4997}
4998
4999/* Same, but fill in its code as CODE, and do _not_ write it into
5000   the code_to_optab table.  */
5001static inline optab
5002init_optabv (code)
5003     enum rtx_code code;
5004{
5005  optab op = new_optab ();
5006  op->code = code;
5007  return op;
5008}
5009
5010/* Initialize the libfunc fields of an entire group of entries in some
5011   optab.  Each entry is set equal to a string consisting of a leading
5012   pair of underscores followed by a generic operation name followed by
5013   a mode name (downshifted to lower case) followed by a single character
5014   representing the number of operands for the given operation (which is
5015   usually one of the characters '2', '3', or '4').
5016
5017   OPTABLE is the table in which libfunc fields are to be initialized.
5018   FIRST_MODE is the first machine mode index in the given optab to
5019     initialize.
5020   LAST_MODE is the last machine mode index in the given optab to
5021     initialize.
5022   OPNAME is the generic (string) name of the operation.
5023   SUFFIX is the character which specifies the number of operands for
5024     the given generic operation.
5025*/
5026
5027static void
5028init_libfuncs (optable, first_mode, last_mode, opname, suffix)
5029     optab optable;
5030     int first_mode;
5031     int last_mode;
5032     const char *opname;
5033     int suffix;
5034{
5035  int mode;
5036  unsigned opname_len = strlen (opname);
5037
5038  for (mode = first_mode; (int) mode <= (int) last_mode;
5039       mode = (enum machine_mode) ((int) mode + 1))
5040    {
5041      const char *mname = GET_MODE_NAME (mode);
5042      unsigned mname_len = strlen (mname);
5043      char *libfunc_name = alloca (2 + opname_len + mname_len + 1 + 1);
5044      char *p;
5045      const char *q;
5046
5047      p = libfunc_name;
5048      *p++ = '_';
5049      *p++ = '_';
5050      for (q = opname; *q; )
5051	*p++ = *q++;
5052      for (q = mname; *q; q++)
5053	*p++ = TOLOWER (*q);
5054      *p++ = suffix;
5055      *p = '\0';
5056
5057      optable->handlers[(int) mode].libfunc
5058	= gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (libfunc_name,
5059						       p - libfunc_name));
5060    }
5061}
5062
5063/* Initialize the libfunc fields of an entire group of entries in some
5064   optab which correspond to all integer mode operations.  The parameters
5065   have the same meaning as similarly named ones for the `init_libfuncs'
5066   routine.  (See above).  */
5067
5068static void
5069init_integral_libfuncs (optable, opname, suffix)
5070     optab optable;
5071     const char *opname;
5072     int suffix;
5073{
5074  init_libfuncs (optable, SImode, TImode, opname, suffix);
5075}
5076
5077/* Initialize the libfunc fields of an entire group of entries in some
5078   optab which correspond to all real mode operations.  The parameters
5079   have the same meaning as similarly named ones for the `init_libfuncs'
5080   routine.  (See above).  */
5081
5082static void
5083init_floating_libfuncs (optable, opname, suffix)
5084     optab optable;
5085     const char *opname;
5086     int suffix;
5087{
5088  init_libfuncs (optable, SFmode, TFmode, opname, suffix);
5089}
5090
5091rtx
5092init_one_libfunc (name)
5093     const char *name;
5094{
5095  /* Create a FUNCTION_DECL that can be passed to
5096     targetm.encode_section_info.  */
5097  /* ??? We don't have any type information except for this is
5098     a function.  Pretend this is "int foo()".  */
5099  tree decl = build_decl (FUNCTION_DECL, get_identifier (name),
5100			  build_function_type (integer_type_node, NULL_TREE));
5101  DECL_ARTIFICIAL (decl) = 1;
5102  DECL_EXTERNAL (decl) = 1;
5103  TREE_PUBLIC (decl) = 1;
5104
5105  /* Return the symbol_ref from the mem rtx.  */
5106  return XEXP (DECL_RTL (decl), 0);
5107}
5108
5109/* Call this once to initialize the contents of the optabs
5110   appropriately for the current target machine.  */
5111
5112void
5113init_optabs ()
5114{
5115  unsigned int i, j, k;
5116
5117  /* Start by initializing all tables to contain CODE_FOR_nothing.  */
5118
5119  for (i = 0; i < ARRAY_SIZE (fixtab); i++)
5120    for (j = 0; j < ARRAY_SIZE (fixtab[0]); j++)
5121      for (k = 0; k < ARRAY_SIZE (fixtab[0][0]); k++)
5122	fixtab[i][j][k] = CODE_FOR_nothing;
5123
5124  for (i = 0; i < ARRAY_SIZE (fixtrunctab); i++)
5125    for (j = 0; j < ARRAY_SIZE (fixtrunctab[0]); j++)
5126      for (k = 0; k < ARRAY_SIZE (fixtrunctab[0][0]); k++)
5127	fixtrunctab[i][j][k] = CODE_FOR_nothing;
5128
5129  for (i = 0; i < ARRAY_SIZE (floattab); i++)
5130    for (j = 0; j < ARRAY_SIZE (floattab[0]); j++)
5131      for (k = 0; k < ARRAY_SIZE (floattab[0][0]); k++)
5132	floattab[i][j][k] = CODE_FOR_nothing;
5133
5134  for (i = 0; i < ARRAY_SIZE (extendtab); i++)
5135    for (j = 0; j < ARRAY_SIZE (extendtab[0]); j++)
5136      for (k = 0; k < ARRAY_SIZE (extendtab[0][0]); k++)
5137	extendtab[i][j][k] = CODE_FOR_nothing;
5138
5139  for (i = 0; i < NUM_RTX_CODE; i++)
5140    setcc_gen_code[i] = CODE_FOR_nothing;
5141
5142#ifdef HAVE_conditional_move
5143  for (i = 0; i < NUM_MACHINE_MODES; i++)
5144    movcc_gen_code[i] = CODE_FOR_nothing;
5145#endif
5146
5147  add_optab = init_optab (PLUS);
5148  addv_optab = init_optabv (PLUS);
5149  sub_optab = init_optab (MINUS);
5150  subv_optab = init_optabv (MINUS);
5151  smul_optab = init_optab (MULT);
5152  smulv_optab = init_optabv (MULT);
5153  smul_highpart_optab = init_optab (UNKNOWN);
5154  umul_highpart_optab = init_optab (UNKNOWN);
5155  smul_widen_optab = init_optab (UNKNOWN);
5156  umul_widen_optab = init_optab (UNKNOWN);
5157  sdiv_optab = init_optab (DIV);
5158  sdivv_optab = init_optabv (DIV);
5159  sdivmod_optab = init_optab (UNKNOWN);
5160  udiv_optab = init_optab (UDIV);
5161  udivmod_optab = init_optab (UNKNOWN);
5162  smod_optab = init_optab (MOD);
5163  umod_optab = init_optab (UMOD);
5164  ftrunc_optab = init_optab (UNKNOWN);
5165  and_optab = init_optab (AND);
5166  ior_optab = init_optab (IOR);
5167  xor_optab = init_optab (XOR);
5168  ashl_optab = init_optab (ASHIFT);
5169  ashr_optab = init_optab (ASHIFTRT);
5170  lshr_optab = init_optab (LSHIFTRT);
5171  rotl_optab = init_optab (ROTATE);
5172  rotr_optab = init_optab (ROTATERT);
5173  smin_optab = init_optab (SMIN);
5174  smax_optab = init_optab (SMAX);
5175  umin_optab = init_optab (UMIN);
5176  umax_optab = init_optab (UMAX);
5177
5178  /* These three have codes assigned exclusively for the sake of
5179     have_insn_for.  */
5180  mov_optab = init_optab (SET);
5181  movstrict_optab = init_optab (STRICT_LOW_PART);
5182  cmp_optab = init_optab (COMPARE);
5183
5184  ucmp_optab = init_optab (UNKNOWN);
5185  tst_optab = init_optab (UNKNOWN);
5186  neg_optab = init_optab (NEG);
5187  negv_optab = init_optabv (NEG);
5188  abs_optab = init_optab (ABS);
5189  absv_optab = init_optabv (ABS);
5190  one_cmpl_optab = init_optab (NOT);
5191  ffs_optab = init_optab (FFS);
5192  sqrt_optab = init_optab (SQRT);
5193  sin_optab = init_optab (UNKNOWN);
5194  cos_optab = init_optab (UNKNOWN);
5195  exp_optab = init_optab (UNKNOWN);
5196  log_optab = init_optab (UNKNOWN);
5197  strlen_optab = init_optab (UNKNOWN);
5198  cbranch_optab = init_optab (UNKNOWN);
5199  cmov_optab = init_optab (UNKNOWN);
5200  cstore_optab = init_optab (UNKNOWN);
5201  push_optab = init_optab (UNKNOWN);
5202
5203  for (i = 0; i < NUM_MACHINE_MODES; i++)
5204    {
5205      movstr_optab[i] = CODE_FOR_nothing;
5206      clrstr_optab[i] = CODE_FOR_nothing;
5207
5208#ifdef HAVE_SECONDARY_RELOADS
5209      reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
5210#endif
5211    }
5212
5213  /* Fill in the optabs with the insns we support.  */
5214  init_all_optabs ();
5215
5216#ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
5217  /* This flag says the same insns that convert to a signed fixnum
5218     also convert validly to an unsigned one.  */
5219  for (i = 0; i < NUM_MACHINE_MODES; i++)
5220    for (j = 0; j < NUM_MACHINE_MODES; j++)
5221      fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
5222#endif
5223
5224  /* Initialize the optabs with the names of the library functions.  */
5225  init_integral_libfuncs (add_optab, "add", '3');
5226  init_floating_libfuncs (add_optab, "add", '3');
5227  init_integral_libfuncs (addv_optab, "addv", '3');
5228  init_floating_libfuncs (addv_optab, "add", '3');
5229  init_integral_libfuncs (sub_optab, "sub", '3');
5230  init_floating_libfuncs (sub_optab, "sub", '3');
5231  init_integral_libfuncs (subv_optab, "subv", '3');
5232  init_floating_libfuncs (subv_optab, "sub", '3');
5233  init_integral_libfuncs (smul_optab, "mul", '3');
5234  init_floating_libfuncs (smul_optab, "mul", '3');
5235  init_integral_libfuncs (smulv_optab, "mulv", '3');
5236  init_floating_libfuncs (smulv_optab, "mul", '3');
5237  init_integral_libfuncs (sdiv_optab, "div", '3');
5238  init_floating_libfuncs (sdiv_optab, "div", '3');
5239  init_integral_libfuncs (sdivv_optab, "divv", '3');
5240  init_integral_libfuncs (udiv_optab, "udiv", '3');
5241  init_integral_libfuncs (sdivmod_optab, "divmod", '4');
5242  init_integral_libfuncs (udivmod_optab, "udivmod", '4');
5243  init_integral_libfuncs (smod_optab, "mod", '3');
5244  init_integral_libfuncs (umod_optab, "umod", '3');
5245  init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
5246  init_integral_libfuncs (and_optab, "and", '3');
5247  init_integral_libfuncs (ior_optab, "ior", '3');
5248  init_integral_libfuncs (xor_optab, "xor", '3');
5249  init_integral_libfuncs (ashl_optab, "ashl", '3');
5250  init_integral_libfuncs (ashr_optab, "ashr", '3');
5251  init_integral_libfuncs (lshr_optab, "lshr", '3');
5252  init_integral_libfuncs (smin_optab, "min", '3');
5253  init_floating_libfuncs (smin_optab, "min", '3');
5254  init_integral_libfuncs (smax_optab, "max", '3');
5255  init_floating_libfuncs (smax_optab, "max", '3');
5256  init_integral_libfuncs (umin_optab, "umin", '3');
5257  init_integral_libfuncs (umax_optab, "umax", '3');
5258  init_integral_libfuncs (neg_optab, "neg", '2');
5259  init_floating_libfuncs (neg_optab, "neg", '2');
5260  init_integral_libfuncs (negv_optab, "negv", '2');
5261  init_floating_libfuncs (negv_optab, "neg", '2');
5262  init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
5263  init_integral_libfuncs (ffs_optab, "ffs", '2');
5264
5265  /* Comparison libcalls for integers MUST come in pairs, signed/unsigned.  */
5266  init_integral_libfuncs (cmp_optab, "cmp", '2');
5267  init_integral_libfuncs (ucmp_optab, "ucmp", '2');
5268  init_floating_libfuncs (cmp_optab, "cmp", '2');
5269
5270#ifdef MULSI3_LIBCALL
5271  smul_optab->handlers[(int) SImode].libfunc
5272    = init_one_libfunc (MULSI3_LIBCALL);
5273#endif
5274#ifdef MULDI3_LIBCALL
5275  smul_optab->handlers[(int) DImode].libfunc
5276    = init_one_libfunc (MULDI3_LIBCALL);
5277#endif
5278
5279#ifdef DIVSI3_LIBCALL
5280  sdiv_optab->handlers[(int) SImode].libfunc
5281    = init_one_libfunc (DIVSI3_LIBCALL);
5282#endif
5283#ifdef DIVDI3_LIBCALL
5284  sdiv_optab->handlers[(int) DImode].libfunc
5285    = init_one_libfunc (DIVDI3_LIBCALL);
5286#endif
5287
5288#ifdef UDIVSI3_LIBCALL
5289  udiv_optab->handlers[(int) SImode].libfunc
5290    = init_one_libfunc (UDIVSI3_LIBCALL);
5291#endif
5292#ifdef UDIVDI3_LIBCALL
5293  udiv_optab->handlers[(int) DImode].libfunc
5294    = init_one_libfunc (UDIVDI3_LIBCALL);
5295#endif
5296
5297#ifdef MODSI3_LIBCALL
5298  smod_optab->handlers[(int) SImode].libfunc
5299    = init_one_libfunc (MODSI3_LIBCALL);
5300#endif
5301#ifdef MODDI3_LIBCALL
5302  smod_optab->handlers[(int) DImode].libfunc
5303    = init_one_libfunc (MODDI3_LIBCALL);
5304#endif
5305
5306#ifdef UMODSI3_LIBCALL
5307  umod_optab->handlers[(int) SImode].libfunc
5308    = init_one_libfunc (UMODSI3_LIBCALL);
5309#endif
5310#ifdef UMODDI3_LIBCALL
5311  umod_optab->handlers[(int) DImode].libfunc
5312    = init_one_libfunc (UMODDI3_LIBCALL);
5313#endif
5314
5315  /* Use cabs for DC complex abs, since systems generally have cabs.
5316     Don't define any libcall for SCmode, so that cabs will be used.  */
5317  abs_optab->handlers[(int) DCmode].libfunc
5318    = init_one_libfunc ("cabs");
5319
5320  /* The ffs function operates on `int'.  */
5321  ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)].libfunc
5322    = init_one_libfunc ("ffs");
5323
5324  extendsfdf2_libfunc = init_one_libfunc ("__extendsfdf2");
5325  extendsfxf2_libfunc = init_one_libfunc ("__extendsfxf2");
5326  extendsftf2_libfunc = init_one_libfunc ("__extendsftf2");
5327  extenddfxf2_libfunc = init_one_libfunc ("__extenddfxf2");
5328  extenddftf2_libfunc = init_one_libfunc ("__extenddftf2");
5329
5330  truncdfsf2_libfunc = init_one_libfunc ("__truncdfsf2");
5331  truncxfsf2_libfunc = init_one_libfunc ("__truncxfsf2");
5332  trunctfsf2_libfunc = init_one_libfunc ("__trunctfsf2");
5333  truncxfdf2_libfunc = init_one_libfunc ("__truncxfdf2");
5334  trunctfdf2_libfunc = init_one_libfunc ("__trunctfdf2");
5335
5336  abort_libfunc = init_one_libfunc ("abort");
5337  memcpy_libfunc = init_one_libfunc ("memcpy");
5338  memmove_libfunc = init_one_libfunc ("memmove");
5339  bcopy_libfunc = init_one_libfunc ("bcopy");
5340  memcmp_libfunc = init_one_libfunc ("memcmp");
5341  bcmp_libfunc = init_one_libfunc ("__gcc_bcmp");
5342  memset_libfunc = init_one_libfunc ("memset");
5343  bzero_libfunc = init_one_libfunc ("bzero");
5344
5345  unwind_resume_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
5346					    ? "_Unwind_SjLj_Resume"
5347					    : "_Unwind_Resume");
5348#ifndef DONT_USE_BUILTIN_SETJMP
5349  setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
5350  longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
5351#else
5352  setjmp_libfunc = init_one_libfunc ("setjmp");
5353  longjmp_libfunc = init_one_libfunc ("longjmp");
5354#endif
5355  unwind_sjlj_register_libfunc = init_one_libfunc ("_Unwind_SjLj_Register");
5356  unwind_sjlj_unregister_libfunc
5357    = init_one_libfunc ("_Unwind_SjLj_Unregister");
5358
5359  eqhf2_libfunc = init_one_libfunc ("__eqhf2");
5360  nehf2_libfunc = init_one_libfunc ("__nehf2");
5361  gthf2_libfunc = init_one_libfunc ("__gthf2");
5362  gehf2_libfunc = init_one_libfunc ("__gehf2");
5363  lthf2_libfunc = init_one_libfunc ("__lthf2");
5364  lehf2_libfunc = init_one_libfunc ("__lehf2");
5365  unordhf2_libfunc = init_one_libfunc ("__unordhf2");
5366
5367  eqsf2_libfunc = init_one_libfunc ("__eqsf2");
5368  nesf2_libfunc = init_one_libfunc ("__nesf2");
5369  gtsf2_libfunc = init_one_libfunc ("__gtsf2");
5370  gesf2_libfunc = init_one_libfunc ("__gesf2");
5371  ltsf2_libfunc = init_one_libfunc ("__ltsf2");
5372  lesf2_libfunc = init_one_libfunc ("__lesf2");
5373  unordsf2_libfunc = init_one_libfunc ("__unordsf2");
5374
5375  eqdf2_libfunc = init_one_libfunc ("__eqdf2");
5376  nedf2_libfunc = init_one_libfunc ("__nedf2");
5377  gtdf2_libfunc = init_one_libfunc ("__gtdf2");
5378  gedf2_libfunc = init_one_libfunc ("__gedf2");
5379  ltdf2_libfunc = init_one_libfunc ("__ltdf2");
5380  ledf2_libfunc = init_one_libfunc ("__ledf2");
5381  unorddf2_libfunc = init_one_libfunc ("__unorddf2");
5382
5383  eqxf2_libfunc = init_one_libfunc ("__eqxf2");
5384  nexf2_libfunc = init_one_libfunc ("__nexf2");
5385  gtxf2_libfunc = init_one_libfunc ("__gtxf2");
5386  gexf2_libfunc = init_one_libfunc ("__gexf2");
5387  ltxf2_libfunc = init_one_libfunc ("__ltxf2");
5388  lexf2_libfunc = init_one_libfunc ("__lexf2");
5389  unordxf2_libfunc = init_one_libfunc ("__unordxf2");
5390
5391  eqtf2_libfunc = init_one_libfunc ("__eqtf2");
5392  netf2_libfunc = init_one_libfunc ("__netf2");
5393  gttf2_libfunc = init_one_libfunc ("__gttf2");
5394  getf2_libfunc = init_one_libfunc ("__getf2");
5395  lttf2_libfunc = init_one_libfunc ("__lttf2");
5396  letf2_libfunc = init_one_libfunc ("__letf2");
5397  unordtf2_libfunc = init_one_libfunc ("__unordtf2");
5398
5399  floatsisf_libfunc = init_one_libfunc ("__floatsisf");
5400  floatdisf_libfunc = init_one_libfunc ("__floatdisf");
5401  floattisf_libfunc = init_one_libfunc ("__floattisf");
5402
5403  floatsidf_libfunc = init_one_libfunc ("__floatsidf");
5404  floatdidf_libfunc = init_one_libfunc ("__floatdidf");
5405  floattidf_libfunc = init_one_libfunc ("__floattidf");
5406
5407  floatsixf_libfunc = init_one_libfunc ("__floatsixf");
5408  floatdixf_libfunc = init_one_libfunc ("__floatdixf");
5409  floattixf_libfunc = init_one_libfunc ("__floattixf");
5410
5411  floatsitf_libfunc = init_one_libfunc ("__floatsitf");
5412  floatditf_libfunc = init_one_libfunc ("__floatditf");
5413  floattitf_libfunc = init_one_libfunc ("__floattitf");
5414
5415  fixsfsi_libfunc = init_one_libfunc ("__fixsfsi");
5416  fixsfdi_libfunc = init_one_libfunc ("__fixsfdi");
5417  fixsfti_libfunc = init_one_libfunc ("__fixsfti");
5418
5419  fixdfsi_libfunc = init_one_libfunc ("__fixdfsi");
5420  fixdfdi_libfunc = init_one_libfunc ("__fixdfdi");
5421  fixdfti_libfunc = init_one_libfunc ("__fixdfti");
5422
5423  fixxfsi_libfunc = init_one_libfunc ("__fixxfsi");
5424  fixxfdi_libfunc = init_one_libfunc ("__fixxfdi");
5425  fixxfti_libfunc = init_one_libfunc ("__fixxfti");
5426
5427  fixtfsi_libfunc = init_one_libfunc ("__fixtfsi");
5428  fixtfdi_libfunc = init_one_libfunc ("__fixtfdi");
5429  fixtfti_libfunc = init_one_libfunc ("__fixtfti");
5430
5431  fixunssfsi_libfunc = init_one_libfunc ("__fixunssfsi");
5432  fixunssfdi_libfunc = init_one_libfunc ("__fixunssfdi");
5433  fixunssfti_libfunc = init_one_libfunc ("__fixunssfti");
5434
5435  fixunsdfsi_libfunc = init_one_libfunc ("__fixunsdfsi");
5436  fixunsdfdi_libfunc = init_one_libfunc ("__fixunsdfdi");
5437  fixunsdfti_libfunc = init_one_libfunc ("__fixunsdfti");
5438
5439  fixunsxfsi_libfunc = init_one_libfunc ("__fixunsxfsi");
5440  fixunsxfdi_libfunc = init_one_libfunc ("__fixunsxfdi");
5441  fixunsxfti_libfunc = init_one_libfunc ("__fixunsxfti");
5442
5443  fixunstfsi_libfunc = init_one_libfunc ("__fixunstfsi");
5444  fixunstfdi_libfunc = init_one_libfunc ("__fixunstfdi");
5445  fixunstfti_libfunc = init_one_libfunc ("__fixunstfti");
5446
5447  /* For function entry/exit instrumentation.  */
5448  profile_function_entry_libfunc
5449    = init_one_libfunc ("__cyg_profile_func_enter");
5450  profile_function_exit_libfunc
5451    = init_one_libfunc ("__cyg_profile_func_exit");
5452
5453  if (HAVE_conditional_trap)
5454    trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
5455
5456#ifdef INIT_TARGET_OPTABS
5457  /* Allow the target to add more libcalls or rename some, etc.  */
5458  INIT_TARGET_OPTABS;
5459#endif
5460}
5461
5462/* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
5463   CODE.  Return 0 on failure.  */
5464
5465rtx
5466gen_cond_trap (code, op1, op2, tcode)
5467     enum rtx_code code ATTRIBUTE_UNUSED;
5468     rtx op1, op2 ATTRIBUTE_UNUSED, tcode ATTRIBUTE_UNUSED;
5469{
5470  enum machine_mode mode = GET_MODE (op1);
5471  enum insn_code icode;
5472  rtx insn;
5473
5474  if (!HAVE_conditional_trap)
5475    return 0;
5476
5477  if (mode == VOIDmode)
5478    return 0;
5479
5480  icode = cmp_optab->handlers[(int) mode].insn_code;
5481  if (icode == CODE_FOR_nothing)
5482    return 0;
5483
5484  start_sequence ();
5485  op1 = prepare_operand (icode, op1, 0, mode, mode, 0);
5486  op2 = prepare_operand (icode, op2, 0, mode, mode, 0);
5487  emit_insn (GEN_FCN (icode) (op1, op2));
5488
5489  PUT_CODE (trap_rtx, code);
5490  insn = gen_conditional_trap (trap_rtx, tcode);
5491  if (insn)
5492    {
5493      emit_insn (insn);
5494      insn = get_insns ();
5495    }
5496  end_sequence ();
5497
5498  return insn;
5499}
5500
5501#include "gt-optabs.h"
5502