dojump.c (do_compare_rtx_and_jump): Try swapping the condition for floating point...
[official-gcc.git] / gcc / dojump.c
blob3685ff513d00880d220e31732830e5e87a479708
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
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"
39 static bool prefer_and_bit_test (enum machine_mode, int);
40 static void do_jump_by_parts_greater (tree, int, rtx, rtx);
41 static void do_jump_by_parts_equality (tree, rtx, rtx);
42 static void do_compare_and_jump (tree, enum rtx_code, enum rtx_code, rtx,
43 rtx);
45 /* At the start of a function, record that we have no previously-pushed
46 arguments waiting to be popped. */
48 void
49 init_pending_stack_adjust (void)
51 pending_stack_adjust = 0;
54 /* Discard any pending stack adjustment. This avoid relying on the
55 RTL optimizers to remove useless adjustments when we know the
56 stack pointer value is dead. */
57 void
58 discard_pending_stack_adjust (void)
60 stack_pointer_delta -= pending_stack_adjust;
61 pending_stack_adjust = 0;
64 /* When exiting from function, if safe, clear out any pending stack adjust
65 so the adjustment won't get done.
67 Note, if the current function calls alloca, then it must have a
68 frame pointer regardless of the value of flag_omit_frame_pointer. */
70 void
71 clear_pending_stack_adjust (void)
73 if (optimize > 0
74 && (! flag_omit_frame_pointer || cfun->calls_alloca)
75 && EXIT_IGNORE_STACK)
76 discard_pending_stack_adjust ();
79 /* Pop any previously-pushed arguments that have not been popped yet. */
81 void
82 do_pending_stack_adjust (void)
84 if (inhibit_defer_pop == 0)
86 if (pending_stack_adjust != 0)
87 adjust_stack (GEN_INT (pending_stack_adjust));
88 pending_stack_adjust = 0;
92 /* Expand conditional expressions. */
94 /* Generate code to evaluate EXP and jump to LABEL if the value is zero.
95 LABEL is an rtx of code CODE_LABEL, in this function and all the
96 functions here. */
98 void
99 jumpifnot (tree exp, rtx label)
101 do_jump (exp, label, NULL_RTX);
104 /* Generate code to evaluate EXP and jump to LABEL if the value is nonzero. */
106 void
107 jumpif (tree exp, rtx label)
109 do_jump (exp, NULL_RTX, label);
112 /* Used internally by prefer_and_bit_test. */
114 static GTY(()) rtx and_reg;
115 static GTY(()) rtx and_test;
116 static GTY(()) rtx shift_test;
118 /* Compare the relative costs of "(X & (1 << BITNUM))" and "(X >> BITNUM) & 1",
119 where X is an arbitrary register of mode MODE. Return true if the former
120 is preferred. */
122 static bool
123 prefer_and_bit_test (enum machine_mode mode, int bitnum)
125 if (and_test == 0)
127 /* Set up rtxes for the two variations. Use NULL as a placeholder
128 for the BITNUM-based constants. */
129 and_reg = gen_rtx_REG (mode, FIRST_PSEUDO_REGISTER);
130 and_test = gen_rtx_AND (mode, and_reg, NULL);
131 shift_test = gen_rtx_AND (mode, gen_rtx_ASHIFTRT (mode, and_reg, NULL),
132 const1_rtx);
134 else
136 /* Change the mode of the previously-created rtxes. */
137 PUT_MODE (and_reg, mode);
138 PUT_MODE (and_test, mode);
139 PUT_MODE (shift_test, mode);
140 PUT_MODE (XEXP (shift_test, 0), mode);
143 /* Fill in the integers. */
144 XEXP (and_test, 1)
145 = immed_double_const ((unsigned HOST_WIDE_INT) 1 << bitnum, 0, mode);
146 XEXP (XEXP (shift_test, 0), 1) = GEN_INT (bitnum);
148 return (rtx_cost (and_test, IF_THEN_ELSE, optimize_insn_for_speed_p ())
149 <= rtx_cost (shift_test, IF_THEN_ELSE, optimize_insn_for_speed_p ()));
152 /* Generate code to evaluate EXP and jump to IF_FALSE_LABEL if
153 the result is zero, or IF_TRUE_LABEL if the result is one.
154 Either of IF_FALSE_LABEL and IF_TRUE_LABEL may be zero,
155 meaning fall through in that case.
157 do_jump always does any pending stack adjust except when it does not
158 actually perform a jump. An example where there is no jump
159 is when EXP is `(foo (), 0)' and IF_FALSE_LABEL is null. */
161 void
162 do_jump (tree exp, rtx if_false_label, rtx if_true_label)
164 enum tree_code code = TREE_CODE (exp);
165 rtx temp;
166 int i;
167 tree type;
168 enum machine_mode mode;
169 rtx drop_through_label = 0;
171 switch (code)
173 case ERROR_MARK:
174 break;
176 case INTEGER_CST:
177 temp = integer_zerop (exp) ? if_false_label : if_true_label;
178 if (temp)
179 emit_jump (temp);
180 break;
182 #if 0
183 /* This is not true with #pragma weak */
184 case ADDR_EXPR:
185 /* The address of something can never be zero. */
186 if (if_true_label)
187 emit_jump (if_true_label);
188 break;
189 #endif
191 case NOP_EXPR:
192 if (TREE_CODE (TREE_OPERAND (exp, 0)) == COMPONENT_REF
193 || TREE_CODE (TREE_OPERAND (exp, 0)) == BIT_FIELD_REF
194 || TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_REF
195 || TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_RANGE_REF)
196 goto normal;
197 case CONVERT_EXPR:
198 /* If we are narrowing the operand, we have to do the compare in the
199 narrower mode. */
200 if ((TYPE_PRECISION (TREE_TYPE (exp))
201 < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0)))))
202 goto normal;
203 case NON_LVALUE_EXPR:
204 case ABS_EXPR:
205 case NEGATE_EXPR:
206 case LROTATE_EXPR:
207 case RROTATE_EXPR:
208 /* These cannot change zero->nonzero or vice versa. */
209 do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label);
210 break;
212 case TRUTH_NOT_EXPR:
213 do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label);
214 break;
216 case COND_EXPR:
218 rtx label1 = gen_label_rtx ();
219 if (!if_true_label || !if_false_label)
221 drop_through_label = gen_label_rtx ();
222 if (!if_true_label)
223 if_true_label = drop_through_label;
224 if (!if_false_label)
225 if_false_label = drop_through_label;
228 do_pending_stack_adjust ();
229 do_jump (TREE_OPERAND (exp, 0), label1, NULL_RTX);
230 do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label);
231 emit_label (label1);
232 do_jump (TREE_OPERAND (exp, 2), if_false_label, if_true_label);
233 break;
236 case COMPOUND_EXPR:
237 /* Lowered by gimplify.c. */
238 gcc_unreachable ();
240 case COMPONENT_REF:
241 case BIT_FIELD_REF:
242 case ARRAY_REF:
243 case ARRAY_RANGE_REF:
245 HOST_WIDE_INT bitsize, bitpos;
246 int unsignedp;
247 enum machine_mode mode;
248 tree type;
249 tree offset;
250 int volatilep = 0;
252 /* Get description of this reference. We don't actually care
253 about the underlying object here. */
254 get_inner_reference (exp, &bitsize, &bitpos, &offset, &mode,
255 &unsignedp, &volatilep, false);
257 type = lang_hooks.types.type_for_size (bitsize, unsignedp);
258 if (! SLOW_BYTE_ACCESS
259 && type != 0 && bitsize >= 0
260 && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (exp))
261 && have_insn_for (COMPARE, TYPE_MODE (type)))
263 do_jump (fold_convert (type, exp), if_false_label, if_true_label);
264 break;
266 goto normal;
269 case EQ_EXPR:
271 tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
273 gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
274 != MODE_COMPLEX_FLOAT);
275 gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
276 != MODE_COMPLEX_INT);
278 if (integer_zerop (TREE_OPERAND (exp, 1)))
279 do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label);
280 else if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_INT
281 && !can_compare_p (EQ, TYPE_MODE (inner_type), ccp_jump))
282 do_jump_by_parts_equality (exp, if_false_label, if_true_label);
283 else
284 do_compare_and_jump (exp, EQ, EQ, if_false_label, if_true_label);
285 break;
288 case MINUS_EXPR:
289 /* Nonzero iff operands of minus differ. */
290 exp = build2 (NE_EXPR, TREE_TYPE (exp),
291 TREE_OPERAND (exp, 0),
292 TREE_OPERAND (exp, 1));
293 /* FALLTHRU */
294 case NE_EXPR:
296 tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
298 gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
299 != MODE_COMPLEX_FLOAT);
300 gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
301 != MODE_COMPLEX_INT);
303 if (integer_zerop (TREE_OPERAND (exp, 1)))
304 do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label);
305 else if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_INT
306 && !can_compare_p (NE, TYPE_MODE (inner_type), ccp_jump))
307 do_jump_by_parts_equality (exp, if_true_label, if_false_label);
308 else
309 do_compare_and_jump (exp, NE, NE, if_false_label, if_true_label);
310 break;
313 case LT_EXPR:
314 mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
315 if (GET_MODE_CLASS (mode) == MODE_INT
316 && ! can_compare_p (LT, mode, ccp_jump))
317 do_jump_by_parts_greater (exp, 1, if_false_label, if_true_label);
318 else
319 do_compare_and_jump (exp, LT, LTU, if_false_label, if_true_label);
320 break;
322 case LE_EXPR:
323 mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
324 if (GET_MODE_CLASS (mode) == MODE_INT
325 && ! can_compare_p (LE, mode, ccp_jump))
326 do_jump_by_parts_greater (exp, 0, if_true_label, if_false_label);
327 else
328 do_compare_and_jump (exp, LE, LEU, if_false_label, if_true_label);
329 break;
331 case GT_EXPR:
332 mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
333 if (GET_MODE_CLASS (mode) == MODE_INT
334 && ! can_compare_p (GT, mode, ccp_jump))
335 do_jump_by_parts_greater (exp, 0, if_false_label, if_true_label);
336 else
337 do_compare_and_jump (exp, GT, GTU, if_false_label, if_true_label);
338 break;
340 case GE_EXPR:
341 mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
342 if (GET_MODE_CLASS (mode) == MODE_INT
343 && ! can_compare_p (GE, mode, ccp_jump))
344 do_jump_by_parts_greater (exp, 1, if_true_label, if_false_label);
345 else
346 do_compare_and_jump (exp, GE, GEU, if_false_label, if_true_label);
347 break;
349 case ORDERED_EXPR:
350 do_compare_and_jump (exp, ORDERED, ORDERED,
351 if_false_label, if_true_label);
352 break;
354 case UNORDERED_EXPR:
355 do_compare_and_jump (exp, UNORDERED, UNORDERED,
356 if_false_label, if_true_label);
357 break;
359 case UNLT_EXPR:
360 do_compare_and_jump (exp, UNLT, UNLT, if_false_label, if_true_label);
361 break;
363 case UNLE_EXPR:
364 do_compare_and_jump (exp, UNLE, UNLE, if_false_label, if_true_label);
365 break;
367 case UNGT_EXPR:
368 do_compare_and_jump (exp, UNGT, UNGT, if_false_label, if_true_label);
369 break;
371 case UNGE_EXPR:
372 do_compare_and_jump (exp, UNGE, UNGE, if_false_label, if_true_label);
373 break;
375 case UNEQ_EXPR:
376 do_compare_and_jump (exp, UNEQ, UNEQ, if_false_label, if_true_label);
377 break;
379 case LTGT_EXPR:
380 do_compare_and_jump (exp, LTGT, LTGT, if_false_label, if_true_label);
381 break;
383 case BIT_AND_EXPR:
384 /* fold_single_bit_test() converts (X & (1 << C)) into (X >> C) & 1.
385 See if the former is preferred for jump tests and restore it
386 if so. */
387 if (integer_onep (TREE_OPERAND (exp, 1)))
389 tree exp0 = TREE_OPERAND (exp, 0);
390 rtx set_label, clr_label;
392 /* Strip narrowing integral type conversions. */
393 while (CONVERT_EXPR_P (exp0)
394 && TREE_OPERAND (exp0, 0) != error_mark_node
395 && TYPE_PRECISION (TREE_TYPE (exp0))
396 <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp0, 0))))
397 exp0 = TREE_OPERAND (exp0, 0);
399 /* "exp0 ^ 1" inverts the sense of the single bit test. */
400 if (TREE_CODE (exp0) == BIT_XOR_EXPR
401 && integer_onep (TREE_OPERAND (exp0, 1)))
403 exp0 = TREE_OPERAND (exp0, 0);
404 clr_label = if_true_label;
405 set_label = if_false_label;
407 else
409 clr_label = if_false_label;
410 set_label = if_true_label;
413 if (TREE_CODE (exp0) == RSHIFT_EXPR)
415 tree arg = TREE_OPERAND (exp0, 0);
416 tree shift = TREE_OPERAND (exp0, 1);
417 tree argtype = TREE_TYPE (arg);
418 if (TREE_CODE (shift) == INTEGER_CST
419 && compare_tree_int (shift, 0) >= 0
420 && compare_tree_int (shift, HOST_BITS_PER_WIDE_INT) < 0
421 && prefer_and_bit_test (TYPE_MODE (argtype),
422 TREE_INT_CST_LOW (shift)))
424 unsigned HOST_WIDE_INT mask
425 = (unsigned HOST_WIDE_INT) 1 << TREE_INT_CST_LOW (shift);
426 do_jump (build2 (BIT_AND_EXPR, argtype, arg,
427 build_int_cst_wide_type (argtype, mask, 0)),
428 clr_label, set_label);
429 break;
434 /* If we are AND'ing with a small constant, do this comparison in the
435 smallest type that fits. If the machine doesn't have comparisons
436 that small, it will be converted back to the wider comparison.
437 This helps if we are testing the sign bit of a narrower object.
438 combine can't do this for us because it can't know whether a
439 ZERO_EXTRACT or a compare in a smaller mode exists, but we do. */
441 if (! SLOW_BYTE_ACCESS
442 && TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST
443 && TYPE_PRECISION (TREE_TYPE (exp)) <= HOST_BITS_PER_WIDE_INT
444 && (i = tree_floor_log2 (TREE_OPERAND (exp, 1))) >= 0
445 && (mode = mode_for_size (i + 1, MODE_INT, 0)) != BLKmode
446 && (type = lang_hooks.types.type_for_mode (mode, 1)) != 0
447 && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (exp))
448 && have_insn_for (COMPARE, TYPE_MODE (type)))
450 do_jump (fold_convert (type, exp), if_false_label, if_true_label);
451 break;
454 if (TYPE_PRECISION (TREE_TYPE (exp)) > 1
455 || TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST)
456 goto normal;
458 /* Boolean comparisons can be compiled as TRUTH_AND_EXPR. */
460 case TRUTH_AND_EXPR:
461 /* High branch cost, expand as the bitwise AND of the conditions.
462 Do the same if the RHS has side effects, because we're effectively
463 turning a TRUTH_AND_EXPR into a TRUTH_ANDIF_EXPR. */
464 if (BRANCH_COST (optimize_insn_for_speed_p (),
465 false) >= 4
466 || TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 1)))
467 goto normal;
469 case TRUTH_ANDIF_EXPR:
470 if (if_false_label == NULL_RTX)
472 drop_through_label = gen_label_rtx ();
473 do_jump (TREE_OPERAND (exp, 0), drop_through_label, NULL_RTX);
474 do_jump (TREE_OPERAND (exp, 1), NULL_RTX, if_true_label);
476 else
478 do_jump (TREE_OPERAND (exp, 0), if_false_label, NULL_RTX);
479 do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label);
481 break;
483 case BIT_IOR_EXPR:
484 case TRUTH_OR_EXPR:
485 /* High branch cost, expand as the bitwise OR of the conditions.
486 Do the same if the RHS has side effects, because we're effectively
487 turning a TRUTH_OR_EXPR into a TRUTH_ORIF_EXPR. */
488 if (BRANCH_COST (optimize_insn_for_speed_p (), false)>= 4
489 || TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 1)))
490 goto normal;
492 case TRUTH_ORIF_EXPR:
493 if (if_true_label == NULL_RTX)
495 drop_through_label = gen_label_rtx ();
496 do_jump (TREE_OPERAND (exp, 0), NULL_RTX, drop_through_label);
497 do_jump (TREE_OPERAND (exp, 1), if_false_label, NULL_RTX);
499 else
501 do_jump (TREE_OPERAND (exp, 0), NULL_RTX, if_true_label);
502 do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label);
504 break;
506 /* Fall through and generate the normal code. */
507 default:
508 normal:
509 temp = expand_normal (exp);
510 do_pending_stack_adjust ();
511 /* The RTL optimizers prefer comparisons against pseudos. */
512 if (GET_CODE (temp) == SUBREG)
514 /* Compare promoted variables in their promoted mode. */
515 if (SUBREG_PROMOTED_VAR_P (temp)
516 && REG_P (XEXP (temp, 0)))
517 temp = XEXP (temp, 0);
518 else
519 temp = copy_to_reg (temp);
521 do_compare_rtx_and_jump (temp, CONST0_RTX (GET_MODE (temp)),
522 NE, TYPE_UNSIGNED (TREE_TYPE (exp)),
523 GET_MODE (temp), NULL_RTX,
524 if_false_label, if_true_label);
527 if (drop_through_label)
529 do_pending_stack_adjust ();
530 emit_label (drop_through_label);
534 /* Compare OP0 with OP1, word at a time, in mode MODE.
535 UNSIGNEDP says to do unsigned comparison.
536 Jump to IF_TRUE_LABEL if OP0 is greater, IF_FALSE_LABEL otherwise. */
538 static void
539 do_jump_by_parts_greater_rtx (enum machine_mode mode, int unsignedp, rtx op0,
540 rtx op1, rtx if_false_label, rtx if_true_label)
542 int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
543 rtx drop_through_label = 0;
544 int i;
546 if (! if_true_label || ! if_false_label)
547 drop_through_label = gen_label_rtx ();
548 if (! if_true_label)
549 if_true_label = drop_through_label;
550 if (! if_false_label)
551 if_false_label = drop_through_label;
553 /* Compare a word at a time, high order first. */
554 for (i = 0; i < nwords; i++)
556 rtx op0_word, op1_word;
558 if (WORDS_BIG_ENDIAN)
560 op0_word = operand_subword_force (op0, i, mode);
561 op1_word = operand_subword_force (op1, i, mode);
563 else
565 op0_word = operand_subword_force (op0, nwords - 1 - i, mode);
566 op1_word = operand_subword_force (op1, nwords - 1 - i, mode);
569 /* All but high-order word must be compared as unsigned. */
570 do_compare_rtx_and_jump (op0_word, op1_word, GT,
571 (unsignedp || i > 0), word_mode, NULL_RTX,
572 NULL_RTX, if_true_label);
574 /* Consider lower words only if these are equal. */
575 do_compare_rtx_and_jump (op0_word, op1_word, NE, unsignedp, word_mode,
576 NULL_RTX, NULL_RTX, if_false_label);
579 if (if_false_label)
580 emit_jump (if_false_label);
581 if (drop_through_label)
582 emit_label (drop_through_label);
585 /* Given a comparison expression EXP for values too wide to be compared
586 with one insn, test the comparison and jump to the appropriate label.
587 The code of EXP is ignored; we always test GT if SWAP is 0,
588 and LT if SWAP is 1. */
590 static void
591 do_jump_by_parts_greater (tree exp, int swap, rtx if_false_label,
592 rtx if_true_label)
594 rtx op0 = expand_normal (TREE_OPERAND (exp, swap));
595 rtx op1 = expand_normal (TREE_OPERAND (exp, !swap));
596 enum machine_mode mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
597 int unsignedp = TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0)));
599 do_jump_by_parts_greater_rtx (mode, unsignedp, op0, op1, if_false_label,
600 if_true_label);
603 /* Jump according to whether OP0 is 0. We assume that OP0 has an integer
604 mode, MODE, that is too wide for the available compare insns. Either
605 Either (but not both) of IF_TRUE_LABEL and IF_FALSE_LABEL may be NULL_RTX
606 to indicate drop through. */
608 static void
609 do_jump_by_parts_zero_rtx (enum machine_mode mode, rtx op0,
610 rtx if_false_label, rtx if_true_label)
612 int nwords = GET_MODE_SIZE (mode) / UNITS_PER_WORD;
613 rtx part;
614 int i;
615 rtx drop_through_label = 0;
617 /* The fastest way of doing this comparison on almost any machine is to
618 "or" all the words and compare the result. If all have to be loaded
619 from memory and this is a very wide item, it's possible this may
620 be slower, but that's highly unlikely. */
622 part = gen_reg_rtx (word_mode);
623 emit_move_insn (part, operand_subword_force (op0, 0, mode));
624 for (i = 1; i < nwords && part != 0; i++)
625 part = expand_binop (word_mode, ior_optab, part,
626 operand_subword_force (op0, i, mode),
627 part, 1, OPTAB_WIDEN);
629 if (part != 0)
631 do_compare_rtx_and_jump (part, const0_rtx, EQ, 1, word_mode,
632 NULL_RTX, if_false_label, if_true_label);
634 return;
637 /* If we couldn't do the "or" simply, do this with a series of compares. */
638 if (! if_false_label)
639 drop_through_label = if_false_label = gen_label_rtx ();
641 for (i = 0; i < nwords; i++)
642 do_compare_rtx_and_jump (operand_subword_force (op0, i, mode),
643 const0_rtx, EQ, 1, word_mode, NULL_RTX,
644 if_false_label, NULL_RTX);
646 if (if_true_label)
647 emit_jump (if_true_label);
649 if (drop_through_label)
650 emit_label (drop_through_label);
653 /* Test for the equality of two RTX expressions OP0 and OP1 in mode MODE,
654 where MODE is an integer mode too wide to be compared with one insn.
655 Either (but not both) of IF_TRUE_LABEL and IF_FALSE_LABEL may be NULL_RTX
656 to indicate drop through. */
658 static void
659 do_jump_by_parts_equality_rtx (enum machine_mode mode, rtx op0, rtx op1,
660 rtx if_false_label, rtx if_true_label)
662 int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
663 rtx drop_through_label = 0;
664 int i;
666 if (op1 == const0_rtx)
668 do_jump_by_parts_zero_rtx (mode, op0, if_false_label, if_true_label);
669 return;
671 else if (op0 == const0_rtx)
673 do_jump_by_parts_zero_rtx (mode, op1, if_false_label, if_true_label);
674 return;
677 if (! if_false_label)
678 drop_through_label = if_false_label = gen_label_rtx ();
680 for (i = 0; i < nwords; i++)
681 do_compare_rtx_and_jump (operand_subword_force (op0, i, mode),
682 operand_subword_force (op1, i, mode),
683 EQ, 0, word_mode, NULL_RTX,
684 if_false_label, NULL_RTX);
686 if (if_true_label)
687 emit_jump (if_true_label);
688 if (drop_through_label)
689 emit_label (drop_through_label);
692 /* Given an EQ_EXPR expression EXP for values too wide to be compared
693 with one insn, test the comparison and jump to the appropriate label. */
695 static void
696 do_jump_by_parts_equality (tree exp, rtx if_false_label, rtx if_true_label)
698 rtx op0 = expand_normal (TREE_OPERAND (exp, 0));
699 rtx op1 = expand_normal (TREE_OPERAND (exp, 1));
700 enum machine_mode mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
701 do_jump_by_parts_equality_rtx (mode, op0, op1, if_false_label,
702 if_true_label);
705 /* Split a comparison into two others, the second of which has the other
706 "orderedness". The first is always ORDERED or UNORDERED if MODE
707 does not honor NaNs (which means that it can be skipped in that case;
708 see do_compare_rtx_and_jump).
710 The two conditions are written in *CODE1 and *CODE2. Return true if
711 the conditions must be ANDed, false if they must be ORed. */
713 bool
714 split_comparison (enum rtx_code code, enum machine_mode mode,
715 enum rtx_code *code1, enum rtx_code *code2)
717 switch (code)
719 case LT:
720 *code1 = ORDERED;
721 *code2 = UNLT;
722 return true;
723 case LE:
724 *code1 = ORDERED;
725 *code2 = UNLE;
726 return true;
727 case GT:
728 *code1 = ORDERED;
729 *code2 = UNGT;
730 return true;
731 case GE:
732 *code1 = ORDERED;
733 *code2 = UNGE;
734 return true;
735 case EQ:
736 *code1 = ORDERED;
737 *code2 = UNEQ;
738 return true;
739 case NE:
740 *code1 = UNORDERED;
741 *code2 = LTGT;
742 return false;
743 case UNLT:
744 *code1 = UNORDERED;
745 *code2 = LT;
746 return false;
747 case UNLE:
748 *code1 = UNORDERED;
749 *code2 = LE;
750 return false;
751 case UNGT:
752 *code1 = UNORDERED;
753 *code2 = GT;
754 return false;
755 case UNGE:
756 *code1 = UNORDERED;
757 *code2 = GE;
758 return false;
759 case UNEQ:
760 *code1 = UNORDERED;
761 *code2 = EQ;
762 return false;
763 case LTGT:
764 /* Do not turn a trapping comparison into a non-trapping one. */
765 if (HONOR_SNANS (mode))
767 *code1 = LT;
768 *code2 = GT;
769 return false;
771 else
773 *code1 = ORDERED;
774 *code2 = NE;
775 return true;
777 default:
778 gcc_unreachable ();
783 /* Like do_compare_and_jump but expects the values to compare as two rtx's.
784 The decision as to signed or unsigned comparison must be made by the caller.
786 If MODE is BLKmode, SIZE is an RTX giving the size of the objects being
787 compared. */
789 void
790 do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
791 enum machine_mode mode, rtx size, rtx if_false_label,
792 rtx if_true_label)
794 rtx tem;
795 rtx dummy_label = NULL_RTX;
797 /* Reverse the comparison if that is safe and we want to jump if it is
798 false. Also convert to the reverse comparison if the target can
799 implement it. */
800 if ((! if_true_label
801 || ! can_compare_p (code, mode, ccp_jump))
802 && (! FLOAT_MODE_P (mode)
803 || code == ORDERED || code == UNORDERED
804 || (! HONOR_NANS (mode) && (code == LTGT || code == UNEQ))
805 || (! HONOR_SNANS (mode) && (code == EQ || code == NE))))
807 enum rtx_code rcode;
808 if (FLOAT_MODE_P (mode))
809 rcode = reverse_condition_maybe_unordered (code);
810 else
811 rcode = reverse_condition (code);
813 /* Canonicalize to UNORDERED for the libcall. */
814 if (can_compare_p (rcode, mode, ccp_jump)
815 || (code == ORDERED && ! can_compare_p (ORDERED, mode, ccp_jump)))
817 tem = if_true_label;
818 if_true_label = if_false_label;
819 if_false_label = tem;
820 code = rcode;
824 /* If one operand is constant, make it the second one. Only do this
825 if the other operand is not constant as well. */
827 if (swap_commutative_operands_p (op0, op1))
829 tem = op0;
830 op0 = op1;
831 op1 = tem;
832 code = swap_condition (code);
835 do_pending_stack_adjust ();
837 code = unsignedp ? unsigned_condition (code) : code;
838 if (0 != (tem = simplify_relational_operation (code, mode, VOIDmode,
839 op0, op1)))
841 if (CONSTANT_P (tem))
843 rtx label = (tem == const0_rtx || tem == CONST0_RTX (mode))
844 ? if_false_label : if_true_label;
845 if (label)
846 emit_jump (label);
847 return;
850 code = GET_CODE (tem);
851 mode = GET_MODE (tem);
852 op0 = XEXP (tem, 0);
853 op1 = XEXP (tem, 1);
854 unsignedp = (code == GTU || code == LTU || code == GEU || code == LEU);
857 if (! if_true_label)
858 dummy_label = if_true_label = gen_label_rtx ();
860 if (GET_MODE_CLASS (mode) == MODE_INT
861 && ! can_compare_p (code, mode, ccp_jump))
863 switch (code)
865 case LTU:
866 do_jump_by_parts_greater_rtx (mode, 1, op1, op0,
867 if_false_label, if_true_label);
868 break;
870 case LEU:
871 do_jump_by_parts_greater_rtx (mode, 1, op0, op1,
872 if_true_label, if_false_label);
873 break;
875 case GTU:
876 do_jump_by_parts_greater_rtx (mode, 1, op0, op1,
877 if_false_label, if_true_label);
878 break;
880 case GEU:
881 do_jump_by_parts_greater_rtx (mode, 1, op1, op0,
882 if_true_label, if_false_label);
883 break;
885 case LT:
886 do_jump_by_parts_greater_rtx (mode, 0, op1, op0,
887 if_false_label, if_true_label);
888 break;
890 case LE:
891 do_jump_by_parts_greater_rtx (mode, 0, op0, op1,
892 if_true_label, if_false_label);
893 break;
895 case GT:
896 do_jump_by_parts_greater_rtx (mode, 0, op0, op1,
897 if_false_label, if_true_label);
898 break;
900 case GE:
901 do_jump_by_parts_greater_rtx (mode, 0, op1, op0,
902 if_true_label, if_false_label);
903 break;
905 case EQ:
906 do_jump_by_parts_equality_rtx (mode, op0, op1, if_false_label,
907 if_true_label);
908 break;
910 case NE:
911 do_jump_by_parts_equality_rtx (mode, op0, op1, if_true_label,
912 if_false_label);
913 break;
915 default:
916 gcc_unreachable ();
919 else
921 if (GET_MODE_CLASS (mode) == MODE_FLOAT
922 && ! can_compare_p (code, mode, ccp_jump)
923 && can_compare_p (swap_condition (code), mode, ccp_jump))
925 rtx tmp;
926 code = swap_condition (code);
927 tmp = op0;
928 op0 = op1;
929 op1 = tmp;
932 else if (GET_MODE_CLASS (mode) == MODE_FLOAT
933 && ! can_compare_p (code, mode, ccp_jump)
935 /* Never split ORDERED and UNORDERED. These must be implemented. */
936 && (code != ORDERED && code != UNORDERED)
938 /* Split a floating-point comparison if we can jump on other
939 conditions... */
940 && (have_insn_for (COMPARE, mode)
942 /* ... or if there is no libcall for it. */
943 || code_to_optab[code] == NULL))
945 enum rtx_code first_code;
946 bool and_them = split_comparison (code, mode, &first_code, &code);
948 /* If there are no NaNs, the first comparison should always fall
949 through. */
950 if (!HONOR_NANS (mode))
951 gcc_assert (first_code == (and_them ? ORDERED : UNORDERED));
953 else
955 if (and_them)
957 rtx dest_label;
958 /* If we only jump if true, just bypass the second jump. */
959 if (! if_false_label)
961 if (! dummy_label)
962 dummy_label = gen_label_rtx ();
963 dest_label = dummy_label;
965 else
966 dest_label = if_false_label;
967 do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode,
968 size, dest_label, NULL_RTX);
970 else
971 do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode,
972 size, NULL_RTX, if_true_label);
976 emit_cmp_and_jump_insns (op0, op1, code, size, mode, unsignedp,
977 if_true_label);
980 if (if_false_label)
981 emit_jump (if_false_label);
982 if (dummy_label)
983 emit_label (dummy_label);
986 /* Generate code for a comparison expression EXP (including code to compute
987 the values to be compared) and a conditional jump to IF_FALSE_LABEL and/or
988 IF_TRUE_LABEL. One of the labels can be NULL_RTX, in which case the
989 generated code will drop through.
990 SIGNED_CODE should be the rtx operation for this comparison for
991 signed data; UNSIGNED_CODE, likewise for use if data is unsigned.
993 We force a stack adjustment unless there are currently
994 things pushed on the stack that aren't yet used. */
996 static void
997 do_compare_and_jump (tree exp, enum rtx_code signed_code,
998 enum rtx_code unsigned_code, rtx if_false_label,
999 rtx if_true_label)
1001 rtx op0, op1;
1002 tree type;
1003 enum machine_mode mode;
1004 int unsignedp;
1005 enum rtx_code code;
1007 /* Don't crash if the comparison was erroneous. */
1008 op0 = expand_normal (TREE_OPERAND (exp, 0));
1009 if (TREE_CODE (TREE_OPERAND (exp, 0)) == ERROR_MARK)
1010 return;
1012 op1 = expand_normal (TREE_OPERAND (exp, 1));
1013 if (TREE_CODE (TREE_OPERAND (exp, 1)) == ERROR_MARK)
1014 return;
1016 type = TREE_TYPE (TREE_OPERAND (exp, 0));
1017 mode = TYPE_MODE (type);
1018 if (TREE_CODE (TREE_OPERAND (exp, 0)) == INTEGER_CST
1019 && (TREE_CODE (TREE_OPERAND (exp, 1)) != INTEGER_CST
1020 || (GET_MODE_BITSIZE (mode)
1021 > GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp,
1022 1)))))))
1024 /* op0 might have been replaced by promoted constant, in which
1025 case the type of second argument should be used. */
1026 type = TREE_TYPE (TREE_OPERAND (exp, 1));
1027 mode = TYPE_MODE (type);
1029 unsignedp = TYPE_UNSIGNED (type);
1030 code = unsignedp ? unsigned_code : signed_code;
1032 #ifdef HAVE_canonicalize_funcptr_for_compare
1033 /* If function pointers need to be "canonicalized" before they can
1034 be reliably compared, then canonicalize them.
1035 Only do this if *both* sides of the comparison are function pointers.
1036 If one side isn't, we want a noncanonicalized comparison. See PR
1037 middle-end/17564. */
1038 if (HAVE_canonicalize_funcptr_for_compare
1039 && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == POINTER_TYPE
1040 && TREE_CODE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))))
1041 == FUNCTION_TYPE
1042 && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 1))) == POINTER_TYPE
1043 && TREE_CODE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 1))))
1044 == FUNCTION_TYPE)
1046 rtx new_op0 = gen_reg_rtx (mode);
1047 rtx new_op1 = gen_reg_rtx (mode);
1049 emit_insn (gen_canonicalize_funcptr_for_compare (new_op0, op0));
1050 op0 = new_op0;
1052 emit_insn (gen_canonicalize_funcptr_for_compare (new_op1, op1));
1053 op1 = new_op1;
1055 #endif
1057 do_compare_rtx_and_jump (op0, op1, code, unsignedp, mode,
1058 ((mode == BLKmode)
1059 ? expr_size (TREE_OPERAND (exp, 0)) : NULL_RTX),
1060 if_false_label, if_true_label);
1063 #include "gt-dojump.h"