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