1 /* Convert tree expression to rtl instructions, for GNU compiler.
2 Copyright (C) 1988-2015 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
22 #include "coretypes.h"
28 #include "double-int.h"
36 #include "fold-const.h"
37 #include "stor-layout.h"
39 #include "hard-reg-set.h"
41 #include "insn-config.h"
42 #include "insn-attr.h"
43 /* Include expr.h after insn-config.h so we get HAVE_conditional_move. */
45 #include "statistics.h"
46 #include "fixed-value.h"
55 #include "insn-codes.h"
57 #include "langhooks.h"
60 #include "basic-block.h"
63 static bool prefer_and_bit_test (machine_mode
, int);
64 static void do_jump_by_parts_greater (tree
, tree
, int, rtx
, rtx
, int);
65 static void do_jump_by_parts_equality (tree
, tree
, rtx
, rtx
, int);
66 static void do_compare_and_jump (tree
, tree
, enum rtx_code
, enum rtx_code
, rtx
,
69 /* Invert probability if there is any. -1 stands for unknown. */
74 return prob
== -1 ? -1 : REG_BR_PROB_BASE
- prob
;
77 /* At the start of a function, record that we have no previously-pushed
78 arguments waiting to be popped. */
81 init_pending_stack_adjust (void)
83 pending_stack_adjust
= 0;
86 /* Discard any pending stack adjustment. This avoid relying on the
87 RTL optimizers to remove useless adjustments when we know the
88 stack pointer value is dead. */
90 discard_pending_stack_adjust (void)
92 stack_pointer_delta
-= pending_stack_adjust
;
93 pending_stack_adjust
= 0;
96 /* When exiting from function, if safe, clear out any pending stack adjust
97 so the adjustment won't get done.
99 Note, if the current function calls alloca, then it must have a
100 frame pointer regardless of the value of flag_omit_frame_pointer. */
103 clear_pending_stack_adjust (void)
106 && (! flag_omit_frame_pointer
|| cfun
->calls_alloca
)
107 && EXIT_IGNORE_STACK
)
108 discard_pending_stack_adjust ();
111 /* Pop any previously-pushed arguments that have not been popped yet. */
114 do_pending_stack_adjust (void)
116 if (inhibit_defer_pop
== 0)
118 if (pending_stack_adjust
!= 0)
119 adjust_stack (GEN_INT (pending_stack_adjust
));
120 pending_stack_adjust
= 0;
124 /* Remember pending_stack_adjust/stack_pointer_delta.
125 To be used around code that may call do_pending_stack_adjust (),
126 but the generated code could be discarded e.g. using delete_insns_since. */
129 save_pending_stack_adjust (saved_pending_stack_adjust
*save
)
131 save
->x_pending_stack_adjust
= pending_stack_adjust
;
132 save
->x_stack_pointer_delta
= stack_pointer_delta
;
135 /* Restore the saved pending_stack_adjust/stack_pointer_delta. */
138 restore_pending_stack_adjust (saved_pending_stack_adjust
*save
)
140 if (inhibit_defer_pop
== 0)
142 pending_stack_adjust
= save
->x_pending_stack_adjust
;
143 stack_pointer_delta
= save
->x_stack_pointer_delta
;
147 /* Expand conditional expressions. */
149 /* Generate code to evaluate EXP and jump to LABEL if the value is zero.
150 LABEL is an rtx of code CODE_LABEL, in this function and all the
154 jumpifnot (tree exp
, rtx label
, int prob
)
156 do_jump (exp
, label
, NULL_RTX
, inv (prob
));
160 jumpifnot_1 (enum tree_code code
, tree op0
, tree op1
, rtx label
, int prob
)
162 do_jump_1 (code
, op0
, op1
, label
, NULL_RTX
, inv (prob
));
165 /* Generate code to evaluate EXP and jump to LABEL if the value is nonzero. */
168 jumpif (tree exp
, rtx label
, int prob
)
170 do_jump (exp
, NULL_RTX
, label
, prob
);
174 jumpif_1 (enum tree_code code
, tree op0
, tree op1
, rtx label
, int prob
)
176 do_jump_1 (code
, op0
, op1
, NULL_RTX
, label
, prob
);
179 /* Used internally by prefer_and_bit_test. */
181 static GTY(()) rtx and_reg
;
182 static GTY(()) rtx and_test
;
183 static GTY(()) rtx shift_test
;
185 /* Compare the relative costs of "(X & (1 << BITNUM))" and "(X >> BITNUM) & 1",
186 where X is an arbitrary register of mode MODE. Return true if the former
190 prefer_and_bit_test (machine_mode mode
, int bitnum
)
193 wide_int mask
= wi::set_bit_in_zero (bitnum
, GET_MODE_PRECISION (mode
));
197 /* Set up rtxes for the two variations. Use NULL as a placeholder
198 for the BITNUM-based constants. */
199 and_reg
= gen_rtx_REG (mode
, FIRST_PSEUDO_REGISTER
);
200 and_test
= gen_rtx_AND (mode
, and_reg
, NULL
);
201 shift_test
= gen_rtx_AND (mode
, gen_rtx_ASHIFTRT (mode
, and_reg
, NULL
),
206 /* Change the mode of the previously-created rtxes. */
207 PUT_MODE (and_reg
, mode
);
208 PUT_MODE (and_test
, mode
);
209 PUT_MODE (shift_test
, mode
);
210 PUT_MODE (XEXP (shift_test
, 0), mode
);
213 /* Fill in the integers. */
214 XEXP (and_test
, 1) = immed_wide_int_const (mask
, mode
);
215 XEXP (XEXP (shift_test
, 0), 1) = GEN_INT (bitnum
);
217 speed_p
= optimize_insn_for_speed_p ();
218 return (rtx_cost (and_test
, IF_THEN_ELSE
, 0, speed_p
)
219 <= rtx_cost (shift_test
, IF_THEN_ELSE
, 0, speed_p
));
222 /* Subroutine of do_jump, dealing with exploded comparisons of the type
223 OP0 CODE OP1 . IF_FALSE_LABEL and IF_TRUE_LABEL like in do_jump.
224 PROB is probability of jump to if_true_label, or -1 if unknown. */
227 do_jump_1 (enum tree_code code
, tree op0
, tree op1
,
228 rtx if_false_label
, rtx if_true_label
, int prob
)
231 rtx_code_label
*drop_through_label
= 0;
237 tree inner_type
= TREE_TYPE (op0
);
239 gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type
))
240 != MODE_COMPLEX_FLOAT
);
241 gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type
))
242 != MODE_COMPLEX_INT
);
244 if (integer_zerop (op1
))
245 do_jump (op0
, if_true_label
, if_false_label
, inv (prob
));
246 else if (GET_MODE_CLASS (TYPE_MODE (inner_type
)) == MODE_INT
247 && !can_compare_p (EQ
, TYPE_MODE (inner_type
), ccp_jump
))
248 do_jump_by_parts_equality (op0
, op1
, if_false_label
, if_true_label
,
251 do_compare_and_jump (op0
, op1
, EQ
, EQ
, if_false_label
, if_true_label
,
258 tree inner_type
= TREE_TYPE (op0
);
260 gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type
))
261 != MODE_COMPLEX_FLOAT
);
262 gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type
))
263 != MODE_COMPLEX_INT
);
265 if (integer_zerop (op1
))
266 do_jump (op0
, if_false_label
, if_true_label
, prob
);
267 else if (GET_MODE_CLASS (TYPE_MODE (inner_type
)) == MODE_INT
268 && !can_compare_p (NE
, TYPE_MODE (inner_type
), ccp_jump
))
269 do_jump_by_parts_equality (op0
, op1
, if_true_label
, if_false_label
,
272 do_compare_and_jump (op0
, op1
, NE
, NE
, if_false_label
, if_true_label
,
278 mode
= TYPE_MODE (TREE_TYPE (op0
));
279 if (GET_MODE_CLASS (mode
) == MODE_INT
280 && ! can_compare_p (LT
, mode
, ccp_jump
))
281 do_jump_by_parts_greater (op0
, op1
, 1, if_false_label
, if_true_label
,
284 do_compare_and_jump (op0
, op1
, LT
, LTU
, if_false_label
, if_true_label
,
289 mode
= TYPE_MODE (TREE_TYPE (op0
));
290 if (GET_MODE_CLASS (mode
) == MODE_INT
291 && ! can_compare_p (LE
, mode
, ccp_jump
))
292 do_jump_by_parts_greater (op0
, op1
, 0, if_true_label
, if_false_label
,
295 do_compare_and_jump (op0
, op1
, LE
, LEU
, if_false_label
, if_true_label
,
300 mode
= TYPE_MODE (TREE_TYPE (op0
));
301 if (GET_MODE_CLASS (mode
) == MODE_INT
302 && ! can_compare_p (GT
, mode
, ccp_jump
))
303 do_jump_by_parts_greater (op0
, op1
, 0, if_false_label
, if_true_label
,
306 do_compare_and_jump (op0
, op1
, GT
, GTU
, if_false_label
, if_true_label
,
311 mode
= TYPE_MODE (TREE_TYPE (op0
));
312 if (GET_MODE_CLASS (mode
) == MODE_INT
313 && ! can_compare_p (GE
, mode
, ccp_jump
))
314 do_jump_by_parts_greater (op0
, op1
, 1, if_true_label
, if_false_label
,
317 do_compare_and_jump (op0
, op1
, GE
, GEU
, if_false_label
, if_true_label
,
322 do_compare_and_jump (op0
, op1
, ORDERED
, ORDERED
,
323 if_false_label
, if_true_label
, prob
);
327 do_compare_and_jump (op0
, op1
, UNORDERED
, UNORDERED
,
328 if_false_label
, if_true_label
, prob
);
332 do_compare_and_jump (op0
, op1
, UNLT
, UNLT
, if_false_label
, if_true_label
,
337 do_compare_and_jump (op0
, op1
, UNLE
, UNLE
, if_false_label
, if_true_label
,
342 do_compare_and_jump (op0
, op1
, UNGT
, UNGT
, if_false_label
, if_true_label
,
347 do_compare_and_jump (op0
, op1
, UNGE
, UNGE
, if_false_label
, if_true_label
,
352 do_compare_and_jump (op0
, op1
, UNEQ
, UNEQ
, if_false_label
, if_true_label
,
357 do_compare_and_jump (op0
, op1
, LTGT
, LTGT
, if_false_label
, if_true_label
,
361 case TRUTH_ANDIF_EXPR
:
363 /* Spread the probability that the expression is false evenly between
364 the two conditions. So the first condition is false half the total
365 probability of being false. The second condition is false the other
366 half of the total probability of being false, so its jump has a false
367 probability of half the total, relative to the probability we
368 reached it (i.e. the first condition was true). */
373 int false_prob
= inv (prob
);
374 int op0_false_prob
= false_prob
/ 2;
375 int op1_false_prob
= GCOV_COMPUTE_SCALE ((false_prob
/ 2),
376 inv (op0_false_prob
));
377 /* Get the probability that each jump below is true. */
378 op0_prob
= inv (op0_false_prob
);
379 op1_prob
= inv (op1_false_prob
);
381 if (if_false_label
== NULL_RTX
)
383 drop_through_label
= gen_label_rtx ();
384 do_jump (op0
, drop_through_label
, NULL_RTX
, op0_prob
);
385 do_jump (op1
, NULL_RTX
, if_true_label
, op1_prob
);
389 do_jump (op0
, if_false_label
, NULL_RTX
, op0_prob
);
390 do_jump (op1
, if_false_label
, if_true_label
, op1_prob
);
395 case TRUTH_ORIF_EXPR
:
397 /* Spread the probability evenly between the two conditions. So
398 the first condition has half the total probability of being true.
399 The second condition has the other half of the total probability,
400 so its jump has a probability of half the total, relative to
401 the probability we reached it (i.e. the first condition was false). */
407 op1_prob
= GCOV_COMPUTE_SCALE ((prob
/ 2), inv (op0_prob
));
409 if (if_true_label
== NULL_RTX
)
411 drop_through_label
= gen_label_rtx ();
412 do_jump (op0
, NULL_RTX
, drop_through_label
, op0_prob
);
413 do_jump (op1
, if_false_label
, NULL_RTX
, op1_prob
);
417 do_jump (op0
, NULL_RTX
, if_true_label
, op0_prob
);
418 do_jump (op1
, if_false_label
, if_true_label
, op1_prob
);
427 if (drop_through_label
)
429 do_pending_stack_adjust ();
430 emit_label (drop_through_label
);
434 /* Generate code to evaluate EXP and jump to IF_FALSE_LABEL if
435 the result is zero, or IF_TRUE_LABEL if the result is one.
436 Either of IF_FALSE_LABEL and IF_TRUE_LABEL may be zero,
437 meaning fall through in that case.
439 do_jump always does any pending stack adjust except when it does not
440 actually perform a jump. An example where there is no jump
441 is when EXP is `(foo (), 0)' and IF_FALSE_LABEL is null.
443 PROB is probability of jump to if_true_label, or -1 if unknown. */
446 do_jump (tree exp
, rtx if_false_label
, rtx if_true_label
, int prob
)
448 enum tree_code code
= TREE_CODE (exp
);
453 rtx_code_label
*drop_through_label
= 0;
461 temp
= integer_zerop (exp
) ? if_false_label
: if_true_label
;
467 /* This is not true with #pragma weak */
469 /* The address of something can never be zero. */
471 emit_jump (if_true_label
);
476 if (TREE_CODE (TREE_OPERAND (exp
, 0)) == COMPONENT_REF
477 || TREE_CODE (TREE_OPERAND (exp
, 0)) == BIT_FIELD_REF
478 || TREE_CODE (TREE_OPERAND (exp
, 0)) == ARRAY_REF
479 || TREE_CODE (TREE_OPERAND (exp
, 0)) == ARRAY_RANGE_REF
)
482 /* If we are narrowing the operand, we have to do the compare in the
484 if ((TYPE_PRECISION (TREE_TYPE (exp
))
485 < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp
, 0)))))
487 case NON_LVALUE_EXPR
:
492 /* These cannot change zero->nonzero or vice versa. */
493 do_jump (TREE_OPERAND (exp
, 0), if_false_label
, if_true_label
, prob
);
497 do_jump (TREE_OPERAND (exp
, 0), if_true_label
, if_false_label
,
503 rtx_code_label
*label1
= gen_label_rtx ();
504 if (!if_true_label
|| !if_false_label
)
506 drop_through_label
= gen_label_rtx ();
508 if_true_label
= drop_through_label
;
510 if_false_label
= drop_through_label
;
513 do_pending_stack_adjust ();
514 do_jump (TREE_OPERAND (exp
, 0), label1
, NULL_RTX
, -1);
515 do_jump (TREE_OPERAND (exp
, 1), if_false_label
, if_true_label
, prob
);
517 do_jump (TREE_OPERAND (exp
, 2), if_false_label
, if_true_label
, prob
);
522 /* Lowered by gimplify.c. */
526 /* Nonzero iff operands of minus differ. */
544 case TRUTH_ANDIF_EXPR
:
545 case TRUTH_ORIF_EXPR
:
547 do_jump_1 (code
, TREE_OPERAND (exp
, 0), TREE_OPERAND (exp
, 1),
548 if_false_label
, if_true_label
, prob
);
552 /* fold_single_bit_test() converts (X & (1 << C)) into (X >> C) & 1.
553 See if the former is preferred for jump tests and restore it
555 if (integer_onep (TREE_OPERAND (exp
, 1)))
557 tree exp0
= TREE_OPERAND (exp
, 0);
558 rtx set_label
, clr_label
;
559 int setclr_prob
= prob
;
561 /* Strip narrowing integral type conversions. */
562 while (CONVERT_EXPR_P (exp0
)
563 && TREE_OPERAND (exp0
, 0) != error_mark_node
564 && TYPE_PRECISION (TREE_TYPE (exp0
))
565 <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp0
, 0))))
566 exp0
= TREE_OPERAND (exp0
, 0);
568 /* "exp0 ^ 1" inverts the sense of the single bit test. */
569 if (TREE_CODE (exp0
) == BIT_XOR_EXPR
570 && integer_onep (TREE_OPERAND (exp0
, 1)))
572 exp0
= TREE_OPERAND (exp0
, 0);
573 clr_label
= if_true_label
;
574 set_label
= if_false_label
;
575 setclr_prob
= inv (prob
);
579 clr_label
= if_false_label
;
580 set_label
= if_true_label
;
583 if (TREE_CODE (exp0
) == RSHIFT_EXPR
)
585 tree arg
= TREE_OPERAND (exp0
, 0);
586 tree shift
= TREE_OPERAND (exp0
, 1);
587 tree argtype
= TREE_TYPE (arg
);
588 if (TREE_CODE (shift
) == INTEGER_CST
589 && compare_tree_int (shift
, 0) >= 0
590 && compare_tree_int (shift
, HOST_BITS_PER_WIDE_INT
) < 0
591 && prefer_and_bit_test (TYPE_MODE (argtype
),
592 TREE_INT_CST_LOW (shift
)))
594 unsigned HOST_WIDE_INT mask
595 = (unsigned HOST_WIDE_INT
) 1 << TREE_INT_CST_LOW (shift
);
596 do_jump (build2 (BIT_AND_EXPR
, argtype
, arg
,
597 build_int_cstu (argtype
, mask
)),
598 clr_label
, set_label
, setclr_prob
);
604 /* If we are AND'ing with a small constant, do this comparison in the
605 smallest type that fits. If the machine doesn't have comparisons
606 that small, it will be converted back to the wider comparison.
607 This helps if we are testing the sign bit of a narrower object.
608 combine can't do this for us because it can't know whether a
609 ZERO_EXTRACT or a compare in a smaller mode exists, but we do. */
611 if (! SLOW_BYTE_ACCESS
612 && TREE_CODE (TREE_OPERAND (exp
, 1)) == INTEGER_CST
613 && TYPE_PRECISION (TREE_TYPE (exp
)) <= HOST_BITS_PER_WIDE_INT
614 && (i
= tree_floor_log2 (TREE_OPERAND (exp
, 1))) >= 0
615 && (mode
= mode_for_size (i
+ 1, MODE_INT
, 0)) != BLKmode
616 && (type
= lang_hooks
.types
.type_for_mode (mode
, 1)) != 0
617 && TYPE_PRECISION (type
) < TYPE_PRECISION (TREE_TYPE (exp
))
618 && have_insn_for (COMPARE
, TYPE_MODE (type
)))
620 do_jump (fold_convert (type
, exp
), if_false_label
, if_true_label
,
625 if (TYPE_PRECISION (TREE_TYPE (exp
)) > 1
626 || TREE_CODE (TREE_OPERAND (exp
, 1)) == INTEGER_CST
)
629 /* Boolean comparisons can be compiled as TRUTH_AND_EXPR. */
632 /* High branch cost, expand as the bitwise AND of the conditions.
633 Do the same if the RHS has side effects, because we're effectively
634 turning a TRUTH_AND_EXPR into a TRUTH_ANDIF_EXPR. */
635 if (BRANCH_COST (optimize_insn_for_speed_p (),
637 || TREE_SIDE_EFFECTS (TREE_OPERAND (exp
, 1)))
639 code
= TRUTH_ANDIF_EXPR
;
644 /* High branch cost, expand as the bitwise OR of the conditions.
645 Do the same if the RHS has side effects, because we're effectively
646 turning a TRUTH_OR_EXPR into a TRUTH_ORIF_EXPR. */
647 if (BRANCH_COST (optimize_insn_for_speed_p (), false) >= 4
648 || TREE_SIDE_EFFECTS (TREE_OPERAND (exp
, 1)))
650 code
= TRUTH_ORIF_EXPR
;
653 /* Fall through and generate the normal code. */
656 temp
= expand_normal (exp
);
657 do_pending_stack_adjust ();
658 /* The RTL optimizers prefer comparisons against pseudos. */
659 if (GET_CODE (temp
) == SUBREG
)
661 /* Compare promoted variables in their promoted mode. */
662 if (SUBREG_PROMOTED_VAR_P (temp
)
663 && REG_P (XEXP (temp
, 0)))
664 temp
= XEXP (temp
, 0);
666 temp
= copy_to_reg (temp
);
668 do_compare_rtx_and_jump (temp
, CONST0_RTX (GET_MODE (temp
)),
669 NE
, TYPE_UNSIGNED (TREE_TYPE (exp
)),
670 GET_MODE (temp
), NULL_RTX
,
671 if_false_label
, if_true_label
, prob
);
674 if (drop_through_label
)
676 do_pending_stack_adjust ();
677 emit_label (drop_through_label
);
681 /* Compare OP0 with OP1, word at a time, in mode MODE.
682 UNSIGNEDP says to do unsigned comparison.
683 Jump to IF_TRUE_LABEL if OP0 is greater, IF_FALSE_LABEL otherwise. */
686 do_jump_by_parts_greater_rtx (machine_mode mode
, int unsignedp
, rtx op0
,
687 rtx op1
, rtx if_false_label
, rtx if_true_label
,
690 int nwords
= (GET_MODE_SIZE (mode
) / UNITS_PER_WORD
);
691 rtx drop_through_label
= 0;
692 bool drop_through_if_true
= false, drop_through_if_false
= false;
693 enum rtx_code code
= GT
;
696 if (! if_true_label
|| ! if_false_label
)
697 drop_through_label
= gen_label_rtx ();
700 if_true_label
= drop_through_label
;
701 drop_through_if_true
= true;
703 if (! if_false_label
)
705 if_false_label
= drop_through_label
;
706 drop_through_if_false
= true;
709 /* Deal with the special case 0 > x: only one comparison is necessary and
710 we reverse it to avoid jumping to the drop-through label. */
711 if (op0
== const0_rtx
&& drop_through_if_true
&& !drop_through_if_false
)
714 if_true_label
= if_false_label
;
715 if_false_label
= drop_through_label
;
716 drop_through_if_true
= false;
717 drop_through_if_false
= true;
720 /* Compare a word at a time, high order first. */
721 for (i
= 0; i
< nwords
; i
++)
723 rtx op0_word
, op1_word
;
725 if (WORDS_BIG_ENDIAN
)
727 op0_word
= operand_subword_force (op0
, i
, mode
);
728 op1_word
= operand_subword_force (op1
, i
, mode
);
732 op0_word
= operand_subword_force (op0
, nwords
- 1 - i
, mode
);
733 op1_word
= operand_subword_force (op1
, nwords
- 1 - i
, mode
);
736 /* All but high-order word must be compared as unsigned. */
737 do_compare_rtx_and_jump (op0_word
, op1_word
, code
, (unsignedp
|| i
> 0),
738 word_mode
, NULL_RTX
, NULL_RTX
, if_true_label
,
741 /* Emit only one comparison for 0. Do not emit the last cond jump. */
742 if (op0
== const0_rtx
|| i
== nwords
- 1)
745 /* Consider lower words only if these are equal. */
746 do_compare_rtx_and_jump (op0_word
, op1_word
, NE
, unsignedp
, word_mode
,
747 NULL_RTX
, NULL_RTX
, if_false_label
, inv (prob
));
750 if (!drop_through_if_false
)
751 emit_jump (if_false_label
);
752 if (drop_through_label
)
753 emit_label (drop_through_label
);
756 /* Given a comparison expression EXP for values too wide to be compared
757 with one insn, test the comparison and jump to the appropriate label.
758 The code of EXP is ignored; we always test GT if SWAP is 0,
759 and LT if SWAP is 1. */
762 do_jump_by_parts_greater (tree treeop0
, tree treeop1
, int swap
,
763 rtx if_false_label
, rtx if_true_label
, int prob
)
765 rtx op0
= expand_normal (swap
? treeop1
: treeop0
);
766 rtx op1
= expand_normal (swap
? treeop0
: treeop1
);
767 machine_mode mode
= TYPE_MODE (TREE_TYPE (treeop0
));
768 int unsignedp
= TYPE_UNSIGNED (TREE_TYPE (treeop0
));
770 do_jump_by_parts_greater_rtx (mode
, unsignedp
, op0
, op1
, if_false_label
,
771 if_true_label
, prob
);
774 /* Jump according to whether OP0 is 0. We assume that OP0 has an integer
775 mode, MODE, that is too wide for the available compare insns. Either
776 Either (but not both) of IF_TRUE_LABEL and IF_FALSE_LABEL may be NULL_RTX
777 to indicate drop through. */
780 do_jump_by_parts_zero_rtx (machine_mode mode
, rtx op0
,
781 rtx if_false_label
, rtx if_true_label
, int prob
)
783 int nwords
= GET_MODE_SIZE (mode
) / UNITS_PER_WORD
;
786 rtx drop_through_label
= 0;
788 /* The fastest way of doing this comparison on almost any machine is to
789 "or" all the words and compare the result. If all have to be loaded
790 from memory and this is a very wide item, it's possible this may
791 be slower, but that's highly unlikely. */
793 part
= gen_reg_rtx (word_mode
);
794 emit_move_insn (part
, operand_subword_force (op0
, 0, mode
));
795 for (i
= 1; i
< nwords
&& part
!= 0; i
++)
796 part
= expand_binop (word_mode
, ior_optab
, part
,
797 operand_subword_force (op0
, i
, mode
),
798 part
, 1, OPTAB_WIDEN
);
802 do_compare_rtx_and_jump (part
, const0_rtx
, EQ
, 1, word_mode
,
803 NULL_RTX
, if_false_label
, if_true_label
, prob
);
807 /* If we couldn't do the "or" simply, do this with a series of compares. */
808 if (! if_false_label
)
809 drop_through_label
= if_false_label
= gen_label_rtx ();
811 for (i
= 0; i
< nwords
; i
++)
812 do_compare_rtx_and_jump (operand_subword_force (op0
, i
, mode
),
813 const0_rtx
, EQ
, 1, word_mode
, NULL_RTX
,
814 if_false_label
, NULL_RTX
, prob
);
817 emit_jump (if_true_label
);
819 if (drop_through_label
)
820 emit_label (drop_through_label
);
823 /* Test for the equality of two RTX expressions OP0 and OP1 in mode MODE,
824 where MODE is an integer mode too wide to be compared with one insn.
825 Either (but not both) of IF_TRUE_LABEL and IF_FALSE_LABEL may be NULL_RTX
826 to indicate drop through. */
829 do_jump_by_parts_equality_rtx (machine_mode mode
, rtx op0
, rtx op1
,
830 rtx if_false_label
, rtx if_true_label
, int prob
)
832 int nwords
= (GET_MODE_SIZE (mode
) / UNITS_PER_WORD
);
833 rtx drop_through_label
= 0;
836 if (op1
== const0_rtx
)
838 do_jump_by_parts_zero_rtx (mode
, op0
, if_false_label
, if_true_label
,
842 else if (op0
== const0_rtx
)
844 do_jump_by_parts_zero_rtx (mode
, op1
, if_false_label
, if_true_label
,
849 if (! if_false_label
)
850 drop_through_label
= if_false_label
= gen_label_rtx ();
852 for (i
= 0; i
< nwords
; i
++)
853 do_compare_rtx_and_jump (operand_subword_force (op0
, i
, mode
),
854 operand_subword_force (op1
, i
, mode
),
855 EQ
, 0, word_mode
, NULL_RTX
,
856 if_false_label
, NULL_RTX
, prob
);
859 emit_jump (if_true_label
);
860 if (drop_through_label
)
861 emit_label (drop_through_label
);
864 /* Given an EQ_EXPR expression EXP for values too wide to be compared
865 with one insn, test the comparison and jump to the appropriate label. */
868 do_jump_by_parts_equality (tree treeop0
, tree treeop1
, rtx if_false_label
,
869 rtx if_true_label
, int prob
)
871 rtx op0
= expand_normal (treeop0
);
872 rtx op1
= expand_normal (treeop1
);
873 machine_mode mode
= TYPE_MODE (TREE_TYPE (treeop0
));
874 do_jump_by_parts_equality_rtx (mode
, op0
, op1
, if_false_label
,
875 if_true_label
, prob
);
878 /* Split a comparison into two others, the second of which has the other
879 "orderedness". The first is always ORDERED or UNORDERED if MODE
880 does not honor NaNs (which means that it can be skipped in that case;
881 see do_compare_rtx_and_jump).
883 The two conditions are written in *CODE1 and *CODE2. Return true if
884 the conditions must be ANDed, false if they must be ORed. */
887 split_comparison (enum rtx_code code
, machine_mode mode
,
888 enum rtx_code
*code1
, enum rtx_code
*code2
)
937 /* Do not turn a trapping comparison into a non-trapping one. */
938 if (HONOR_SNANS (mode
))
956 /* Like do_compare_and_jump but expects the values to compare as two rtx's.
957 The decision as to signed or unsigned comparison must be made by the caller.
959 If MODE is BLKmode, SIZE is an RTX giving the size of the objects being
963 do_compare_rtx_and_jump (rtx op0
, rtx op1
, enum rtx_code code
, int unsignedp
,
964 machine_mode mode
, rtx size
, rtx if_false_label
,
965 rtx if_true_label
, int prob
)
968 rtx dummy_label
= NULL
;
970 /* Reverse the comparison if that is safe and we want to jump if it is
971 false. Also convert to the reverse comparison if the target can
974 || ! can_compare_p (code
, mode
, ccp_jump
))
975 && (! FLOAT_MODE_P (mode
)
976 || code
== ORDERED
|| code
== UNORDERED
977 || (! HONOR_NANS (mode
) && (code
== LTGT
|| code
== UNEQ
))
978 || (! HONOR_SNANS (mode
) && (code
== EQ
|| code
== NE
))))
981 if (FLOAT_MODE_P (mode
))
982 rcode
= reverse_condition_maybe_unordered (code
);
984 rcode
= reverse_condition (code
);
986 /* Canonicalize to UNORDERED for the libcall. */
987 if (can_compare_p (rcode
, mode
, ccp_jump
)
988 || (code
== ORDERED
&& ! can_compare_p (ORDERED
, mode
, ccp_jump
)))
990 std::swap (if_true_label
, if_false_label
);
996 /* If one operand is constant, make it the second one. Only do this
997 if the other operand is not constant as well. */
999 if (swap_commutative_operands_p (op0
, op1
))
1001 std::swap (op0
, op1
);
1002 code
= swap_condition (code
);
1005 do_pending_stack_adjust ();
1007 code
= unsignedp
? unsigned_condition (code
) : code
;
1008 if (0 != (tem
= simplify_relational_operation (code
, mode
, VOIDmode
,
1011 if (CONSTANT_P (tem
))
1013 rtx label
= (tem
== const0_rtx
|| tem
== CONST0_RTX (mode
))
1014 ? if_false_label
: if_true_label
;
1020 code
= GET_CODE (tem
);
1021 mode
= GET_MODE (tem
);
1022 op0
= XEXP (tem
, 0);
1023 op1
= XEXP (tem
, 1);
1024 unsignedp
= (code
== GTU
|| code
== LTU
|| code
== GEU
|| code
== LEU
);
1027 if (! if_true_label
)
1028 dummy_label
= if_true_label
= gen_label_rtx ();
1030 if (GET_MODE_CLASS (mode
) == MODE_INT
1031 && ! can_compare_p (code
, mode
, ccp_jump
))
1036 do_jump_by_parts_greater_rtx (mode
, 1, op1
, op0
,
1037 if_false_label
, if_true_label
, prob
);
1041 do_jump_by_parts_greater_rtx (mode
, 1, op0
, op1
,
1042 if_true_label
, if_false_label
,
1047 do_jump_by_parts_greater_rtx (mode
, 1, op0
, op1
,
1048 if_false_label
, if_true_label
, prob
);
1052 do_jump_by_parts_greater_rtx (mode
, 1, op1
, op0
,
1053 if_true_label
, if_false_label
,
1058 do_jump_by_parts_greater_rtx (mode
, 0, op1
, op0
,
1059 if_false_label
, if_true_label
, prob
);
1063 do_jump_by_parts_greater_rtx (mode
, 0, op0
, op1
,
1064 if_true_label
, if_false_label
,
1069 do_jump_by_parts_greater_rtx (mode
, 0, op0
, op1
,
1070 if_false_label
, if_true_label
, prob
);
1074 do_jump_by_parts_greater_rtx (mode
, 0, op1
, op0
,
1075 if_true_label
, if_false_label
,
1080 do_jump_by_parts_equality_rtx (mode
, op0
, op1
, if_false_label
,
1081 if_true_label
, prob
);
1085 do_jump_by_parts_equality_rtx (mode
, op0
, op1
, if_true_label
,
1086 if_false_label
, inv (prob
));
1095 if (SCALAR_FLOAT_MODE_P (mode
)
1096 && ! can_compare_p (code
, mode
, ccp_jump
)
1097 && can_compare_p (swap_condition (code
), mode
, ccp_jump
))
1100 code
= swap_condition (code
);
1105 else if (SCALAR_FLOAT_MODE_P (mode
)
1106 && ! can_compare_p (code
, mode
, ccp_jump
)
1107 /* Never split ORDERED and UNORDERED.
1108 These must be implemented. */
1109 && (code
!= ORDERED
&& code
!= UNORDERED
)
1110 /* Split a floating-point comparison if
1111 we can jump on other conditions... */
1112 && (have_insn_for (COMPARE
, mode
)
1113 /* ... or if there is no libcall for it. */
1114 || code_to_optab (code
) == unknown_optab
))
1116 enum rtx_code first_code
;
1117 bool and_them
= split_comparison (code
, mode
, &first_code
, &code
);
1119 /* If there are no NaNs, the first comparison should always fall
1121 if (!HONOR_NANS (mode
))
1122 gcc_assert (first_code
== (and_them
? ORDERED
: UNORDERED
));
1126 int first_prob
= prob
;
1127 if (first_code
== UNORDERED
)
1128 first_prob
= REG_BR_PROB_BASE
/ 100;
1129 else if (first_code
== ORDERED
)
1130 first_prob
= REG_BR_PROB_BASE
- REG_BR_PROB_BASE
/ 100;
1134 /* If we only jump if true, just bypass the second jump. */
1135 if (! if_false_label
)
1138 dummy_label
= gen_label_rtx ();
1139 dest_label
= dummy_label
;
1142 dest_label
= if_false_label
;
1143 do_compare_rtx_and_jump (op0
, op1
, first_code
, unsignedp
, mode
,
1144 size
, dest_label
, NULL_RTX
,
1148 do_compare_rtx_and_jump (op0
, op1
, first_code
, unsignedp
, mode
,
1149 size
, NULL_RTX
, if_true_label
,
1154 emit_cmp_and_jump_insns (op0
, op1
, code
, size
, mode
, unsignedp
,
1155 if_true_label
, prob
);
1159 emit_jump (if_false_label
);
1161 emit_label (dummy_label
);
1164 /* Generate code for a comparison expression EXP (including code to compute
1165 the values to be compared) and a conditional jump to IF_FALSE_LABEL and/or
1166 IF_TRUE_LABEL. One of the labels can be NULL_RTX, in which case the
1167 generated code will drop through.
1168 SIGNED_CODE should be the rtx operation for this comparison for
1169 signed data; UNSIGNED_CODE, likewise for use if data is unsigned.
1171 We force a stack adjustment unless there are currently
1172 things pushed on the stack that aren't yet used. */
1175 do_compare_and_jump (tree treeop0
, tree treeop1
, enum rtx_code signed_code
,
1176 enum rtx_code unsigned_code
, rtx if_false_label
,
1177 rtx if_true_label
, int prob
)
1185 /* Don't crash if the comparison was erroneous. */
1186 op0
= expand_normal (treeop0
);
1187 if (TREE_CODE (treeop0
) == ERROR_MARK
)
1190 op1
= expand_normal (treeop1
);
1191 if (TREE_CODE (treeop1
) == ERROR_MARK
)
1194 type
= TREE_TYPE (treeop0
);
1195 mode
= TYPE_MODE (type
);
1196 if (TREE_CODE (treeop0
) == INTEGER_CST
1197 && (TREE_CODE (treeop1
) != INTEGER_CST
1198 || (GET_MODE_BITSIZE (mode
)
1199 > GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (treeop1
))))))
1201 /* op0 might have been replaced by promoted constant, in which
1202 case the type of second argument should be used. */
1203 type
= TREE_TYPE (treeop1
);
1204 mode
= TYPE_MODE (type
);
1206 unsignedp
= TYPE_UNSIGNED (type
);
1207 code
= unsignedp
? unsigned_code
: signed_code
;
1209 #ifdef HAVE_canonicalize_funcptr_for_compare
1210 /* If function pointers need to be "canonicalized" before they can
1211 be reliably compared, then canonicalize them.
1212 Only do this if *both* sides of the comparison are function pointers.
1213 If one side isn't, we want a noncanonicalized comparison. See PR
1214 middle-end/17564. */
1215 if (HAVE_canonicalize_funcptr_for_compare
1216 && TREE_CODE (TREE_TYPE (treeop0
)) == POINTER_TYPE
1217 && TREE_CODE (TREE_TYPE (TREE_TYPE (treeop0
)))
1219 && TREE_CODE (TREE_TYPE (treeop1
)) == POINTER_TYPE
1220 && TREE_CODE (TREE_TYPE (TREE_TYPE (treeop1
)))
1223 rtx new_op0
= gen_reg_rtx (mode
);
1224 rtx new_op1
= gen_reg_rtx (mode
);
1226 emit_insn (gen_canonicalize_funcptr_for_compare (new_op0
, op0
));
1229 emit_insn (gen_canonicalize_funcptr_for_compare (new_op1
, op1
));
1234 do_compare_rtx_and_jump (op0
, op1
, code
, unsignedp
, mode
,
1236 ? expr_size (treeop0
) : NULL_RTX
),
1237 if_false_label
, if_true_label
, prob
);
1240 #include "gt-dojump.h"