1 | /* Machine mode definitions for GCC; included by rtl.h and tree.h. |
2 | Copyright (C) 1991-2024 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 mode_size[NUM_MACHINE_MODES]; |
26 | extern CONST_MODE_PRECISION poly_uint16 mode_precision[NUM_MACHINE_MODES]; |
27 | extern const unsigned short mode_inner[NUM_MACHINE_MODES]; |
28 | extern CONST_MODE_NUNITS poly_uint16 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 short mode_next[NUM_MACHINE_MODES]; |
32 | extern const unsigned short mode_wider[NUM_MACHINE_MODES]; |
33 | extern const unsigned short mode_2xwider[NUM_MACHINE_MODES]; |
34 | |
35 | template<typename T> |
36 | struct mode_traits |
37 | { |
38 | /* For use by the machmode support code only. |
39 | |
40 | There are cases in which the machmode support code needs to forcibly |
41 | convert a machine_mode to a specific mode class T, and in which the |
42 | context guarantees that this is valid without the need for an assert. |
43 | This can be done using: |
44 | |
45 | return typename mode_traits<T>::from_int (mode); |
46 | |
47 | when returning a T and: |
48 | |
49 | res = T (typename mode_traits<T>::from_int (mode)); |
50 | |
51 | when assigning to a value RES that must be assignment-compatible |
52 | with (but possibly not the same as) T. */ |
53 | #ifdef USE_ENUM_MODES |
54 | /* Allow direct conversion of enums to specific mode classes only |
55 | when USE_ENUM_MODES is defined. This is only intended for use |
56 | by gencondmd, so that it can tell more easily when .md conditions |
57 | are always false. */ |
58 | typedef machine_mode from_int; |
59 | #else |
60 | /* Here we use an enum type distinct from machine_mode but with the |
61 | same range as machine_mode. T should have a constructor that |
62 | accepts this enum type; it should not have a constructor that |
63 | accepts machine_mode. |
64 | |
65 | We use this somewhat indirect approach to avoid too many constructor |
66 | calls when the compiler is built with -O0. For example, even in |
67 | unoptimized code, the return statement above would construct the |
68 | returned T directly from the numerical value of MODE. */ |
69 | enum from_int { dummy = MAX_MACHINE_MODE }; |
70 | #endif |
71 | }; |
72 | |
73 | template<> |
74 | struct mode_traits<machine_mode> |
75 | { |
76 | /* machine_mode itself needs no conversion. */ |
77 | typedef machine_mode from_int; |
78 | }; |
79 | |
80 | /* Always treat machine modes as fixed-size while compiling code specific |
81 | to targets that have no variable-size modes. */ |
82 | #if defined (IN_TARGET_CODE) && NUM_POLY_INT_COEFFS == 1 |
83 | #define ONLY_FIXED_SIZE_MODES 1 |
84 | #else |
85 | #define ONLY_FIXED_SIZE_MODES 0 |
86 | #endif |
87 | |
88 | /* Get the name of mode MODE as a string. */ |
89 | |
90 | extern const char * const mode_name[NUM_MACHINE_MODES]; |
91 | #define GET_MODE_NAME(MODE) mode_name[MODE] |
92 | |
93 | /* Mode classes. */ |
94 | |
95 | #include "mode-classes.def" |
96 | #define DEF_MODE_CLASS(M) M |
97 | enum mode_class { MODE_CLASSES, MAX_MODE_CLASS }; |
98 | #undef DEF_MODE_CLASS |
99 | #undef MODE_CLASSES |
100 | |
101 | /* Get the general kind of object that mode MODE represents |
102 | (integer, floating, complex, etc.) */ |
103 | |
104 | extern const unsigned char mode_class[NUM_MACHINE_MODES]; |
105 | #define GET_MODE_CLASS(MODE) ((enum mode_class) mode_class[MODE]) |
106 | |
107 | /* Nonzero if MODE is an integral mode. */ |
108 | #define INTEGRAL_MODE_P(MODE) \ |
109 | (GET_MODE_CLASS (MODE) == MODE_INT \ |
110 | || GET_MODE_CLASS (MODE) == MODE_PARTIAL_INT \ |
111 | || GET_MODE_CLASS (MODE) == MODE_COMPLEX_INT \ |
112 | || GET_MODE_CLASS (MODE) == MODE_VECTOR_BOOL \ |
113 | || GET_MODE_CLASS (MODE) == MODE_VECTOR_INT) |
114 | |
115 | /* Nonzero if MODE is a floating-point mode. */ |
116 | #define FLOAT_MODE_P(MODE) \ |
117 | (GET_MODE_CLASS (MODE) == MODE_FLOAT \ |
118 | || GET_MODE_CLASS (MODE) == MODE_DECIMAL_FLOAT \ |
119 | || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT \ |
120 | || GET_MODE_CLASS (MODE) == MODE_VECTOR_FLOAT) |
121 | |
122 | /* Nonzero if MODE is a complex mode. */ |
123 | #define COMPLEX_MODE_P(MODE) \ |
124 | (GET_MODE_CLASS (MODE) == MODE_COMPLEX_INT \ |
125 | || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) |
126 | |
127 | /* Nonzero if MODE is a vector mode. */ |
128 | #define VECTOR_MODE_P(MODE) \ |
129 | (GET_MODE_CLASS (MODE) == MODE_VECTOR_BOOL \ |
130 | || GET_MODE_CLASS (MODE) == MODE_VECTOR_INT \ |
131 | || GET_MODE_CLASS (MODE) == MODE_VECTOR_FLOAT \ |
132 | || GET_MODE_CLASS (MODE) == MODE_VECTOR_FRACT \ |
133 | || GET_MODE_CLASS (MODE) == MODE_VECTOR_UFRACT \ |
134 | || GET_MODE_CLASS (MODE) == MODE_VECTOR_ACCUM \ |
135 | || GET_MODE_CLASS (MODE) == MODE_VECTOR_UACCUM) |
136 | |
137 | /* Nonzero if MODE is a scalar integral mode. */ |
138 | #define SCALAR_INT_MODE_P(MODE) \ |
139 | (GET_MODE_CLASS (MODE) == MODE_INT \ |
140 | || GET_MODE_CLASS (MODE) == MODE_PARTIAL_INT) |
141 | |
142 | /* Nonzero if MODE is a scalar floating point mode. */ |
143 | #define SCALAR_FLOAT_MODE_P(MODE) \ |
144 | (GET_MODE_CLASS (MODE) == MODE_FLOAT \ |
145 | || GET_MODE_CLASS (MODE) == MODE_DECIMAL_FLOAT) |
146 | |
147 | /* Nonzero if MODE is a decimal floating point mode. */ |
148 | #define DECIMAL_FLOAT_MODE_P(MODE) \ |
149 | (GET_MODE_CLASS (MODE) == MODE_DECIMAL_FLOAT) |
150 | |
151 | /* Nonzero if MODE is a scalar fract mode. */ |
152 | #define SCALAR_FRACT_MODE_P(MODE) \ |
153 | (GET_MODE_CLASS (MODE) == MODE_FRACT) |
154 | |
155 | /* Nonzero if MODE is a scalar ufract mode. */ |
156 | #define SCALAR_UFRACT_MODE_P(MODE) \ |
157 | (GET_MODE_CLASS (MODE) == MODE_UFRACT) |
158 | |
159 | /* Nonzero if MODE is a scalar fract or ufract mode. */ |
160 | #define ALL_SCALAR_FRACT_MODE_P(MODE) \ |
161 | (SCALAR_FRACT_MODE_P (MODE) || SCALAR_UFRACT_MODE_P (MODE)) |
162 | |
163 | /* Nonzero if MODE is a scalar accum mode. */ |
164 | #define SCALAR_ACCUM_MODE_P(MODE) \ |
165 | (GET_MODE_CLASS (MODE) == MODE_ACCUM) |
166 | |
167 | /* Nonzero if MODE is a scalar uaccum mode. */ |
168 | #define SCALAR_UACCUM_MODE_P(MODE) \ |
169 | (GET_MODE_CLASS (MODE) == MODE_UACCUM) |
170 | |
171 | /* Nonzero if MODE is a scalar accum or uaccum mode. */ |
172 | #define ALL_SCALAR_ACCUM_MODE_P(MODE) \ |
173 | (SCALAR_ACCUM_MODE_P (MODE) || SCALAR_UACCUM_MODE_P (MODE)) |
174 | |
175 | /* Nonzero if MODE is a scalar fract or accum mode. */ |
176 | #define SIGNED_SCALAR_FIXED_POINT_MODE_P(MODE) \ |
177 | (SCALAR_FRACT_MODE_P (MODE) || SCALAR_ACCUM_MODE_P (MODE)) |
178 | |
179 | /* Nonzero if MODE is a scalar ufract or uaccum mode. */ |
180 | #define UNSIGNED_SCALAR_FIXED_POINT_MODE_P(MODE) \ |
181 | (SCALAR_UFRACT_MODE_P (MODE) || SCALAR_UACCUM_MODE_P (MODE)) |
182 | |
183 | /* Nonzero if MODE is a scalar fract, ufract, accum or uaccum mode. */ |
184 | #define ALL_SCALAR_FIXED_POINT_MODE_P(MODE) \ |
185 | (SIGNED_SCALAR_FIXED_POINT_MODE_P (MODE) \ |
186 | || UNSIGNED_SCALAR_FIXED_POINT_MODE_P (MODE)) |
187 | |
188 | /* Nonzero if MODE is a scalar/vector fract mode. */ |
189 | #define FRACT_MODE_P(MODE) \ |
190 | (GET_MODE_CLASS (MODE) == MODE_FRACT \ |
191 | || GET_MODE_CLASS (MODE) == MODE_VECTOR_FRACT) |
192 | |
193 | /* Nonzero if MODE is a scalar/vector ufract mode. */ |
194 | #define UFRACT_MODE_P(MODE) \ |
195 | (GET_MODE_CLASS (MODE) == MODE_UFRACT \ |
196 | || GET_MODE_CLASS (MODE) == MODE_VECTOR_UFRACT) |
197 | |
198 | /* Nonzero if MODE is a scalar/vector fract or ufract mode. */ |
199 | #define ALL_FRACT_MODE_P(MODE) \ |
200 | (FRACT_MODE_P (MODE) || UFRACT_MODE_P (MODE)) |
201 | |
202 | /* Nonzero if MODE is a scalar/vector accum mode. */ |
203 | #define ACCUM_MODE_P(MODE) \ |
204 | (GET_MODE_CLASS (MODE) == MODE_ACCUM \ |
205 | || GET_MODE_CLASS (MODE) == MODE_VECTOR_ACCUM) |
206 | |
207 | /* Nonzero if MODE is a scalar/vector uaccum mode. */ |
208 | #define UACCUM_MODE_P(MODE) \ |
209 | (GET_MODE_CLASS (MODE) == MODE_UACCUM \ |
210 | || GET_MODE_CLASS (MODE) == MODE_VECTOR_UACCUM) |
211 | |
212 | /* Nonzero if MODE is a scalar/vector accum or uaccum mode. */ |
213 | #define ALL_ACCUM_MODE_P(MODE) \ |
214 | (ACCUM_MODE_P (MODE) || UACCUM_MODE_P (MODE)) |
215 | |
216 | /* Nonzero if MODE is a scalar/vector fract or accum mode. */ |
217 | #define SIGNED_FIXED_POINT_MODE_P(MODE) \ |
218 | (FRACT_MODE_P (MODE) || ACCUM_MODE_P (MODE)) |
219 | |
220 | /* Nonzero if MODE is a scalar/vector ufract or uaccum mode. */ |
221 | #define UNSIGNED_FIXED_POINT_MODE_P(MODE) \ |
222 | (UFRACT_MODE_P (MODE) || UACCUM_MODE_P (MODE)) |
223 | |
224 | /* Nonzero if MODE is a scalar/vector fract, ufract, accum or uaccum mode. */ |
225 | #define ALL_FIXED_POINT_MODE_P(MODE) \ |
226 | (SIGNED_FIXED_POINT_MODE_P (MODE) \ |
227 | || UNSIGNED_FIXED_POINT_MODE_P (MODE)) |
228 | |
229 | /* Nonzero if MODE is opaque. */ |
230 | #define OPAQUE_MODE_P(MODE) \ |
231 | (GET_MODE_CLASS (MODE) == MODE_OPAQUE) |
232 | |
233 | /* Nonzero if CLASS modes can be widened. */ |
234 | #define CLASS_HAS_WIDER_MODES_P(CLASS) \ |
235 | (CLASS == MODE_INT \ |
236 | || CLASS == MODE_PARTIAL_INT \ |
237 | || CLASS == MODE_FLOAT \ |
238 | || CLASS == MODE_DECIMAL_FLOAT \ |
239 | || CLASS == MODE_COMPLEX_FLOAT \ |
240 | || CLASS == MODE_FRACT \ |
241 | || CLASS == MODE_UFRACT \ |
242 | || CLASS == MODE_ACCUM \ |
243 | || CLASS == MODE_UACCUM) |
244 | |
245 | /* The MACHINE_MODE_BITSIZE should be exactly aligned with the type of the |
246 | machine_mode array in the machmode.h and genmodes.cc. For example as below. |
247 | +------------------------+-------+ |
248 | | MACHINE_MODE_BITSIZE | 16 | |
249 | +------------------------+-------+ |
250 | | mode_inter[] | short | |
251 | | mode_next[] | short | |
252 | | mode_wider[] | short | |
253 | | mode_2xwider[] | short | |
254 | | mode_complex[] | short | |
255 | | class_narrowest_mode[] | short | |
256 | +------------------------+-------+ |
257 | */ |
258 | #define MACHINE_MODE_BITSIZE 16 |
259 | |
260 | /* An optional T (i.e. a T or nothing), where T is some form of mode class. */ |
261 | template<typename T> |
262 | class opt_mode |
263 | { |
264 | public: |
265 | enum from_int { dummy = MAX_MACHINE_MODE }; |
266 | |
267 | ALWAYS_INLINE CONSTEXPR opt_mode () : m_mode (E_VOIDmode) {} |
268 | ALWAYS_INLINE CONSTEXPR opt_mode (const T &m) : m_mode (m) {} |
269 | template<typename U> |
270 | ALWAYS_INLINE CONSTEXPR opt_mode (const U &m) : m_mode (T (m)) {} |
271 | ALWAYS_INLINE CONSTEXPR opt_mode (from_int m) : m_mode (machine_mode (m)) {} |
272 | |
273 | machine_mode else_void () const; |
274 | machine_mode else_blk () const { return else_mode (BLKmode); } |
275 | machine_mode else_mode (machine_mode) const; |
276 | T require () const; |
277 | |
278 | bool exists () const; |
279 | template<typename U> bool exists (U *) const; |
280 | |
281 | bool operator== (const T &m) const { return m_mode == m; } |
282 | bool operator!= (const T &m) const { return m_mode != m; } |
283 | |
284 | private: |
285 | machine_mode m_mode; |
286 | }; |
287 | |
288 | /* If the object contains a T, return its enum value, otherwise return |
289 | E_VOIDmode. */ |
290 | |
291 | template<typename T> |
292 | ALWAYS_INLINE machine_mode |
293 | opt_mode<T>::else_void () const |
294 | { |
295 | return m_mode; |
296 | } |
297 | |
298 | /* If the T exists, return its enum value, otherwise return FALLBACK. */ |
299 | |
300 | template<typename T> |
301 | inline machine_mode |
302 | opt_mode<T>::else_mode (machine_mode fallback) const |
303 | { |
304 | return m_mode == E_VOIDmode ? fallback : m_mode; |
305 | } |
306 | |
307 | /* Assert that the object contains a T and return it. */ |
308 | |
309 | template<typename T> |
310 | inline T |
311 | opt_mode<T>::require () const |
312 | { |
313 | gcc_checking_assert (m_mode != E_VOIDmode); |
314 | return typename mode_traits<T>::from_int (m_mode); |
315 | } |
316 | |
317 | /* Return true if the object contains a T rather than nothing. */ |
318 | |
319 | template<typename T> |
320 | ALWAYS_INLINE bool |
321 | opt_mode<T>::exists () const |
322 | { |
323 | return m_mode != E_VOIDmode; |
324 | } |
325 | |
326 | /* Return true if the object contains a T, storing it in *MODE if so. */ |
327 | |
328 | template<typename T> |
329 | template<typename U> |
330 | inline bool |
331 | opt_mode<T>::exists (U *mode) const |
332 | { |
333 | if (m_mode != E_VOIDmode) |
334 | { |
335 | *mode = T (typename mode_traits<T>::from_int (m_mode)); |
336 | return true; |
337 | } |
338 | return false; |
339 | } |
340 | |
341 | /* A POD version of mode class T. */ |
342 | |
343 | template<typename T> |
344 | struct pod_mode |
345 | { |
346 | typedef typename mode_traits<T>::from_int from_int; |
347 | typedef typename T::measurement_type measurement_type; |
348 | |
349 | machine_mode m_mode; |
350 | ALWAYS_INLINE CONSTEXPR |
351 | operator machine_mode () const { return m_mode; } |
352 | |
353 | ALWAYS_INLINE CONSTEXPR |
354 | operator T () const { return from_int (m_mode); } |
355 | |
356 | ALWAYS_INLINE pod_mode &operator = (const T &m) { m_mode = m; return *this; } |
357 | }; |
358 | |
359 | /* Return true if mode M has type T. */ |
360 | |
361 | template<typename T> |
362 | inline bool |
363 | is_a (machine_mode m) |
364 | { |
365 | return T::includes_p (m); |
366 | } |
367 | |
368 | template<typename T, typename U> |
369 | inline bool |
370 | is_a (const opt_mode<U> &m) |
371 | { |
372 | return T::includes_p (m.else_void ()); |
373 | } |
374 | |
375 | /* Assert that mode M has type T, and return it in that form. */ |
376 | |
377 | template<typename T> |
378 | inline T |
379 | as_a (machine_mode m) |
380 | { |
381 | gcc_checking_assert (T::includes_p (m)); |
382 | return typename mode_traits<T>::from_int (m); |
383 | } |
384 | |
385 | template<typename T, typename U> |
386 | inline T |
387 | as_a (const opt_mode<U> &m) |
388 | { |
389 | return as_a <T> (m.else_void ()); |
390 | } |
391 | |
392 | /* Convert M to an opt_mode<T>. */ |
393 | |
394 | template<typename T> |
395 | inline opt_mode<T> |
396 | dyn_cast (machine_mode m) |
397 | { |
398 | if (T::includes_p (m)) |
399 | return T (typename mode_traits<T>::from_int (m)); |
400 | return opt_mode<T> (); |
401 | } |
402 | |
403 | template<typename T, typename U> |
404 | inline opt_mode<T> |
405 | dyn_cast (const opt_mode<U> &m) |
406 | { |
407 | return dyn_cast <T> (m.else_void ()); |
408 | } |
409 | |
410 | /* Return true if mode M has type T, storing it as a T in *RESULT |
411 | if so. */ |
412 | |
413 | template<typename T, typename U> |
414 | inline bool |
415 | is_a (machine_mode m, U *result) |
416 | { |
417 | if (T::includes_p (m)) |
418 | { |
419 | *result = T (typename mode_traits<T>::from_int (m)); |
420 | return true; |
421 | } |
422 | return false; |
423 | } |
424 | |
425 | /* Represents a machine mode that is known to be a SCALAR_INT_MODE_P. */ |
426 | class scalar_int_mode |
427 | { |
428 | public: |
429 | typedef mode_traits<scalar_int_mode>::from_int from_int; |
430 | typedef unsigned short measurement_type; |
431 | |
432 | ALWAYS_INLINE scalar_int_mode () {} |
433 | |
434 | ALWAYS_INLINE CONSTEXPR |
435 | scalar_int_mode (from_int m) : m_mode (machine_mode (m)) {} |
436 | |
437 | ALWAYS_INLINE CONSTEXPR operator machine_mode () const { return m_mode; } |
438 | |
439 | static bool includes_p (machine_mode); |
440 | |
441 | protected: |
442 | machine_mode m_mode; |
443 | }; |
444 | |
445 | /* Return true if M is a scalar_int_mode. */ |
446 | |
447 | inline bool |
448 | scalar_int_mode::includes_p (machine_mode m) |
449 | { |
450 | return SCALAR_INT_MODE_P (m); |
451 | } |
452 | |
453 | /* Represents a machine mode that is known to be a SCALAR_FLOAT_MODE_P. */ |
454 | class scalar_float_mode |
455 | { |
456 | public: |
457 | typedef mode_traits<scalar_float_mode>::from_int from_int; |
458 | typedef unsigned short measurement_type; |
459 | |
460 | ALWAYS_INLINE scalar_float_mode () {} |
461 | |
462 | ALWAYS_INLINE CONSTEXPR |
463 | scalar_float_mode (from_int m) : m_mode (machine_mode (m)) {} |
464 | |
465 | ALWAYS_INLINE CONSTEXPR operator machine_mode () const { return m_mode; } |
466 | |
467 | static bool includes_p (machine_mode); |
468 | |
469 | protected: |
470 | machine_mode m_mode; |
471 | }; |
472 | |
473 | /* Return true if M is a scalar_float_mode. */ |
474 | |
475 | inline bool |
476 | scalar_float_mode::includes_p (machine_mode m) |
477 | { |
478 | return SCALAR_FLOAT_MODE_P (m); |
479 | } |
480 | |
481 | /* Represents a machine mode that is known to be scalar. */ |
482 | class scalar_mode |
483 | { |
484 | public: |
485 | typedef mode_traits<scalar_mode>::from_int from_int; |
486 | typedef unsigned short measurement_type; |
487 | |
488 | ALWAYS_INLINE scalar_mode () {} |
489 | |
490 | ALWAYS_INLINE CONSTEXPR |
491 | scalar_mode (from_int m) : m_mode (machine_mode (m)) {} |
492 | |
493 | ALWAYS_INLINE CONSTEXPR |
494 | scalar_mode (const scalar_int_mode &m) : m_mode (m) {} |
495 | |
496 | ALWAYS_INLINE CONSTEXPR |
497 | scalar_mode (const scalar_float_mode &m) : m_mode (m) {} |
498 | |
499 | ALWAYS_INLINE CONSTEXPR |
500 | scalar_mode (const scalar_int_mode_pod &m) : m_mode (m) {} |
501 | |
502 | ALWAYS_INLINE CONSTEXPR operator machine_mode () const { return m_mode; } |
503 | |
504 | static bool includes_p (machine_mode); |
505 | |
506 | protected: |
507 | machine_mode m_mode; |
508 | }; |
509 | |
510 | /* Return true if M represents some kind of scalar value. */ |
511 | |
512 | inline bool |
513 | scalar_mode::includes_p (machine_mode m) |
514 | { |
515 | switch (GET_MODE_CLASS (m)) |
516 | { |
517 | case MODE_INT: |
518 | case MODE_PARTIAL_INT: |
519 | case MODE_FRACT: |
520 | case MODE_UFRACT: |
521 | case MODE_ACCUM: |
522 | case MODE_UACCUM: |
523 | case MODE_FLOAT: |
524 | case MODE_DECIMAL_FLOAT: |
525 | return true; |
526 | default: |
527 | return false; |
528 | } |
529 | } |
530 | |
531 | /* Represents a machine mode that is known to be a COMPLEX_MODE_P. */ |
532 | class complex_mode |
533 | { |
534 | public: |
535 | typedef mode_traits<complex_mode>::from_int from_int; |
536 | typedef unsigned short measurement_type; |
537 | |
538 | ALWAYS_INLINE complex_mode () {} |
539 | |
540 | ALWAYS_INLINE CONSTEXPR |
541 | complex_mode (from_int m) : m_mode (machine_mode (m)) {} |
542 | |
543 | ALWAYS_INLINE CONSTEXPR operator machine_mode () const { return m_mode; } |
544 | |
545 | static bool includes_p (machine_mode); |
546 | |
547 | protected: |
548 | machine_mode m_mode; |
549 | }; |
550 | |
551 | /* Return true if M is a complex_mode. */ |
552 | |
553 | inline bool |
554 | complex_mode::includes_p (machine_mode m) |
555 | { |
556 | return COMPLEX_MODE_P (m); |
557 | } |
558 | |
559 | /* Return the base GET_MODE_SIZE value for MODE. */ |
560 | |
561 | ALWAYS_INLINE poly_uint16 |
562 | mode_to_bytes (machine_mode mode) |
563 | { |
564 | #if GCC_VERSION >= 4001 |
565 | return (__builtin_constant_p (mode) |
566 | ? mode_size_inline (mode) : mode_size[mode]); |
567 | #else |
568 | return mode_size[mode]; |
569 | #endif |
570 | } |
571 | |
572 | /* Return the base GET_MODE_BITSIZE value for MODE. */ |
573 | |
574 | ALWAYS_INLINE poly_uint16 |
575 | mode_to_bits (machine_mode mode) |
576 | { |
577 | return mode_to_bytes (mode) * BITS_PER_UNIT; |
578 | } |
579 | |
580 | /* Return the base GET_MODE_PRECISION value for MODE. */ |
581 | |
582 | ALWAYS_INLINE poly_uint16 |
583 | mode_to_precision (machine_mode mode) |
584 | { |
585 | return mode_precision[mode]; |
586 | } |
587 | |
588 | /* Return the base GET_MODE_INNER value for MODE. */ |
589 | |
590 | ALWAYS_INLINE scalar_mode |
591 | mode_to_inner (machine_mode mode) |
592 | { |
593 | #if GCC_VERSION >= 4001 |
594 | return scalar_mode::from_int (__builtin_constant_p (mode) |
595 | ? mode_inner_inline (mode) |
596 | : mode_inner[mode]); |
597 | #else |
598 | return scalar_mode::from_int (mode_inner[mode]); |
599 | #endif |
600 | } |
601 | |
602 | /* Return the base GET_MODE_UNIT_SIZE value for MODE. */ |
603 | |
604 | ALWAYS_INLINE unsigned char |
605 | mode_to_unit_size (machine_mode mode) |
606 | { |
607 | #if GCC_VERSION >= 4001 |
608 | return (__builtin_constant_p (mode) |
609 | ? mode_unit_size_inline (mode) : mode_unit_size[mode]); |
610 | #else |
611 | return mode_unit_size[mode]; |
612 | #endif |
613 | } |
614 | |
615 | /* Return the base GET_MODE_UNIT_PRECISION value for MODE. */ |
616 | |
617 | ALWAYS_INLINE unsigned short |
618 | mode_to_unit_precision (machine_mode mode) |
619 | { |
620 | #if GCC_VERSION >= 4001 |
621 | return (__builtin_constant_p (mode) |
622 | ? mode_unit_precision_inline (mode) : mode_unit_precision[mode]); |
623 | #else |
624 | return mode_unit_precision[mode]; |
625 | #endif |
626 | } |
627 | |
628 | /* Return the base GET_MODE_NUNITS value for MODE. */ |
629 | |
630 | ALWAYS_INLINE poly_uint16 |
631 | mode_to_nunits (machine_mode mode) |
632 | { |
633 | #if GCC_VERSION >= 4001 |
634 | return (__builtin_constant_p (mode) |
635 | ? mode_nunits_inline (mode) : mode_nunits[mode]); |
636 | #else |
637 | return mode_nunits[mode]; |
638 | #endif |
639 | } |
640 | |
641 | /* Get the size in bytes of an object of mode MODE. */ |
642 | |
643 | #if ONLY_FIXED_SIZE_MODES |
644 | #define GET_MODE_SIZE(MODE) ((unsigned short) mode_to_bytes (MODE).coeffs[0]) |
645 | #else |
646 | ALWAYS_INLINE poly_uint16 |
647 | GET_MODE_SIZE (machine_mode mode) |
648 | { |
649 | return mode_to_bytes (mode); |
650 | } |
651 | |
652 | template<typename T> |
653 | ALWAYS_INLINE typename if_poly<typename T::measurement_type>::type |
654 | GET_MODE_SIZE (const T &mode) |
655 | { |
656 | return mode_to_bytes (mode); |
657 | } |
658 | |
659 | template<typename T> |
660 | ALWAYS_INLINE typename if_nonpoly<typename T::measurement_type>::type |
661 | GET_MODE_SIZE (const T &mode) |
662 | { |
663 | return mode_to_bytes (mode).coeffs[0]; |
664 | } |
665 | #endif |
666 | |
667 | /* Get the size in bits of an object of mode MODE. */ |
668 | |
669 | #if ONLY_FIXED_SIZE_MODES |
670 | #define GET_MODE_BITSIZE(MODE) ((unsigned short) mode_to_bits (MODE).coeffs[0]) |
671 | #else |
672 | ALWAYS_INLINE poly_uint16 |
673 | GET_MODE_BITSIZE (machine_mode mode) |
674 | { |
675 | return mode_to_bits (mode); |
676 | } |
677 | |
678 | template<typename T> |
679 | ALWAYS_INLINE typename if_poly<typename T::measurement_type>::type |
680 | GET_MODE_BITSIZE (const T &mode) |
681 | { |
682 | return mode_to_bits (mode); |
683 | } |
684 | |
685 | template<typename T> |
686 | ALWAYS_INLINE typename if_nonpoly<typename T::measurement_type>::type |
687 | GET_MODE_BITSIZE (const T &mode) |
688 | { |
689 | return mode_to_bits (mode).coeffs[0]; |
690 | } |
691 | #endif |
692 | |
693 | /* Get the number of value bits of an object of mode MODE. */ |
694 | |
695 | #if ONLY_FIXED_SIZE_MODES |
696 | #define GET_MODE_PRECISION(MODE) \ |
697 | ((unsigned short) mode_to_precision (MODE).coeffs[0]) |
698 | #else |
699 | ALWAYS_INLINE poly_uint16 |
700 | GET_MODE_PRECISION (machine_mode mode) |
701 | { |
702 | return mode_to_precision (mode); |
703 | } |
704 | |
705 | template<typename T> |
706 | ALWAYS_INLINE typename if_poly<typename T::measurement_type>::type |
707 | GET_MODE_PRECISION (const T &mode) |
708 | { |
709 | return mode_to_precision (mode); |
710 | } |
711 | |
712 | template<typename T> |
713 | ALWAYS_INLINE typename if_nonpoly<typename T::measurement_type>::type |
714 | GET_MODE_PRECISION (const T &mode) |
715 | { |
716 | return mode_to_precision (mode).coeffs[0]; |
717 | } |
718 | #endif |
719 | |
720 | /* Get the number of integral bits of an object of mode MODE. */ |
721 | extern CONST_MODE_IBIT unsigned char mode_ibit[NUM_MACHINE_MODES]; |
722 | #define GET_MODE_IBIT(MODE) mode_ibit[MODE] |
723 | |
724 | /* Get the number of fractional bits of an object of mode MODE. */ |
725 | extern CONST_MODE_FBIT unsigned char mode_fbit[NUM_MACHINE_MODES]; |
726 | #define GET_MODE_FBIT(MODE) mode_fbit[MODE] |
727 | |
728 | /* Get a bitmask containing 1 for all bits in a word |
729 | that fit within mode MODE. */ |
730 | |
731 | extern CONST_MODE_MASK unsigned HOST_WIDE_INT |
732 | mode_mask_array[NUM_MACHINE_MODES]; |
733 | |
734 | #define GET_MODE_MASK(MODE) mode_mask_array[MODE] |
735 | |
736 | /* Return the mode of the basic parts of MODE. For vector modes this is the |
737 | mode of the vector elements. For complex modes it is the mode of the real |
738 | and imaginary parts. For other modes it is MODE itself. */ |
739 | |
740 | #define GET_MODE_INNER(MODE) (mode_to_inner (MODE)) |
741 | |
742 | /* Get the size in bytes or bits of the basic parts of an |
743 | object of mode MODE. */ |
744 | |
745 | #define GET_MODE_UNIT_SIZE(MODE) mode_to_unit_size (MODE) |
746 | |
747 | #define GET_MODE_UNIT_BITSIZE(MODE) \ |
748 | ((unsigned short) (GET_MODE_UNIT_SIZE (MODE) * BITS_PER_UNIT)) |
749 | |
750 | #define GET_MODE_UNIT_PRECISION(MODE) (mode_to_unit_precision (MODE)) |
751 | |
752 | /* Get the number of units in an object of mode MODE. This is 2 for |
753 | complex modes and the number of elements for vector modes. */ |
754 | |
755 | #if ONLY_FIXED_SIZE_MODES |
756 | #define GET_MODE_NUNITS(MODE) (mode_to_nunits (MODE).coeffs[0]) |
757 | #else |
758 | ALWAYS_INLINE poly_uint16 |
759 | GET_MODE_NUNITS (machine_mode mode) |
760 | { |
761 | return mode_to_nunits (mode); |
762 | } |
763 | |
764 | template<typename T> |
765 | ALWAYS_INLINE typename if_poly<typename T::measurement_type>::type |
766 | GET_MODE_NUNITS (const T &mode) |
767 | { |
768 | return mode_to_nunits (mode); |
769 | } |
770 | |
771 | template<typename T> |
772 | ALWAYS_INLINE typename if_nonpoly<typename T::measurement_type>::type |
773 | GET_MODE_NUNITS (const T &mode) |
774 | { |
775 | return mode_to_nunits (mode).coeffs[0]; |
776 | } |
777 | #endif |
778 | |
779 | /* Get the next natural mode (not narrower, eg, QI -> HI -> SI -> DI -> TI |
780 | or HF -> BF -> SF -> DF -> XF -> TF). */ |
781 | |
782 | template<typename T> |
783 | ALWAYS_INLINE opt_mode<T> |
784 | GET_MODE_NEXT_MODE (const T &m) |
785 | { |
786 | return typename opt_mode<T>::from_int (mode_next[m]); |
787 | } |
788 | |
789 | /* Get the next wider mode (eg, QI -> HI -> SI -> DI -> TI |
790 | or { HF, BF } -> SF -> DF -> XF -> TF). |
791 | This is similar to GET_MODE_NEXT_MODE, but while GET_MODE_NEXT_MODE |
792 | can include mode that have the same precision (e.g. |
793 | GET_MODE_NEXT_MODE (HFmode) can be BFmode even when both have the same |
794 | precision), this one will skip those. And always VOIDmode for |
795 | modes whose class is !CLASS_HAS_WIDER_MODES_P. */ |
796 | |
797 | template<typename T> |
798 | ALWAYS_INLINE opt_mode<T> |
799 | GET_MODE_WIDER_MODE (const T &m) |
800 | { |
801 | return typename opt_mode<T>::from_int (mode_wider[m]); |
802 | } |
803 | |
804 | /* For scalars, this is a mode with twice the precision. For vectors, |
805 | this is a mode with the same inner mode but with twice the elements. */ |
806 | |
807 | template<typename T> |
808 | ALWAYS_INLINE opt_mode<T> |
809 | GET_MODE_2XWIDER_MODE (const T &m) |
810 | { |
811 | return typename opt_mode<T>::from_int (mode_2xwider[m]); |
812 | } |
813 | |
814 | /* Get the complex mode from the component mode. */ |
815 | extern const unsigned short mode_complex[NUM_MACHINE_MODES]; |
816 | #define GET_MODE_COMPLEX_MODE(MODE) ((machine_mode) mode_complex[MODE]) |
817 | |
818 | /* Represents a machine mode that must have a fixed size. The main |
819 | use of this class is to represent the modes of objects that always |
820 | have static storage duration, such as constant pool entries. |
821 | (No current target supports the concept of variable-size static data.) */ |
822 | class fixed_size_mode |
823 | { |
824 | public: |
825 | typedef mode_traits<fixed_size_mode>::from_int from_int; |
826 | typedef unsigned short measurement_type; |
827 | |
828 | ALWAYS_INLINE fixed_size_mode () {} |
829 | |
830 | ALWAYS_INLINE CONSTEXPR |
831 | fixed_size_mode (from_int m) : m_mode (machine_mode (m)) {} |
832 | |
833 | ALWAYS_INLINE CONSTEXPR |
834 | fixed_size_mode (const scalar_mode &m) : m_mode (m) {} |
835 | |
836 | ALWAYS_INLINE CONSTEXPR |
837 | fixed_size_mode (const scalar_int_mode &m) : m_mode (m) {} |
838 | |
839 | ALWAYS_INLINE CONSTEXPR |
840 | fixed_size_mode (const scalar_float_mode &m) : m_mode (m) {} |
841 | |
842 | ALWAYS_INLINE CONSTEXPR |
843 | fixed_size_mode (const scalar_mode_pod &m) : m_mode (m) {} |
844 | |
845 | ALWAYS_INLINE CONSTEXPR |
846 | fixed_size_mode (const scalar_int_mode_pod &m) : m_mode (m) {} |
847 | |
848 | ALWAYS_INLINE CONSTEXPR |
849 | fixed_size_mode (const complex_mode &m) : m_mode (m) {} |
850 | |
851 | ALWAYS_INLINE CONSTEXPR operator machine_mode () const { return m_mode; } |
852 | |
853 | static bool includes_p (machine_mode); |
854 | |
855 | protected: |
856 | machine_mode m_mode; |
857 | }; |
858 | |
859 | /* Return true if MODE has a fixed size. */ |
860 | |
861 | inline bool |
862 | fixed_size_mode::includes_p (machine_mode mode) |
863 | { |
864 | return mode_to_bytes (mode).is_constant (); |
865 | } |
866 | |
867 | /* Wrapper for mode arguments to target macros, so that if a target |
868 | doesn't need polynomial-sized modes, its header file can continue |
869 | to treat everything as fixed_size_mode. This should go away once |
870 | macros are moved to target hooks. It shouldn't be used in other |
871 | contexts. */ |
872 | #if NUM_POLY_INT_COEFFS == 1 |
873 | #define MACRO_MODE(MODE) (as_a <fixed_size_mode> (MODE)) |
874 | #else |
875 | #define MACRO_MODE(MODE) (MODE) |
876 | #endif |
877 | |
878 | extern opt_machine_mode mode_for_size (poly_uint64, enum mode_class, int); |
879 | |
880 | /* Return the machine mode to use for a MODE_INT of SIZE bits, if one |
881 | exists. If LIMIT is nonzero, modes wider than MAX_FIXED_MODE_SIZE |
882 | will not be used. */ |
883 | |
884 | inline opt_scalar_int_mode |
885 | int_mode_for_size (poly_uint64 size, int limit) |
886 | { |
887 | return dyn_cast <scalar_int_mode> (m: mode_for_size (size, MODE_INT, limit)); |
888 | } |
889 | |
890 | /* Return the machine mode to use for a MODE_FLOAT of SIZE bits, if one |
891 | exists. */ |
892 | |
893 | inline opt_scalar_float_mode |
894 | float_mode_for_size (poly_uint64 size) |
895 | { |
896 | return dyn_cast <scalar_float_mode> (m: mode_for_size (size, MODE_FLOAT, 0)); |
897 | } |
898 | |
899 | /* Likewise for MODE_DECIMAL_FLOAT. */ |
900 | |
901 | inline opt_scalar_float_mode |
902 | decimal_float_mode_for_size (unsigned int size) |
903 | { |
904 | return dyn_cast <scalar_float_mode> |
905 | (m: mode_for_size (size, MODE_DECIMAL_FLOAT, 0)); |
906 | } |
907 | |
908 | extern machine_mode smallest_mode_for_size (poly_uint64, enum mode_class); |
909 | |
910 | /* Find the narrowest integer mode that contains at least SIZE bits. |
911 | Such a mode must exist. */ |
912 | |
913 | inline scalar_int_mode |
914 | smallest_int_mode_for_size (poly_uint64 size) |
915 | { |
916 | return as_a <scalar_int_mode> (m: smallest_mode_for_size (size, MODE_INT)); |
917 | } |
918 | |
919 | extern opt_scalar_int_mode int_mode_for_mode (machine_mode); |
920 | extern opt_machine_mode bitwise_mode_for_mode (machine_mode); |
921 | extern opt_machine_mode mode_for_vector (scalar_mode, poly_uint64); |
922 | extern opt_machine_mode related_vector_mode (machine_mode, scalar_mode, |
923 | poly_uint64 = 0); |
924 | extern opt_machine_mode related_int_vector_mode (machine_mode); |
925 | |
926 | /* A class for iterating through possible bitfield modes. */ |
927 | class bit_field_mode_iterator |
928 | { |
929 | public: |
930 | bit_field_mode_iterator (HOST_WIDE_INT, HOST_WIDE_INT, |
931 | poly_int64, poly_int64, |
932 | unsigned int, bool); |
933 | bool next_mode (scalar_int_mode *); |
934 | bool prefer_smaller_modes (); |
935 | |
936 | private: |
937 | opt_scalar_int_mode m_mode; |
938 | /* We use signed values here because the bit position can be negative |
939 | for invalid input such as gcc.dg/pr48335-8.c. */ |
940 | HOST_WIDE_INT m_bitsize; |
941 | HOST_WIDE_INT m_bitpos; |
942 | poly_int64 m_bitregion_start; |
943 | poly_int64 m_bitregion_end; |
944 | unsigned int m_align; |
945 | bool m_volatilep; |
946 | int m_count; |
947 | }; |
948 | |
949 | /* Find the best mode to use to access a bit field. */ |
950 | |
951 | extern bool get_best_mode (int, int, poly_uint64, poly_uint64, unsigned int, |
952 | unsigned HOST_WIDE_INT, bool, scalar_int_mode *); |
953 | |
954 | /* Determine alignment, 1<=result<=BIGGEST_ALIGNMENT. */ |
955 | |
956 | extern CONST_MODE_BASE_ALIGN unsigned short mode_base_align[NUM_MACHINE_MODES]; |
957 | |
958 | extern unsigned get_mode_alignment (machine_mode); |
959 | |
960 | #define GET_MODE_ALIGNMENT(MODE) get_mode_alignment (MODE) |
961 | |
962 | /* For each class, get the narrowest mode in that class. */ |
963 | |
964 | extern const unsigned short class_narrowest_mode[MAX_MODE_CLASS]; |
965 | #define GET_CLASS_NARROWEST_MODE(CLASS) \ |
966 | ((machine_mode) class_narrowest_mode[CLASS]) |
967 | |
968 | /* The narrowest full integer mode available on the target. */ |
969 | |
970 | #define NARROWEST_INT_MODE \ |
971 | (scalar_int_mode \ |
972 | (scalar_int_mode::from_int (class_narrowest_mode[MODE_INT]))) |
973 | |
974 | /* Return the narrowest mode in T's class. */ |
975 | |
976 | template<typename T> |
977 | inline T |
978 | get_narrowest_mode (T mode) |
979 | { |
980 | return typename mode_traits<T>::from_int |
981 | (class_narrowest_mode[GET_MODE_CLASS (mode)]); |
982 | } |
983 | |
984 | /* Define the integer modes whose sizes are BITS_PER_UNIT and BITS_PER_WORD |
985 | and the mode whose class is Pmode and whose size is POINTER_SIZE. */ |
986 | |
987 | extern scalar_int_mode byte_mode; |
988 | extern scalar_int_mode word_mode; |
989 | extern scalar_int_mode ptr_mode; |
990 | |
991 | /* Target-dependent machine mode initialization - in insn-modes.cc. */ |
992 | extern void init_adjust_machine_modes (void); |
993 | |
994 | #define TRULY_NOOP_TRUNCATION_MODES_P(MODE1, MODE2) \ |
995 | (targetm.truly_noop_truncation (GET_MODE_PRECISION (MODE1), \ |
996 | GET_MODE_PRECISION (MODE2))) |
997 | |
998 | /* Return true if MODE is a scalar integer mode that fits in a |
999 | HOST_WIDE_INT. */ |
1000 | |
1001 | inline bool |
1002 | HWI_COMPUTABLE_MODE_P (machine_mode mode) |
1003 | { |
1004 | machine_mode mme = mode; |
1005 | return (SCALAR_INT_MODE_P (mme) |
1006 | && mode_to_precision (mode: mme).coeffs[0] <= HOST_BITS_PER_WIDE_INT); |
1007 | } |
1008 | |
1009 | inline bool |
1010 | HWI_COMPUTABLE_MODE_P (scalar_int_mode mode) |
1011 | { |
1012 | return GET_MODE_PRECISION (mode) <= HOST_BITS_PER_WIDE_INT; |
1013 | } |
1014 | |
1015 | struct int_n_data_t { |
1016 | /* These parts are initailized by genmodes output */ |
1017 | unsigned int bitsize; |
1018 | scalar_int_mode_pod m; |
1019 | /* RID_* is RID_INTN_BASE + index into this array */ |
1020 | }; |
1021 | |
1022 | /* This is also in tree.h. genmodes.cc guarantees the're sorted from |
1023 | smallest bitsize to largest bitsize. */ |
1024 | extern bool int_n_enabled_p[NUM_INT_N_ENTS]; |
1025 | extern const int_n_data_t int_n_data[NUM_INT_N_ENTS]; |
1026 | |
1027 | /* Return true if MODE has class MODE_INT, storing it as a scalar_int_mode |
1028 | in *INT_MODE if so. */ |
1029 | |
1030 | template<typename T> |
1031 | inline bool |
1032 | is_int_mode (machine_mode mode, T *int_mode) |
1033 | { |
1034 | if (GET_MODE_CLASS (mode) == MODE_INT) |
1035 | { |
1036 | *int_mode = scalar_int_mode (scalar_int_mode::from_int (mode)); |
1037 | return true; |
1038 | } |
1039 | return false; |
1040 | } |
1041 | |
1042 | /* Return true if MODE has class MODE_FLOAT, storing it as a |
1043 | scalar_float_mode in *FLOAT_MODE if so. */ |
1044 | |
1045 | template<typename T> |
1046 | inline bool |
1047 | is_float_mode (machine_mode mode, T *float_mode) |
1048 | { |
1049 | if (GET_MODE_CLASS (mode) == MODE_FLOAT) |
1050 | { |
1051 | *float_mode = scalar_float_mode (scalar_float_mode::from_int (mode)); |
1052 | return true; |
1053 | } |
1054 | return false; |
1055 | } |
1056 | |
1057 | /* Return true if MODE has class MODE_COMPLEX_INT, storing it as |
1058 | a complex_mode in *CMODE if so. */ |
1059 | |
1060 | template<typename T> |
1061 | inline bool |
1062 | is_complex_int_mode (machine_mode mode, T *cmode) |
1063 | { |
1064 | if (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT) |
1065 | { |
1066 | *cmode = complex_mode (complex_mode::from_int (mode)); |
1067 | return true; |
1068 | } |
1069 | return false; |
1070 | } |
1071 | |
1072 | /* Return true if MODE has class MODE_COMPLEX_FLOAT, storing it as |
1073 | a complex_mode in *CMODE if so. */ |
1074 | |
1075 | template<typename T> |
1076 | inline bool |
1077 | is_complex_float_mode (machine_mode mode, T *cmode) |
1078 | { |
1079 | if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT) |
1080 | { |
1081 | *cmode = complex_mode (complex_mode::from_int (mode)); |
1082 | return true; |
1083 | } |
1084 | return false; |
1085 | } |
1086 | |
1087 | /* Return true if MODE is a scalar integer mode with a precision |
1088 | smaller than LIMIT's precision. */ |
1089 | |
1090 | inline bool |
1091 | is_narrower_int_mode (machine_mode mode, scalar_int_mode limit) |
1092 | { |
1093 | scalar_int_mode int_mode; |
1094 | return (is_a <scalar_int_mode> (m: mode, result: &int_mode) |
1095 | && GET_MODE_PRECISION (mode: int_mode) < GET_MODE_PRECISION (mode: limit)); |
1096 | } |
1097 | |
1098 | namespace mode_iterator |
1099 | { |
1100 | /* Start mode iterator *ITER at the first mode in class MCLASS, if any. */ |
1101 | |
1102 | template<typename T> |
1103 | inline void |
1104 | start (opt_mode<T> *iter, enum mode_class mclass) |
1105 | { |
1106 | if (GET_CLASS_NARROWEST_MODE (mclass) == E_VOIDmode) |
1107 | *iter = opt_mode<T> (); |
1108 | else |
1109 | *iter = as_a<T> (GET_CLASS_NARROWEST_MODE (mclass)); |
1110 | } |
1111 | |
1112 | inline void |
1113 | start (machine_mode *iter, enum mode_class mclass) |
1114 | { |
1115 | *iter = GET_CLASS_NARROWEST_MODE (mclass); |
1116 | } |
1117 | |
1118 | /* Return true if mode iterator *ITER has not reached the end. */ |
1119 | |
1120 | template<typename T> |
1121 | inline bool |
1122 | iterate_p (opt_mode<T> *iter) |
1123 | { |
1124 | return iter->exists (); |
1125 | } |
1126 | |
1127 | inline bool |
1128 | iterate_p (machine_mode *iter) |
1129 | { |
1130 | return *iter != E_VOIDmode; |
1131 | } |
1132 | |
1133 | /* Set mode iterator *ITER to the next mode in the same class, |
1134 | if any. */ |
1135 | |
1136 | template<typename T> |
1137 | inline void |
1138 | get_next (opt_mode<T> *iter) |
1139 | { |
1140 | *iter = GET_MODE_NEXT_MODE (iter->require ()); |
1141 | } |
1142 | |
1143 | inline void |
1144 | get_next (machine_mode *iter) |
1145 | { |
1146 | *iter = GET_MODE_NEXT_MODE (m: *iter).else_void (); |
1147 | } |
1148 | |
1149 | /* Set mode iterator *ITER to the next mode in the same class. |
1150 | Such a mode is known to exist. */ |
1151 | |
1152 | template<typename T> |
1153 | inline void |
1154 | get_known_next (T *iter) |
1155 | { |
1156 | *iter = GET_MODE_NEXT_MODE (*iter).require (); |
1157 | } |
1158 | |
1159 | /* Set mode iterator *ITER to the next wider mode in the same class, |
1160 | if any. */ |
1161 | |
1162 | template<typename T> |
1163 | inline void |
1164 | get_wider (opt_mode<T> *iter) |
1165 | { |
1166 | *iter = GET_MODE_WIDER_MODE (iter->require ()); |
1167 | } |
1168 | |
1169 | inline void |
1170 | get_wider (machine_mode *iter) |
1171 | { |
1172 | *iter = GET_MODE_WIDER_MODE (m: *iter).else_void (); |
1173 | } |
1174 | |
1175 | /* Set mode iterator *ITER to the next wider mode in the same class. |
1176 | Such a mode is known to exist. */ |
1177 | |
1178 | template<typename T> |
1179 | inline void |
1180 | get_known_wider (T *iter) |
1181 | { |
1182 | *iter = GET_MODE_WIDER_MODE (*iter).require (); |
1183 | } |
1184 | |
1185 | /* Set mode iterator *ITER to the mode that is two times wider than the |
1186 | current one, if such a mode exists. */ |
1187 | |
1188 | template<typename T> |
1189 | inline void |
1190 | get_2xwider (opt_mode<T> *iter) |
1191 | { |
1192 | *iter = GET_MODE_2XWIDER_MODE (iter->require ()); |
1193 | } |
1194 | |
1195 | inline void |
1196 | get_2xwider (machine_mode *iter) |
1197 | { |
1198 | *iter = GET_MODE_2XWIDER_MODE (m: *iter).else_void (); |
1199 | } |
1200 | } |
1201 | |
1202 | /* Make ITERATOR iterate over all the modes in mode class CLASS, |
1203 | from narrowest to widest. */ |
1204 | #define FOR_EACH_MODE_IN_CLASS(ITERATOR, CLASS) \ |
1205 | for (mode_iterator::start (&(ITERATOR), CLASS); \ |
1206 | mode_iterator::iterate_p (&(ITERATOR)); \ |
1207 | mode_iterator::get_next (&(ITERATOR))) |
1208 | |
1209 | /* Make ITERATOR iterate over all the modes in the range [START, END), |
1210 | in order of increasing width. */ |
1211 | #define FOR_EACH_MODE(ITERATOR, START, END) \ |
1212 | for ((ITERATOR) = (START); \ |
1213 | (ITERATOR) != (END); \ |
1214 | mode_iterator::get_known_next (&(ITERATOR))) |
1215 | |
1216 | /* Make ITERATOR iterate over START and all non-narrower modes in the same |
1217 | class, in order of increasing width. */ |
1218 | #define FOR_EACH_MODE_FROM(ITERATOR, START) \ |
1219 | for ((ITERATOR) = (START); \ |
1220 | mode_iterator::iterate_p (&(ITERATOR)); \ |
1221 | mode_iterator::get_next (&(ITERATOR))) |
1222 | |
1223 | /* Make ITERATOR iterate over START and all wider modes in the same |
1224 | class, in order of strictly increasing width. */ |
1225 | #define FOR_EACH_WIDER_MODE_FROM(ITERATOR, START) \ |
1226 | for ((ITERATOR) = (START); \ |
1227 | mode_iterator::iterate_p (&(ITERATOR)); \ |
1228 | mode_iterator::get_wider (&(ITERATOR))) |
1229 | |
1230 | /* Make ITERATOR iterate over modes in the range [NARROWEST, END) |
1231 | in order of increasing width, where NARROWEST is the narrowest mode |
1232 | in END's class. */ |
1233 | #define FOR_EACH_MODE_UNTIL(ITERATOR, END) \ |
1234 | FOR_EACH_MODE (ITERATOR, get_narrowest_mode (END), END) |
1235 | |
1236 | /* Make ITERATOR iterate over modes in the same class as MODE, in order |
1237 | of non-decreasing width. Start at next such mode after START, |
1238 | or don't iterate at all if there is no such mode. */ |
1239 | #define FOR_EACH_NEXT_MODE(ITERATOR, START) \ |
1240 | for ((ITERATOR) = (START), mode_iterator::get_next (&(ITERATOR)); \ |
1241 | mode_iterator::iterate_p (&(ITERATOR)); \ |
1242 | mode_iterator::get_next (&(ITERATOR))) |
1243 | |
1244 | /* Make ITERATOR iterate over modes in the same class as MODE, in order |
1245 | of increasing width. Start at the first mode wider than START, |
1246 | or don't iterate at all if there is no wider mode. */ |
1247 | #define FOR_EACH_WIDER_MODE(ITERATOR, START) \ |
1248 | for ((ITERATOR) = (START), mode_iterator::get_wider (&(ITERATOR)); \ |
1249 | mode_iterator::iterate_p (&(ITERATOR)); \ |
1250 | mode_iterator::get_wider (&(ITERATOR))) |
1251 | |
1252 | /* Make ITERATOR iterate over modes in the same class as MODE, in order |
1253 | of increasing width, and with each mode being twice the width of the |
1254 | previous mode. Start at the mode that is two times wider than START, |
1255 | or don't iterate at all if there is no such mode. */ |
1256 | #define FOR_EACH_2XWIDER_MODE(ITERATOR, START) \ |
1257 | for ((ITERATOR) = (START), mode_iterator::get_2xwider (&(ITERATOR)); \ |
1258 | mode_iterator::iterate_p (&(ITERATOR)); \ |
1259 | mode_iterator::get_2xwider (&(ITERATOR))) |
1260 | |
1261 | template<typename T> |
1262 | void |
1263 | gt_ggc_mx (pod_mode<T> *) |
1264 | { |
1265 | } |
1266 | |
1267 | template<typename T> |
1268 | void |
1269 | gt_pch_nx (pod_mode<T> *) |
1270 | { |
1271 | } |
1272 | |
1273 | template<typename T> |
1274 | void |
1275 | gt_pch_nx (pod_mode<T> *, gt_pointer_operator, void *) |
1276 | { |
1277 | } |
1278 | |
1279 | #endif /* not HAVE_MACHINE_MODES */ |
1280 | |