OSDN Git Service

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