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