OSDN Git Service

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