OSDN Git Service

PR c++/49165
[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, 2005, 2006, 2007, 2008, 2009, 2010
4    Free Software Foundation, Inc.
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
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 #include "basic-block.h"
38 #include "output.h"
39
40 static bool prefer_and_bit_test (enum machine_mode, int);
41 static void do_jump_by_parts_greater (tree, tree, int, rtx, rtx, int);
42 static void do_jump_by_parts_equality (tree, tree, rtx, rtx, int);
43 static void do_compare_and_jump (tree, tree, enum rtx_code, enum rtx_code, rtx,
44                                  rtx, int);
45
46 /* Invert probability if there is any.  -1 stands for unknown.  */
47
48 static inline int
49 inv (int prob)
50 {
51   return prob == -1 ? -1 : REG_BR_PROB_BASE - prob;
52 }
53
54 /* At the start of a function, record that we have no previously-pushed
55    arguments waiting to be popped.  */
56
57 void
58 init_pending_stack_adjust (void)
59 {
60   pending_stack_adjust = 0;
61 }
62
63 /* Discard any pending stack adjustment.  This avoid relying on the
64    RTL optimizers to remove useless adjustments when we know the
65    stack pointer value is dead.  */
66 void
67 discard_pending_stack_adjust (void)
68 {
69   stack_pointer_delta -= pending_stack_adjust;
70   pending_stack_adjust = 0;
71 }
72
73 /* When exiting from function, if safe, clear out any pending stack adjust
74    so the adjustment won't get done.
75
76    Note, if the current function calls alloca, then it must have a
77    frame pointer regardless of the value of flag_omit_frame_pointer.  */
78
79 void
80 clear_pending_stack_adjust (void)
81 {
82   if (optimize > 0
83       && (! flag_omit_frame_pointer || cfun->calls_alloca)
84       && EXIT_IGNORE_STACK)
85     discard_pending_stack_adjust ();
86 }
87
88 /* Pop any previously-pushed arguments that have not been popped yet.  */
89
90 void
91 do_pending_stack_adjust (void)
92 {
93   if (inhibit_defer_pop == 0)
94     {
95       if (pending_stack_adjust != 0)
96         adjust_stack (GEN_INT (pending_stack_adjust));
97       pending_stack_adjust = 0;
98     }
99 }
100 \f
101 /* Expand conditional expressions.  */
102
103 /* Generate code to evaluate EXP and jump to LABEL if the value is zero.
104    LABEL is an rtx of code CODE_LABEL, in this function and all the
105    functions here.  */
106
107 void
108 jumpifnot (tree exp, rtx label, int prob)
109 {
110   do_jump (exp, label, NULL_RTX, inv (prob));
111 }
112
113 void
114 jumpifnot_1 (enum tree_code code, tree op0, tree op1, rtx label, int prob)
115 {
116   do_jump_1 (code, op0, op1, label, NULL_RTX, inv (prob));
117 }
118
119 /* Generate code to evaluate EXP and jump to LABEL if the value is nonzero.  */
120
121 void
122 jumpif (tree exp, rtx label, int prob)
123 {
124   do_jump (exp, NULL_RTX, label, prob);
125 }
126
127 void
128 jumpif_1 (enum tree_code code, tree op0, tree op1, rtx label, int prob)
129 {
130   do_jump_1 (code, op0, op1, NULL_RTX, label, prob);
131 }
132
133 /* Used internally by prefer_and_bit_test.  */
134
135 static GTY(()) rtx and_reg;
136 static GTY(()) rtx and_test;
137 static GTY(()) rtx shift_test;
138
139 /* Compare the relative costs of "(X & (1 << BITNUM))" and "(X >> BITNUM) & 1",
140    where X is an arbitrary register of mode MODE.  Return true if the former
141    is preferred.  */
142
143 static bool
144 prefer_and_bit_test (enum machine_mode mode, int bitnum)
145 {
146   if (and_test == 0)
147     {
148       /* Set up rtxes for the two variations.  Use NULL as a placeholder
149          for the BITNUM-based constants.  */
150       and_reg = gen_rtx_REG (mode, FIRST_PSEUDO_REGISTER);
151       and_test = gen_rtx_AND (mode, and_reg, NULL);
152       shift_test = gen_rtx_AND (mode, gen_rtx_ASHIFTRT (mode, and_reg, NULL),
153                                 const1_rtx);
154     }
155   else
156     {
157       /* Change the mode of the previously-created rtxes.  */
158       PUT_MODE (and_reg, mode);
159       PUT_MODE (and_test, mode);
160       PUT_MODE (shift_test, mode);
161       PUT_MODE (XEXP (shift_test, 0), mode);
162     }
163
164   /* Fill in the integers.  */
165   XEXP (and_test, 1)
166     = immed_double_int_const (double_int_setbit (double_int_zero, bitnum),
167                                                  mode);
168   XEXP (XEXP (shift_test, 0), 1) = GEN_INT (bitnum);
169
170   return (rtx_cost (and_test, IF_THEN_ELSE, optimize_insn_for_speed_p ())
171           <= rtx_cost (shift_test, IF_THEN_ELSE, optimize_insn_for_speed_p ()));
172 }
173
174 /* Subroutine of do_jump, dealing with exploded comparisons of the type
175    OP0 CODE OP1 .  IF_FALSE_LABEL and IF_TRUE_LABEL like in do_jump.
176    PROB is probability of jump to if_true_label, or -1 if unknown.  */
177
178 void
179 do_jump_1 (enum tree_code code, tree op0, tree op1,
180            rtx if_false_label, rtx if_true_label, int prob)
181 {
182   enum machine_mode mode;
183   rtx drop_through_label = 0;
184
185   switch (code)
186     {
187     case EQ_EXPR:
188       {
189         tree inner_type = TREE_TYPE (op0);
190
191         gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
192                     != MODE_COMPLEX_FLOAT);
193         gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
194                     != MODE_COMPLEX_INT);
195
196         if (integer_zerop (op1))
197           do_jump (op0, if_true_label, if_false_label, inv (prob));
198         else if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_INT
199                  && !can_compare_p (EQ, TYPE_MODE (inner_type), ccp_jump))
200           do_jump_by_parts_equality (op0, op1, if_false_label, if_true_label,
201                                      prob);
202         else
203           do_compare_and_jump (op0, op1, EQ, EQ, if_false_label, if_true_label,
204                                prob);
205         break;
206       }
207
208     case NE_EXPR:
209       {
210         tree inner_type = TREE_TYPE (op0);
211
212         gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
213                     != MODE_COMPLEX_FLOAT);
214         gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
215                     != MODE_COMPLEX_INT);
216
217         if (integer_zerop (op1))
218           do_jump (op0, if_false_label, if_true_label, prob);
219         else if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_INT
220            && !can_compare_p (NE, TYPE_MODE (inner_type), ccp_jump))
221           do_jump_by_parts_equality (op0, op1, if_true_label, if_false_label,
222                                      inv (prob));
223         else
224           do_compare_and_jump (op0, op1, NE, NE, if_false_label, if_true_label,
225                                prob);
226         break;
227       }
228
229     case LT_EXPR:
230       mode = TYPE_MODE (TREE_TYPE (op0));
231       if (GET_MODE_CLASS (mode) == MODE_INT
232           && ! can_compare_p (LT, mode, ccp_jump))
233         do_jump_by_parts_greater (op0, op1, 1, if_false_label, if_true_label,
234                                   prob);
235       else
236         do_compare_and_jump (op0, op1, LT, LTU, if_false_label, if_true_label,
237                              prob);
238       break;
239
240     case LE_EXPR:
241       mode = TYPE_MODE (TREE_TYPE (op0));
242       if (GET_MODE_CLASS (mode) == MODE_INT
243           && ! can_compare_p (LE, mode, ccp_jump))
244         do_jump_by_parts_greater (op0, op1, 0, if_true_label, if_false_label,
245                                   inv (prob));
246       else
247         do_compare_and_jump (op0, op1, LE, LEU, if_false_label, if_true_label,
248                              prob);
249       break;
250
251     case GT_EXPR:
252       mode = TYPE_MODE (TREE_TYPE (op0));
253       if (GET_MODE_CLASS (mode) == MODE_INT
254           && ! can_compare_p (GT, mode, ccp_jump))
255         do_jump_by_parts_greater (op0, op1, 0, if_false_label, if_true_label,
256                                   prob);
257       else
258         do_compare_and_jump (op0, op1, GT, GTU, if_false_label, if_true_label,
259                              prob);
260       break;
261
262     case GE_EXPR:
263       mode = TYPE_MODE (TREE_TYPE (op0));
264       if (GET_MODE_CLASS (mode) == MODE_INT
265           && ! can_compare_p (GE, mode, ccp_jump))
266         do_jump_by_parts_greater (op0, op1, 1, if_true_label, if_false_label,
267                                   inv (prob));
268       else
269         do_compare_and_jump (op0, op1, GE, GEU, if_false_label, if_true_label,
270                              prob);
271       break;
272
273     case ORDERED_EXPR:
274       do_compare_and_jump (op0, op1, ORDERED, ORDERED,
275                            if_false_label, if_true_label, prob);
276       break;
277
278     case UNORDERED_EXPR:
279       do_compare_and_jump (op0, op1, UNORDERED, UNORDERED,
280                            if_false_label, if_true_label, prob);
281       break;
282
283     case UNLT_EXPR:
284       do_compare_and_jump (op0, op1, UNLT, UNLT, if_false_label, if_true_label,
285                            prob);
286       break;
287
288     case UNLE_EXPR:
289       do_compare_and_jump (op0, op1, UNLE, UNLE, if_false_label, if_true_label,
290                            prob);
291       break;
292
293     case UNGT_EXPR:
294       do_compare_and_jump (op0, op1, UNGT, UNGT, if_false_label, if_true_label,
295                            prob);
296       break;
297
298     case UNGE_EXPR:
299       do_compare_and_jump (op0, op1, UNGE, UNGE, if_false_label, if_true_label,
300                            prob);
301       break;
302
303     case UNEQ_EXPR:
304       do_compare_and_jump (op0, op1, UNEQ, UNEQ, if_false_label, if_true_label,
305                            prob);
306       break;
307
308     case LTGT_EXPR:
309       do_compare_and_jump (op0, op1, LTGT, LTGT, if_false_label, if_true_label,
310                            prob);
311       break;
312
313     case TRUTH_ANDIF_EXPR:
314       if (if_false_label == NULL_RTX)
315         {
316           drop_through_label = gen_label_rtx ();
317           do_jump (op0, drop_through_label, NULL_RTX, prob);
318           do_jump (op1, NULL_RTX, if_true_label, prob);
319         }
320       else
321         {
322           do_jump (op0, if_false_label, NULL_RTX, prob);
323           do_jump (op1, if_false_label, if_true_label, prob);
324         }
325       break;
326
327     case TRUTH_ORIF_EXPR:
328       if (if_true_label == NULL_RTX)
329         {
330           drop_through_label = gen_label_rtx ();
331           do_jump (op0, NULL_RTX, drop_through_label, prob);
332           do_jump (op1, if_false_label, NULL_RTX, prob);
333         }
334       else
335         {
336           do_jump (op0, NULL_RTX, if_true_label, prob);
337           do_jump (op1, if_false_label, if_true_label, prob);
338         }
339       break;
340
341     default:
342       gcc_unreachable ();
343     }
344
345   if (drop_through_label)
346     {
347       do_pending_stack_adjust ();
348       emit_label (drop_through_label);
349     }
350 }
351
352 /* Generate code to evaluate EXP and jump to IF_FALSE_LABEL if
353    the result is zero, or IF_TRUE_LABEL if the result is one.
354    Either of IF_FALSE_LABEL and IF_TRUE_LABEL may be zero,
355    meaning fall through in that case.
356
357    do_jump always does any pending stack adjust except when it does not
358    actually perform a jump.  An example where there is no jump
359    is when EXP is `(foo (), 0)' and IF_FALSE_LABEL is null.
360
361    PROB is probability of jump to if_true_label, or -1 if unknown.  */
362
363 void
364 do_jump (tree exp, rtx if_false_label, rtx if_true_label, int prob)
365 {
366   enum tree_code code = TREE_CODE (exp);
367   rtx temp;
368   int i;
369   tree type;
370   enum machine_mode mode;
371   rtx drop_through_label = 0;
372
373   switch (code)
374     {
375     case ERROR_MARK:
376       break;
377
378     case INTEGER_CST:
379       temp = integer_zerop (exp) ? if_false_label : if_true_label;
380       if (temp)
381         emit_jump (temp);
382       break;
383
384 #if 0
385       /* This is not true with #pragma weak  */
386     case ADDR_EXPR:
387       /* The address of something can never be zero.  */
388       if (if_true_label)
389         emit_jump (if_true_label);
390       break;
391 #endif
392
393     case NOP_EXPR:
394       if (TREE_CODE (TREE_OPERAND (exp, 0)) == COMPONENT_REF
395           || TREE_CODE (TREE_OPERAND (exp, 0)) == BIT_FIELD_REF
396           || TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_REF
397           || TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_RANGE_REF)
398         goto normal;
399     case CONVERT_EXPR:
400       /* If we are narrowing the operand, we have to do the compare in the
401          narrower mode.  */
402       if ((TYPE_PRECISION (TREE_TYPE (exp))
403            < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0)))))
404         goto normal;
405     case NON_LVALUE_EXPR:
406     case ABS_EXPR:
407     case NEGATE_EXPR:
408     case LROTATE_EXPR:
409     case RROTATE_EXPR:
410       /* These cannot change zero->nonzero or vice versa.  */
411       do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label, prob);
412       break;
413
414     case TRUTH_NOT_EXPR:
415       do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label,
416                inv (prob));
417       break;
418
419     case COND_EXPR:
420       {
421         rtx label1 = gen_label_rtx ();
422         if (!if_true_label || !if_false_label)
423           {
424             drop_through_label = gen_label_rtx ();
425             if (!if_true_label)
426               if_true_label = drop_through_label;
427             if (!if_false_label)
428               if_false_label = drop_through_label;
429           }
430
431         do_pending_stack_adjust ();
432         do_jump (TREE_OPERAND (exp, 0), label1, NULL_RTX, -1);
433         do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label, prob);
434         emit_label (label1);
435         do_jump (TREE_OPERAND (exp, 2), if_false_label, if_true_label, prob);
436         break;
437       }
438
439     case COMPOUND_EXPR:
440       /* Lowered by gimplify.c.  */
441       gcc_unreachable ();
442
443     case COMPONENT_REF:
444     case BIT_FIELD_REF:
445     case ARRAY_REF:
446     case ARRAY_RANGE_REF:
447       {
448         HOST_WIDE_INT bitsize, bitpos;
449         int unsignedp;
450         enum machine_mode mode;
451         tree type;
452         tree offset;
453         int volatilep = 0;
454
455         /* Get description of this reference.  We don't actually care
456            about the underlying object here.  */
457         get_inner_reference (exp, &bitsize, &bitpos, &offset, &mode,
458                              &unsignedp, &volatilep, false);
459
460         type = lang_hooks.types.type_for_size (bitsize, unsignedp);
461         if (! SLOW_BYTE_ACCESS
462             && type != 0 && bitsize >= 0
463             && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (exp))
464             && have_insn_for (COMPARE, TYPE_MODE (type)))
465           {
466             do_jump (fold_convert (type, exp), if_false_label, if_true_label,
467                      prob);
468             break;
469           }
470         goto normal;
471       }
472
473     case MINUS_EXPR:
474       /* Nonzero iff operands of minus differ.  */
475       code = NE_EXPR;
476
477       /* FALLTHRU */
478     case EQ_EXPR:
479     case NE_EXPR:
480     case LT_EXPR:
481     case LE_EXPR:
482     case GT_EXPR:
483     case GE_EXPR:
484     case ORDERED_EXPR:
485     case UNORDERED_EXPR:
486     case UNLT_EXPR:
487     case UNLE_EXPR:
488     case UNGT_EXPR:
489     case UNGE_EXPR:
490     case UNEQ_EXPR:
491     case LTGT_EXPR:
492     case TRUTH_ANDIF_EXPR:
493     case TRUTH_ORIF_EXPR:
494     other_code:
495       do_jump_1 (code, TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
496                  if_false_label, if_true_label, prob);
497       break;
498
499     case BIT_AND_EXPR:
500       /* fold_single_bit_test() converts (X & (1 << C)) into (X >> C) & 1.
501          See if the former is preferred for jump tests and restore it
502          if so.  */
503       if (integer_onep (TREE_OPERAND (exp, 1)))
504         {
505           tree exp0 = TREE_OPERAND (exp, 0);
506           rtx set_label, clr_label;
507           int setclr_prob = prob;
508
509           /* Strip narrowing integral type conversions.  */
510           while (CONVERT_EXPR_P (exp0)
511                  && TREE_OPERAND (exp0, 0) != error_mark_node
512                  && TYPE_PRECISION (TREE_TYPE (exp0))
513                     <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp0, 0))))
514             exp0 = TREE_OPERAND (exp0, 0);
515
516           /* "exp0 ^ 1" inverts the sense of the single bit test.  */
517           if (TREE_CODE (exp0) == BIT_XOR_EXPR
518               && integer_onep (TREE_OPERAND (exp0, 1)))
519             {
520               exp0 = TREE_OPERAND (exp0, 0);
521               clr_label = if_true_label;
522               set_label = if_false_label;
523               setclr_prob = inv (prob);
524             }
525           else
526             {
527               clr_label = if_false_label;
528               set_label = if_true_label;
529             }
530
531           if (TREE_CODE (exp0) == RSHIFT_EXPR)
532             {
533               tree arg = TREE_OPERAND (exp0, 0);
534               tree shift = TREE_OPERAND (exp0, 1);
535               tree argtype = TREE_TYPE (arg);
536               if (TREE_CODE (shift) == INTEGER_CST
537                   && compare_tree_int (shift, 0) >= 0
538                   && compare_tree_int (shift, HOST_BITS_PER_WIDE_INT) < 0
539                   && prefer_and_bit_test (TYPE_MODE (argtype),
540                                           TREE_INT_CST_LOW (shift)))
541                 {
542                   unsigned HOST_WIDE_INT mask
543                     = (unsigned HOST_WIDE_INT) 1 << TREE_INT_CST_LOW (shift);
544                   do_jump (build2 (BIT_AND_EXPR, argtype, arg,
545                                    build_int_cstu (argtype, mask)),
546                            clr_label, set_label, setclr_prob);
547                   break;
548                 }
549             }
550         }
551
552       /* If we are AND'ing with a small constant, do this comparison in the
553          smallest type that fits.  If the machine doesn't have comparisons
554          that small, it will be converted back to the wider comparison.
555          This helps if we are testing the sign bit of a narrower object.
556          combine can't do this for us because it can't know whether a
557          ZERO_EXTRACT or a compare in a smaller mode exists, but we do.  */
558
559       if (! SLOW_BYTE_ACCESS
560           && TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST
561           && TYPE_PRECISION (TREE_TYPE (exp)) <= HOST_BITS_PER_WIDE_INT
562           && (i = tree_floor_log2 (TREE_OPERAND (exp, 1))) >= 0
563           && (mode = mode_for_size (i + 1, MODE_INT, 0)) != BLKmode
564           && (type = lang_hooks.types.type_for_mode (mode, 1)) != 0
565           && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (exp))
566           && have_insn_for (COMPARE, TYPE_MODE (type)))
567         {
568           do_jump (fold_convert (type, exp), if_false_label, if_true_label,
569                    prob);
570           break;
571         }
572
573       if (TYPE_PRECISION (TREE_TYPE (exp)) > 1
574           || TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST)
575         goto normal;
576
577       /* Boolean comparisons can be compiled as TRUTH_AND_EXPR.  */
578
579     case TRUTH_AND_EXPR:
580       /* High branch cost, expand as the bitwise AND of the conditions.
581          Do the same if the RHS has side effects, because we're effectively
582          turning a TRUTH_AND_EXPR into a TRUTH_ANDIF_EXPR.  */
583       if (BRANCH_COST (optimize_insn_for_speed_p (),
584                        false) >= 4
585           || TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 1)))
586         goto normal;
587       code = TRUTH_ANDIF_EXPR;
588       goto other_code;
589
590     case BIT_IOR_EXPR:
591     case TRUTH_OR_EXPR:
592       /* High branch cost, expand as the bitwise OR of the conditions.
593          Do the same if the RHS has side effects, because we're effectively
594          turning a TRUTH_OR_EXPR into a TRUTH_ORIF_EXPR.  */
595       if (BRANCH_COST (optimize_insn_for_speed_p (), false) >= 4
596           || TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 1)))
597         goto normal;
598       code = TRUTH_ORIF_EXPR;
599       goto other_code;
600
601       /* Fall through and generate the normal code.  */
602     default:
603     normal:
604       temp = expand_normal (exp);
605       do_pending_stack_adjust ();
606       /* The RTL optimizers prefer comparisons against pseudos.  */
607       if (GET_CODE (temp) == SUBREG)
608         {
609           /* Compare promoted variables in their promoted mode.  */
610           if (SUBREG_PROMOTED_VAR_P (temp)
611               && REG_P (XEXP (temp, 0)))
612             temp = XEXP (temp, 0);
613           else
614             temp = copy_to_reg (temp);
615         }
616       do_compare_rtx_and_jump (temp, CONST0_RTX (GET_MODE (temp)),
617                                NE, TYPE_UNSIGNED (TREE_TYPE (exp)),
618                                GET_MODE (temp), NULL_RTX,
619                                if_false_label, if_true_label, prob);
620     }
621
622   if (drop_through_label)
623     {
624       do_pending_stack_adjust ();
625       emit_label (drop_through_label);
626     }
627 }
628 \f
629 /* Compare OP0 with OP1, word at a time, in mode MODE.
630    UNSIGNEDP says to do unsigned comparison.
631    Jump to IF_TRUE_LABEL if OP0 is greater, IF_FALSE_LABEL otherwise.  */
632
633 static void
634 do_jump_by_parts_greater_rtx (enum machine_mode mode, int unsignedp, rtx op0,
635                               rtx op1, rtx if_false_label, rtx if_true_label,
636                               int prob)
637 {
638   int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
639   rtx drop_through_label = 0;
640   bool drop_through_if_true = false, drop_through_if_false = false;
641   enum rtx_code code = GT;
642   int i;
643
644   if (! if_true_label || ! if_false_label)
645     drop_through_label = gen_label_rtx ();
646   if (! if_true_label)
647     {
648       if_true_label = drop_through_label;
649       drop_through_if_true = true;
650     }
651   if (! if_false_label)
652     {
653       if_false_label = drop_through_label;
654       drop_through_if_false = true;
655     }
656
657   /* Deal with the special case 0 > x: only one comparison is necessary and
658      we reverse it to avoid jumping to the drop-through label.  */
659   if (op0 == const0_rtx && drop_through_if_true && !drop_through_if_false)
660     {
661       code = LE;
662       if_true_label = if_false_label;
663       if_false_label = drop_through_label;
664       drop_through_if_true = false;
665       drop_through_if_false = true;
666     }
667
668   /* Compare a word at a time, high order first.  */
669   for (i = 0; i < nwords; i++)
670     {
671       rtx op0_word, op1_word;
672
673       if (WORDS_BIG_ENDIAN)
674         {
675           op0_word = operand_subword_force (op0, i, mode);
676           op1_word = operand_subword_force (op1, i, mode);
677         }
678       else
679         {
680           op0_word = operand_subword_force (op0, nwords - 1 - i, mode);
681           op1_word = operand_subword_force (op1, nwords - 1 - i, mode);
682         }
683
684       /* All but high-order word must be compared as unsigned.  */
685       do_compare_rtx_and_jump (op0_word, op1_word, code, (unsignedp || i > 0),
686                                word_mode, NULL_RTX, NULL_RTX, if_true_label,
687                                prob);
688
689       /* Emit only one comparison for 0.  Do not emit the last cond jump.  */
690       if (op0 == const0_rtx || i == nwords - 1)
691         break;
692
693       /* Consider lower words only if these are equal.  */
694       do_compare_rtx_and_jump (op0_word, op1_word, NE, unsignedp, word_mode,
695                                NULL_RTX, NULL_RTX, if_false_label, inv (prob));
696     }
697
698   if (!drop_through_if_false)
699     emit_jump (if_false_label);
700   if (drop_through_label)
701     emit_label (drop_through_label);
702 }
703
704 /* Given a comparison expression EXP for values too wide to be compared
705    with one insn, test the comparison and jump to the appropriate label.
706    The code of EXP is ignored; we always test GT if SWAP is 0,
707    and LT if SWAP is 1.  */
708
709 static void
710 do_jump_by_parts_greater (tree treeop0, tree treeop1, int swap,
711                           rtx if_false_label, rtx if_true_label, int prob)
712 {
713   rtx op0 = expand_normal (swap ? treeop1 : treeop0);
714   rtx op1 = expand_normal (swap ? treeop0 : treeop1);
715   enum machine_mode mode = TYPE_MODE (TREE_TYPE (treeop0));
716   int unsignedp = TYPE_UNSIGNED (TREE_TYPE (treeop0));
717
718   do_jump_by_parts_greater_rtx (mode, unsignedp, op0, op1, if_false_label,
719                                 if_true_label, prob);
720 }
721 \f
722 /* Jump according to whether OP0 is 0.  We assume that OP0 has an integer
723    mode, MODE, that is too wide for the available compare insns.  Either
724    Either (but not both) of IF_TRUE_LABEL and IF_FALSE_LABEL may be NULL_RTX
725    to indicate drop through.  */
726
727 static void
728 do_jump_by_parts_zero_rtx (enum machine_mode mode, rtx op0,
729                            rtx if_false_label, rtx if_true_label, int prob)
730 {
731   int nwords = GET_MODE_SIZE (mode) / UNITS_PER_WORD;
732   rtx part;
733   int i;
734   rtx drop_through_label = 0;
735
736   /* The fastest way of doing this comparison on almost any machine is to
737      "or" all the words and compare the result.  If all have to be loaded
738      from memory and this is a very wide item, it's possible this may
739      be slower, but that's highly unlikely.  */
740
741   part = gen_reg_rtx (word_mode);
742   emit_move_insn (part, operand_subword_force (op0, 0, mode));
743   for (i = 1; i < nwords && part != 0; i++)
744     part = expand_binop (word_mode, ior_optab, part,
745                          operand_subword_force (op0, i, mode),
746                          part, 1, OPTAB_WIDEN);
747
748   if (part != 0)
749     {
750       do_compare_rtx_and_jump (part, const0_rtx, EQ, 1, word_mode,
751                                NULL_RTX, if_false_label, if_true_label, prob);
752       return;
753     }
754
755   /* If we couldn't do the "or" simply, do this with a series of compares.  */
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                              const0_rtx, EQ, 1, word_mode, NULL_RTX,
762                              if_false_label, NULL_RTX, prob);
763
764   if (if_true_label)
765     emit_jump (if_true_label);
766
767   if (drop_through_label)
768     emit_label (drop_through_label);
769 }
770
771 /* Test for the equality of two RTX expressions OP0 and OP1 in mode MODE,
772    where MODE is an integer mode too wide to be compared with one insn.
773    Either (but not both) of IF_TRUE_LABEL and IF_FALSE_LABEL may be NULL_RTX
774    to indicate drop through.  */
775
776 static void
777 do_jump_by_parts_equality_rtx (enum machine_mode mode, rtx op0, rtx op1,
778                                rtx if_false_label, rtx if_true_label, int prob)
779 {
780   int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
781   rtx drop_through_label = 0;
782   int i;
783
784   if (op1 == const0_rtx)
785     {
786       do_jump_by_parts_zero_rtx (mode, op0, if_false_label, if_true_label,
787                                  prob);
788       return;
789     }
790   else if (op0 == const0_rtx)
791     {
792       do_jump_by_parts_zero_rtx (mode, op1, if_false_label, if_true_label,
793                                  prob);
794       return;
795     }
796
797   if (! if_false_label)
798     drop_through_label = if_false_label = gen_label_rtx ();
799
800   for (i = 0; i < nwords; i++)
801     do_compare_rtx_and_jump (operand_subword_force (op0, i, mode),
802                              operand_subword_force (op1, i, mode),
803                              EQ, 0, word_mode, NULL_RTX,
804                              if_false_label, NULL_RTX, prob);
805
806   if (if_true_label)
807     emit_jump (if_true_label);
808   if (drop_through_label)
809     emit_label (drop_through_label);
810 }
811
812 /* Given an EQ_EXPR expression EXP for values too wide to be compared
813    with one insn, test the comparison and jump to the appropriate label.  */
814
815 static void
816 do_jump_by_parts_equality (tree treeop0, tree treeop1, rtx if_false_label,
817                            rtx if_true_label, int prob)
818 {
819   rtx op0 = expand_normal (treeop0);
820   rtx op1 = expand_normal (treeop1);
821   enum machine_mode mode = TYPE_MODE (TREE_TYPE (treeop0));
822   do_jump_by_parts_equality_rtx (mode, op0, op1, if_false_label,
823                                  if_true_label, prob);
824 }
825 \f
826 /* Split a comparison into two others, the second of which has the other
827    "orderedness".  The first is always ORDERED or UNORDERED if MODE
828    does not honor NaNs (which means that it can be skipped in that case;
829    see do_compare_rtx_and_jump).
830
831    The two conditions are written in *CODE1 and *CODE2.  Return true if
832    the conditions must be ANDed, false if they must be ORed.  */
833
834 bool
835 split_comparison (enum rtx_code code, enum machine_mode mode,
836                   enum rtx_code *code1, enum rtx_code *code2)
837 {
838   switch (code)
839     {
840     case LT:
841       *code1 = ORDERED;
842       *code2 = UNLT;
843       return true;
844     case LE:
845       *code1 = ORDERED;
846       *code2 = UNLE;
847       return true;
848     case GT:
849       *code1 = ORDERED;
850       *code2 = UNGT;
851       return true;
852     case GE:
853       *code1 = ORDERED;
854       *code2 = UNGE;
855       return true;
856     case EQ:
857       *code1 = ORDERED;
858       *code2 = UNEQ;
859       return true;
860     case NE:
861       *code1 = UNORDERED;
862       *code2 = LTGT;
863       return false;
864     case UNLT:
865       *code1 = UNORDERED;
866       *code2 = LT;
867       return false;
868     case UNLE:
869       *code1 = UNORDERED;
870       *code2 = LE;
871       return false;
872     case UNGT:
873       *code1 = UNORDERED;
874       *code2 = GT;
875       return false;
876     case UNGE:
877       *code1 = UNORDERED;
878       *code2 = GE;
879       return false;
880     case UNEQ:
881       *code1 = UNORDERED;
882       *code2 = EQ;
883       return false;
884     case LTGT:
885       /* Do not turn a trapping comparison into a non-trapping one.  */
886       if (HONOR_SNANS (mode))
887         {
888           *code1 = LT;
889           *code2 = GT;
890           return false;
891         }
892       else
893         {
894           *code1 = ORDERED;
895           *code2 = NE;
896           return true;
897         }
898     default:
899       gcc_unreachable ();
900     }
901 }
902
903
904 /* Like do_compare_and_jump but expects the values to compare as two rtx's.
905    The decision as to signed or unsigned comparison must be made by the caller.
906
907    If MODE is BLKmode, SIZE is an RTX giving the size of the objects being
908    compared.  */
909
910 void
911 do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
912                          enum machine_mode mode, rtx size, rtx if_false_label,
913                          rtx if_true_label, int prob)
914 {
915   rtx tem;
916   rtx dummy_label = NULL_RTX;
917   rtx last;
918
919   /* Reverse the comparison if that is safe and we want to jump if it is
920      false.  Also convert to the reverse comparison if the target can
921      implement it.  */
922   if ((! if_true_label
923        || ! can_compare_p (code, mode, ccp_jump))
924       && (! FLOAT_MODE_P (mode)
925           || code == ORDERED || code == UNORDERED
926           || (! HONOR_NANS (mode) && (code == LTGT || code == UNEQ))
927           || (! HONOR_SNANS (mode) && (code == EQ || code == NE))))
928     {
929       enum rtx_code rcode;
930       if (FLOAT_MODE_P (mode))
931         rcode = reverse_condition_maybe_unordered (code);
932       else
933         rcode = reverse_condition (code);
934
935       /* Canonicalize to UNORDERED for the libcall.  */
936       if (can_compare_p (rcode, mode, ccp_jump)
937           || (code == ORDERED && ! can_compare_p (ORDERED, mode, ccp_jump)))
938         {
939           tem = if_true_label;
940           if_true_label = if_false_label;
941           if_false_label = tem;
942           code = rcode;
943           prob = inv (prob);
944         }
945     }
946
947   /* If one operand is constant, make it the second one.  Only do this
948      if the other operand is not constant as well.  */
949
950   if (swap_commutative_operands_p (op0, op1))
951     {
952       tem = op0;
953       op0 = op1;
954       op1 = tem;
955       code = swap_condition (code);
956     }
957
958   do_pending_stack_adjust ();
959
960   code = unsignedp ? unsigned_condition (code) : code;
961   if (0 != (tem = simplify_relational_operation (code, mode, VOIDmode,
962                                                  op0, op1)))
963     {
964       if (CONSTANT_P (tem))
965         {
966           rtx label = (tem == const0_rtx || tem == CONST0_RTX (mode))
967                       ? if_false_label : if_true_label;
968           if (label)
969             emit_jump (label);
970           return;
971         }
972
973       code = GET_CODE (tem);
974       mode = GET_MODE (tem);
975       op0 = XEXP (tem, 0);
976       op1 = XEXP (tem, 1);
977       unsignedp = (code == GTU || code == LTU || code == GEU || code == LEU);
978     }
979
980   if (! if_true_label)
981     dummy_label = if_true_label = gen_label_rtx ();
982
983   if (GET_MODE_CLASS (mode) == MODE_INT
984       && ! can_compare_p (code, mode, ccp_jump))
985     {
986       switch (code)
987         {
988         case LTU:
989           do_jump_by_parts_greater_rtx (mode, 1, op1, op0,
990                                         if_false_label, if_true_label, prob);
991           break;
992
993         case LEU:
994           do_jump_by_parts_greater_rtx (mode, 1, op0, op1,
995                                         if_true_label, if_false_label,
996                                         inv (prob));
997           break;
998
999         case GTU:
1000           do_jump_by_parts_greater_rtx (mode, 1, op0, op1,
1001                                         if_false_label, if_true_label, prob);
1002           break;
1003
1004         case GEU:
1005           do_jump_by_parts_greater_rtx (mode, 1, op1, op0,
1006                                         if_true_label, if_false_label,
1007                                         inv (prob));
1008           break;
1009
1010         case LT:
1011           do_jump_by_parts_greater_rtx (mode, 0, op1, op0,
1012                                         if_false_label, if_true_label, prob);
1013           break;
1014
1015         case LE:
1016           do_jump_by_parts_greater_rtx (mode, 0, op0, op1,
1017                                         if_true_label, if_false_label,
1018                                         inv (prob));
1019           break;
1020
1021         case GT:
1022           do_jump_by_parts_greater_rtx (mode, 0, op0, op1,
1023                                         if_false_label, if_true_label, prob);
1024           break;
1025
1026         case GE:
1027           do_jump_by_parts_greater_rtx (mode, 0, op1, op0,
1028                                         if_true_label, if_false_label,
1029                                         inv (prob));
1030           break;
1031
1032         case EQ:
1033           do_jump_by_parts_equality_rtx (mode, op0, op1, if_false_label,
1034                                          if_true_label, prob);
1035           break;
1036
1037         case NE:
1038           do_jump_by_parts_equality_rtx (mode, op0, op1, if_true_label,
1039                                          if_false_label, inv (prob));
1040           break;
1041
1042         default:
1043           gcc_unreachable ();
1044         }
1045     }
1046   else
1047     {
1048       if (GET_MODE_CLASS (mode) == MODE_FLOAT
1049           && ! can_compare_p (code, mode, ccp_jump)
1050           && can_compare_p (swap_condition (code), mode, ccp_jump))
1051         {
1052           rtx tmp;
1053           code = swap_condition (code);
1054           tmp = op0;
1055           op0 = op1;
1056           op1 = tmp;
1057         }
1058
1059       else if (GET_MODE_CLASS (mode) == MODE_FLOAT
1060                && ! can_compare_p (code, mode, ccp_jump)
1061
1062                /* Never split ORDERED and UNORDERED.  These must be implemented.  */
1063                && (code != ORDERED && code != UNORDERED)
1064
1065                /* Split a floating-point comparison if we can jump on other
1066                   conditions...  */
1067                && (have_insn_for (COMPARE, mode)
1068
1069                    /* ... or if there is no libcall for it.  */
1070                    || code_to_optab[code] == NULL))
1071         {
1072           enum rtx_code first_code;
1073           bool and_them = split_comparison (code, mode, &first_code, &code);
1074
1075           /* If there are no NaNs, the first comparison should always fall
1076              through.  */
1077           if (!HONOR_NANS (mode))
1078             gcc_assert (first_code == (and_them ? ORDERED : UNORDERED));
1079
1080           else
1081             {
1082               if (and_them)
1083                 {
1084                   rtx dest_label;
1085                   /* If we only jump if true, just bypass the second jump.  */
1086                   if (! if_false_label)
1087                     {
1088                       if (! dummy_label)
1089                         dummy_label = gen_label_rtx ();
1090                       dest_label = dummy_label;
1091                     }
1092                   else
1093                     dest_label = if_false_label;
1094                   do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode,
1095                                            size, dest_label, NULL_RTX, prob);
1096                 }
1097               else
1098                 do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode,
1099                                          size, NULL_RTX, if_true_label, prob);
1100             }
1101         }
1102
1103       last = get_last_insn ();
1104       emit_cmp_and_jump_insns (op0, op1, code, size, mode, unsignedp,
1105                                if_true_label);
1106       if (prob != -1 && profile_status != PROFILE_ABSENT)
1107         {
1108           for (last = NEXT_INSN (last);
1109                last && NEXT_INSN (last);
1110                last = NEXT_INSN (last))
1111             if (JUMP_P (last))
1112               break;
1113           if (!last
1114               || !JUMP_P (last)
1115               || NEXT_INSN (last)
1116               || !any_condjump_p (last))
1117             {
1118               if (dump_file)
1119                 fprintf (dump_file, "Failed to add probability note\n");
1120             }
1121           else
1122             {
1123               gcc_assert (!find_reg_note (last, REG_BR_PROB, 0));
1124               add_reg_note (last, REG_BR_PROB, GEN_INT (prob));
1125             }
1126         }
1127     }
1128
1129   if (if_false_label)
1130     emit_jump (if_false_label);
1131   if (dummy_label)
1132     emit_label (dummy_label);
1133 }
1134
1135 /* Generate code for a comparison expression EXP (including code to compute
1136    the values to be compared) and a conditional jump to IF_FALSE_LABEL and/or
1137    IF_TRUE_LABEL.  One of the labels can be NULL_RTX, in which case the
1138    generated code will drop through.
1139    SIGNED_CODE should be the rtx operation for this comparison for
1140    signed data; UNSIGNED_CODE, likewise for use if data is unsigned.
1141
1142    We force a stack adjustment unless there are currently
1143    things pushed on the stack that aren't yet used.  */
1144
1145 static void
1146 do_compare_and_jump (tree treeop0, tree treeop1, enum rtx_code signed_code,
1147                      enum rtx_code unsigned_code, rtx if_false_label,
1148                      rtx if_true_label, int prob)
1149 {
1150   rtx op0, op1;
1151   tree type;
1152   enum machine_mode mode;
1153   int unsignedp;
1154   enum rtx_code code;
1155
1156   /* Don't crash if the comparison was erroneous.  */
1157   op0 = expand_normal (treeop0);
1158   if (TREE_CODE (treeop0) == ERROR_MARK)
1159     return;
1160
1161   op1 = expand_normal (treeop1);
1162   if (TREE_CODE (treeop1) == ERROR_MARK)
1163     return;
1164
1165   type = TREE_TYPE (treeop0);
1166   mode = TYPE_MODE (type);
1167   if (TREE_CODE (treeop0) == INTEGER_CST
1168       && (TREE_CODE (treeop1) != INTEGER_CST
1169           || (GET_MODE_BITSIZE (mode)
1170               > GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (treeop1))))))
1171     {
1172       /* op0 might have been replaced by promoted constant, in which
1173          case the type of second argument should be used.  */
1174       type = TREE_TYPE (treeop1);
1175       mode = TYPE_MODE (type);
1176     }
1177   unsignedp = TYPE_UNSIGNED (type);
1178   code = unsignedp ? unsigned_code : signed_code;
1179
1180 #ifdef HAVE_canonicalize_funcptr_for_compare
1181   /* If function pointers need to be "canonicalized" before they can
1182      be reliably compared, then canonicalize them.
1183      Only do this if *both* sides of the comparison are function pointers.
1184      If one side isn't, we want a noncanonicalized comparison.  See PR
1185      middle-end/17564.  */
1186   if (HAVE_canonicalize_funcptr_for_compare
1187       && TREE_CODE (TREE_TYPE (treeop0)) == POINTER_TYPE
1188       && TREE_CODE (TREE_TYPE (TREE_TYPE (treeop0)))
1189           == FUNCTION_TYPE
1190       && TREE_CODE (TREE_TYPE (treeop1)) == POINTER_TYPE
1191       && TREE_CODE (TREE_TYPE (TREE_TYPE (treeop1)))
1192           == FUNCTION_TYPE)
1193     {
1194       rtx new_op0 = gen_reg_rtx (mode);
1195       rtx new_op1 = gen_reg_rtx (mode);
1196
1197       emit_insn (gen_canonicalize_funcptr_for_compare (new_op0, op0));
1198       op0 = new_op0;
1199
1200       emit_insn (gen_canonicalize_funcptr_for_compare (new_op1, op1));
1201       op1 = new_op1;
1202     }
1203 #endif
1204
1205   do_compare_rtx_and_jump (op0, op1, code, unsignedp, mode,
1206                            ((mode == BLKmode)
1207                             ? expr_size (treeop0) : NULL_RTX),
1208                            if_false_label, if_true_label, prob);
1209 }
1210
1211 #include "gt-dojump.h"