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
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
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/>. */
24 #include "coretypes.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. */
35 #include "langhooks.h"
37 #include "basic-block.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
,
46 /* Invert probability if there is any. -1 stands for unknown. */
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. */
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. */
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. */
80 clear_pending_stack_adjust (void)
83 && (! flag_omit_frame_pointer
|| cfun
->calls_alloca
)
85 discard_pending_stack_adjust ();
88 /* Pop any previously-pushed arguments that have not been popped yet. */
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
108 jumpifnot (tree exp
, rtx label
, int prob
)
110 do_jump (exp
, label
, NULL_RTX
, inv (prob
));
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. */
122 jumpif (tree exp
, rtx label
, int prob
)
124 do_jump (exp
, NULL_RTX
, label
, prob
);
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
144 prefer_and_bit_test (enum machine_mode mode
, int bitnum
)
148 /* Set up rtxes for the two variations. Use NULL as a placeholder
149 for the BITNUM-based constants. */
150 and_reg
= gen_rtx_REG (mode
, FIRST_PSEUDO_REGISTER
);
151 and_test
= gen_rtx_AND (mode
, and_reg
, NULL
);
152 shift_test
= gen_rtx_AND (mode
, gen_rtx_ASHIFTRT (mode
, and_reg
, NULL
),
157 /* Change the mode of the previously-created rtxes. */
158 PUT_MODE (and_reg
, mode
);
159 PUT_MODE (and_test
, mode
);
160 PUT_MODE (shift_test
, mode
);
161 PUT_MODE (XEXP (shift_test
, 0), mode
);
164 /* Fill in the integers. */
166 = immed_double_int_const (double_int_setbit (double_int_zero
, bitnum
),
168 XEXP (XEXP (shift_test
, 0), 1) = GEN_INT (bitnum
);
170 return (rtx_cost (and_test
, IF_THEN_ELSE
, optimize_insn_for_speed_p ())
171 <= rtx_cost (shift_test
, IF_THEN_ELSE
, optimize_insn_for_speed_p ()));
174 /* Subroutine of do_jump, dealing with exploded comparisons of the type
175 OP0 CODE OP1 . IF_FALSE_LABEL and IF_TRUE_LABEL like in do_jump.
176 PROB is probability of jump to if_true_label, or -1 if unknown. */
179 do_jump_1 (enum tree_code code
, tree op0
, tree op1
,
180 rtx if_false_label
, rtx if_true_label
, int prob
)
182 enum machine_mode mode
;
183 rtx drop_through_label
= 0;
189 tree inner_type
= TREE_TYPE (op0
);
191 gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type
))
192 != MODE_COMPLEX_FLOAT
);
193 gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type
))
194 != MODE_COMPLEX_INT
);
196 if (integer_zerop (op1
))
197 do_jump (op0
, if_true_label
, if_false_label
, inv (prob
));
198 else if (GET_MODE_CLASS (TYPE_MODE (inner_type
)) == MODE_INT
199 && !can_compare_p (EQ
, TYPE_MODE (inner_type
), ccp_jump
))
200 do_jump_by_parts_equality (op0
, op1
, if_false_label
, if_true_label
,
203 do_compare_and_jump (op0
, op1
, EQ
, EQ
, if_false_label
, if_true_label
,
210 tree inner_type
= TREE_TYPE (op0
);
212 gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type
))
213 != MODE_COMPLEX_FLOAT
);
214 gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type
))
215 != MODE_COMPLEX_INT
);
217 if (integer_zerop (op1
))
218 do_jump (op0
, if_false_label
, if_true_label
, prob
);
219 else if (GET_MODE_CLASS (TYPE_MODE (inner_type
)) == MODE_INT
220 && !can_compare_p (NE
, TYPE_MODE (inner_type
), ccp_jump
))
221 do_jump_by_parts_equality (op0
, op1
, if_true_label
, if_false_label
,
224 do_compare_and_jump (op0
, op1
, NE
, NE
, if_false_label
, if_true_label
,
230 mode
= TYPE_MODE (TREE_TYPE (op0
));
231 if (GET_MODE_CLASS (mode
) == MODE_INT
232 && ! can_compare_p (LT
, mode
, ccp_jump
))
233 do_jump_by_parts_greater (op0
, op1
, 1, if_false_label
, if_true_label
,
236 do_compare_and_jump (op0
, op1
, LT
, LTU
, if_false_label
, if_true_label
,
241 mode
= TYPE_MODE (TREE_TYPE (op0
));
242 if (GET_MODE_CLASS (mode
) == MODE_INT
243 && ! can_compare_p (LE
, mode
, ccp_jump
))
244 do_jump_by_parts_greater (op0
, op1
, 0, if_true_label
, if_false_label
,
247 do_compare_and_jump (op0
, op1
, LE
, LEU
, if_false_label
, if_true_label
,
252 mode
= TYPE_MODE (TREE_TYPE (op0
));
253 if (GET_MODE_CLASS (mode
) == MODE_INT
254 && ! can_compare_p (GT
, mode
, ccp_jump
))
255 do_jump_by_parts_greater (op0
, op1
, 0, if_false_label
, if_true_label
,
258 do_compare_and_jump (op0
, op1
, GT
, GTU
, if_false_label
, if_true_label
,
263 mode
= TYPE_MODE (TREE_TYPE (op0
));
264 if (GET_MODE_CLASS (mode
) == MODE_INT
265 && ! can_compare_p (GE
, mode
, ccp_jump
))
266 do_jump_by_parts_greater (op0
, op1
, 1, if_true_label
, if_false_label
,
269 do_compare_and_jump (op0
, op1
, GE
, GEU
, if_false_label
, if_true_label
,
274 do_compare_and_jump (op0
, op1
, ORDERED
, ORDERED
,
275 if_false_label
, if_true_label
, prob
);
279 do_compare_and_jump (op0
, op1
, UNORDERED
, UNORDERED
,
280 if_false_label
, if_true_label
, prob
);
284 do_compare_and_jump (op0
, op1
, UNLT
, UNLT
, if_false_label
, if_true_label
,
289 do_compare_and_jump (op0
, op1
, UNLE
, UNLE
, if_false_label
, if_true_label
,
294 do_compare_and_jump (op0
, op1
, UNGT
, UNGT
, if_false_label
, if_true_label
,
299 do_compare_and_jump (op0
, op1
, UNGE
, UNGE
, if_false_label
, if_true_label
,
304 do_compare_and_jump (op0
, op1
, UNEQ
, UNEQ
, if_false_label
, if_true_label
,
309 do_compare_and_jump (op0
, op1
, LTGT
, LTGT
, if_false_label
, if_true_label
,
313 case TRUTH_ANDIF_EXPR
:
314 if (if_false_label
== NULL_RTX
)
316 drop_through_label
= gen_label_rtx ();
317 do_jump (op0
, drop_through_label
, NULL_RTX
, prob
);
318 do_jump (op1
, NULL_RTX
, if_true_label
, prob
);
322 do_jump (op0
, if_false_label
, NULL_RTX
, prob
);
323 do_jump (op1
, if_false_label
, if_true_label
, prob
);
327 case TRUTH_ORIF_EXPR
:
328 if (if_true_label
== NULL_RTX
)
330 drop_through_label
= gen_label_rtx ();
331 do_jump (op0
, NULL_RTX
, drop_through_label
, prob
);
332 do_jump (op1
, if_false_label
, NULL_RTX
, prob
);
336 do_jump (op0
, NULL_RTX
, if_true_label
, prob
);
337 do_jump (op1
, if_false_label
, if_true_label
, prob
);
345 if (drop_through_label
)
347 do_pending_stack_adjust ();
348 emit_label (drop_through_label
);
352 /* Generate code to evaluate EXP and jump to IF_FALSE_LABEL if
353 the result is zero, or IF_TRUE_LABEL if the result is one.
354 Either of IF_FALSE_LABEL and IF_TRUE_LABEL may be zero,
355 meaning fall through in that case.
357 do_jump always does any pending stack adjust except when it does not
358 actually perform a jump. An example where there is no jump
359 is when EXP is `(foo (), 0)' and IF_FALSE_LABEL is null.
361 PROB is probability of jump to if_true_label, or -1 if unknown. */
364 do_jump (tree exp
, rtx if_false_label
, rtx if_true_label
, int prob
)
366 enum tree_code code
= TREE_CODE (exp
);
370 enum machine_mode mode
;
371 rtx drop_through_label
= 0;
379 temp
= integer_zerop (exp
) ? if_false_label
: if_true_label
;
385 /* This is not true with #pragma weak */
387 /* The address of something can never be zero. */
389 emit_jump (if_true_label
);
394 if (TREE_CODE (TREE_OPERAND (exp
, 0)) == COMPONENT_REF
395 || TREE_CODE (TREE_OPERAND (exp
, 0)) == BIT_FIELD_REF
396 || TREE_CODE (TREE_OPERAND (exp
, 0)) == ARRAY_REF
397 || TREE_CODE (TREE_OPERAND (exp
, 0)) == ARRAY_RANGE_REF
)
400 /* If we are narrowing the operand, we have to do the compare in the
402 if ((TYPE_PRECISION (TREE_TYPE (exp
))
403 < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp
, 0)))))
405 case NON_LVALUE_EXPR
:
410 /* These cannot change zero->nonzero or vice versa. */
411 do_jump (TREE_OPERAND (exp
, 0), if_false_label
, if_true_label
, prob
);
415 do_jump (TREE_OPERAND (exp
, 0), if_true_label
, if_false_label
,
421 rtx label1
= gen_label_rtx ();
422 if (!if_true_label
|| !if_false_label
)
424 drop_through_label
= gen_label_rtx ();
426 if_true_label
= drop_through_label
;
428 if_false_label
= drop_through_label
;
431 do_pending_stack_adjust ();
432 do_jump (TREE_OPERAND (exp
, 0), label1
, NULL_RTX
, -1);
433 do_jump (TREE_OPERAND (exp
, 1), if_false_label
, if_true_label
, prob
);
435 do_jump (TREE_OPERAND (exp
, 2), if_false_label
, if_true_label
, prob
);
440 /* Lowered by gimplify.c. */
446 case ARRAY_RANGE_REF
:
448 HOST_WIDE_INT bitsize
, bitpos
;
450 enum machine_mode mode
;
455 /* Get description of this reference. We don't actually care
456 about the underlying object here. */
457 get_inner_reference (exp
, &bitsize
, &bitpos
, &offset
, &mode
,
458 &unsignedp
, &volatilep
, false);
460 type
= lang_hooks
.types
.type_for_size (bitsize
, unsignedp
);
461 if (! SLOW_BYTE_ACCESS
462 && type
!= 0 && bitsize
>= 0
463 && TYPE_PRECISION (type
) < TYPE_PRECISION (TREE_TYPE (exp
))
464 && have_insn_for (COMPARE
, TYPE_MODE (type
)))
466 do_jump (fold_convert (type
, exp
), if_false_label
, if_true_label
,
474 /* Nonzero iff operands of minus differ. */
492 case TRUTH_ANDIF_EXPR
:
493 case TRUTH_ORIF_EXPR
:
495 do_jump_1 (code
, TREE_OPERAND (exp
, 0), TREE_OPERAND (exp
, 1),
496 if_false_label
, if_true_label
, prob
);
500 /* fold_single_bit_test() converts (X & (1 << C)) into (X >> C) & 1.
501 See if the former is preferred for jump tests and restore it
503 if (integer_onep (TREE_OPERAND (exp
, 1)))
505 tree exp0
= TREE_OPERAND (exp
, 0);
506 rtx set_label
, clr_label
;
507 int setclr_prob
= prob
;
509 /* Strip narrowing integral type conversions. */
510 while (CONVERT_EXPR_P (exp0
)
511 && TREE_OPERAND (exp0
, 0) != error_mark_node
512 && TYPE_PRECISION (TREE_TYPE (exp0
))
513 <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp0
, 0))))
514 exp0
= TREE_OPERAND (exp0
, 0);
516 /* "exp0 ^ 1" inverts the sense of the single bit test. */
517 if (TREE_CODE (exp0
) == BIT_XOR_EXPR
518 && integer_onep (TREE_OPERAND (exp0
, 1)))
520 exp0
= TREE_OPERAND (exp0
, 0);
521 clr_label
= if_true_label
;
522 set_label
= if_false_label
;
523 setclr_prob
= inv (prob
);
527 clr_label
= if_false_label
;
528 set_label
= if_true_label
;
531 if (TREE_CODE (exp0
) == RSHIFT_EXPR
)
533 tree arg
= TREE_OPERAND (exp0
, 0);
534 tree shift
= TREE_OPERAND (exp0
, 1);
535 tree argtype
= TREE_TYPE (arg
);
536 if (TREE_CODE (shift
) == INTEGER_CST
537 && compare_tree_int (shift
, 0) >= 0
538 && compare_tree_int (shift
, HOST_BITS_PER_WIDE_INT
) < 0
539 && prefer_and_bit_test (TYPE_MODE (argtype
),
540 TREE_INT_CST_LOW (shift
)))
542 unsigned HOST_WIDE_INT mask
543 = (unsigned HOST_WIDE_INT
) 1 << TREE_INT_CST_LOW (shift
);
544 do_jump (build2 (BIT_AND_EXPR
, argtype
, arg
,
545 build_int_cstu (argtype
, mask
)),
546 clr_label
, set_label
, setclr_prob
);
552 /* If we are AND'ing with a small constant, do this comparison in the
553 smallest type that fits. If the machine doesn't have comparisons
554 that small, it will be converted back to the wider comparison.
555 This helps if we are testing the sign bit of a narrower object.
556 combine can't do this for us because it can't know whether a
557 ZERO_EXTRACT or a compare in a smaller mode exists, but we do. */
559 if (! SLOW_BYTE_ACCESS
560 && TREE_CODE (TREE_OPERAND (exp
, 1)) == INTEGER_CST
561 && TYPE_PRECISION (TREE_TYPE (exp
)) <= HOST_BITS_PER_WIDE_INT
562 && (i
= tree_floor_log2 (TREE_OPERAND (exp
, 1))) >= 0
563 && (mode
= mode_for_size (i
+ 1, MODE_INT
, 0)) != BLKmode
564 && (type
= lang_hooks
.types
.type_for_mode (mode
, 1)) != 0
565 && TYPE_PRECISION (type
) < TYPE_PRECISION (TREE_TYPE (exp
))
566 && have_insn_for (COMPARE
, TYPE_MODE (type
)))
568 do_jump (fold_convert (type
, exp
), if_false_label
, if_true_label
,
573 if (TYPE_PRECISION (TREE_TYPE (exp
)) > 1
574 || TREE_CODE (TREE_OPERAND (exp
, 1)) == INTEGER_CST
)
577 /* Boolean comparisons can be compiled as TRUTH_AND_EXPR. */
580 /* High branch cost, expand as the bitwise AND of the conditions.
581 Do the same if the RHS has side effects, because we're effectively
582 turning a TRUTH_AND_EXPR into a TRUTH_ANDIF_EXPR. */
583 if (BRANCH_COST (optimize_insn_for_speed_p (),
585 || TREE_SIDE_EFFECTS (TREE_OPERAND (exp
, 1)))
587 code
= TRUTH_ANDIF_EXPR
;
592 /* High branch cost, expand as the bitwise OR of the conditions.
593 Do the same if the RHS has side effects, because we're effectively
594 turning a TRUTH_OR_EXPR into a TRUTH_ORIF_EXPR. */
595 if (BRANCH_COST (optimize_insn_for_speed_p (), false) >= 4
596 || TREE_SIDE_EFFECTS (TREE_OPERAND (exp
, 1)))
598 code
= TRUTH_ORIF_EXPR
;
601 /* Fall through and generate the normal code. */
604 temp
= expand_normal (exp
);
605 do_pending_stack_adjust ();
606 /* The RTL optimizers prefer comparisons against pseudos. */
607 if (GET_CODE (temp
) == SUBREG
)
609 /* Compare promoted variables in their promoted mode. */
610 if (SUBREG_PROMOTED_VAR_P (temp
)
611 && REG_P (XEXP (temp
, 0)))
612 temp
= XEXP (temp
, 0);
614 temp
= copy_to_reg (temp
);
616 do_compare_rtx_and_jump (temp
, CONST0_RTX (GET_MODE (temp
)),
617 NE
, TYPE_UNSIGNED (TREE_TYPE (exp
)),
618 GET_MODE (temp
), NULL_RTX
,
619 if_false_label
, if_true_label
, prob
);
622 if (drop_through_label
)
624 do_pending_stack_adjust ();
625 emit_label (drop_through_label
);
629 /* Compare OP0 with OP1, word at a time, in mode MODE.
630 UNSIGNEDP says to do unsigned comparison.
631 Jump to IF_TRUE_LABEL if OP0 is greater, IF_FALSE_LABEL otherwise. */
634 do_jump_by_parts_greater_rtx (enum machine_mode mode
, int unsignedp
, rtx op0
,
635 rtx op1
, rtx if_false_label
, rtx if_true_label
,
638 int nwords
= (GET_MODE_SIZE (mode
) / UNITS_PER_WORD
);
639 rtx drop_through_label
= 0;
642 if (! if_true_label
|| ! if_false_label
)
643 drop_through_label
= gen_label_rtx ();
645 if_true_label
= drop_through_label
;
646 if (! if_false_label
)
647 if_false_label
= drop_through_label
;
649 /* Compare a word at a time, high order first. */
650 for (i
= 0; i
< nwords
; i
++)
652 rtx op0_word
, op1_word
;
654 if (WORDS_BIG_ENDIAN
)
656 op0_word
= operand_subword_force (op0
, i
, mode
);
657 op1_word
= operand_subword_force (op1
, i
, mode
);
661 op0_word
= operand_subword_force (op0
, nwords
- 1 - i
, mode
);
662 op1_word
= operand_subword_force (op1
, nwords
- 1 - i
, mode
);
665 /* All but high-order word must be compared as unsigned. */
666 do_compare_rtx_and_jump (op0_word
, op1_word
, GT
,
667 (unsignedp
|| i
> 0), word_mode
, NULL_RTX
,
668 NULL_RTX
, if_true_label
, prob
);
670 /* Consider lower words only if these are equal. */
671 do_compare_rtx_and_jump (op0_word
, op1_word
, NE
, unsignedp
, word_mode
,
672 NULL_RTX
, NULL_RTX
, if_false_label
,
677 emit_jump (if_false_label
);
678 if (drop_through_label
)
679 emit_label (drop_through_label
);
682 /* Given a comparison expression EXP for values too wide to be compared
683 with one insn, test the comparison and jump to the appropriate label.
684 The code of EXP is ignored; we always test GT if SWAP is 0,
685 and LT if SWAP is 1. */
688 do_jump_by_parts_greater (tree treeop0
, tree treeop1
, int swap
,
689 rtx if_false_label
, rtx if_true_label
, int prob
)
691 rtx op0
= expand_normal (swap
? treeop1
: treeop0
);
692 rtx op1
= expand_normal (swap
? treeop0
: treeop1
);
693 enum machine_mode mode
= TYPE_MODE (TREE_TYPE (treeop0
));
694 int unsignedp
= TYPE_UNSIGNED (TREE_TYPE (treeop0
));
696 do_jump_by_parts_greater_rtx (mode
, unsignedp
, op0
, op1
, if_false_label
,
697 if_true_label
, prob
);
700 /* Jump according to whether OP0 is 0. We assume that OP0 has an integer
701 mode, MODE, that is too wide for the available compare insns. Either
702 Either (but not both) of IF_TRUE_LABEL and IF_FALSE_LABEL may be NULL_RTX
703 to indicate drop through. */
706 do_jump_by_parts_zero_rtx (enum machine_mode mode
, rtx op0
,
707 rtx if_false_label
, rtx if_true_label
, int prob
)
709 int nwords
= GET_MODE_SIZE (mode
) / UNITS_PER_WORD
;
712 rtx drop_through_label
= 0;
714 /* The fastest way of doing this comparison on almost any machine is to
715 "or" all the words and compare the result. If all have to be loaded
716 from memory and this is a very wide item, it's possible this may
717 be slower, but that's highly unlikely. */
719 part
= gen_reg_rtx (word_mode
);
720 emit_move_insn (part
, operand_subword_force (op0
, 0, mode
));
721 for (i
= 1; i
< nwords
&& part
!= 0; i
++)
722 part
= expand_binop (word_mode
, ior_optab
, part
,
723 operand_subword_force (op0
, i
, mode
),
724 part
, 1, OPTAB_WIDEN
);
728 do_compare_rtx_and_jump (part
, const0_rtx
, EQ
, 1, word_mode
,
729 NULL_RTX
, if_false_label
, if_true_label
, prob
);
733 /* If we couldn't do the "or" simply, do this with a series of compares. */
734 if (! if_false_label
)
735 drop_through_label
= if_false_label
= gen_label_rtx ();
737 for (i
= 0; i
< nwords
; i
++)
738 do_compare_rtx_and_jump (operand_subword_force (op0
, i
, mode
),
739 const0_rtx
, EQ
, 1, word_mode
, NULL_RTX
,
740 if_false_label
, NULL_RTX
, prob
);
743 emit_jump (if_true_label
);
745 if (drop_through_label
)
746 emit_label (drop_through_label
);
749 /* Test for the equality of two RTX expressions OP0 and OP1 in mode MODE,
750 where MODE is an integer mode too wide to be compared with one insn.
751 Either (but not both) of IF_TRUE_LABEL and IF_FALSE_LABEL may be NULL_RTX
752 to indicate drop through. */
755 do_jump_by_parts_equality_rtx (enum machine_mode mode
, rtx op0
, rtx op1
,
756 rtx if_false_label
, rtx if_true_label
, int prob
)
758 int nwords
= (GET_MODE_SIZE (mode
) / UNITS_PER_WORD
);
759 rtx drop_through_label
= 0;
762 if (op1
== const0_rtx
)
764 do_jump_by_parts_zero_rtx (mode
, op0
, if_false_label
, if_true_label
,
768 else if (op0
== const0_rtx
)
770 do_jump_by_parts_zero_rtx (mode
, op1
, if_false_label
, if_true_label
,
775 if (! if_false_label
)
776 drop_through_label
= if_false_label
= gen_label_rtx ();
778 for (i
= 0; i
< nwords
; i
++)
779 do_compare_rtx_and_jump (operand_subword_force (op0
, i
, mode
),
780 operand_subword_force (op1
, i
, mode
),
781 EQ
, 0, word_mode
, NULL_RTX
,
782 if_false_label
, NULL_RTX
, prob
);
785 emit_jump (if_true_label
);
786 if (drop_through_label
)
787 emit_label (drop_through_label
);
790 /* Given an EQ_EXPR expression EXP for values too wide to be compared
791 with one insn, test the comparison and jump to the appropriate label. */
794 do_jump_by_parts_equality (tree treeop0
, tree treeop1
, rtx if_false_label
,
795 rtx if_true_label
, int prob
)
797 rtx op0
= expand_normal (treeop0
);
798 rtx op1
= expand_normal (treeop1
);
799 enum machine_mode mode
= TYPE_MODE (TREE_TYPE (treeop0
));
800 do_jump_by_parts_equality_rtx (mode
, op0
, op1
, if_false_label
,
801 if_true_label
, prob
);
804 /* Split a comparison into two others, the second of which has the other
805 "orderedness". The first is always ORDERED or UNORDERED if MODE
806 does not honor NaNs (which means that it can be skipped in that case;
807 see do_compare_rtx_and_jump).
809 The two conditions are written in *CODE1 and *CODE2. Return true if
810 the conditions must be ANDed, false if they must be ORed. */
813 split_comparison (enum rtx_code code
, enum machine_mode mode
,
814 enum rtx_code
*code1
, enum rtx_code
*code2
)
863 /* Do not turn a trapping comparison into a non-trapping one. */
864 if (HONOR_SNANS (mode
))
882 /* Like do_compare_and_jump but expects the values to compare as two rtx's.
883 The decision as to signed or unsigned comparison must be made by the caller.
885 If MODE is BLKmode, SIZE is an RTX giving the size of the objects being
889 do_compare_rtx_and_jump (rtx op0
, rtx op1
, enum rtx_code code
, int unsignedp
,
890 enum machine_mode mode
, rtx size
, rtx if_false_label
,
891 rtx if_true_label
, int prob
)
894 rtx dummy_label
= NULL_RTX
;
897 /* Reverse the comparison if that is safe and we want to jump if it is
898 false. Also convert to the reverse comparison if the target can
901 || ! can_compare_p (code
, mode
, ccp_jump
))
902 && (! FLOAT_MODE_P (mode
)
903 || code
== ORDERED
|| code
== UNORDERED
904 || (! HONOR_NANS (mode
) && (code
== LTGT
|| code
== UNEQ
))
905 || (! HONOR_SNANS (mode
) && (code
== EQ
|| code
== NE
))))
908 if (FLOAT_MODE_P (mode
))
909 rcode
= reverse_condition_maybe_unordered (code
);
911 rcode
= reverse_condition (code
);
913 /* Canonicalize to UNORDERED for the libcall. */
914 if (can_compare_p (rcode
, mode
, ccp_jump
)
915 || (code
== ORDERED
&& ! can_compare_p (ORDERED
, mode
, ccp_jump
)))
918 if_true_label
= if_false_label
;
919 if_false_label
= tem
;
925 /* If one operand is constant, make it the second one. Only do this
926 if the other operand is not constant as well. */
928 if (swap_commutative_operands_p (op0
, op1
))
933 code
= swap_condition (code
);
936 do_pending_stack_adjust ();
938 code
= unsignedp
? unsigned_condition (code
) : code
;
939 if (0 != (tem
= simplify_relational_operation (code
, mode
, VOIDmode
,
942 if (CONSTANT_P (tem
))
944 rtx label
= (tem
== const0_rtx
|| tem
== CONST0_RTX (mode
))
945 ? if_false_label
: if_true_label
;
951 code
= GET_CODE (tem
);
952 mode
= GET_MODE (tem
);
955 unsignedp
= (code
== GTU
|| code
== LTU
|| code
== GEU
|| code
== LEU
);
959 dummy_label
= if_true_label
= gen_label_rtx ();
961 if (GET_MODE_CLASS (mode
) == MODE_INT
962 && ! can_compare_p (code
, mode
, ccp_jump
))
967 do_jump_by_parts_greater_rtx (mode
, 1, op1
, op0
,
968 if_false_label
, if_true_label
, prob
);
972 do_jump_by_parts_greater_rtx (mode
, 1, op0
, op1
,
973 if_true_label
, if_false_label
,
978 do_jump_by_parts_greater_rtx (mode
, 1, op0
, op1
,
979 if_false_label
, if_true_label
, prob
);
983 do_jump_by_parts_greater_rtx (mode
, 1, op1
, op0
,
984 if_true_label
, if_false_label
,
989 do_jump_by_parts_greater_rtx (mode
, 0, op1
, op0
,
990 if_false_label
, if_true_label
, prob
);
994 do_jump_by_parts_greater_rtx (mode
, 0, op0
, op1
,
995 if_true_label
, if_false_label
,
1000 do_jump_by_parts_greater_rtx (mode
, 0, op0
, op1
,
1001 if_false_label
, if_true_label
, prob
);
1005 do_jump_by_parts_greater_rtx (mode
, 0, op1
, op0
,
1006 if_true_label
, if_false_label
,
1011 do_jump_by_parts_equality_rtx (mode
, op0
, op1
, if_false_label
,
1012 if_true_label
, prob
);
1016 do_jump_by_parts_equality_rtx (mode
, op0
, op1
, if_true_label
,
1017 if_false_label
, inv (prob
));
1026 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
1027 && ! can_compare_p (code
, mode
, ccp_jump
)
1028 && can_compare_p (swap_condition (code
), mode
, ccp_jump
))
1031 code
= swap_condition (code
);
1037 else if (GET_MODE_CLASS (mode
) == MODE_FLOAT
1038 && ! can_compare_p (code
, mode
, ccp_jump
)
1040 /* Never split ORDERED and UNORDERED. These must be implemented. */
1041 && (code
!= ORDERED
&& code
!= UNORDERED
)
1043 /* Split a floating-point comparison if we can jump on other
1045 && (have_insn_for (COMPARE
, mode
)
1047 /* ... or if there is no libcall for it. */
1048 || code_to_optab
[code
] == NULL
))
1050 enum rtx_code first_code
;
1051 bool and_them
= split_comparison (code
, mode
, &first_code
, &code
);
1053 /* If there are no NaNs, the first comparison should always fall
1055 if (!HONOR_NANS (mode
))
1056 gcc_assert (first_code
== (and_them
? ORDERED
: UNORDERED
));
1063 /* If we only jump if true, just bypass the second jump. */
1064 if (! if_false_label
)
1067 dummy_label
= gen_label_rtx ();
1068 dest_label
= dummy_label
;
1071 dest_label
= if_false_label
;
1072 do_compare_rtx_and_jump (op0
, op1
, first_code
, unsignedp
, mode
,
1073 size
, dest_label
, NULL_RTX
, prob
);
1076 do_compare_rtx_and_jump (op0
, op1
, first_code
, unsignedp
, mode
,
1077 size
, NULL_RTX
, if_true_label
, prob
);
1081 last
= get_last_insn ();
1082 emit_cmp_and_jump_insns (op0
, op1
, code
, size
, mode
, unsignedp
,
1084 if (prob
!= -1 && profile_status
!= PROFILE_ABSENT
)
1086 for (last
= NEXT_INSN (last
);
1087 last
&& NEXT_INSN (last
);
1088 last
= NEXT_INSN (last
))
1094 || !any_condjump_p (last
))
1097 fprintf (dump_file
, "Failed to add probability note\n");
1101 gcc_assert (!find_reg_note (last
, REG_BR_PROB
, 0));
1102 add_reg_note (last
, REG_BR_PROB
, GEN_INT (prob
));
1108 emit_jump (if_false_label
);
1110 emit_label (dummy_label
);
1113 /* Generate code for a comparison expression EXP (including code to compute
1114 the values to be compared) and a conditional jump to IF_FALSE_LABEL and/or
1115 IF_TRUE_LABEL. One of the labels can be NULL_RTX, in which case the
1116 generated code will drop through.
1117 SIGNED_CODE should be the rtx operation for this comparison for
1118 signed data; UNSIGNED_CODE, likewise for use if data is unsigned.
1120 We force a stack adjustment unless there are currently
1121 things pushed on the stack that aren't yet used. */
1124 do_compare_and_jump (tree treeop0
, tree treeop1
, enum rtx_code signed_code
,
1125 enum rtx_code unsigned_code
, rtx if_false_label
,
1126 rtx if_true_label
, int prob
)
1130 enum machine_mode mode
;
1134 /* Don't crash if the comparison was erroneous. */
1135 op0
= expand_normal (treeop0
);
1136 if (TREE_CODE (treeop0
) == ERROR_MARK
)
1139 op1
= expand_normal (treeop1
);
1140 if (TREE_CODE (treeop1
) == ERROR_MARK
)
1143 type
= TREE_TYPE (treeop0
);
1144 mode
= TYPE_MODE (type
);
1145 if (TREE_CODE (treeop0
) == INTEGER_CST
1146 && (TREE_CODE (treeop1
) != INTEGER_CST
1147 || (GET_MODE_BITSIZE (mode
)
1148 > GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (treeop1
))))))
1150 /* op0 might have been replaced by promoted constant, in which
1151 case the type of second argument should be used. */
1152 type
= TREE_TYPE (treeop1
);
1153 mode
= TYPE_MODE (type
);
1155 unsignedp
= TYPE_UNSIGNED (type
);
1156 code
= unsignedp
? unsigned_code
: signed_code
;
1158 #ifdef HAVE_canonicalize_funcptr_for_compare
1159 /* If function pointers need to be "canonicalized" before they can
1160 be reliably compared, then canonicalize them.
1161 Only do this if *both* sides of the comparison are function pointers.
1162 If one side isn't, we want a noncanonicalized comparison. See PR
1163 middle-end/17564. */
1164 if (HAVE_canonicalize_funcptr_for_compare
1165 && TREE_CODE (TREE_TYPE (treeop0
)) == POINTER_TYPE
1166 && TREE_CODE (TREE_TYPE (TREE_TYPE (treeop0
)))
1168 && TREE_CODE (TREE_TYPE (treeop1
)) == POINTER_TYPE
1169 && TREE_CODE (TREE_TYPE (TREE_TYPE (treeop1
)))
1172 rtx new_op0
= gen_reg_rtx (mode
);
1173 rtx new_op1
= gen_reg_rtx (mode
);
1175 emit_insn (gen_canonicalize_funcptr_for_compare (new_op0
, op0
));
1178 emit_insn (gen_canonicalize_funcptr_for_compare (new_op1
, op1
));
1183 do_compare_rtx_and_jump (op0
, op1
, code
, unsignedp
, mode
,
1185 ? expr_size (treeop0
) : NULL_RTX
),
1186 if_false_label
, if_true_label
, prob
);
1189 #include "gt-dojump.h"