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