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