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