dojump.c revision 146895
1/* Convert tree expression to rtl instructions, for GNU compiler.
2   Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3   2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 2, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING.  If not, write to the Free
19Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2002111-1307, USA.  */
21
22#include "config.h"
23#include "system.h"
24#include "coretypes.h"
25#include "tm.h"
26#include "rtl.h"
27#include "tree.h"
28#include "flags.h"
29#include "function.h"
30#include "insn-config.h"
31#include "insn-attr.h"
32/* Include expr.h after insn-config.h so we get HAVE_conditional_move.  */
33#include "expr.h"
34#include "optabs.h"
35#include "langhooks.h"
36#include "ggc.h"
37
38static bool prefer_and_bit_test (enum machine_mode, int);
39static void do_jump_by_parts_greater (tree, int, rtx, rtx);
40static void do_jump_by_parts_equality (tree, rtx, rtx);
41static void do_compare_and_jump	(tree, enum rtx_code, enum rtx_code, rtx,
42				 rtx);
43
44/* At the start of a function, record that we have no previously-pushed
45   arguments waiting to be popped.  */
46
47void
48init_pending_stack_adjust (void)
49{
50  pending_stack_adjust = 0;
51}
52
53/* Discard any pending stack adjustment.  This avoid relying on the
54   RTL optimizers to remove useless adjustments when we know the
55   stack pointer value is dead.  */
56void discard_pending_stack_adjust (void)
57{
58  stack_pointer_delta -= pending_stack_adjust;
59  pending_stack_adjust = 0;
60}
61
62/* When exiting from function, if safe, clear out any pending stack adjust
63   so the adjustment won't get done.
64
65   Note, if the current function calls alloca, then it must have a
66   frame pointer regardless of the value of flag_omit_frame_pointer.  */
67
68void
69clear_pending_stack_adjust (void)
70{
71  if (optimize > 0
72      && (! flag_omit_frame_pointer || current_function_calls_alloca)
73      && EXIT_IGNORE_STACK
74      && ! (DECL_INLINE (current_function_decl) && ! flag_no_inline)
75      && ! flag_inline_functions)
76    discard_pending_stack_adjust ();
77}
78
79/* Pop any previously-pushed arguments that have not been popped yet.  */
80
81void
82do_pending_stack_adjust (void)
83{
84  if (inhibit_defer_pop == 0)
85    {
86      if (pending_stack_adjust != 0)
87        adjust_stack (GEN_INT (pending_stack_adjust));
88      pending_stack_adjust = 0;
89    }
90}
91
92/* Expand conditional expressions.  */
93
94/* Generate code to evaluate EXP and jump to LABEL if the value is zero.
95   LABEL is an rtx of code CODE_LABEL, in this function and all the
96   functions here.  */
97
98void
99jumpifnot (tree exp, rtx label)
100{
101  do_jump (exp, label, NULL_RTX);
102}
103
104/* Generate code to evaluate EXP and jump to LABEL if the value is nonzero.  */
105
106void
107jumpif (tree exp, rtx label)
108{
109  do_jump (exp, NULL_RTX, label);
110}
111
112/* Used internally by prefer_and_bit_test.  */
113
114static GTY(()) rtx and_reg;
115static GTY(()) rtx and_test;
116static GTY(()) rtx shift_test;
117
118/* Compare the relative costs of "(X & (1 << BITNUM))" and "(X >> BITNUM) & 1"
119   where X is an arbitrary register of mode MODE.  Return true if the former
120   is preferred.  */
121
122static bool
123prefer_and_bit_test (enum machine_mode mode, int bitnum)
124{
125  if (and_test == 0)
126    {
127      /* Set up rtxes for the two variations.  Use NULL as a placeholder
128	 for the BITNUM-based constants.  */
129      and_reg = gen_rtx_REG (mode, FIRST_PSEUDO_REGISTER);
130      and_test = gen_rtx_AND (mode, and_reg, NULL);
131      shift_test = gen_rtx_AND (mode, gen_rtx_ASHIFTRT (mode, and_reg, NULL),
132				const1_rtx);
133    }
134  else
135    {
136      /* Change the mode of the previously-created rtxes.  */
137      PUT_MODE (and_reg, mode);
138      PUT_MODE (and_test, mode);
139      PUT_MODE (shift_test, mode);
140      PUT_MODE (XEXP (shift_test, 0), mode);
141    }
142
143  /* Fill in the integers.  */
144  XEXP (and_test, 1) = GEN_INT ((unsigned HOST_WIDE_INT) 1 << bitnum);
145  XEXP (XEXP (shift_test, 0), 1) = GEN_INT (bitnum);
146
147  return (rtx_cost (and_test, IF_THEN_ELSE)
148	  <= rtx_cost (shift_test, IF_THEN_ELSE));
149}
150
151/* Generate code to evaluate EXP and jump to IF_FALSE_LABEL if
152   the result is zero, or IF_TRUE_LABEL if the result is one.
153   Either of IF_FALSE_LABEL and IF_TRUE_LABEL may be zero,
154   meaning fall through in that case.
155
156   do_jump always does any pending stack adjust except when it does not
157   actually perform a jump.  An example where there is no jump
158   is when EXP is `(foo (), 0)' and IF_FALSE_LABEL is null.
159
160   This function is responsible for optimizing cases such as
161   &&, || and comparison operators in EXP.  */
162
163void
164do_jump (tree exp, rtx if_false_label, rtx if_true_label)
165{
166  enum tree_code code = TREE_CODE (exp);
167  /* Some cases need to create a label to jump to
168     in order to properly fall through.
169     These cases set DROP_THROUGH_LABEL nonzero.  */
170  rtx drop_through_label = 0;
171  rtx temp;
172  int i;
173  tree type;
174  enum machine_mode mode;
175
176  emit_queue ();
177
178  switch (code)
179    {
180    case ERROR_MARK:
181      break;
182
183    case INTEGER_CST:
184      temp = integer_zerop (exp) ? if_false_label : if_true_label;
185      if (temp)
186        emit_jump (temp);
187      break;
188
189#if 0
190      /* This is not true with #pragma weak  */
191    case ADDR_EXPR:
192      /* The address of something can never be zero.  */
193      if (if_true_label)
194        emit_jump (if_true_label);
195      break;
196#endif
197
198    case UNSAVE_EXPR:
199      do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label);
200      TREE_OPERAND (exp, 0)
201	= (*lang_hooks.unsave_expr_now) (TREE_OPERAND (exp, 0));
202      break;
203
204    case NOP_EXPR:
205      if (TREE_CODE (TREE_OPERAND (exp, 0)) == COMPONENT_REF
206          || TREE_CODE (TREE_OPERAND (exp, 0)) == BIT_FIELD_REF
207          || TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_REF
208          || TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_RANGE_REF)
209        goto normal;
210    case CONVERT_EXPR:
211      /* If we are narrowing the operand, we have to do the compare in the
212         narrower mode.  */
213      if ((TYPE_PRECISION (TREE_TYPE (exp))
214           < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0)))))
215        goto normal;
216    case NON_LVALUE_EXPR:
217    case REFERENCE_EXPR:
218    case ABS_EXPR:
219    case NEGATE_EXPR:
220    case LROTATE_EXPR:
221    case RROTATE_EXPR:
222      /* These cannot change zero->nonzero or vice versa.  */
223      do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label);
224      break;
225
226    case WITH_RECORD_EXPR:
227      /* Put the object on the placeholder list, recurse through our first
228         operand, and pop the list.  */
229      placeholder_list = tree_cons (TREE_OPERAND (exp, 1), NULL_TREE,
230                                    placeholder_list);
231      do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label);
232      placeholder_list = TREE_CHAIN (placeholder_list);
233      break;
234
235#if 0
236      /* This is never less insns than evaluating the PLUS_EXPR followed by
237         a test and can be longer if the test is eliminated.  */
238    case PLUS_EXPR:
239      /* Reduce to minus.  */
240      exp = build (MINUS_EXPR, TREE_TYPE (exp),
241                   TREE_OPERAND (exp, 0),
242                   fold (build1 (NEGATE_EXPR, TREE_TYPE (TREE_OPERAND (exp, 1)),
243                                 TREE_OPERAND (exp, 1))));
244      /* Process as MINUS.  */
245#endif
246
247    case MINUS_EXPR:
248      /* Nonzero iff operands of minus differ.  */
249      do_compare_and_jump (build (NE_EXPR, TREE_TYPE (exp),
250                                  TREE_OPERAND (exp, 0),
251                                  TREE_OPERAND (exp, 1)),
252                           NE, NE, if_false_label, if_true_label);
253      break;
254
255    case BIT_AND_EXPR:
256      /* fold_single_bit_test() converts (X & (1 << C)) into (X >> C) & 1.
257	 See if the former is preferred for jump tests and restore it
258	 if so.  */
259      if (integer_onep (TREE_OPERAND (exp, 1)))
260	{
261	  tree exp0 = TREE_OPERAND (exp, 0);
262	  rtx set_label, clr_label;
263
264	  /* Strip narrowing integral type conversions.  */
265	  while ((TREE_CODE (exp0) == NOP_EXPR
266		  || TREE_CODE (exp0) == CONVERT_EXPR
267		  || TREE_CODE (exp0) == NON_LVALUE_EXPR)
268		 && TREE_OPERAND (exp0, 0) != error_mark_node
269		 && TYPE_PRECISION (TREE_TYPE (exp0))
270		    <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp0, 0))))
271	    exp0 = TREE_OPERAND (exp0, 0);
272
273	  /* "exp0 ^ 1" inverts the sense of the single bit test.  */
274	  if (TREE_CODE (exp0) == BIT_XOR_EXPR
275	      && integer_onep (TREE_OPERAND (exp0, 1)))
276	    {
277	      exp0 = TREE_OPERAND (exp0, 0);
278	      clr_label = if_true_label;
279	      set_label = if_false_label;
280	    }
281	  else
282	    {
283	      clr_label = if_false_label;
284	      set_label = if_true_label;
285	    }
286
287	  if (TREE_CODE (exp0) == RSHIFT_EXPR)
288	    {
289	      tree arg = TREE_OPERAND (exp0, 0);
290	      tree shift = TREE_OPERAND (exp0, 1);
291	      tree argtype = TREE_TYPE (arg);
292	      if (TREE_CODE (shift) == INTEGER_CST
293		  && compare_tree_int (shift, 0) >= 0
294		  && compare_tree_int (shift, HOST_BITS_PER_WIDE_INT) < 0
295		  && prefer_and_bit_test (TYPE_MODE (argtype),
296					  TREE_INT_CST_LOW (shift)))
297		{
298		  HOST_WIDE_INT mask = (HOST_WIDE_INT) 1
299				       << TREE_INT_CST_LOW (shift);
300		  tree t = build_int_2 (mask, 0);
301		  TREE_TYPE (t) = argtype;
302		  do_jump (build (BIT_AND_EXPR, argtype, arg, t),
303			   clr_label, set_label);
304		  break;
305		}
306	    }
307	}
308
309      /* If we are AND'ing with a small constant, do this comparison in the
310         smallest type that fits.  If the machine doesn't have comparisons
311         that small, it will be converted back to the wider comparison.
312         This helps if we are testing the sign bit of a narrower object.
313         combine can't do this for us because it can't know whether a
314         ZERO_EXTRACT or a compare in a smaller mode exists, but we do.  */
315
316      if (! SLOW_BYTE_ACCESS
317          && TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST
318          && TYPE_PRECISION (TREE_TYPE (exp)) <= HOST_BITS_PER_WIDE_INT
319          && (i = tree_floor_log2 (TREE_OPERAND (exp, 1))) >= 0
320          && (mode = mode_for_size (i + 1, MODE_INT, 0)) != BLKmode
321          && (type = (*lang_hooks.types.type_for_mode) (mode, 1)) != 0
322          && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (exp))
323          && (cmp_optab->handlers[(int) TYPE_MODE (type)].insn_code
324              != CODE_FOR_nothing))
325        {
326          do_jump (convert (type, exp), if_false_label, if_true_label);
327          break;
328        }
329      goto normal;
330
331    case TRUTH_NOT_EXPR:
332      do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label);
333      break;
334
335    case TRUTH_ANDIF_EXPR:
336      if (if_false_label == 0)
337        if_false_label = drop_through_label = gen_label_rtx ();
338      do_jump (TREE_OPERAND (exp, 0), if_false_label, NULL_RTX);
339      start_cleanup_deferral ();
340      do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label);
341      end_cleanup_deferral ();
342      break;
343
344    case TRUTH_ORIF_EXPR:
345      if (if_true_label == 0)
346        if_true_label = drop_through_label = gen_label_rtx ();
347      do_jump (TREE_OPERAND (exp, 0), NULL_RTX, if_true_label);
348      start_cleanup_deferral ();
349      do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label);
350      end_cleanup_deferral ();
351      break;
352
353    case COMPOUND_EXPR:
354      push_temp_slots ();
355      expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, 0);
356      preserve_temp_slots (NULL_RTX);
357      free_temp_slots ();
358      pop_temp_slots ();
359      emit_queue ();
360      do_pending_stack_adjust ();
361      do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label);
362      break;
363
364    case COMPONENT_REF:
365    case BIT_FIELD_REF:
366    case ARRAY_REF:
367    case ARRAY_RANGE_REF:
368      {
369        HOST_WIDE_INT bitsize, bitpos;
370        int unsignedp;
371        enum machine_mode mode;
372        tree type;
373        tree offset;
374        int volatilep = 0;
375
376        /* Get description of this reference.  We don't actually care
377           about the underlying object here.  */
378        get_inner_reference (exp, &bitsize, &bitpos, &offset, &mode,
379                             &unsignedp, &volatilep);
380
381        type = (*lang_hooks.types.type_for_size) (bitsize, unsignedp);
382        if (! SLOW_BYTE_ACCESS
383            && type != 0 && bitsize >= 0
384            && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (exp))
385            && (cmp_optab->handlers[(int) TYPE_MODE (type)].insn_code
386          != CODE_FOR_nothing))
387          {
388            do_jump (convert (type, exp), if_false_label, if_true_label);
389            break;
390          }
391        goto normal;
392      }
393
394    case COND_EXPR:
395      /* Do (a ? 1 : 0) and (a ? 0 : 1) as special cases.  */
396      if (integer_onep (TREE_OPERAND (exp, 1))
397          && integer_zerop (TREE_OPERAND (exp, 2)))
398        do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label);
399
400      else if (integer_zerop (TREE_OPERAND (exp, 1))
401               && integer_onep (TREE_OPERAND (exp, 2)))
402        do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label);
403
404      else
405      {
406        rtx label1 = gen_label_rtx ();
407        drop_through_label = gen_label_rtx ();
408
409        do_jump (TREE_OPERAND (exp, 0), label1, NULL_RTX);
410
411        start_cleanup_deferral ();
412        /* Now the THEN-expression.  */
413        do_jump (TREE_OPERAND (exp, 1),
414                 if_false_label ? if_false_label : drop_through_label,
415                 if_true_label ? if_true_label : drop_through_label);
416        /* In case the do_jump just above never jumps.  */
417        do_pending_stack_adjust ();
418        emit_label (label1);
419
420        /* Now the ELSE-expression.  */
421        do_jump (TREE_OPERAND (exp, 2),
422           if_false_label ? if_false_label : drop_through_label,
423           if_true_label ? if_true_label : drop_through_label);
424        end_cleanup_deferral ();
425      }
426      break;
427
428    case EQ_EXPR:
429      {
430        tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
431
432        if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_COMPLEX_FLOAT
433            || GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_COMPLEX_INT)
434          {
435            tree exp0 = save_expr (TREE_OPERAND (exp, 0));
436            tree exp1 = save_expr (TREE_OPERAND (exp, 1));
437            do_jump
438              (fold
439               (build (TRUTH_ANDIF_EXPR, TREE_TYPE (exp),
440                 fold (build (EQ_EXPR, TREE_TYPE (exp),
441                  fold (build1 (REALPART_EXPR,
442                    TREE_TYPE (inner_type),
443                    exp0)),
444                  fold (build1 (REALPART_EXPR,
445                    TREE_TYPE (inner_type),
446                    exp1)))),
447                 fold (build (EQ_EXPR, TREE_TYPE (exp),
448                  fold (build1 (IMAGPART_EXPR,
449                    TREE_TYPE (inner_type),
450                    exp0)),
451                  fold (build1 (IMAGPART_EXPR,
452                    TREE_TYPE (inner_type),
453                    exp1)))))),
454               if_false_label, if_true_label);
455          }
456
457        else if (integer_zerop (TREE_OPERAND (exp, 1)))
458          do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label);
459
460        else if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_INT
461                 && !can_compare_p (EQ, TYPE_MODE (inner_type), ccp_jump))
462          do_jump_by_parts_equality (exp, if_false_label, if_true_label);
463        else
464          do_compare_and_jump (exp, EQ, EQ, if_false_label, if_true_label);
465        break;
466      }
467
468    case NE_EXPR:
469      {
470        tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
471
472        if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_COMPLEX_FLOAT
473            || GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_COMPLEX_INT)
474          {
475            tree exp0 = save_expr (TREE_OPERAND (exp, 0));
476            tree exp1 = save_expr (TREE_OPERAND (exp, 1));
477            do_jump
478              (fold
479               (build (TRUTH_ORIF_EXPR, TREE_TYPE (exp),
480                 fold (build (NE_EXPR, TREE_TYPE (exp),
481                  fold (build1 (REALPART_EXPR,
482                    TREE_TYPE (inner_type),
483                    exp0)),
484                  fold (build1 (REALPART_EXPR,
485                    TREE_TYPE (inner_type),
486                    exp1)))),
487                 fold (build (NE_EXPR, TREE_TYPE (exp),
488                    fold (build1 (IMAGPART_EXPR,
489                      TREE_TYPE (inner_type),
490                      exp0)),
491                    fold (build1 (IMAGPART_EXPR,
492                      TREE_TYPE (inner_type),
493                      exp1)))))),
494               if_false_label, if_true_label);
495          }
496
497        else if (integer_zerop (TREE_OPERAND (exp, 1)))
498          do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label);
499
500        else if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_INT
501           && !can_compare_p (NE, TYPE_MODE (inner_type), ccp_jump))
502          do_jump_by_parts_equality (exp, if_true_label, if_false_label);
503        else
504          do_compare_and_jump (exp, NE, NE, if_false_label, if_true_label);
505        break;
506      }
507
508    case LT_EXPR:
509      mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
510      if (GET_MODE_CLASS (mode) == MODE_INT
511          && ! can_compare_p (LT, mode, ccp_jump))
512        do_jump_by_parts_greater (exp, 1, if_false_label, if_true_label);
513      else
514        do_compare_and_jump (exp, LT, LTU, if_false_label, if_true_label);
515      break;
516
517    case LE_EXPR:
518      mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
519      if (GET_MODE_CLASS (mode) == MODE_INT
520          && ! can_compare_p (LE, mode, ccp_jump))
521        do_jump_by_parts_greater (exp, 0, if_true_label, if_false_label);
522      else
523        do_compare_and_jump (exp, LE, LEU, if_false_label, if_true_label);
524      break;
525
526    case GT_EXPR:
527      mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
528      if (GET_MODE_CLASS (mode) == MODE_INT
529          && ! can_compare_p (GT, mode, ccp_jump))
530        do_jump_by_parts_greater (exp, 0, if_false_label, if_true_label);
531      else
532        do_compare_and_jump (exp, GT, GTU, if_false_label, if_true_label);
533      break;
534
535    case GE_EXPR:
536      mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
537      if (GET_MODE_CLASS (mode) == MODE_INT
538          && ! can_compare_p (GE, mode, ccp_jump))
539        do_jump_by_parts_greater (exp, 1, if_true_label, if_false_label);
540      else
541        do_compare_and_jump (exp, GE, GEU, if_false_label, if_true_label);
542      break;
543
544    case UNORDERED_EXPR:
545    case ORDERED_EXPR:
546      {
547        enum rtx_code cmp, rcmp;
548        int do_rev;
549
550        if (code == UNORDERED_EXPR)
551          cmp = UNORDERED, rcmp = ORDERED;
552        else
553          cmp = ORDERED, rcmp = UNORDERED;
554        mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
555
556        do_rev = 0;
557        if (! can_compare_p (cmp, mode, ccp_jump)
558            && (can_compare_p (rcmp, mode, ccp_jump)
559          /* If the target doesn't provide either UNORDERED or ORDERED
560             comparisons, canonicalize on UNORDERED for the library.  */
561          || rcmp == UNORDERED))
562          do_rev = 1;
563
564        if (! do_rev)
565          do_compare_and_jump (exp, cmp, cmp, if_false_label, if_true_label);
566        else
567          do_compare_and_jump (exp, rcmp, rcmp, if_true_label, if_false_label);
568      }
569      break;
570
571    {
572      enum rtx_code rcode1;
573      enum tree_code tcode2;
574
575      case UNLT_EXPR:
576        rcode1 = UNLT;
577        tcode2 = LT_EXPR;
578        goto unordered_bcc;
579      case UNLE_EXPR:
580        rcode1 = UNLE;
581        tcode2 = LE_EXPR;
582        goto unordered_bcc;
583      case UNGT_EXPR:
584        rcode1 = UNGT;
585        tcode2 = GT_EXPR;
586        goto unordered_bcc;
587      case UNGE_EXPR:
588        rcode1 = UNGE;
589        tcode2 = GE_EXPR;
590        goto unordered_bcc;
591      case UNEQ_EXPR:
592        rcode1 = UNEQ;
593        tcode2 = EQ_EXPR;
594        goto unordered_bcc;
595
596      unordered_bcc:
597        mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
598        if (can_compare_p (rcode1, mode, ccp_jump))
599          do_compare_and_jump (exp, rcode1, rcode1, if_false_label,
600                               if_true_label);
601        else
602          {
603            tree op0 = save_expr (TREE_OPERAND (exp, 0));
604            tree op1 = save_expr (TREE_OPERAND (exp, 1));
605            tree cmp0, cmp1;
606
607            /* If the target doesn't support combined unordered
608               compares, decompose into UNORDERED + comparison.  */
609            cmp0 = fold (build (UNORDERED_EXPR, TREE_TYPE (exp), op0, op1));
610            cmp1 = fold (build (tcode2, TREE_TYPE (exp), op0, op1));
611            exp = build (TRUTH_ORIF_EXPR, TREE_TYPE (exp), cmp0, cmp1);
612            do_jump (exp, if_false_label, if_true_label);
613          }
614      }
615      break;
616
617      /* Special case:
618          __builtin_expect (<test>, 0)	and
619          __builtin_expect (<test>, 1)
620
621         We need to do this here, so that <test> is not converted to a SCC
622         operation on machines that use condition code registers and COMPARE
623         like the PowerPC, and then the jump is done based on whether the SCC
624         operation produced a 1 or 0.  */
625    case CALL_EXPR:
626      /* Check for a built-in function.  */
627      {
628	tree fndecl = get_callee_fndecl (exp);
629	tree arglist = TREE_OPERAND (exp, 1);
630
631	if (fndecl
632	    && DECL_BUILT_IN (fndecl)
633	    && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT
634	    && arglist != NULL_TREE
635	    && TREE_CHAIN (arglist) != NULL_TREE)
636	  {
637	    rtx seq = expand_builtin_expect_jump (exp, if_false_label,
638						  if_true_label);
639
640	    if (seq != NULL_RTX)
641	      {
642		emit_insn (seq);
643		return;
644	      }
645	  }
646      }
647      /* Fall through and generate the normal code.  */
648
649    default:
650    normal:
651      temp = expand_expr (exp, NULL_RTX, VOIDmode, 0);
652#if 0
653      /* This is not needed any more and causes poor code since it causes
654         comparisons and tests from non-SI objects to have different code
655         sequences.  */
656      /* Copy to register to avoid generating bad insns by cse
657         from (set (mem ...) (arithop))  (set (cc0) (mem ...)).  */
658      if (!cse_not_expected && GET_CODE (temp) == MEM)
659        temp = copy_to_reg (temp);
660#endif
661      do_pending_stack_adjust ();
662      /* Do any postincrements in the expression that was tested.  */
663      emit_queue ();
664
665      if (GET_CODE (temp) == CONST_INT
666          || (GET_CODE (temp) == CONST_DOUBLE && GET_MODE (temp) == VOIDmode)
667          || GET_CODE (temp) == LABEL_REF)
668        {
669          rtx target = temp == const0_rtx ? if_false_label : if_true_label;
670          if (target)
671            emit_jump (target);
672        }
673      else if (GET_MODE_CLASS (GET_MODE (temp)) == MODE_INT
674               && ! can_compare_p (NE, GET_MODE (temp), ccp_jump))
675        /* Note swapping the labels gives us not-equal.  */
676        do_jump_by_parts_equality_rtx (temp, if_true_label, if_false_label);
677      else if (GET_MODE (temp) != VOIDmode)
678	{
679	  /* The RTL optimizers prefer comparisons against pseudos.  */
680	  if (GET_CODE (temp) == SUBREG)
681	    {
682	      /* Compare promoted variables in their promoted mode.  */
683	      if (SUBREG_PROMOTED_VAR_P (temp)
684		  && GET_CODE (XEXP (temp, 0)) == REG)
685		temp = XEXP (temp, 0);
686	      else
687		temp = copy_to_reg (temp);
688	    }
689	  do_compare_rtx_and_jump (temp, CONST0_RTX (GET_MODE (temp)),
690				   NE, TREE_UNSIGNED (TREE_TYPE (exp)),
691				   GET_MODE (temp), NULL_RTX,
692				   if_false_label, if_true_label);
693	}
694      else
695        abort ();
696    }
697
698  if (drop_through_label)
699    {
700      /* If do_jump produces code that might be jumped around,
701         do any stack adjusts from that code, before the place
702         where control merges in.  */
703      do_pending_stack_adjust ();
704      emit_label (drop_through_label);
705    }
706}
707
708/* Given a comparison expression EXP for values too wide to be compared
709   with one insn, test the comparison and jump to the appropriate label.
710   The code of EXP is ignored; we always test GT if SWAP is 0,
711   and LT if SWAP is 1.  */
712
713static void
714do_jump_by_parts_greater (tree exp, int swap, rtx if_false_label,
715			  rtx if_true_label)
716{
717  rtx op0 = expand_expr (TREE_OPERAND (exp, swap), NULL_RTX, VOIDmode, 0);
718  rtx op1 = expand_expr (TREE_OPERAND (exp, !swap), NULL_RTX, VOIDmode, 0);
719  enum machine_mode mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
720  int unsignedp = TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0)));
721
722  do_jump_by_parts_greater_rtx (mode, unsignedp, op0, op1, if_false_label, if_true_label);
723}
724
725/* Compare OP0 with OP1, word at a time, in mode MODE.
726   UNSIGNEDP says to do unsigned comparison.
727   Jump to IF_TRUE_LABEL if OP0 is greater, IF_FALSE_LABEL otherwise.  */
728
729void
730do_jump_by_parts_greater_rtx (enum machine_mode mode, int unsignedp, rtx op0,
731			      rtx op1, rtx if_false_label, rtx if_true_label)
732{
733  int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
734  rtx drop_through_label = 0;
735  int i;
736
737  if (! if_true_label || ! if_false_label)
738    drop_through_label = gen_label_rtx ();
739  if (! if_true_label)
740    if_true_label = drop_through_label;
741  if (! if_false_label)
742    if_false_label = drop_through_label;
743
744  /* Compare a word at a time, high order first.  */
745  for (i = 0; i < nwords; i++)
746    {
747      rtx op0_word, op1_word;
748
749      if (WORDS_BIG_ENDIAN)
750        {
751          op0_word = operand_subword_force (op0, i, mode);
752          op1_word = operand_subword_force (op1, i, mode);
753        }
754      else
755        {
756          op0_word = operand_subword_force (op0, nwords - 1 - i, mode);
757          op1_word = operand_subword_force (op1, nwords - 1 - i, mode);
758        }
759
760      /* All but high-order word must be compared as unsigned.  */
761      do_compare_rtx_and_jump (op0_word, op1_word, GT,
762                               (unsignedp || i > 0), word_mode, NULL_RTX,
763                               NULL_RTX, if_true_label);
764
765      /* Consider lower words only if these are equal.  */
766      do_compare_rtx_and_jump (op0_word, op1_word, NE, unsignedp, word_mode,
767                               NULL_RTX, NULL_RTX, if_false_label);
768    }
769
770  if (if_false_label)
771    emit_jump (if_false_label);
772  if (drop_through_label)
773    emit_label (drop_through_label);
774}
775
776/* Given an EQ_EXPR expression EXP for values too wide to be compared
777   with one insn, test the comparison and jump to the appropriate label.  */
778
779static void
780do_jump_by_parts_equality (tree exp, rtx if_false_label, rtx if_true_label)
781{
782  rtx op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, 0);
783  rtx op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
784  enum machine_mode mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
785  int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
786  int i;
787  rtx drop_through_label = 0;
788
789  if (! if_false_label)
790    drop_through_label = if_false_label = gen_label_rtx ();
791
792  for (i = 0; i < nwords; i++)
793    do_compare_rtx_and_jump (operand_subword_force (op0, i, mode),
794                             operand_subword_force (op1, i, mode),
795                             EQ, TREE_UNSIGNED (TREE_TYPE (exp)),
796                             word_mode, NULL_RTX, if_false_label, NULL_RTX);
797
798  if (if_true_label)
799    emit_jump (if_true_label);
800  if (drop_through_label)
801    emit_label (drop_through_label);
802}
803
804/* Jump according to whether OP0 is 0.
805   We assume that OP0 has an integer mode that is too wide
806   for the available compare insns.  */
807
808void
809do_jump_by_parts_equality_rtx (rtx op0, rtx if_false_label, rtx if_true_label)
810{
811  int nwords = GET_MODE_SIZE (GET_MODE (op0)) / UNITS_PER_WORD;
812  rtx part;
813  int i;
814  rtx drop_through_label = 0;
815
816  /* The fastest way of doing this comparison on almost any machine is to
817     "or" all the words and compare the result.  If all have to be loaded
818     from memory and this is a very wide item, it's possible this may
819     be slower, but that's highly unlikely.  */
820
821  part = gen_reg_rtx (word_mode);
822  emit_move_insn (part, operand_subword_force (op0, 0, GET_MODE (op0)));
823  for (i = 1; i < nwords && part != 0; i++)
824    part = expand_binop (word_mode, ior_optab, part,
825                         operand_subword_force (op0, i, GET_MODE (op0)),
826                         part, 1, OPTAB_WIDEN);
827
828  if (part != 0)
829    {
830      do_compare_rtx_and_jump (part, const0_rtx, EQ, 1, word_mode,
831                               NULL_RTX, if_false_label, if_true_label);
832
833      return;
834    }
835
836  /* If we couldn't do the "or" simply, do this with a series of compares.  */
837  if (! if_false_label)
838    drop_through_label = if_false_label = gen_label_rtx ();
839
840  for (i = 0; i < nwords; i++)
841    do_compare_rtx_and_jump (operand_subword_force (op0, i, GET_MODE (op0)),
842                             const0_rtx, EQ, 1, word_mode, NULL_RTX,
843                             if_false_label, NULL_RTX);
844
845  if (if_true_label)
846    emit_jump (if_true_label);
847
848  if (drop_through_label)
849    emit_label (drop_through_label);
850}
851
852/* Generate code for a comparison of OP0 and OP1 with rtx code CODE.
853   (including code to compute the values to be compared)
854   and set (CC0) according to the result.
855   The decision as to signed or unsigned comparison must be made by the caller.
856
857   We force a stack adjustment unless there are currently
858   things pushed on the stack that aren't yet used.
859
860   If MODE is BLKmode, SIZE is an RTX giving the size of the objects being
861   compared.  */
862
863rtx
864compare_from_rtx (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
865		  enum machine_mode mode, rtx size)
866{
867  enum rtx_code ucode;
868  rtx tem;
869
870  /* If one operand is constant, make it the second one.  Only do this
871     if the other operand is not constant as well.  */
872
873  if (swap_commutative_operands_p (op0, op1))
874    {
875      tem = op0;
876      op0 = op1;
877      op1 = tem;
878      code = swap_condition (code);
879    }
880
881  if (flag_force_mem)
882    {
883      op0 = force_not_mem (op0);
884      op1 = force_not_mem (op1);
885    }
886
887  do_pending_stack_adjust ();
888
889  ucode = unsignedp ? unsigned_condition (code) : code;
890  if ((tem = simplify_relational_operation (ucode, mode, op0, op1)) != 0)
891    return tem;
892
893#if 0
894  /* There's no need to do this now that combine.c can eliminate lots of
895     sign extensions.  This can be less efficient in certain cases on other
896     machines.  */
897
898  /* If this is a signed equality comparison, we can do it as an
899     unsigned comparison since zero-extension is cheaper than sign
900     extension and comparisons with zero are done as unsigned.  This is
901     the case even on machines that can do fast sign extension, since
902     zero-extension is easier to combine with other operations than
903     sign-extension is.  If we are comparing against a constant, we must
904     convert it to what it would look like unsigned.  */
905  if ((code == EQ || code == NE) && ! unsignedp
906      && GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT)
907    {
908      if (GET_CODE (op1) == CONST_INT
909          && (INTVAL (op1) & GET_MODE_MASK (GET_MODE (op0))) != INTVAL (op1))
910        op1 = GEN_INT (INTVAL (op1) & GET_MODE_MASK (GET_MODE (op0)));
911      unsignedp = 1;
912    }
913#endif
914
915  emit_cmp_insn (op0, op1, code, size, mode, unsignedp);
916
917#if HAVE_cc0
918  return gen_rtx_fmt_ee (code, VOIDmode, cc0_rtx, const0_rtx);
919#else
920  return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
921#endif
922}
923
924/* Like do_compare_and_jump but expects the values to compare as two rtx's.
925   The decision as to signed or unsigned comparison must be made by the caller.
926
927   If MODE is BLKmode, SIZE is an RTX giving the size of the objects being
928   compared.  */
929
930void
931do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
932			 enum machine_mode mode, rtx size, rtx if_false_label,
933			 rtx if_true_label)
934{
935  enum rtx_code ucode;
936  rtx tem;
937  int dummy_true_label = 0;
938
939  /* Reverse the comparison if that is safe and we want to jump if it is
940     false.  */
941  if (! if_true_label && ! FLOAT_MODE_P (mode))
942    {
943      if_true_label = if_false_label;
944      if_false_label = 0;
945      code = reverse_condition (code);
946    }
947
948  /* If one operand is constant, make it the second one.  Only do this
949     if the other operand is not constant as well.  */
950
951  if (swap_commutative_operands_p (op0, op1))
952    {
953      tem = op0;
954      op0 = op1;
955      op1 = tem;
956      code = swap_condition (code);
957    }
958
959  if (flag_force_mem)
960    {
961      op0 = force_not_mem (op0);
962      op1 = force_not_mem (op1);
963    }
964
965  do_pending_stack_adjust ();
966
967  ucode = unsignedp ? unsigned_condition (code) : code;
968  if ((tem = simplify_relational_operation (ucode, mode, op0, op1)) != 0)
969    {
970      if (tem == const_true_rtx)
971        {
972          if (if_true_label)
973            emit_jump (if_true_label);
974        }
975      else
976        {
977          if (if_false_label)
978            emit_jump (if_false_label);
979        }
980      return;
981    }
982
983#if 0
984  /* There's no need to do this now that combine.c can eliminate lots of
985     sign extensions.  This can be less efficient in certain cases on other
986     machines.  */
987
988  /* If this is a signed equality comparison, we can do it as an
989     unsigned comparison since zero-extension is cheaper than sign
990     extension and comparisons with zero are done as unsigned.  This is
991     the case even on machines that can do fast sign extension, since
992     zero-extension is easier to combine with other operations than
993     sign-extension is.  If we are comparing against a constant, we must
994     convert it to what it would look like unsigned.  */
995  if ((code == EQ || code == NE) && ! unsignedp
996      && GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT)
997    {
998      if (GET_CODE (op1) == CONST_INT
999          && (INTVAL (op1) & GET_MODE_MASK (GET_MODE (op0))) != INTVAL (op1))
1000        op1 = GEN_INT (INTVAL (op1) & GET_MODE_MASK (GET_MODE (op0)));
1001      unsignedp = 1;
1002    }
1003#endif
1004
1005  if (! if_true_label)
1006    {
1007      dummy_true_label = 1;
1008      if_true_label = gen_label_rtx ();
1009    }
1010
1011  emit_cmp_and_jump_insns (op0, op1, code, size, mode, unsignedp,
1012                           if_true_label);
1013
1014  if (if_false_label)
1015    emit_jump (if_false_label);
1016  if (dummy_true_label)
1017    emit_label (if_true_label);
1018}
1019
1020/* Generate code for a comparison expression EXP (including code to compute
1021   the values to be compared) and a conditional jump to IF_FALSE_LABEL and/or
1022   IF_TRUE_LABEL.  One of the labels can be NULL_RTX, in which case the
1023   generated code will drop through.
1024   SIGNED_CODE should be the rtx operation for this comparison for
1025   signed data; UNSIGNED_CODE, likewise for use if data is unsigned.
1026
1027   We force a stack adjustment unless there are currently
1028   things pushed on the stack that aren't yet used.  */
1029
1030static void
1031do_compare_and_jump (tree exp, enum rtx_code signed_code,
1032		     enum rtx_code unsigned_code, rtx if_false_label,
1033		     rtx if_true_label)
1034{
1035  rtx op0, op1;
1036  tree type;
1037  enum machine_mode mode;
1038  int unsignedp;
1039  enum rtx_code code;
1040
1041  /* Don't crash if the comparison was erroneous.  */
1042  op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, 0);
1043  if (TREE_CODE (TREE_OPERAND (exp, 0)) == ERROR_MARK)
1044    return;
1045
1046  op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
1047  if (TREE_CODE (TREE_OPERAND (exp, 1)) == ERROR_MARK)
1048    return;
1049
1050  type = TREE_TYPE (TREE_OPERAND (exp, 0));
1051  mode = TYPE_MODE (type);
1052  if (TREE_CODE (TREE_OPERAND (exp, 0)) == INTEGER_CST
1053      && (TREE_CODE (TREE_OPERAND (exp, 1)) != INTEGER_CST
1054          || (GET_MODE_BITSIZE (mode)
1055              > GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp,
1056                                                                      1)))))))
1057    {
1058      /* op0 might have been replaced by promoted constant, in which
1059         case the type of second argument should be used.  */
1060      type = TREE_TYPE (TREE_OPERAND (exp, 1));
1061      mode = TYPE_MODE (type);
1062    }
1063  unsignedp = TREE_UNSIGNED (type);
1064  code = unsignedp ? unsigned_code : signed_code;
1065
1066#ifdef HAVE_canonicalize_funcptr_for_compare
1067  /* If function pointers need to be "canonicalized" before they can
1068     be reliably compared, then canonicalize them.  */
1069  if (HAVE_canonicalize_funcptr_for_compare
1070      && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == POINTER_TYPE
1071      && (TREE_CODE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))))
1072          == FUNCTION_TYPE))
1073    {
1074      rtx new_op0 = gen_reg_rtx (mode);
1075
1076      emit_insn (gen_canonicalize_funcptr_for_compare (new_op0, op0));
1077      op0 = new_op0;
1078    }
1079
1080  if (HAVE_canonicalize_funcptr_for_compare
1081      && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 1))) == POINTER_TYPE
1082      && (TREE_CODE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 1))))
1083          == FUNCTION_TYPE))
1084    {
1085      rtx new_op1 = gen_reg_rtx (mode);
1086
1087      emit_insn (gen_canonicalize_funcptr_for_compare (new_op1, op1));
1088      op1 = new_op1;
1089    }
1090#endif
1091
1092  /* Do any postincrements in the expression that was tested.  */
1093  emit_queue ();
1094
1095  do_compare_rtx_and_jump (op0, op1, code, unsignedp, mode,
1096                           ((mode == BLKmode)
1097                            ? expr_size (TREE_OPERAND (exp, 0)) : NULL_RTX),
1098                           if_false_label, if_true_label);
1099}
1100
1101#include "gt-dojump.h"
1102