new tests
[official-gcc.git] / gcc / dojump.c
blob6437a1f2295028badb2cd87b95d31db83e3e1efb
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 "output.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 if (and_test == 0)
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),
153 const1_rtx);
155 else
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. */
165 XEXP (and_test, 1)
166 = immed_double_int_const (double_int_setbit (double_int_zero, bitnum),
167 mode);
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. */
178 void
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;
185 switch (code)
187 case EQ_EXPR:
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,
201 prob);
202 else
203 do_compare_and_jump (op0, op1, EQ, EQ, if_false_label, if_true_label,
204 prob);
205 break;
208 case NE_EXPR:
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,
222 inv (prob));
223 else
224 do_compare_and_jump (op0, op1, NE, NE, if_false_label, if_true_label,
225 prob);
226 break;
229 case LT_EXPR:
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,
234 prob);
235 else
236 do_compare_and_jump (op0, op1, LT, LTU, if_false_label, if_true_label,
237 prob);
238 break;
240 case LE_EXPR:
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,
245 inv (prob));
246 else
247 do_compare_and_jump (op0, op1, LE, LEU, if_false_label, if_true_label,
248 prob);
249 break;
251 case GT_EXPR:
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,
256 prob);
257 else
258 do_compare_and_jump (op0, op1, GT, GTU, if_false_label, if_true_label,
259 prob);
260 break;
262 case GE_EXPR:
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,
267 inv (prob));
268 else
269 do_compare_and_jump (op0, op1, GE, GEU, if_false_label, if_true_label,
270 prob);
271 break;
273 case ORDERED_EXPR:
274 do_compare_and_jump (op0, op1, ORDERED, ORDERED,
275 if_false_label, if_true_label, prob);
276 break;
278 case UNORDERED_EXPR:
279 do_compare_and_jump (op0, op1, UNORDERED, UNORDERED,
280 if_false_label, if_true_label, prob);
281 break;
283 case UNLT_EXPR:
284 do_compare_and_jump (op0, op1, UNLT, UNLT, if_false_label, if_true_label,
285 prob);
286 break;
288 case UNLE_EXPR:
289 do_compare_and_jump (op0, op1, UNLE, UNLE, if_false_label, if_true_label,
290 prob);
291 break;
293 case UNGT_EXPR:
294 do_compare_and_jump (op0, op1, UNGT, UNGT, if_false_label, if_true_label,
295 prob);
296 break;
298 case UNGE_EXPR:
299 do_compare_and_jump (op0, op1, UNGE, UNGE, if_false_label, if_true_label,
300 prob);
301 break;
303 case UNEQ_EXPR:
304 do_compare_and_jump (op0, op1, UNEQ, UNEQ, if_false_label, if_true_label,
305 prob);
306 break;
308 case LTGT_EXPR:
309 do_compare_and_jump (op0, op1, LTGT, LTGT, if_false_label, if_true_label,
310 prob);
311 break;
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);
320 else
322 do_jump (op0, if_false_label, NULL_RTX, prob);
323 do_jump (op1, if_false_label, if_true_label, prob);
325 break;
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);
334 else
336 do_jump (op0, NULL_RTX, if_true_label, prob);
337 do_jump (op1, if_false_label, if_true_label, prob);
339 break;
341 default:
342 gcc_unreachable ();
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. */
363 void
364 do_jump (tree exp, rtx if_false_label, rtx if_true_label, int prob)
366 enum tree_code code = TREE_CODE (exp);
367 rtx temp;
368 int i;
369 tree type;
370 enum machine_mode mode;
371 rtx drop_through_label = 0;
373 switch (code)
375 case ERROR_MARK:
376 break;
378 case INTEGER_CST:
379 temp = integer_zerop (exp) ? if_false_label : if_true_label;
380 if (temp)
381 emit_jump (temp);
382 break;
384 #if 0
385 /* This is not true with #pragma weak */
386 case ADDR_EXPR:
387 /* The address of something can never be zero. */
388 if (if_true_label)
389 emit_jump (if_true_label);
390 break;
391 #endif
393 case NOP_EXPR:
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)
398 goto normal;
399 case CONVERT_EXPR:
400 /* If we are narrowing the operand, we have to do the compare in the
401 narrower mode. */
402 if ((TYPE_PRECISION (TREE_TYPE (exp))
403 < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0)))))
404 goto normal;
405 case NON_LVALUE_EXPR:
406 case ABS_EXPR:
407 case NEGATE_EXPR:
408 case LROTATE_EXPR:
409 case RROTATE_EXPR:
410 /* These cannot change zero->nonzero or vice versa. */
411 do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label, prob);
412 break;
414 case TRUTH_NOT_EXPR:
415 do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label,
416 inv (prob));
417 break;
419 case COND_EXPR:
421 rtx label1 = gen_label_rtx ();
422 if (!if_true_label || !if_false_label)
424 drop_through_label = gen_label_rtx ();
425 if (!if_true_label)
426 if_true_label = drop_through_label;
427 if (!if_false_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);
434 emit_label (label1);
435 do_jump (TREE_OPERAND (exp, 2), if_false_label, if_true_label, prob);
436 break;
439 case COMPOUND_EXPR:
440 /* Lowered by gimplify.c. */
441 gcc_unreachable ();
443 case COMPONENT_REF:
444 case BIT_FIELD_REF:
445 case ARRAY_REF:
446 case ARRAY_RANGE_REF:
448 HOST_WIDE_INT bitsize, bitpos;
449 int unsignedp;
450 enum machine_mode mode;
451 tree type;
452 tree offset;
453 int volatilep = 0;
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,
467 prob);
468 break;
470 goto normal;
473 case MINUS_EXPR:
474 /* Nonzero iff operands of minus differ. */
475 code = NE_EXPR;
477 /* FALLTHRU */
478 case EQ_EXPR:
479 case NE_EXPR:
480 case LT_EXPR:
481 case LE_EXPR:
482 case GT_EXPR:
483 case GE_EXPR:
484 case ORDERED_EXPR:
485 case UNORDERED_EXPR:
486 case UNLT_EXPR:
487 case UNLE_EXPR:
488 case UNGT_EXPR:
489 case UNGE_EXPR:
490 case UNEQ_EXPR:
491 case LTGT_EXPR:
492 case TRUTH_ANDIF_EXPR:
493 case TRUTH_ORIF_EXPR:
494 other_code:
495 do_jump_1 (code, TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
496 if_false_label, if_true_label, prob);
497 break;
499 case BIT_AND_EXPR:
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
502 if so. */
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);
525 else
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);
547 break;
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,
569 prob);
570 break;
573 if (TYPE_PRECISION (TREE_TYPE (exp)) > 1
574 || TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST)
575 goto normal;
577 /* Boolean comparisons can be compiled as TRUTH_AND_EXPR. */
579 case 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 (),
584 false) >= 4
585 || TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 1)))
586 goto normal;
587 code = TRUTH_ANDIF_EXPR;
588 goto other_code;
590 case BIT_IOR_EXPR:
591 case TRUTH_OR_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)))
597 goto normal;
598 code = TRUTH_ORIF_EXPR;
599 goto other_code;
601 /* Fall through and generate the normal code. */
602 default:
603 normal:
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);
613 else
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. */
633 static void
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,
636 int prob)
638 int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
639 rtx drop_through_label = 0;
640 bool drop_through_if_true = false, drop_through_if_false = false;
641 enum rtx_code code = GT;
642 int i;
644 if (! if_true_label || ! if_false_label)
645 drop_through_label = gen_label_rtx ();
646 if (! if_true_label)
648 if_true_label = drop_through_label;
649 drop_through_if_true = true;
651 if (! if_false_label)
653 if_false_label = drop_through_label;
654 drop_through_if_false = true;
657 /* Deal with the special case 0 > x: only one comparison is necessary and
658 we reverse it to avoid jumping to the drop-through label. */
659 if (op0 == const0_rtx && drop_through_if_true && !drop_through_if_false)
661 code = LE;
662 if_true_label = if_false_label;
663 if_false_label = drop_through_label;
664 drop_through_if_true = false;
665 drop_through_if_false = true;
668 /* Compare a word at a time, high order first. */
669 for (i = 0; i < nwords; i++)
671 rtx op0_word, op1_word;
673 if (WORDS_BIG_ENDIAN)
675 op0_word = operand_subword_force (op0, i, mode);
676 op1_word = operand_subword_force (op1, i, mode);
678 else
680 op0_word = operand_subword_force (op0, nwords - 1 - i, mode);
681 op1_word = operand_subword_force (op1, nwords - 1 - i, mode);
684 /* All but high-order word must be compared as unsigned. */
685 do_compare_rtx_and_jump (op0_word, op1_word, code, (unsignedp || i > 0),
686 word_mode, NULL_RTX, NULL_RTX, if_true_label,
687 prob);
689 /* Emit only one comparison for 0. Do not emit the last cond jump. */
690 if (op0 == const0_rtx || i == nwords - 1)
691 break;
693 /* Consider lower words only if these are equal. */
694 do_compare_rtx_and_jump (op0_word, op1_word, NE, unsignedp, word_mode,
695 NULL_RTX, NULL_RTX, if_false_label, inv (prob));
698 if (!drop_through_if_false)
699 emit_jump (if_false_label);
700 if (drop_through_label)
701 emit_label (drop_through_label);
704 /* Given a comparison expression EXP for values too wide to be compared
705 with one insn, test the comparison and jump to the appropriate label.
706 The code of EXP is ignored; we always test GT if SWAP is 0,
707 and LT if SWAP is 1. */
709 static void
710 do_jump_by_parts_greater (tree treeop0, tree treeop1, int swap,
711 rtx if_false_label, rtx if_true_label, int prob)
713 rtx op0 = expand_normal (swap ? treeop1 : treeop0);
714 rtx op1 = expand_normal (swap ? treeop0 : treeop1);
715 enum machine_mode mode = TYPE_MODE (TREE_TYPE (treeop0));
716 int unsignedp = TYPE_UNSIGNED (TREE_TYPE (treeop0));
718 do_jump_by_parts_greater_rtx (mode, unsignedp, op0, op1, if_false_label,
719 if_true_label, prob);
722 /* Jump according to whether OP0 is 0. We assume that OP0 has an integer
723 mode, MODE, that is too wide for the available compare insns. Either
724 Either (but not both) of IF_TRUE_LABEL and IF_FALSE_LABEL may be NULL_RTX
725 to indicate drop through. */
727 static void
728 do_jump_by_parts_zero_rtx (enum machine_mode mode, rtx op0,
729 rtx if_false_label, rtx if_true_label, int prob)
731 int nwords = GET_MODE_SIZE (mode) / UNITS_PER_WORD;
732 rtx part;
733 int i;
734 rtx drop_through_label = 0;
736 /* The fastest way of doing this comparison on almost any machine is to
737 "or" all the words and compare the result. If all have to be loaded
738 from memory and this is a very wide item, it's possible this may
739 be slower, but that's highly unlikely. */
741 part = gen_reg_rtx (word_mode);
742 emit_move_insn (part, operand_subword_force (op0, 0, mode));
743 for (i = 1; i < nwords && part != 0; i++)
744 part = expand_binop (word_mode, ior_optab, part,
745 operand_subword_force (op0, i, mode),
746 part, 1, OPTAB_WIDEN);
748 if (part != 0)
750 do_compare_rtx_and_jump (part, const0_rtx, EQ, 1, word_mode,
751 NULL_RTX, if_false_label, if_true_label, prob);
752 return;
755 /* If we couldn't do the "or" simply, do this with a series of compares. */
756 if (! if_false_label)
757 drop_through_label = if_false_label = gen_label_rtx ();
759 for (i = 0; i < nwords; i++)
760 do_compare_rtx_and_jump (operand_subword_force (op0, i, mode),
761 const0_rtx, EQ, 1, word_mode, NULL_RTX,
762 if_false_label, NULL_RTX, prob);
764 if (if_true_label)
765 emit_jump (if_true_label);
767 if (drop_through_label)
768 emit_label (drop_through_label);
771 /* Test for the equality of two RTX expressions OP0 and OP1 in mode MODE,
772 where MODE is an integer mode too wide to be compared with one insn.
773 Either (but not both) of IF_TRUE_LABEL and IF_FALSE_LABEL may be NULL_RTX
774 to indicate drop through. */
776 static void
777 do_jump_by_parts_equality_rtx (enum machine_mode mode, rtx op0, rtx op1,
778 rtx if_false_label, rtx if_true_label, int prob)
780 int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
781 rtx drop_through_label = 0;
782 int i;
784 if (op1 == const0_rtx)
786 do_jump_by_parts_zero_rtx (mode, op0, if_false_label, if_true_label,
787 prob);
788 return;
790 else if (op0 == const0_rtx)
792 do_jump_by_parts_zero_rtx (mode, op1, if_false_label, if_true_label,
793 prob);
794 return;
797 if (! if_false_label)
798 drop_through_label = if_false_label = gen_label_rtx ();
800 for (i = 0; i < nwords; i++)
801 do_compare_rtx_and_jump (operand_subword_force (op0, i, mode),
802 operand_subword_force (op1, i, mode),
803 EQ, 0, word_mode, NULL_RTX,
804 if_false_label, NULL_RTX, prob);
806 if (if_true_label)
807 emit_jump (if_true_label);
808 if (drop_through_label)
809 emit_label (drop_through_label);
812 /* Given an EQ_EXPR expression EXP for values too wide to be compared
813 with one insn, test the comparison and jump to the appropriate label. */
815 static void
816 do_jump_by_parts_equality (tree treeop0, tree treeop1, rtx if_false_label,
817 rtx if_true_label, int prob)
819 rtx op0 = expand_normal (treeop0);
820 rtx op1 = expand_normal (treeop1);
821 enum machine_mode mode = TYPE_MODE (TREE_TYPE (treeop0));
822 do_jump_by_parts_equality_rtx (mode, op0, op1, if_false_label,
823 if_true_label, prob);
826 /* Split a comparison into two others, the second of which has the other
827 "orderedness". The first is always ORDERED or UNORDERED if MODE
828 does not honor NaNs (which means that it can be skipped in that case;
829 see do_compare_rtx_and_jump).
831 The two conditions are written in *CODE1 and *CODE2. Return true if
832 the conditions must be ANDed, false if they must be ORed. */
834 bool
835 split_comparison (enum rtx_code code, enum machine_mode mode,
836 enum rtx_code *code1, enum rtx_code *code2)
838 switch (code)
840 case LT:
841 *code1 = ORDERED;
842 *code2 = UNLT;
843 return true;
844 case LE:
845 *code1 = ORDERED;
846 *code2 = UNLE;
847 return true;
848 case GT:
849 *code1 = ORDERED;
850 *code2 = UNGT;
851 return true;
852 case GE:
853 *code1 = ORDERED;
854 *code2 = UNGE;
855 return true;
856 case EQ:
857 *code1 = ORDERED;
858 *code2 = UNEQ;
859 return true;
860 case NE:
861 *code1 = UNORDERED;
862 *code2 = LTGT;
863 return false;
864 case UNLT:
865 *code1 = UNORDERED;
866 *code2 = LT;
867 return false;
868 case UNLE:
869 *code1 = UNORDERED;
870 *code2 = LE;
871 return false;
872 case UNGT:
873 *code1 = UNORDERED;
874 *code2 = GT;
875 return false;
876 case UNGE:
877 *code1 = UNORDERED;
878 *code2 = GE;
879 return false;
880 case UNEQ:
881 *code1 = UNORDERED;
882 *code2 = EQ;
883 return false;
884 case LTGT:
885 /* Do not turn a trapping comparison into a non-trapping one. */
886 if (HONOR_SNANS (mode))
888 *code1 = LT;
889 *code2 = GT;
890 return false;
892 else
894 *code1 = ORDERED;
895 *code2 = NE;
896 return true;
898 default:
899 gcc_unreachable ();
904 /* Like do_compare_and_jump but expects the values to compare as two rtx's.
905 The decision as to signed or unsigned comparison must be made by the caller.
907 If MODE is BLKmode, SIZE is an RTX giving the size of the objects being
908 compared. */
910 void
911 do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
912 enum machine_mode mode, rtx size, rtx if_false_label,
913 rtx if_true_label, int prob)
915 rtx tem;
916 rtx dummy_label = NULL_RTX;
917 rtx last;
919 /* Reverse the comparison if that is safe and we want to jump if it is
920 false. Also convert to the reverse comparison if the target can
921 implement it. */
922 if ((! if_true_label
923 || ! can_compare_p (code, mode, ccp_jump))
924 && (! FLOAT_MODE_P (mode)
925 || code == ORDERED || code == UNORDERED
926 || (! HONOR_NANS (mode) && (code == LTGT || code == UNEQ))
927 || (! HONOR_SNANS (mode) && (code == EQ || code == NE))))
929 enum rtx_code rcode;
930 if (FLOAT_MODE_P (mode))
931 rcode = reverse_condition_maybe_unordered (code);
932 else
933 rcode = reverse_condition (code);
935 /* Canonicalize to UNORDERED for the libcall. */
936 if (can_compare_p (rcode, mode, ccp_jump)
937 || (code == ORDERED && ! can_compare_p (ORDERED, mode, ccp_jump)))
939 tem = if_true_label;
940 if_true_label = if_false_label;
941 if_false_label = tem;
942 code = rcode;
943 prob = inv (prob);
947 /* If one operand is constant, make it the second one. Only do this
948 if the other operand is not constant as well. */
950 if (swap_commutative_operands_p (op0, op1))
952 tem = op0;
953 op0 = op1;
954 op1 = tem;
955 code = swap_condition (code);
958 do_pending_stack_adjust ();
960 code = unsignedp ? unsigned_condition (code) : code;
961 if (0 != (tem = simplify_relational_operation (code, mode, VOIDmode,
962 op0, op1)))
964 if (CONSTANT_P (tem))
966 rtx label = (tem == const0_rtx || tem == CONST0_RTX (mode))
967 ? if_false_label : if_true_label;
968 if (label)
969 emit_jump (label);
970 return;
973 code = GET_CODE (tem);
974 mode = GET_MODE (tem);
975 op0 = XEXP (tem, 0);
976 op1 = XEXP (tem, 1);
977 unsignedp = (code == GTU || code == LTU || code == GEU || code == LEU);
980 if (! if_true_label)
981 dummy_label = if_true_label = gen_label_rtx ();
983 if (GET_MODE_CLASS (mode) == MODE_INT
984 && ! can_compare_p (code, mode, ccp_jump))
986 switch (code)
988 case LTU:
989 do_jump_by_parts_greater_rtx (mode, 1, op1, op0,
990 if_false_label, if_true_label, prob);
991 break;
993 case LEU:
994 do_jump_by_parts_greater_rtx (mode, 1, op0, op1,
995 if_true_label, if_false_label,
996 inv (prob));
997 break;
999 case GTU:
1000 do_jump_by_parts_greater_rtx (mode, 1, op0, op1,
1001 if_false_label, if_true_label, prob);
1002 break;
1004 case GEU:
1005 do_jump_by_parts_greater_rtx (mode, 1, op1, op0,
1006 if_true_label, if_false_label,
1007 inv (prob));
1008 break;
1010 case LT:
1011 do_jump_by_parts_greater_rtx (mode, 0, op1, op0,
1012 if_false_label, if_true_label, prob);
1013 break;
1015 case LE:
1016 do_jump_by_parts_greater_rtx (mode, 0, op0, op1,
1017 if_true_label, if_false_label,
1018 inv (prob));
1019 break;
1021 case GT:
1022 do_jump_by_parts_greater_rtx (mode, 0, op0, op1,
1023 if_false_label, if_true_label, prob);
1024 break;
1026 case GE:
1027 do_jump_by_parts_greater_rtx (mode, 0, op1, op0,
1028 if_true_label, if_false_label,
1029 inv (prob));
1030 break;
1032 case EQ:
1033 do_jump_by_parts_equality_rtx (mode, op0, op1, if_false_label,
1034 if_true_label, prob);
1035 break;
1037 case NE:
1038 do_jump_by_parts_equality_rtx (mode, op0, op1, if_true_label,
1039 if_false_label, inv (prob));
1040 break;
1042 default:
1043 gcc_unreachable ();
1046 else
1048 if (GET_MODE_CLASS (mode) == MODE_FLOAT
1049 && ! can_compare_p (code, mode, ccp_jump)
1050 && can_compare_p (swap_condition (code), mode, ccp_jump))
1052 rtx tmp;
1053 code = swap_condition (code);
1054 tmp = op0;
1055 op0 = op1;
1056 op1 = tmp;
1059 else if (GET_MODE_CLASS (mode) == MODE_FLOAT
1060 && ! can_compare_p (code, mode, ccp_jump)
1062 /* Never split ORDERED and UNORDERED. These must be implemented. */
1063 && (code != ORDERED && code != UNORDERED)
1065 /* Split a floating-point comparison if we can jump on other
1066 conditions... */
1067 && (have_insn_for (COMPARE, mode)
1069 /* ... or if there is no libcall for it. */
1070 || code_to_optab[code] == NULL))
1072 enum rtx_code first_code;
1073 bool and_them = split_comparison (code, mode, &first_code, &code);
1075 /* If there are no NaNs, the first comparison should always fall
1076 through. */
1077 if (!HONOR_NANS (mode))
1078 gcc_assert (first_code == (and_them ? ORDERED : UNORDERED));
1080 else
1082 if (and_them)
1084 rtx dest_label;
1085 /* If we only jump if true, just bypass the second jump. */
1086 if (! if_false_label)
1088 if (! dummy_label)
1089 dummy_label = gen_label_rtx ();
1090 dest_label = dummy_label;
1092 else
1093 dest_label = if_false_label;
1094 do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode,
1095 size, dest_label, NULL_RTX, prob);
1097 else
1098 do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode,
1099 size, NULL_RTX, if_true_label, prob);
1103 last = get_last_insn ();
1104 emit_cmp_and_jump_insns (op0, op1, code, size, mode, unsignedp,
1105 if_true_label);
1106 if (prob != -1 && profile_status != PROFILE_ABSENT)
1108 for (last = NEXT_INSN (last);
1109 last && NEXT_INSN (last);
1110 last = NEXT_INSN (last))
1111 if (JUMP_P (last))
1112 break;
1113 if (!last
1114 || !JUMP_P (last)
1115 || NEXT_INSN (last)
1116 || !any_condjump_p (last))
1118 if (dump_file)
1119 fprintf (dump_file, "Failed to add probability note\n");
1121 else
1123 gcc_assert (!find_reg_note (last, REG_BR_PROB, 0));
1124 add_reg_note (last, REG_BR_PROB, GEN_INT (prob));
1129 if (if_false_label)
1130 emit_jump (if_false_label);
1131 if (dummy_label)
1132 emit_label (dummy_label);
1135 /* Generate code for a comparison expression EXP (including code to compute
1136 the values to be compared) and a conditional jump to IF_FALSE_LABEL and/or
1137 IF_TRUE_LABEL. One of the labels can be NULL_RTX, in which case the
1138 generated code will drop through.
1139 SIGNED_CODE should be the rtx operation for this comparison for
1140 signed data; UNSIGNED_CODE, likewise for use if data is unsigned.
1142 We force a stack adjustment unless there are currently
1143 things pushed on the stack that aren't yet used. */
1145 static void
1146 do_compare_and_jump (tree treeop0, tree treeop1, enum rtx_code signed_code,
1147 enum rtx_code unsigned_code, rtx if_false_label,
1148 rtx if_true_label, int prob)
1150 rtx op0, op1;
1151 tree type;
1152 enum machine_mode mode;
1153 int unsignedp;
1154 enum rtx_code code;
1156 /* Don't crash if the comparison was erroneous. */
1157 op0 = expand_normal (treeop0);
1158 if (TREE_CODE (treeop0) == ERROR_MARK)
1159 return;
1161 op1 = expand_normal (treeop1);
1162 if (TREE_CODE (treeop1) == ERROR_MARK)
1163 return;
1165 type = TREE_TYPE (treeop0);
1166 mode = TYPE_MODE (type);
1167 if (TREE_CODE (treeop0) == INTEGER_CST
1168 && (TREE_CODE (treeop1) != INTEGER_CST
1169 || (GET_MODE_BITSIZE (mode)
1170 > GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (treeop1))))))
1172 /* op0 might have been replaced by promoted constant, in which
1173 case the type of second argument should be used. */
1174 type = TREE_TYPE (treeop1);
1175 mode = TYPE_MODE (type);
1177 unsignedp = TYPE_UNSIGNED (type);
1178 code = unsignedp ? unsigned_code : signed_code;
1180 #ifdef HAVE_canonicalize_funcptr_for_compare
1181 /* If function pointers need to be "canonicalized" before they can
1182 be reliably compared, then canonicalize them.
1183 Only do this if *both* sides of the comparison are function pointers.
1184 If one side isn't, we want a noncanonicalized comparison. See PR
1185 middle-end/17564. */
1186 if (HAVE_canonicalize_funcptr_for_compare
1187 && TREE_CODE (TREE_TYPE (treeop0)) == POINTER_TYPE
1188 && TREE_CODE (TREE_TYPE (TREE_TYPE (treeop0)))
1189 == FUNCTION_TYPE
1190 && TREE_CODE (TREE_TYPE (treeop1)) == POINTER_TYPE
1191 && TREE_CODE (TREE_TYPE (TREE_TYPE (treeop1)))
1192 == FUNCTION_TYPE)
1194 rtx new_op0 = gen_reg_rtx (mode);
1195 rtx new_op1 = gen_reg_rtx (mode);
1197 emit_insn (gen_canonicalize_funcptr_for_compare (new_op0, op0));
1198 op0 = new_op0;
1200 emit_insn (gen_canonicalize_funcptr_for_compare (new_op1, op1));
1201 op1 = new_op1;
1203 #endif
1205 do_compare_rtx_and_jump (op0, op1, code, unsignedp, mode,
1206 ((mode == BLKmode)
1207 ? expr_size (treeop0) : NULL_RTX),
1208 if_false_label, if_true_label, prob);
1211 #include "gt-dojump.h"