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