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
)
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
),
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. */
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. */
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;
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
,
205 do_compare_and_jump (op0
, op1
, EQ
, EQ
, if_false_label
, if_true_label
,
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
,
226 do_compare_and_jump (op0
, op1
, NE
, NE
, if_false_label
, if_true_label
,
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
,
238 do_compare_and_jump (op0
, op1
, LT
, LTU
, if_false_label
, if_true_label
,
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
,
249 do_compare_and_jump (op0
, op1
, LE
, LEU
, if_false_label
, if_true_label
,
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
,
260 do_compare_and_jump (op0
, op1
, GT
, GTU
, if_false_label
, if_true_label
,
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
,
271 do_compare_and_jump (op0
, op1
, GE
, GEU
, if_false_label
, if_true_label
,
276 do_compare_and_jump (op0
, op1
, ORDERED
, ORDERED
,
277 if_false_label
, if_true_label
, prob
);
281 do_compare_and_jump (op0
, op1
, UNORDERED
, UNORDERED
,
282 if_false_label
, if_true_label
, prob
);
286 do_compare_and_jump (op0
, op1
, UNLT
, UNLT
, if_false_label
, if_true_label
,
291 do_compare_and_jump (op0
, op1
, UNLE
, UNLE
, if_false_label
, if_true_label
,
296 do_compare_and_jump (op0
, op1
, UNGT
, UNGT
, if_false_label
, if_true_label
,
301 do_compare_and_jump (op0
, op1
, UNGE
, UNGE
, if_false_label
, if_true_label
,
306 do_compare_and_jump (op0
, op1
, UNEQ
, UNEQ
, if_false_label
, if_true_label
,
311 do_compare_and_jump (op0
, op1
, LTGT
, LTGT
, if_false_label
, if_true_label
,
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
);
324 do_jump (op0
, if_false_label
, NULL_RTX
, prob
);
325 do_jump (op1
, if_false_label
, if_true_label
, prob
);
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
);
338 do_jump (op0
, NULL_RTX
, if_true_label
, prob
);
339 do_jump (op1
, if_false_label
, if_true_label
, prob
);
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. */
366 do_jump (tree exp
, rtx if_false_label
, rtx if_true_label
, int prob
)
368 enum tree_code code
= TREE_CODE (exp
);
372 enum machine_mode mode
;
373 rtx drop_through_label
= 0;
381 temp
= integer_zerop (exp
) ? if_false_label
: if_true_label
;
387 /* This is not true with #pragma weak */
389 /* The address of something can never be zero. */
391 emit_jump (if_true_label
);
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
)
402 /* If we are narrowing the operand, we have to do the compare in the
404 if ((TYPE_PRECISION (TREE_TYPE (exp
))
405 < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp
, 0)))))
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
))
416 /* These cannot change zero->nonzero or vice versa. */
417 do_jump (TREE_OPERAND (exp
, 0), if_false_label
, if_true_label
, prob
);
421 do_jump (TREE_OPERAND (exp
, 0), if_true_label
, if_false_label
,
427 rtx label1
= gen_label_rtx ();
428 if (!if_true_label
|| !if_false_label
)
430 drop_through_label
= gen_label_rtx ();
432 if_true_label
= drop_through_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
);
441 do_jump (TREE_OPERAND (exp
, 2), if_false_label
, if_true_label
, prob
);
446 /* Lowered by gimplify.c. */
450 /* Nonzero iff operands of minus differ. */
468 case TRUTH_ANDIF_EXPR
:
469 case TRUTH_ORIF_EXPR
:
471 do_jump_1 (code
, TREE_OPERAND (exp
, 0), TREE_OPERAND (exp
, 1),
472 if_false_label
, if_true_label
, prob
);
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
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
);
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
);
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
,
549 if (TYPE_PRECISION (TREE_TYPE (exp
)) > 1
550 || TREE_CODE (TREE_OPERAND (exp
, 1)) == INTEGER_CST
)
553 /* Boolean comparisons can be compiled as 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 (),
561 || TREE_SIDE_EFFECTS (TREE_OPERAND (exp
, 1)))
563 code
= TRUTH_ANDIF_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)))
574 code
= TRUTH_ORIF_EXPR
;
577 /* Fall through and generate the normal code. */
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);
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. */
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
,
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
;
620 if (! if_true_label
|| ! if_false_label
)
621 drop_through_label
= gen_label_rtx ();
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
)
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
);
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
,
665 /* Emit only one comparison for 0. Do not emit the last cond jump. */
666 if (op0
== const0_rtx
|| i
== nwords
- 1)
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. */
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. */
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
;
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
);
726 do_compare_rtx_and_jump (part
, const0_rtx
, EQ
, 1, word_mode
,
727 NULL_RTX
, if_false_label
, if_true_label
, prob
);
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
);
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. */
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;
760 if (op1
== const0_rtx
)
762 do_jump_by_parts_zero_rtx (mode
, op0
, if_false_label
, if_true_label
,
766 else if (op0
== const0_rtx
)
768 do_jump_by_parts_zero_rtx (mode
, op1
, if_false_label
, if_true_label
,
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
);
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. */
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. */
811 split_comparison (enum rtx_code code
, enum machine_mode mode
,
812 enum rtx_code
*code1
, enum rtx_code
*code2
)
861 /* Do not turn a trapping comparison into a non-trapping one. */
862 if (HONOR_SNANS (mode
))
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
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
)
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
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
))))
905 if (FLOAT_MODE_P (mode
))
906 rcode
= reverse_condition_maybe_unordered (code
);
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
)))
915 if_true_label
= if_false_label
;
916 if_false_label
= tem
;
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
))
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
,
939 if (CONSTANT_P (tem
))
941 rtx label
= (tem
== const0_rtx
|| tem
== CONST0_RTX (mode
))
942 ? if_false_label
: if_true_label
;
948 code
= GET_CODE (tem
);
949 mode
= GET_MODE (tem
);
952 unsignedp
= (code
== GTU
|| code
== LTU
|| code
== GEU
|| code
== LEU
);
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
))
964 do_jump_by_parts_greater_rtx (mode
, 1, op1
, op0
,
965 if_false_label
, if_true_label
, prob
);
969 do_jump_by_parts_greater_rtx (mode
, 1, op0
, op1
,
970 if_true_label
, if_false_label
,
975 do_jump_by_parts_greater_rtx (mode
, 1, op0
, op1
,
976 if_false_label
, if_true_label
, prob
);
980 do_jump_by_parts_greater_rtx (mode
, 1, op1
, op0
,
981 if_true_label
, if_false_label
,
986 do_jump_by_parts_greater_rtx (mode
, 0, op1
, op0
,
987 if_false_label
, if_true_label
, prob
);
991 do_jump_by_parts_greater_rtx (mode
, 0, op0
, op1
,
992 if_true_label
, if_false_label
,
997 do_jump_by_parts_greater_rtx (mode
, 0, op0
, op1
,
998 if_false_label
, if_true_label
, prob
);
1002 do_jump_by_parts_greater_rtx (mode
, 0, op1
, op0
,
1003 if_true_label
, if_false_label
,
1008 do_jump_by_parts_equality_rtx (mode
, op0
, op1
, if_false_label
,
1009 if_true_label
, prob
);
1013 do_jump_by_parts_equality_rtx (mode
, op0
, op1
, if_true_label
,
1014 if_false_label
, inv (prob
));
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
))
1028 code
= swap_condition (code
);
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
1049 if (!HONOR_NANS (mode
))
1050 gcc_assert (first_code
== (and_them
? ORDERED
: UNORDERED
));
1057 /* If we only jump if true, just bypass the second jump. */
1058 if (! if_false_label
)
1061 dummy_label
= gen_label_rtx ();
1062 dest_label
= dummy_label
;
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
);
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
);
1080 emit_jump (if_false_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. */
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
)
1102 enum machine_mode mode
;
1106 /* Don't crash if the comparison was erroneous. */
1107 op0
= expand_normal (treeop0
);
1108 if (TREE_CODE (treeop0
) == ERROR_MARK
)
1111 op1
= expand_normal (treeop1
);
1112 if (TREE_CODE (treeop1
) == ERROR_MARK
)
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
)))
1140 && TREE_CODE (TREE_TYPE (treeop1
)) == POINTER_TYPE
1141 && TREE_CODE (TREE_TYPE (TREE_TYPE (treeop1
)))
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
));
1150 emit_insn (gen_canonicalize_funcptr_for_compare (new_op1
, op1
));
1155 do_compare_rtx_and_jump (op0
, op1
, code
, unsignedp
, mode
,
1157 ? expr_size (treeop0
) : NULL_RTX
),
1158 if_false_label
, if_true_label
, prob
);
1161 #include "gt-dojump.h"