OSDN Git Service

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