OSDN Git Service

* sbitmap.c: Fix comment formatting.
[pf3gnuchains/gcc-fork.git] / gcc / simplify-rtx.c
1 /* RTL simplification functions for GNU compiler.
2    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3    1999, 2000, 2001 Free Software Foundation, Inc.
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING.  If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22
23 #include "config.h"
24 #include "system.h"
25
26 #include "rtl.h"
27 #include "tm_p.h"
28 #include "regs.h"
29 #include "hard-reg-set.h"
30 #include "flags.h"
31 #include "real.h"
32 #include "insn-config.h"
33 #include "recog.h"
34 #include "function.h"
35 #include "expr.h"
36 #include "optabs.h"
37 #include "toplev.h"
38 #include "output.h"
39 #include "ggc.h"
40
41 /* Simplification and canonicalization of RTL.  */
42
43 /* Nonzero if X has the form (PLUS frame-pointer integer).  We check for
44    virtual regs here because the simplify_*_operation routines are called
45    by integrate.c, which is called before virtual register instantiation.
46
47    ?!? FIXED_BASE_PLUS_P and NONZERO_BASE_PLUS_P need to move into 
48    a header file so that their definitions can be shared with the
49    simplification routines in simplify-rtx.c.  Until then, do not
50    change these macros without also changing the copy in simplify-rtx.c.  */
51
52 #define FIXED_BASE_PLUS_P(X)                                    \
53   ((X) == frame_pointer_rtx || (X) == hard_frame_pointer_rtx    \
54    || ((X) == arg_pointer_rtx && fixed_regs[ARG_POINTER_REGNUM])\
55    || (X) == virtual_stack_vars_rtx                             \
56    || (X) == virtual_incoming_args_rtx                          \
57    || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \
58        && (XEXP (X, 0) == frame_pointer_rtx                     \
59            || XEXP (X, 0) == hard_frame_pointer_rtx             \
60            || ((X) == arg_pointer_rtx                           \
61                && fixed_regs[ARG_POINTER_REGNUM])               \
62            || XEXP (X, 0) == virtual_stack_vars_rtx             \
63            || XEXP (X, 0) == virtual_incoming_args_rtx))        \
64    || GET_CODE (X) == ADDRESSOF)
65
66 /* Similar, but also allows reference to the stack pointer.
67
68    This used to include FIXED_BASE_PLUS_P, however, we can't assume that
69    arg_pointer_rtx by itself is nonzero, because on at least one machine,
70    the i960, the arg pointer is zero when it is unused.  */
71
72 #define NONZERO_BASE_PLUS_P(X)                                  \
73   ((X) == frame_pointer_rtx || (X) == hard_frame_pointer_rtx    \
74    || (X) == virtual_stack_vars_rtx                             \
75    || (X) == virtual_incoming_args_rtx                          \
76    || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \
77        && (XEXP (X, 0) == frame_pointer_rtx                     \
78            || XEXP (X, 0) == hard_frame_pointer_rtx             \
79            || ((X) == arg_pointer_rtx                           \
80                && fixed_regs[ARG_POINTER_REGNUM])               \
81            || XEXP (X, 0) == virtual_stack_vars_rtx             \
82            || XEXP (X, 0) == virtual_incoming_args_rtx))        \
83    || (X) == stack_pointer_rtx                                  \
84    || (X) == virtual_stack_dynamic_rtx                          \
85    || (X) == virtual_outgoing_args_rtx                          \
86    || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \
87        && (XEXP (X, 0) == stack_pointer_rtx                     \
88            || XEXP (X, 0) == virtual_stack_dynamic_rtx          \
89            || XEXP (X, 0) == virtual_outgoing_args_rtx))        \
90    || GET_CODE (X) == ADDRESSOF)
91
92 /* Much code operates on (low, high) pairs; the low value is an
93    unsigned wide int, the high value a signed wide int.  We
94    occasionally need to sign extend from low to high as if low were a
95    signed wide int.  */
96 #define HWI_SIGN_EXTEND(low) \
97  ((((HOST_WIDE_INT) low) < 0) ? ((HOST_WIDE_INT) -1) : ((HOST_WIDE_INT) 0))
98
99 static rtx simplify_plus_minus          PARAMS ((enum rtx_code,
100                                                  enum machine_mode, rtx, rtx));
101 static void check_fold_consts           PARAMS ((PTR));
102 #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
103 static void simplify_unary_real         PARAMS ((PTR));
104 static void simplify_binary_real        PARAMS ((PTR));
105 #endif
106 static void simplify_binary_is2orm1     PARAMS ((PTR));
107
108 \f
109 /* Make a binary operation by properly ordering the operands and 
110    seeing if the expression folds.  */
111
112 rtx
113 simplify_gen_binary (code, mode, op0, op1)
114      enum rtx_code code;
115      enum machine_mode mode;
116      rtx op0, op1;
117 {
118   rtx tem;
119
120   /* Put complex operands first and constants second if commutative.  */
121   if (GET_RTX_CLASS (code) == 'c'
122       && swap_commutative_operands_p (op0, op1))
123     tem = op0, op0 = op1, op1 = tem;
124
125   /* If this simplifies, do it.  */
126   tem = simplify_binary_operation (code, mode, op0, op1);
127
128   if (tem)
129     return tem;
130
131   /* Handle addition and subtraction of CONST_INT specially.  Otherwise,
132      just form the operation.  */
133
134   if (code == PLUS && GET_CODE (op1) == CONST_INT
135       && GET_MODE (op0) != VOIDmode)
136     return plus_constant (op0, INTVAL (op1));
137   else if (code == MINUS && GET_CODE (op1) == CONST_INT
138            && GET_MODE (op0) != VOIDmode)
139     return plus_constant (op0, - INTVAL (op1));
140   else
141     return gen_rtx_fmt_ee (code, mode, op0, op1);
142 }
143 \f
144 /* If X is a MEM referencing the constant pool, return the real value.
145    Otherwise return X.  */
146 rtx
147 avoid_constant_pool_reference (x)
148      rtx x;
149 {
150   rtx c, addr;
151   enum machine_mode cmode;
152
153   if (GET_CODE (x) != MEM)
154     return x;
155   addr = XEXP (x, 0);
156
157   if (GET_CODE (addr) != SYMBOL_REF
158       || ! CONSTANT_POOL_ADDRESS_P (addr))
159     return x;
160
161   c = get_pool_constant (addr);
162   cmode = get_pool_mode (addr);
163
164   /* If we're accessing the constant in a different mode than it was
165      originally stored, attempt to fix that up via subreg simplifications.
166      If that fails we have no choice but to return the original memory.  */
167   if (cmode != GET_MODE (x))
168     {
169       c = simplify_subreg (GET_MODE (x), c, cmode, 0);
170       return c ? c : x;
171     }
172
173   return c;
174 }
175 \f
176 /* Make a unary operation by first seeing if it folds and otherwise making
177    the specified operation.  */
178
179 rtx
180 simplify_gen_unary (code, mode, op, op_mode)
181      enum rtx_code code;
182      enum machine_mode mode;
183      rtx op;
184      enum machine_mode op_mode;
185 {
186   rtx tem;
187
188   /* If this simplifies, use it.  */
189   if ((tem = simplify_unary_operation (code, mode, op, op_mode)) != 0)
190     return tem;
191
192   return gen_rtx_fmt_e (code, mode, op);
193 }
194
195 /* Likewise for ternary operations.  */
196
197 rtx
198 simplify_gen_ternary (code, mode, op0_mode, op0, op1, op2)
199      enum rtx_code code;
200      enum machine_mode mode, op0_mode;
201      rtx op0, op1, op2;
202 {
203   rtx tem;
204
205   /* If this simplifies, use it.  */
206   if (0 != (tem = simplify_ternary_operation (code, mode, op0_mode,
207                                               op0, op1, op2)))
208     return tem;
209
210   return gen_rtx_fmt_eee (code, mode, op0, op1, op2);
211 }
212 \f
213 /* Likewise, for relational operations.
214    CMP_MODE specifies mode comparison is done in.
215   */
216
217 rtx
218 simplify_gen_relational (code, mode, cmp_mode, op0, op1)
219      enum rtx_code code;
220      enum machine_mode mode;
221      enum machine_mode cmp_mode;
222      rtx op0, op1;
223 {
224   rtx tem;
225
226   if ((tem = simplify_relational_operation (code, cmp_mode, op0, op1)) != 0)
227     return tem;
228
229   /* Put complex operands first and constants second.  */
230   if (swap_commutative_operands_p (op0, op1))
231     tem = op0, op0 = op1, op1 = tem, code = swap_condition (code);
232
233   return gen_rtx_fmt_ee (code, mode, op0, op1);
234 }
235 \f
236 /* Replace all occurrences of OLD in X with NEW and try to simplify the
237    resulting RTX.  Return a new RTX which is as simplified as possible.  */
238
239 rtx
240 simplify_replace_rtx (x, old, new)
241      rtx x;
242      rtx old;
243      rtx new;
244 {
245   enum rtx_code code = GET_CODE (x);
246   enum machine_mode mode = GET_MODE (x);
247
248   /* If X is OLD, return NEW.  Otherwise, if this is an expression, try
249      to build a new expression substituting recursively.  If we can't do
250      anything, return our input.  */
251
252   if (x == old)
253     return new;
254
255   switch (GET_RTX_CLASS (code))
256     {
257     case '1':
258       {
259         enum machine_mode op_mode = GET_MODE (XEXP (x, 0));
260         rtx op = (XEXP (x, 0) == old
261                   ? new : simplify_replace_rtx (XEXP (x, 0), old, new));
262
263         return simplify_gen_unary (code, mode, op, op_mode);
264       }
265
266     case '2':
267     case 'c':
268       return
269         simplify_gen_binary (code, mode,
270                              simplify_replace_rtx (XEXP (x, 0), old, new),
271                              simplify_replace_rtx (XEXP (x, 1), old, new));
272     case '<':
273       {
274         enum machine_mode op_mode = (GET_MODE (XEXP (x, 0)) != VOIDmode
275                                      ? GET_MODE (XEXP (x, 0))
276                                      : GET_MODE (XEXP (x, 1)));
277         rtx op0 = simplify_replace_rtx (XEXP (x, 0), old, new);
278         rtx op1 = simplify_replace_rtx (XEXP (x, 1), old, new);
279
280         return
281           simplify_gen_relational (code, mode,
282                                    (op_mode != VOIDmode
283                                     ? op_mode
284                                     : GET_MODE (op0) != VOIDmode
285                                     ? GET_MODE (op0)
286                                     : GET_MODE (op1)),
287                                    op0, op1);
288       }
289
290     case '3':
291     case 'b':
292       {
293         enum machine_mode op_mode = GET_MODE (XEXP (x, 0));
294         rtx op0 = simplify_replace_rtx (XEXP (x, 0), old, new);
295
296         return
297           simplify_gen_ternary (code, mode, 
298                                 (op_mode != VOIDmode
299                                  ? op_mode
300                                  : GET_MODE (op0)),
301                                 op0,
302                                 simplify_replace_rtx (XEXP (x, 1), old, new),
303                                 simplify_replace_rtx (XEXP (x, 2), old, new));
304       }
305
306     case 'x':
307       /* The only case we try to handle is a SUBREG.  */
308       if (code == SUBREG)
309         {
310           rtx exp;
311           exp = simplify_gen_subreg (GET_MODE (x),
312                                      simplify_replace_rtx (SUBREG_REG (x),
313                                                            old, new),
314                                      GET_MODE (SUBREG_REG (x)),
315                                      SUBREG_BYTE (x));
316           if (exp)
317            x = exp;
318         }
319       return x;
320
321     default:
322       if (GET_CODE (x) == MEM)
323         return
324           replace_equiv_address_nv (x,
325                                     simplify_replace_rtx (XEXP (x, 0),
326                                                           old, new));
327
328       return x;
329     }
330   return x;
331 }
332 \f
333 #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
334 /* Subroutine of simplify_unary_operation, called via do_float_handler.
335    Handles simplification of unary ops on floating point values.  */
336 struct simplify_unary_real_args
337 {
338   rtx operand;
339   rtx result;
340   enum machine_mode mode;
341   enum rtx_code code;
342   bool want_integer;
343 };
344 #define REAL_VALUE_ABS(d_) \
345    (REAL_VALUE_NEGATIVE (d_) ? REAL_VALUE_NEGATE (d_) : (d_))
346
347 static void
348 simplify_unary_real (p)
349      PTR p;
350 {
351   REAL_VALUE_TYPE d;
352
353   struct simplify_unary_real_args *args =
354     (struct simplify_unary_real_args *) p;
355
356   REAL_VALUE_FROM_CONST_DOUBLE (d, args->operand);
357
358   if (args->want_integer)
359     {
360       HOST_WIDE_INT i;
361
362       switch (args->code)
363         {
364         case FIX:               i = REAL_VALUE_FIX (d);           break;
365         case UNSIGNED_FIX:      i = REAL_VALUE_UNSIGNED_FIX (d);  break;
366         default:
367           abort ();
368         }
369       args->result = GEN_INT (trunc_int_for_mode (i, args->mode));
370     }
371   else
372     {
373       switch (args->code)
374         {
375         case SQRT:
376           /* We don't attempt to optimize this.  */
377           args->result = 0;
378           return;
379
380         case ABS:             d = REAL_VALUE_ABS (d);                   break;
381         case NEG:             d = REAL_VALUE_NEGATE (d);                break;
382         case FLOAT_TRUNCATE:  d = real_value_truncate (args->mode, d);  break;
383         case FLOAT_EXTEND:    /* All this does is change the mode.  */  break;
384         case FIX:             d = REAL_VALUE_RNDZINT (d);               break;
385         case UNSIGNED_FIX:    d = REAL_VALUE_UNSIGNED_RNDZINT (d);      break;
386         default:
387           abort ();
388         }
389       args->result = CONST_DOUBLE_FROM_REAL_VALUE (d, args->mode);
390     }
391 }
392 #endif
393
394 /* Try to simplify a unary operation CODE whose output mode is to be
395    MODE with input operand OP whose mode was originally OP_MODE.
396    Return zero if no simplification can be made.  */
397 rtx
398 simplify_unary_operation (code, mode, op, op_mode)
399      enum rtx_code code;
400      enum machine_mode mode;
401      rtx op;
402      enum machine_mode op_mode;
403 {
404   unsigned int width = GET_MODE_BITSIZE (mode);
405   rtx trueop = avoid_constant_pool_reference (op);
406
407   /* The order of these tests is critical so that, for example, we don't
408      check the wrong mode (input vs. output) for a conversion operation,
409      such as FIX.  At some point, this should be simplified.  */
410
411 #if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
412
413   if (code == FLOAT && GET_MODE (trueop) == VOIDmode
414       && (GET_CODE (trueop) == CONST_DOUBLE || GET_CODE (trueop) == CONST_INT))
415     {
416       HOST_WIDE_INT hv, lv;
417       REAL_VALUE_TYPE d;
418
419       if (GET_CODE (trueop) == CONST_INT)
420         lv = INTVAL (trueop), hv = HWI_SIGN_EXTEND (lv);
421       else
422         lv = CONST_DOUBLE_LOW (trueop),  hv = CONST_DOUBLE_HIGH (trueop);
423
424 #ifdef REAL_ARITHMETIC
425       REAL_VALUE_FROM_INT (d, lv, hv, mode);
426 #else
427       if (hv < 0)
428         {
429           d = (double) (~ hv);
430           d *= ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))
431                 * (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)));
432           d += (double) (unsigned HOST_WIDE_INT) (~ lv);
433           d = (- d - 1.0);
434         }
435       else
436         {
437           d = (double) hv;
438           d *= ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))
439                 * (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)));
440           d += (double) (unsigned HOST_WIDE_INT) lv;
441         }
442 #endif  /* REAL_ARITHMETIC */
443       d = real_value_truncate (mode, d);
444       return CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
445     }
446   else if (code == UNSIGNED_FLOAT && GET_MODE (trueop) == VOIDmode
447            && (GET_CODE (trueop) == CONST_DOUBLE
448                || GET_CODE (trueop) == CONST_INT))
449     {
450       HOST_WIDE_INT hv, lv;
451       REAL_VALUE_TYPE d;
452
453       if (GET_CODE (trueop) == CONST_INT)
454         lv = INTVAL (trueop), hv = HWI_SIGN_EXTEND (lv);
455       else
456         lv = CONST_DOUBLE_LOW (trueop),  hv = CONST_DOUBLE_HIGH (trueop);
457
458       if (op_mode == VOIDmode)
459         {
460           /* We don't know how to interpret negative-looking numbers in
461              this case, so don't try to fold those.  */
462           if (hv < 0)
463             return 0;
464         }
465       else if (GET_MODE_BITSIZE (op_mode) >= HOST_BITS_PER_WIDE_INT * 2)
466         ;
467       else
468         hv = 0, lv &= GET_MODE_MASK (op_mode);
469
470 #ifdef REAL_ARITHMETIC
471       REAL_VALUE_FROM_UNSIGNED_INT (d, lv, hv, mode);
472 #else
473
474       d = (double) (unsigned HOST_WIDE_INT) hv;
475       d *= ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))
476             * (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)));
477       d += (double) (unsigned HOST_WIDE_INT) lv;
478 #endif  /* REAL_ARITHMETIC */
479       d = real_value_truncate (mode, d);
480       return CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
481     }
482 #endif
483
484   if (GET_CODE (trueop) == CONST_INT
485       && width <= HOST_BITS_PER_WIDE_INT && width > 0)
486     {
487       register HOST_WIDE_INT arg0 = INTVAL (trueop);
488       register HOST_WIDE_INT val;
489
490       switch (code)
491         {
492         case NOT:
493           val = ~ arg0;
494           break;
495
496         case NEG:
497           val = - arg0;
498           break;
499
500         case ABS:
501           val = (arg0 >= 0 ? arg0 : - arg0);
502           break;
503
504         case FFS:
505           /* Don't use ffs here.  Instead, get low order bit and then its
506              number.  If arg0 is zero, this will return 0, as desired.  */
507           arg0 &= GET_MODE_MASK (mode);
508           val = exact_log2 (arg0 & (- arg0)) + 1;
509           break;
510
511         case TRUNCATE:
512           val = arg0;
513           break;
514
515         case ZERO_EXTEND:
516           if (op_mode == VOIDmode)
517             op_mode = mode;
518           if (GET_MODE_BITSIZE (op_mode) == HOST_BITS_PER_WIDE_INT)
519             {
520               /* If we were really extending the mode,
521                  we would have to distinguish between zero-extension
522                  and sign-extension.  */
523               if (width != GET_MODE_BITSIZE (op_mode))
524                 abort ();
525               val = arg0;
526             }
527           else if (GET_MODE_BITSIZE (op_mode) < HOST_BITS_PER_WIDE_INT)
528             val = arg0 & ~((HOST_WIDE_INT) (-1) << GET_MODE_BITSIZE (op_mode));
529           else
530             return 0;
531           break;
532
533         case SIGN_EXTEND:
534           if (op_mode == VOIDmode)
535             op_mode = mode;
536           if (GET_MODE_BITSIZE (op_mode) == HOST_BITS_PER_WIDE_INT)
537             {
538               /* If we were really extending the mode,
539                  we would have to distinguish between zero-extension
540                  and sign-extension.  */
541               if (width != GET_MODE_BITSIZE (op_mode))
542                 abort ();
543               val = arg0;
544             }
545           else if (GET_MODE_BITSIZE (op_mode) < HOST_BITS_PER_WIDE_INT)
546             {
547               val
548                 = arg0 & ~((HOST_WIDE_INT) (-1) << GET_MODE_BITSIZE (op_mode));
549               if (val
550                   & ((HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (op_mode) - 1)))
551                 val -= (HOST_WIDE_INT) 1 << GET_MODE_BITSIZE (op_mode);
552             }
553           else
554             return 0;
555           break;
556
557         case SQRT:
558         case FLOAT_EXTEND:
559         case FLOAT_TRUNCATE:
560           return 0;
561
562         default:
563           abort ();
564         }
565
566       val = trunc_int_for_mode (val, mode);
567
568       return GEN_INT (val);
569     }
570
571   /* We can do some operations on integer CONST_DOUBLEs.  Also allow
572      for a DImode operation on a CONST_INT.  */
573   else if (GET_MODE (trueop) == VOIDmode && width <= HOST_BITS_PER_INT * 2
574            && (GET_CODE (trueop) == CONST_DOUBLE
575                || GET_CODE (trueop) == CONST_INT))
576     {
577       unsigned HOST_WIDE_INT l1, lv;
578       HOST_WIDE_INT h1, hv;
579
580       if (GET_CODE (trueop) == CONST_DOUBLE)
581         l1 = CONST_DOUBLE_LOW (trueop), h1 = CONST_DOUBLE_HIGH (trueop);
582       else
583         l1 = INTVAL (trueop), h1 = HWI_SIGN_EXTEND (l1);
584
585       switch (code)
586         {
587         case NOT:
588           lv = ~ l1;
589           hv = ~ h1;
590           break;
591
592         case NEG:
593           neg_double (l1, h1, &lv, &hv);
594           break;
595
596         case ABS:
597           if (h1 < 0)
598             neg_double (l1, h1, &lv, &hv);
599           else
600             lv = l1, hv = h1;
601           break;
602
603         case FFS:
604           hv = 0;
605           if (l1 == 0)
606             lv = HOST_BITS_PER_WIDE_INT + exact_log2 (h1 & (-h1)) + 1;
607           else
608             lv = exact_log2 (l1 & (-l1)) + 1;
609           break;
610
611         case TRUNCATE:
612           /* This is just a change-of-mode, so do nothing.  */
613           lv = l1, hv = h1;
614           break;
615
616         case ZERO_EXTEND:
617           if (op_mode == VOIDmode
618               || GET_MODE_BITSIZE (op_mode) > HOST_BITS_PER_WIDE_INT)
619             return 0;
620
621           hv = 0;
622           lv = l1 & GET_MODE_MASK (op_mode);
623           break;
624
625         case SIGN_EXTEND:
626           if (op_mode == VOIDmode
627               || GET_MODE_BITSIZE (op_mode) > HOST_BITS_PER_WIDE_INT)
628             return 0;
629           else
630             {
631               lv = l1 & GET_MODE_MASK (op_mode);
632               if (GET_MODE_BITSIZE (op_mode) < HOST_BITS_PER_WIDE_INT
633                   && (lv & ((HOST_WIDE_INT) 1
634                             << (GET_MODE_BITSIZE (op_mode) - 1))) != 0)
635                 lv -= (HOST_WIDE_INT) 1 << GET_MODE_BITSIZE (op_mode);
636
637               hv = HWI_SIGN_EXTEND (lv);
638             }
639           break;
640
641         case SQRT:
642           return 0;
643
644         default:
645           return 0;
646         }
647
648       return immed_double_const (lv, hv, mode);
649     }
650
651 #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
652   else if (GET_CODE (trueop) == CONST_DOUBLE
653            && GET_MODE_CLASS (mode) == MODE_FLOAT)
654     {
655       struct simplify_unary_real_args args;
656       args.operand = trueop;
657       args.mode = mode;
658       args.code = code;
659       args.want_integer = false;
660
661       if (do_float_handler (simplify_unary_real, (PTR) &args))
662         return args.result;
663
664       return 0;
665     }
666
667   else if (GET_CODE (trueop) == CONST_DOUBLE
668            && GET_MODE_CLASS (GET_MODE (trueop)) == MODE_FLOAT
669            && GET_MODE_CLASS (mode) == MODE_INT
670            && width <= HOST_BITS_PER_WIDE_INT && width > 0)
671     {
672       struct simplify_unary_real_args args;
673       args.operand = trueop;
674       args.mode = mode;
675       args.code = code;
676       args.want_integer = true;
677
678       if (do_float_handler (simplify_unary_real, (PTR) &args))
679         return args.result;
680
681       return 0;
682     }
683 #endif
684   /* This was formerly used only for non-IEEE float.
685      eggert@twinsun.com says it is safe for IEEE also.  */
686   else
687     {
688       enum rtx_code reversed;
689       /* There are some simplifications we can do even if the operands
690          aren't constant.  */
691       switch (code)
692         {
693         case NOT:
694           /* (not (not X)) == X.  */
695           if (GET_CODE (op) == NOT)
696             return XEXP (op, 0);
697
698           /* (not (eq X Y)) == (ne X Y), etc.  */
699           if (mode == BImode && GET_RTX_CLASS (GET_CODE (op)) == '<'
700               && ((reversed = reversed_comparison_code (op, NULL_RTX))
701                   != UNKNOWN))
702             return gen_rtx_fmt_ee (reversed,
703                                    op_mode, XEXP (op, 0), XEXP (op, 1));
704           break;
705
706         case NEG:
707           /* (neg (neg X)) == X.  */
708           if (GET_CODE (op) == NEG)
709             return XEXP (op, 0);
710           break;
711
712         case SIGN_EXTEND:
713           /* (sign_extend (truncate (minus (label_ref L1) (label_ref L2))))
714              becomes just the MINUS if its mode is MODE.  This allows
715              folding switch statements on machines using casesi (such as
716              the VAX).  */
717           if (GET_CODE (op) == TRUNCATE
718               && GET_MODE (XEXP (op, 0)) == mode
719               && GET_CODE (XEXP (op, 0)) == MINUS
720               && GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF
721               && GET_CODE (XEXP (XEXP (op, 0), 1)) == LABEL_REF)
722             return XEXP (op, 0);
723
724 #if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
725           if (! POINTERS_EXTEND_UNSIGNED
726               && mode == Pmode && GET_MODE (op) == ptr_mode
727               && (CONSTANT_P (op)
728                   || (GET_CODE (op) == SUBREG
729                       && GET_CODE (SUBREG_REG (op)) == REG
730                       && REG_POINTER (SUBREG_REG (op))
731                       && GET_MODE (SUBREG_REG (op)) == Pmode)))
732             return convert_memory_address (Pmode, op);
733 #endif
734           break;
735
736 #if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
737         case ZERO_EXTEND:
738           if (POINTERS_EXTEND_UNSIGNED > 0
739               && mode == Pmode && GET_MODE (op) == ptr_mode
740               && (CONSTANT_P (op)
741                   || (GET_CODE (op) == SUBREG
742                       && GET_CODE (SUBREG_REG (op)) == REG
743                       && REG_POINTER (SUBREG_REG (op))
744                       && GET_MODE (SUBREG_REG (op)) == Pmode)))
745             return convert_memory_address (Pmode, op);
746           break;
747 #endif
748           
749         default:
750           break;
751         }
752
753       return 0;
754     }
755 }
756 \f
757 #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
758 /* Subroutine of simplify_binary_operation, called via do_float_handler.
759    Handles simplification of binary ops on floating point values.  */
760 struct simplify_binary_real_args
761 {
762   rtx trueop0, trueop1;
763   rtx result;
764   enum rtx_code code;
765   enum machine_mode mode;
766 };
767
768 static void
769 simplify_binary_real (p)
770      PTR p;
771 {
772   REAL_VALUE_TYPE f0, f1, value;
773   struct simplify_binary_real_args *args =
774     (struct simplify_binary_real_args *) p;
775
776   REAL_VALUE_FROM_CONST_DOUBLE (f0, args->trueop0);
777   REAL_VALUE_FROM_CONST_DOUBLE (f1, args->trueop1);
778   f0 = real_value_truncate (args->mode, f0);
779   f1 = real_value_truncate (args->mode, f1);
780
781 #ifdef REAL_ARITHMETIC
782 #ifndef REAL_INFINITY
783   if (args->code == DIV && REAL_VALUES_EQUAL (f1, dconst0))
784     {
785       args->result = 0;
786       return;
787     }
788 #endif
789   REAL_ARITHMETIC (value, rtx_to_tree_code (args->code), f0, f1);
790 #else
791   switch (args->code)
792     {
793     case PLUS:
794       value = f0 + f1;
795       break;
796     case MINUS:
797       value = f0 - f1;
798       break;
799     case MULT:
800       value = f0 * f1;
801       break;
802     case DIV:
803 #ifndef REAL_INFINITY
804       if (f1 == 0)
805         return 0;
806 #endif
807       value = f0 / f1;
808       break;
809     case SMIN:
810       value = MIN (f0, f1);
811       break;
812     case SMAX:
813       value = MAX (f0, f1);
814       break;
815     default:
816       abort ();
817     }
818 #endif
819
820   value = real_value_truncate (args->mode, value);
821   args->result = CONST_DOUBLE_FROM_REAL_VALUE (value, args->mode);
822 }
823 #endif
824
825 /* Another subroutine called via do_float_handler.  This one tests
826    the floating point value given against 2. and -1.  */
827 struct simplify_binary_is2orm1_args
828 {
829   rtx value;
830   bool is_2;
831   bool is_m1;
832 };
833
834 static void
835 simplify_binary_is2orm1 (p)
836      PTR p;
837 {
838   REAL_VALUE_TYPE d;
839   struct simplify_binary_is2orm1_args *args =
840     (struct simplify_binary_is2orm1_args *) p;
841
842   REAL_VALUE_FROM_CONST_DOUBLE (d, args->value);
843   args->is_2 = REAL_VALUES_EQUAL (d, dconst2);
844   args->is_m1 = REAL_VALUES_EQUAL (d, dconstm1);
845 }
846
847 /* Simplify a binary operation CODE with result mode MODE, operating on OP0
848    and OP1.  Return 0 if no simplification is possible.
849
850    Don't use this for relational operations such as EQ or LT.
851    Use simplify_relational_operation instead.  */
852 rtx
853 simplify_binary_operation (code, mode, op0, op1)
854      enum rtx_code code;
855      enum machine_mode mode;
856      rtx op0, op1;
857 {
858   register HOST_WIDE_INT arg0, arg1, arg0s, arg1s;
859   HOST_WIDE_INT val;
860   unsigned int width = GET_MODE_BITSIZE (mode);
861   rtx tem;
862   rtx trueop0 = avoid_constant_pool_reference (op0);
863   rtx trueop1 = avoid_constant_pool_reference (op1);
864
865   /* Relational operations don't work here.  We must know the mode
866      of the operands in order to do the comparison correctly.
867      Assuming a full word can give incorrect results.
868      Consider comparing 128 with -128 in QImode.  */
869
870   if (GET_RTX_CLASS (code) == '<')
871     abort ();
872
873   /* Make sure the constant is second.  */
874   if (GET_RTX_CLASS (code) == 'c'
875       && swap_commutative_operands_p (trueop0, trueop1))
876     {
877       tem = op0, op0 = op1, op1 = tem;
878       tem = trueop0, trueop0 = trueop1, trueop1 = tem;
879     }
880
881 #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
882   if (GET_MODE_CLASS (mode) == MODE_FLOAT
883       && GET_CODE (trueop0) == CONST_DOUBLE
884       && GET_CODE (trueop1) == CONST_DOUBLE
885       && mode == GET_MODE (op0) && mode == GET_MODE (op1))
886     {
887       struct simplify_binary_real_args args;
888       args.trueop0 = trueop0;
889       args.trueop1 = trueop1;
890       args.mode = mode;
891       args.code = code;
892
893       if (do_float_handler (simplify_binary_real, (PTR) &args))
894         return args.result;
895       return 0;
896     }
897 #endif  /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */
898
899   /* We can fold some multi-word operations.  */
900   if (GET_MODE_CLASS (mode) == MODE_INT
901       && width == HOST_BITS_PER_WIDE_INT * 2
902       && (GET_CODE (trueop0) == CONST_DOUBLE
903           || GET_CODE (trueop0) == CONST_INT)
904       && (GET_CODE (trueop1) == CONST_DOUBLE
905           || GET_CODE (trueop1) == CONST_INT))
906     {
907       unsigned HOST_WIDE_INT l1, l2, lv;
908       HOST_WIDE_INT h1, h2, hv;
909
910       if (GET_CODE (trueop0) == CONST_DOUBLE)
911         l1 = CONST_DOUBLE_LOW (trueop0), h1 = CONST_DOUBLE_HIGH (trueop0);
912       else
913         l1 = INTVAL (trueop0), h1 = HWI_SIGN_EXTEND (l1);
914
915       if (GET_CODE (trueop1) == CONST_DOUBLE)
916         l2 = CONST_DOUBLE_LOW (trueop1), h2 = CONST_DOUBLE_HIGH (trueop1);
917       else
918         l2 = INTVAL (trueop1), h2 = HWI_SIGN_EXTEND (l2);
919
920       switch (code)
921         {
922         case MINUS:
923           /* A - B == A + (-B).  */
924           neg_double (l2, h2, &lv, &hv);
925           l2 = lv, h2 = hv;
926
927           /* .. fall through ...  */
928
929         case PLUS:
930           add_double (l1, h1, l2, h2, &lv, &hv);
931           break;
932
933         case MULT:
934           mul_double (l1, h1, l2, h2, &lv, &hv);
935           break;
936
937         case DIV:  case MOD:   case UDIV:  case UMOD:
938           /* We'd need to include tree.h to do this and it doesn't seem worth
939              it.  */
940           return 0;
941
942         case AND:
943           lv = l1 & l2, hv = h1 & h2;
944           break;
945
946         case IOR:
947           lv = l1 | l2, hv = h1 | h2;
948           break;
949
950         case XOR:
951           lv = l1 ^ l2, hv = h1 ^ h2;
952           break;
953
954         case SMIN:
955           if (h1 < h2
956               || (h1 == h2
957                   && ((unsigned HOST_WIDE_INT) l1
958                       < (unsigned HOST_WIDE_INT) l2)))
959             lv = l1, hv = h1;
960           else
961             lv = l2, hv = h2;
962           break;
963
964         case SMAX:
965           if (h1 > h2
966               || (h1 == h2
967                   && ((unsigned HOST_WIDE_INT) l1
968                       > (unsigned HOST_WIDE_INT) l2)))
969             lv = l1, hv = h1;
970           else
971             lv = l2, hv = h2;
972           break;
973
974         case UMIN:
975           if ((unsigned HOST_WIDE_INT) h1 < (unsigned HOST_WIDE_INT) h2
976               || (h1 == h2
977                   && ((unsigned HOST_WIDE_INT) l1
978                       < (unsigned HOST_WIDE_INT) l2)))
979             lv = l1, hv = h1;
980           else
981             lv = l2, hv = h2;
982           break;
983
984         case UMAX:
985           if ((unsigned HOST_WIDE_INT) h1 > (unsigned HOST_WIDE_INT) h2
986               || (h1 == h2
987                   && ((unsigned HOST_WIDE_INT) l1
988                       > (unsigned HOST_WIDE_INT) l2)))
989             lv = l1, hv = h1;
990           else
991             lv = l2, hv = h2;
992           break;
993
994         case LSHIFTRT:   case ASHIFTRT:
995         case ASHIFT:
996         case ROTATE:     case ROTATERT:
997 #ifdef SHIFT_COUNT_TRUNCATED
998           if (SHIFT_COUNT_TRUNCATED)
999             l2 &= (GET_MODE_BITSIZE (mode) - 1), h2 = 0;
1000 #endif
1001
1002           if (h2 != 0 || l2 >= GET_MODE_BITSIZE (mode))
1003             return 0;
1004
1005           if (code == LSHIFTRT || code == ASHIFTRT)
1006             rshift_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv,
1007                            code == ASHIFTRT);
1008           else if (code == ASHIFT)
1009             lshift_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv, 1);
1010           else if (code == ROTATE)
1011             lrotate_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv);
1012           else /* code == ROTATERT */
1013             rrotate_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv);
1014           break;
1015
1016         default:
1017           return 0;
1018         }
1019
1020       return immed_double_const (lv, hv, mode);
1021     }
1022
1023   if (GET_CODE (op0) != CONST_INT || GET_CODE (op1) != CONST_INT
1024       || width > HOST_BITS_PER_WIDE_INT || width == 0)
1025     {
1026       /* Even if we can't compute a constant result,
1027          there are some cases worth simplifying.  */
1028
1029       switch (code)
1030         {
1031         case PLUS:
1032           /* In IEEE floating point, x+0 is not the same as x.  Similarly
1033              for the other optimizations below.  */
1034           if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1035               && FLOAT_MODE_P (mode) && ! flag_unsafe_math_optimizations)
1036             break;
1037
1038           if (trueop1 == CONST0_RTX (mode))
1039             return op0;
1040
1041           /* ((-a) + b) -> (b - a) and similarly for (a + (-b)) */
1042           if (GET_CODE (op0) == NEG)
1043             return simplify_gen_binary (MINUS, mode, op1, XEXP (op0, 0));
1044           else if (GET_CODE (op1) == NEG)
1045             return simplify_gen_binary (MINUS, mode, op0, XEXP (op1, 0));
1046
1047           /* (~a) + 1 -> -a */
1048           if (INTEGRAL_MODE_P (mode)
1049               && GET_CODE (op0) == NOT
1050               && trueop1 == const1_rtx)
1051             return gen_rtx_NEG (mode, XEXP (op0, 0));
1052
1053           /* Handle both-operands-constant cases.  We can only add
1054              CONST_INTs to constants since the sum of relocatable symbols
1055              can't be handled by most assemblers.  Don't add CONST_INT
1056              to CONST_INT since overflow won't be computed properly if wider
1057              than HOST_BITS_PER_WIDE_INT.  */
1058
1059           if (CONSTANT_P (op0) && GET_MODE (op0) != VOIDmode
1060               && GET_CODE (op1) == CONST_INT)
1061             return plus_constant (op0, INTVAL (op1));
1062           else if (CONSTANT_P (op1) && GET_MODE (op1) != VOIDmode
1063                    && GET_CODE (op0) == CONST_INT)
1064             return plus_constant (op1, INTVAL (op0));
1065
1066           /* See if this is something like X * C - X or vice versa or
1067              if the multiplication is written as a shift.  If so, we can
1068              distribute and make a new multiply, shift, or maybe just
1069              have X (if C is 2 in the example above).  But don't make
1070              real multiply if we didn't have one before.  */
1071
1072           if (! FLOAT_MODE_P (mode))
1073             {
1074               HOST_WIDE_INT coeff0 = 1, coeff1 = 1;
1075               rtx lhs = op0, rhs = op1;
1076               int had_mult = 0;
1077
1078               if (GET_CODE (lhs) == NEG)
1079                 coeff0 = -1, lhs = XEXP (lhs, 0);
1080               else if (GET_CODE (lhs) == MULT
1081                        && GET_CODE (XEXP (lhs, 1)) == CONST_INT)
1082                 {
1083                   coeff0 = INTVAL (XEXP (lhs, 1)), lhs = XEXP (lhs, 0);
1084                   had_mult = 1;
1085                 }
1086               else if (GET_CODE (lhs) == ASHIFT
1087                        && GET_CODE (XEXP (lhs, 1)) == CONST_INT
1088                        && INTVAL (XEXP (lhs, 1)) >= 0
1089                        && INTVAL (XEXP (lhs, 1)) < HOST_BITS_PER_WIDE_INT)
1090                 {
1091                   coeff0 = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (lhs, 1));
1092                   lhs = XEXP (lhs, 0);
1093                 }
1094
1095               if (GET_CODE (rhs) == NEG)
1096                 coeff1 = -1, rhs = XEXP (rhs, 0);
1097               else if (GET_CODE (rhs) == MULT
1098                        && GET_CODE (XEXP (rhs, 1)) == CONST_INT)
1099                 {
1100                   coeff1 = INTVAL (XEXP (rhs, 1)), rhs = XEXP (rhs, 0);
1101                   had_mult = 1;
1102                 }
1103               else if (GET_CODE (rhs) == ASHIFT
1104                        && GET_CODE (XEXP (rhs, 1)) == CONST_INT
1105                        && INTVAL (XEXP (rhs, 1)) >= 0
1106                        && INTVAL (XEXP (rhs, 1)) < HOST_BITS_PER_WIDE_INT)
1107                 {
1108                   coeff1 = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (rhs, 1));
1109                   rhs = XEXP (rhs, 0);
1110                 }
1111
1112               if (rtx_equal_p (lhs, rhs))
1113                 {
1114                   tem = simplify_gen_binary (MULT, mode, lhs,
1115                                         GEN_INT (coeff0 + coeff1));
1116                   return (GET_CODE (tem) == MULT && ! had_mult) ? 0 : tem;
1117                 }
1118             }
1119
1120           /* If one of the operands is a PLUS or a MINUS, see if we can
1121              simplify this by the associative law. 
1122              Don't use the associative law for floating point.
1123              The inaccuracy makes it nonassociative,
1124              and subtle programs can break if operations are associated.  */
1125
1126           if (INTEGRAL_MODE_P (mode)
1127               && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
1128                   || GET_CODE (op1) == PLUS || GET_CODE (op1) == MINUS)
1129               && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
1130             return tem;
1131           break;
1132
1133         case COMPARE:
1134 #ifdef HAVE_cc0
1135           /* Convert (compare FOO (const_int 0)) to FOO unless we aren't
1136              using cc0, in which case we want to leave it as a COMPARE
1137              so we can distinguish it from a register-register-copy.
1138
1139              In IEEE floating point, x-0 is not the same as x.  */
1140
1141           if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
1142                || ! FLOAT_MODE_P (mode) || flag_unsafe_math_optimizations)
1143               && trueop1 == CONST0_RTX (mode))
1144             return op0;
1145 #endif
1146
1147           /* Convert (compare (gt (flags) 0) (lt (flags) 0)) to (flags).  */
1148           if (((GET_CODE (op0) == GT && GET_CODE (op1) == LT)
1149                || (GET_CODE (op0) == GTU && GET_CODE (op1) == LTU))
1150               && XEXP (op0, 1) == const0_rtx && XEXP (op1, 1) == const0_rtx)
1151             {
1152               rtx xop00 = XEXP (op0, 0);
1153               rtx xop10 = XEXP (op1, 0);
1154
1155 #ifdef HAVE_cc0
1156               if (GET_CODE (xop00) == CC0 && GET_CODE (xop10) == CC0)
1157 #else
1158               if (GET_CODE (xop00) == REG && GET_CODE (xop10) == REG
1159                   && GET_MODE (xop00) == GET_MODE (xop10)
1160                   && REGNO (xop00) == REGNO (xop10)
1161                   && GET_MODE_CLASS (GET_MODE (xop00)) == MODE_CC
1162                   && GET_MODE_CLASS (GET_MODE (xop10)) == MODE_CC)
1163 #endif
1164                 return xop00;
1165             }
1166
1167           break;              
1168         case MINUS:
1169           /* None of these optimizations can be done for IEEE
1170              floating point.  */
1171           if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1172               && FLOAT_MODE_P (mode) && ! flag_unsafe_math_optimizations)
1173             break;
1174
1175           /* We can't assume x-x is 0 even with non-IEEE floating point,
1176              but since it is zero except in very strange circumstances, we
1177              will treat it as zero with -funsafe-math-optimizations.  */
1178           if (rtx_equal_p (trueop0, trueop1)
1179               && ! side_effects_p (op0)
1180               && (! FLOAT_MODE_P (mode) || flag_unsafe_math_optimizations))
1181             return CONST0_RTX (mode);
1182
1183           /* Change subtraction from zero into negation.  */
1184           if (trueop0 == CONST0_RTX (mode))
1185             return gen_rtx_NEG (mode, op1);
1186
1187           /* (-1 - a) is ~a.  */
1188           if (trueop0 == constm1_rtx)
1189             return gen_rtx_NOT (mode, op1);
1190
1191           /* Subtracting 0 has no effect.  */
1192           if (trueop1 == CONST0_RTX (mode))
1193             return op0;
1194
1195           /* See if this is something like X * C - X or vice versa or
1196              if the multiplication is written as a shift.  If so, we can
1197              distribute and make a new multiply, shift, or maybe just
1198              have X (if C is 2 in the example above).  But don't make
1199              real multiply if we didn't have one before.  */
1200
1201           if (! FLOAT_MODE_P (mode))
1202             {
1203               HOST_WIDE_INT coeff0 = 1, coeff1 = 1;
1204               rtx lhs = op0, rhs = op1;
1205               int had_mult = 0;
1206
1207               if (GET_CODE (lhs) == NEG)
1208                 coeff0 = -1, lhs = XEXP (lhs, 0);
1209               else if (GET_CODE (lhs) == MULT
1210                        && GET_CODE (XEXP (lhs, 1)) == CONST_INT)
1211                 {
1212                   coeff0 = INTVAL (XEXP (lhs, 1)), lhs = XEXP (lhs, 0);
1213                   had_mult = 1;
1214                 }
1215               else if (GET_CODE (lhs) == ASHIFT
1216                        && GET_CODE (XEXP (lhs, 1)) == CONST_INT
1217                        && INTVAL (XEXP (lhs, 1)) >= 0
1218                        && INTVAL (XEXP (lhs, 1)) < HOST_BITS_PER_WIDE_INT)
1219                 {
1220                   coeff0 = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (lhs, 1));
1221                   lhs = XEXP (lhs, 0);
1222                 }
1223
1224               if (GET_CODE (rhs) == NEG)
1225                 coeff1 = - 1, rhs = XEXP (rhs, 0);
1226               else if (GET_CODE (rhs) == MULT
1227                        && GET_CODE (XEXP (rhs, 1)) == CONST_INT)
1228                 {
1229                   coeff1 = INTVAL (XEXP (rhs, 1)), rhs = XEXP (rhs, 0);
1230                   had_mult = 1;
1231                 }
1232               else if (GET_CODE (rhs) == ASHIFT
1233                        && GET_CODE (XEXP (rhs, 1)) == CONST_INT
1234                        && INTVAL (XEXP (rhs, 1)) >= 0
1235                        && INTVAL (XEXP (rhs, 1)) < HOST_BITS_PER_WIDE_INT)
1236                 {
1237                   coeff1 = ((HOST_WIDE_INT) 1) << INTVAL (XEXP (rhs, 1));
1238                   rhs = XEXP (rhs, 0);
1239                 }
1240
1241               if (rtx_equal_p (lhs, rhs))
1242                 {
1243                   tem = simplify_gen_binary (MULT, mode, lhs,
1244                                              GEN_INT (coeff0 - coeff1));
1245                   return (GET_CODE (tem) == MULT && ! had_mult) ? 0 : tem;
1246                 }
1247             }
1248
1249           /* (a - (-b)) -> (a + b).  */
1250           if (GET_CODE (op1) == NEG)
1251             return simplify_gen_binary (PLUS, mode, op0, XEXP (op1, 0));
1252
1253           /* If one of the operands is a PLUS or a MINUS, see if we can
1254              simplify this by the associative law. 
1255              Don't use the associative law for floating point.
1256              The inaccuracy makes it nonassociative,
1257              and subtle programs can break if operations are associated.  */
1258
1259           if (INTEGRAL_MODE_P (mode)
1260               && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
1261                   || GET_CODE (op1) == PLUS || GET_CODE (op1) == MINUS)
1262               && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
1263             return tem;
1264
1265           /* Don't let a relocatable value get a negative coeff.  */
1266           if (GET_CODE (op1) == CONST_INT && GET_MODE (op0) != VOIDmode)
1267             return plus_constant (op0, - INTVAL (op1));
1268
1269           /* (x - (x & y)) -> (x & ~y) */
1270           if (GET_CODE (op1) == AND)
1271             {
1272              if (rtx_equal_p (op0, XEXP (op1, 0)))
1273                return simplify_gen_binary (AND, mode, op0,
1274                                            gen_rtx_NOT (mode, XEXP (op1, 1)));
1275              if (rtx_equal_p (op0, XEXP (op1, 1)))
1276                return simplify_gen_binary (AND, mode, op0,
1277                                            gen_rtx_NOT (mode, XEXP (op1, 0)));
1278            }
1279           break;
1280
1281         case MULT:
1282           if (trueop1 == constm1_rtx)
1283             {
1284               tem = simplify_unary_operation (NEG, mode, op0, mode);
1285
1286               return tem ? tem : gen_rtx_NEG (mode, op0);
1287             }
1288
1289           /* In IEEE floating point, x*0 is not always 0.  */
1290           if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
1291                || ! FLOAT_MODE_P (mode) || flag_unsafe_math_optimizations)
1292               && trueop1 == CONST0_RTX (mode)
1293               && ! side_effects_p (op0))
1294             return op1;
1295
1296           /* In IEEE floating point, x*1 is not equivalent to x for nans.
1297              However, ANSI says we can drop signals,
1298              so we can do this anyway.  */
1299           if (trueop1 == CONST1_RTX (mode))
1300             return op0;
1301
1302           /* Convert multiply by constant power of two into shift unless
1303              we are still generating RTL.  This test is a kludge.  */
1304           if (GET_CODE (trueop1) == CONST_INT
1305               && (val = exact_log2 (INTVAL (trueop1))) >= 0
1306               /* If the mode is larger than the host word size, and the
1307                  uppermost bit is set, then this isn't a power of two due
1308                  to implicit sign extension.  */
1309               && (width <= HOST_BITS_PER_WIDE_INT
1310                   || val != HOST_BITS_PER_WIDE_INT - 1)
1311               && ! rtx_equal_function_value_matters)
1312             return gen_rtx_ASHIFT (mode, op0, GEN_INT (val));
1313
1314           if (GET_CODE (trueop1) == CONST_DOUBLE
1315               && GET_MODE_CLASS (GET_MODE (trueop1)) == MODE_FLOAT)
1316             {
1317               struct simplify_binary_is2orm1_args args;
1318
1319               args.value = trueop1;
1320               if (! do_float_handler (simplify_binary_is2orm1, (PTR) &args))
1321                 return 0;
1322
1323               /* x*2 is x+x and x*(-1) is -x */
1324               if (args.is_2 && GET_MODE (op0) == mode)
1325                 return gen_rtx_PLUS (mode, op0, copy_rtx (op0));
1326
1327               else if (args.is_m1 && GET_MODE (op0) == mode)
1328                 return gen_rtx_NEG (mode, op0);
1329             }
1330           break;
1331
1332         case IOR:
1333           if (trueop1 == const0_rtx)
1334             return op0;
1335           if (GET_CODE (trueop1) == CONST_INT
1336               && ((INTVAL (trueop1) & GET_MODE_MASK (mode))
1337                   == GET_MODE_MASK (mode)))
1338             return op1;
1339           if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
1340             return op0;
1341           /* A | (~A) -> -1 */
1342           if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
1343                || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
1344               && ! side_effects_p (op0)
1345               && GET_MODE_CLASS (mode) != MODE_CC)
1346             return constm1_rtx;
1347           break;
1348
1349         case XOR:
1350           if (trueop1 == const0_rtx)
1351             return op0;
1352           if (GET_CODE (trueop1) == CONST_INT
1353               && ((INTVAL (trueop1) & GET_MODE_MASK (mode))
1354                   == GET_MODE_MASK (mode)))
1355             return gen_rtx_NOT (mode, op0);
1356           if (trueop0 == trueop1 && ! side_effects_p (op0)
1357               && GET_MODE_CLASS (mode) != MODE_CC)
1358             return const0_rtx;
1359           break;
1360
1361         case AND:
1362           if (trueop1 == const0_rtx && ! side_effects_p (op0))
1363             return const0_rtx;
1364           if (GET_CODE (trueop1) == CONST_INT
1365               && ((INTVAL (trueop1) & GET_MODE_MASK (mode))
1366                   == GET_MODE_MASK (mode)))
1367             return op0;
1368           if (trueop0 == trueop1 && ! side_effects_p (op0)
1369               && GET_MODE_CLASS (mode) != MODE_CC)
1370             return op0;
1371           /* A & (~A) -> 0 */
1372           if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
1373                || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
1374               && ! side_effects_p (op0)
1375               && GET_MODE_CLASS (mode) != MODE_CC)
1376             return const0_rtx;
1377           break;
1378
1379         case UDIV:
1380           /* Convert divide by power of two into shift (divide by 1 handled
1381              below).  */
1382           if (GET_CODE (trueop1) == CONST_INT
1383               && (arg1 = exact_log2 (INTVAL (trueop1))) > 0)
1384             return gen_rtx_LSHIFTRT (mode, op0, GEN_INT (arg1));
1385
1386           /* ... fall through ...  */
1387
1388         case DIV:
1389           if (trueop1 == CONST1_RTX (mode))
1390             return op0;
1391
1392           /* In IEEE floating point, 0/x is not always 0.  */
1393           if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
1394                || ! FLOAT_MODE_P (mode) || flag_unsafe_math_optimizations)
1395               && trueop0 == CONST0_RTX (mode)
1396               && ! side_effects_p (op1))
1397             return op0;
1398
1399 #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
1400           /* Change division by a constant into multiplication.  Only do
1401              this with -funsafe-math-optimizations.  */
1402           else if (GET_CODE (trueop1) == CONST_DOUBLE
1403                    && GET_MODE_CLASS (GET_MODE (trueop1)) == MODE_FLOAT
1404                    && trueop1 != CONST0_RTX (mode)
1405                    && flag_unsafe_math_optimizations)
1406             {
1407               REAL_VALUE_TYPE d;
1408               REAL_VALUE_FROM_CONST_DOUBLE (d, trueop1);
1409
1410               if (! REAL_VALUES_EQUAL (d, dconst0))
1411                 {
1412 #if defined (REAL_ARITHMETIC)
1413                   REAL_ARITHMETIC (d, rtx_to_tree_code (DIV), dconst1, d);
1414                   return gen_rtx_MULT (mode, op0, 
1415                                        CONST_DOUBLE_FROM_REAL_VALUE (d, mode));
1416 #else
1417                   return
1418                     gen_rtx_MULT (mode, op0, 
1419                                   CONST_DOUBLE_FROM_REAL_VALUE (1./d, mode));
1420 #endif
1421                 }
1422             }
1423 #endif
1424           break;
1425
1426         case UMOD:
1427           /* Handle modulus by power of two (mod with 1 handled below).  */
1428           if (GET_CODE (trueop1) == CONST_INT
1429               && exact_log2 (INTVAL (trueop1)) > 0)
1430             return gen_rtx_AND (mode, op0, GEN_INT (INTVAL (op1) - 1));
1431
1432           /* ... fall through ...  */
1433
1434         case MOD:
1435           if ((trueop0 == const0_rtx || trueop1 == const1_rtx)
1436               && ! side_effects_p (op0) && ! side_effects_p (op1))
1437             return const0_rtx;
1438           break;
1439
1440         case ROTATERT:
1441         case ROTATE:
1442           /* Rotating ~0 always results in ~0.  */
1443           if (GET_CODE (trueop0) == CONST_INT && width <= HOST_BITS_PER_WIDE_INT
1444               && (unsigned HOST_WIDE_INT) INTVAL (trueop0) == GET_MODE_MASK (mode)
1445               && ! side_effects_p (op1))
1446             return op0;
1447
1448           /* ... fall through ...  */
1449
1450         case ASHIFT:
1451         case ASHIFTRT:
1452         case LSHIFTRT:
1453           if (trueop1 == const0_rtx)
1454             return op0;
1455           if (trueop0 == const0_rtx && ! side_effects_p (op1))
1456             return op0;
1457           break;
1458
1459         case SMIN:
1460           if (width <= HOST_BITS_PER_WIDE_INT && GET_CODE (trueop1) == CONST_INT 
1461               && INTVAL (trueop1) == (HOST_WIDE_INT) 1 << (width -1)
1462               && ! side_effects_p (op0))
1463             return op1;
1464           else if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
1465             return op0;
1466           break;
1467            
1468         case SMAX:
1469           if (width <= HOST_BITS_PER_WIDE_INT && GET_CODE (trueop1) == CONST_INT
1470               && ((unsigned HOST_WIDE_INT) INTVAL (trueop1)
1471                   == (unsigned HOST_WIDE_INT) GET_MODE_MASK (mode) >> 1)
1472               && ! side_effects_p (op0))
1473             return op1;
1474           else if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
1475             return op0;
1476           break;
1477
1478         case UMIN:
1479           if (trueop1 == const0_rtx && ! side_effects_p (op0))
1480             return op1;
1481           else if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
1482             return op0;
1483           break;
1484             
1485         case UMAX:
1486           if (trueop1 == constm1_rtx && ! side_effects_p (op0))
1487             return op1;
1488           else if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
1489             return op0;
1490           break;
1491
1492         default:
1493           abort ();
1494         }
1495       
1496       return 0;
1497     }
1498
1499   /* Get the integer argument values in two forms:
1500      zero-extended in ARG0, ARG1 and sign-extended in ARG0S, ARG1S.  */
1501
1502   arg0 = INTVAL (trueop0);
1503   arg1 = INTVAL (trueop1);
1504
1505   if (width < HOST_BITS_PER_WIDE_INT)
1506     {
1507       arg0 &= ((HOST_WIDE_INT) 1 << width) - 1;
1508       arg1 &= ((HOST_WIDE_INT) 1 << width) - 1;
1509
1510       arg0s = arg0;
1511       if (arg0s & ((HOST_WIDE_INT) 1 << (width - 1)))
1512         arg0s |= ((HOST_WIDE_INT) (-1) << width);
1513
1514       arg1s = arg1;
1515       if (arg1s & ((HOST_WIDE_INT) 1 << (width - 1)))
1516         arg1s |= ((HOST_WIDE_INT) (-1) << width);
1517     }
1518   else
1519     {
1520       arg0s = arg0;
1521       arg1s = arg1;
1522     }
1523
1524   /* Compute the value of the arithmetic.  */
1525
1526   switch (code)
1527     {
1528     case PLUS:
1529       val = arg0s + arg1s;
1530       break;
1531
1532     case MINUS:
1533       val = arg0s - arg1s;
1534       break;
1535
1536     case MULT:
1537       val = arg0s * arg1s;
1538       break;
1539
1540     case DIV:
1541       if (arg1s == 0
1542           || (arg0s == (HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1)
1543               && arg1s == -1))
1544         return 0;
1545       val = arg0s / arg1s;
1546       break;
1547
1548     case MOD:
1549       if (arg1s == 0
1550           || (arg0s == (HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1)
1551               && arg1s == -1))
1552         return 0;
1553       val = arg0s % arg1s;
1554       break;
1555
1556     case UDIV:
1557       if (arg1 == 0
1558           || (arg0s == (HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1)
1559               && arg1s == -1))
1560         return 0;
1561       val = (unsigned HOST_WIDE_INT) arg0 / arg1;
1562       break;
1563
1564     case UMOD:
1565       if (arg1 == 0
1566           || (arg0s == (HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1)
1567               && arg1s == -1))
1568         return 0;
1569       val = (unsigned HOST_WIDE_INT) arg0 % arg1;
1570       break;
1571
1572     case AND:
1573       val = arg0 & arg1;
1574       break;
1575
1576     case IOR:
1577       val = arg0 | arg1;
1578       break;
1579
1580     case XOR:
1581       val = arg0 ^ arg1;
1582       break;
1583
1584     case LSHIFTRT:
1585       /* If shift count is undefined, don't fold it; let the machine do
1586          what it wants.  But truncate it if the machine will do that.  */
1587       if (arg1 < 0)
1588         return 0;
1589
1590 #ifdef SHIFT_COUNT_TRUNCATED
1591       if (SHIFT_COUNT_TRUNCATED)
1592         arg1 %= width;
1593 #endif
1594
1595       val = ((unsigned HOST_WIDE_INT) arg0) >> arg1;
1596       break;
1597
1598     case ASHIFT:
1599       if (arg1 < 0)
1600         return 0;
1601
1602 #ifdef SHIFT_COUNT_TRUNCATED
1603       if (SHIFT_COUNT_TRUNCATED)
1604         arg1 %= width;
1605 #endif
1606
1607       val = ((unsigned HOST_WIDE_INT) arg0) << arg1;
1608       break;
1609
1610     case ASHIFTRT:
1611       if (arg1 < 0)
1612         return 0;
1613
1614 #ifdef SHIFT_COUNT_TRUNCATED
1615       if (SHIFT_COUNT_TRUNCATED)
1616         arg1 %= width;
1617 #endif
1618
1619       val = arg0s >> arg1;
1620
1621       /* Bootstrap compiler may not have sign extended the right shift.
1622          Manually extend the sign to insure bootstrap cc matches gcc.  */
1623       if (arg0s < 0 && arg1 > 0)
1624         val |= ((HOST_WIDE_INT) -1) << (HOST_BITS_PER_WIDE_INT - arg1);
1625
1626       break;
1627
1628     case ROTATERT:
1629       if (arg1 < 0)
1630         return 0;
1631
1632       arg1 %= width;
1633       val = ((((unsigned HOST_WIDE_INT) arg0) << (width - arg1))
1634              | (((unsigned HOST_WIDE_INT) arg0) >> arg1));
1635       break;
1636
1637     case ROTATE:
1638       if (arg1 < 0)
1639         return 0;
1640
1641       arg1 %= width;
1642       val = ((((unsigned HOST_WIDE_INT) arg0) << arg1)
1643              | (((unsigned HOST_WIDE_INT) arg0) >> (width - arg1)));
1644       break;
1645
1646     case COMPARE:
1647       /* Do nothing here.  */
1648       return 0;
1649
1650     case SMIN:
1651       val = arg0s <= arg1s ? arg0s : arg1s;
1652       break;
1653
1654     case UMIN:
1655       val = ((unsigned HOST_WIDE_INT) arg0
1656              <= (unsigned HOST_WIDE_INT) arg1 ? arg0 : arg1);
1657       break;
1658
1659     case SMAX:
1660       val = arg0s > arg1s ? arg0s : arg1s;
1661       break;
1662
1663     case UMAX:
1664       val = ((unsigned HOST_WIDE_INT) arg0
1665              > (unsigned HOST_WIDE_INT) arg1 ? arg0 : arg1);
1666       break;
1667
1668     default:
1669       abort ();
1670     }
1671
1672   val = trunc_int_for_mode (val, mode);
1673
1674   return GEN_INT (val);
1675 }
1676 \f
1677 /* Simplify a PLUS or MINUS, at least one of whose operands may be another
1678    PLUS or MINUS.
1679
1680    Rather than test for specific case, we do this by a brute-force method
1681    and do all possible simplifications until no more changes occur.  Then
1682    we rebuild the operation.  */
1683
1684 static rtx
1685 simplify_plus_minus (code, mode, op0, op1)
1686      enum rtx_code code;
1687      enum machine_mode mode;
1688      rtx op0, op1;
1689 {
1690   rtx ops[8];
1691   int negs[8];
1692   rtx result, tem;
1693   int n_ops = 2, input_ops = 2, input_consts = 0, n_consts = 0;
1694   int first = 1, negate = 0, changed;
1695   int i, j;
1696
1697   memset ((char *) ops, 0, sizeof ops);
1698   
1699   /* Set up the two operands and then expand them until nothing has been
1700      changed.  If we run out of room in our array, give up; this should
1701      almost never happen.  */
1702
1703   ops[0] = op0, ops[1] = op1, negs[0] = 0, negs[1] = (code == MINUS);
1704
1705   changed = 1;
1706   while (changed)
1707     {
1708       changed = 0;
1709
1710       for (i = 0; i < n_ops; i++)
1711         switch (GET_CODE (ops[i]))
1712           {
1713           case PLUS:
1714           case MINUS:
1715             if (n_ops == 7)
1716               return 0;
1717
1718             ops[n_ops] = XEXP (ops[i], 1);
1719             negs[n_ops++] = GET_CODE (ops[i]) == MINUS ? !negs[i] : negs[i];
1720             ops[i] = XEXP (ops[i], 0);
1721             input_ops++;
1722             changed = 1;
1723             break;
1724
1725           case NEG:
1726             ops[i] = XEXP (ops[i], 0);
1727             negs[i] = ! negs[i];
1728             changed = 1;
1729             break;
1730
1731           case CONST:
1732             ops[i] = XEXP (ops[i], 0);
1733             input_consts++;
1734             changed = 1;
1735             break;
1736
1737           case NOT:
1738             /* ~a -> (-a - 1) */
1739             if (n_ops != 7)
1740               {
1741                 ops[n_ops] = constm1_rtx;
1742                 negs[n_ops++] = negs[i];
1743                 ops[i] = XEXP (ops[i], 0);
1744                 negs[i] = ! negs[i];
1745                 changed = 1;
1746               }
1747             break;
1748
1749           case CONST_INT:
1750             if (negs[i])
1751               ops[i] = GEN_INT (- INTVAL (ops[i])), negs[i] = 0, changed = 1;
1752             break;
1753
1754           default:
1755             break;
1756           }
1757     }
1758
1759   /* If we only have two operands, we can't do anything.  */
1760   if (n_ops <= 2)
1761     return 0;
1762
1763   /* Now simplify each pair of operands until nothing changes.  The first
1764      time through just simplify constants against each other.  */
1765
1766   changed = 1;
1767   while (changed)
1768     {
1769       changed = first;
1770
1771       for (i = 0; i < n_ops - 1; i++)
1772         for (j = i + 1; j < n_ops; j++)
1773           if (ops[i] != 0 && ops[j] != 0
1774               && (! first || (CONSTANT_P (ops[i]) && CONSTANT_P (ops[j]))))
1775             {
1776               rtx lhs = ops[i], rhs = ops[j];
1777               enum rtx_code ncode = PLUS;
1778
1779               if (negs[i] && ! negs[j])
1780                 lhs = ops[j], rhs = ops[i], ncode = MINUS;
1781               else if (! negs[i] && negs[j])
1782                 ncode = MINUS;
1783
1784               tem = simplify_binary_operation (ncode, mode, lhs, rhs);
1785               if (tem)
1786                 {
1787                   ops[i] = tem, ops[j] = 0;
1788                   negs[i] = negs[i] && negs[j];
1789                   if (GET_CODE (tem) == NEG)
1790                     ops[i] = XEXP (tem, 0), negs[i] = ! negs[i];
1791
1792                   if (GET_CODE (ops[i]) == CONST_INT && negs[i])
1793                     ops[i] = GEN_INT (- INTVAL (ops[i])), negs[i] = 0;
1794                   changed = 1;
1795                 }
1796             }
1797
1798       first = 0;
1799     }
1800
1801   /* Pack all the operands to the lower-numbered entries and give up if
1802      we didn't reduce the number of operands we had.  Make sure we
1803      count a CONST as two operands.  If we have the same number of
1804      operands, but have made more CONSTs than we had, this is also
1805      an improvement, so accept it.  */
1806
1807   for (i = 0, j = 0; j < n_ops; j++)
1808     if (ops[j] != 0)
1809       {
1810         ops[i] = ops[j], negs[i++] = negs[j];
1811         if (GET_CODE (ops[j]) == CONST)
1812           n_consts++;
1813       }
1814
1815   if (i + n_consts > input_ops
1816       || (i + n_consts == input_ops && n_consts <= input_consts))
1817     return 0;
1818
1819   n_ops = i;
1820
1821   /* If we have a CONST_INT, put it last.  */
1822   for (i = 0; i < n_ops - 1; i++)
1823     if (GET_CODE (ops[i]) == CONST_INT)
1824       {
1825         tem = ops[n_ops - 1], ops[n_ops - 1] = ops[i] , ops[i] = tem;
1826         j = negs[n_ops - 1], negs[n_ops - 1] = negs[i], negs[i] = j;
1827       }
1828
1829   /* Put a non-negated operand first.  If there aren't any, make all
1830      operands positive and negate the whole thing later.  */
1831   for (i = 0; i < n_ops && negs[i]; i++)
1832     ;
1833
1834   if (i == n_ops)
1835     {
1836       for (i = 0; i < n_ops; i++)
1837         negs[i] = 0;
1838       negate = 1;
1839     }
1840   else if (i != 0)
1841     {
1842       tem = ops[0], ops[0] = ops[i], ops[i] = tem;
1843       j = negs[0], negs[0] = negs[i], negs[i] = j;
1844     }
1845
1846   /* Now make the result by performing the requested operations.  */
1847   result = ops[0];
1848   for (i = 1; i < n_ops; i++)
1849     result = simplify_gen_binary (negs[i] ? MINUS : PLUS, mode, result, ops[i]);
1850
1851   return negate ? gen_rtx_NEG (mode, result) : result;
1852 }
1853
1854 struct cfc_args
1855 {
1856   rtx op0, op1;                 /* Input */
1857   int equal, op0lt, op1lt;      /* Output */
1858   int unordered;
1859 };
1860
1861 static void
1862 check_fold_consts (data)
1863   PTR data;
1864 {
1865   struct cfc_args *args = (struct cfc_args *) data;
1866   REAL_VALUE_TYPE d0, d1;
1867
1868   /* We may possibly raise an exception while reading the value.  */
1869   args->unordered = 1;
1870   REAL_VALUE_FROM_CONST_DOUBLE (d0, args->op0);
1871   REAL_VALUE_FROM_CONST_DOUBLE (d1, args->op1);
1872
1873   /* Comparisons of Inf versus Inf are ordered.  */
1874   if (REAL_VALUE_ISNAN (d0)
1875       || REAL_VALUE_ISNAN (d1))
1876     return;
1877   args->equal = REAL_VALUES_EQUAL (d0, d1);
1878   args->op0lt = REAL_VALUES_LESS (d0, d1);
1879   args->op1lt = REAL_VALUES_LESS (d1, d0);
1880   args->unordered = 0;
1881 }
1882
1883 /* Like simplify_binary_operation except used for relational operators.
1884    MODE is the mode of the operands, not that of the result.  If MODE
1885    is VOIDmode, both operands must also be VOIDmode and we compare the
1886    operands in "infinite precision".
1887
1888    If no simplification is possible, this function returns zero.  Otherwise,
1889    it returns either const_true_rtx or const0_rtx.  */
1890
1891 rtx
1892 simplify_relational_operation (code, mode, op0, op1)
1893      enum rtx_code code;
1894      enum machine_mode mode;
1895      rtx op0, op1;
1896 {
1897   int equal, op0lt, op0ltu, op1lt, op1ltu;
1898   rtx tem;
1899   rtx trueop0;
1900   rtx trueop1;
1901
1902   if (mode == VOIDmode
1903       && (GET_MODE (op0) != VOIDmode
1904           || GET_MODE (op1) != VOIDmode))
1905     abort ();
1906
1907   /* If op0 is a compare, extract the comparison arguments from it.  */
1908   if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
1909     op1 = XEXP (op0, 1), op0 = XEXP (op0, 0);
1910
1911   trueop0 = avoid_constant_pool_reference (op0);
1912   trueop1 = avoid_constant_pool_reference (op1);
1913
1914   /* We can't simplify MODE_CC values since we don't know what the
1915      actual comparison is.  */
1916   if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC
1917 #ifdef HAVE_cc0
1918       || op0 == cc0_rtx
1919 #endif
1920       )
1921     return 0;
1922
1923   /* Make sure the constant is second.  */
1924   if (swap_commutative_operands_p (trueop0, trueop1))
1925     {
1926       tem = op0, op0 = op1, op1 = tem;
1927       tem = trueop0, trueop0 = trueop1, trueop1 = tem;
1928       code = swap_condition (code);
1929     }
1930
1931   /* For integer comparisons of A and B maybe we can simplify A - B and can
1932      then simplify a comparison of that with zero.  If A and B are both either
1933      a register or a CONST_INT, this can't help; testing for these cases will
1934      prevent infinite recursion here and speed things up.
1935
1936      If CODE is an unsigned comparison, then we can never do this optimization,
1937      because it gives an incorrect result if the subtraction wraps around zero.
1938      ANSI C defines unsigned operations such that they never overflow, and
1939      thus such cases can not be ignored.  */
1940
1941   if (INTEGRAL_MODE_P (mode) && trueop1 != const0_rtx
1942       && ! ((GET_CODE (op0) == REG || GET_CODE (trueop0) == CONST_INT)
1943             && (GET_CODE (op1) == REG || GET_CODE (trueop1) == CONST_INT))
1944       && 0 != (tem = simplify_binary_operation (MINUS, mode, op0, op1))
1945       && code != GTU && code != GEU && code != LTU && code != LEU)
1946     return simplify_relational_operation (signed_condition (code),
1947                                           mode, tem, const0_rtx);
1948
1949   if (flag_unsafe_math_optimizations && code == ORDERED)
1950     return const_true_rtx;
1951
1952   if (flag_unsafe_math_optimizations && code == UNORDERED)
1953     return const0_rtx;
1954
1955   /* For non-IEEE floating-point, if the two operands are equal, we know the
1956      result.  */
1957   if (rtx_equal_p (trueop0, trueop1)
1958       && (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
1959           || ! FLOAT_MODE_P (GET_MODE (trueop0)) 
1960           || flag_unsafe_math_optimizations))
1961     equal = 1, op0lt = 0, op0ltu = 0, op1lt = 0, op1ltu = 0;
1962
1963   /* If the operands are floating-point constants, see if we can fold
1964      the result.  */
1965 #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
1966   else if (GET_CODE (trueop0) == CONST_DOUBLE
1967            && GET_CODE (trueop1) == CONST_DOUBLE
1968            && GET_MODE_CLASS (GET_MODE (trueop0)) == MODE_FLOAT)
1969     {
1970       struct cfc_args args;
1971
1972       /* Setup input for check_fold_consts() */
1973       args.op0 = trueop0;
1974       args.op1 = trueop1;
1975       
1976       
1977       if (!do_float_handler (check_fold_consts, (PTR) &args))
1978         args.unordered = 1;
1979
1980       if (args.unordered)
1981         switch (code)
1982           {
1983           case UNEQ:
1984           case UNLT:
1985           case UNGT:
1986           case UNLE:
1987           case UNGE:
1988           case NE:
1989           case UNORDERED:
1990             return const_true_rtx;
1991           case EQ:
1992           case LT:
1993           case GT:
1994           case LE:
1995           case GE:
1996           case LTGT:
1997           case ORDERED:
1998             return const0_rtx;
1999           default:
2000             return 0;
2001           }
2002
2003       /* Receive output from check_fold_consts() */
2004       equal = args.equal;
2005       op0lt = op0ltu = args.op0lt;
2006       op1lt = op1ltu = args.op1lt;
2007     }
2008 #endif  /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */
2009
2010   /* Otherwise, see if the operands are both integers.  */
2011   else if ((GET_MODE_CLASS (mode) == MODE_INT || mode == VOIDmode)
2012            && (GET_CODE (trueop0) == CONST_DOUBLE
2013                || GET_CODE (trueop0) == CONST_INT)
2014            && (GET_CODE (trueop1) == CONST_DOUBLE
2015                || GET_CODE (trueop1) == CONST_INT))
2016     {
2017       int width = GET_MODE_BITSIZE (mode);
2018       HOST_WIDE_INT l0s, h0s, l1s, h1s;
2019       unsigned HOST_WIDE_INT l0u, h0u, l1u, h1u;
2020
2021       /* Get the two words comprising each integer constant.  */
2022       if (GET_CODE (trueop0) == CONST_DOUBLE)
2023         {
2024           l0u = l0s = CONST_DOUBLE_LOW (trueop0);
2025           h0u = h0s = CONST_DOUBLE_HIGH (trueop0);
2026         }
2027       else
2028         {
2029           l0u = l0s = INTVAL (trueop0);
2030           h0u = h0s = HWI_SIGN_EXTEND (l0s);
2031         }
2032           
2033       if (GET_CODE (trueop1) == CONST_DOUBLE)
2034         {
2035           l1u = l1s = CONST_DOUBLE_LOW (trueop1);
2036           h1u = h1s = CONST_DOUBLE_HIGH (trueop1);
2037         }
2038       else
2039         {
2040           l1u = l1s = INTVAL (trueop1);
2041           h1u = h1s = HWI_SIGN_EXTEND (l1s);
2042         }
2043
2044       /* If WIDTH is nonzero and smaller than HOST_BITS_PER_WIDE_INT,
2045          we have to sign or zero-extend the values.  */
2046       if (width != 0 && width < HOST_BITS_PER_WIDE_INT)
2047         {
2048           l0u &= ((HOST_WIDE_INT) 1 << width) - 1;
2049           l1u &= ((HOST_WIDE_INT) 1 << width) - 1;
2050
2051           if (l0s & ((HOST_WIDE_INT) 1 << (width - 1)))
2052             l0s |= ((HOST_WIDE_INT) (-1) << width);
2053
2054           if (l1s & ((HOST_WIDE_INT) 1 << (width - 1)))
2055             l1s |= ((HOST_WIDE_INT) (-1) << width);
2056         }
2057       if (width != 0 && width <= HOST_BITS_PER_WIDE_INT)
2058         h0u = h1u = 0, h0s = HWI_SIGN_EXTEND (l0s), h1s = HWI_SIGN_EXTEND (l1s);
2059
2060       equal = (h0u == h1u && l0u == l1u);
2061       op0lt = (h0s < h1s || (h0s == h1s && l0u < l1u));
2062       op1lt = (h1s < h0s || (h1s == h0s && l1u < l0u));
2063       op0ltu = (h0u < h1u || (h0u == h1u && l0u < l1u));
2064       op1ltu = (h1u < h0u || (h1u == h0u && l1u < l0u));
2065     }
2066
2067   /* Otherwise, there are some code-specific tests we can make.  */
2068   else
2069     {
2070       switch (code)
2071         {
2072         case EQ:
2073           /* References to the frame plus a constant or labels cannot
2074              be zero, but a SYMBOL_REF can due to #pragma weak.  */
2075           if (((NONZERO_BASE_PLUS_P (op0) && trueop1 == const0_rtx)
2076                || GET_CODE (trueop0) == LABEL_REF)
2077 #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
2078               /* On some machines, the ap reg can be 0 sometimes.  */
2079               && op0 != arg_pointer_rtx
2080 #endif
2081                 )
2082             return const0_rtx;
2083           break;
2084
2085         case NE:
2086           if (((NONZERO_BASE_PLUS_P (op0) && trueop1 == const0_rtx)
2087                || GET_CODE (trueop0) == LABEL_REF)
2088 #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
2089               && op0 != arg_pointer_rtx
2090 #endif
2091               )
2092             return const_true_rtx;
2093           break;
2094
2095         case GEU:
2096           /* Unsigned values are never negative.  */
2097           if (trueop1 == const0_rtx)
2098             return const_true_rtx;
2099           break;
2100
2101         case LTU:
2102           if (trueop1 == const0_rtx)
2103             return const0_rtx;
2104           break;
2105
2106         case LEU:
2107           /* Unsigned values are never greater than the largest
2108              unsigned value.  */
2109           if (GET_CODE (trueop1) == CONST_INT
2110               && (unsigned HOST_WIDE_INT) INTVAL (trueop1) == GET_MODE_MASK (mode)
2111             && INTEGRAL_MODE_P (mode))
2112           return const_true_rtx;
2113           break;
2114
2115         case GTU:
2116           if (GET_CODE (trueop1) == CONST_INT
2117               && (unsigned HOST_WIDE_INT) INTVAL (trueop1) == GET_MODE_MASK (mode)
2118               && INTEGRAL_MODE_P (mode))
2119             return const0_rtx;
2120           break;
2121           
2122         default:
2123           break;
2124         }
2125
2126       return 0;
2127     }
2128
2129   /* If we reach here, EQUAL, OP0LT, OP0LTU, OP1LT, and OP1LTU are set
2130      as appropriate.  */
2131   switch (code)
2132     {
2133     case EQ:
2134     case UNEQ:
2135       return equal ? const_true_rtx : const0_rtx;
2136     case NE:
2137     case LTGT:
2138       return ! equal ? const_true_rtx : const0_rtx;
2139     case LT:
2140     case UNLT:
2141       return op0lt ? const_true_rtx : const0_rtx;
2142     case GT:
2143     case UNGT:
2144       return op1lt ? const_true_rtx : const0_rtx;
2145     case LTU:
2146       return op0ltu ? const_true_rtx : const0_rtx;
2147     case GTU:
2148       return op1ltu ? const_true_rtx : const0_rtx;
2149     case LE:
2150     case UNLE:
2151       return equal || op0lt ? const_true_rtx : const0_rtx;
2152     case GE:
2153     case UNGE:
2154       return equal || op1lt ? const_true_rtx : const0_rtx;
2155     case LEU:
2156       return equal || op0ltu ? const_true_rtx : const0_rtx;
2157     case GEU:
2158       return equal || op1ltu ? const_true_rtx : const0_rtx;
2159     case ORDERED:
2160       return const_true_rtx;
2161     case UNORDERED:
2162       return const0_rtx;
2163     default:
2164       abort ();
2165     }
2166 }
2167 \f
2168 /* Simplify CODE, an operation with result mode MODE and three operands,
2169    OP0, OP1, and OP2.  OP0_MODE was the mode of OP0 before it became
2170    a constant.  Return 0 if no simplifications is possible.  */
2171
2172 rtx
2173 simplify_ternary_operation (code, mode, op0_mode, op0, op1, op2)
2174      enum rtx_code code;
2175      enum machine_mode mode, op0_mode;
2176      rtx op0, op1, op2;
2177 {
2178   unsigned int width = GET_MODE_BITSIZE (mode);
2179
2180   /* VOIDmode means "infinite" precision.  */
2181   if (width == 0)
2182     width = HOST_BITS_PER_WIDE_INT;
2183
2184   switch (code)
2185     {
2186     case SIGN_EXTRACT:
2187     case ZERO_EXTRACT:
2188       if (GET_CODE (op0) == CONST_INT
2189           && GET_CODE (op1) == CONST_INT
2190           && GET_CODE (op2) == CONST_INT
2191           && ((unsigned) INTVAL (op1) + (unsigned) INTVAL (op2) <= width)
2192           && width <= (unsigned) HOST_BITS_PER_WIDE_INT)
2193         {
2194           /* Extracting a bit-field from a constant */
2195           HOST_WIDE_INT val = INTVAL (op0);
2196
2197           if (BITS_BIG_ENDIAN)
2198             val >>= (GET_MODE_BITSIZE (op0_mode)
2199                      - INTVAL (op2) - INTVAL (op1));
2200           else
2201             val >>= INTVAL (op2);
2202
2203           if (HOST_BITS_PER_WIDE_INT != INTVAL (op1))
2204             {
2205               /* First zero-extend.  */
2206               val &= ((HOST_WIDE_INT) 1 << INTVAL (op1)) - 1;
2207               /* If desired, propagate sign bit.  */
2208               if (code == SIGN_EXTRACT
2209                   && (val & ((HOST_WIDE_INT) 1 << (INTVAL (op1) - 1))))
2210                 val |= ~ (((HOST_WIDE_INT) 1 << INTVAL (op1)) - 1);
2211             }
2212
2213           /* Clear the bits that don't belong in our mode,
2214              unless they and our sign bit are all one.
2215              So we get either a reasonable negative value or a reasonable
2216              unsigned value for this mode.  */
2217           if (width < HOST_BITS_PER_WIDE_INT
2218               && ((val & ((HOST_WIDE_INT) (-1) << (width - 1)))
2219                   != ((HOST_WIDE_INT) (-1) << (width - 1))))
2220             val &= ((HOST_WIDE_INT) 1 << width) - 1;
2221
2222           return GEN_INT (val);
2223         }
2224       break;
2225
2226     case IF_THEN_ELSE:
2227       if (GET_CODE (op0) == CONST_INT)
2228         return op0 != const0_rtx ? op1 : op2;
2229
2230       /* Convert a == b ? b : a to "a".  */
2231       if (GET_CODE (op0) == NE && ! side_effects_p (op0)
2232           && (! FLOAT_MODE_P (mode) || flag_unsafe_math_optimizations)
2233           && rtx_equal_p (XEXP (op0, 0), op1)
2234           && rtx_equal_p (XEXP (op0, 1), op2))
2235         return op1;
2236       else if (GET_CODE (op0) == EQ && ! side_effects_p (op0)
2237           && (! FLOAT_MODE_P (mode) || flag_unsafe_math_optimizations)
2238           && rtx_equal_p (XEXP (op0, 1), op1)
2239           && rtx_equal_p (XEXP (op0, 0), op2))
2240         return op2;
2241       else if (GET_RTX_CLASS (GET_CODE (op0)) == '<' && ! side_effects_p (op0))
2242         {
2243           enum machine_mode cmp_mode = (GET_MODE (XEXP (op0, 0)) == VOIDmode
2244                                         ? GET_MODE (XEXP (op0, 1))
2245                                         : GET_MODE (XEXP (op0, 0)));
2246           rtx temp;
2247           if (cmp_mode == VOIDmode)
2248             cmp_mode = op0_mode;
2249           temp = simplify_relational_operation (GET_CODE (op0), cmp_mode,
2250                                                 XEXP (op0, 0), XEXP (op0, 1));
2251
2252           /* See if any simplifications were possible.  */
2253           if (temp == const0_rtx)
2254             return op2;
2255           else if (temp == const1_rtx)
2256             return op1;
2257           else if (temp)
2258             op0 = temp;
2259
2260           /* Look for happy constants in op1 and op2.  */
2261           if (GET_CODE (op1) == CONST_INT && GET_CODE (op2) == CONST_INT)
2262             {
2263               HOST_WIDE_INT t = INTVAL (op1);
2264               HOST_WIDE_INT f = INTVAL (op2);
2265               
2266               if (t == STORE_FLAG_VALUE && f == 0)
2267                 code = GET_CODE (op0);
2268               else if (t == 0 && f == STORE_FLAG_VALUE)
2269                 {
2270                   enum rtx_code tmp;
2271                   tmp = reversed_comparison_code (op0, NULL_RTX);
2272                   if (tmp == UNKNOWN)
2273                     break;
2274                   code = tmp;
2275                 }
2276               else
2277                 break;
2278
2279               return gen_rtx_fmt_ee (code, mode, XEXP (op0, 0), XEXP (op0, 1));
2280             }
2281         }
2282       break;
2283
2284     default:
2285       abort ();
2286     }
2287
2288   return 0;
2289 }
2290
2291 /* Simplify SUBREG:OUTERMODE(OP:INNERMODE, BYTE)
2292    Return 0 if no simplifications is possible.  */
2293 rtx
2294 simplify_subreg (outermode, op, innermode, byte)
2295      rtx op;
2296      unsigned int byte;
2297      enum machine_mode outermode, innermode;
2298 {
2299   /* Little bit of sanity checking.  */
2300   if (innermode == VOIDmode || outermode == VOIDmode
2301       || innermode == BLKmode || outermode == BLKmode)
2302     abort ();
2303
2304   if (GET_MODE (op) != innermode
2305       && GET_MODE (op) != VOIDmode)
2306     abort ();
2307
2308   if (byte % GET_MODE_SIZE (outermode)
2309       || byte >= GET_MODE_SIZE (innermode))
2310     abort ();
2311
2312   if (outermode == innermode && !byte)
2313     return op;
2314
2315   /* Attempt to simplify constant to non-SUBREG expression.  */
2316   if (CONSTANT_P (op))
2317     {
2318       int offset, part;
2319       unsigned HOST_WIDE_INT val = 0;
2320
2321       /* ??? This code is partly redundant with code below, but can handle
2322          the subregs of floats and similar corner cases.
2323          Later it we should move all simplification code here and rewrite
2324          GEN_LOWPART_IF_POSSIBLE, GEN_HIGHPART, OPERAND_SUBWORD and friends
2325          using SIMPLIFY_SUBREG.  */
2326       if (subreg_lowpart_offset (outermode, innermode) == byte)
2327         {
2328           rtx new = gen_lowpart_if_possible (outermode, op);
2329           if (new)
2330             return new;
2331         }
2332
2333       /* Similar comment as above apply here.  */
2334       if (GET_MODE_SIZE (outermode) == UNITS_PER_WORD
2335           && GET_MODE_SIZE (innermode) > UNITS_PER_WORD
2336           && GET_MODE_CLASS (outermode) == MODE_INT)
2337         {
2338           rtx new = constant_subword (op,
2339                                       (byte / UNITS_PER_WORD),
2340                                       innermode);
2341           if (new)
2342             return new;
2343         }
2344
2345       offset = byte * BITS_PER_UNIT;
2346       switch (GET_CODE (op))
2347         {
2348         case CONST_DOUBLE:
2349           if (GET_MODE (op) != VOIDmode)
2350             break;
2351
2352           /* We can't handle this case yet.  */
2353           if (GET_MODE_BITSIZE (outermode) >= HOST_BITS_PER_WIDE_INT)
2354             return NULL_RTX;
2355
2356           part = offset >= HOST_BITS_PER_WIDE_INT;
2357           if ((BITS_PER_WORD > HOST_BITS_PER_WIDE_INT
2358                && BYTES_BIG_ENDIAN)
2359               || (BITS_PER_WORD <= HOST_BITS_PER_WIDE_INT
2360                   && WORDS_BIG_ENDIAN))
2361             part = !part;
2362           val = part ? CONST_DOUBLE_HIGH (op) : CONST_DOUBLE_LOW (op);
2363           offset %= HOST_BITS_PER_WIDE_INT;
2364
2365           /* We've already picked the word we want from a double, so 
2366              pretend this is actually an integer.  */
2367           innermode = mode_for_size (HOST_BITS_PER_WIDE_INT, MODE_INT, 0);
2368
2369           /* FALLTHROUGH */
2370         case CONST_INT:
2371           if (GET_CODE (op) == CONST_INT)
2372             val = INTVAL (op);
2373
2374           /* We don't handle synthetizing of non-integral constants yet.  */
2375           if (GET_MODE_CLASS (outermode) != MODE_INT)
2376             return NULL_RTX;
2377
2378           if (BYTES_BIG_ENDIAN || WORDS_BIG_ENDIAN)
2379             {
2380               if (WORDS_BIG_ENDIAN)
2381                 offset = (GET_MODE_BITSIZE (innermode)
2382                           - GET_MODE_BITSIZE (outermode) - offset);
2383               if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
2384                   && GET_MODE_SIZE (outermode) < UNITS_PER_WORD)
2385                 offset = (offset + BITS_PER_WORD - GET_MODE_BITSIZE (outermode)
2386                           - 2 * (offset % BITS_PER_WORD));
2387             }
2388
2389           if (offset >= HOST_BITS_PER_WIDE_INT)
2390             return ((HOST_WIDE_INT) val < 0) ? constm1_rtx : const0_rtx;
2391           else
2392             {
2393               val >>= offset;
2394               if (GET_MODE_BITSIZE (outermode) < HOST_BITS_PER_WIDE_INT)
2395                 val = trunc_int_for_mode (val, outermode);
2396               return GEN_INT (val);
2397             }
2398         default:
2399           break;
2400         }
2401     }
2402
2403   /* Changing mode twice with SUBREG => just change it once,
2404      or not at all if changing back op starting mode.  */
2405   if (GET_CODE (op) == SUBREG)
2406     {
2407       enum machine_mode innermostmode = GET_MODE (SUBREG_REG (op));
2408       int final_offset = byte + SUBREG_BYTE (op);
2409       rtx new;
2410
2411       if (outermode == innermostmode
2412           && byte == 0 && SUBREG_BYTE (op) == 0)
2413         return SUBREG_REG (op);
2414
2415       /* The SUBREG_BYTE represents offset, as if the value were stored
2416          in memory.  Irritating exception is paradoxical subreg, where
2417          we define SUBREG_BYTE to be 0.  On big endian machines, this
2418          value should be negative.  For a moment, undo this exception.  */
2419       if (byte == 0 && GET_MODE_SIZE (innermode) < GET_MODE_SIZE (outermode))
2420         {
2421           int difference = (GET_MODE_SIZE (innermode) - GET_MODE_SIZE (outermode));
2422           if (WORDS_BIG_ENDIAN)
2423             final_offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
2424           if (BYTES_BIG_ENDIAN)
2425             final_offset += difference % UNITS_PER_WORD;
2426         }
2427       if (SUBREG_BYTE (op) == 0
2428           && GET_MODE_SIZE (innermostmode) < GET_MODE_SIZE (innermode))
2429         {
2430           int difference = (GET_MODE_SIZE (innermostmode) - GET_MODE_SIZE (innermode));
2431           if (WORDS_BIG_ENDIAN)
2432             final_offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
2433           if (BYTES_BIG_ENDIAN)
2434             final_offset += difference % UNITS_PER_WORD;
2435         }
2436
2437       /* See whether resulting subreg will be paradoxical.  */
2438       if (GET_MODE_SIZE (innermostmode) > GET_MODE_SIZE (outermode))
2439         {
2440           /* In nonparadoxical subregs we can't handle negative offsets.  */
2441           if (final_offset < 0)
2442             return NULL_RTX;
2443           /* Bail out in case resulting subreg would be incorrect.  */
2444           if (final_offset % GET_MODE_SIZE (outermode)
2445               || (unsigned) final_offset >= GET_MODE_SIZE (innermostmode))
2446             return NULL_RTX;
2447         }
2448       else
2449         {
2450           int offset = 0;
2451           int difference = (GET_MODE_SIZE (innermostmode) - GET_MODE_SIZE (outermode));
2452
2453           /* In paradoxical subreg, see if we are still looking on lower part.
2454              If so, our SUBREG_BYTE will be 0.  */
2455           if (WORDS_BIG_ENDIAN)
2456             offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
2457           if (BYTES_BIG_ENDIAN)
2458             offset += difference % UNITS_PER_WORD;
2459           if (offset == final_offset)
2460             final_offset = 0;
2461           else
2462             return NULL_RTX;
2463         }
2464
2465       /* Recurse for futher possible simplifications.  */
2466       new = simplify_subreg (outermode, SUBREG_REG (op),
2467                              GET_MODE (SUBREG_REG (op)),
2468                              final_offset);
2469       if (new)
2470         return new;
2471       return gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset);
2472     }
2473
2474   /* SUBREG of a hard register => just change the register number
2475      and/or mode.  If the hard register is not valid in that mode,
2476      suppress this simplification.  If the hard register is the stack,
2477      frame, or argument pointer, leave this as a SUBREG.  */
2478
2479   if (REG_P (op)
2480       && (! REG_FUNCTION_VALUE_P (op)
2481           || ! rtx_equal_function_value_matters)
2482 #ifdef CLASS_CANNOT_CHANGE_MODE
2483       && ! (CLASS_CANNOT_CHANGE_MODE_P (outermode, innermode)
2484             && GET_MODE_CLASS (innermode) != MODE_COMPLEX_INT
2485             && GET_MODE_CLASS (innermode) != MODE_COMPLEX_FLOAT
2486             && (TEST_HARD_REG_BIT
2487                 (reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
2488                  REGNO (op))))
2489 #endif
2490       && REGNO (op) < FIRST_PSEUDO_REGISTER
2491       && ((reload_completed && !frame_pointer_needed)
2492           || (REGNO (op) != FRAME_POINTER_REGNUM
2493 #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
2494               && REGNO (op) != HARD_FRAME_POINTER_REGNUM
2495 #endif
2496              ))
2497 #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
2498       && REGNO (op) != ARG_POINTER_REGNUM
2499 #endif
2500       && REGNO (op) != STACK_POINTER_REGNUM)
2501     {
2502       int final_regno = subreg_hard_regno (gen_rtx_SUBREG (outermode, op, byte),
2503                                            0);
2504
2505       /* ??? We do allow it if the current REG is not valid for
2506          its mode.  This is a kludge to work around how float/complex
2507          arguments are passed on 32-bit Sparc and should be fixed.  */
2508       if (HARD_REGNO_MODE_OK (final_regno, outermode)
2509           || ! HARD_REGNO_MODE_OK (REGNO (op), innermode))
2510         return gen_rtx_REG (outermode, final_regno);
2511     }
2512
2513   /* If we have a SUBREG of a register that we are replacing and we are
2514      replacing it with a MEM, make a new MEM and try replacing the
2515      SUBREG with it.  Don't do this if the MEM has a mode-dependent address
2516      or if we would be widening it.  */
2517
2518   if (GET_CODE (op) == MEM
2519       && ! mode_dependent_address_p (XEXP (op, 0))
2520       /* Allow splitting of volatile memory references in case we don't
2521          have instruction to move the whole thing.  */
2522       && (! MEM_VOLATILE_P (op)
2523           || (mov_optab->handlers[(int) innermode].insn_code
2524               == CODE_FOR_nothing))
2525       && GET_MODE_SIZE (outermode) <= GET_MODE_SIZE (GET_MODE (op)))
2526     return adjust_address_nv (op, outermode, byte);
2527
2528   /* Handle complex values represented as CONCAT
2529      of real and imaginary part.  */
2530   if (GET_CODE (op) == CONCAT)
2531     {
2532       int is_realpart = byte < GET_MODE_UNIT_SIZE (innermode);
2533       rtx part = is_realpart ? XEXP (op, 0) : XEXP (op, 1);
2534       unsigned int final_offset;
2535       rtx res;
2536
2537       final_offset = byte % (GET_MODE_UNIT_SIZE (innermode));
2538       res = simplify_subreg (outermode, part, GET_MODE (part), final_offset);
2539       if (res)
2540         return res;
2541       /* We can at least simplify it by referring directly to the relevent part.  */
2542       return gen_rtx_SUBREG (outermode, part, final_offset);
2543     }
2544
2545   return NULL_RTX;
2546 }
2547 /* Make a SUBREG operation or equivalent if it folds.  */
2548
2549 rtx
2550 simplify_gen_subreg (outermode, op, innermode, byte)
2551      rtx op;
2552      unsigned int byte;
2553      enum machine_mode outermode, innermode;
2554 {
2555   rtx new;
2556   /* Little bit of sanity checking.  */
2557   if (innermode == VOIDmode || outermode == VOIDmode
2558       || innermode == BLKmode || outermode == BLKmode)
2559     abort ();
2560
2561   if (GET_MODE (op) != innermode
2562       && GET_MODE (op) != VOIDmode)
2563     abort ();
2564
2565   if (byte % GET_MODE_SIZE (outermode)
2566       || byte >= GET_MODE_SIZE (innermode))
2567     abort ();
2568
2569   if (GET_CODE (op) == QUEUED)
2570     return NULL_RTX;
2571
2572   new = simplify_subreg (outermode, op, innermode, byte);
2573   if (new)
2574     return new;
2575
2576   if (GET_CODE (op) == SUBREG || GET_MODE (op) == VOIDmode)
2577     return NULL_RTX;
2578
2579   return gen_rtx_SUBREG (outermode, op, byte);
2580 }
2581 /* Simplify X, an rtx expression.
2582
2583    Return the simplified expression or NULL if no simplifications
2584    were possible.
2585
2586    This is the preferred entry point into the simplification routines;
2587    however, we still allow passes to call the more specific routines.
2588
2589    Right now GCC has three (yes, three) major bodies of RTL simplficiation
2590    code that need to be unified.
2591
2592         1. fold_rtx in cse.c.  This code uses various CSE specific
2593            information to aid in RTL simplification.
2594
2595         2. simplify_rtx in combine.c.  Similar to fold_rtx, except that
2596            it uses combine specific information to aid in RTL
2597            simplification.
2598
2599         3. The routines in this file.
2600
2601
2602    Long term we want to only have one body of simplification code; to
2603    get to that state I recommend the following steps:
2604
2605         1. Pour over fold_rtx & simplify_rtx and move any simplifications
2606            which are not pass dependent state into these routines.
2607
2608         2. As code is moved by #1, change fold_rtx & simplify_rtx to
2609            use this routine whenever possible.
2610
2611         3. Allow for pass dependent state to be provided to these
2612            routines and add simplifications based on the pass dependent
2613            state.  Remove code from cse.c & combine.c that becomes
2614            redundant/dead.
2615
2616     It will take time, but ultimately the compiler will be easier to
2617     maintain and improve.  It's totally silly that when we add a
2618     simplification that it needs to be added to 4 places (3 for RTL
2619     simplification and 1 for tree simplification.  */
2620            
2621 rtx
2622 simplify_rtx (x)
2623      rtx x;
2624 {
2625   enum rtx_code code = GET_CODE (x);
2626   enum machine_mode mode = GET_MODE (x);
2627
2628   switch (GET_RTX_CLASS (code))
2629     {
2630     case '1':
2631       return simplify_unary_operation (code, mode,
2632                                        XEXP (x, 0), GET_MODE (XEXP (x, 0)));
2633     case 'c':
2634       if (swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
2635         {
2636           rtx tem;
2637
2638           tem = XEXP (x, 0);
2639           XEXP (x, 0) = XEXP (x, 1);
2640           XEXP (x, 1) = tem;
2641           return simplify_binary_operation (code, mode,
2642                                             XEXP (x, 0), XEXP (x, 1));
2643         }
2644
2645     case '2':
2646       return simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1));
2647
2648     case '3':
2649     case 'b':
2650       return simplify_ternary_operation (code, mode, GET_MODE (XEXP (x, 0)),
2651                                          XEXP (x, 0), XEXP (x, 1),
2652                                          XEXP (x, 2));
2653
2654     case '<':
2655       return simplify_relational_operation (code,
2656                                             ((GET_MODE (XEXP (x, 0))
2657                                               != VOIDmode)
2658                                              ? GET_MODE (XEXP (x, 0))
2659                                              : GET_MODE (XEXP (x, 1))),
2660                                             XEXP (x, 0), XEXP (x, 1));
2661     case 'x':
2662       /* The only case we try to handle is a SUBREG.  */
2663       if (code == SUBREG)
2664         return simplify_gen_subreg (mode, SUBREG_REG (x),
2665                                     GET_MODE (SUBREG_REG (x)),
2666                                     SUBREG_BYTE (x));
2667       return NULL;
2668     default:
2669       return NULL;
2670     }
2671 }