OSDN Git Service

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