Merge trunk version 193672 into gupc branch.
[official-gcc.git] / gcc / dojump.c
blobc1acdd3297d6403e4549b04d4d98b47861ff0f78
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.
6 This file is part of GCC.
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.
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.
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/>. */
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 "tm_p.h"
40 static bool prefer_and_bit_test (enum machine_mode, int);
41 static void do_jump_by_parts_greater (tree, tree, int, rtx, rtx, int);
42 static void do_jump_by_parts_equality (tree, tree, rtx, rtx, int);
43 static void do_compare_and_jump (tree, tree, enum rtx_code, enum rtx_code, rtx,
44 rtx, int);
46 /* Invert probability if there is any. -1 stands for unknown. */
48 static inline int
49 inv (int prob)
51 return prob == -1 ? -1 : REG_BR_PROB_BASE - prob;
54 /* At the start of a function, record that we have no previously-pushed
55 arguments waiting to be popped. */
57 void
58 init_pending_stack_adjust (void)
60 pending_stack_adjust = 0;
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)
69 stack_pointer_delta -= pending_stack_adjust;
70 pending_stack_adjust = 0;
73 /* When exiting from function, if safe, clear out any pending stack adjust
74 so the adjustment won't get done.
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. */
79 void
80 clear_pending_stack_adjust (void)
82 if (optimize > 0
83 && (! flag_omit_frame_pointer || cfun->calls_alloca)
84 && EXIT_IGNORE_STACK)
85 discard_pending_stack_adjust ();
88 /* Pop any previously-pushed arguments that have not been popped yet. */
90 void
91 do_pending_stack_adjust (void)
93 if (inhibit_defer_pop == 0)
95 if (pending_stack_adjust != 0)
96 adjust_stack (GEN_INT (pending_stack_adjust));
97 pending_stack_adjust = 0;
101 /* Expand conditional expressions. */
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. */
107 void
108 jumpifnot (tree exp, rtx label, int prob)
110 do_jump (exp, label, NULL_RTX, inv (prob));
113 void
114 jumpifnot_1 (enum tree_code code, tree op0, tree op1, rtx label, int prob)
116 do_jump_1 (code, op0, op1, label, NULL_RTX, inv (prob));
119 /* Generate code to evaluate EXP and jump to LABEL if the value is nonzero. */
121 void
122 jumpif (tree exp, rtx label, int prob)
124 do_jump (exp, NULL_RTX, label, prob);
127 void
128 jumpif_1 (enum tree_code code, tree op0, tree op1, rtx label, int prob)
130 do_jump_1 (code, op0, op1, NULL_RTX, label, prob);
133 /* Used internally by prefer_and_bit_test. */
135 static GTY(()) rtx and_reg;
136 static GTY(()) rtx and_test;
137 static GTY(()) rtx shift_test;
139 /* Compare the relative costs of "(X & (1 << BITNUM))" and "(X >> BITNUM) & 1",
140 where X is an arbitrary register of mode MODE. Return true if the former
141 is preferred. */
143 static bool
144 prefer_and_bit_test (enum machine_mode mode, int bitnum)
146 bool speed_p;
148 if (and_test == 0)
150 /* Set up rtxes for the two variations. Use NULL as a placeholder
151 for the BITNUM-based constants. */
152 and_reg = gen_rtx_REG (mode, FIRST_PSEUDO_REGISTER);
153 and_test = gen_rtx_AND (mode, and_reg, NULL);
154 shift_test = gen_rtx_AND (mode, gen_rtx_ASHIFTRT (mode, and_reg, NULL),
155 const1_rtx);
157 else
159 /* Change the mode of the previously-created rtxes. */
160 PUT_MODE (and_reg, mode);
161 PUT_MODE (and_test, mode);
162 PUT_MODE (shift_test, mode);
163 PUT_MODE (XEXP (shift_test, 0), mode);
166 /* Fill in the integers. */
167 XEXP (and_test, 1)
168 = immed_double_int_const (double_int_zero.set_bit (bitnum), mode);
169 XEXP (XEXP (shift_test, 0), 1) = GEN_INT (bitnum);
171 speed_p = optimize_insn_for_speed_p ();
172 return (rtx_cost (and_test, IF_THEN_ELSE, 0, speed_p)
173 <= rtx_cost (shift_test, IF_THEN_ELSE, 0, speed_p));
176 /* Subroutine of do_jump, dealing with exploded comparisons of the type
177 OP0 CODE OP1 . IF_FALSE_LABEL and IF_TRUE_LABEL like in do_jump.
178 PROB is probability of jump to if_true_label, or -1 if unknown. */
180 void
181 do_jump_1 (enum tree_code code, tree op0, tree op1,
182 rtx if_false_label, rtx if_true_label, int prob)
184 enum machine_mode mode;
185 rtx drop_through_label = 0;
187 switch (code)
189 case EQ_EXPR:
191 tree inner_type = TREE_TYPE (op0);
193 gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
194 != MODE_COMPLEX_FLOAT);
195 gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
196 != MODE_COMPLEX_INT);
198 if (integer_zerop (op1))
199 do_jump (op0, if_true_label, if_false_label, inv (prob));
200 else if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_INT
201 && !can_compare_p (EQ, TYPE_MODE (inner_type), ccp_jump))
202 do_jump_by_parts_equality (op0, op1, if_false_label, if_true_label,
203 prob);
204 else
205 do_compare_and_jump (op0, op1, EQ, EQ, if_false_label, if_true_label,
206 prob);
207 break;
210 case NE_EXPR:
212 tree inner_type = TREE_TYPE (op0);
214 gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
215 != MODE_COMPLEX_FLOAT);
216 gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
217 != MODE_COMPLEX_INT);
219 if (integer_zerop (op1))
220 do_jump (op0, if_false_label, if_true_label, prob);
221 else if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_INT
222 && !can_compare_p (NE, TYPE_MODE (inner_type), ccp_jump))
223 do_jump_by_parts_equality (op0, op1, if_true_label, if_false_label,
224 inv (prob));
225 else
226 do_compare_and_jump (op0, op1, NE, NE, if_false_label, if_true_label,
227 prob);
228 break;
231 case LT_EXPR:
232 mode = TYPE_MODE (TREE_TYPE (op0));
233 if (GET_MODE_CLASS (mode) == MODE_INT
234 && ! can_compare_p (LT, mode, ccp_jump))
235 do_jump_by_parts_greater (op0, op1, 1, if_false_label, if_true_label,
236 prob);
237 else
238 do_compare_and_jump (op0, op1, LT, LTU, if_false_label, if_true_label,
239 prob);
240 break;
242 case LE_EXPR:
243 mode = TYPE_MODE (TREE_TYPE (op0));
244 if (GET_MODE_CLASS (mode) == MODE_INT
245 && ! can_compare_p (LE, mode, ccp_jump))
246 do_jump_by_parts_greater (op0, op1, 0, if_true_label, if_false_label,
247 inv (prob));
248 else
249 do_compare_and_jump (op0, op1, LE, LEU, if_false_label, if_true_label,
250 prob);
251 break;
253 case GT_EXPR:
254 mode = TYPE_MODE (TREE_TYPE (op0));
255 if (GET_MODE_CLASS (mode) == MODE_INT
256 && ! can_compare_p (GT, mode, ccp_jump))
257 do_jump_by_parts_greater (op0, op1, 0, if_false_label, if_true_label,
258 prob);
259 else
260 do_compare_and_jump (op0, op1, GT, GTU, if_false_label, if_true_label,
261 prob);
262 break;
264 case GE_EXPR:
265 mode = TYPE_MODE (TREE_TYPE (op0));
266 if (GET_MODE_CLASS (mode) == MODE_INT
267 && ! can_compare_p (GE, mode, ccp_jump))
268 do_jump_by_parts_greater (op0, op1, 1, if_true_label, if_false_label,
269 inv (prob));
270 else
271 do_compare_and_jump (op0, op1, GE, GEU, if_false_label, if_true_label,
272 prob);
273 break;
275 case ORDERED_EXPR:
276 do_compare_and_jump (op0, op1, ORDERED, ORDERED,
277 if_false_label, if_true_label, prob);
278 break;
280 case UNORDERED_EXPR:
281 do_compare_and_jump (op0, op1, UNORDERED, UNORDERED,
282 if_false_label, if_true_label, prob);
283 break;
285 case UNLT_EXPR:
286 do_compare_and_jump (op0, op1, UNLT, UNLT, if_false_label, if_true_label,
287 prob);
288 break;
290 case UNLE_EXPR:
291 do_compare_and_jump (op0, op1, UNLE, UNLE, if_false_label, if_true_label,
292 prob);
293 break;
295 case UNGT_EXPR:
296 do_compare_and_jump (op0, op1, UNGT, UNGT, if_false_label, if_true_label,
297 prob);
298 break;
300 case UNGE_EXPR:
301 do_compare_and_jump (op0, op1, UNGE, UNGE, if_false_label, if_true_label,
302 prob);
303 break;
305 case UNEQ_EXPR:
306 do_compare_and_jump (op0, op1, UNEQ, UNEQ, if_false_label, if_true_label,
307 prob);
308 break;
310 case LTGT_EXPR:
311 do_compare_and_jump (op0, op1, LTGT, LTGT, if_false_label, if_true_label,
312 prob);
313 break;
315 case TRUTH_ANDIF_EXPR:
316 if (if_false_label == NULL_RTX)
318 drop_through_label = gen_label_rtx ();
319 do_jump (op0, drop_through_label, NULL_RTX, prob);
320 do_jump (op1, NULL_RTX, if_true_label, prob);
322 else
324 do_jump (op0, if_false_label, NULL_RTX, prob);
325 do_jump (op1, if_false_label, if_true_label, prob);
327 break;
329 case TRUTH_ORIF_EXPR:
330 if (if_true_label == NULL_RTX)
332 drop_through_label = gen_label_rtx ();
333 do_jump (op0, NULL_RTX, drop_through_label, prob);
334 do_jump (op1, if_false_label, NULL_RTX, prob);
336 else
338 do_jump (op0, NULL_RTX, if_true_label, prob);
339 do_jump (op1, if_false_label, if_true_label, prob);
341 break;
343 default:
344 gcc_unreachable ();
347 if (drop_through_label)
349 do_pending_stack_adjust ();
350 emit_label (drop_through_label);
354 /* Generate code to evaluate EXP and jump to IF_FALSE_LABEL if
355 the result is zero, or IF_TRUE_LABEL if the result is one.
356 Either of IF_FALSE_LABEL and IF_TRUE_LABEL may be zero,
357 meaning fall through in that case.
359 do_jump always does any pending stack adjust except when it does not
360 actually perform a jump. An example where there is no jump
361 is when EXP is `(foo (), 0)' and IF_FALSE_LABEL is null.
363 PROB is probability of jump to if_true_label, or -1 if unknown. */
365 void
366 do_jump (tree exp, rtx if_false_label, rtx if_true_label, int prob)
368 enum tree_code code = TREE_CODE (exp);
369 rtx temp;
370 int i;
371 tree type;
372 enum machine_mode mode;
373 rtx drop_through_label = 0;
375 switch (code)
377 case ERROR_MARK:
378 break;
380 case INTEGER_CST:
381 temp = integer_zerop (exp) ? if_false_label : if_true_label;
382 if (temp)
383 emit_jump (temp);
384 break;
386 #if 0
387 /* This is not true with #pragma weak */
388 case ADDR_EXPR:
389 /* The address of something can never be zero. */
390 if (if_true_label)
391 emit_jump (if_true_label);
392 break;
393 #endif
395 case NOP_EXPR:
396 if (TREE_CODE (TREE_OPERAND (exp, 0)) == COMPONENT_REF
397 || TREE_CODE (TREE_OPERAND (exp, 0)) == BIT_FIELD_REF
398 || TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_REF
399 || TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_RANGE_REF)
400 goto normal;
401 case CONVERT_EXPR:
402 /* If we are narrowing the operand, we have to do the compare in the
403 narrower mode. */
404 if ((TYPE_PRECISION (TREE_TYPE (exp))
405 < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0)))))
406 goto normal;
407 case NON_LVALUE_EXPR:
408 /* if a shared pointer conversion that will change representation,
409 then we have to compare in the result type. */
410 if (upc_pts_cvt_op_p (exp))
411 goto normal;
412 case ABS_EXPR:
413 case NEGATE_EXPR:
414 case LROTATE_EXPR:
415 case RROTATE_EXPR:
416 /* These cannot change zero->nonzero or vice versa. */
417 do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label, prob);
418 break;
420 case TRUTH_NOT_EXPR:
421 do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label,
422 inv (prob));
423 break;
425 case COND_EXPR:
427 rtx label1 = gen_label_rtx ();
428 if (!if_true_label || !if_false_label)
430 drop_through_label = gen_label_rtx ();
431 if (!if_true_label)
432 if_true_label = drop_through_label;
433 if (!if_false_label)
434 if_false_label = drop_through_label;
437 do_pending_stack_adjust ();
438 do_jump (TREE_OPERAND (exp, 0), label1, NULL_RTX, -1);
439 do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label, prob);
440 emit_label (label1);
441 do_jump (TREE_OPERAND (exp, 2), if_false_label, if_true_label, prob);
442 break;
445 case COMPOUND_EXPR:
446 /* Lowered by gimplify.c. */
447 gcc_unreachable ();
449 case MINUS_EXPR:
450 /* Nonzero iff operands of minus differ. */
451 code = NE_EXPR;
453 /* FALLTHRU */
454 case EQ_EXPR:
455 case NE_EXPR:
456 case LT_EXPR:
457 case LE_EXPR:
458 case GT_EXPR:
459 case GE_EXPR:
460 case ORDERED_EXPR:
461 case UNORDERED_EXPR:
462 case UNLT_EXPR:
463 case UNLE_EXPR:
464 case UNGT_EXPR:
465 case UNGE_EXPR:
466 case UNEQ_EXPR:
467 case LTGT_EXPR:
468 case TRUTH_ANDIF_EXPR:
469 case TRUTH_ORIF_EXPR:
470 other_code:
471 do_jump_1 (code, TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
472 if_false_label, if_true_label, prob);
473 break;
475 case BIT_AND_EXPR:
476 /* fold_single_bit_test() converts (X & (1 << C)) into (X >> C) & 1.
477 See if the former is preferred for jump tests and restore it
478 if so. */
479 if (integer_onep (TREE_OPERAND (exp, 1)))
481 tree exp0 = TREE_OPERAND (exp, 0);
482 rtx set_label, clr_label;
483 int setclr_prob = prob;
485 /* Strip narrowing integral type conversions. */
486 while (CONVERT_EXPR_P (exp0)
487 && TREE_OPERAND (exp0, 0) != error_mark_node
488 && TYPE_PRECISION (TREE_TYPE (exp0))
489 <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp0, 0))))
490 exp0 = TREE_OPERAND (exp0, 0);
492 /* "exp0 ^ 1" inverts the sense of the single bit test. */
493 if (TREE_CODE (exp0) == BIT_XOR_EXPR
494 && integer_onep (TREE_OPERAND (exp0, 1)))
496 exp0 = TREE_OPERAND (exp0, 0);
497 clr_label = if_true_label;
498 set_label = if_false_label;
499 setclr_prob = inv (prob);
501 else
503 clr_label = if_false_label;
504 set_label = if_true_label;
507 if (TREE_CODE (exp0) == RSHIFT_EXPR)
509 tree arg = TREE_OPERAND (exp0, 0);
510 tree shift = TREE_OPERAND (exp0, 1);
511 tree argtype = TREE_TYPE (arg);
512 if (TREE_CODE (shift) == INTEGER_CST
513 && compare_tree_int (shift, 0) >= 0
514 && compare_tree_int (shift, HOST_BITS_PER_WIDE_INT) < 0
515 && prefer_and_bit_test (TYPE_MODE (argtype),
516 TREE_INT_CST_LOW (shift)))
518 unsigned HOST_WIDE_INT mask
519 = (unsigned HOST_WIDE_INT) 1 << TREE_INT_CST_LOW (shift);
520 do_jump (build2 (BIT_AND_EXPR, argtype, arg,
521 build_int_cstu (argtype, mask)),
522 clr_label, set_label, setclr_prob);
523 break;
528 /* If we are AND'ing with a small constant, do this comparison in the
529 smallest type that fits. If the machine doesn't have comparisons
530 that small, it will be converted back to the wider comparison.
531 This helps if we are testing the sign bit of a narrower object.
532 combine can't do this for us because it can't know whether a
533 ZERO_EXTRACT or a compare in a smaller mode exists, but we do. */
535 if (! SLOW_BYTE_ACCESS
536 && TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST
537 && TYPE_PRECISION (TREE_TYPE (exp)) <= HOST_BITS_PER_WIDE_INT
538 && (i = tree_floor_log2 (TREE_OPERAND (exp, 1))) >= 0
539 && (mode = mode_for_size (i + 1, MODE_INT, 0)) != BLKmode
540 && (type = lang_hooks.types.type_for_mode (mode, 1)) != 0
541 && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (exp))
542 && have_insn_for (COMPARE, TYPE_MODE (type)))
544 do_jump (fold_convert (type, exp), if_false_label, if_true_label,
545 prob);
546 break;
549 if (TYPE_PRECISION (TREE_TYPE (exp)) > 1
550 || TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST)
551 goto normal;
553 /* Boolean comparisons can be compiled as TRUTH_AND_EXPR. */
555 case TRUTH_AND_EXPR:
556 /* High branch cost, expand as the bitwise AND of the conditions.
557 Do the same if the RHS has side effects, because we're effectively
558 turning a TRUTH_AND_EXPR into a TRUTH_ANDIF_EXPR. */
559 if (BRANCH_COST (optimize_insn_for_speed_p (),
560 false) >= 4
561 || TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 1)))
562 goto normal;
563 code = TRUTH_ANDIF_EXPR;
564 goto other_code;
566 case BIT_IOR_EXPR:
567 case TRUTH_OR_EXPR:
568 /* High branch cost, expand as the bitwise OR of the conditions.
569 Do the same if the RHS has side effects, because we're effectively
570 turning a TRUTH_OR_EXPR into a TRUTH_ORIF_EXPR. */
571 if (BRANCH_COST (optimize_insn_for_speed_p (), false) >= 4
572 || TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 1)))
573 goto normal;
574 code = TRUTH_ORIF_EXPR;
575 goto other_code;
577 /* Fall through and generate the normal code. */
578 default:
579 normal:
580 temp = expand_normal (exp);
581 do_pending_stack_adjust ();
582 /* The RTL optimizers prefer comparisons against pseudos. */
583 if (GET_CODE (temp) == SUBREG)
585 /* Compare promoted variables in their promoted mode. */
586 if (SUBREG_PROMOTED_VAR_P (temp)
587 && REG_P (XEXP (temp, 0)))
588 temp = XEXP (temp, 0);
589 else
590 temp = copy_to_reg (temp);
592 do_compare_rtx_and_jump (temp, CONST0_RTX (GET_MODE (temp)),
593 NE, TYPE_UNSIGNED (TREE_TYPE (exp)),
594 GET_MODE (temp), NULL_RTX,
595 if_false_label, if_true_label, prob);
598 if (drop_through_label)
600 do_pending_stack_adjust ();
601 emit_label (drop_through_label);
605 /* Compare OP0 with OP1, word at a time, in mode MODE.
606 UNSIGNEDP says to do unsigned comparison.
607 Jump to IF_TRUE_LABEL if OP0 is greater, IF_FALSE_LABEL otherwise. */
609 static void
610 do_jump_by_parts_greater_rtx (enum machine_mode mode, int unsignedp, rtx op0,
611 rtx op1, rtx if_false_label, rtx if_true_label,
612 int prob)
614 int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
615 rtx drop_through_label = 0;
616 bool drop_through_if_true = false, drop_through_if_false = false;
617 enum rtx_code code = GT;
618 int i;
620 if (! if_true_label || ! if_false_label)
621 drop_through_label = gen_label_rtx ();
622 if (! if_true_label)
624 if_true_label = drop_through_label;
625 drop_through_if_true = true;
627 if (! if_false_label)
629 if_false_label = drop_through_label;
630 drop_through_if_false = true;
633 /* Deal with the special case 0 > x: only one comparison is necessary and
634 we reverse it to avoid jumping to the drop-through label. */
635 if (op0 == const0_rtx && drop_through_if_true && !drop_through_if_false)
637 code = LE;
638 if_true_label = if_false_label;
639 if_false_label = drop_through_label;
640 drop_through_if_true = false;
641 drop_through_if_false = true;
644 /* Compare a word at a time, high order first. */
645 for (i = 0; i < nwords; i++)
647 rtx op0_word, op1_word;
649 if (WORDS_BIG_ENDIAN)
651 op0_word = operand_subword_force (op0, i, mode);
652 op1_word = operand_subword_force (op1, i, mode);
654 else
656 op0_word = operand_subword_force (op0, nwords - 1 - i, mode);
657 op1_word = operand_subword_force (op1, nwords - 1 - i, mode);
660 /* All but high-order word must be compared as unsigned. */
661 do_compare_rtx_and_jump (op0_word, op1_word, code, (unsignedp || i > 0),
662 word_mode, NULL_RTX, NULL_RTX, if_true_label,
663 prob);
665 /* Emit only one comparison for 0. Do not emit the last cond jump. */
666 if (op0 == const0_rtx || i == nwords - 1)
667 break;
669 /* Consider lower words only if these are equal. */
670 do_compare_rtx_and_jump (op0_word, op1_word, NE, unsignedp, word_mode,
671 NULL_RTX, NULL_RTX, if_false_label, inv (prob));
674 if (!drop_through_if_false)
675 emit_jump (if_false_label);
676 if (drop_through_label)
677 emit_label (drop_through_label);
680 /* Given a comparison expression EXP for values too wide to be compared
681 with one insn, test the comparison and jump to the appropriate label.
682 The code of EXP is ignored; we always test GT if SWAP is 0,
683 and LT if SWAP is 1. */
685 static void
686 do_jump_by_parts_greater (tree treeop0, tree treeop1, int swap,
687 rtx if_false_label, rtx if_true_label, int prob)
689 rtx op0 = expand_normal (swap ? treeop1 : treeop0);
690 rtx op1 = expand_normal (swap ? treeop0 : treeop1);
691 enum machine_mode mode = TYPE_MODE (TREE_TYPE (treeop0));
692 int unsignedp = TYPE_UNSIGNED (TREE_TYPE (treeop0));
694 do_jump_by_parts_greater_rtx (mode, unsignedp, op0, op1, if_false_label,
695 if_true_label, prob);
698 /* Jump according to whether OP0 is 0. We assume that OP0 has an integer
699 mode, MODE, that is too wide for the available compare insns. Either
700 Either (but not both) of IF_TRUE_LABEL and IF_FALSE_LABEL may be NULL_RTX
701 to indicate drop through. */
703 static void
704 do_jump_by_parts_zero_rtx (enum machine_mode mode, rtx op0,
705 rtx if_false_label, rtx if_true_label, int prob)
707 int nwords = GET_MODE_SIZE (mode) / UNITS_PER_WORD;
708 rtx part;
709 int i;
710 rtx drop_through_label = 0;
712 /* The fastest way of doing this comparison on almost any machine is to
713 "or" all the words and compare the result. If all have to be loaded
714 from memory and this is a very wide item, it's possible this may
715 be slower, but that's highly unlikely. */
717 part = gen_reg_rtx (word_mode);
718 emit_move_insn (part, operand_subword_force (op0, 0, mode));
719 for (i = 1; i < nwords && part != 0; i++)
720 part = expand_binop (word_mode, ior_optab, part,
721 operand_subword_force (op0, i, mode),
722 part, 1, OPTAB_WIDEN);
724 if (part != 0)
726 do_compare_rtx_and_jump (part, const0_rtx, EQ, 1, word_mode,
727 NULL_RTX, if_false_label, if_true_label, prob);
728 return;
731 /* If we couldn't do the "or" simply, do this with a series of compares. */
732 if (! if_false_label)
733 drop_through_label = if_false_label = gen_label_rtx ();
735 for (i = 0; i < nwords; i++)
736 do_compare_rtx_and_jump (operand_subword_force (op0, i, mode),
737 const0_rtx, EQ, 1, word_mode, NULL_RTX,
738 if_false_label, NULL_RTX, prob);
740 if (if_true_label)
741 emit_jump (if_true_label);
743 if (drop_through_label)
744 emit_label (drop_through_label);
747 /* Test for the equality of two RTX expressions OP0 and OP1 in mode MODE,
748 where MODE is an integer mode too wide to be compared with one insn.
749 Either (but not both) of IF_TRUE_LABEL and IF_FALSE_LABEL may be NULL_RTX
750 to indicate drop through. */
752 static void
753 do_jump_by_parts_equality_rtx (enum machine_mode mode, rtx op0, rtx op1,
754 rtx if_false_label, rtx if_true_label, int prob)
756 int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
757 rtx drop_through_label = 0;
758 int i;
760 if (op1 == const0_rtx)
762 do_jump_by_parts_zero_rtx (mode, op0, if_false_label, if_true_label,
763 prob);
764 return;
766 else if (op0 == const0_rtx)
768 do_jump_by_parts_zero_rtx (mode, op1, if_false_label, if_true_label,
769 prob);
770 return;
773 if (! if_false_label)
774 drop_through_label = if_false_label = gen_label_rtx ();
776 for (i = 0; i < nwords; i++)
777 do_compare_rtx_and_jump (operand_subword_force (op0, i, mode),
778 operand_subword_force (op1, i, mode),
779 EQ, 0, word_mode, NULL_RTX,
780 if_false_label, NULL_RTX, prob);
782 if (if_true_label)
783 emit_jump (if_true_label);
784 if (drop_through_label)
785 emit_label (drop_through_label);
788 /* Given an EQ_EXPR expression EXP for values too wide to be compared
789 with one insn, test the comparison and jump to the appropriate label. */
791 static void
792 do_jump_by_parts_equality (tree treeop0, tree treeop1, rtx if_false_label,
793 rtx if_true_label, int prob)
795 rtx op0 = expand_normal (treeop0);
796 rtx op1 = expand_normal (treeop1);
797 enum machine_mode mode = TYPE_MODE (TREE_TYPE (treeop0));
798 do_jump_by_parts_equality_rtx (mode, op0, op1, if_false_label,
799 if_true_label, prob);
802 /* Split a comparison into two others, the second of which has the other
803 "orderedness". The first is always ORDERED or UNORDERED if MODE
804 does not honor NaNs (which means that it can be skipped in that case;
805 see do_compare_rtx_and_jump).
807 The two conditions are written in *CODE1 and *CODE2. Return true if
808 the conditions must be ANDed, false if they must be ORed. */
810 bool
811 split_comparison (enum rtx_code code, enum machine_mode mode,
812 enum rtx_code *code1, enum rtx_code *code2)
814 switch (code)
816 case LT:
817 *code1 = ORDERED;
818 *code2 = UNLT;
819 return true;
820 case LE:
821 *code1 = ORDERED;
822 *code2 = UNLE;
823 return true;
824 case GT:
825 *code1 = ORDERED;
826 *code2 = UNGT;
827 return true;
828 case GE:
829 *code1 = ORDERED;
830 *code2 = UNGE;
831 return true;
832 case EQ:
833 *code1 = ORDERED;
834 *code2 = UNEQ;
835 return true;
836 case NE:
837 *code1 = UNORDERED;
838 *code2 = LTGT;
839 return false;
840 case UNLT:
841 *code1 = UNORDERED;
842 *code2 = LT;
843 return false;
844 case UNLE:
845 *code1 = UNORDERED;
846 *code2 = LE;
847 return false;
848 case UNGT:
849 *code1 = UNORDERED;
850 *code2 = GT;
851 return false;
852 case UNGE:
853 *code1 = UNORDERED;
854 *code2 = GE;
855 return false;
856 case UNEQ:
857 *code1 = UNORDERED;
858 *code2 = EQ;
859 return false;
860 case LTGT:
861 /* Do not turn a trapping comparison into a non-trapping one. */
862 if (HONOR_SNANS (mode))
864 *code1 = LT;
865 *code2 = GT;
866 return false;
868 else
870 *code1 = ORDERED;
871 *code2 = NE;
872 return true;
874 default:
875 gcc_unreachable ();
880 /* Like do_compare_and_jump but expects the values to compare as two rtx's.
881 The decision as to signed or unsigned comparison must be made by the caller.
883 If MODE is BLKmode, SIZE is an RTX giving the size of the objects being
884 compared. */
886 void
887 do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
888 enum machine_mode mode, rtx size, rtx if_false_label,
889 rtx if_true_label, int prob)
891 rtx tem;
892 rtx dummy_label = NULL_RTX;
894 /* Reverse the comparison if that is safe and we want to jump if it is
895 false. Also convert to the reverse comparison if the target can
896 implement it. */
897 if ((! if_true_label
898 || ! can_compare_p (code, mode, ccp_jump))
899 && (! FLOAT_MODE_P (mode)
900 || code == ORDERED || code == UNORDERED
901 || (! HONOR_NANS (mode) && (code == LTGT || code == UNEQ))
902 || (! HONOR_SNANS (mode) && (code == EQ || code == NE))))
904 enum rtx_code rcode;
905 if (FLOAT_MODE_P (mode))
906 rcode = reverse_condition_maybe_unordered (code);
907 else
908 rcode = reverse_condition (code);
910 /* Canonicalize to UNORDERED for the libcall. */
911 if (can_compare_p (rcode, mode, ccp_jump)
912 || (code == ORDERED && ! can_compare_p (ORDERED, mode, ccp_jump)))
914 tem = if_true_label;
915 if_true_label = if_false_label;
916 if_false_label = tem;
917 code = rcode;
918 prob = inv (prob);
922 /* If one operand is constant, make it the second one. Only do this
923 if the other operand is not constant as well. */
925 if (swap_commutative_operands_p (op0, op1))
927 tem = op0;
928 op0 = op1;
929 op1 = tem;
930 code = swap_condition (code);
933 do_pending_stack_adjust ();
935 code = unsignedp ? unsigned_condition (code) : code;
936 if (0 != (tem = simplify_relational_operation (code, mode, VOIDmode,
937 op0, op1)))
939 if (CONSTANT_P (tem))
941 rtx label = (tem == const0_rtx || tem == CONST0_RTX (mode))
942 ? if_false_label : if_true_label;
943 if (label)
944 emit_jump (label);
945 return;
948 code = GET_CODE (tem);
949 mode = GET_MODE (tem);
950 op0 = XEXP (tem, 0);
951 op1 = XEXP (tem, 1);
952 unsignedp = (code == GTU || code == LTU || code == GEU || code == LEU);
955 if (! if_true_label)
956 dummy_label = if_true_label = gen_label_rtx ();
958 if (GET_MODE_CLASS (mode) == MODE_INT
959 && ! can_compare_p (code, mode, ccp_jump))
961 switch (code)
963 case LTU:
964 do_jump_by_parts_greater_rtx (mode, 1, op1, op0,
965 if_false_label, if_true_label, prob);
966 break;
968 case LEU:
969 do_jump_by_parts_greater_rtx (mode, 1, op0, op1,
970 if_true_label, if_false_label,
971 inv (prob));
972 break;
974 case GTU:
975 do_jump_by_parts_greater_rtx (mode, 1, op0, op1,
976 if_false_label, if_true_label, prob);
977 break;
979 case GEU:
980 do_jump_by_parts_greater_rtx (mode, 1, op1, op0,
981 if_true_label, if_false_label,
982 inv (prob));
983 break;
985 case LT:
986 do_jump_by_parts_greater_rtx (mode, 0, op1, op0,
987 if_false_label, if_true_label, prob);
988 break;
990 case LE:
991 do_jump_by_parts_greater_rtx (mode, 0, op0, op1,
992 if_true_label, if_false_label,
993 inv (prob));
994 break;
996 case GT:
997 do_jump_by_parts_greater_rtx (mode, 0, op0, op1,
998 if_false_label, if_true_label, prob);
999 break;
1001 case GE:
1002 do_jump_by_parts_greater_rtx (mode, 0, op1, op0,
1003 if_true_label, if_false_label,
1004 inv (prob));
1005 break;
1007 case EQ:
1008 do_jump_by_parts_equality_rtx (mode, op0, op1, if_false_label,
1009 if_true_label, prob);
1010 break;
1012 case NE:
1013 do_jump_by_parts_equality_rtx (mode, op0, op1, if_true_label,
1014 if_false_label, inv (prob));
1015 break;
1017 default:
1018 gcc_unreachable ();
1021 else
1023 if (SCALAR_FLOAT_MODE_P (mode)
1024 && ! can_compare_p (code, mode, ccp_jump)
1025 && can_compare_p (swap_condition (code), mode, ccp_jump))
1027 rtx tmp;
1028 code = swap_condition (code);
1029 tmp = op0;
1030 op0 = op1;
1031 op1 = tmp;
1033 else if (SCALAR_FLOAT_MODE_P (mode)
1034 && ! can_compare_p (code, mode, ccp_jump)
1035 /* Never split ORDERED and UNORDERED.
1036 These must be implemented. */
1037 && (code != ORDERED && code != UNORDERED)
1038 /* Split a floating-point comparison if
1039 we can jump on other conditions... */
1040 && (have_insn_for (COMPARE, mode)
1041 /* ... or if there is no libcall for it. */
1042 || code_to_optab (code) == unknown_optab))
1044 enum rtx_code first_code;
1045 bool and_them = split_comparison (code, mode, &first_code, &code);
1047 /* If there are no NaNs, the first comparison should always fall
1048 through. */
1049 if (!HONOR_NANS (mode))
1050 gcc_assert (first_code == (and_them ? ORDERED : UNORDERED));
1052 else
1054 if (and_them)
1056 rtx dest_label;
1057 /* If we only jump if true, just bypass the second jump. */
1058 if (! if_false_label)
1060 if (! dummy_label)
1061 dummy_label = gen_label_rtx ();
1062 dest_label = dummy_label;
1064 else
1065 dest_label = if_false_label;
1066 do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode,
1067 size, dest_label, NULL_RTX, prob);
1069 else
1070 do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode,
1071 size, NULL_RTX, if_true_label, prob);
1075 emit_cmp_and_jump_insns (op0, op1, code, size, mode, unsignedp,
1076 if_true_label, prob);
1079 if (if_false_label)
1080 emit_jump (if_false_label);
1081 if (dummy_label)
1082 emit_label (dummy_label);
1085 /* Generate code for a comparison expression EXP (including code to compute
1086 the values to be compared) and a conditional jump to IF_FALSE_LABEL and/or
1087 IF_TRUE_LABEL. One of the labels can be NULL_RTX, in which case the
1088 generated code will drop through.
1089 SIGNED_CODE should be the rtx operation for this comparison for
1090 signed data; UNSIGNED_CODE, likewise for use if data is unsigned.
1092 We force a stack adjustment unless there are currently
1093 things pushed on the stack that aren't yet used. */
1095 static void
1096 do_compare_and_jump (tree treeop0, tree treeop1, enum rtx_code signed_code,
1097 enum rtx_code unsigned_code, rtx if_false_label,
1098 rtx if_true_label, int prob)
1100 rtx op0, op1;
1101 tree type;
1102 enum machine_mode mode;
1103 int unsignedp;
1104 enum rtx_code code;
1106 /* Don't crash if the comparison was erroneous. */
1107 op0 = expand_normal (treeop0);
1108 if (TREE_CODE (treeop0) == ERROR_MARK)
1109 return;
1111 op1 = expand_normal (treeop1);
1112 if (TREE_CODE (treeop1) == ERROR_MARK)
1113 return;
1115 type = TREE_TYPE (treeop0);
1116 mode = TYPE_MODE (type);
1117 if (TREE_CODE (treeop0) == INTEGER_CST
1118 && (TREE_CODE (treeop1) != INTEGER_CST
1119 || (GET_MODE_BITSIZE (mode)
1120 > GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (treeop1))))))
1122 /* op0 might have been replaced by promoted constant, in which
1123 case the type of second argument should be used. */
1124 type = TREE_TYPE (treeop1);
1125 mode = TYPE_MODE (type);
1127 unsignedp = TYPE_UNSIGNED (type);
1128 code = unsignedp ? unsigned_code : signed_code;
1130 #ifdef HAVE_canonicalize_funcptr_for_compare
1131 /* If function pointers need to be "canonicalized" before they can
1132 be reliably compared, then canonicalize them.
1133 Only do this if *both* sides of the comparison are function pointers.
1134 If one side isn't, we want a noncanonicalized comparison. See PR
1135 middle-end/17564. */
1136 if (HAVE_canonicalize_funcptr_for_compare
1137 && TREE_CODE (TREE_TYPE (treeop0)) == POINTER_TYPE
1138 && TREE_CODE (TREE_TYPE (TREE_TYPE (treeop0)))
1139 == FUNCTION_TYPE
1140 && TREE_CODE (TREE_TYPE (treeop1)) == POINTER_TYPE
1141 && TREE_CODE (TREE_TYPE (TREE_TYPE (treeop1)))
1142 == FUNCTION_TYPE)
1144 rtx new_op0 = gen_reg_rtx (mode);
1145 rtx new_op1 = gen_reg_rtx (mode);
1147 emit_insn (gen_canonicalize_funcptr_for_compare (new_op0, op0));
1148 op0 = new_op0;
1150 emit_insn (gen_canonicalize_funcptr_for_compare (new_op1, op1));
1151 op1 = new_op1;
1153 #endif
1155 do_compare_rtx_and_jump (op0, op1, code, unsignedp, mode,
1156 ((mode == BLKmode)
1157 ? expr_size (treeop0) : NULL_RTX),
1158 if_false_label, if_true_label, prob);
1161 #include "gt-dojump.h"