]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/dojump.c
double-int.h (double_int_setbit): Declare.
[thirdparty/gcc.git] / gcc / dojump.c
CommitLineData
1cff8964
AE
1/* Convert tree expression to rtl instructions, for GNU compiler.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
40e90eac 3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
9dcd6f09 4 Free Software Foundation, Inc.
1cff8964
AE
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
9dcd6f09 10Software Foundation; either version 3, or (at your option) any later
1cff8964
AE
11version.
12
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License
9dcd6f09
NC
19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
1cff8964
AE
21
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"
dbf833ee 36#include "ggc.h"
a4cbe62d 37#include "basic-block.h"
40e90eac 38#include "output.h"
1cff8964 39
dbf833ee 40static bool prefer_and_bit_test (enum machine_mode, int);
40e90eac
JJ
41static void do_jump_by_parts_greater (tree, tree, int, rtx, rtx, int);
42static void do_jump_by_parts_equality (tree, tree, rtx, rtx, int);
4df62c77 43static void do_compare_and_jump (tree, tree, enum rtx_code, enum rtx_code, rtx,
40e90eac
JJ
44 rtx, int);
45
46/* Invert probability if there is any. -1 stands for unknown. */
47
48static inline int
49inv (int prob)
50{
51 return prob == -1 ? -1 : REG_BR_PROB_BASE - prob;
52}
1cff8964
AE
53
54/* At the start of a function, record that we have no previously-pushed
55 arguments waiting to be popped. */
56
57void
7080f735 58init_pending_stack_adjust (void)
1cff8964
AE
59{
60 pending_stack_adjust = 0;
61}
62
a494ed43
EB
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. */
83f676b3
RS
66void
67discard_pending_stack_adjust (void)
a494ed43
EB
68{
69 stack_pointer_delta -= pending_stack_adjust;
70 pending_stack_adjust = 0;
71}
72
1cff8964
AE
73/* When exiting from function, if safe, clear out any pending stack adjust
74 so the adjustment won't get done.
75
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. */
78
79void
7080f735 80clear_pending_stack_adjust (void)
1cff8964 81{
1cff8964 82 if (optimize > 0
e3b5732b 83 && (! flag_omit_frame_pointer || cfun->calls_alloca)
c37f4ba4 84 && EXIT_IGNORE_STACK)
a494ed43 85 discard_pending_stack_adjust ();
1cff8964
AE
86}
87
88/* Pop any previously-pushed arguments that have not been popped yet. */
89
90void
7080f735 91do_pending_stack_adjust (void)
1cff8964
AE
92{
93 if (inhibit_defer_pop == 0)
94 {
95 if (pending_stack_adjust != 0)
96 adjust_stack (GEN_INT (pending_stack_adjust));
97 pending_stack_adjust = 0;
98 }
99}
100\f
101/* Expand conditional expressions. */
102
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. */
106
107void
40e90eac 108jumpifnot (tree exp, rtx label, int prob)
1cff8964 109{
40e90eac 110 do_jump (exp, label, NULL_RTX, inv (prob));
1cff8964
AE
111}
112
4df62c77 113void
40e90eac 114jumpifnot_1 (enum tree_code code, tree op0, tree op1, rtx label, int prob)
4df62c77 115{
40e90eac 116 do_jump_1 (code, op0, op1, label, NULL_RTX, inv (prob));
4df62c77
MM
117}
118
1cff8964
AE
119/* Generate code to evaluate EXP and jump to LABEL if the value is nonzero. */
120
121void
40e90eac 122jumpif (tree exp, rtx label, int prob)
1cff8964 123{
40e90eac 124 do_jump (exp, NULL_RTX, label, prob);
1cff8964
AE
125}
126
4df62c77 127void
40e90eac 128jumpif_1 (enum tree_code code, tree op0, tree op1, rtx label, int prob)
4df62c77 129{
40e90eac 130 do_jump_1 (code, op0, op1, NULL_RTX, label, prob);
4df62c77
MM
131}
132
dbf833ee
RS
133/* Used internally by prefer_and_bit_test. */
134
135static GTY(()) rtx and_reg;
136static GTY(()) rtx and_test;
137static GTY(()) rtx shift_test;
138
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. */
142
143static bool
144prefer_and_bit_test (enum machine_mode mode, int bitnum)
145{
146 if (and_test == 0)
147 {
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);
154 }
155 else
156 {
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);
162 }
163
164 /* Fill in the integers. */
472e0df9 165 XEXP (and_test, 1)
54fb1ae0
AS
166 = immed_double_int_const (double_int_setbit (double_int_zero, bitnum),
167 mode);
dbf833ee
RS
168 XEXP (XEXP (shift_test, 0), 1) = GEN_INT (bitnum);
169
f40751dd
JH
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 ()));
dbf833ee
RS
172}
173
4df62c77 174/* Subroutine of do_jump, dealing with exploded comparisons of the type
40e90eac
JJ
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. */
4df62c77
MM
177
178void
179do_jump_1 (enum tree_code code, tree op0, tree op1,
40e90eac 180 rtx if_false_label, rtx if_true_label, int prob)
4df62c77
MM
181{
182 enum machine_mode mode;
183 rtx drop_through_label = 0;
184
185 switch (code)
186 {
187 case EQ_EXPR:
188 {
189 tree inner_type = TREE_TYPE (op0);
190
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);
195
196 if (integer_zerop (op1))
40e90eac 197 do_jump (op0, if_true_label, if_false_label, inv (prob));
4df62c77
MM
198 else if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_INT
199 && !can_compare_p (EQ, TYPE_MODE (inner_type), ccp_jump))
40e90eac
JJ
200 do_jump_by_parts_equality (op0, op1, if_false_label, if_true_label,
201 prob);
4df62c77 202 else
40e90eac
JJ
203 do_compare_and_jump (op0, op1, EQ, EQ, if_false_label, if_true_label,
204 prob);
4df62c77
MM
205 break;
206 }
207
208 case NE_EXPR:
209 {
210 tree inner_type = TREE_TYPE (op0);
211
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);
216
217 if (integer_zerop (op1))
40e90eac 218 do_jump (op0, if_false_label, if_true_label, prob);
4df62c77
MM
219 else if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_INT
220 && !can_compare_p (NE, TYPE_MODE (inner_type), ccp_jump))
40e90eac
JJ
221 do_jump_by_parts_equality (op0, op1, if_true_label, if_false_label,
222 inv (prob));
4df62c77 223 else
40e90eac
JJ
224 do_compare_and_jump (op0, op1, NE, NE, if_false_label, if_true_label,
225 prob);
4df62c77
MM
226 break;
227 }
228
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))
40e90eac
JJ
233 do_jump_by_parts_greater (op0, op1, 1, if_false_label, if_true_label,
234 prob);
4df62c77 235 else
40e90eac
JJ
236 do_compare_and_jump (op0, op1, LT, LTU, if_false_label, if_true_label,
237 prob);
4df62c77
MM
238 break;
239
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))
40e90eac
JJ
244 do_jump_by_parts_greater (op0, op1, 0, if_true_label, if_false_label,
245 inv (prob));
4df62c77 246 else
40e90eac
JJ
247 do_compare_and_jump (op0, op1, LE, LEU, if_false_label, if_true_label,
248 prob);
4df62c77
MM
249 break;
250
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))
40e90eac
JJ
255 do_jump_by_parts_greater (op0, op1, 0, if_false_label, if_true_label,
256 prob);
4df62c77 257 else
40e90eac
JJ
258 do_compare_and_jump (op0, op1, GT, GTU, if_false_label, if_true_label,
259 prob);
4df62c77
MM
260 break;
261
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))
40e90eac
JJ
266 do_jump_by_parts_greater (op0, op1, 1, if_true_label, if_false_label,
267 inv (prob));
4df62c77 268 else
40e90eac
JJ
269 do_compare_and_jump (op0, op1, GE, GEU, if_false_label, if_true_label,
270 prob);
4df62c77
MM
271 break;
272
273 case ORDERED_EXPR:
274 do_compare_and_jump (op0, op1, ORDERED, ORDERED,
40e90eac 275 if_false_label, if_true_label, prob);
4df62c77
MM
276 break;
277
278 case UNORDERED_EXPR:
279 do_compare_and_jump (op0, op1, UNORDERED, UNORDERED,
40e90eac 280 if_false_label, if_true_label, prob);
4df62c77
MM
281 break;
282
283 case UNLT_EXPR:
40e90eac
JJ
284 do_compare_and_jump (op0, op1, UNLT, UNLT, if_false_label, if_true_label,
285 prob);
4df62c77
MM
286 break;
287
288 case UNLE_EXPR:
40e90eac
JJ
289 do_compare_and_jump (op0, op1, UNLE, UNLE, if_false_label, if_true_label,
290 prob);
4df62c77
MM
291 break;
292
293 case UNGT_EXPR:
40e90eac
JJ
294 do_compare_and_jump (op0, op1, UNGT, UNGT, if_false_label, if_true_label,
295 prob);
4df62c77
MM
296 break;
297
298 case UNGE_EXPR:
40e90eac
JJ
299 do_compare_and_jump (op0, op1, UNGE, UNGE, if_false_label, if_true_label,
300 prob);
4df62c77
MM
301 break;
302
303 case UNEQ_EXPR:
40e90eac
JJ
304 do_compare_and_jump (op0, op1, UNEQ, UNEQ, if_false_label, if_true_label,
305 prob);
4df62c77
MM
306 break;
307
308 case LTGT_EXPR:
40e90eac
JJ
309 do_compare_and_jump (op0, op1, LTGT, LTGT, if_false_label, if_true_label,
310 prob);
4df62c77
MM
311 break;
312
313 case TRUTH_ANDIF_EXPR:
314 if (if_false_label == NULL_RTX)
315 {
316 drop_through_label = gen_label_rtx ();
40e90eac
JJ
317 do_jump (op0, drop_through_label, NULL_RTX, prob);
318 do_jump (op1, NULL_RTX, if_true_label, prob);
4df62c77
MM
319 }
320 else
321 {
40e90eac
JJ
322 do_jump (op0, if_false_label, NULL_RTX, prob);
323 do_jump (op1, if_false_label, if_true_label, prob);
4df62c77
MM
324 }
325 break;
326
327 case TRUTH_ORIF_EXPR:
328 if (if_true_label == NULL_RTX)
329 {
330 drop_through_label = gen_label_rtx ();
40e90eac
JJ
331 do_jump (op0, NULL_RTX, drop_through_label, prob);
332 do_jump (op1, if_false_label, NULL_RTX, prob);
4df62c77
MM
333 }
334 else
335 {
40e90eac
JJ
336 do_jump (op0, NULL_RTX, if_true_label, prob);
337 do_jump (op1, if_false_label, if_true_label, prob);
4df62c77
MM
338 }
339 break;
340
341 default:
342 gcc_unreachable ();
343 }
344
345 if (drop_through_label)
346 {
347 do_pending_stack_adjust ();
348 emit_label (drop_through_label);
349 }
350}
351
1cff8964
AE
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.
356
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
40e90eac
JJ
359 is when EXP is `(foo (), 0)' and IF_FALSE_LABEL is null.
360
361 PROB is probability of jump to if_true_label, or -1 if unknown. */
1cff8964
AE
362
363void
40e90eac 364do_jump (tree exp, rtx if_false_label, rtx if_true_label, int prob)
1cff8964
AE
365{
366 enum tree_code code = TREE_CODE (exp);
1cff8964
AE
367 rtx temp;
368 int i;
369 tree type;
370 enum machine_mode mode;
8ea9d0c7 371 rtx drop_through_label = 0;
1cff8964 372
1cff8964
AE
373 switch (code)
374 {
375 case ERROR_MARK:
376 break;
377
378 case INTEGER_CST:
379 temp = integer_zerop (exp) ? if_false_label : if_true_label;
380 if (temp)
381 emit_jump (temp);
382 break;
383
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
392
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:
1cff8964
AE
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. */
40e90eac 411 do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label, prob);
1cff8964
AE
412 break;
413
1cff8964 414 case TRUTH_NOT_EXPR:
8ac074e8
JJ
415 do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label,
416 inv (prob));
1cff8964
AE
417 break;
418
8ea9d0c7
PB
419 case COND_EXPR:
420 {
421 rtx label1 = gen_label_rtx ();
422 if (!if_true_label || !if_false_label)
423 {
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;
429 }
430
431 do_pending_stack_adjust ();
40e90eac
JJ
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);
8ea9d0c7 434 emit_label (label1);
40e90eac 435 do_jump (TREE_OPERAND (exp, 2), if_false_label, if_true_label, prob);
8ea9d0c7
PB
436 break;
437 }
438
1cff8964 439 case COMPOUND_EXPR:
7c27e184 440 /* Lowered by gimplify.c. */
ced3f397 441 gcc_unreachable ();
1cff8964
AE
442
443 case COMPONENT_REF:
444 case BIT_FIELD_REF:
445 case ARRAY_REF:
446 case ARRAY_RANGE_REF:
447 {
448 HOST_WIDE_INT bitsize, bitpos;
449 int unsignedp;
450 enum machine_mode mode;
451 tree type;
452 tree offset;
453 int volatilep = 0;
454
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,
2614034e 458 &unsignedp, &volatilep, false);
1cff8964 459
ae2bcd98 460 type = lang_hooks.types.type_for_size (bitsize, unsignedp);
1cff8964
AE
461 if (! SLOW_BYTE_ACCESS
462 && type != 0 && bitsize >= 0
463 && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (exp))
fedc1775 464 && have_insn_for (COMPARE, TYPE_MODE (type)))
1cff8964 465 {
40e90eac
JJ
466 do_jump (fold_convert (type, exp), if_false_label, if_true_label,
467 prob);
1cff8964
AE
468 break;
469 }
470 goto normal;
471 }
472
0b04d281
DE
473 case MINUS_EXPR:
474 /* Nonzero iff operands of minus differ. */
4df62c77
MM
475 code = NE_EXPR;
476
0b04d281 477 /* FALLTHRU */
4df62c77 478 case EQ_EXPR:
1cff8964 479 case NE_EXPR:
1cff8964 480 case LT_EXPR:
1cff8964 481 case LE_EXPR:
1cff8964 482 case GT_EXPR:
1cff8964 483 case GE_EXPR:
1cff8964 484 case ORDERED_EXPR:
337e5d98 485 case UNORDERED_EXPR:
337e5d98 486 case UNLT_EXPR:
337e5d98 487 case UNLE_EXPR:
337e5d98 488 case UNGT_EXPR:
337e5d98 489 case UNGE_EXPR:
337e5d98 490 case UNEQ_EXPR:
337e5d98 491 case LTGT_EXPR:
4df62c77
MM
492 case TRUTH_ANDIF_EXPR:
493 case TRUTH_ORIF_EXPR:
c3223baf 494 other_code:
4df62c77 495 do_jump_1 (code, TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
40e90eac 496 if_false_label, if_true_label, prob);
1cff8964 497 break;
30821654
PB
498
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)))
504 {
505 tree exp0 = TREE_OPERAND (exp, 0);
506 rtx set_label, clr_label;
40e90eac 507 int setclr_prob = prob;
30821654
PB
508
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);
515
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)))
519 {
520 exp0 = TREE_OPERAND (exp0, 0);
521 clr_label = if_true_label;
522 set_label = if_false_label;
40e90eac 523 setclr_prob = inv (prob);
30821654
PB
524 }
525 else
526 {
527 clr_label = if_false_label;
528 set_label = if_true_label;
529 }
530
531 if (TREE_CODE (exp0) == RSHIFT_EXPR)
532 {
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)))
541 {
472e0df9
JJ
542 unsigned HOST_WIDE_INT mask
543 = (unsigned HOST_WIDE_INT) 1 << TREE_INT_CST_LOW (shift);
30821654 544 do_jump (build2 (BIT_AND_EXPR, argtype, arg,
472e0df9 545 build_int_cst_wide_type (argtype, mask, 0)),
40e90eac 546 clr_label, set_label, setclr_prob);
30821654
PB
547 break;
548 }
549 }
550 }
551
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. */
558
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))
fedc1775 566 && have_insn_for (COMPARE, TYPE_MODE (type)))
30821654 567 {
40e90eac
JJ
568 do_jump (fold_convert (type, exp), if_false_label, if_true_label,
569 prob);
30821654
PB
570 break;
571 }
572
573 if (TYPE_PRECISION (TREE_TYPE (exp)) > 1
574 || TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST)
575 goto normal;
576
577 /* Boolean comparisons can be compiled as TRUTH_AND_EXPR. */
1cff8964 578
d1f36c51 579 case TRUTH_AND_EXPR:
97191ef9
PB
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. */
3a4fd356
JH
583 if (BRANCH_COST (optimize_insn_for_speed_p (),
584 false) >= 4
585 || TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 1)))
d1f36c51 586 goto normal;
c3223baf
MM
587 code = TRUTH_ANDIF_EXPR;
588 goto other_code;
d1f36c51 589
30821654 590 case BIT_IOR_EXPR:
d1f36c51 591 case TRUTH_OR_EXPR:
97191ef9
PB
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. */
40e90eac 595 if (BRANCH_COST (optimize_insn_for_speed_p (), false) >= 4
3a4fd356 596 || TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 1)))
d1f36c51 597 goto normal;
c3223baf
MM
598 code = TRUTH_ORIF_EXPR;
599 goto other_code;
d1f36c51 600
938d968e 601 /* Fall through and generate the normal code. */
1cff8964
AE
602 default:
603 normal:
84217346 604 temp = expand_normal (exp);
1cff8964 605 do_pending_stack_adjust ();
feb04780
RS
606 /* The RTL optimizers prefer comparisons against pseudos. */
607 if (GET_CODE (temp) == SUBREG)
9311f3f6 608 {
feb04780
RS
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);
9311f3f6 615 }
feb04780
RS
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,
40e90eac 619 if_false_label, if_true_label, prob);
1cff8964 620 }
8ea9d0c7
PB
621
622 if (drop_through_label)
623 {
624 do_pending_stack_adjust ();
625 emit_label (drop_through_label);
626 }
1cff8964
AE
627}
628\f
1cff8964
AE
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. */
632
3bf78d3b 633static void
7080f735 634do_jump_by_parts_greater_rtx (enum machine_mode mode, int unsignedp, rtx op0,
40e90eac
JJ
635 rtx op1, rtx if_false_label, rtx if_true_label,
636 int prob)
1cff8964
AE
637{
638 int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
639 rtx drop_through_label = 0;
640 int i;
641
642 if (! if_true_label || ! if_false_label)
643 drop_through_label = gen_label_rtx ();
644 if (! if_true_label)
645 if_true_label = drop_through_label;
646 if (! if_false_label)
647 if_false_label = drop_through_label;
648
649 /* Compare a word at a time, high order first. */
650 for (i = 0; i < nwords; i++)
651 {
652 rtx op0_word, op1_word;
653
654 if (WORDS_BIG_ENDIAN)
655 {
656 op0_word = operand_subword_force (op0, i, mode);
657 op1_word = operand_subword_force (op1, i, mode);
658 }
659 else
660 {
661 op0_word = operand_subword_force (op0, nwords - 1 - i, mode);
662 op1_word = operand_subword_force (op1, nwords - 1 - i, mode);
663 }
664
665 /* All but high-order word must be compared as unsigned. */
666 do_compare_rtx_and_jump (op0_word, op1_word, GT,
667 (unsignedp || i > 0), word_mode, NULL_RTX,
40e90eac 668 NULL_RTX, if_true_label, prob);
1cff8964
AE
669
670 /* Consider lower words only if these are equal. */
671 do_compare_rtx_and_jump (op0_word, op1_word, NE, unsignedp, word_mode,
40e90eac
JJ
672 NULL_RTX, NULL_RTX, if_false_label,
673 inv (prob));
1cff8964
AE
674 }
675
676 if (if_false_label)
677 emit_jump (if_false_label);
678 if (drop_through_label)
679 emit_label (drop_through_label);
680}
3bf78d3b
RS
681
682/* Given a comparison expression EXP for values too wide to be compared
683 with one insn, test the comparison and jump to the appropriate label.
684 The code of EXP is ignored; we always test GT if SWAP is 0,
685 and LT if SWAP is 1. */
686
687static void
4df62c77 688do_jump_by_parts_greater (tree treeop0, tree treeop1, int swap,
40e90eac 689 rtx if_false_label, rtx if_true_label, int prob)
3bf78d3b 690{
4df62c77
MM
691 rtx op0 = expand_normal (swap ? treeop1 : treeop0);
692 rtx op1 = expand_normal (swap ? treeop0 : treeop1);
693 enum machine_mode mode = TYPE_MODE (TREE_TYPE (treeop0));
694 int unsignedp = TYPE_UNSIGNED (TREE_TYPE (treeop0));
3bf78d3b
RS
695
696 do_jump_by_parts_greater_rtx (mode, unsignedp, op0, op1, if_false_label,
40e90eac 697 if_true_label, prob);
3bf78d3b 698}
1cff8964 699\f
feb04780
RS
700/* Jump according to whether OP0 is 0. We assume that OP0 has an integer
701 mode, MODE, that is too wide for the available compare insns. Either
702 Either (but not both) of IF_TRUE_LABEL and IF_FALSE_LABEL may be NULL_RTX
703 to indicate drop through. */
1cff8964 704
feb04780
RS
705static void
706do_jump_by_parts_zero_rtx (enum machine_mode mode, rtx op0,
40e90eac 707 rtx if_false_label, rtx if_true_label, int prob)
1cff8964 708{
feb04780 709 int nwords = GET_MODE_SIZE (mode) / UNITS_PER_WORD;
1cff8964
AE
710 rtx part;
711 int i;
712 rtx drop_through_label = 0;
713
714 /* The fastest way of doing this comparison on almost any machine is to
715 "or" all the words and compare the result. If all have to be loaded
716 from memory and this is a very wide item, it's possible this may
717 be slower, but that's highly unlikely. */
718
719 part = gen_reg_rtx (word_mode);
0a49e5c2 720 emit_move_insn (part, operand_subword_force (op0, 0, mode));
1cff8964
AE
721 for (i = 1; i < nwords && part != 0; i++)
722 part = expand_binop (word_mode, ior_optab, part,
0a49e5c2 723 operand_subword_force (op0, i, mode),
1cff8964
AE
724 part, 1, OPTAB_WIDEN);
725
726 if (part != 0)
727 {
728 do_compare_rtx_and_jump (part, const0_rtx, EQ, 1, word_mode,
40e90eac 729 NULL_RTX, if_false_label, if_true_label, prob);
1cff8964
AE
730 return;
731 }
732
733 /* If we couldn't do the "or" simply, do this with a series of compares. */
734 if (! if_false_label)
735 drop_through_label = if_false_label = gen_label_rtx ();
736
737 for (i = 0; i < nwords; i++)
0a49e5c2 738 do_compare_rtx_and_jump (operand_subword_force (op0, i, mode),
1cff8964 739 const0_rtx, EQ, 1, word_mode, NULL_RTX,
40e90eac 740 if_false_label, NULL_RTX, prob);
1cff8964
AE
741
742 if (if_true_label)
743 emit_jump (if_true_label);
744
745 if (drop_through_label)
746 emit_label (drop_through_label);
747}
feb04780
RS
748
749/* Test for the equality of two RTX expressions OP0 and OP1 in mode MODE,
750 where MODE is an integer mode too wide to be compared with one insn.
751 Either (but not both) of IF_TRUE_LABEL and IF_FALSE_LABEL may be NULL_RTX
752 to indicate drop through. */
753
754static void
755do_jump_by_parts_equality_rtx (enum machine_mode mode, rtx op0, rtx op1,
40e90eac 756 rtx if_false_label, rtx if_true_label, int prob)
feb04780
RS
757{
758 int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
759 rtx drop_through_label = 0;
760 int i;
761
762 if (op1 == const0_rtx)
763 {
40e90eac
JJ
764 do_jump_by_parts_zero_rtx (mode, op0, if_false_label, if_true_label,
765 prob);
feb04780
RS
766 return;
767 }
768 else if (op0 == const0_rtx)
769 {
40e90eac
JJ
770 do_jump_by_parts_zero_rtx (mode, op1, if_false_label, if_true_label,
771 prob);
feb04780
RS
772 return;
773 }
774
775 if (! if_false_label)
776 drop_through_label = if_false_label = gen_label_rtx ();
777
778 for (i = 0; i < nwords; i++)
779 do_compare_rtx_and_jump (operand_subword_force (op0, i, mode),
780 operand_subword_force (op1, i, mode),
781 EQ, 0, word_mode, NULL_RTX,
40e90eac 782 if_false_label, NULL_RTX, prob);
feb04780
RS
783
784 if (if_true_label)
785 emit_jump (if_true_label);
786 if (drop_through_label)
787 emit_label (drop_through_label);
788}
789
790/* Given an EQ_EXPR expression EXP for values too wide to be compared
791 with one insn, test the comparison and jump to the appropriate label. */
792
793static void
4df62c77 794do_jump_by_parts_equality (tree treeop0, tree treeop1, rtx if_false_label,
40e90eac 795 rtx if_true_label, int prob)
feb04780 796{
4df62c77
MM
797 rtx op0 = expand_normal (treeop0);
798 rtx op1 = expand_normal (treeop1);
799 enum machine_mode mode = TYPE_MODE (TREE_TYPE (treeop0));
feb04780 800 do_jump_by_parts_equality_rtx (mode, op0, op1, if_false_label,
40e90eac 801 if_true_label, prob);
feb04780 802}
1cff8964 803\f
337e5d98
PB
804/* Split a comparison into two others, the second of which has the other
805 "orderedness". The first is always ORDERED or UNORDERED if MODE
806 does not honor NaNs (which means that it can be skipped in that case;
807 see do_compare_rtx_and_jump).
808
809 The two conditions are written in *CODE1 and *CODE2. Return true if
810 the conditions must be ANDed, false if they must be ORed. */
811
812bool
813split_comparison (enum rtx_code code, enum machine_mode mode,
814 enum rtx_code *code1, enum rtx_code *code2)
815{
816 switch (code)
817 {
818 case LT:
819 *code1 = ORDERED;
820 *code2 = UNLT;
821 return true;
822 case LE:
823 *code1 = ORDERED;
824 *code2 = UNLE;
825 return true;
826 case GT:
827 *code1 = ORDERED;
828 *code2 = UNGT;
829 return true;
830 case GE:
831 *code1 = ORDERED;
832 *code2 = UNGE;
833 return true;
834 case EQ:
835 *code1 = ORDERED;
836 *code2 = UNEQ;
837 return true;
838 case NE:
839 *code1 = UNORDERED;
840 *code2 = LTGT;
841 return false;
842 case UNLT:
843 *code1 = UNORDERED;
844 *code2 = LT;
845 return false;
846 case UNLE:
847 *code1 = UNORDERED;
848 *code2 = LE;
849 return false;
850 case UNGT:
851 *code1 = UNORDERED;
852 *code2 = GT;
853 return false;
854 case UNGE:
855 *code1 = UNORDERED;
856 *code2 = GE;
857 return false;
858 case UNEQ:
859 *code1 = UNORDERED;
860 *code2 = EQ;
861 return false;
862 case LTGT:
863 /* Do not turn a trapping comparison into a non-trapping one. */
864 if (HONOR_SNANS (mode))
865 {
866 *code1 = LT;
867 *code2 = GT;
868 return false;
869 }
870 else
871 {
872 *code1 = ORDERED;
873 *code2 = NE;
874 return true;
875 }
876 default:
877 gcc_unreachable ();
878 }
879}
880
881
1cff8964
AE
882/* Like do_compare_and_jump but expects the values to compare as two rtx's.
883 The decision as to signed or unsigned comparison must be made by the caller.
884
885 If MODE is BLKmode, SIZE is an RTX giving the size of the objects being
886 compared. */
887
888void
7080f735
AJ
889do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
890 enum machine_mode mode, rtx size, rtx if_false_label,
40e90eac 891 rtx if_true_label, int prob)
1cff8964 892{
1cff8964 893 rtx tem;
337e5d98 894 rtx dummy_label = NULL_RTX;
40e90eac 895 rtx last;
1cff8964
AE
896
897 /* Reverse the comparison if that is safe and we want to jump if it is
337e5d98
PB
898 false. Also convert to the reverse comparison if the target can
899 implement it. */
900 if ((! if_true_label
901 || ! can_compare_p (code, mode, ccp_jump))
902 && (! FLOAT_MODE_P (mode)
903 || code == ORDERED || code == UNORDERED
904 || (! HONOR_NANS (mode) && (code == LTGT || code == UNEQ))
905 || (! HONOR_SNANS (mode) && (code == EQ || code == NE))))
1cff8964 906 {
337e5d98
PB
907 enum rtx_code rcode;
908 if (FLOAT_MODE_P (mode))
909 rcode = reverse_condition_maybe_unordered (code);
910 else
911 rcode = reverse_condition (code);
912
913 /* Canonicalize to UNORDERED for the libcall. */
914 if (can_compare_p (rcode, mode, ccp_jump)
915 || (code == ORDERED && ! can_compare_p (ORDERED, mode, ccp_jump)))
916 {
917 tem = if_true_label;
918 if_true_label = if_false_label;
919 if_false_label = tem;
920 code = rcode;
40e90eac 921 prob = inv (prob);
337e5d98 922 }
1cff8964
AE
923 }
924
925 /* If one operand is constant, make it the second one. Only do this
926 if the other operand is not constant as well. */
927
928 if (swap_commutative_operands_p (op0, op1))
929 {
930 tem = op0;
931 op0 = op1;
932 op1 = tem;
933 code = swap_condition (code);
934 }
935
1cff8964
AE
936 do_pending_stack_adjust ();
937
c6fb08ad
PB
938 code = unsignedp ? unsigned_condition (code) : code;
939 if (0 != (tem = simplify_relational_operation (code, mode, VOIDmode,
940 op0, op1)))
1cff8964 941 {
c6fb08ad
PB
942 if (CONSTANT_P (tem))
943 {
944 rtx label = (tem == const0_rtx || tem == CONST0_RTX (mode))
945 ? if_false_label : if_true_label;
946 if (label)
947 emit_jump (label);
948 return;
949 }
1cff8964 950
c6fb08ad
PB
951 code = GET_CODE (tem);
952 mode = GET_MODE (tem);
953 op0 = XEXP (tem, 0);
954 op1 = XEXP (tem, 1);
955 unsignedp = (code == GTU || code == LTU || code == GEU || code == LEU);
1cff8964 956 }
1cff8964
AE
957
958 if (! if_true_label)
337e5d98 959 dummy_label = if_true_label = gen_label_rtx ();
1cff8964 960
feb04780
RS
961 if (GET_MODE_CLASS (mode) == MODE_INT
962 && ! can_compare_p (code, mode, ccp_jump))
963 {
964 switch (code)
965 {
966 case LTU:
967 do_jump_by_parts_greater_rtx (mode, 1, op1, op0,
40e90eac 968 if_false_label, if_true_label, prob);
feb04780
RS
969 break;
970
971 case LEU:
972 do_jump_by_parts_greater_rtx (mode, 1, op0, op1,
40e90eac
JJ
973 if_true_label, if_false_label,
974 inv (prob));
feb04780
RS
975 break;
976
fb9c6d49
RS
977 case GTU:
978 do_jump_by_parts_greater_rtx (mode, 1, op0, op1,
40e90eac 979 if_false_label, if_true_label, prob);
fb9c6d49
RS
980 break;
981
982 case GEU:
983 do_jump_by_parts_greater_rtx (mode, 1, op1, op0,
40e90eac
JJ
984 if_true_label, if_false_label,
985 inv (prob));
fb9c6d49
RS
986 break;
987
feb04780
RS
988 case LT:
989 do_jump_by_parts_greater_rtx (mode, 0, op1, op0,
40e90eac 990 if_false_label, if_true_label, prob);
feb04780
RS
991 break;
992
1dc5d842
RS
993 case LE:
994 do_jump_by_parts_greater_rtx (mode, 0, op0, op1,
40e90eac
JJ
995 if_true_label, if_false_label,
996 inv (prob));
1dc5d842
RS
997 break;
998
feb04780
RS
999 case GT:
1000 do_jump_by_parts_greater_rtx (mode, 0, op0, op1,
40e90eac 1001 if_false_label, if_true_label, prob);
feb04780
RS
1002 break;
1003
1004 case GE:
1005 do_jump_by_parts_greater_rtx (mode, 0, op1, op0,
40e90eac
JJ
1006 if_true_label, if_false_label,
1007 inv (prob));
feb04780
RS
1008 break;
1009
1010 case EQ:
1011 do_jump_by_parts_equality_rtx (mode, op0, op1, if_false_label,
40e90eac 1012 if_true_label, prob);
feb04780
RS
1013 break;
1014
1015 case NE:
1016 do_jump_by_parts_equality_rtx (mode, op0, op1, if_true_label,
40e90eac 1017 if_false_label, inv (prob));
feb04780
RS
1018 break;
1019
1020 default:
1021 gcc_unreachable ();
1022 }
1023 }
1024 else
337e5d98
PB
1025 {
1026 if (GET_MODE_CLASS (mode) == MODE_FLOAT
1027 && ! can_compare_p (code, mode, ccp_jump)
45475a3f
PB
1028 && can_compare_p (swap_condition (code), mode, ccp_jump))
1029 {
1030 rtx tmp;
1031 code = swap_condition (code);
1032 tmp = op0;
1033 op0 = op1;
1034 op1 = tmp;
1035 }
1036
1037 else if (GET_MODE_CLASS (mode) == MODE_FLOAT
1038 && ! can_compare_p (code, mode, ccp_jump)
337e5d98 1039
45475a3f
PB
1040 /* Never split ORDERED and UNORDERED. These must be implemented. */
1041 && (code != ORDERED && code != UNORDERED)
337e5d98 1042
45475a3f
PB
1043 /* Split a floating-point comparison if we can jump on other
1044 conditions... */
1045 && (have_insn_for (COMPARE, mode)
337e5d98 1046
45475a3f
PB
1047 /* ... or if there is no libcall for it. */
1048 || code_to_optab[code] == NULL))
337e5d98
PB
1049 {
1050 enum rtx_code first_code;
1051 bool and_them = split_comparison (code, mode, &first_code, &code);
1052
1053 /* If there are no NaNs, the first comparison should always fall
1054 through. */
1055 if (!HONOR_NANS (mode))
1056 gcc_assert (first_code == (and_them ? ORDERED : UNORDERED));
1057
1058 else
1059 {
1060 if (and_them)
1061 {
1062 rtx dest_label;
1063 /* If we only jump if true, just bypass the second jump. */
1064 if (! if_false_label)
1065 {
1066 if (! dummy_label)
1067 dummy_label = gen_label_rtx ();
1068 dest_label = dummy_label;
1069 }
1070 else
1071 dest_label = if_false_label;
1072 do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode,
40e90eac 1073 size, dest_label, NULL_RTX, prob);
337e5d98
PB
1074 }
1075 else
1076 do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode,
40e90eac 1077 size, NULL_RTX, if_true_label, prob);
337e5d98
PB
1078 }
1079 }
1080
40e90eac 1081 last = get_last_insn ();
337e5d98
PB
1082 emit_cmp_and_jump_insns (op0, op1, code, size, mode, unsignedp,
1083 if_true_label);
40e90eac
JJ
1084 if (prob != -1 && profile_status != PROFILE_ABSENT)
1085 {
1086 for (last = NEXT_INSN (last);
1087 last && NEXT_INSN (last);
1088 last = NEXT_INSN (last))
1089 if (JUMP_P (last))
1090 break;
1091 if (!last
1092 || !JUMP_P (last)
1093 || NEXT_INSN (last)
1094 || !any_condjump_p (last))
1095 {
1096 if (dump_file)
1097 fprintf (dump_file, "Failed to add probability note\n");
1098 }
1099 else
1100 {
1101 gcc_assert (!find_reg_note (last, REG_BR_PROB, 0));
1102 add_reg_note (last, REG_BR_PROB, GEN_INT (prob));
1103 }
1104 }
337e5d98 1105 }
1cff8964
AE
1106
1107 if (if_false_label)
1108 emit_jump (if_false_label);
337e5d98
PB
1109 if (dummy_label)
1110 emit_label (dummy_label);
1cff8964
AE
1111}
1112
1113/* Generate code for a comparison expression EXP (including code to compute
1114 the values to be compared) and a conditional jump to IF_FALSE_LABEL and/or
1115 IF_TRUE_LABEL. One of the labels can be NULL_RTX, in which case the
1116 generated code will drop through.
1117 SIGNED_CODE should be the rtx operation for this comparison for
1118 signed data; UNSIGNED_CODE, likewise for use if data is unsigned.
1119
1120 We force a stack adjustment unless there are currently
1121 things pushed on the stack that aren't yet used. */
1122
1123static void
4df62c77 1124do_compare_and_jump (tree treeop0, tree treeop1, enum rtx_code signed_code,
7080f735 1125 enum rtx_code unsigned_code, rtx if_false_label,
40e90eac 1126 rtx if_true_label, int prob)
1cff8964
AE
1127{
1128 rtx op0, op1;
1129 tree type;
1130 enum machine_mode mode;
1131 int unsignedp;
1132 enum rtx_code code;
1133
1134 /* Don't crash if the comparison was erroneous. */
4df62c77
MM
1135 op0 = expand_normal (treeop0);
1136 if (TREE_CODE (treeop0) == ERROR_MARK)
1cff8964
AE
1137 return;
1138
4df62c77
MM
1139 op1 = expand_normal (treeop1);
1140 if (TREE_CODE (treeop1) == ERROR_MARK)
1cff8964
AE
1141 return;
1142
4df62c77 1143 type = TREE_TYPE (treeop0);
1cff8964 1144 mode = TYPE_MODE (type);
4df62c77
MM
1145 if (TREE_CODE (treeop0) == INTEGER_CST
1146 && (TREE_CODE (treeop1) != INTEGER_CST
1cff8964 1147 || (GET_MODE_BITSIZE (mode)
4df62c77 1148 > GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (treeop1))))))
1cff8964
AE
1149 {
1150 /* op0 might have been replaced by promoted constant, in which
1151 case the type of second argument should be used. */
4df62c77 1152 type = TREE_TYPE (treeop1);
1cff8964
AE
1153 mode = TYPE_MODE (type);
1154 }
8df83eae 1155 unsignedp = TYPE_UNSIGNED (type);
1cff8964
AE
1156 code = unsignedp ? unsigned_code : signed_code;
1157
1158#ifdef HAVE_canonicalize_funcptr_for_compare
1159 /* If function pointers need to be "canonicalized" before they can
b8c26d70
NN
1160 be reliably compared, then canonicalize them.
1161 Only do this if *both* sides of the comparison are function pointers.
1162 If one side isn't, we want a noncanonicalized comparison. See PR
6c6cfbfd 1163 middle-end/17564. */
1cff8964 1164 if (HAVE_canonicalize_funcptr_for_compare
4df62c77
MM
1165 && TREE_CODE (TREE_TYPE (treeop0)) == POINTER_TYPE
1166 && TREE_CODE (TREE_TYPE (TREE_TYPE (treeop0)))
b8c26d70 1167 == FUNCTION_TYPE
4df62c77
MM
1168 && TREE_CODE (TREE_TYPE (treeop1)) == POINTER_TYPE
1169 && TREE_CODE (TREE_TYPE (TREE_TYPE (treeop1)))
b8c26d70 1170 == FUNCTION_TYPE)
1cff8964
AE
1171 {
1172 rtx new_op0 = gen_reg_rtx (mode);
b8c26d70 1173 rtx new_op1 = gen_reg_rtx (mode);
1cff8964
AE
1174
1175 emit_insn (gen_canonicalize_funcptr_for_compare (new_op0, op0));
1176 op0 = new_op0;
1cff8964
AE
1177
1178 emit_insn (gen_canonicalize_funcptr_for_compare (new_op1, op1));
1179 op1 = new_op1;
1180 }
1181#endif
1182
1cff8964
AE
1183 do_compare_rtx_and_jump (op0, op1, code, unsignedp, mode,
1184 ((mode == BLKmode)
4df62c77 1185 ? expr_size (treeop0) : NULL_RTX),
40e90eac 1186 if_false_label, if_true_label, prob);
1cff8964 1187}
dbf833ee
RS
1188
1189#include "gt-dojump.h"