File: | build/gcc/machmode.h |
Warning: | line 421, column 60 Undefined or garbage value returned to caller |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* Rtl-level induction variable analysis. | ||||
2 | Copyright (C) 2004-2021 Free Software Foundation, Inc. | ||||
3 | |||||
4 | This file is part of GCC. | ||||
5 | |||||
6 | GCC is free software; you can redistribute it and/or modify it | ||||
7 | under the terms of the GNU General Public License as published by the | ||||
8 | Free Software Foundation; either version 3, or (at your option) any | ||||
9 | later version. | ||||
10 | |||||
11 | GCC is distributed in the hope that it will be useful, but WITHOUT | ||||
12 | ANY 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 | /* This is a simple analysis of induction variables of the loop. The major use | ||||
21 | is for determining the number of iterations of a loop for loop unrolling, | ||||
22 | doloop optimization and branch prediction. The iv information is computed | ||||
23 | on demand. | ||||
24 | |||||
25 | Induction variables are analyzed by walking the use-def chains. When | ||||
26 | a basic induction variable (biv) is found, it is cached in the bivs | ||||
27 | hash table. When register is proved to be a biv, its description | ||||
28 | is stored to DF_REF_DATA of the def reference. | ||||
29 | |||||
30 | The analysis works always with one loop -- you must call | ||||
31 | iv_analysis_loop_init (loop) for it. All the other functions then work with | ||||
32 | this loop. When you need to work with another loop, just call | ||||
33 | iv_analysis_loop_init for it. When you no longer need iv analysis, call | ||||
34 | iv_analysis_done () to clean up the memory. | ||||
35 | |||||
36 | The available functions are: | ||||
37 | |||||
38 | iv_analyze (insn, mode, reg, iv): Stores the description of the induction | ||||
39 | variable corresponding to the use of register REG in INSN to IV, given | ||||
40 | that REG has mode MODE. Returns true if REG is an induction variable | ||||
41 | in INSN. false otherwise. If a use of REG is not found in INSN, | ||||
42 | the following insns are scanned (so that we may call this function | ||||
43 | on insns returned by get_condition). | ||||
44 | iv_analyze_result (insn, def, iv): Stores to IV the description of the iv | ||||
45 | corresponding to DEF, which is a register defined in INSN. | ||||
46 | iv_analyze_expr (insn, mode, expr, iv): Stores to IV the description of iv | ||||
47 | corresponding to expression EXPR evaluated at INSN. All registers used by | ||||
48 | EXPR must also be used in INSN. MODE is the mode of EXPR. | ||||
49 | */ | ||||
50 | |||||
51 | #include "config.h" | ||||
52 | #include "system.h" | ||||
53 | #include "coretypes.h" | ||||
54 | #include "backend.h" | ||||
55 | #include "rtl.h" | ||||
56 | #include "df.h" | ||||
57 | #include "memmodel.h" | ||||
58 | #include "emit-rtl.h" | ||||
59 | #include "diagnostic-core.h" | ||||
60 | #include "cfgloop.h" | ||||
61 | #include "intl.h" | ||||
62 | #include "dumpfile.h" | ||||
63 | #include "rtl-iter.h" | ||||
64 | #include "tree-ssa-loop-niter.h" | ||||
65 | #include "regs.h" | ||||
66 | #include "function-abi.h" | ||||
67 | |||||
68 | /* Possible return values of iv_get_reaching_def. */ | ||||
69 | |||||
70 | enum iv_grd_result | ||||
71 | { | ||||
72 | /* More than one reaching def, or reaching def that does not | ||||
73 | dominate the use. */ | ||||
74 | GRD_INVALID, | ||||
75 | |||||
76 | /* The use is trivial invariant of the loop, i.e. is not changed | ||||
77 | inside the loop. */ | ||||
78 | GRD_INVARIANT, | ||||
79 | |||||
80 | /* The use is reached by initial value and a value from the | ||||
81 | previous iteration. */ | ||||
82 | GRD_MAYBE_BIV, | ||||
83 | |||||
84 | /* The use has single dominating def. */ | ||||
85 | GRD_SINGLE_DOM | ||||
86 | }; | ||||
87 | |||||
88 | /* Information about a biv. */ | ||||
89 | |||||
90 | class biv_entry | ||||
91 | { | ||||
92 | public: | ||||
93 | unsigned regno; /* The register of the biv. */ | ||||
94 | class rtx_iv iv; /* Value of the biv. */ | ||||
95 | }; | ||||
96 | |||||
97 | static bool clean_slate = true; | ||||
98 | |||||
99 | static unsigned int iv_ref_table_size = 0; | ||||
100 | |||||
101 | /* Table of rtx_ivs indexed by the df_ref uid field. */ | ||||
102 | static class rtx_iv ** iv_ref_table; | ||||
103 | |||||
104 | /* Induction variable stored at the reference. */ | ||||
105 | #define DF_REF_IV(REF)iv_ref_table[((REF)->base.id)] iv_ref_table[DF_REF_ID (REF)((REF)->base.id)] | ||||
106 | #define DF_REF_IV_SET(REF, IV)iv_ref_table[((REF)->base.id)] = (IV) iv_ref_table[DF_REF_ID (REF)((REF)->base.id)] = (IV) | ||||
107 | |||||
108 | /* The current loop. */ | ||||
109 | |||||
110 | static class loop *current_loop; | ||||
111 | |||||
112 | /* Hashtable helper. */ | ||||
113 | |||||
114 | struct biv_entry_hasher : free_ptr_hash <biv_entry> | ||||
115 | { | ||||
116 | typedef rtx_def *compare_type; | ||||
117 | static inline hashval_t hash (const biv_entry *); | ||||
118 | static inline bool equal (const biv_entry *, const rtx_def *); | ||||
119 | }; | ||||
120 | |||||
121 | /* Returns hash value for biv B. */ | ||||
122 | |||||
123 | inline hashval_t | ||||
124 | biv_entry_hasher::hash (const biv_entry *b) | ||||
125 | { | ||||
126 | return b->regno; | ||||
127 | } | ||||
128 | |||||
129 | /* Compares biv B and register R. */ | ||||
130 | |||||
131 | inline bool | ||||
132 | biv_entry_hasher::equal (const biv_entry *b, const rtx_def *r) | ||||
133 | { | ||||
134 | return b->regno == REGNO (r)(rhs_regno(r)); | ||||
135 | } | ||||
136 | |||||
137 | /* Bivs of the current loop. */ | ||||
138 | |||||
139 | static hash_table<biv_entry_hasher> *bivs; | ||||
140 | |||||
141 | static bool iv_analyze_op (rtx_insn *, scalar_int_mode, rtx, class rtx_iv *); | ||||
142 | |||||
143 | /* Return the RTX code corresponding to the IV extend code EXTEND. */ | ||||
144 | static inline enum rtx_code | ||||
145 | iv_extend_to_rtx_code (enum iv_extend_code extend) | ||||
146 | { | ||||
147 | switch (extend) | ||||
148 | { | ||||
149 | case IV_SIGN_EXTEND: | ||||
150 | return SIGN_EXTEND; | ||||
151 | case IV_ZERO_EXTEND: | ||||
152 | return ZERO_EXTEND; | ||||
153 | case IV_UNKNOWN_EXTEND: | ||||
154 | return UNKNOWN; | ||||
155 | } | ||||
156 | gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/loop-iv.c" , 156, __FUNCTION__)); | ||||
157 | } | ||||
158 | |||||
159 | /* Dumps information about IV to FILE. */ | ||||
160 | |||||
161 | extern void dump_iv_info (FILE *, class rtx_iv *); | ||||
162 | void | ||||
163 | dump_iv_info (FILE *file, class rtx_iv *iv) | ||||
164 | { | ||||
165 | if (!iv->base) | ||||
166 | { | ||||
167 | fprintf (file, "not simple"); | ||||
168 | return; | ||||
169 | } | ||||
170 | |||||
171 | if (iv->step == const0_rtx(const_int_rtx[64]) | ||||
172 | && !iv->first_special) | ||||
173 | fprintf (file, "invariant "); | ||||
174 | |||||
175 | print_rtl (file, iv->base); | ||||
176 | if (iv->step != const0_rtx(const_int_rtx[64])) | ||||
177 | { | ||||
178 | fprintf (file, " + "); | ||||
179 | print_rtl (file, iv->step); | ||||
180 | fprintf (file, " * iteration"); | ||||
181 | } | ||||
182 | fprintf (file, " (in %s)", GET_MODE_NAME (iv->mode)mode_name[iv->mode]); | ||||
183 | |||||
184 | if (iv->mode != iv->extend_mode) | ||||
185 | fprintf (file, " %s to %s", | ||||
186 | rtx_name[iv_extend_to_rtx_code (iv->extend)], | ||||
187 | GET_MODE_NAME (iv->extend_mode)mode_name[iv->extend_mode]); | ||||
188 | |||||
189 | if (iv->mult != const1_rtx(const_int_rtx[64 +1])) | ||||
190 | { | ||||
191 | fprintf (file, " * "); | ||||
192 | print_rtl (file, iv->mult); | ||||
193 | } | ||||
194 | if (iv->delta != const0_rtx(const_int_rtx[64])) | ||||
195 | { | ||||
196 | fprintf (file, " + "); | ||||
197 | print_rtl (file, iv->delta); | ||||
198 | } | ||||
199 | if (iv->first_special) | ||||
200 | fprintf (file, " (first special)"); | ||||
201 | } | ||||
202 | |||||
203 | static void | ||||
204 | check_iv_ref_table_size (void) | ||||
205 | { | ||||
206 | if (iv_ref_table_size < DF_DEFS_TABLE_SIZE ()(df->def_info.table_size)) | ||||
207 | { | ||||
208 | unsigned int new_size = DF_DEFS_TABLE_SIZE ()(df->def_info.table_size) + (DF_DEFS_TABLE_SIZE ()(df->def_info.table_size) / 4); | ||||
209 | iv_ref_table = XRESIZEVEC (class rtx_iv *, iv_ref_table, new_size)((class rtx_iv * *) xrealloc ((void *) (iv_ref_table), sizeof (class rtx_iv *) * (new_size))); | ||||
210 | memset (&iv_ref_table[iv_ref_table_size], 0, | ||||
211 | (new_size - iv_ref_table_size) * sizeof (class rtx_iv *)); | ||||
212 | iv_ref_table_size = new_size; | ||||
213 | } | ||||
214 | } | ||||
215 | |||||
216 | |||||
217 | /* Checks whether REG is a well-behaved register. */ | ||||
218 | |||||
219 | static bool | ||||
220 | simple_reg_p (rtx reg) | ||||
221 | { | ||||
222 | unsigned r; | ||||
223 | |||||
224 | if (GET_CODE (reg)((enum rtx_code) (reg)->code) == SUBREG) | ||||
225 | { | ||||
226 | if (!subreg_lowpart_p (reg)) | ||||
227 | return false; | ||||
228 | reg = SUBREG_REG (reg)(((reg)->u.fld[0]).rt_rtx); | ||||
229 | } | ||||
230 | |||||
231 | if (!REG_P (reg)(((enum rtx_code) (reg)->code) == REG)) | ||||
232 | return false; | ||||
233 | |||||
234 | r = REGNO (reg)(rhs_regno(reg)); | ||||
235 | if (HARD_REGISTER_NUM_P (r)((r) < 76)) | ||||
236 | return false; | ||||
237 | |||||
238 | if (GET_MODE_CLASS (GET_MODE (reg))((enum mode_class) mode_class[((machine_mode) (reg)->mode) ]) != MODE_INT) | ||||
239 | return false; | ||||
240 | |||||
241 | return true; | ||||
242 | } | ||||
243 | |||||
244 | /* Clears the information about ivs stored in df. */ | ||||
245 | |||||
246 | static void | ||||
247 | clear_iv_info (void) | ||||
248 | { | ||||
249 | unsigned i, n_defs = DF_DEFS_TABLE_SIZE ()(df->def_info.table_size); | ||||
250 | class rtx_iv *iv; | ||||
251 | |||||
252 | check_iv_ref_table_size (); | ||||
253 | for (i = 0; i < n_defs; i++) | ||||
254 | { | ||||
255 | iv = iv_ref_table[i]; | ||||
256 | if (iv) | ||||
257 | { | ||||
258 | free (iv); | ||||
259 | iv_ref_table[i] = NULL__null; | ||||
260 | } | ||||
261 | } | ||||
262 | |||||
263 | bivs->empty (); | ||||
264 | } | ||||
265 | |||||
266 | |||||
267 | /* Prepare the data for an induction variable analysis of a LOOP. */ | ||||
268 | |||||
269 | void | ||||
270 | iv_analysis_loop_init (class loop *loop) | ||||
271 | { | ||||
272 | current_loop = loop; | ||||
273 | |||||
274 | /* Clear the information from the analysis of the previous loop. */ | ||||
275 | if (clean_slate) | ||||
276 | { | ||||
277 | df_set_flags (DF_EQ_NOTES + DF_DEFER_INSN_RESCAN); | ||||
278 | bivs = new hash_table<biv_entry_hasher> (10); | ||||
279 | clean_slate = false; | ||||
280 | } | ||||
281 | else | ||||
282 | clear_iv_info (); | ||||
283 | |||||
284 | /* Get rid of the ud chains before processing the rescans. Then add | ||||
285 | the problem back. */ | ||||
286 | df_remove_problem (df_chain(df->problems_by_index[DF_CHAIN])); | ||||
287 | df_process_deferred_rescans (); | ||||
288 | df_set_flags (DF_RD_PRUNE_DEAD_DEFS); | ||||
289 | df_chain_add_problem (DF_UD_CHAIN); | ||||
290 | df_note_add_problem (); | ||||
291 | df_analyze_loop (loop); | ||||
292 | if (dump_file) | ||||
293 | df_dump_region (dump_file); | ||||
294 | |||||
295 | check_iv_ref_table_size (); | ||||
296 | } | ||||
297 | |||||
298 | /* Finds the definition of REG that dominates loop latch and stores | ||||
299 | it to DEF. Returns false if there is not a single definition | ||||
300 | dominating the latch. If REG has no definition in loop, DEF | ||||
301 | is set to NULL and true is returned. */ | ||||
302 | |||||
303 | static bool | ||||
304 | latch_dominating_def (rtx reg, df_ref *def) | ||||
305 | { | ||||
306 | df_ref single_rd = NULL__null, adef; | ||||
307 | unsigned regno = REGNO (reg)(rhs_regno(reg)); | ||||
308 | class df_rd_bb_info *bb_info = DF_RD_BB_INFO (current_loop->latch)(df_rd_get_bb_info ((current_loop->latch)->index)); | ||||
309 | |||||
310 | for (adef = DF_REG_DEF_CHAIN (regno)(df->def_regs[(regno)]->reg_chain); adef; adef = DF_REF_NEXT_REG (adef)((adef)->base.next_reg)) | ||||
311 | { | ||||
312 | if (!bitmap_bit_p (df->blocks_to_analyze, DF_REF_BBNO (adef)(((((adef)->base.cl) == DF_REF_ARTIFICIAL) ? (adef)->artificial_ref .bb : BLOCK_FOR_INSN (((adef)->base.insn_info->insn)))-> index)) | ||||
313 | || !bitmap_bit_p (&bb_info->out, DF_REF_ID (adef)((adef)->base.id))) | ||||
314 | continue; | ||||
315 | |||||
316 | /* More than one reaching definition. */ | ||||
317 | if (single_rd) | ||||
318 | return false; | ||||
319 | |||||
320 | if (!just_once_each_iteration_p (current_loop, DF_REF_BB (adef)((((adef)->base.cl) == DF_REF_ARTIFICIAL) ? (adef)->artificial_ref .bb : BLOCK_FOR_INSN (((adef)->base.insn_info->insn))))) | ||||
321 | return false; | ||||
322 | |||||
323 | single_rd = adef; | ||||
324 | } | ||||
325 | |||||
326 | *def = single_rd; | ||||
327 | return true; | ||||
328 | } | ||||
329 | |||||
330 | /* Gets definition of REG reaching its use in INSN and stores it to DEF. */ | ||||
331 | |||||
332 | static enum iv_grd_result | ||||
333 | iv_get_reaching_def (rtx_insn *insn, rtx reg, df_ref *def) | ||||
334 | { | ||||
335 | df_ref use, adef; | ||||
336 | basic_block def_bb, use_bb; | ||||
337 | rtx_insn *def_insn; | ||||
338 | bool dom_p; | ||||
339 | |||||
340 | *def = NULL__null; | ||||
341 | if (!simple_reg_p (reg)) | ||||
342 | return GRD_INVALID; | ||||
343 | if (GET_CODE (reg)((enum rtx_code) (reg)->code) == SUBREG) | ||||
344 | reg = SUBREG_REG (reg)(((reg)->u.fld[0]).rt_rtx); | ||||
345 | gcc_assert (REG_P (reg))((void)(!((((enum rtx_code) (reg)->code) == REG)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/loop-iv.c" , 345, __FUNCTION__), 0 : 0)); | ||||
346 | |||||
347 | use = df_find_use (insn, reg); | ||||
348 | gcc_assert (use != NULL)((void)(!(use != __null) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/loop-iv.c" , 348, __FUNCTION__), 0 : 0)); | ||||
349 | |||||
350 | if (!DF_REF_CHAIN (use)((use)->base.chain)) | ||||
351 | return GRD_INVARIANT; | ||||
352 | |||||
353 | /* More than one reaching def. */ | ||||
354 | if (DF_REF_CHAIN (use)((use)->base.chain)->next) | ||||
355 | return GRD_INVALID; | ||||
356 | |||||
357 | adef = DF_REF_CHAIN (use)((use)->base.chain)->ref; | ||||
358 | |||||
359 | /* We do not handle setting only part of the register. */ | ||||
360 | if (DF_REF_FLAGS (adef)((adef)->base.flags) & DF_REF_READ_WRITE) | ||||
361 | return GRD_INVALID; | ||||
362 | |||||
363 | def_insn = DF_REF_INSN (adef)((adef)->base.insn_info->insn); | ||||
364 | def_bb = DF_REF_BB (adef)((((adef)->base.cl) == DF_REF_ARTIFICIAL) ? (adef)->artificial_ref .bb : BLOCK_FOR_INSN (((adef)->base.insn_info->insn))); | ||||
365 | use_bb = BLOCK_FOR_INSN (insn); | ||||
366 | |||||
367 | if (use_bb == def_bb) | ||||
368 | dom_p = (DF_INSN_LUID (def_insn)((((df->insns[(INSN_UID (def_insn))]))->luid)) < DF_INSN_LUID (insn)((((df->insns[(INSN_UID (insn))]))->luid))); | ||||
369 | else | ||||
370 | dom_p = dominated_by_p (CDI_DOMINATORS, use_bb, def_bb); | ||||
371 | |||||
372 | if (dom_p) | ||||
373 | { | ||||
374 | *def = adef; | ||||
375 | return GRD_SINGLE_DOM; | ||||
376 | } | ||||
377 | |||||
378 | /* The definition does not dominate the use. This is still OK if | ||||
379 | this may be a use of a biv, i.e. if the def_bb dominates loop | ||||
380 | latch. */ | ||||
381 | if (just_once_each_iteration_p (current_loop, def_bb)) | ||||
382 | return GRD_MAYBE_BIV; | ||||
383 | |||||
384 | return GRD_INVALID; | ||||
385 | } | ||||
386 | |||||
387 | /* Sets IV to invariant CST in MODE. Always returns true (just for | ||||
388 | consistency with other iv manipulation functions that may fail). */ | ||||
389 | |||||
390 | static bool | ||||
391 | iv_constant (class rtx_iv *iv, scalar_int_mode mode, rtx cst) | ||||
392 | { | ||||
393 | iv->mode = mode; | ||||
394 | iv->base = cst; | ||||
395 | iv->step = const0_rtx(const_int_rtx[64]); | ||||
396 | iv->first_special = false; | ||||
397 | iv->extend = IV_UNKNOWN_EXTEND; | ||||
398 | iv->extend_mode = iv->mode; | ||||
399 | iv->delta = const0_rtx(const_int_rtx[64]); | ||||
400 | iv->mult = const1_rtx(const_int_rtx[64 +1]); | ||||
401 | |||||
402 | return true; | ||||
403 | } | ||||
404 | |||||
405 | /* Evaluates application of subreg to MODE on IV. */ | ||||
406 | |||||
407 | static bool | ||||
408 | iv_subreg (class rtx_iv *iv, scalar_int_mode mode) | ||||
409 | { | ||||
410 | /* If iv is invariant, just calculate the new value. */ | ||||
411 | if (iv->step == const0_rtx(const_int_rtx[64]) | ||||
412 | && !iv->first_special) | ||||
413 | { | ||||
414 | rtx val = get_iv_value (iv, const0_rtx(const_int_rtx[64])); | ||||
415 | val = lowpart_subreg (mode, val, | ||||
416 | iv->extend == IV_UNKNOWN_EXTEND | ||||
417 | ? iv->mode : iv->extend_mode); | ||||
418 | |||||
419 | iv->base = val; | ||||
420 | iv->extend = IV_UNKNOWN_EXTEND; | ||||
421 | iv->mode = iv->extend_mode = mode; | ||||
422 | iv->delta = const0_rtx(const_int_rtx[64]); | ||||
423 | iv->mult = const1_rtx(const_int_rtx[64 +1]); | ||||
424 | return true; | ||||
425 | } | ||||
426 | |||||
427 | if (iv->extend_mode == mode) | ||||
428 | return true; | ||||
429 | |||||
430 | if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (iv->mode)) | ||||
431 | return false; | ||||
432 | |||||
433 | iv->extend = IV_UNKNOWN_EXTEND; | ||||
434 | iv->mode = mode; | ||||
435 | |||||
436 | iv->base = simplify_gen_binary (PLUS, iv->extend_mode, iv->delta, | ||||
437 | simplify_gen_binary (MULT, iv->extend_mode, | ||||
438 | iv->base, iv->mult)); | ||||
439 | iv->step = simplify_gen_binary (MULT, iv->extend_mode, iv->step, iv->mult); | ||||
440 | iv->mult = const1_rtx(const_int_rtx[64 +1]); | ||||
441 | iv->delta = const0_rtx(const_int_rtx[64]); | ||||
442 | iv->first_special = false; | ||||
443 | |||||
444 | return true; | ||||
445 | } | ||||
446 | |||||
447 | /* Evaluates application of EXTEND to MODE on IV. */ | ||||
448 | |||||
449 | static bool | ||||
450 | iv_extend (class rtx_iv *iv, enum iv_extend_code extend, scalar_int_mode mode) | ||||
451 | { | ||||
452 | /* If iv is invariant, just calculate the new value. */ | ||||
453 | if (iv->step == const0_rtx(const_int_rtx[64]) | ||||
454 | && !iv->first_special) | ||||
455 | { | ||||
456 | rtx val = get_iv_value (iv, const0_rtx(const_int_rtx[64])); | ||||
457 | if (iv->extend_mode != iv->mode | ||||
458 | && iv->extend != IV_UNKNOWN_EXTEND | ||||
459 | && iv->extend != extend) | ||||
460 | val = lowpart_subreg (iv->mode, val, iv->extend_mode); | ||||
461 | val = simplify_gen_unary (iv_extend_to_rtx_code (extend), mode, | ||||
462 | val, | ||||
463 | iv->extend == extend | ||||
464 | ? iv->extend_mode : iv->mode); | ||||
465 | iv->base = val; | ||||
466 | iv->extend = IV_UNKNOWN_EXTEND; | ||||
467 | iv->mode = iv->extend_mode = mode; | ||||
468 | iv->delta = const0_rtx(const_int_rtx[64]); | ||||
469 | iv->mult = const1_rtx(const_int_rtx[64 +1]); | ||||
470 | return true; | ||||
471 | } | ||||
472 | |||||
473 | if (mode != iv->extend_mode) | ||||
474 | return false; | ||||
475 | |||||
476 | if (iv->extend != IV_UNKNOWN_EXTEND | ||||
477 | && iv->extend != extend) | ||||
478 | return false; | ||||
479 | |||||
480 | iv->extend = extend; | ||||
481 | |||||
482 | return true; | ||||
483 | } | ||||
484 | |||||
485 | /* Evaluates negation of IV. */ | ||||
486 | |||||
487 | static bool | ||||
488 | iv_neg (class rtx_iv *iv) | ||||
489 | { | ||||
490 | if (iv->extend == IV_UNKNOWN_EXTEND) | ||||
491 | { | ||||
492 | iv->base = simplify_gen_unary (NEG, iv->extend_mode, | ||||
493 | iv->base, iv->extend_mode); | ||||
494 | iv->step = simplify_gen_unary (NEG, iv->extend_mode, | ||||
495 | iv->step, iv->extend_mode); | ||||
496 | } | ||||
497 | else | ||||
498 | { | ||||
499 | iv->delta = simplify_gen_unary (NEG, iv->extend_mode, | ||||
500 | iv->delta, iv->extend_mode); | ||||
501 | iv->mult = simplify_gen_unary (NEG, iv->extend_mode, | ||||
502 | iv->mult, iv->extend_mode); | ||||
503 | } | ||||
504 | |||||
505 | return true; | ||||
506 | } | ||||
507 | |||||
508 | /* Evaluates addition or subtraction (according to OP) of IV1 to IV0. */ | ||||
509 | |||||
510 | static bool | ||||
511 | iv_add (class rtx_iv *iv0, class rtx_iv *iv1, enum rtx_code op) | ||||
512 | { | ||||
513 | scalar_int_mode mode; | ||||
514 | rtx arg; | ||||
515 | |||||
516 | /* Extend the constant to extend_mode of the other operand if necessary. */ | ||||
517 | if (iv0->extend == IV_UNKNOWN_EXTEND | ||||
518 | && iv0->mode == iv0->extend_mode | ||||
519 | && iv0->step == const0_rtx(const_int_rtx[64]) | ||||
520 | && GET_MODE_SIZE (iv0->extend_mode) < GET_MODE_SIZE (iv1->extend_mode)) | ||||
521 | { | ||||
522 | iv0->extend_mode = iv1->extend_mode; | ||||
523 | iv0->base = simplify_gen_unary (ZERO_EXTEND, iv0->extend_mode, | ||||
524 | iv0->base, iv0->mode); | ||||
525 | } | ||||
526 | if (iv1->extend == IV_UNKNOWN_EXTEND | ||||
527 | && iv1->mode == iv1->extend_mode | ||||
528 | && iv1->step == const0_rtx(const_int_rtx[64]) | ||||
529 | && GET_MODE_SIZE (iv1->extend_mode) < GET_MODE_SIZE (iv0->extend_mode)) | ||||
530 | { | ||||
531 | iv1->extend_mode = iv0->extend_mode; | ||||
532 | iv1->base = simplify_gen_unary (ZERO_EXTEND, iv1->extend_mode, | ||||
533 | iv1->base, iv1->mode); | ||||
534 | } | ||||
535 | |||||
536 | mode = iv0->extend_mode; | ||||
537 | if (mode != iv1->extend_mode) | ||||
538 | return false; | ||||
539 | |||||
540 | if (iv0->extend == IV_UNKNOWN_EXTEND | ||||
541 | && iv1->extend == IV_UNKNOWN_EXTEND) | ||||
542 | { | ||||
543 | if (iv0->mode != iv1->mode) | ||||
544 | return false; | ||||
545 | |||||
546 | iv0->base = simplify_gen_binary (op, mode, iv0->base, iv1->base); | ||||
547 | iv0->step = simplify_gen_binary (op, mode, iv0->step, iv1->step); | ||||
548 | |||||
549 | return true; | ||||
550 | } | ||||
551 | |||||
552 | /* Handle addition of constant. */ | ||||
553 | if (iv1->extend == IV_UNKNOWN_EXTEND | ||||
554 | && iv1->mode == mode | ||||
555 | && iv1->step == const0_rtx(const_int_rtx[64])) | ||||
556 | { | ||||
557 | iv0->delta = simplify_gen_binary (op, mode, iv0->delta, iv1->base); | ||||
558 | return true; | ||||
559 | } | ||||
560 | |||||
561 | if (iv0->extend == IV_UNKNOWN_EXTEND | ||||
562 | && iv0->mode == mode | ||||
563 | && iv0->step == const0_rtx(const_int_rtx[64])) | ||||
564 | { | ||||
565 | arg = iv0->base; | ||||
566 | *iv0 = *iv1; | ||||
567 | if (op == MINUS | ||||
568 | && !iv_neg (iv0)) | ||||
569 | return false; | ||||
570 | |||||
571 | iv0->delta = simplify_gen_binary (PLUS, mode, iv0->delta, arg); | ||||
572 | return true; | ||||
573 | } | ||||
574 | |||||
575 | return false; | ||||
576 | } | ||||
577 | |||||
578 | /* Evaluates multiplication of IV by constant CST. */ | ||||
579 | |||||
580 | static bool | ||||
581 | iv_mult (class rtx_iv *iv, rtx mby) | ||||
582 | { | ||||
583 | scalar_int_mode mode = iv->extend_mode; | ||||
584 | |||||
585 | if (GET_MODE (mby)((machine_mode) (mby)->mode) != VOIDmode((void) 0, E_VOIDmode) | ||||
586 | && GET_MODE (mby)((machine_mode) (mby)->mode) != mode) | ||||
587 | return false; | ||||
588 | |||||
589 | if (iv->extend == IV_UNKNOWN_EXTEND) | ||||
590 | { | ||||
591 | iv->base = simplify_gen_binary (MULT, mode, iv->base, mby); | ||||
592 | iv->step = simplify_gen_binary (MULT, mode, iv->step, mby); | ||||
593 | } | ||||
594 | else | ||||
595 | { | ||||
596 | iv->delta = simplify_gen_binary (MULT, mode, iv->delta, mby); | ||||
597 | iv->mult = simplify_gen_binary (MULT, mode, iv->mult, mby); | ||||
598 | } | ||||
599 | |||||
600 | return true; | ||||
601 | } | ||||
602 | |||||
603 | /* Evaluates shift of IV by constant CST. */ | ||||
604 | |||||
605 | static bool | ||||
606 | iv_shift (class rtx_iv *iv, rtx mby) | ||||
607 | { | ||||
608 | scalar_int_mode mode = iv->extend_mode; | ||||
609 | |||||
610 | if (GET_MODE (mby)((machine_mode) (mby)->mode) != VOIDmode((void) 0, E_VOIDmode) | ||||
611 | && GET_MODE (mby)((machine_mode) (mby)->mode) != mode) | ||||
612 | return false; | ||||
613 | |||||
614 | if (iv->extend == IV_UNKNOWN_EXTEND) | ||||
615 | { | ||||
616 | iv->base = simplify_gen_binary (ASHIFT, mode, iv->base, mby); | ||||
617 | iv->step = simplify_gen_binary (ASHIFT, mode, iv->step, mby); | ||||
618 | } | ||||
619 | else | ||||
620 | { | ||||
621 | iv->delta = simplify_gen_binary (ASHIFT, mode, iv->delta, mby); | ||||
622 | iv->mult = simplify_gen_binary (ASHIFT, mode, iv->mult, mby); | ||||
623 | } | ||||
624 | |||||
625 | return true; | ||||
626 | } | ||||
627 | |||||
628 | /* The recursive part of get_biv_step. Gets the value of the single value | ||||
629 | defined by DEF wrto initial value of REG inside loop, in shape described | ||||
630 | at get_biv_step. */ | ||||
631 | |||||
632 | static bool | ||||
633 | get_biv_step_1 (df_ref def, scalar_int_mode outer_mode, rtx reg, | ||||
634 | rtx *inner_step, scalar_int_mode *inner_mode, | ||||
635 | enum iv_extend_code *extend, | ||||
636 | rtx *outer_step) | ||||
637 | { | ||||
638 | rtx set, rhs, op0 = NULL_RTX(rtx) 0, op1 = NULL_RTX(rtx) 0; | ||||
639 | rtx next, nextr; | ||||
640 | enum rtx_code code; | ||||
641 | rtx_insn *insn = DF_REF_INSN (def)((def)->base.insn_info->insn); | ||||
642 | df_ref next_def; | ||||
643 | enum iv_grd_result res; | ||||
644 | |||||
645 | set = single_set (insn); | ||||
646 | if (!set) | ||||
647 | return false; | ||||
648 | |||||
649 | rhs = find_reg_equal_equiv_note (insn); | ||||
650 | if (rhs) | ||||
651 | rhs = XEXP (rhs, 0)(((rhs)->u.fld[0]).rt_rtx); | ||||
652 | else | ||||
653 | rhs = SET_SRC (set)(((set)->u.fld[1]).rt_rtx); | ||||
654 | |||||
655 | code = GET_CODE (rhs)((enum rtx_code) (rhs)->code); | ||||
656 | switch (code) | ||||
657 | { | ||||
658 | case SUBREG: | ||||
659 | case REG: | ||||
660 | next = rhs; | ||||
661 | break; | ||||
662 | |||||
663 | case PLUS: | ||||
664 | case MINUS: | ||||
665 | op0 = XEXP (rhs, 0)(((rhs)->u.fld[0]).rt_rtx); | ||||
666 | op1 = XEXP (rhs, 1)(((rhs)->u.fld[1]).rt_rtx); | ||||
667 | |||||
668 | if (code == PLUS && CONSTANT_P (op0)((rtx_class[(int) (((enum rtx_code) (op0)->code))]) == RTX_CONST_OBJ )) | ||||
669 | std::swap (op0, op1); | ||||
670 | |||||
671 | if (!simple_reg_p (op0) | ||||
672 | || !CONSTANT_P (op1)((rtx_class[(int) (((enum rtx_code) (op1)->code))]) == RTX_CONST_OBJ )) | ||||
673 | return false; | ||||
674 | |||||
675 | if (GET_MODE (rhs)((machine_mode) (rhs)->mode) != outer_mode) | ||||
676 | { | ||||
677 | /* ppc64 uses expressions like | ||||
678 | |||||
679 | (set x:SI (plus:SI (subreg:SI y:DI) 1)). | ||||
680 | |||||
681 | this is equivalent to | ||||
682 | |||||
683 | (set x':DI (plus:DI y:DI 1)) | ||||
684 | (set x:SI (subreg:SI (x':DI)). */ | ||||
685 | if (GET_CODE (op0)((enum rtx_code) (op0)->code) != SUBREG) | ||||
686 | return false; | ||||
687 | if (GET_MODE (SUBREG_REG (op0))((machine_mode) ((((op0)->u.fld[0]).rt_rtx))->mode) != outer_mode) | ||||
688 | return false; | ||||
689 | } | ||||
690 | |||||
691 | next = op0; | ||||
692 | break; | ||||
693 | |||||
694 | case SIGN_EXTEND: | ||||
695 | case ZERO_EXTEND: | ||||
696 | if (GET_MODE (rhs)((machine_mode) (rhs)->mode) != outer_mode) | ||||
697 | return false; | ||||
698 | |||||
699 | op0 = XEXP (rhs, 0)(((rhs)->u.fld[0]).rt_rtx); | ||||
700 | if (!simple_reg_p (op0)) | ||||
701 | return false; | ||||
702 | |||||
703 | next = op0; | ||||
704 | break; | ||||
705 | |||||
706 | default: | ||||
707 | return false; | ||||
708 | } | ||||
709 | |||||
710 | if (GET_CODE (next)((enum rtx_code) (next)->code) == SUBREG) | ||||
711 | { | ||||
712 | if (!subreg_lowpart_p (next)) | ||||
713 | return false; | ||||
714 | |||||
715 | nextr = SUBREG_REG (next)(((next)->u.fld[0]).rt_rtx); | ||||
716 | if (GET_MODE (nextr)((machine_mode) (nextr)->mode) != outer_mode) | ||||
717 | return false; | ||||
718 | } | ||||
719 | else | ||||
720 | nextr = next; | ||||
721 | |||||
722 | res = iv_get_reaching_def (insn, nextr, &next_def); | ||||
723 | |||||
724 | if (res == GRD_INVALID || res == GRD_INVARIANT) | ||||
725 | return false; | ||||
726 | |||||
727 | if (res == GRD_MAYBE_BIV) | ||||
728 | { | ||||
729 | if (!rtx_equal_p (nextr, reg)) | ||||
730 | return false; | ||||
731 | |||||
732 | *inner_step = const0_rtx(const_int_rtx[64]); | ||||
733 | *extend = IV_UNKNOWN_EXTEND; | ||||
734 | *inner_mode = outer_mode; | ||||
735 | *outer_step = const0_rtx(const_int_rtx[64]); | ||||
736 | } | ||||
737 | else if (!get_biv_step_1 (next_def, outer_mode, reg, | ||||
738 | inner_step, inner_mode, extend, | ||||
739 | outer_step)) | ||||
740 | return false; | ||||
741 | |||||
742 | if (GET_CODE (next)((enum rtx_code) (next)->code) == SUBREG) | ||||
743 | { | ||||
744 | scalar_int_mode amode; | ||||
745 | if (!is_a <scalar_int_mode> (GET_MODE (next)((machine_mode) (next)->mode), &amode) | ||||
746 | || GET_MODE_SIZE (amode) > GET_MODE_SIZE (*inner_mode)) | ||||
747 | return false; | ||||
748 | |||||
749 | *inner_mode = amode; | ||||
750 | *inner_step = simplify_gen_binary (PLUS, outer_mode, | ||||
751 | *inner_step, *outer_step); | ||||
752 | *outer_step = const0_rtx(const_int_rtx[64]); | ||||
753 | *extend = IV_UNKNOWN_EXTEND; | ||||
754 | } | ||||
755 | |||||
756 | switch (code) | ||||
757 | { | ||||
758 | case REG: | ||||
759 | case SUBREG: | ||||
760 | break; | ||||
761 | |||||
762 | case PLUS: | ||||
763 | case MINUS: | ||||
764 | if (*inner_mode == outer_mode | ||||
765 | /* See comment in previous switch. */ | ||||
766 | || GET_MODE (rhs)((machine_mode) (rhs)->mode) != outer_mode) | ||||
767 | *inner_step = simplify_gen_binary (code, outer_mode, | ||||
768 | *inner_step, op1); | ||||
769 | else | ||||
770 | *outer_step = simplify_gen_binary (code, outer_mode, | ||||
771 | *outer_step, op1); | ||||
772 | break; | ||||
773 | |||||
774 | case SIGN_EXTEND: | ||||
775 | case ZERO_EXTEND: | ||||
776 | gcc_assert (GET_MODE (op0) == *inner_mode((void)(!(((machine_mode) (op0)->mode) == *inner_mode && *extend == IV_UNKNOWN_EXTEND && *outer_step == (const_int_rtx [64])) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/loop-iv.c" , 778, __FUNCTION__), 0 : 0)) | ||||
777 | && *extend == IV_UNKNOWN_EXTEND((void)(!(((machine_mode) (op0)->mode) == *inner_mode && *extend == IV_UNKNOWN_EXTEND && *outer_step == (const_int_rtx [64])) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/loop-iv.c" , 778, __FUNCTION__), 0 : 0)) | ||||
778 | && *outer_step == const0_rtx)((void)(!(((machine_mode) (op0)->mode) == *inner_mode && *extend == IV_UNKNOWN_EXTEND && *outer_step == (const_int_rtx [64])) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/loop-iv.c" , 778, __FUNCTION__), 0 : 0)); | ||||
779 | |||||
780 | *extend = (code == SIGN_EXTEND) ? IV_SIGN_EXTEND : IV_ZERO_EXTEND; | ||||
781 | break; | ||||
782 | |||||
783 | default: | ||||
784 | return false; | ||||
785 | } | ||||
786 | |||||
787 | return true; | ||||
788 | } | ||||
789 | |||||
790 | /* Gets the operation on register REG inside loop, in shape | ||||
791 | |||||
792 | OUTER_STEP + EXTEND_{OUTER_MODE} (SUBREG_{INNER_MODE} (REG + INNER_STEP)) | ||||
793 | |||||
794 | If the operation cannot be described in this shape, return false. | ||||
795 | LAST_DEF is the definition of REG that dominates loop latch. */ | ||||
796 | |||||
797 | static bool | ||||
798 | get_biv_step (df_ref last_def, scalar_int_mode outer_mode, rtx reg, | ||||
799 | rtx *inner_step, scalar_int_mode *inner_mode, | ||||
800 | enum iv_extend_code *extend, rtx *outer_step) | ||||
801 | { | ||||
802 | if (!get_biv_step_1 (last_def, outer_mode, reg, | ||||
803 | inner_step, inner_mode, extend, | ||||
804 | outer_step)) | ||||
805 | return false; | ||||
806 | |||||
807 | gcc_assert ((*inner_mode == outer_mode) != (*extend != IV_UNKNOWN_EXTEND))((void)(!((*inner_mode == outer_mode) != (*extend != IV_UNKNOWN_EXTEND )) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/loop-iv.c" , 807, __FUNCTION__), 0 : 0)); | ||||
808 | gcc_assert (*inner_mode != outer_mode || *outer_step == const0_rtx)((void)(!(*inner_mode != outer_mode || *outer_step == (const_int_rtx [64])) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/loop-iv.c" , 808, __FUNCTION__), 0 : 0)); | ||||
809 | |||||
810 | return true; | ||||
811 | } | ||||
812 | |||||
813 | /* Records information that DEF is induction variable IV. */ | ||||
814 | |||||
815 | static void | ||||
816 | record_iv (df_ref def, class rtx_iv *iv) | ||||
817 | { | ||||
818 | class rtx_iv *recorded_iv = XNEW (class rtx_iv)((class rtx_iv *) xmalloc (sizeof (class rtx_iv))); | ||||
819 | |||||
820 | *recorded_iv = *iv; | ||||
821 | check_iv_ref_table_size (); | ||||
822 | DF_REF_IV_SET (def, recorded_iv)iv_ref_table[((def)->base.id)] = (recorded_iv); | ||||
823 | } | ||||
824 | |||||
825 | /* If DEF was already analyzed for bivness, store the description of the biv to | ||||
826 | IV and return true. Otherwise return false. */ | ||||
827 | |||||
828 | static bool | ||||
829 | analyzed_for_bivness_p (rtx def, class rtx_iv *iv) | ||||
830 | { | ||||
831 | class biv_entry *biv = bivs->find_with_hash (def, REGNO (def)(rhs_regno(def))); | ||||
832 | |||||
833 | if (!biv) | ||||
834 | return false; | ||||
835 | |||||
836 | *iv = biv->iv; | ||||
837 | return true; | ||||
838 | } | ||||
839 | |||||
840 | static void | ||||
841 | record_biv (rtx def, class rtx_iv *iv) | ||||
842 | { | ||||
843 | class biv_entry *biv = XNEW (class biv_entry)((class biv_entry *) xmalloc (sizeof (class biv_entry))); | ||||
844 | biv_entry **slot = bivs->find_slot_with_hash (def, REGNO (def)(rhs_regno(def)), INSERT); | ||||
845 | |||||
846 | biv->regno = REGNO (def)(rhs_regno(def)); | ||||
847 | biv->iv = *iv; | ||||
848 | gcc_assert (!*slot)((void)(!(!*slot) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/loop-iv.c" , 848, __FUNCTION__), 0 : 0)); | ||||
849 | *slot = biv; | ||||
850 | } | ||||
851 | |||||
852 | /* Determines whether DEF is a biv and if so, stores its description | ||||
853 | to *IV. OUTER_MODE is the mode of DEF. */ | ||||
854 | |||||
855 | static bool | ||||
856 | iv_analyze_biv (scalar_int_mode outer_mode, rtx def, class rtx_iv *iv) | ||||
857 | { | ||||
858 | rtx inner_step, outer_step; | ||||
859 | scalar_int_mode inner_mode; | ||||
860 | enum iv_extend_code extend; | ||||
861 | df_ref last_def; | ||||
862 | |||||
863 | if (dump_file) | ||||
864 | { | ||||
865 | fprintf (dump_file, "Analyzing "); | ||||
866 | print_rtl (dump_file, def); | ||||
867 | fprintf (dump_file, " for bivness.\n"); | ||||
868 | } | ||||
869 | |||||
870 | if (!REG_P (def)(((enum rtx_code) (def)->code) == REG)) | ||||
871 | { | ||||
872 | if (!CONSTANT_P (def)((rtx_class[(int) (((enum rtx_code) (def)->code))]) == RTX_CONST_OBJ )) | ||||
873 | return false; | ||||
874 | |||||
875 | return iv_constant (iv, outer_mode, def); | ||||
876 | } | ||||
877 | |||||
878 | if (!latch_dominating_def (def, &last_def)) | ||||
879 | { | ||||
880 | if (dump_file) | ||||
881 | fprintf (dump_file, " not simple.\n"); | ||||
882 | return false; | ||||
883 | } | ||||
884 | |||||
885 | if (!last_def) | ||||
886 | return iv_constant (iv, outer_mode, def); | ||||
887 | |||||
888 | if (analyzed_for_bivness_p (def, iv)) | ||||
889 | { | ||||
890 | if (dump_file) | ||||
891 | fprintf (dump_file, " already analysed.\n"); | ||||
892 | return iv->base != NULL_RTX(rtx) 0; | ||||
893 | } | ||||
894 | |||||
895 | if (!get_biv_step (last_def, outer_mode, def, &inner_step, &inner_mode, | ||||
896 | &extend, &outer_step)) | ||||
897 | { | ||||
898 | iv->base = NULL_RTX(rtx) 0; | ||||
899 | goto end; | ||||
900 | } | ||||
901 | |||||
902 | /* Loop transforms base to es (base + inner_step) + outer_step, | ||||
903 | where es means extend of subreg between inner_mode and outer_mode. | ||||
904 | The corresponding induction variable is | ||||
905 | |||||
906 | es ((base - outer_step) + i * (inner_step + outer_step)) + outer_step */ | ||||
907 | |||||
908 | iv->base = simplify_gen_binary (MINUS, outer_mode, def, outer_step); | ||||
909 | iv->step = simplify_gen_binary (PLUS, outer_mode, inner_step, outer_step); | ||||
910 | iv->mode = inner_mode; | ||||
911 | iv->extend_mode = outer_mode; | ||||
912 | iv->extend = extend; | ||||
913 | iv->mult = const1_rtx(const_int_rtx[64 +1]); | ||||
914 | iv->delta = outer_step; | ||||
915 | iv->first_special = inner_mode != outer_mode; | ||||
916 | |||||
917 | end: | ||||
918 | if (dump_file) | ||||
919 | { | ||||
920 | fprintf (dump_file, " "); | ||||
921 | dump_iv_info (dump_file, iv); | ||||
922 | fprintf (dump_file, "\n"); | ||||
923 | } | ||||
924 | |||||
925 | record_biv (def, iv); | ||||
926 | return iv->base != NULL_RTX(rtx) 0; | ||||
927 | } | ||||
928 | |||||
929 | /* Analyzes expression RHS used at INSN and stores the result to *IV. | ||||
930 | The mode of the induction variable is MODE. */ | ||||
931 | |||||
932 | bool | ||||
933 | iv_analyze_expr (rtx_insn *insn, scalar_int_mode mode, rtx rhs, | ||||
934 | class rtx_iv *iv) | ||||
935 | { | ||||
936 | rtx mby = NULL_RTX(rtx) 0; | ||||
937 | rtx op0 = NULL_RTX(rtx) 0, op1 = NULL_RTX(rtx) 0; | ||||
938 | class rtx_iv iv0, iv1; | ||||
939 | enum rtx_code code = GET_CODE (rhs)((enum rtx_code) (rhs)->code); | ||||
940 | scalar_int_mode omode = mode; | ||||
941 | |||||
942 | iv->base = NULL_RTX(rtx) 0; | ||||
943 | iv->step = NULL_RTX(rtx) 0; | ||||
944 | |||||
945 | gcc_assert (GET_MODE (rhs) == mode || GET_MODE (rhs) == VOIDmode)((void)(!(((machine_mode) (rhs)->mode) == mode || ((machine_mode ) (rhs)->mode) == ((void) 0, E_VOIDmode)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/loop-iv.c" , 945, __FUNCTION__), 0 : 0)); | ||||
946 | |||||
947 | if (CONSTANT_P (rhs)((rtx_class[(int) (((enum rtx_code) (rhs)->code))]) == RTX_CONST_OBJ ) | ||||
948 | || REG_P (rhs)(((enum rtx_code) (rhs)->code) == REG) | ||||
949 | || code == SUBREG) | ||||
950 | return iv_analyze_op (insn, mode, rhs, iv); | ||||
951 | |||||
952 | switch (code) | ||||
953 | { | ||||
954 | case REG: | ||||
955 | op0 = rhs; | ||||
956 | break; | ||||
957 | |||||
958 | case SIGN_EXTEND: | ||||
959 | case ZERO_EXTEND: | ||||
960 | case NEG: | ||||
961 | op0 = XEXP (rhs, 0)(((rhs)->u.fld[0]).rt_rtx); | ||||
962 | /* We don't know how many bits there are in a sign-extended constant. */ | ||||
963 | if (!is_a <scalar_int_mode> (GET_MODE (op0)((machine_mode) (op0)->mode), &omode)) | ||||
964 | return false; | ||||
965 | break; | ||||
966 | |||||
967 | case PLUS: | ||||
968 | case MINUS: | ||||
969 | op0 = XEXP (rhs, 0)(((rhs)->u.fld[0]).rt_rtx); | ||||
970 | op1 = XEXP (rhs, 1)(((rhs)->u.fld[1]).rt_rtx); | ||||
971 | break; | ||||
972 | |||||
973 | case MULT: | ||||
974 | op0 = XEXP (rhs, 0)(((rhs)->u.fld[0]).rt_rtx); | ||||
975 | mby = XEXP (rhs, 1)(((rhs)->u.fld[1]).rt_rtx); | ||||
976 | if (!CONSTANT_P (mby)((rtx_class[(int) (((enum rtx_code) (mby)->code))]) == RTX_CONST_OBJ )) | ||||
977 | std::swap (op0, mby); | ||||
978 | if (!CONSTANT_P (mby)((rtx_class[(int) (((enum rtx_code) (mby)->code))]) == RTX_CONST_OBJ )) | ||||
979 | return false; | ||||
980 | break; | ||||
981 | |||||
982 | case ASHIFT: | ||||
983 | op0 = XEXP (rhs, 0)(((rhs)->u.fld[0]).rt_rtx); | ||||
984 | mby = XEXP (rhs, 1)(((rhs)->u.fld[1]).rt_rtx); | ||||
985 | if (!CONSTANT_P (mby)((rtx_class[(int) (((enum rtx_code) (mby)->code))]) == RTX_CONST_OBJ )) | ||||
986 | return false; | ||||
987 | break; | ||||
988 | |||||
989 | default: | ||||
990 | return false; | ||||
991 | } | ||||
992 | |||||
993 | if (op0 | ||||
994 | && !iv_analyze_expr (insn, omode, op0, &iv0)) | ||||
995 | return false; | ||||
996 | |||||
997 | if (op1
|
28.1 | 'op1' is null |
9.1 | 'set' is non-null |
9.1 | 'set' is non-null |
1 | Assuming 'adef' is non-null |
1 | /* Machine mode definitions for GCC; included by rtl.h and tree.h. | |||
2 | Copyright (C) 1991-2021 Free Software Foundation, Inc. | |||
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 | #ifndef HAVE_MACHINE_MODES | |||
21 | #define HAVE_MACHINE_MODES | |||
22 | ||||
23 | typedef opt_mode<machine_mode> opt_machine_mode; | |||
24 | ||||
25 | extern CONST_MODE_SIZE poly_uint16_pod mode_size[NUM_MACHINE_MODES]; | |||
26 | extern CONST_MODE_PRECISIONconst poly_uint16_pod mode_precision[NUM_MACHINE_MODES]; | |||
27 | extern const unsigned char mode_inner[NUM_MACHINE_MODES]; | |||
28 | extern CONST_MODE_NUNITSconst poly_uint16_pod mode_nunits[NUM_MACHINE_MODES]; | |||
29 | extern CONST_MODE_UNIT_SIZE unsigned char mode_unit_size[NUM_MACHINE_MODES]; | |||
30 | extern const unsigned short mode_unit_precision[NUM_MACHINE_MODES]; | |||
31 | extern const unsigned char mode_wider[NUM_MACHINE_MODES]; | |||
32 | extern const unsigned char mode_2xwider[NUM_MACHINE_MODES]; | |||
33 | ||||
34 | template<typename T> | |||
35 | struct mode_traits | |||
36 | { | |||
37 | /* For use by the machmode support code only. | |||
38 | ||||
39 | There are cases in which the machmode support code needs to forcibly | |||
40 | convert a machine_mode to a specific mode class T, and in which the | |||
41 | context guarantees that this is valid without the need for an assert. | |||
42 | This can be done using: | |||
43 | ||||
44 | return typename mode_traits<T>::from_int (mode); | |||
45 | ||||
46 | when returning a T and: | |||
47 | ||||
48 | res = T (typename mode_traits<T>::from_int (mode)); | |||
49 | ||||
50 | when assigning to a value RES that must be assignment-compatible | |||
51 | with (but possibly not the same as) T. */ | |||
52 | #ifdef USE_ENUM_MODES | |||
53 | /* Allow direct conversion of enums to specific mode classes only | |||
54 | when USE_ENUM_MODES is defined. This is only intended for use | |||
55 | by gencondmd, so that it can tell more easily when .md conditions | |||
56 | are always false. */ | |||
57 | typedef machine_mode from_int; | |||
58 | #else | |||
59 | /* Here we use an enum type distinct from machine_mode but with the | |||
60 | same range as machine_mode. T should have a constructor that | |||
61 | accepts this enum type; it should not have a constructor that | |||
62 | accepts machine_mode. | |||
63 | ||||
64 | We use this somewhat indirect approach to avoid too many constructor | |||
65 | calls when the compiler is built with -O0. For example, even in | |||
66 | unoptimized code, the return statement above would construct the | |||
67 | returned T directly from the numerical value of MODE. */ | |||
68 | enum from_int { dummy = MAX_MACHINE_MODE }; | |||
69 | #endif | |||
70 | }; | |||
71 | ||||
72 | template<> | |||
73 | struct mode_traits<machine_mode> | |||
74 | { | |||
75 | /* machine_mode itself needs no conversion. */ | |||
76 | typedef machine_mode from_int; | |||
77 | }; | |||
78 | ||||
79 | /* Always treat machine modes as fixed-size while compiling code specific | |||
80 | to targets that have no variable-size modes. */ | |||
81 | #if defined (IN_TARGET_CODE) && NUM_POLY_INT_COEFFS1 == 1 | |||
82 | #define ONLY_FIXED_SIZE_MODES0 1 | |||
83 | #else | |||
84 | #define ONLY_FIXED_SIZE_MODES0 0 | |||
85 | #endif | |||
86 | ||||
87 | /* Get the name of mode MODE as a string. */ | |||
88 | ||||
89 | extern const char * const mode_name[NUM_MACHINE_MODES]; | |||
90 | #define GET_MODE_NAME(MODE)mode_name[MODE] mode_name[MODE] | |||
91 | ||||
92 | /* Mode classes. */ | |||
93 | ||||
94 | #include "mode-classes.def" | |||
95 | #define DEF_MODE_CLASS(M) M | |||
96 | enum mode_class { MODE_CLASSES, MAX_MODE_CLASS }; | |||
97 | #undef DEF_MODE_CLASS | |||
98 | #undef MODE_CLASSES | |||
99 | ||||
100 | /* Get the general kind of object that mode MODE represents | |||
101 | (integer, floating, complex, etc.) */ | |||
102 | ||||
103 | extern const unsigned char mode_class[NUM_MACHINE_MODES]; | |||
104 | #define GET_MODE_CLASS(MODE)((enum mode_class) mode_class[MODE]) ((enum mode_class) mode_class[MODE]) | |||
105 | ||||
106 | /* Nonzero if MODE is an integral mode. */ | |||
107 | #define INTEGRAL_MODE_P(MODE)(((enum mode_class) mode_class[MODE]) == MODE_INT || ((enum mode_class ) mode_class[MODE]) == MODE_PARTIAL_INT || ((enum mode_class) mode_class[MODE]) == MODE_COMPLEX_INT || ((enum mode_class) mode_class [MODE]) == MODE_VECTOR_BOOL || ((enum mode_class) mode_class[ MODE]) == MODE_VECTOR_INT) \ | |||
108 | (GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_INT \ | |||
109 | || GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_PARTIAL_INT \ | |||
110 | || GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_COMPLEX_INT \ | |||
111 | || GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_VECTOR_BOOL \ | |||
112 | || GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_VECTOR_INT) | |||
113 | ||||
114 | /* Nonzero if MODE is a floating-point mode. */ | |||
115 | #define FLOAT_MODE_P(MODE)(((enum mode_class) mode_class[MODE]) == MODE_FLOAT || ((enum mode_class) mode_class[MODE]) == MODE_DECIMAL_FLOAT || ((enum mode_class) mode_class[MODE]) == MODE_COMPLEX_FLOAT || ((enum mode_class) mode_class[MODE]) == MODE_VECTOR_FLOAT) \ | |||
116 | (GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_FLOAT \ | |||
117 | || GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_DECIMAL_FLOAT \ | |||
118 | || GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_COMPLEX_FLOAT \ | |||
119 | || GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_VECTOR_FLOAT) | |||
120 | ||||
121 | /* Nonzero if MODE is a complex mode. */ | |||
122 | #define COMPLEX_MODE_P(MODE)(((enum mode_class) mode_class[MODE]) == MODE_COMPLEX_INT || ( (enum mode_class) mode_class[MODE]) == MODE_COMPLEX_FLOAT) \ | |||
123 | (GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_COMPLEX_INT \ | |||
124 | || GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_COMPLEX_FLOAT) | |||
125 | ||||
126 | /* Nonzero if MODE is a vector mode. */ | |||
127 | #define VECTOR_MODE_P(MODE)(((enum mode_class) mode_class[MODE]) == MODE_VECTOR_BOOL || ( (enum mode_class) mode_class[MODE]) == MODE_VECTOR_INT || ((enum mode_class) mode_class[MODE]) == MODE_VECTOR_FLOAT || ((enum mode_class) mode_class[MODE]) == MODE_VECTOR_FRACT || ((enum mode_class) mode_class[MODE]) == MODE_VECTOR_UFRACT || ((enum mode_class) mode_class[MODE]) == MODE_VECTOR_ACCUM || ((enum mode_class) mode_class[MODE]) == MODE_VECTOR_UACCUM) \ | |||
128 | (GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_VECTOR_BOOL \ | |||
129 | || GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_VECTOR_INT \ | |||
130 | || GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_VECTOR_FLOAT \ | |||
131 | || GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_VECTOR_FRACT \ | |||
132 | || GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_VECTOR_UFRACT \ | |||
133 | || GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_VECTOR_ACCUM \ | |||
134 | || GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_VECTOR_UACCUM) | |||
135 | ||||
136 | /* Nonzero if MODE is a scalar integral mode. */ | |||
137 | #define SCALAR_INT_MODE_P(MODE)(((enum mode_class) mode_class[MODE]) == MODE_INT || ((enum mode_class ) mode_class[MODE]) == MODE_PARTIAL_INT) \ | |||
138 | (GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_INT \ | |||
139 | || GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_PARTIAL_INT) | |||
140 | ||||
141 | /* Nonzero if MODE is a scalar floating point mode. */ | |||
142 | #define SCALAR_FLOAT_MODE_P(MODE)(((enum mode_class) mode_class[MODE]) == MODE_FLOAT || ((enum mode_class) mode_class[MODE]) == MODE_DECIMAL_FLOAT) \ | |||
143 | (GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_FLOAT \ | |||
144 | || GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_DECIMAL_FLOAT) | |||
145 | ||||
146 | /* Nonzero if MODE is a decimal floating point mode. */ | |||
147 | #define DECIMAL_FLOAT_MODE_P(MODE)(((enum mode_class) mode_class[MODE]) == MODE_DECIMAL_FLOAT) \ | |||
148 | (GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_DECIMAL_FLOAT) | |||
149 | ||||
150 | /* Nonzero if MODE is a scalar fract mode. */ | |||
151 | #define SCALAR_FRACT_MODE_P(MODE)(((enum mode_class) mode_class[MODE]) == MODE_FRACT) \ | |||
152 | (GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_FRACT) | |||
153 | ||||
154 | /* Nonzero if MODE is a scalar ufract mode. */ | |||
155 | #define SCALAR_UFRACT_MODE_P(MODE)(((enum mode_class) mode_class[MODE]) == MODE_UFRACT) \ | |||
156 | (GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_UFRACT) | |||
157 | ||||
158 | /* Nonzero if MODE is a scalar fract or ufract mode. */ | |||
159 | #define ALL_SCALAR_FRACT_MODE_P(MODE)((((enum mode_class) mode_class[MODE]) == MODE_FRACT) || (((enum mode_class) mode_class[MODE]) == MODE_UFRACT)) \ | |||
160 | (SCALAR_FRACT_MODE_P (MODE)(((enum mode_class) mode_class[MODE]) == MODE_FRACT) || SCALAR_UFRACT_MODE_P (MODE)(((enum mode_class) mode_class[MODE]) == MODE_UFRACT)) | |||
161 | ||||
162 | /* Nonzero if MODE is a scalar accum mode. */ | |||
163 | #define SCALAR_ACCUM_MODE_P(MODE)(((enum mode_class) mode_class[MODE]) == MODE_ACCUM) \ | |||
164 | (GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_ACCUM) | |||
165 | ||||
166 | /* Nonzero if MODE is a scalar uaccum mode. */ | |||
167 | #define SCALAR_UACCUM_MODE_P(MODE)(((enum mode_class) mode_class[MODE]) == MODE_UACCUM) \ | |||
168 | (GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_UACCUM) | |||
169 | ||||
170 | /* Nonzero if MODE is a scalar accum or uaccum mode. */ | |||
171 | #define ALL_SCALAR_ACCUM_MODE_P(MODE)((((enum mode_class) mode_class[MODE]) == MODE_ACCUM) || (((enum mode_class) mode_class[MODE]) == MODE_UACCUM)) \ | |||
172 | (SCALAR_ACCUM_MODE_P (MODE)(((enum mode_class) mode_class[MODE]) == MODE_ACCUM) || SCALAR_UACCUM_MODE_P (MODE)(((enum mode_class) mode_class[MODE]) == MODE_UACCUM)) | |||
173 | ||||
174 | /* Nonzero if MODE is a scalar fract or accum mode. */ | |||
175 | #define SIGNED_SCALAR_FIXED_POINT_MODE_P(MODE)((((enum mode_class) mode_class[MODE]) == MODE_FRACT) || (((enum mode_class) mode_class[MODE]) == MODE_ACCUM)) \ | |||
176 | (SCALAR_FRACT_MODE_P (MODE)(((enum mode_class) mode_class[MODE]) == MODE_FRACT) || SCALAR_ACCUM_MODE_P (MODE)(((enum mode_class) mode_class[MODE]) == MODE_ACCUM)) | |||
177 | ||||
178 | /* Nonzero if MODE is a scalar ufract or uaccum mode. */ | |||
179 | #define UNSIGNED_SCALAR_FIXED_POINT_MODE_P(MODE)((((enum mode_class) mode_class[MODE]) == MODE_UFRACT) || ((( enum mode_class) mode_class[MODE]) == MODE_UACCUM)) \ | |||
180 | (SCALAR_UFRACT_MODE_P (MODE)(((enum mode_class) mode_class[MODE]) == MODE_UFRACT) || SCALAR_UACCUM_MODE_P (MODE)(((enum mode_class) mode_class[MODE]) == MODE_UACCUM)) | |||
181 | ||||
182 | /* Nonzero if MODE is a scalar fract, ufract, accum or uaccum mode. */ | |||
183 | #define ALL_SCALAR_FIXED_POINT_MODE_P(MODE)(((((enum mode_class) mode_class[MODE]) == MODE_FRACT) || ((( enum mode_class) mode_class[MODE]) == MODE_ACCUM)) || ((((enum mode_class) mode_class[MODE]) == MODE_UFRACT) || (((enum mode_class ) mode_class[MODE]) == MODE_UACCUM))) \ | |||
184 | (SIGNED_SCALAR_FIXED_POINT_MODE_P (MODE)((((enum mode_class) mode_class[MODE]) == MODE_FRACT) || (((enum mode_class) mode_class[MODE]) == MODE_ACCUM)) \ | |||
185 | || UNSIGNED_SCALAR_FIXED_POINT_MODE_P (MODE)((((enum mode_class) mode_class[MODE]) == MODE_UFRACT) || ((( enum mode_class) mode_class[MODE]) == MODE_UACCUM))) | |||
186 | ||||
187 | /* Nonzero if MODE is a scalar/vector fract mode. */ | |||
188 | #define FRACT_MODE_P(MODE)(((enum mode_class) mode_class[MODE]) == MODE_FRACT || ((enum mode_class) mode_class[MODE]) == MODE_VECTOR_FRACT) \ | |||
189 | (GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_FRACT \ | |||
190 | || GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_VECTOR_FRACT) | |||
191 | ||||
192 | /* Nonzero if MODE is a scalar/vector ufract mode. */ | |||
193 | #define UFRACT_MODE_P(MODE)(((enum mode_class) mode_class[MODE]) == MODE_UFRACT || ((enum mode_class) mode_class[MODE]) == MODE_VECTOR_UFRACT) \ | |||
194 | (GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_UFRACT \ | |||
195 | || GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_VECTOR_UFRACT) | |||
196 | ||||
197 | /* Nonzero if MODE is a scalar/vector fract or ufract mode. */ | |||
198 | #define ALL_FRACT_MODE_P(MODE)((((enum mode_class) mode_class[MODE]) == MODE_FRACT || ((enum mode_class) mode_class[MODE]) == MODE_VECTOR_FRACT) || (((enum mode_class) mode_class[MODE]) == MODE_UFRACT || ((enum mode_class ) mode_class[MODE]) == MODE_VECTOR_UFRACT)) \ | |||
199 | (FRACT_MODE_P (MODE)(((enum mode_class) mode_class[MODE]) == MODE_FRACT || ((enum mode_class) mode_class[MODE]) == MODE_VECTOR_FRACT) || UFRACT_MODE_P (MODE)(((enum mode_class) mode_class[MODE]) == MODE_UFRACT || ((enum mode_class) mode_class[MODE]) == MODE_VECTOR_UFRACT)) | |||
200 | ||||
201 | /* Nonzero if MODE is a scalar/vector accum mode. */ | |||
202 | #define ACCUM_MODE_P(MODE)(((enum mode_class) mode_class[MODE]) == MODE_ACCUM || ((enum mode_class) mode_class[MODE]) == MODE_VECTOR_ACCUM) \ | |||
203 | (GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_ACCUM \ | |||
204 | || GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_VECTOR_ACCUM) | |||
205 | ||||
206 | /* Nonzero if MODE is a scalar/vector uaccum mode. */ | |||
207 | #define UACCUM_MODE_P(MODE)(((enum mode_class) mode_class[MODE]) == MODE_UACCUM || ((enum mode_class) mode_class[MODE]) == MODE_VECTOR_UACCUM) \ | |||
208 | (GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_UACCUM \ | |||
209 | || GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_VECTOR_UACCUM) | |||
210 | ||||
211 | /* Nonzero if MODE is a scalar/vector accum or uaccum mode. */ | |||
212 | #define ALL_ACCUM_MODE_P(MODE)((((enum mode_class) mode_class[MODE]) == MODE_ACCUM || ((enum mode_class) mode_class[MODE]) == MODE_VECTOR_ACCUM) || (((enum mode_class) mode_class[MODE]) == MODE_UACCUM || ((enum mode_class ) mode_class[MODE]) == MODE_VECTOR_UACCUM)) \ | |||
213 | (ACCUM_MODE_P (MODE)(((enum mode_class) mode_class[MODE]) == MODE_ACCUM || ((enum mode_class) mode_class[MODE]) == MODE_VECTOR_ACCUM) || UACCUM_MODE_P (MODE)(((enum mode_class) mode_class[MODE]) == MODE_UACCUM || ((enum mode_class) mode_class[MODE]) == MODE_VECTOR_UACCUM)) | |||
214 | ||||
215 | /* Nonzero if MODE is a scalar/vector fract or accum mode. */ | |||
216 | #define SIGNED_FIXED_POINT_MODE_P(MODE)((((enum mode_class) mode_class[MODE]) == MODE_FRACT || ((enum mode_class) mode_class[MODE]) == MODE_VECTOR_FRACT) || (((enum mode_class) mode_class[MODE]) == MODE_ACCUM || ((enum mode_class ) mode_class[MODE]) == MODE_VECTOR_ACCUM)) \ | |||
217 | (FRACT_MODE_P (MODE)(((enum mode_class) mode_class[MODE]) == MODE_FRACT || ((enum mode_class) mode_class[MODE]) == MODE_VECTOR_FRACT) || ACCUM_MODE_P (MODE)(((enum mode_class) mode_class[MODE]) == MODE_ACCUM || ((enum mode_class) mode_class[MODE]) == MODE_VECTOR_ACCUM)) | |||
218 | ||||
219 | /* Nonzero if MODE is a scalar/vector ufract or uaccum mode. */ | |||
220 | #define UNSIGNED_FIXED_POINT_MODE_P(MODE)((((enum mode_class) mode_class[MODE]) == MODE_UFRACT || ((enum mode_class) mode_class[MODE]) == MODE_VECTOR_UFRACT) || (((enum mode_class) mode_class[MODE]) == MODE_UACCUM || ((enum mode_class ) mode_class[MODE]) == MODE_VECTOR_UACCUM)) \ | |||
221 | (UFRACT_MODE_P (MODE)(((enum mode_class) mode_class[MODE]) == MODE_UFRACT || ((enum mode_class) mode_class[MODE]) == MODE_VECTOR_UFRACT) || UACCUM_MODE_P (MODE)(((enum mode_class) mode_class[MODE]) == MODE_UACCUM || ((enum mode_class) mode_class[MODE]) == MODE_VECTOR_UACCUM)) | |||
222 | ||||
223 | /* Nonzero if MODE is a scalar/vector fract, ufract, accum or uaccum mode. */ | |||
224 | #define ALL_FIXED_POINT_MODE_P(MODE)(((((enum mode_class) mode_class[MODE]) == MODE_FRACT || ((enum mode_class) mode_class[MODE]) == MODE_VECTOR_FRACT) || (((enum mode_class) mode_class[MODE]) == MODE_ACCUM || ((enum mode_class ) mode_class[MODE]) == MODE_VECTOR_ACCUM)) || ((((enum mode_class ) mode_class[MODE]) == MODE_UFRACT || ((enum mode_class) mode_class [MODE]) == MODE_VECTOR_UFRACT) || (((enum mode_class) mode_class [MODE]) == MODE_UACCUM || ((enum mode_class) mode_class[MODE] ) == MODE_VECTOR_UACCUM))) \ | |||
225 | (SIGNED_FIXED_POINT_MODE_P (MODE)((((enum mode_class) mode_class[MODE]) == MODE_FRACT || ((enum mode_class) mode_class[MODE]) == MODE_VECTOR_FRACT) || (((enum mode_class) mode_class[MODE]) == MODE_ACCUM || ((enum mode_class ) mode_class[MODE]) == MODE_VECTOR_ACCUM)) \ | |||
226 | || UNSIGNED_FIXED_POINT_MODE_P (MODE)((((enum mode_class) mode_class[MODE]) == MODE_UFRACT || ((enum mode_class) mode_class[MODE]) == MODE_VECTOR_UFRACT) || (((enum mode_class) mode_class[MODE]) == MODE_UACCUM || ((enum mode_class ) mode_class[MODE]) == MODE_VECTOR_UACCUM))) | |||
227 | ||||
228 | /* Nonzero if MODE is opaque. */ | |||
229 | #define OPAQUE_MODE_P(MODE)(((enum mode_class) mode_class[MODE]) == MODE_OPAQUE) \ | |||
230 | (GET_MODE_CLASS (MODE)((enum mode_class) mode_class[MODE]) == MODE_OPAQUE) | |||
231 | ||||
232 | /* Nonzero if CLASS modes can be widened. */ | |||
233 | #define CLASS_HAS_WIDER_MODES_P(CLASS)(CLASS == MODE_INT || CLASS == MODE_PARTIAL_INT || CLASS == MODE_FLOAT || CLASS == MODE_DECIMAL_FLOAT || CLASS == MODE_COMPLEX_FLOAT || CLASS == MODE_FRACT || CLASS == MODE_UFRACT || CLASS == MODE_ACCUM || CLASS == MODE_UACCUM) \ | |||
234 | (CLASS == MODE_INT \ | |||
235 | || CLASS == MODE_PARTIAL_INT \ | |||
236 | || CLASS == MODE_FLOAT \ | |||
237 | || CLASS == MODE_DECIMAL_FLOAT \ | |||
238 | || CLASS == MODE_COMPLEX_FLOAT \ | |||
239 | || CLASS == MODE_FRACT \ | |||
240 | || CLASS == MODE_UFRACT \ | |||
241 | || CLASS == MODE_ACCUM \ | |||
242 | || CLASS == MODE_UACCUM) | |||
243 | ||||
244 | /* An optional T (i.e. a T or nothing), where T is some form of mode class. */ | |||
245 | template<typename T> | |||
246 | class opt_mode | |||
247 | { | |||
248 | public: | |||
249 | enum from_int { dummy = MAX_MACHINE_MODE }; | |||
250 | ||||
251 | ALWAYS_INLINEinline __attribute__ ((always_inline)) CONSTEXPRconstexpr opt_mode () : m_mode (E_VOIDmode) {} | |||
252 | ALWAYS_INLINEinline __attribute__ ((always_inline)) CONSTEXPRconstexpr opt_mode (const T &m) : m_mode (m) {} | |||
253 | template<typename U> | |||
254 | ALWAYS_INLINEinline __attribute__ ((always_inline)) CONSTEXPRconstexpr opt_mode (const U &m) : m_mode (T (m)) {} | |||
255 | ALWAYS_INLINEinline __attribute__ ((always_inline)) CONSTEXPRconstexpr opt_mode (from_int m) : m_mode (machine_mode (m)) {} | |||
256 | ||||
257 | machine_mode else_void () const; | |||
258 | machine_mode else_blk () const { return else_mode (BLKmode((void) 0, E_BLKmode)); } | |||
259 | machine_mode else_mode (machine_mode) const; | |||
260 | T require () const; | |||
261 | ||||
262 | bool exists () const; | |||
263 | template<typename U> bool exists (U *) const; | |||
264 | ||||
265 | bool operator== (const T &m) const { return m_mode == m; } | |||
266 | bool operator!= (const T &m) const { return m_mode != m; } | |||
267 | ||||
268 | private: | |||
269 | machine_mode m_mode; | |||
270 | }; | |||
271 | ||||
272 | /* If the object contains a T, return its enum value, otherwise return | |||
273 | E_VOIDmode. */ | |||
274 | ||||
275 | template<typename T> | |||
276 | ALWAYS_INLINEinline __attribute__ ((always_inline)) machine_mode | |||
277 | opt_mode<T>::else_void () const | |||
278 | { | |||
279 | return m_mode; | |||
280 | } | |||
281 | ||||
282 | /* If the T exists, return its enum value, otherwise return FALLBACK. */ | |||
283 | ||||
284 | template<typename T> | |||
285 | inline machine_mode | |||
286 | opt_mode<T>::else_mode (machine_mode fallback) const | |||
287 | { | |||
288 | return m_mode == E_VOIDmode ? fallback : m_mode; | |||
289 | } | |||
290 | ||||
291 | /* Assert that the object contains a T and return it. */ | |||
292 | ||||
293 | template<typename T> | |||
294 | inline T | |||
295 | opt_mode<T>::require () const | |||
296 | { | |||
297 | gcc_checking_assert (m_mode != E_VOIDmode)((void)(!(m_mode != E_VOIDmode) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/machmode.h" , 297, __FUNCTION__), 0 : 0)); | |||
298 | return typename mode_traits<T>::from_int (m_mode); | |||
299 | } | |||
300 | ||||
301 | /* Return true if the object contains a T rather than nothing. */ | |||
302 | ||||
303 | template<typename T> | |||
304 | ALWAYS_INLINEinline __attribute__ ((always_inline)) bool | |||
305 | opt_mode<T>::exists () const | |||
306 | { | |||
307 | return m_mode != E_VOIDmode; | |||
308 | } | |||
309 | ||||
310 | /* Return true if the object contains a T, storing it in *MODE if so. */ | |||
311 | ||||
312 | template<typename T> | |||
313 | template<typename U> | |||
314 | inline bool | |||
315 | opt_mode<T>::exists (U *mode) const | |||
316 | { | |||
317 | if (m_mode != E_VOIDmode) | |||
318 | { | |||
319 | *mode = T (typename mode_traits<T>::from_int (m_mode)); | |||
320 | return true; | |||
321 | } | |||
322 | return false; | |||
323 | } | |||
324 | ||||
325 | /* A POD version of mode class T. */ | |||
326 | ||||
327 | template<typename T> | |||
328 | struct pod_mode | |||
329 | { | |||
330 | typedef typename mode_traits<T>::from_int from_int; | |||
331 | typedef typename T::measurement_type measurement_type; | |||
332 | ||||
333 | machine_mode m_mode; | |||
334 | ALWAYS_INLINEinline __attribute__ ((always_inline)) CONSTEXPRconstexpr | |||
335 | operator machine_mode () const { return m_mode; } | |||
336 | ||||
337 | ALWAYS_INLINEinline __attribute__ ((always_inline)) CONSTEXPRconstexpr | |||
338 | operator T () const { return from_int (m_mode); } | |||
339 | ||||
340 | ALWAYS_INLINEinline __attribute__ ((always_inline)) pod_mode &operator = (const T &m) { m_mode = m; return *this; } | |||
341 | }; | |||
342 | ||||
343 | /* Return true if mode M has type T. */ | |||
344 | ||||
345 | template<typename T> | |||
346 | inline bool | |||
347 | is_a (machine_mode m) | |||
348 | { | |||
349 | return T::includes_p (m); | |||
350 | } | |||
351 | ||||
352 | template<typename T, typename U> | |||
353 | inline bool | |||
354 | is_a (const opt_mode<U> &m) | |||
355 | { | |||
356 | return T::includes_p (m.else_void ()); | |||
357 | } | |||
358 | ||||
359 | /* Assert that mode M has type T, and return it in that form. */ | |||
360 | ||||
361 | template<typename T> | |||
362 | inline T | |||
363 | as_a (machine_mode m) | |||
364 | { | |||
365 | gcc_checking_assert (T::includes_p (m))((void)(!(T::includes_p (m)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/machmode.h" , 365, __FUNCTION__), 0 : 0)); | |||
366 | return typename mode_traits<T>::from_int (m); | |||
367 | } | |||
368 | ||||
369 | template<typename T, typename U> | |||
370 | inline T | |||
371 | as_a (const opt_mode<U> &m) | |||
372 | { | |||
373 | return as_a <T> (m.else_void ()); | |||
374 | } | |||
375 | ||||
376 | /* Convert M to an opt_mode<T>. */ | |||
377 | ||||
378 | template<typename T> | |||
379 | inline opt_mode<T> | |||
380 | dyn_cast (machine_mode m) | |||
381 | { | |||
382 | if (T::includes_p (m)) | |||
383 | return T (typename mode_traits<T>::from_int (m)); | |||
384 | return opt_mode<T> (); | |||
385 | } | |||
386 | ||||
387 | template<typename T, typename U> | |||
388 | inline opt_mode<T> | |||
389 | dyn_cast (const opt_mode<U> &m) | |||
390 | { | |||
391 | return dyn_cast <T> (m.else_void ()); | |||
392 | } | |||
393 | ||||
394 | /* Return true if mode M has type T, storing it as a T in *RESULT | |||
395 | if so. */ | |||
396 | ||||
397 | template<typename T, typename U> | |||
398 | inline bool | |||
399 | is_a (machine_mode m, U *result) | |||
400 | { | |||
401 | if (T::includes_p (m)) | |||
402 | { | |||
403 | *result = T (typename mode_traits<T>::from_int (m)); | |||
404 | return true; | |||
405 | } | |||
406 | return false; | |||
407 | } | |||
408 | ||||
409 | /* Represents a machine mode that is known to be a SCALAR_INT_MODE_P. */ | |||
410 | class scalar_int_mode | |||
411 | { | |||
412 | public: | |||
413 | typedef mode_traits<scalar_int_mode>::from_int from_int; | |||
414 | typedef unsigned short measurement_type; | |||
415 | ||||
416 | ALWAYS_INLINEinline __attribute__ ((always_inline)) scalar_int_mode () {} | |||
417 | ||||
418 | ALWAYS_INLINEinline __attribute__ ((always_inline)) CONSTEXPRconstexpr | |||
419 | scalar_int_mode (from_int m) : m_mode (machine_mode (m)) {} | |||
420 | ||||
421 | ALWAYS_INLINEinline __attribute__ ((always_inline)) CONSTEXPRconstexpr operator machine_mode () const { return m_mode; } | |||
| ||||
422 | ||||
423 | static bool includes_p (machine_mode); | |||
424 | ||||
425 | protected: | |||
426 | machine_mode m_mode; | |||
427 | }; | |||
428 | ||||
429 | /* Return true if M is a scalar_int_mode. */ | |||
430 | ||||
431 | inline bool | |||
432 | scalar_int_mode::includes_p (machine_mode m) | |||
433 | { | |||
434 | return SCALAR_INT_MODE_P (m)(((enum mode_class) mode_class[m]) == MODE_INT || ((enum mode_class ) mode_class[m]) == MODE_PARTIAL_INT); | |||
435 | } | |||
436 | ||||
437 | /* Represents a machine mode that is known to be a SCALAR_FLOAT_MODE_P. */ | |||
438 | class scalar_float_mode | |||
439 | { | |||
440 | public: | |||
441 | typedef mode_traits<scalar_float_mode>::from_int from_int; | |||
442 | typedef unsigned short measurement_type; | |||
443 | ||||
444 | ALWAYS_INLINEinline __attribute__ ((always_inline)) scalar_float_mode () {} | |||
445 | ||||
446 | ALWAYS_INLINEinline __attribute__ ((always_inline)) CONSTEXPRconstexpr | |||
447 | scalar_float_mode (from_int m) : m_mode (machine_mode (m)) {} | |||
448 | ||||
449 | ALWAYS_INLINEinline __attribute__ ((always_inline)) CONSTEXPRconstexpr operator machine_mode () const { return m_mode; } | |||
450 | ||||
451 | static bool includes_p (machine_mode); | |||
452 | ||||
453 | protected: | |||
454 | machine_mode m_mode; | |||
455 | }; | |||
456 | ||||
457 | /* Return true if M is a scalar_float_mode. */ | |||
458 | ||||
459 | inline bool | |||
460 | scalar_float_mode::includes_p (machine_mode m) | |||
461 | { | |||
462 | return SCALAR_FLOAT_MODE_P (m)(((enum mode_class) mode_class[m]) == MODE_FLOAT || ((enum mode_class ) mode_class[m]) == MODE_DECIMAL_FLOAT); | |||
463 | } | |||
464 | ||||
465 | /* Represents a machine mode that is known to be scalar. */ | |||
466 | class scalar_mode | |||
467 | { | |||
468 | public: | |||
469 | typedef mode_traits<scalar_mode>::from_int from_int; | |||
470 | typedef unsigned short measurement_type; | |||
471 | ||||
472 | ALWAYS_INLINEinline __attribute__ ((always_inline)) scalar_mode () {} | |||
473 | ||||
474 | ALWAYS_INLINEinline __attribute__ ((always_inline)) CONSTEXPRconstexpr | |||
475 | scalar_mode (from_int m) : m_mode (machine_mode (m)) {} | |||
476 | ||||
477 | ALWAYS_INLINEinline __attribute__ ((always_inline)) CONSTEXPRconstexpr | |||
478 | scalar_mode (const scalar_int_mode &m) : m_mode (m) {} | |||
479 | ||||
480 | ALWAYS_INLINEinline __attribute__ ((always_inline)) CONSTEXPRconstexpr | |||
481 | scalar_mode (const scalar_float_mode &m) : m_mode (m) {} | |||
482 | ||||
483 | ALWAYS_INLINEinline __attribute__ ((always_inline)) CONSTEXPRconstexpr | |||
484 | scalar_mode (const scalar_int_mode_pod &m) : m_mode (m) {} | |||
485 | ||||
486 | ALWAYS_INLINEinline __attribute__ ((always_inline)) CONSTEXPRconstexpr operator machine_mode () const { return m_mode; } | |||
487 | ||||
488 | static bool includes_p (machine_mode); | |||
489 | ||||
490 | protected: | |||
491 | machine_mode m_mode; | |||
492 | }; | |||
493 | ||||
494 | /* Return true if M represents some kind of scalar value. */ | |||
495 | ||||
496 | inline bool | |||
497 | scalar_mode::includes_p (machine_mode m) | |||
498 | { | |||
499 | switch (GET_MODE_CLASS (m)((enum mode_class) mode_class[m])) | |||
500 | { | |||
501 | case MODE_INT: | |||
502 | case MODE_PARTIAL_INT: | |||
503 | case MODE_FRACT: | |||
504 | case MODE_UFRACT: | |||
505 | case MODE_ACCUM: | |||
506 | case MODE_UACCUM: | |||
507 | case MODE_FLOAT: | |||
508 | case MODE_DECIMAL_FLOAT: | |||
509 | return true; | |||
510 | default: | |||
511 | return false; | |||
512 | } | |||
513 | } | |||
514 | ||||
515 | /* Represents a machine mode that is known to be a COMPLEX_MODE_P. */ | |||
516 | class complex_mode | |||
517 | { | |||
518 | public: | |||
519 | typedef mode_traits<complex_mode>::from_int from_int; | |||
520 | typedef unsigned short measurement_type; | |||
521 | ||||
522 | ALWAYS_INLINEinline __attribute__ ((always_inline)) complex_mode () {} | |||
523 | ||||
524 | ALWAYS_INLINEinline __attribute__ ((always_inline)) CONSTEXPRconstexpr | |||
525 | complex_mode (from_int m) : m_mode (machine_mode (m)) {} | |||
526 | ||||
527 | ALWAYS_INLINEinline __attribute__ ((always_inline)) CONSTEXPRconstexpr operator machine_mode () const { return m_mode; } | |||
528 | ||||
529 | static bool includes_p (machine_mode); | |||
530 | ||||
531 | protected: | |||
532 | machine_mode m_mode; | |||
533 | }; | |||
534 | ||||
535 | /* Return true if M is a complex_mode. */ | |||
536 | ||||
537 | inline bool | |||
538 | complex_mode::includes_p (machine_mode m) | |||
539 | { | |||
540 | return COMPLEX_MODE_P (m)(((enum mode_class) mode_class[m]) == MODE_COMPLEX_INT || ((enum mode_class) mode_class[m]) == MODE_COMPLEX_FLOAT); | |||
541 | } | |||
542 | ||||
543 | /* Return the base GET_MODE_SIZE value for MODE. */ | |||
544 | ||||
545 | ALWAYS_INLINEinline __attribute__ ((always_inline)) poly_uint16 | |||
546 | mode_to_bytes (machine_mode mode) | |||
547 | { | |||
548 | #if GCC_VERSION(4 * 1000 + 2) >= 4001 | |||
549 | return (__builtin_constant_p (mode) | |||
550 | ? mode_size_inline (mode) : mode_size[mode]); | |||
551 | #else | |||
552 | return mode_size[mode]; | |||
553 | #endif | |||
554 | } | |||
555 | ||||
556 | /* Return the base GET_MODE_BITSIZE value for MODE. */ | |||
557 | ||||
558 | ALWAYS_INLINEinline __attribute__ ((always_inline)) poly_uint16 | |||
559 | mode_to_bits (machine_mode mode) | |||
560 | { | |||
561 | return mode_to_bytes (mode) * BITS_PER_UNIT(8); | |||
562 | } | |||
563 | ||||
564 | /* Return the base GET_MODE_PRECISION value for MODE. */ | |||
565 | ||||
566 | ALWAYS_INLINEinline __attribute__ ((always_inline)) poly_uint16 | |||
567 | mode_to_precision (machine_mode mode) | |||
568 | { | |||
569 | return mode_precision[mode]; | |||
570 | } | |||
571 | ||||
572 | /* Return the base GET_MODE_INNER value for MODE. */ | |||
573 | ||||
574 | ALWAYS_INLINEinline __attribute__ ((always_inline)) scalar_mode | |||
575 | mode_to_inner (machine_mode mode) | |||
576 | { | |||
577 | #if GCC_VERSION(4 * 1000 + 2) >= 4001 | |||
578 | return scalar_mode::from_int (__builtin_constant_p (mode) | |||
579 | ? mode_inner_inline (mode) | |||
580 | : mode_inner[mode]); | |||
581 | #else | |||
582 | return scalar_mode::from_int (mode_inner[mode]); | |||
583 | #endif | |||
584 | } | |||
585 | ||||
586 | /* Return the base GET_MODE_UNIT_SIZE value for MODE. */ | |||
587 | ||||
588 | ALWAYS_INLINEinline __attribute__ ((always_inline)) unsigned char | |||
589 | mode_to_unit_size (machine_mode mode) | |||
590 | { | |||
591 | #if GCC_VERSION(4 * 1000 + 2) >= 4001 | |||
592 | return (__builtin_constant_p (mode) | |||
593 | ? mode_unit_size_inline (mode) : mode_unit_size[mode]); | |||
594 | #else | |||
595 | return mode_unit_size[mode]; | |||
596 | #endif | |||
597 | } | |||
598 | ||||
599 | /* Return the base GET_MODE_UNIT_PRECISION value for MODE. */ | |||
600 | ||||
601 | ALWAYS_INLINEinline __attribute__ ((always_inline)) unsigned short | |||
602 | mode_to_unit_precision (machine_mode mode) | |||
603 | { | |||
604 | #if GCC_VERSION(4 * 1000 + 2) >= 4001 | |||
605 | return (__builtin_constant_p (mode) | |||
606 | ? mode_unit_precision_inline (mode) : mode_unit_precision[mode]); | |||
607 | #else | |||
608 | return mode_unit_precision[mode]; | |||
609 | #endif | |||
610 | } | |||
611 | ||||
612 | /* Return the base GET_MODE_NUNITS value for MODE. */ | |||
613 | ||||
614 | ALWAYS_INLINEinline __attribute__ ((always_inline)) poly_uint16 | |||
615 | mode_to_nunits (machine_mode mode) | |||
616 | { | |||
617 | #if GCC_VERSION(4 * 1000 + 2) >= 4001 | |||
618 | return (__builtin_constant_p (mode) | |||
619 | ? mode_nunits_inline (mode) : mode_nunits[mode]); | |||
620 | #else | |||
621 | return mode_nunits[mode]; | |||
622 | #endif | |||
623 | } | |||
624 | ||||
625 | /* Get the size in bytes of an object of mode MODE. */ | |||
626 | ||||
627 | #if ONLY_FIXED_SIZE_MODES0 | |||
628 | #define GET_MODE_SIZE(MODE) ((unsigned short) mode_to_bytes (MODE).coeffs[0]) | |||
629 | #else | |||
630 | ALWAYS_INLINEinline __attribute__ ((always_inline)) poly_uint16 | |||
631 | GET_MODE_SIZE (machine_mode mode) | |||
632 | { | |||
633 | return mode_to_bytes (mode); | |||
634 | } | |||
635 | ||||
636 | template<typename T> | |||
637 | ALWAYS_INLINEinline __attribute__ ((always_inline)) typename if_poly<typename T::measurement_type>::type | |||
638 | GET_MODE_SIZE (const T &mode) | |||
639 | { | |||
640 | return mode_to_bytes (mode); | |||
641 | } | |||
642 | ||||
643 | template<typename T> | |||
644 | ALWAYS_INLINEinline __attribute__ ((always_inline)) typename if_nonpoly<typename T::measurement_type>::type | |||
645 | GET_MODE_SIZE (const T &mode) | |||
646 | { | |||
647 | return mode_to_bytes (mode).coeffs[0]; | |||
648 | } | |||
649 | #endif | |||
650 | ||||
651 | /* Get the size in bits of an object of mode MODE. */ | |||
652 | ||||
653 | #if ONLY_FIXED_SIZE_MODES0 | |||
654 | #define GET_MODE_BITSIZE(MODE) ((unsigned short) mode_to_bits (MODE).coeffs[0]) | |||
655 | #else | |||
656 | ALWAYS_INLINEinline __attribute__ ((always_inline)) poly_uint16 | |||
657 | GET_MODE_BITSIZE (machine_mode mode) | |||
658 | { | |||
659 | return mode_to_bits (mode); | |||
660 | } | |||
661 | ||||
662 | template<typename T> | |||
663 | ALWAYS_INLINEinline __attribute__ ((always_inline)) typename if_poly<typename T::measurement_type>::type | |||
664 | GET_MODE_BITSIZE (const T &mode) | |||
665 | { | |||
666 | return mode_to_bits (mode); | |||
667 | } | |||
668 | ||||
669 | template<typename T> | |||
670 | ALWAYS_INLINEinline __attribute__ ((always_inline)) typename if_nonpoly<typename T::measurement_type>::type | |||
671 | GET_MODE_BITSIZE (const T &mode) | |||
672 | { | |||
673 | return mode_to_bits (mode).coeffs[0]; | |||
674 | } | |||
675 | #endif | |||
676 | ||||
677 | /* Get the number of value bits of an object of mode MODE. */ | |||
678 | ||||
679 | #if ONLY_FIXED_SIZE_MODES0 | |||
680 | #define GET_MODE_PRECISION(MODE) \ | |||
681 | ((unsigned short) mode_to_precision (MODE).coeffs[0]) | |||
682 | #else | |||
683 | ALWAYS_INLINEinline __attribute__ ((always_inline)) poly_uint16 | |||
684 | GET_MODE_PRECISION (machine_mode mode) | |||
685 | { | |||
686 | return mode_to_precision (mode); | |||
687 | } | |||
688 | ||||
689 | template<typename T> | |||
690 | ALWAYS_INLINEinline __attribute__ ((always_inline)) typename if_poly<typename T::measurement_type>::type | |||
691 | GET_MODE_PRECISION (const T &mode) | |||
692 | { | |||
693 | return mode_to_precision (mode); | |||
694 | } | |||
695 | ||||
696 | template<typename T> | |||
697 | ALWAYS_INLINEinline __attribute__ ((always_inline)) typename if_nonpoly<typename T::measurement_type>::type | |||
698 | GET_MODE_PRECISION (const T &mode) | |||
699 | { | |||
700 | return mode_to_precision (mode).coeffs[0]; | |||
701 | } | |||
702 | #endif | |||
703 | ||||
704 | /* Get the number of integral bits of an object of mode MODE. */ | |||
705 | extern CONST_MODE_IBITconst unsigned char mode_ibit[NUM_MACHINE_MODES]; | |||
706 | #define GET_MODE_IBIT(MODE)mode_ibit[MODE] mode_ibit[MODE] | |||
707 | ||||
708 | /* Get the number of fractional bits of an object of mode MODE. */ | |||
709 | extern CONST_MODE_FBITconst unsigned char mode_fbit[NUM_MACHINE_MODES]; | |||
710 | #define GET_MODE_FBIT(MODE)mode_fbit[MODE] mode_fbit[MODE] | |||
711 | ||||
712 | /* Get a bitmask containing 1 for all bits in a word | |||
713 | that fit within mode MODE. */ | |||
714 | ||||
715 | extern CONST_MODE_MASKconst unsigned HOST_WIDE_INTlong | |||
716 | mode_mask_array[NUM_MACHINE_MODES]; | |||
717 | ||||
718 | #define GET_MODE_MASK(MODE)mode_mask_array[MODE] mode_mask_array[MODE] | |||
719 | ||||
720 | /* Return the mode of the basic parts of MODE. For vector modes this is the | |||
721 | mode of the vector elements. For complex modes it is the mode of the real | |||
722 | and imaginary parts. For other modes it is MODE itself. */ | |||
723 | ||||
724 | #define GET_MODE_INNER(MODE)(mode_to_inner (MODE)) (mode_to_inner (MODE)) | |||
725 | ||||
726 | /* Get the size in bytes or bits of the basic parts of an | |||
727 | object of mode MODE. */ | |||
728 | ||||
729 | #define GET_MODE_UNIT_SIZE(MODE)mode_to_unit_size (MODE) mode_to_unit_size (MODE) | |||
730 | ||||
731 | #define GET_MODE_UNIT_BITSIZE(MODE)((unsigned short) (mode_to_unit_size (MODE) * (8))) \ | |||
732 | ((unsigned short) (GET_MODE_UNIT_SIZE (MODE)mode_to_unit_size (MODE) * BITS_PER_UNIT(8))) | |||
733 | ||||
734 | #define GET_MODE_UNIT_PRECISION(MODE)(mode_to_unit_precision (MODE)) (mode_to_unit_precision (MODE)) | |||
735 | ||||
736 | /* Get the number of units in an object of mode MODE. This is 2 for | |||
737 | complex modes and the number of elements for vector modes. */ | |||
738 | ||||
739 | #if ONLY_FIXED_SIZE_MODES0 | |||
740 | #define GET_MODE_NUNITS(MODE) (mode_to_nunits (MODE).coeffs[0]) | |||
741 | #else | |||
742 | ALWAYS_INLINEinline __attribute__ ((always_inline)) poly_uint16 | |||
743 | GET_MODE_NUNITS (machine_mode mode) | |||
744 | { | |||
745 | return mode_to_nunits (mode); | |||
746 | } | |||
747 | ||||
748 | template<typename T> | |||
749 | ALWAYS_INLINEinline __attribute__ ((always_inline)) typename if_poly<typename T::measurement_type>::type | |||
750 | GET_MODE_NUNITS (const T &mode) | |||
751 | { | |||
752 | return mode_to_nunits (mode); | |||
753 | } | |||
754 | ||||
755 | template<typename T> | |||
756 | ALWAYS_INLINEinline __attribute__ ((always_inline)) typename if_nonpoly<typename T::measurement_type>::type | |||
757 | GET_MODE_NUNITS (const T &mode) | |||
758 | { | |||
759 | return mode_to_nunits (mode).coeffs[0]; | |||
760 | } | |||
761 | #endif | |||
762 | ||||
763 | /* Get the next wider natural mode (eg, QI -> HI -> SI -> DI -> TI). */ | |||
764 | ||||
765 | template<typename T> | |||
766 | ALWAYS_INLINEinline __attribute__ ((always_inline)) opt_mode<T> | |||
767 | GET_MODE_WIDER_MODE (const T &m) | |||
768 | { | |||
769 | return typename opt_mode<T>::from_int (mode_wider[m]); | |||
770 | } | |||
771 | ||||
772 | /* For scalars, this is a mode with twice the precision. For vectors, | |||
773 | this is a mode with the same inner mode but with twice the elements. */ | |||
774 | ||||
775 | template<typename T> | |||
776 | ALWAYS_INLINEinline __attribute__ ((always_inline)) opt_mode<T> | |||
777 | GET_MODE_2XWIDER_MODE (const T &m) | |||
778 | { | |||
779 | return typename opt_mode<T>::from_int (mode_2xwider[m]); | |||
780 | } | |||
781 | ||||
782 | /* Get the complex mode from the component mode. */ | |||
783 | extern const unsigned char mode_complex[NUM_MACHINE_MODES]; | |||
784 | #define GET_MODE_COMPLEX_MODE(MODE)((machine_mode) mode_complex[MODE]) ((machine_mode) mode_complex[MODE]) | |||
785 | ||||
786 | /* Represents a machine mode that must have a fixed size. The main | |||
787 | use of this class is to represent the modes of objects that always | |||
788 | have static storage duration, such as constant pool entries. | |||
789 | (No current target supports the concept of variable-size static data.) */ | |||
790 | class fixed_size_mode | |||
791 | { | |||
792 | public: | |||
793 | typedef mode_traits<fixed_size_mode>::from_int from_int; | |||
794 | typedef unsigned short measurement_type; | |||
795 | ||||
796 | ALWAYS_INLINEinline __attribute__ ((always_inline)) fixed_size_mode () {} | |||
797 | ||||
798 | ALWAYS_INLINEinline __attribute__ ((always_inline)) CONSTEXPRconstexpr | |||
799 | fixed_size_mode (from_int m) : m_mode (machine_mode (m)) {} | |||
800 | ||||
801 | ALWAYS_INLINEinline __attribute__ ((always_inline)) CONSTEXPRconstexpr | |||
802 | fixed_size_mode (const scalar_mode &m) : m_mode (m) {} | |||
803 | ||||
804 | ALWAYS_INLINEinline __attribute__ ((always_inline)) CONSTEXPRconstexpr | |||
805 | fixed_size_mode (const scalar_int_mode &m) : m_mode (m) {} | |||
806 | ||||
807 | ALWAYS_INLINEinline __attribute__ ((always_inline)) CONSTEXPRconstexpr | |||
808 | fixed_size_mode (const scalar_float_mode &m) : m_mode (m) {} | |||
809 | ||||
810 | ALWAYS_INLINEinline __attribute__ ((always_inline)) CONSTEXPRconstexpr | |||
811 | fixed_size_mode (const scalar_mode_pod &m) : m_mode (m) {} | |||
812 | ||||
813 | ALWAYS_INLINEinline __attribute__ ((always_inline)) CONSTEXPRconstexpr | |||
814 | fixed_size_mode (const scalar_int_mode_pod &m) : m_mode (m) {} | |||
815 | ||||
816 | ALWAYS_INLINEinline __attribute__ ((always_inline)) CONSTEXPRconstexpr | |||
817 | fixed_size_mode (const complex_mode &m) : m_mode (m) {} | |||
818 | ||||
819 | ALWAYS_INLINEinline __attribute__ ((always_inline)) CONSTEXPRconstexpr operator machine_mode () const { return m_mode; } | |||
820 | ||||
821 | static bool includes_p (machine_mode); | |||
822 | ||||
823 | protected: | |||
824 | machine_mode m_mode; | |||
825 | }; | |||
826 | ||||
827 | /* Return true if MODE has a fixed size. */ | |||
828 | ||||
829 | inline bool | |||
830 | fixed_size_mode::includes_p (machine_mode mode) | |||
831 | { | |||
832 | return mode_to_bytes (mode).is_constant (); | |||
833 | } | |||
834 | ||||
835 | /* Wrapper for mode arguments to target macros, so that if a target | |||
836 | doesn't need polynomial-sized modes, its header file can continue | |||
837 | to treat everything as fixed_size_mode. This should go away once | |||
838 | macros are moved to target hooks. It shouldn't be used in other | |||
839 | contexts. */ | |||
840 | #if NUM_POLY_INT_COEFFS1 == 1 | |||
841 | #define MACRO_MODE(MODE)(as_a <fixed_size_mode> (MODE)) (as_a <fixed_size_mode> (MODE)) | |||
842 | #else | |||
843 | #define MACRO_MODE(MODE)(as_a <fixed_size_mode> (MODE)) (MODE) | |||
844 | #endif | |||
845 | ||||
846 | extern opt_machine_mode mode_for_size (poly_uint64, enum mode_class, int); | |||
847 | ||||
848 | /* Return the machine mode to use for a MODE_INT of SIZE bits, if one | |||
849 | exists. If LIMIT is nonzero, modes wider than MAX_FIXED_MODE_SIZE | |||
850 | will not be used. */ | |||
851 | ||||
852 | inline opt_scalar_int_mode | |||
853 | int_mode_for_size (poly_uint64 size, int limit) | |||
854 | { | |||
855 | return dyn_cast <scalar_int_mode> (mode_for_size (size, MODE_INT, limit)); | |||
856 | } | |||
857 | ||||
858 | /* Return the machine mode to use for a MODE_FLOAT of SIZE bits, if one | |||
859 | exists. */ | |||
860 | ||||
861 | inline opt_scalar_float_mode | |||
862 | float_mode_for_size (poly_uint64 size) | |||
863 | { | |||
864 | return dyn_cast <scalar_float_mode> (mode_for_size (size, MODE_FLOAT, 0)); | |||
865 | } | |||
866 | ||||
867 | /* Likewise for MODE_DECIMAL_FLOAT. */ | |||
868 | ||||
869 | inline opt_scalar_float_mode | |||
870 | decimal_float_mode_for_size (unsigned int size) | |||
871 | { | |||
872 | return dyn_cast <scalar_float_mode> | |||
873 | (mode_for_size (size, MODE_DECIMAL_FLOAT, 0)); | |||
874 | } | |||
875 | ||||
876 | extern machine_mode smallest_mode_for_size (poly_uint64, enum mode_class); | |||
877 | ||||
878 | /* Find the narrowest integer mode that contains at least SIZE bits. | |||
879 | Such a mode must exist. */ | |||
880 | ||||
881 | inline scalar_int_mode | |||
882 | smallest_int_mode_for_size (poly_uint64 size) | |||
883 | { | |||
884 | return as_a <scalar_int_mode> (smallest_mode_for_size (size, MODE_INT)); | |||
885 | } | |||
886 | ||||
887 | extern opt_scalar_int_mode int_mode_for_mode (machine_mode); | |||
888 | extern opt_machine_mode bitwise_mode_for_mode (machine_mode); | |||
889 | extern opt_machine_mode mode_for_vector (scalar_mode, poly_uint64); | |||
890 | extern opt_machine_mode related_vector_mode (machine_mode, scalar_mode, | |||
891 | poly_uint64 = 0); | |||
892 | extern opt_machine_mode related_int_vector_mode (machine_mode); | |||
893 | ||||
894 | /* A class for iterating through possible bitfield modes. */ | |||
895 | class bit_field_mode_iterator | |||
896 | { | |||
897 | public: | |||
898 | bit_field_mode_iterator (HOST_WIDE_INTlong, HOST_WIDE_INTlong, | |||
899 | poly_int64, poly_int64, | |||
900 | unsigned int, bool); | |||
901 | bool next_mode (scalar_int_mode *); | |||
902 | bool prefer_smaller_modes (); | |||
903 | ||||
904 | private: | |||
905 | opt_scalar_int_mode m_mode; | |||
906 | /* We use signed values here because the bit position can be negative | |||
907 | for invalid input such as gcc.dg/pr48335-8.c. */ | |||
908 | HOST_WIDE_INTlong m_bitsize; | |||
909 | HOST_WIDE_INTlong m_bitpos; | |||
910 | poly_int64 m_bitregion_start; | |||
911 | poly_int64 m_bitregion_end; | |||
912 | unsigned int m_align; | |||
913 | bool m_volatilep; | |||
914 | int m_count; | |||
915 | }; | |||
916 | ||||
917 | /* Find the best mode to use to access a bit field. */ | |||
918 | ||||
919 | extern bool get_best_mode (int, int, poly_uint64, poly_uint64, unsigned int, | |||
920 | unsigned HOST_WIDE_INTlong, bool, scalar_int_mode *); | |||
921 | ||||
922 | /* Determine alignment, 1<=result<=BIGGEST_ALIGNMENT. */ | |||
923 | ||||
924 | extern CONST_MODE_BASE_ALIGN unsigned short mode_base_align[NUM_MACHINE_MODES]; | |||
925 | ||||
926 | extern unsigned get_mode_alignment (machine_mode); | |||
927 | ||||
928 | #define GET_MODE_ALIGNMENT(MODE)get_mode_alignment (MODE) get_mode_alignment (MODE) | |||
929 | ||||
930 | /* For each class, get the narrowest mode in that class. */ | |||
931 | ||||
932 | extern const unsigned char class_narrowest_mode[MAX_MODE_CLASS]; | |||
933 | #define GET_CLASS_NARROWEST_MODE(CLASS)((machine_mode) class_narrowest_mode[CLASS]) \ | |||
934 | ((machine_mode) class_narrowest_mode[CLASS]) | |||
935 | ||||
936 | /* The narrowest full integer mode available on the target. */ | |||
937 | ||||
938 | #define NARROWEST_INT_MODE(scalar_int_mode (scalar_int_mode::from_int (class_narrowest_mode [MODE_INT]))) \ | |||
939 | (scalar_int_mode \ | |||
940 | (scalar_int_mode::from_int (class_narrowest_mode[MODE_INT]))) | |||
941 | ||||
942 | /* Return the narrowest mode in T's class. */ | |||
943 | ||||
944 | template<typename T> | |||
945 | inline T | |||
946 | get_narrowest_mode (T mode) | |||
947 | { | |||
948 | return typename mode_traits<T>::from_int | |||
949 | (class_narrowest_mode[GET_MODE_CLASS (mode)((enum mode_class) mode_class[mode])]); | |||
950 | } | |||
951 | ||||
952 | /* Define the integer modes whose sizes are BITS_PER_UNIT and BITS_PER_WORD | |||
953 | and the mode whose class is Pmode and whose size is POINTER_SIZE. */ | |||
954 | ||||
955 | extern scalar_int_mode byte_mode; | |||
956 | extern scalar_int_mode word_mode; | |||
957 | extern scalar_int_mode ptr_mode; | |||
958 | ||||
959 | /* Target-dependent machine mode initialization - in insn-modes.c. */ | |||
960 | extern void init_adjust_machine_modes (void); | |||
961 | ||||
962 | #define TRULY_NOOP_TRUNCATION_MODES_P(MODE1, MODE2)(targetm.truly_noop_truncation (GET_MODE_PRECISION (MODE1), GET_MODE_PRECISION (MODE2))) \ | |||
963 | (targetm.truly_noop_truncation (GET_MODE_PRECISION (MODE1), \ | |||
964 | GET_MODE_PRECISION (MODE2))) | |||
965 | ||||
966 | /* Return true if MODE is a scalar integer mode that fits in a | |||
967 | HOST_WIDE_INT. */ | |||
968 | ||||
969 | inline bool | |||
970 | HWI_COMPUTABLE_MODE_P (machine_mode mode) | |||
971 | { | |||
972 | machine_mode mme = mode; | |||
973 | return (SCALAR_INT_MODE_P (mme)(((enum mode_class) mode_class[mme]) == MODE_INT || ((enum mode_class ) mode_class[mme]) == MODE_PARTIAL_INT) | |||
974 | && mode_to_precision (mme).coeffs[0] <= HOST_BITS_PER_WIDE_INT64); | |||
975 | } | |||
976 | ||||
977 | inline bool | |||
978 | HWI_COMPUTABLE_MODE_P (scalar_int_mode mode) | |||
979 | { | |||
980 | return GET_MODE_PRECISION (mode) <= HOST_BITS_PER_WIDE_INT64; | |||
981 | } | |||
982 | ||||
983 | struct int_n_data_t { | |||
984 | /* These parts are initailized by genmodes output */ | |||
985 | unsigned int bitsize; | |||
986 | scalar_int_mode_pod m; | |||
987 | /* RID_* is RID_INTN_BASE + index into this array */ | |||
988 | }; | |||
989 | ||||
990 | /* This is also in tree.h. genmodes.c guarantees the're sorted from | |||
991 | smallest bitsize to largest bitsize. */ | |||
992 | extern bool int_n_enabled_p[NUM_INT_N_ENTS1]; | |||
993 | extern const int_n_data_t int_n_data[NUM_INT_N_ENTS1]; | |||
994 | ||||
995 | /* Return true if MODE has class MODE_INT, storing it as a scalar_int_mode | |||
996 | in *INT_MODE if so. */ | |||
997 | ||||
998 | template<typename T> | |||
999 | inline bool | |||
1000 | is_int_mode (machine_mode mode, T *int_mode) | |||
1001 | { | |||
1002 | if (GET_MODE_CLASS (mode)((enum mode_class) mode_class[mode]) == MODE_INT) | |||
1003 | { | |||
1004 | *int_mode = scalar_int_mode (scalar_int_mode::from_int (mode)); | |||
1005 | return true; | |||
1006 | } | |||
1007 | return false; | |||
1008 | } | |||
1009 | ||||
1010 | /* Return true if MODE has class MODE_FLOAT, storing it as a | |||
1011 | scalar_float_mode in *FLOAT_MODE if so. */ | |||
1012 | ||||
1013 | template<typename T> | |||
1014 | inline bool | |||
1015 | is_float_mode (machine_mode mode, T *float_mode) | |||
1016 | { | |||
1017 | if (GET_MODE_CLASS (mode)((enum mode_class) mode_class[mode]) == MODE_FLOAT) | |||
1018 | { | |||
1019 | *float_mode = scalar_float_mode (scalar_float_mode::from_int (mode)); | |||
1020 | return true; | |||
1021 | } | |||
1022 | return false; | |||
1023 | } | |||
1024 | ||||
1025 | /* Return true if MODE has class MODE_COMPLEX_INT, storing it as | |||
1026 | a complex_mode in *CMODE if so. */ | |||
1027 | ||||
1028 | template<typename T> | |||
1029 | inline bool | |||
1030 | is_complex_int_mode (machine_mode mode, T *cmode) | |||
1031 | { | |||
1032 | if (GET_MODE_CLASS (mode)((enum mode_class) mode_class[mode]) == MODE_COMPLEX_INT) | |||
1033 | { | |||
1034 | *cmode = complex_mode (complex_mode::from_int (mode)); | |||
1035 | return true; | |||
1036 | } | |||
1037 | return false; | |||
1038 | } | |||
1039 | ||||
1040 | /* Return true if MODE has class MODE_COMPLEX_FLOAT, storing it as | |||
1041 | a complex_mode in *CMODE if so. */ | |||
1042 | ||||
1043 | template<typename T> | |||
1044 | inline bool | |||
1045 | is_complex_float_mode (machine_mode mode, T *cmode) | |||
1046 | { | |||
1047 | if (GET_MODE_CLASS (mode)((enum mode_class) mode_class[mode]) == MODE_COMPLEX_FLOAT) | |||
1048 | { | |||
1049 | *cmode = complex_mode (complex_mode::from_int (mode)); | |||
1050 | return true; | |||
1051 | } | |||
1052 | return false; | |||
1053 | } | |||
1054 | ||||
1055 | /* Return true if MODE is a scalar integer mode with a precision | |||
1056 | smaller than LIMIT's precision. */ | |||
1057 | ||||
1058 | inline bool | |||
1059 | is_narrower_int_mode (machine_mode mode, scalar_int_mode limit) | |||
1060 | { | |||
1061 | scalar_int_mode int_mode; | |||
1062 | return (is_a <scalar_int_mode> (mode, &int_mode) | |||
1063 | && GET_MODE_PRECISION (int_mode) < GET_MODE_PRECISION (limit)); | |||
1064 | } | |||
1065 | ||||
1066 | namespace mode_iterator | |||
1067 | { | |||
1068 | /* Start mode iterator *ITER at the first mode in class MCLASS, if any. */ | |||
1069 | ||||
1070 | template<typename T> | |||
1071 | inline void | |||
1072 | start (opt_mode<T> *iter, enum mode_class mclass) | |||
1073 | { | |||
1074 | if (GET_CLASS_NARROWEST_MODE (mclass)((machine_mode) class_narrowest_mode[mclass]) == E_VOIDmode) | |||
1075 | *iter = opt_mode<T> (); | |||
1076 | else | |||
1077 | *iter = as_a<T> (GET_CLASS_NARROWEST_MODE (mclass)((machine_mode) class_narrowest_mode[mclass])); | |||
1078 | } | |||
1079 | ||||
1080 | inline void | |||
1081 | start (machine_mode *iter, enum mode_class mclass) | |||
1082 | { | |||
1083 | *iter = GET_CLASS_NARROWEST_MODE (mclass)((machine_mode) class_narrowest_mode[mclass]); | |||
1084 | } | |||
1085 | ||||
1086 | /* Return true if mode iterator *ITER has not reached the end. */ | |||
1087 | ||||
1088 | template<typename T> | |||
1089 | inline bool | |||
1090 | iterate_p (opt_mode<T> *iter) | |||
1091 | { | |||
1092 | return iter->exists (); | |||
1093 | } | |||
1094 | ||||
1095 | inline bool | |||
1096 | iterate_p (machine_mode *iter) | |||
1097 | { | |||
1098 | return *iter != E_VOIDmode; | |||
1099 | } | |||
1100 | ||||
1101 | /* Set mode iterator *ITER to the next widest mode in the same class, | |||
1102 | if any. */ | |||
1103 | ||||
1104 | template<typename T> | |||
1105 | inline void | |||
1106 | get_wider (opt_mode<T> *iter) | |||
1107 | { | |||
1108 | *iter = GET_MODE_WIDER_MODE (iter->require ()); | |||
1109 | } | |||
1110 | ||||
1111 | inline void | |||
1112 | get_wider (machine_mode *iter) | |||
1113 | { | |||
1114 | *iter = GET_MODE_WIDER_MODE (*iter).else_void (); | |||
1115 | } | |||
1116 | ||||
1117 | /* Set mode iterator *ITER to the next widest mode in the same class. | |||
1118 | Such a mode is known to exist. */ | |||
1119 | ||||
1120 | template<typename T> | |||
1121 | inline void | |||
1122 | get_known_wider (T *iter) | |||
1123 | { | |||
1124 | *iter = GET_MODE_WIDER_MODE (*iter).require (); | |||
1125 | } | |||
1126 | ||||
1127 | /* Set mode iterator *ITER to the mode that is two times wider than the | |||
1128 | current one, if such a mode exists. */ | |||
1129 | ||||
1130 | template<typename T> | |||
1131 | inline void | |||
1132 | get_2xwider (opt_mode<T> *iter) | |||
1133 | { | |||
1134 | *iter = GET_MODE_2XWIDER_MODE (iter->require ()); | |||
1135 | } | |||
1136 | ||||
1137 | inline void | |||
1138 | get_2xwider (machine_mode *iter) | |||
1139 | { | |||
1140 | *iter = GET_MODE_2XWIDER_MODE (*iter).else_void (); | |||
1141 | } | |||
1142 | } | |||
1143 | ||||
1144 | /* Make ITERATOR iterate over all the modes in mode class CLASS, | |||
1145 | from narrowest to widest. */ | |||
1146 | #define FOR_EACH_MODE_IN_CLASS(ITERATOR, CLASS)for (mode_iterator::start (&(ITERATOR), CLASS); mode_iterator ::iterate_p (&(ITERATOR)); mode_iterator::get_wider (& (ITERATOR))) \ | |||
1147 | for (mode_iterator::start (&(ITERATOR), CLASS); \ | |||
1148 | mode_iterator::iterate_p (&(ITERATOR)); \ | |||
1149 | mode_iterator::get_wider (&(ITERATOR))) | |||
1150 | ||||
1151 | /* Make ITERATOR iterate over all the modes in the range [START, END), | |||
1152 | in order of increasing width. */ | |||
1153 | #define FOR_EACH_MODE(ITERATOR, START, END)for ((ITERATOR) = (START); (ITERATOR) != (END); mode_iterator ::get_known_wider (&(ITERATOR))) \ | |||
1154 | for ((ITERATOR) = (START); \ | |||
1155 | (ITERATOR) != (END); \ | |||
1156 | mode_iterator::get_known_wider (&(ITERATOR))) | |||
1157 | ||||
1158 | /* Make ITERATOR iterate over START and all wider modes in the same | |||
1159 | class, in order of increasing width. */ | |||
1160 | #define FOR_EACH_MODE_FROM(ITERATOR, START)for ((ITERATOR) = (START); mode_iterator::iterate_p (&(ITERATOR )); mode_iterator::get_wider (&(ITERATOR))) \ | |||
1161 | for ((ITERATOR) = (START); \ | |||
1162 | mode_iterator::iterate_p (&(ITERATOR)); \ | |||
1163 | mode_iterator::get_wider (&(ITERATOR))) | |||
1164 | ||||
1165 | /* Make ITERATOR iterate over modes in the range [NARROWEST, END) | |||
1166 | in order of increasing width, where NARROWEST is the narrowest mode | |||
1167 | in END's class. */ | |||
1168 | #define FOR_EACH_MODE_UNTIL(ITERATOR, END)for ((ITERATOR) = (get_narrowest_mode (END)); (ITERATOR) != ( END); mode_iterator::get_known_wider (&(ITERATOR))) \ | |||
1169 | FOR_EACH_MODE (ITERATOR, get_narrowest_mode (END), END)for ((ITERATOR) = (get_narrowest_mode (END)); (ITERATOR) != ( END); mode_iterator::get_known_wider (&(ITERATOR))) | |||
1170 | ||||
1171 | /* Make ITERATOR iterate over modes in the same class as MODE, in order | |||
1172 | of increasing width. Start at the first mode wider than START, | |||
1173 | or don't iterate at all if there is no wider mode. */ | |||
1174 | #define FOR_EACH_WIDER_MODE(ITERATOR, START)for ((ITERATOR) = (START), mode_iterator::get_wider (&(ITERATOR )); mode_iterator::iterate_p (&(ITERATOR)); mode_iterator ::get_wider (&(ITERATOR))) \ | |||
1175 | for ((ITERATOR) = (START), mode_iterator::get_wider (&(ITERATOR)); \ | |||
1176 | mode_iterator::iterate_p (&(ITERATOR)); \ | |||
1177 | mode_iterator::get_wider (&(ITERATOR))) | |||
1178 | ||||
1179 | /* Make ITERATOR iterate over modes in the same class as MODE, in order | |||
1180 | of increasing width, and with each mode being twice the width of the | |||
1181 | previous mode. Start at the mode that is two times wider than START, | |||
1182 | or don't iterate at all if there is no such mode. */ | |||
1183 | #define FOR_EACH_2XWIDER_MODE(ITERATOR, START)for ((ITERATOR) = (START), mode_iterator::get_2xwider (&( ITERATOR)); mode_iterator::iterate_p (&(ITERATOR)); mode_iterator ::get_2xwider (&(ITERATOR))) \ | |||
1184 | for ((ITERATOR) = (START), mode_iterator::get_2xwider (&(ITERATOR)); \ | |||
1185 | mode_iterator::iterate_p (&(ITERATOR)); \ | |||
1186 | mode_iterator::get_2xwider (&(ITERATOR))) | |||
1187 | ||||
1188 | template<typename T> | |||
1189 | void | |||
1190 | gt_ggc_mx (pod_mode<T> *) | |||
1191 | { | |||
1192 | } | |||
1193 | ||||
1194 | template<typename T> | |||
1195 | void | |||
1196 | gt_pch_nx (pod_mode<T> *) | |||
1197 | { | |||
1198 | } | |||
1199 | ||||
1200 | template<typename T> | |||
1201 | void | |||
1202 | gt_pch_nx (pod_mode<T> *, void (*) (void *, void *), void *) | |||
1203 | { | |||
1204 | } | |||
1205 | ||||
1206 | #endif /* not HAVE_MACHINE_MODES */ |