]> gcc.gnu.org Git - gcc.git/blame - gcc/dojump.c
Update copyright years.
[gcc.git] / gcc / dojump.c
CommitLineData
1cff8964 1/* Convert tree expression to rtl instructions, for GNU compiler.
818ab71a 2 Copyright (C) 1988-2016 Free Software Foundation, Inc.
1cff8964
AE
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
9dcd6f09 8Software Foundation; either version 3, or (at your option) any later
1cff8964
AE
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
9dcd6f09
NC
17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
1cff8964
AE
19
20#include "config.h"
21#include "system.h"
22#include "coretypes.h"
c7131fb2 23#include "backend.h"
957060b5 24#include "target.h"
1cff8964
AE
25#include "rtl.h"
26#include "tree.h"
957060b5
AM
27#include "predict.h"
28#include "tm_p.h"
957060b5
AM
29#include "optabs.h"
30#include "emit-rtl.h"
40e23961 31#include "fold-const.h"
d8a2d370 32#include "stor-layout.h"
1cff8964 33/* Include expr.h after insn-config.h so we get HAVE_conditional_move. */
36566b39
PK
34#include "dojump.h"
35#include "explow.h"
1cff8964 36#include "expr.h"
1cff8964
AE
37#include "langhooks.h"
38
ef4bddc2 39static bool prefer_and_bit_test (machine_mode, int);
1476d1bd
MM
40static void do_jump_by_parts_greater (tree, tree, int,
41 rtx_code_label *, rtx_code_label *, int);
42static void do_jump_by_parts_equality (tree, tree, rtx_code_label *,
43 rtx_code_label *, int);
44static void do_compare_and_jump (tree, tree, enum rtx_code, enum rtx_code,
45 rtx_code_label *, rtx_code_label *, int);
40e90eac
JJ
46
47/* Invert probability if there is any. -1 stands for unknown. */
48
49static inline int
50inv (int prob)
51{
52 return prob == -1 ? -1 : REG_BR_PROB_BASE - prob;
53}
1cff8964
AE
54
55/* At the start of a function, record that we have no previously-pushed
56 arguments waiting to be popped. */
57
58void
7080f735 59init_pending_stack_adjust (void)
1cff8964
AE
60{
61 pending_stack_adjust = 0;
62}
63
a494ed43
EB
64/* Discard any pending stack adjustment. This avoid relying on the
65 RTL optimizers to remove useless adjustments when we know the
66 stack pointer value is dead. */
83f676b3
RS
67void
68discard_pending_stack_adjust (void)
a494ed43
EB
69{
70 stack_pointer_delta -= pending_stack_adjust;
71 pending_stack_adjust = 0;
72}
73
1cff8964
AE
74/* When exiting from function, if safe, clear out any pending stack adjust
75 so the adjustment won't get done.
76
77 Note, if the current function calls alloca, then it must have a
78 frame pointer regardless of the value of flag_omit_frame_pointer. */
79
80void
7080f735 81clear_pending_stack_adjust (void)
1cff8964 82{
1cff8964 83 if (optimize > 0
e3b5732b 84 && (! flag_omit_frame_pointer || cfun->calls_alloca)
c37f4ba4 85 && EXIT_IGNORE_STACK)
a494ed43 86 discard_pending_stack_adjust ();
1cff8964
AE
87}
88
89/* Pop any previously-pushed arguments that have not been popped yet. */
90
91void
7080f735 92do_pending_stack_adjust (void)
1cff8964
AE
93{
94 if (inhibit_defer_pop == 0)
95 {
96 if (pending_stack_adjust != 0)
97 adjust_stack (GEN_INT (pending_stack_adjust));
98 pending_stack_adjust = 0;
99 }
100}
7f2f0a01
JJ
101
102/* Remember pending_stack_adjust/stack_pointer_delta.
103 To be used around code that may call do_pending_stack_adjust (),
104 but the generated code could be discarded e.g. using delete_insns_since. */
105
106void
107save_pending_stack_adjust (saved_pending_stack_adjust *save)
108{
109 save->x_pending_stack_adjust = pending_stack_adjust;
110 save->x_stack_pointer_delta = stack_pointer_delta;
111}
112
113/* Restore the saved pending_stack_adjust/stack_pointer_delta. */
114
115void
116restore_pending_stack_adjust (saved_pending_stack_adjust *save)
117{
118 if (inhibit_defer_pop == 0)
119 {
120 pending_stack_adjust = save->x_pending_stack_adjust;
121 stack_pointer_delta = save->x_stack_pointer_delta;
122 }
123}
1cff8964
AE
124\f
125/* Expand conditional expressions. */
126
1476d1bd 127/* Generate code to evaluate EXP and jump to LABEL if the value is zero. */
1cff8964
AE
128
129void
1476d1bd 130jumpifnot (tree exp, rtx_code_label *label, int prob)
1cff8964 131{
1476d1bd 132 do_jump (exp, label, NULL, inv (prob));
1cff8964
AE
133}
134
4df62c77 135void
1476d1bd
MM
136jumpifnot_1 (enum tree_code code, tree op0, tree op1, rtx_code_label *label,
137 int prob)
4df62c77 138{
1476d1bd 139 do_jump_1 (code, op0, op1, label, NULL, inv (prob));
4df62c77
MM
140}
141
1cff8964
AE
142/* Generate code to evaluate EXP and jump to LABEL if the value is nonzero. */
143
144void
1476d1bd 145jumpif (tree exp, rtx_code_label *label, int prob)
1cff8964 146{
1476d1bd 147 do_jump (exp, NULL, label, prob);
1cff8964
AE
148}
149
4df62c77 150void
1476d1bd
MM
151jumpif_1 (enum tree_code code, tree op0, tree op1,
152 rtx_code_label *label, int prob)
4df62c77 153{
1476d1bd 154 do_jump_1 (code, op0, op1, NULL, label, prob);
4df62c77
MM
155}
156
dbf833ee
RS
157/* Used internally by prefer_and_bit_test. */
158
159static GTY(()) rtx and_reg;
160static GTY(()) rtx and_test;
161static GTY(()) rtx shift_test;
162
163/* Compare the relative costs of "(X & (1 << BITNUM))" and "(X >> BITNUM) & 1",
164 where X is an arbitrary register of mode MODE. Return true if the former
165 is preferred. */
166
167static bool
ef4bddc2 168prefer_and_bit_test (machine_mode mode, int bitnum)
dbf833ee 169{
68f932c4 170 bool speed_p;
807e902e 171 wide_int mask = wi::set_bit_in_zero (bitnum, GET_MODE_PRECISION (mode));
68f932c4 172
dbf833ee
RS
173 if (and_test == 0)
174 {
175 /* Set up rtxes for the two variations. Use NULL as a placeholder
176 for the BITNUM-based constants. */
c3dc5e66 177 and_reg = gen_rtx_REG (mode, LAST_VIRTUAL_REGISTER + 1);
dbf833ee
RS
178 and_test = gen_rtx_AND (mode, and_reg, NULL);
179 shift_test = gen_rtx_AND (mode, gen_rtx_ASHIFTRT (mode, and_reg, NULL),
180 const1_rtx);
181 }
182 else
183 {
184 /* Change the mode of the previously-created rtxes. */
185 PUT_MODE (and_reg, mode);
186 PUT_MODE (and_test, mode);
187 PUT_MODE (shift_test, mode);
188 PUT_MODE (XEXP (shift_test, 0), mode);
189 }
190
191 /* Fill in the integers. */
807e902e 192 XEXP (and_test, 1) = immed_wide_int_const (mask, mode);
dbf833ee
RS
193 XEXP (XEXP (shift_test, 0), 1) = GEN_INT (bitnum);
194
68f932c4 195 speed_p = optimize_insn_for_speed_p ();
e548c9df
AM
196 return (rtx_cost (and_test, mode, IF_THEN_ELSE, 0, speed_p)
197 <= rtx_cost (shift_test, mode, IF_THEN_ELSE, 0, speed_p));
dbf833ee
RS
198}
199
4df62c77 200/* Subroutine of do_jump, dealing with exploded comparisons of the type
40e90eac
JJ
201 OP0 CODE OP1 . IF_FALSE_LABEL and IF_TRUE_LABEL like in do_jump.
202 PROB is probability of jump to if_true_label, or -1 if unknown. */
4df62c77
MM
203
204void
205do_jump_1 (enum tree_code code, tree op0, tree op1,
1476d1bd
MM
206 rtx_code_label *if_false_label, rtx_code_label *if_true_label,
207 int prob)
4df62c77 208{
ef4bddc2 209 machine_mode mode;
19f8b229 210 rtx_code_label *drop_through_label = 0;
4df62c77
MM
211
212 switch (code)
213 {
214 case EQ_EXPR:
215 {
216 tree inner_type = TREE_TYPE (op0);
217
218 gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
219 != MODE_COMPLEX_FLOAT);
220 gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
221 != MODE_COMPLEX_INT);
222
223 if (integer_zerop (op1))
40e90eac 224 do_jump (op0, if_true_label, if_false_label, inv (prob));
4df62c77
MM
225 else if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_INT
226 && !can_compare_p (EQ, TYPE_MODE (inner_type), ccp_jump))
40e90eac
JJ
227 do_jump_by_parts_equality (op0, op1, if_false_label, if_true_label,
228 prob);
4df62c77 229 else
40e90eac
JJ
230 do_compare_and_jump (op0, op1, EQ, EQ, if_false_label, if_true_label,
231 prob);
4df62c77
MM
232 break;
233 }
234
235 case NE_EXPR:
236 {
237 tree inner_type = TREE_TYPE (op0);
238
239 gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
240 != MODE_COMPLEX_FLOAT);
241 gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type))
242 != MODE_COMPLEX_INT);
243
244 if (integer_zerop (op1))
40e90eac 245 do_jump (op0, if_false_label, if_true_label, prob);
4df62c77
MM
246 else if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_INT
247 && !can_compare_p (NE, TYPE_MODE (inner_type), ccp_jump))
40e90eac
JJ
248 do_jump_by_parts_equality (op0, op1, if_true_label, if_false_label,
249 inv (prob));
4df62c77 250 else
40e90eac
JJ
251 do_compare_and_jump (op0, op1, NE, NE, if_false_label, if_true_label,
252 prob);
4df62c77
MM
253 break;
254 }
255
256 case LT_EXPR:
257 mode = TYPE_MODE (TREE_TYPE (op0));
258 if (GET_MODE_CLASS (mode) == MODE_INT
259 && ! can_compare_p (LT, mode, ccp_jump))
40e90eac
JJ
260 do_jump_by_parts_greater (op0, op1, 1, if_false_label, if_true_label,
261 prob);
4df62c77 262 else
40e90eac
JJ
263 do_compare_and_jump (op0, op1, LT, LTU, if_false_label, if_true_label,
264 prob);
4df62c77
MM
265 break;
266
267 case LE_EXPR:
268 mode = TYPE_MODE (TREE_TYPE (op0));
269 if (GET_MODE_CLASS (mode) == MODE_INT
270 && ! can_compare_p (LE, mode, ccp_jump))
40e90eac
JJ
271 do_jump_by_parts_greater (op0, op1, 0, if_true_label, if_false_label,
272 inv (prob));
4df62c77 273 else
40e90eac
JJ
274 do_compare_and_jump (op0, op1, LE, LEU, if_false_label, if_true_label,
275 prob);
4df62c77
MM
276 break;
277
278 case GT_EXPR:
279 mode = TYPE_MODE (TREE_TYPE (op0));
280 if (GET_MODE_CLASS (mode) == MODE_INT
281 && ! can_compare_p (GT, mode, ccp_jump))
40e90eac
JJ
282 do_jump_by_parts_greater (op0, op1, 0, if_false_label, if_true_label,
283 prob);
4df62c77 284 else
40e90eac
JJ
285 do_compare_and_jump (op0, op1, GT, GTU, if_false_label, if_true_label,
286 prob);
4df62c77
MM
287 break;
288
289 case GE_EXPR:
290 mode = TYPE_MODE (TREE_TYPE (op0));
291 if (GET_MODE_CLASS (mode) == MODE_INT
292 && ! can_compare_p (GE, mode, ccp_jump))
40e90eac
JJ
293 do_jump_by_parts_greater (op0, op1, 1, if_true_label, if_false_label,
294 inv (prob));
4df62c77 295 else
40e90eac
JJ
296 do_compare_and_jump (op0, op1, GE, GEU, if_false_label, if_true_label,
297 prob);
4df62c77
MM
298 break;
299
300 case ORDERED_EXPR:
301 do_compare_and_jump (op0, op1, ORDERED, ORDERED,
40e90eac 302 if_false_label, if_true_label, prob);
4df62c77
MM
303 break;
304
305 case UNORDERED_EXPR:
306 do_compare_and_jump (op0, op1, UNORDERED, UNORDERED,
40e90eac 307 if_false_label, if_true_label, prob);
4df62c77
MM
308 break;
309
310 case UNLT_EXPR:
40e90eac
JJ
311 do_compare_and_jump (op0, op1, UNLT, UNLT, if_false_label, if_true_label,
312 prob);
4df62c77
MM
313 break;
314
315 case UNLE_EXPR:
40e90eac
JJ
316 do_compare_and_jump (op0, op1, UNLE, UNLE, if_false_label, if_true_label,
317 prob);
4df62c77
MM
318 break;
319
320 case UNGT_EXPR:
40e90eac
JJ
321 do_compare_and_jump (op0, op1, UNGT, UNGT, if_false_label, if_true_label,
322 prob);
4df62c77
MM
323 break;
324
325 case UNGE_EXPR:
40e90eac
JJ
326 do_compare_and_jump (op0, op1, UNGE, UNGE, if_false_label, if_true_label,
327 prob);
4df62c77
MM
328 break;
329
330 case UNEQ_EXPR:
40e90eac
JJ
331 do_compare_and_jump (op0, op1, UNEQ, UNEQ, if_false_label, if_true_label,
332 prob);
4df62c77
MM
333 break;
334
335 case LTGT_EXPR:
40e90eac
JJ
336 do_compare_and_jump (op0, op1, LTGT, LTGT, if_false_label, if_true_label,
337 prob);
4df62c77
MM
338 break;
339
340 case TRUTH_ANDIF_EXPR:
99206ca9
TJ
341 {
342 /* Spread the probability that the expression is false evenly between
343 the two conditions. So the first condition is false half the total
344 probability of being false. The second condition is false the other
345 half of the total probability of being false, so its jump has a false
346 probability of half the total, relative to the probability we
347 reached it (i.e. the first condition was true). */
348 int op0_prob = -1;
349 int op1_prob = -1;
350 if (prob != -1)
351 {
352 int false_prob = inv (prob);
353 int op0_false_prob = false_prob / 2;
354 int op1_false_prob = GCOV_COMPUTE_SCALE ((false_prob / 2),
355 inv (op0_false_prob));
356 /* Get the probability that each jump below is true. */
357 op0_prob = inv (op0_false_prob);
358 op1_prob = inv (op1_false_prob);
359 }
1476d1bd 360 if (if_false_label == NULL)
99206ca9
TJ
361 {
362 drop_through_label = gen_label_rtx ();
1476d1bd
MM
363 do_jump (op0, drop_through_label, NULL, op0_prob);
364 do_jump (op1, NULL, if_true_label, op1_prob);
99206ca9
TJ
365 }
366 else
367 {
1476d1bd 368 do_jump (op0, if_false_label, NULL, op0_prob);
99206ca9
TJ
369 do_jump (op1, if_false_label, if_true_label, op1_prob);
370 }
371 break;
372 }
4df62c77
MM
373
374 case TRUTH_ORIF_EXPR:
99206ca9
TJ
375 {
376 /* Spread the probability evenly between the two conditions. So
377 the first condition has half the total probability of being true.
378 The second condition has the other half of the total probability,
379 so its jump has a probability of half the total, relative to
380 the probability we reached it (i.e. the first condition was false). */
381 int op0_prob = -1;
382 int op1_prob = -1;
383 if (prob != -1)
384 {
385 op0_prob = prob / 2;
386 op1_prob = GCOV_COMPUTE_SCALE ((prob / 2), inv (op0_prob));
1476d1bd
MM
387 }
388 if (if_true_label == NULL)
389 {
390 drop_through_label = gen_label_rtx ();
391 do_jump (op0, NULL, drop_through_label, op0_prob);
392 do_jump (op1, if_false_label, NULL, op1_prob);
393 }
394 else
395 {
396 do_jump (op0, NULL, if_true_label, op0_prob);
397 do_jump (op1, if_false_label, if_true_label, op1_prob);
398 }
99206ca9
TJ
399 break;
400 }
4df62c77
MM
401
402 default:
403 gcc_unreachable ();
404 }
405
406 if (drop_through_label)
407 {
408 do_pending_stack_adjust ();
409 emit_label (drop_through_label);
410 }
411}
412
1cff8964
AE
413/* Generate code to evaluate EXP and jump to IF_FALSE_LABEL if
414 the result is zero, or IF_TRUE_LABEL if the result is one.
415 Either of IF_FALSE_LABEL and IF_TRUE_LABEL may be zero,
416 meaning fall through in that case.
417
418 do_jump always does any pending stack adjust except when it does not
419 actually perform a jump. An example where there is no jump
40e90eac
JJ
420 is when EXP is `(foo (), 0)' and IF_FALSE_LABEL is null.
421
422 PROB is probability of jump to if_true_label, or -1 if unknown. */
1cff8964
AE
423
424void
1476d1bd
MM
425do_jump (tree exp, rtx_code_label *if_false_label,
426 rtx_code_label *if_true_label, int prob)
1cff8964
AE
427{
428 enum tree_code code = TREE_CODE (exp);
1cff8964
AE
429 rtx temp;
430 int i;
431 tree type;
ef4bddc2 432 machine_mode mode;
1476d1bd 433 rtx_code_label *drop_through_label = NULL;
1cff8964 434
1cff8964
AE
435 switch (code)
436 {
437 case ERROR_MARK:
438 break;
439
440 case INTEGER_CST:
1476d1bd
MM
441 {
442 rtx_code_label *lab = integer_zerop (exp) ? if_false_label
443 : if_true_label;
444 if (lab)
445 emit_jump (lab);
446 break;
447 }
1cff8964
AE
448
449#if 0
450 /* This is not true with #pragma weak */
451 case ADDR_EXPR:
452 /* The address of something can never be zero. */
453 if (if_true_label)
454 emit_jump (if_true_label);
455 break;
456#endif
457
458 case NOP_EXPR:
459 if (TREE_CODE (TREE_OPERAND (exp, 0)) == COMPONENT_REF
460 || TREE_CODE (TREE_OPERAND (exp, 0)) == BIT_FIELD_REF
461 || TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_REF
462 || TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_RANGE_REF)
463 goto normal;
464 case CONVERT_EXPR:
465 /* If we are narrowing the operand, we have to do the compare in the
466 narrower mode. */
467 if ((TYPE_PRECISION (TREE_TYPE (exp))
468 < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0)))))
469 goto normal;
470 case NON_LVALUE_EXPR:
1cff8964
AE
471 case ABS_EXPR:
472 case NEGATE_EXPR:
473 case LROTATE_EXPR:
474 case RROTATE_EXPR:
475 /* These cannot change zero->nonzero or vice versa. */
40e90eac 476 do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label, prob);
1cff8964
AE
477 break;
478
1cff8964 479 case TRUTH_NOT_EXPR:
8ac074e8
JJ
480 do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label,
481 inv (prob));
1cff8964
AE
482 break;
483
8ea9d0c7
PB
484 case COND_EXPR:
485 {
19f8b229 486 rtx_code_label *label1 = gen_label_rtx ();
8ea9d0c7
PB
487 if (!if_true_label || !if_false_label)
488 {
489 drop_through_label = gen_label_rtx ();
490 if (!if_true_label)
491 if_true_label = drop_through_label;
492 if (!if_false_label)
493 if_false_label = drop_through_label;
494 }
495
496 do_pending_stack_adjust ();
1476d1bd 497 do_jump (TREE_OPERAND (exp, 0), label1, NULL, -1);
40e90eac 498 do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label, prob);
8ea9d0c7 499 emit_label (label1);
40e90eac 500 do_jump (TREE_OPERAND (exp, 2), if_false_label, if_true_label, prob);
8ea9d0c7
PB
501 break;
502 }
503
1cff8964 504 case COMPOUND_EXPR:
7c27e184 505 /* Lowered by gimplify.c. */
ced3f397 506 gcc_unreachable ();
1cff8964 507
0b04d281
DE
508 case MINUS_EXPR:
509 /* Nonzero iff operands of minus differ. */
4df62c77
MM
510 code = NE_EXPR;
511
0b04d281 512 /* FALLTHRU */
4df62c77 513 case EQ_EXPR:
1cff8964 514 case NE_EXPR:
1cff8964 515 case LT_EXPR:
1cff8964 516 case LE_EXPR:
1cff8964 517 case GT_EXPR:
1cff8964 518 case GE_EXPR:
1cff8964 519 case ORDERED_EXPR:
337e5d98 520 case UNORDERED_EXPR:
337e5d98 521 case UNLT_EXPR:
337e5d98 522 case UNLE_EXPR:
337e5d98 523 case UNGT_EXPR:
337e5d98 524 case UNGE_EXPR:
337e5d98 525 case UNEQ_EXPR:
337e5d98 526 case LTGT_EXPR:
4df62c77
MM
527 case TRUTH_ANDIF_EXPR:
528 case TRUTH_ORIF_EXPR:
c3223baf 529 other_code:
4df62c77 530 do_jump_1 (code, TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
40e90eac 531 if_false_label, if_true_label, prob);
1cff8964 532 break;
30821654
PB
533
534 case BIT_AND_EXPR:
535 /* fold_single_bit_test() converts (X & (1 << C)) into (X >> C) & 1.
536 See if the former is preferred for jump tests and restore it
537 if so. */
538 if (integer_onep (TREE_OPERAND (exp, 1)))
539 {
540 tree exp0 = TREE_OPERAND (exp, 0);
1476d1bd 541 rtx_code_label *set_label, *clr_label;
40e90eac 542 int setclr_prob = prob;
30821654
PB
543
544 /* Strip narrowing integral type conversions. */
545 while (CONVERT_EXPR_P (exp0)
546 && TREE_OPERAND (exp0, 0) != error_mark_node
547 && TYPE_PRECISION (TREE_TYPE (exp0))
548 <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp0, 0))))
549 exp0 = TREE_OPERAND (exp0, 0);
550
551 /* "exp0 ^ 1" inverts the sense of the single bit test. */
552 if (TREE_CODE (exp0) == BIT_XOR_EXPR
553 && integer_onep (TREE_OPERAND (exp0, 1)))
554 {
555 exp0 = TREE_OPERAND (exp0, 0);
556 clr_label = if_true_label;
557 set_label = if_false_label;
40e90eac 558 setclr_prob = inv (prob);
30821654
PB
559 }
560 else
561 {
562 clr_label = if_false_label;
563 set_label = if_true_label;
564 }
565
566 if (TREE_CODE (exp0) == RSHIFT_EXPR)
567 {
568 tree arg = TREE_OPERAND (exp0, 0);
569 tree shift = TREE_OPERAND (exp0, 1);
570 tree argtype = TREE_TYPE (arg);
571 if (TREE_CODE (shift) == INTEGER_CST
572 && compare_tree_int (shift, 0) >= 0
573 && compare_tree_int (shift, HOST_BITS_PER_WIDE_INT) < 0
574 && prefer_and_bit_test (TYPE_MODE (argtype),
575 TREE_INT_CST_LOW (shift)))
576 {
472e0df9
JJ
577 unsigned HOST_WIDE_INT mask
578 = (unsigned HOST_WIDE_INT) 1 << TREE_INT_CST_LOW (shift);
30821654 579 do_jump (build2 (BIT_AND_EXPR, argtype, arg,
1961ffb8 580 build_int_cstu (argtype, mask)),
40e90eac 581 clr_label, set_label, setclr_prob);
30821654
PB
582 break;
583 }
584 }
585 }
586
587 /* If we are AND'ing with a small constant, do this comparison in the
588 smallest type that fits. If the machine doesn't have comparisons
589 that small, it will be converted back to the wider comparison.
590 This helps if we are testing the sign bit of a narrower object.
591 combine can't do this for us because it can't know whether a
592 ZERO_EXTRACT or a compare in a smaller mode exists, but we do. */
593
594 if (! SLOW_BYTE_ACCESS
595 && TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST
596 && TYPE_PRECISION (TREE_TYPE (exp)) <= HOST_BITS_PER_WIDE_INT
597 && (i = tree_floor_log2 (TREE_OPERAND (exp, 1))) >= 0
598 && (mode = mode_for_size (i + 1, MODE_INT, 0)) != BLKmode
599 && (type = lang_hooks.types.type_for_mode (mode, 1)) != 0
600 && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (exp))
fedc1775 601 && have_insn_for (COMPARE, TYPE_MODE (type)))
30821654 602 {
40e90eac
JJ
603 do_jump (fold_convert (type, exp), if_false_label, if_true_label,
604 prob);
30821654
PB
605 break;
606 }
607
608 if (TYPE_PRECISION (TREE_TYPE (exp)) > 1
609 || TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST)
610 goto normal;
611
612 /* Boolean comparisons can be compiled as TRUTH_AND_EXPR. */
1cff8964 613
d1f36c51 614 case TRUTH_AND_EXPR:
97191ef9
PB
615 /* High branch cost, expand as the bitwise AND of the conditions.
616 Do the same if the RHS has side effects, because we're effectively
617 turning a TRUTH_AND_EXPR into a TRUTH_ANDIF_EXPR. */
3a4fd356
JH
618 if (BRANCH_COST (optimize_insn_for_speed_p (),
619 false) >= 4
620 || TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 1)))
d1f36c51 621 goto normal;
c3223baf
MM
622 code = TRUTH_ANDIF_EXPR;
623 goto other_code;
d1f36c51 624
30821654 625 case BIT_IOR_EXPR:
d1f36c51 626 case TRUTH_OR_EXPR:
97191ef9
PB
627 /* High branch cost, expand as the bitwise OR of the conditions.
628 Do the same if the RHS has side effects, because we're effectively
629 turning a TRUTH_OR_EXPR into a TRUTH_ORIF_EXPR. */
40e90eac 630 if (BRANCH_COST (optimize_insn_for_speed_p (), false) >= 4
3a4fd356 631 || TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 1)))
d1f36c51 632 goto normal;
c3223baf
MM
633 code = TRUTH_ORIF_EXPR;
634 goto other_code;
d1f36c51 635
938d968e 636 /* Fall through and generate the normal code. */
1cff8964
AE
637 default:
638 normal:
84217346 639 temp = expand_normal (exp);
1cff8964 640 do_pending_stack_adjust ();
feb04780
RS
641 /* The RTL optimizers prefer comparisons against pseudos. */
642 if (GET_CODE (temp) == SUBREG)
9311f3f6 643 {
feb04780
RS
644 /* Compare promoted variables in their promoted mode. */
645 if (SUBREG_PROMOTED_VAR_P (temp)
646 && REG_P (XEXP (temp, 0)))
647 temp = XEXP (temp, 0);
648 else
649 temp = copy_to_reg (temp);
9311f3f6 650 }
feb04780
RS
651 do_compare_rtx_and_jump (temp, CONST0_RTX (GET_MODE (temp)),
652 NE, TYPE_UNSIGNED (TREE_TYPE (exp)),
653 GET_MODE (temp), NULL_RTX,
40e90eac 654 if_false_label, if_true_label, prob);
1cff8964 655 }
8ea9d0c7
PB
656
657 if (drop_through_label)
658 {
659 do_pending_stack_adjust ();
660 emit_label (drop_through_label);
661 }
1cff8964
AE
662}
663\f
1cff8964
AE
664/* Compare OP0 with OP1, word at a time, in mode MODE.
665 UNSIGNEDP says to do unsigned comparison.
666 Jump to IF_TRUE_LABEL if OP0 is greater, IF_FALSE_LABEL otherwise. */
667
3bf78d3b 668static void
ef4bddc2 669do_jump_by_parts_greater_rtx (machine_mode mode, int unsignedp, rtx op0,
1476d1bd
MM
670 rtx op1, rtx_code_label *if_false_label,
671 rtx_code_label *if_true_label,
40e90eac 672 int prob)
1cff8964
AE
673{
674 int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
1476d1bd 675 rtx_code_label *drop_through_label = 0;
c8679567
EB
676 bool drop_through_if_true = false, drop_through_if_false = false;
677 enum rtx_code code = GT;
1cff8964
AE
678 int i;
679
680 if (! if_true_label || ! if_false_label)
681 drop_through_label = gen_label_rtx ();
682 if (! if_true_label)
c8679567
EB
683 {
684 if_true_label = drop_through_label;
685 drop_through_if_true = true;
686 }
1cff8964 687 if (! if_false_label)
c8679567
EB
688 {
689 if_false_label = drop_through_label;
690 drop_through_if_false = true;
691 }
692
693 /* Deal with the special case 0 > x: only one comparison is necessary and
694 we reverse it to avoid jumping to the drop-through label. */
695 if (op0 == const0_rtx && drop_through_if_true && !drop_through_if_false)
696 {
697 code = LE;
698 if_true_label = if_false_label;
699 if_false_label = drop_through_label;
700 drop_through_if_true = false;
701 drop_through_if_false = true;
702 }
1cff8964
AE
703
704 /* Compare a word at a time, high order first. */
705 for (i = 0; i < nwords; i++)
706 {
707 rtx op0_word, op1_word;
708
709 if (WORDS_BIG_ENDIAN)
710 {
711 op0_word = operand_subword_force (op0, i, mode);
712 op1_word = operand_subword_force (op1, i, mode);
713 }
714 else
715 {
716 op0_word = operand_subword_force (op0, nwords - 1 - i, mode);
717 op1_word = operand_subword_force (op1, nwords - 1 - i, mode);
718 }
719
720 /* All but high-order word must be compared as unsigned. */
c8679567 721 do_compare_rtx_and_jump (op0_word, op1_word, code, (unsignedp || i > 0),
1476d1bd 722 word_mode, NULL_RTX, NULL, if_true_label,
c8679567
EB
723 prob);
724
725 /* Emit only one comparison for 0. Do not emit the last cond jump. */
726 if (op0 == const0_rtx || i == nwords - 1)
727 break;
1cff8964
AE
728
729 /* Consider lower words only if these are equal. */
730 do_compare_rtx_and_jump (op0_word, op1_word, NE, unsignedp, word_mode,
1476d1bd 731 NULL_RTX, NULL, if_false_label, inv (prob));
1cff8964
AE
732 }
733
c8679567 734 if (!drop_through_if_false)
1cff8964
AE
735 emit_jump (if_false_label);
736 if (drop_through_label)
737 emit_label (drop_through_label);
738}
3bf78d3b
RS
739
740/* Given a comparison expression EXP for values too wide to be compared
741 with one insn, test the comparison and jump to the appropriate label.
742 The code of EXP is ignored; we always test GT if SWAP is 0,
743 and LT if SWAP is 1. */
744
745static void
4df62c77 746do_jump_by_parts_greater (tree treeop0, tree treeop1, int swap,
1476d1bd
MM
747 rtx_code_label *if_false_label,
748 rtx_code_label *if_true_label, int prob)
3bf78d3b 749{
4df62c77
MM
750 rtx op0 = expand_normal (swap ? treeop1 : treeop0);
751 rtx op1 = expand_normal (swap ? treeop0 : treeop1);
ef4bddc2 752 machine_mode mode = TYPE_MODE (TREE_TYPE (treeop0));
4df62c77 753 int unsignedp = TYPE_UNSIGNED (TREE_TYPE (treeop0));
3bf78d3b
RS
754
755 do_jump_by_parts_greater_rtx (mode, unsignedp, op0, op1, if_false_label,
40e90eac 756 if_true_label, prob);
3bf78d3b 757}
1cff8964 758\f
feb04780
RS
759/* Jump according to whether OP0 is 0. We assume that OP0 has an integer
760 mode, MODE, that is too wide for the available compare insns. Either
1476d1bd 761 Either (but not both) of IF_TRUE_LABEL and IF_FALSE_LABEL may be NULL
feb04780 762 to indicate drop through. */
1cff8964 763
feb04780 764static void
ef4bddc2 765do_jump_by_parts_zero_rtx (machine_mode mode, rtx op0,
1476d1bd
MM
766 rtx_code_label *if_false_label,
767 rtx_code_label *if_true_label, int prob)
1cff8964 768{
feb04780 769 int nwords = GET_MODE_SIZE (mode) / UNITS_PER_WORD;
1cff8964
AE
770 rtx part;
771 int i;
1476d1bd 772 rtx_code_label *drop_through_label = NULL;
1cff8964
AE
773
774 /* The fastest way of doing this comparison on almost any machine is to
775 "or" all the words and compare the result. If all have to be loaded
776 from memory and this is a very wide item, it's possible this may
777 be slower, but that's highly unlikely. */
778
779 part = gen_reg_rtx (word_mode);
0a49e5c2 780 emit_move_insn (part, operand_subword_force (op0, 0, mode));
1cff8964
AE
781 for (i = 1; i < nwords && part != 0; i++)
782 part = expand_binop (word_mode, ior_optab, part,
0a49e5c2 783 operand_subword_force (op0, i, mode),
1cff8964
AE
784 part, 1, OPTAB_WIDEN);
785
786 if (part != 0)
787 {
788 do_compare_rtx_and_jump (part, const0_rtx, EQ, 1, word_mode,
40e90eac 789 NULL_RTX, if_false_label, if_true_label, prob);
1cff8964
AE
790 return;
791 }
792
793 /* If we couldn't do the "or" simply, do this with a series of compares. */
794 if (! if_false_label)
1476d1bd 795 if_false_label = drop_through_label = gen_label_rtx ();
1cff8964
AE
796
797 for (i = 0; i < nwords; i++)
0a49e5c2 798 do_compare_rtx_and_jump (operand_subword_force (op0, i, mode),
1cff8964 799 const0_rtx, EQ, 1, word_mode, NULL_RTX,
1476d1bd 800 if_false_label, NULL, prob);
1cff8964
AE
801
802 if (if_true_label)
803 emit_jump (if_true_label);
804
805 if (drop_through_label)
806 emit_label (drop_through_label);
807}
feb04780
RS
808
809/* Test for the equality of two RTX expressions OP0 and OP1 in mode MODE,
810 where MODE is an integer mode too wide to be compared with one insn.
811 Either (but not both) of IF_TRUE_LABEL and IF_FALSE_LABEL may be NULL_RTX
812 to indicate drop through. */
813
814static void
ef4bddc2 815do_jump_by_parts_equality_rtx (machine_mode mode, rtx op0, rtx op1,
1476d1bd
MM
816 rtx_code_label *if_false_label,
817 rtx_code_label *if_true_label, int prob)
feb04780
RS
818{
819 int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
1476d1bd 820 rtx_code_label *drop_through_label = NULL;
feb04780
RS
821 int i;
822
823 if (op1 == const0_rtx)
824 {
40e90eac
JJ
825 do_jump_by_parts_zero_rtx (mode, op0, if_false_label, if_true_label,
826 prob);
feb04780
RS
827 return;
828 }
829 else if (op0 == const0_rtx)
830 {
40e90eac
JJ
831 do_jump_by_parts_zero_rtx (mode, op1, if_false_label, if_true_label,
832 prob);
feb04780
RS
833 return;
834 }
835
836 if (! if_false_label)
837 drop_through_label = if_false_label = gen_label_rtx ();
838
839 for (i = 0; i < nwords; i++)
840 do_compare_rtx_and_jump (operand_subword_force (op0, i, mode),
841 operand_subword_force (op1, i, mode),
842 EQ, 0, word_mode, NULL_RTX,
1476d1bd 843 if_false_label, NULL, prob);
feb04780
RS
844
845 if (if_true_label)
846 emit_jump (if_true_label);
847 if (drop_through_label)
848 emit_label (drop_through_label);
849}
850
851/* Given an EQ_EXPR expression EXP for values too wide to be compared
852 with one insn, test the comparison and jump to the appropriate label. */
853
854static void
1476d1bd
MM
855do_jump_by_parts_equality (tree treeop0, tree treeop1,
856 rtx_code_label *if_false_label,
857 rtx_code_label *if_true_label, int prob)
feb04780 858{
4df62c77
MM
859 rtx op0 = expand_normal (treeop0);
860 rtx op1 = expand_normal (treeop1);
ef4bddc2 861 machine_mode mode = TYPE_MODE (TREE_TYPE (treeop0));
feb04780 862 do_jump_by_parts_equality_rtx (mode, op0, op1, if_false_label,
40e90eac 863 if_true_label, prob);
feb04780 864}
1cff8964 865\f
337e5d98
PB
866/* Split a comparison into two others, the second of which has the other
867 "orderedness". The first is always ORDERED or UNORDERED if MODE
868 does not honor NaNs (which means that it can be skipped in that case;
869 see do_compare_rtx_and_jump).
870
871 The two conditions are written in *CODE1 and *CODE2. Return true if
872 the conditions must be ANDed, false if they must be ORed. */
873
874bool
ef4bddc2 875split_comparison (enum rtx_code code, machine_mode mode,
337e5d98
PB
876 enum rtx_code *code1, enum rtx_code *code2)
877{
878 switch (code)
879 {
880 case LT:
881 *code1 = ORDERED;
882 *code2 = UNLT;
883 return true;
884 case LE:
885 *code1 = ORDERED;
886 *code2 = UNLE;
887 return true;
888 case GT:
889 *code1 = ORDERED;
890 *code2 = UNGT;
891 return true;
892 case GE:
893 *code1 = ORDERED;
894 *code2 = UNGE;
895 return true;
896 case EQ:
897 *code1 = ORDERED;
898 *code2 = UNEQ;
899 return true;
900 case NE:
901 *code1 = UNORDERED;
902 *code2 = LTGT;
903 return false;
904 case UNLT:
905 *code1 = UNORDERED;
906 *code2 = LT;
907 return false;
908 case UNLE:
909 *code1 = UNORDERED;
910 *code2 = LE;
911 return false;
912 case UNGT:
913 *code1 = UNORDERED;
914 *code2 = GT;
915 return false;
916 case UNGE:
917 *code1 = UNORDERED;
918 *code2 = GE;
919 return false;
920 case UNEQ:
921 *code1 = UNORDERED;
922 *code2 = EQ;
923 return false;
924 case LTGT:
925 /* Do not turn a trapping comparison into a non-trapping one. */
926 if (HONOR_SNANS (mode))
927 {
928 *code1 = LT;
929 *code2 = GT;
930 return false;
931 }
932 else
933 {
934 *code1 = ORDERED;
935 *code2 = NE;
936 return true;
937 }
938 default:
939 gcc_unreachable ();
940 }
941}
942
943
1cff8964
AE
944/* Like do_compare_and_jump but expects the values to compare as two rtx's.
945 The decision as to signed or unsigned comparison must be made by the caller.
946
947 If MODE is BLKmode, SIZE is an RTX giving the size of the objects being
948 compared. */
949
950void
7080f735 951do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
1476d1bd
MM
952 machine_mode mode, rtx size,
953 rtx_code_label *if_false_label,
954 rtx_code_label *if_true_label, int prob)
1cff8964 955{
1cff8964 956 rtx tem;
1476d1bd 957 rtx_code_label *dummy_label = NULL;
1cff8964
AE
958
959 /* Reverse the comparison if that is safe and we want to jump if it is
337e5d98
PB
960 false. Also convert to the reverse comparison if the target can
961 implement it. */
962 if ((! if_true_label
963 || ! can_compare_p (code, mode, ccp_jump))
964 && (! FLOAT_MODE_P (mode)
965 || code == ORDERED || code == UNORDERED
966 || (! HONOR_NANS (mode) && (code == LTGT || code == UNEQ))
967 || (! HONOR_SNANS (mode) && (code == EQ || code == NE))))
1cff8964 968 {
337e5d98
PB
969 enum rtx_code rcode;
970 if (FLOAT_MODE_P (mode))
971 rcode = reverse_condition_maybe_unordered (code);
972 else
973 rcode = reverse_condition (code);
974
975 /* Canonicalize to UNORDERED for the libcall. */
976 if (can_compare_p (rcode, mode, ccp_jump)
977 || (code == ORDERED && ! can_compare_p (ORDERED, mode, ccp_jump)))
978 {
00c1cf38 979 std::swap (if_true_label, if_false_label);
337e5d98 980 code = rcode;
40e90eac 981 prob = inv (prob);
337e5d98 982 }
1cff8964
AE
983 }
984
985 /* If one operand is constant, make it the second one. Only do this
986 if the other operand is not constant as well. */
987
988 if (swap_commutative_operands_p (op0, op1))
989 {
00c1cf38 990 std::swap (op0, op1);
1cff8964
AE
991 code = swap_condition (code);
992 }
993
1cff8964
AE
994 do_pending_stack_adjust ();
995
c6fb08ad
PB
996 code = unsignedp ? unsigned_condition (code) : code;
997 if (0 != (tem = simplify_relational_operation (code, mode, VOIDmode,
998 op0, op1)))
1cff8964 999 {
c6fb08ad
PB
1000 if (CONSTANT_P (tem))
1001 {
1476d1bd
MM
1002 rtx_code_label *label = (tem == const0_rtx
1003 || tem == CONST0_RTX (mode))
1004 ? if_false_label : if_true_label;
c6fb08ad
PB
1005 if (label)
1006 emit_jump (label);
1007 return;
1008 }
1cff8964 1009
c6fb08ad
PB
1010 code = GET_CODE (tem);
1011 mode = GET_MODE (tem);
1012 op0 = XEXP (tem, 0);
1013 op1 = XEXP (tem, 1);
1014 unsignedp = (code == GTU || code == LTU || code == GEU || code == LEU);
1cff8964 1015 }
1cff8964
AE
1016
1017 if (! if_true_label)
337e5d98 1018 dummy_label = if_true_label = gen_label_rtx ();
1cff8964 1019
feb04780
RS
1020 if (GET_MODE_CLASS (mode) == MODE_INT
1021 && ! can_compare_p (code, mode, ccp_jump))
1022 {
1023 switch (code)
1024 {
1025 case LTU:
1026 do_jump_by_parts_greater_rtx (mode, 1, op1, op0,
40e90eac 1027 if_false_label, if_true_label, prob);
feb04780
RS
1028 break;
1029
1030 case LEU:
1031 do_jump_by_parts_greater_rtx (mode, 1, op0, op1,
40e90eac
JJ
1032 if_true_label, if_false_label,
1033 inv (prob));
feb04780
RS
1034 break;
1035
fb9c6d49
RS
1036 case GTU:
1037 do_jump_by_parts_greater_rtx (mode, 1, op0, op1,
40e90eac 1038 if_false_label, if_true_label, prob);
fb9c6d49
RS
1039 break;
1040
1041 case GEU:
1042 do_jump_by_parts_greater_rtx (mode, 1, op1, op0,
40e90eac
JJ
1043 if_true_label, if_false_label,
1044 inv (prob));
fb9c6d49
RS
1045 break;
1046
feb04780
RS
1047 case LT:
1048 do_jump_by_parts_greater_rtx (mode, 0, op1, op0,
40e90eac 1049 if_false_label, if_true_label, prob);
feb04780
RS
1050 break;
1051
1dc5d842
RS
1052 case LE:
1053 do_jump_by_parts_greater_rtx (mode, 0, op0, op1,
40e90eac
JJ
1054 if_true_label, if_false_label,
1055 inv (prob));
1dc5d842
RS
1056 break;
1057
feb04780
RS
1058 case GT:
1059 do_jump_by_parts_greater_rtx (mode, 0, op0, op1,
40e90eac 1060 if_false_label, if_true_label, prob);
feb04780
RS
1061 break;
1062
1063 case GE:
1064 do_jump_by_parts_greater_rtx (mode, 0, op1, op0,
40e90eac
JJ
1065 if_true_label, if_false_label,
1066 inv (prob));
feb04780
RS
1067 break;
1068
1069 case EQ:
1070 do_jump_by_parts_equality_rtx (mode, op0, op1, if_false_label,
40e90eac 1071 if_true_label, prob);
feb04780
RS
1072 break;
1073
1074 case NE:
1075 do_jump_by_parts_equality_rtx (mode, op0, op1, if_true_label,
40e90eac 1076 if_false_label, inv (prob));
feb04780
RS
1077 break;
1078
1079 default:
1080 gcc_unreachable ();
1081 }
1082 }
1083 else
337e5d98 1084 {
16e0be9b 1085 if (SCALAR_FLOAT_MODE_P (mode)
337e5d98 1086 && ! can_compare_p (code, mode, ccp_jump)
45475a3f
PB
1087 && can_compare_p (swap_condition (code), mode, ccp_jump))
1088 {
45475a3f 1089 code = swap_condition (code);
fab27f52 1090 std::swap (op0, op1);
45475a3f 1091 }
16e0be9b 1092 else if (SCALAR_FLOAT_MODE_P (mode)
45475a3f 1093 && ! can_compare_p (code, mode, ccp_jump)
2225b9f2
RH
1094 /* Never split ORDERED and UNORDERED.
1095 These must be implemented. */
45475a3f 1096 && (code != ORDERED && code != UNORDERED)
2225b9f2
RH
1097 /* Split a floating-point comparison if
1098 we can jump on other conditions... */
45475a3f 1099 && (have_insn_for (COMPARE, mode)
45475a3f 1100 /* ... or if there is no libcall for it. */
19b5fafb 1101 || code_to_optab (code) == unknown_optab))
337e5d98
PB
1102 {
1103 enum rtx_code first_code;
1104 bool and_them = split_comparison (code, mode, &first_code, &code);
1105
1106 /* If there are no NaNs, the first comparison should always fall
1107 through. */
1108 if (!HONOR_NANS (mode))
1109 gcc_assert (first_code == (and_them ? ORDERED : UNORDERED));
1110
1111 else
1112 {
a0dbf285
DC
1113 int first_prob = prob;
1114 if (first_code == UNORDERED)
1115 first_prob = REG_BR_PROB_BASE / 100;
1116 else if (first_code == ORDERED)
1117 first_prob = REG_BR_PROB_BASE - REG_BR_PROB_BASE / 100;
337e5d98
PB
1118 if (and_them)
1119 {
1476d1bd 1120 rtx_code_label *dest_label;
337e5d98
PB
1121 /* If we only jump if true, just bypass the second jump. */
1122 if (! if_false_label)
1123 {
1124 if (! dummy_label)
1125 dummy_label = gen_label_rtx ();
1126 dest_label = dummy_label;
1127 }
1128 else
1129 dest_label = if_false_label;
1130 do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode,
1476d1bd 1131 size, dest_label, NULL, first_prob);
337e5d98
PB
1132 }
1133 else
1134 do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode,
1476d1bd 1135 size, NULL, if_true_label, first_prob);
337e5d98
PB
1136 }
1137 }
1138
1139 emit_cmp_and_jump_insns (op0, op1, code, size, mode, unsignedp,
a4da41e1 1140 if_true_label, prob);
337e5d98 1141 }
1cff8964
AE
1142
1143 if (if_false_label)
1144 emit_jump (if_false_label);
337e5d98
PB
1145 if (dummy_label)
1146 emit_label (dummy_label);
1cff8964
AE
1147}
1148
1149/* Generate code for a comparison expression EXP (including code to compute
1150 the values to be compared) and a conditional jump to IF_FALSE_LABEL and/or
1151 IF_TRUE_LABEL. One of the labels can be NULL_RTX, in which case the
1152 generated code will drop through.
1153 SIGNED_CODE should be the rtx operation for this comparison for
1154 signed data; UNSIGNED_CODE, likewise for use if data is unsigned.
1155
1156 We force a stack adjustment unless there are currently
1157 things pushed on the stack that aren't yet used. */
1158
1159static void
4df62c77 1160do_compare_and_jump (tree treeop0, tree treeop1, enum rtx_code signed_code,
1476d1bd
MM
1161 enum rtx_code unsigned_code,
1162 rtx_code_label *if_false_label,
1163 rtx_code_label *if_true_label, int prob)
1cff8964
AE
1164{
1165 rtx op0, op1;
1166 tree type;
ef4bddc2 1167 machine_mode mode;
1cff8964
AE
1168 int unsignedp;
1169 enum rtx_code code;
1170
1171 /* Don't crash if the comparison was erroneous. */
4df62c77
MM
1172 op0 = expand_normal (treeop0);
1173 if (TREE_CODE (treeop0) == ERROR_MARK)
1cff8964
AE
1174 return;
1175
4df62c77
MM
1176 op1 = expand_normal (treeop1);
1177 if (TREE_CODE (treeop1) == ERROR_MARK)
1cff8964
AE
1178 return;
1179
4df62c77 1180 type = TREE_TYPE (treeop0);
1cff8964 1181 mode = TYPE_MODE (type);
4df62c77
MM
1182 if (TREE_CODE (treeop0) == INTEGER_CST
1183 && (TREE_CODE (treeop1) != INTEGER_CST
1cff8964 1184 || (GET_MODE_BITSIZE (mode)
4df62c77 1185 > GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (treeop1))))))
1cff8964
AE
1186 {
1187 /* op0 might have been replaced by promoted constant, in which
1188 case the type of second argument should be used. */
4df62c77 1189 type = TREE_TYPE (treeop1);
1cff8964
AE
1190 mode = TYPE_MODE (type);
1191 }
8df83eae 1192 unsignedp = TYPE_UNSIGNED (type);
1cff8964
AE
1193 code = unsignedp ? unsigned_code : signed_code;
1194
1cff8964 1195 /* If function pointers need to be "canonicalized" before they can
b8c26d70
NN
1196 be reliably compared, then canonicalize them.
1197 Only do this if *both* sides of the comparison are function pointers.
1198 If one side isn't, we want a noncanonicalized comparison. See PR
6c6cfbfd 1199 middle-end/17564. */
582554e3 1200 if (targetm.have_canonicalize_funcptr_for_compare ()
a89905fd
JDA
1201 && POINTER_TYPE_P (TREE_TYPE (treeop0))
1202 && POINTER_TYPE_P (TREE_TYPE (treeop1))
1203 && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (treeop0)))
1204 && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (treeop1))))
1cff8964
AE
1205 {
1206 rtx new_op0 = gen_reg_rtx (mode);
b8c26d70 1207 rtx new_op1 = gen_reg_rtx (mode);
1cff8964 1208
582554e3 1209 emit_insn (targetm.gen_canonicalize_funcptr_for_compare (new_op0, op0));
1cff8964 1210 op0 = new_op0;
1cff8964 1211
582554e3 1212 emit_insn (targetm.gen_canonicalize_funcptr_for_compare (new_op1, op1));
1cff8964
AE
1213 op1 = new_op1;
1214 }
1cff8964 1215
1cff8964
AE
1216 do_compare_rtx_and_jump (op0, op1, code, unsignedp, mode,
1217 ((mode == BLKmode)
4df62c77 1218 ? expr_size (treeop0) : NULL_RTX),
40e90eac 1219 if_false_label, if_true_label, prob);
1cff8964 1220}
dbf833ee
RS
1221
1222#include "gt-dojump.h"
This page took 3.66246 seconds and 5 git commands to generate.