Mercurial > hg > CbC > CbC_gcc
comparison gcc/machmode.h @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | f6334be47118 |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 /* Machine mode definitions for GCC; included by rtl.h and tree.h. | 1 /* Machine mode definitions for GCC; included by rtl.h and tree.h. |
2 Copyright (C) 1991, 1993, 1994, 1996, 1998, 1999, 2000, 2001, 2003, | 2 Copyright (C) 1991-2017 Free Software Foundation, Inc. |
3 2007, 2008, 2009, 2010 Free Software Foundation, Inc. | |
4 | 3 |
5 This file is part of GCC. | 4 This file is part of GCC. |
6 | 5 |
7 GCC is free software; you can redistribute it and/or modify it under | 6 GCC is free software; you can redistribute it and/or modify it under |
8 the terms of the GNU General Public License as published by the Free | 7 the terms of the GNU General Public License as published by the Free |
19 <http://www.gnu.org/licenses/>. */ | 18 <http://www.gnu.org/licenses/>. */ |
20 | 19 |
21 #ifndef HAVE_MACHINE_MODES | 20 #ifndef HAVE_MACHINE_MODES |
22 #define HAVE_MACHINE_MODES | 21 #define HAVE_MACHINE_MODES |
23 | 22 |
24 /* Make an enum class that gives all the machine modes. */ | 23 typedef opt_mode<machine_mode> opt_machine_mode; |
25 #include "insn-modes.h" | 24 |
25 extern CONST_MODE_SIZE unsigned short mode_size[NUM_MACHINE_MODES]; | |
26 extern const unsigned short mode_precision[NUM_MACHINE_MODES]; | |
27 extern const unsigned char mode_inner[NUM_MACHINE_MODES]; | |
28 extern const unsigned char 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 }; | |
26 | 78 |
27 /* Get the name of mode MODE as a string. */ | 79 /* Get the name of mode MODE as a string. */ |
28 | 80 |
29 extern const char * const mode_name[NUM_MACHINE_MODES]; | 81 extern const char * const mode_name[NUM_MACHINE_MODES]; |
30 #define GET_MODE_NAME(MODE) mode_name[MODE] | 82 #define GET_MODE_NAME(MODE) mode_name[MODE] |
164 || UNSIGNED_FIXED_POINT_MODE_P (MODE)) | 216 || UNSIGNED_FIXED_POINT_MODE_P (MODE)) |
165 | 217 |
166 /* Nonzero if CLASS modes can be widened. */ | 218 /* Nonzero if CLASS modes can be widened. */ |
167 #define CLASS_HAS_WIDER_MODES_P(CLASS) \ | 219 #define CLASS_HAS_WIDER_MODES_P(CLASS) \ |
168 (CLASS == MODE_INT \ | 220 (CLASS == MODE_INT \ |
221 || CLASS == MODE_PARTIAL_INT \ | |
169 || CLASS == MODE_FLOAT \ | 222 || CLASS == MODE_FLOAT \ |
170 || CLASS == MODE_DECIMAL_FLOAT \ | 223 || CLASS == MODE_DECIMAL_FLOAT \ |
171 || CLASS == MODE_COMPLEX_FLOAT \ | 224 || CLASS == MODE_COMPLEX_FLOAT \ |
172 || CLASS == MODE_FRACT \ | 225 || CLASS == MODE_FRACT \ |
173 || CLASS == MODE_UFRACT \ | 226 || CLASS == MODE_UFRACT \ |
174 || CLASS == MODE_ACCUM \ | 227 || CLASS == MODE_ACCUM \ |
175 || CLASS == MODE_UACCUM) | 228 || CLASS == MODE_UACCUM) |
176 | 229 |
177 /* Get the size in bytes and bits of an object of mode MODE. */ | 230 #define POINTER_BOUNDS_MODE_P(MODE) \ |
178 | 231 (GET_MODE_CLASS (MODE) == MODE_POINTER_BOUNDS) |
179 extern CONST_MODE_SIZE unsigned char mode_size[NUM_MACHINE_MODES]; | 232 |
180 #define GET_MODE_SIZE(MODE) ((unsigned short) mode_size[MODE]) | 233 /* An optional T (i.e. a T or nothing), where T is some form of mode class. */ |
181 #define GET_MODE_BITSIZE(MODE) ((unsigned short) (GET_MODE_SIZE (MODE) * BITS_PER_UNIT)) | 234 template<typename T> |
235 class opt_mode | |
236 { | |
237 public: | |
238 enum from_int { dummy = MAX_MACHINE_MODE }; | |
239 | |
240 ALWAYS_INLINE opt_mode () : m_mode (E_VOIDmode) {} | |
241 ALWAYS_INLINE opt_mode (const T &m) : m_mode (m) {} | |
242 template<typename U> | |
243 ALWAYS_INLINE opt_mode (const U &m) : m_mode (T (m)) {} | |
244 ALWAYS_INLINE opt_mode (from_int m) : m_mode (machine_mode (m)) {} | |
245 | |
246 machine_mode else_void () const; | |
247 machine_mode else_blk () const; | |
248 T require () const; | |
249 | |
250 bool exists () const; | |
251 template<typename U> bool exists (U *) const; | |
252 | |
253 private: | |
254 machine_mode m_mode; | |
255 }; | |
256 | |
257 /* If the object contains a T, return its enum value, otherwise return | |
258 E_VOIDmode. */ | |
259 | |
260 template<typename T> | |
261 ALWAYS_INLINE machine_mode | |
262 opt_mode<T>::else_void () const | |
263 { | |
264 return m_mode; | |
265 } | |
266 | |
267 /* If the T exists, return its enum value, otherwise return E_BLKmode. */ | |
268 | |
269 template<typename T> | |
270 inline machine_mode | |
271 opt_mode<T>::else_blk () const | |
272 { | |
273 return m_mode == E_VOIDmode ? E_BLKmode : m_mode; | |
274 } | |
275 | |
276 /* Assert that the object contains a T and return it. */ | |
277 | |
278 template<typename T> | |
279 inline T | |
280 opt_mode<T>::require () const | |
281 { | |
282 gcc_checking_assert (m_mode != E_VOIDmode); | |
283 return typename mode_traits<T>::from_int (m_mode); | |
284 } | |
285 | |
286 /* Return true if the object contains a T rather than nothing. */ | |
287 | |
288 template<typename T> | |
289 ALWAYS_INLINE bool | |
290 opt_mode<T>::exists () const | |
291 { | |
292 return m_mode != E_VOIDmode; | |
293 } | |
294 | |
295 /* Return true if the object contains a T, storing it in *MODE if so. */ | |
296 | |
297 template<typename T> | |
298 template<typename U> | |
299 inline bool | |
300 opt_mode<T>::exists (U *mode) const | |
301 { | |
302 if (m_mode != E_VOIDmode) | |
303 { | |
304 *mode = T (typename mode_traits<T>::from_int (m_mode)); | |
305 return true; | |
306 } | |
307 return false; | |
308 } | |
309 | |
310 /* A POD version of mode class T. */ | |
311 | |
312 template<typename T> | |
313 struct pod_mode | |
314 { | |
315 typedef typename mode_traits<T>::from_int from_int; | |
316 | |
317 machine_mode m_mode; | |
318 ALWAYS_INLINE operator machine_mode () const { return m_mode; } | |
319 ALWAYS_INLINE operator T () const { return from_int (m_mode); } | |
320 ALWAYS_INLINE pod_mode &operator = (const T &m) { m_mode = m; return *this; } | |
321 }; | |
322 | |
323 /* Return true if mode M has type T. */ | |
324 | |
325 template<typename T> | |
326 inline bool | |
327 is_a (machine_mode m) | |
328 { | |
329 return T::includes_p (m); | |
330 } | |
331 | |
332 template<typename T, typename U> | |
333 inline bool | |
334 is_a (const opt_mode<U> &m) | |
335 { | |
336 return T::includes_p (m.else_void ()); | |
337 } | |
338 | |
339 /* Assert that mode M has type T, and return it in that form. */ | |
340 | |
341 template<typename T> | |
342 inline T | |
343 as_a (machine_mode m) | |
344 { | |
345 gcc_checking_assert (T::includes_p (m)); | |
346 return typename mode_traits<T>::from_int (m); | |
347 } | |
348 | |
349 template<typename T, typename U> | |
350 inline T | |
351 as_a (const opt_mode<U> &m) | |
352 { | |
353 return as_a <T> (m.else_void ()); | |
354 } | |
355 | |
356 /* Convert M to an opt_mode<T>. */ | |
357 | |
358 template<typename T> | |
359 inline opt_mode<T> | |
360 dyn_cast (machine_mode m) | |
361 { | |
362 if (T::includes_p (m)) | |
363 return T (typename mode_traits<T>::from_int (m)); | |
364 return opt_mode<T> (); | |
365 } | |
366 | |
367 template<typename T, typename U> | |
368 inline opt_mode<T> | |
369 dyn_cast (const opt_mode<U> &m) | |
370 { | |
371 return dyn_cast <T> (m.else_void ()); | |
372 } | |
373 | |
374 /* Return true if mode M has type T, storing it as a T in *RESULT | |
375 if so. */ | |
376 | |
377 template<typename T, typename U> | |
378 inline bool | |
379 is_a (machine_mode m, U *result) | |
380 { | |
381 if (T::includes_p (m)) | |
382 { | |
383 *result = T (typename mode_traits<T>::from_int (m)); | |
384 return true; | |
385 } | |
386 return false; | |
387 } | |
388 | |
389 /* Represents a machine mode that is known to be a SCALAR_INT_MODE_P. */ | |
390 class scalar_int_mode | |
391 { | |
392 public: | |
393 typedef mode_traits<scalar_int_mode>::from_int from_int; | |
394 | |
395 ALWAYS_INLINE scalar_int_mode () {} | |
396 ALWAYS_INLINE scalar_int_mode (from_int m) : m_mode (machine_mode (m)) {} | |
397 ALWAYS_INLINE operator machine_mode () const { return m_mode; } | |
398 | |
399 static bool includes_p (machine_mode); | |
400 | |
401 protected: | |
402 machine_mode m_mode; | |
403 }; | |
404 | |
405 /* Return true if M is a scalar_int_mode. */ | |
406 | |
407 inline bool | |
408 scalar_int_mode::includes_p (machine_mode m) | |
409 { | |
410 return SCALAR_INT_MODE_P (m); | |
411 } | |
412 | |
413 /* Represents a machine mode that is known to be a SCALAR_FLOAT_MODE_P. */ | |
414 class scalar_float_mode | |
415 { | |
416 public: | |
417 typedef mode_traits<scalar_float_mode>::from_int from_int; | |
418 | |
419 ALWAYS_INLINE scalar_float_mode () {} | |
420 ALWAYS_INLINE scalar_float_mode (from_int m) : m_mode (machine_mode (m)) {} | |
421 ALWAYS_INLINE 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_float_mode. */ | |
430 | |
431 inline bool | |
432 scalar_float_mode::includes_p (machine_mode m) | |
433 { | |
434 return SCALAR_FLOAT_MODE_P (m); | |
435 } | |
436 | |
437 /* Represents a machine mode that is known to be scalar. */ | |
438 class scalar_mode | |
439 { | |
440 public: | |
441 typedef mode_traits<scalar_mode>::from_int from_int; | |
442 | |
443 ALWAYS_INLINE scalar_mode () {} | |
444 ALWAYS_INLINE scalar_mode (from_int m) : m_mode (machine_mode (m)) {} | |
445 ALWAYS_INLINE scalar_mode (const scalar_int_mode &m) : m_mode (m) {} | |
446 ALWAYS_INLINE scalar_mode (const scalar_float_mode &m) : m_mode (m) {} | |
447 ALWAYS_INLINE scalar_mode (const scalar_int_mode_pod &m) : m_mode (m) {} | |
448 ALWAYS_INLINE operator machine_mode () const { return m_mode; } | |
449 | |
450 static bool includes_p (machine_mode); | |
451 | |
452 protected: | |
453 machine_mode m_mode; | |
454 }; | |
455 | |
456 /* Return true if M represents some kind of scalar value. */ | |
457 | |
458 inline bool | |
459 scalar_mode::includes_p (machine_mode m) | |
460 { | |
461 switch (GET_MODE_CLASS (m)) | |
462 { | |
463 case MODE_INT: | |
464 case MODE_PARTIAL_INT: | |
465 case MODE_FRACT: | |
466 case MODE_UFRACT: | |
467 case MODE_ACCUM: | |
468 case MODE_UACCUM: | |
469 case MODE_FLOAT: | |
470 case MODE_DECIMAL_FLOAT: | |
471 case MODE_POINTER_BOUNDS: | |
472 return true; | |
473 default: | |
474 return false; | |
475 } | |
476 } | |
477 | |
478 /* Represents a machine mode that is known to be a COMPLEX_MODE_P. */ | |
479 class complex_mode | |
480 { | |
481 public: | |
482 typedef mode_traits<complex_mode>::from_int from_int; | |
483 | |
484 ALWAYS_INLINE complex_mode () {} | |
485 ALWAYS_INLINE complex_mode (from_int m) : m_mode (machine_mode (m)) {} | |
486 ALWAYS_INLINE 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 is a complex_mode. */ | |
495 | |
496 inline bool | |
497 complex_mode::includes_p (machine_mode m) | |
498 { | |
499 return COMPLEX_MODE_P (m); | |
500 } | |
501 | |
502 /* Return the base GET_MODE_SIZE value for MODE. */ | |
503 | |
504 ALWAYS_INLINE unsigned short | |
505 mode_to_bytes (machine_mode mode) | |
506 { | |
507 #if GCC_VERSION >= 4001 | |
508 return (__builtin_constant_p (mode) | |
509 ? mode_size_inline (mode) : mode_size[mode]); | |
510 #else | |
511 return mode_size[mode]; | |
512 #endif | |
513 } | |
514 | |
515 /* Return the base GET_MODE_BITSIZE value for MODE. */ | |
516 | |
517 ALWAYS_INLINE unsigned short | |
518 mode_to_bits (machine_mode mode) | |
519 { | |
520 return mode_to_bytes (mode) * BITS_PER_UNIT; | |
521 } | |
522 | |
523 /* Return the base GET_MODE_PRECISION value for MODE. */ | |
524 | |
525 ALWAYS_INLINE unsigned short | |
526 mode_to_precision (machine_mode mode) | |
527 { | |
528 return mode_precision[mode]; | |
529 } | |
530 | |
531 /* Return the base GET_MODE_INNER value for MODE. */ | |
532 | |
533 ALWAYS_INLINE scalar_mode | |
534 mode_to_inner (machine_mode mode) | |
535 { | |
536 #if GCC_VERSION >= 4001 | |
537 return scalar_mode::from_int (__builtin_constant_p (mode) | |
538 ? mode_inner_inline (mode) | |
539 : mode_inner[mode]); | |
540 #else | |
541 return scalar_mode::from_int (mode_inner[mode]); | |
542 #endif | |
543 } | |
544 | |
545 /* Return the base GET_MODE_UNIT_SIZE value for MODE. */ | |
546 | |
547 ALWAYS_INLINE unsigned char | |
548 mode_to_unit_size (machine_mode mode) | |
549 { | |
550 #if GCC_VERSION >= 4001 | |
551 return (__builtin_constant_p (mode) | |
552 ? mode_unit_size_inline (mode) : mode_unit_size[mode]); | |
553 #else | |
554 return mode_unit_size[mode]; | |
555 #endif | |
556 } | |
557 | |
558 /* Return the base GET_MODE_UNIT_PRECISION value for MODE. */ | |
559 | |
560 ALWAYS_INLINE unsigned short | |
561 mode_to_unit_precision (machine_mode mode) | |
562 { | |
563 #if GCC_VERSION >= 4001 | |
564 return (__builtin_constant_p (mode) | |
565 ? mode_unit_precision_inline (mode) : mode_unit_precision[mode]); | |
566 #else | |
567 return mode_unit_precision[mode]; | |
568 #endif | |
569 } | |
570 | |
571 /* Return the base GET_MODE_NUNITS value for MODE. */ | |
572 | |
573 ALWAYS_INLINE unsigned short | |
574 mode_to_nunits (machine_mode mode) | |
575 { | |
576 #if GCC_VERSION >= 4001 | |
577 return (__builtin_constant_p (mode) | |
578 ? mode_nunits_inline (mode) : mode_nunits[mode]); | |
579 #else | |
580 return mode_nunits[mode]; | |
581 #endif | |
582 } | |
583 | |
584 /* Get the size in bytes of an object of mode MODE. */ | |
585 | |
586 #define GET_MODE_SIZE(MODE) (mode_to_bytes (MODE)) | |
587 | |
588 /* Get the size in bits of an object of mode MODE. */ | |
589 | |
590 #define GET_MODE_BITSIZE(MODE) (mode_to_bits (MODE)) | |
182 | 591 |
183 /* Get the number of value bits of an object of mode MODE. */ | 592 /* Get the number of value bits of an object of mode MODE. */ |
184 extern const unsigned short mode_precision[NUM_MACHINE_MODES]; | 593 |
185 #define GET_MODE_PRECISION(MODE) mode_precision[MODE] | 594 #define GET_MODE_PRECISION(MODE) (mode_to_precision (MODE)) |
186 | 595 |
187 /* Get the number of integral bits of an object of mode MODE. */ | 596 /* Get the number of integral bits of an object of mode MODE. */ |
188 extern CONST_MODE_IBIT unsigned char mode_ibit[NUM_MACHINE_MODES]; | 597 extern CONST_MODE_IBIT unsigned char mode_ibit[NUM_MACHINE_MODES]; |
189 #define GET_MODE_IBIT(MODE) mode_ibit[MODE] | 598 #define GET_MODE_IBIT(MODE) mode_ibit[MODE] |
190 | 599 |
197 | 606 |
198 extern const unsigned HOST_WIDE_INT mode_mask_array[NUM_MACHINE_MODES]; | 607 extern const unsigned HOST_WIDE_INT mode_mask_array[NUM_MACHINE_MODES]; |
199 | 608 |
200 #define GET_MODE_MASK(MODE) mode_mask_array[MODE] | 609 #define GET_MODE_MASK(MODE) mode_mask_array[MODE] |
201 | 610 |
202 /* Return the mode of the inner elements in a vector. */ | 611 /* Return the mode of the basic parts of MODE. For vector modes this is the |
203 | 612 mode of the vector elements. For complex modes it is the mode of the real |
204 extern const unsigned char mode_inner[NUM_MACHINE_MODES]; | 613 and imaginary parts. For other modes it is MODE itself. */ |
205 #define GET_MODE_INNER(MODE) ((enum machine_mode) mode_inner[MODE]) | 614 |
206 | 615 #define GET_MODE_INNER(MODE) (mode_to_inner (MODE)) |
207 /* Get the size in bytes of the basic parts of an object of mode MODE. */ | 616 |
208 | 617 /* Get the size in bytes or bits of the basic parts of an |
209 #define GET_MODE_UNIT_SIZE(MODE) \ | 618 object of mode MODE. */ |
210 (GET_MODE_INNER (MODE) == VOIDmode \ | 619 |
211 ? GET_MODE_SIZE (MODE) \ | 620 #define GET_MODE_UNIT_SIZE(MODE) mode_to_unit_size (MODE) |
212 : GET_MODE_SIZE (GET_MODE_INNER (MODE))) | 621 |
213 | 622 #define GET_MODE_UNIT_BITSIZE(MODE) \ |
214 /* Get the number of units in the object. */ | 623 ((unsigned short) (GET_MODE_UNIT_SIZE (MODE) * BITS_PER_UNIT)) |
215 | 624 |
216 extern const unsigned char mode_nunits[NUM_MACHINE_MODES]; | 625 #define GET_MODE_UNIT_PRECISION(MODE) (mode_to_unit_precision (MODE)) |
217 #define GET_MODE_NUNITS(MODE) mode_nunits[MODE] | 626 |
627 /* Get the number of units in an object of mode MODE. This is 2 for | |
628 complex modes and the number of elements for vector modes. */ | |
629 | |
630 #define GET_MODE_NUNITS(MODE) (mode_to_nunits (MODE)) | |
218 | 631 |
219 /* Get the next wider natural mode (eg, QI -> HI -> SI -> DI -> TI). */ | 632 /* Get the next wider natural mode (eg, QI -> HI -> SI -> DI -> TI). */ |
220 | 633 |
221 extern const unsigned char mode_wider[NUM_MACHINE_MODES]; | 634 template<typename T> |
222 #define GET_MODE_WIDER_MODE(MODE) ((enum machine_mode) mode_wider[MODE]) | 635 ALWAYS_INLINE opt_mode<T> |
223 | 636 GET_MODE_WIDER_MODE (const T &m) |
224 extern const unsigned char mode_2xwider[NUM_MACHINE_MODES]; | 637 { |
225 #define GET_MODE_2XWIDER_MODE(MODE) ((enum machine_mode) mode_2xwider[MODE]) | 638 return typename opt_mode<T>::from_int (mode_wider[m]); |
226 | 639 } |
227 /* Return the mode for data of a given size SIZE and mode class CLASS. | 640 |
228 If LIMIT is nonzero, then don't use modes bigger than MAX_FIXED_MODE_SIZE. | 641 /* For scalars, this is a mode with twice the precision. For vectors, |
229 The value is BLKmode if no other mode is found. */ | 642 this is a mode with the same inner mode but with twice the elements. */ |
230 | 643 |
231 extern enum machine_mode mode_for_size (unsigned int, enum mode_class, int); | 644 template<typename T> |
232 | 645 ALWAYS_INLINE opt_mode<T> |
233 /* Similar, but find the smallest mode for a given width. */ | 646 GET_MODE_2XWIDER_MODE (const T &m) |
234 | 647 { |
235 extern enum machine_mode smallest_mode_for_size (unsigned int, | 648 return typename opt_mode<T>::from_int (mode_2xwider[m]); |
236 enum mode_class); | 649 } |
237 | 650 |
238 | 651 /* Get the complex mode from the component mode. */ |
239 /* Return an integer mode of the exact same size as the input mode, | 652 extern const unsigned char mode_complex[NUM_MACHINE_MODES]; |
240 or BLKmode on failure. */ | 653 #define GET_MODE_COMPLEX_MODE(MODE) ((machine_mode) mode_complex[MODE]) |
241 | 654 |
242 extern enum machine_mode int_mode_for_mode (enum machine_mode); | 655 extern opt_machine_mode mode_for_size (unsigned int, enum mode_class, int); |
243 | 656 |
244 /* Return a mode that is suitable for representing a vector, | 657 /* Return the machine mode to use for a MODE_INT of SIZE bits, if one |
245 or BLKmode on failure. */ | 658 exists. If LIMIT is nonzero, modes wider than MAX_FIXED_MODE_SIZE |
246 | 659 will not be used. */ |
247 extern enum machine_mode mode_for_vector (enum machine_mode, unsigned); | 660 |
661 inline opt_scalar_int_mode | |
662 int_mode_for_size (unsigned int size, int limit) | |
663 { | |
664 return dyn_cast <scalar_int_mode> (mode_for_size (size, MODE_INT, limit)); | |
665 } | |
666 | |
667 /* Return the machine mode to use for a MODE_FLOAT of SIZE bits, if one | |
668 exists. */ | |
669 | |
670 inline opt_scalar_float_mode | |
671 float_mode_for_size (unsigned int size) | |
672 { | |
673 return dyn_cast <scalar_float_mode> (mode_for_size (size, MODE_FLOAT, 0)); | |
674 } | |
675 | |
676 /* Likewise for MODE_DECIMAL_FLOAT. */ | |
677 | |
678 inline opt_scalar_float_mode | |
679 decimal_float_mode_for_size (unsigned int size) | |
680 { | |
681 return dyn_cast <scalar_float_mode> | |
682 (mode_for_size (size, MODE_DECIMAL_FLOAT, 0)); | |
683 } | |
684 | |
685 extern machine_mode smallest_mode_for_size (unsigned int, enum mode_class); | |
686 | |
687 /* Find the narrowest integer mode that contains at least SIZE bits. | |
688 Such a mode must exist. */ | |
689 | |
690 inline scalar_int_mode | |
691 smallest_int_mode_for_size (unsigned int size) | |
692 { | |
693 return as_a <scalar_int_mode> (smallest_mode_for_size (size, MODE_INT)); | |
694 } | |
695 | |
696 extern opt_scalar_int_mode int_mode_for_mode (machine_mode); | |
697 extern opt_machine_mode bitwise_mode_for_mode (machine_mode); | |
698 extern opt_machine_mode mode_for_vector (scalar_mode, unsigned); | |
699 extern opt_machine_mode mode_for_int_vector (unsigned int, unsigned int); | |
700 | |
701 /* Return the integer vector equivalent of MODE, if one exists. In other | |
702 words, return the mode for an integer vector that has the same number | |
703 of bits as MODE and the same number of elements as MODE, with the | |
704 latter being 1 if MODE is scalar. The returned mode can be either | |
705 an integer mode or a vector mode. */ | |
706 | |
707 inline opt_machine_mode | |
708 mode_for_int_vector (machine_mode mode) | |
709 { | |
710 return mode_for_int_vector (GET_MODE_UNIT_BITSIZE (mode), | |
711 GET_MODE_NUNITS (mode)); | |
712 } | |
713 | |
714 /* A class for iterating through possible bitfield modes. */ | |
715 class bit_field_mode_iterator | |
716 { | |
717 public: | |
718 bit_field_mode_iterator (HOST_WIDE_INT, HOST_WIDE_INT, | |
719 HOST_WIDE_INT, HOST_WIDE_INT, | |
720 unsigned int, bool); | |
721 bool next_mode (scalar_int_mode *); | |
722 bool prefer_smaller_modes (); | |
723 | |
724 private: | |
725 opt_scalar_int_mode m_mode; | |
726 /* We use signed values here because the bit position can be negative | |
727 for invalid input such as gcc.dg/pr48335-8.c. */ | |
728 HOST_WIDE_INT m_bitsize; | |
729 HOST_WIDE_INT m_bitpos; | |
730 HOST_WIDE_INT m_bitregion_start; | |
731 HOST_WIDE_INT m_bitregion_end; | |
732 unsigned int m_align; | |
733 bool m_volatilep; | |
734 int m_count; | |
735 }; | |
248 | 736 |
249 /* Find the best mode to use to access a bit field. */ | 737 /* Find the best mode to use to access a bit field. */ |
250 | 738 |
251 extern enum machine_mode get_best_mode (int, int, unsigned int, | 739 extern bool get_best_mode (int, int, unsigned HOST_WIDE_INT, |
252 enum machine_mode, int); | 740 unsigned HOST_WIDE_INT, unsigned int, |
741 unsigned HOST_WIDE_INT, bool, scalar_int_mode *); | |
253 | 742 |
254 /* Determine alignment, 1<=result<=BIGGEST_ALIGNMENT. */ | 743 /* Determine alignment, 1<=result<=BIGGEST_ALIGNMENT. */ |
255 | 744 |
256 extern CONST_MODE_BASE_ALIGN unsigned char mode_base_align[NUM_MACHINE_MODES]; | 745 extern CONST_MODE_BASE_ALIGN unsigned short mode_base_align[NUM_MACHINE_MODES]; |
257 | 746 |
258 extern unsigned get_mode_alignment (enum machine_mode); | 747 extern unsigned get_mode_alignment (machine_mode); |
259 | 748 |
260 #define GET_MODE_ALIGNMENT(MODE) get_mode_alignment (MODE) | 749 #define GET_MODE_ALIGNMENT(MODE) get_mode_alignment (MODE) |
261 | 750 |
262 /* For each class, get the narrowest mode in that class. */ | 751 /* For each class, get the narrowest mode in that class. */ |
263 | 752 |
264 extern const unsigned char class_narrowest_mode[MAX_MODE_CLASS]; | 753 extern const unsigned char class_narrowest_mode[MAX_MODE_CLASS]; |
265 #define GET_CLASS_NARROWEST_MODE(CLASS) \ | 754 #define GET_CLASS_NARROWEST_MODE(CLASS) \ |
266 ((enum machine_mode) class_narrowest_mode[CLASS]) | 755 ((machine_mode) class_narrowest_mode[CLASS]) |
756 | |
757 /* The narrowest full integer mode available on the target. */ | |
758 | |
759 #define NARROWEST_INT_MODE \ | |
760 (scalar_int_mode \ | |
761 (scalar_int_mode::from_int (class_narrowest_mode[MODE_INT]))) | |
762 | |
763 /* Return the narrowest mode in T's class. */ | |
764 | |
765 template<typename T> | |
766 inline T | |
767 get_narrowest_mode (T mode) | |
768 { | |
769 return typename mode_traits<T>::from_int | |
770 (class_narrowest_mode[GET_MODE_CLASS (mode)]); | |
771 } | |
267 | 772 |
268 /* Define the integer modes whose sizes are BITS_PER_UNIT and BITS_PER_WORD | 773 /* Define the integer modes whose sizes are BITS_PER_UNIT and BITS_PER_WORD |
269 and the mode whose class is Pmode and whose size is POINTER_SIZE. */ | 774 and the mode whose class is Pmode and whose size is POINTER_SIZE. */ |
270 | 775 |
271 extern enum machine_mode byte_mode; | 776 extern scalar_int_mode byte_mode; |
272 extern enum machine_mode word_mode; | 777 extern scalar_int_mode word_mode; |
273 extern enum machine_mode ptr_mode; | 778 extern scalar_int_mode ptr_mode; |
274 | 779 |
275 /* Target-dependent machine mode initialization - in insn-modes.c. */ | 780 /* Target-dependent machine mode initialization - in insn-modes.c. */ |
276 extern void init_adjust_machine_modes (void); | 781 extern void init_adjust_machine_modes (void); |
277 | 782 |
783 #define TRULY_NOOP_TRUNCATION_MODES_P(MODE1, MODE2) \ | |
784 (targetm.truly_noop_truncation (GET_MODE_PRECISION (MODE1), \ | |
785 GET_MODE_PRECISION (MODE2))) | |
786 | |
787 #define HWI_COMPUTABLE_MODE_P(MODE) \ | |
788 (SCALAR_INT_MODE_P (MODE) \ | |
789 && GET_MODE_PRECISION (MODE) <= HOST_BITS_PER_WIDE_INT) | |
790 | |
791 struct int_n_data_t { | |
792 /* These parts are initailized by genmodes output */ | |
793 unsigned int bitsize; | |
794 scalar_int_mode_pod m; | |
795 /* RID_* is RID_INTN_BASE + index into this array */ | |
796 }; | |
797 | |
798 /* This is also in tree.h. genmodes.c guarantees the're sorted from | |
799 smallest bitsize to largest bitsize. */ | |
800 extern bool int_n_enabled_p[NUM_INT_N_ENTS]; | |
801 extern const int_n_data_t int_n_data[NUM_INT_N_ENTS]; | |
802 | |
803 /* Return true if MODE has class MODE_INT, storing it as a scalar_int_mode | |
804 in *INT_MODE if so. */ | |
805 | |
806 template<typename T> | |
807 inline bool | |
808 is_int_mode (machine_mode mode, T *int_mode) | |
809 { | |
810 if (GET_MODE_CLASS (mode) == MODE_INT) | |
811 { | |
812 *int_mode = scalar_int_mode (scalar_int_mode::from_int (mode)); | |
813 return true; | |
814 } | |
815 return false; | |
816 } | |
817 | |
818 /* Return true if MODE has class MODE_FLOAT, storing it as a | |
819 scalar_float_mode in *FLOAT_MODE if so. */ | |
820 | |
821 template<typename T> | |
822 inline bool | |
823 is_float_mode (machine_mode mode, T *float_mode) | |
824 { | |
825 if (GET_MODE_CLASS (mode) == MODE_FLOAT) | |
826 { | |
827 *float_mode = scalar_float_mode (scalar_float_mode::from_int (mode)); | |
828 return true; | |
829 } | |
830 return false; | |
831 } | |
832 | |
833 /* Return true if MODE has class MODE_COMPLEX_INT, storing it as | |
834 a complex_mode in *CMODE if so. */ | |
835 | |
836 template<typename T> | |
837 inline bool | |
838 is_complex_int_mode (machine_mode mode, T *cmode) | |
839 { | |
840 if (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT) | |
841 { | |
842 *cmode = complex_mode (complex_mode::from_int (mode)); | |
843 return true; | |
844 } | |
845 return false; | |
846 } | |
847 | |
848 /* Return true if MODE has class MODE_COMPLEX_FLOAT, storing it as | |
849 a complex_mode in *CMODE if so. */ | |
850 | |
851 template<typename T> | |
852 inline bool | |
853 is_complex_float_mode (machine_mode mode, T *cmode) | |
854 { | |
855 if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT) | |
856 { | |
857 *cmode = complex_mode (complex_mode::from_int (mode)); | |
858 return true; | |
859 } | |
860 return false; | |
861 } | |
862 | |
863 namespace mode_iterator | |
864 { | |
865 /* Start mode iterator *ITER at the first mode in class MCLASS, if any. */ | |
866 | |
867 template<typename T> | |
868 inline void | |
869 start (opt_mode<T> *iter, enum mode_class mclass) | |
870 { | |
871 if (GET_CLASS_NARROWEST_MODE (mclass) == E_VOIDmode) | |
872 *iter = opt_mode<T> (); | |
873 else | |
874 *iter = as_a<T> (GET_CLASS_NARROWEST_MODE (mclass)); | |
875 } | |
876 | |
877 inline void | |
878 start (machine_mode *iter, enum mode_class mclass) | |
879 { | |
880 *iter = GET_CLASS_NARROWEST_MODE (mclass); | |
881 } | |
882 | |
883 /* Return true if mode iterator *ITER has not reached the end. */ | |
884 | |
885 template<typename T> | |
886 inline bool | |
887 iterate_p (opt_mode<T> *iter) | |
888 { | |
889 return iter->exists (); | |
890 } | |
891 | |
892 inline bool | |
893 iterate_p (machine_mode *iter) | |
894 { | |
895 return *iter != E_VOIDmode; | |
896 } | |
897 | |
898 /* Set mode iterator *ITER to the next widest mode in the same class, | |
899 if any. */ | |
900 | |
901 template<typename T> | |
902 inline void | |
903 get_wider (opt_mode<T> *iter) | |
904 { | |
905 *iter = GET_MODE_WIDER_MODE (iter->require ()); | |
906 } | |
907 | |
908 inline void | |
909 get_wider (machine_mode *iter) | |
910 { | |
911 *iter = GET_MODE_WIDER_MODE (*iter).else_void (); | |
912 } | |
913 | |
914 /* Set mode iterator *ITER to the next widest mode in the same class. | |
915 Such a mode is known to exist. */ | |
916 | |
917 template<typename T> | |
918 inline void | |
919 get_known_wider (T *iter) | |
920 { | |
921 *iter = GET_MODE_WIDER_MODE (*iter).require (); | |
922 } | |
923 | |
924 /* Set mode iterator *ITER to the mode that is two times wider than the | |
925 current one, if such a mode exists. */ | |
926 | |
927 template<typename T> | |
928 inline void | |
929 get_2xwider (opt_mode<T> *iter) | |
930 { | |
931 *iter = GET_MODE_2XWIDER_MODE (iter->require ()); | |
932 } | |
933 | |
934 inline void | |
935 get_2xwider (machine_mode *iter) | |
936 { | |
937 *iter = GET_MODE_2XWIDER_MODE (*iter).else_void (); | |
938 } | |
939 } | |
940 | |
941 /* Make ITERATOR iterate over all the modes in mode class CLASS, | |
942 from narrowest to widest. */ | |
943 #define FOR_EACH_MODE_IN_CLASS(ITERATOR, CLASS) \ | |
944 for (mode_iterator::start (&(ITERATOR), CLASS); \ | |
945 mode_iterator::iterate_p (&(ITERATOR)); \ | |
946 mode_iterator::get_wider (&(ITERATOR))) | |
947 | |
948 /* Make ITERATOR iterate over all the modes in the range [START, END), | |
949 in order of increasing width. */ | |
950 #define FOR_EACH_MODE(ITERATOR, START, END) \ | |
951 for ((ITERATOR) = (START); \ | |
952 (ITERATOR) != (END); \ | |
953 mode_iterator::get_known_wider (&(ITERATOR))) | |
954 | |
955 /* Make ITERATOR iterate over START and all wider modes in the same | |
956 class, in order of increasing width. */ | |
957 #define FOR_EACH_MODE_FROM(ITERATOR, START) \ | |
958 for ((ITERATOR) = (START); \ | |
959 mode_iterator::iterate_p (&(ITERATOR)); \ | |
960 mode_iterator::get_wider (&(ITERATOR))) | |
961 | |
962 /* Make ITERATOR iterate over modes in the range [NARROWEST, END) | |
963 in order of increasing width, where NARROWEST is the narrowest mode | |
964 in END's class. */ | |
965 #define FOR_EACH_MODE_UNTIL(ITERATOR, END) \ | |
966 FOR_EACH_MODE (ITERATOR, get_narrowest_mode (END), END) | |
967 | |
968 /* Make ITERATOR iterate over modes in the same class as MODE, in order | |
969 of increasing width. Start at the first mode wider than START, | |
970 or don't iterate at all if there is no wider mode. */ | |
971 #define FOR_EACH_WIDER_MODE(ITERATOR, START) \ | |
972 for ((ITERATOR) = (START), mode_iterator::get_wider (&(ITERATOR)); \ | |
973 mode_iterator::iterate_p (&(ITERATOR)); \ | |
974 mode_iterator::get_wider (&(ITERATOR))) | |
975 | |
976 /* Make ITERATOR iterate over modes in the same class as MODE, in order | |
977 of increasing width, and with each mode being twice the width of the | |
978 previous mode. Start at the mode that is two times wider than START, | |
979 or don't iterate at all if there is no such mode. */ | |
980 #define FOR_EACH_2XWIDER_MODE(ITERATOR, START) \ | |
981 for ((ITERATOR) = (START), mode_iterator::get_2xwider (&(ITERATOR)); \ | |
982 mode_iterator::iterate_p (&(ITERATOR)); \ | |
983 mode_iterator::get_2xwider (&(ITERATOR))) | |
984 | |
985 template<typename T> | |
986 void | |
987 gt_ggc_mx (pod_mode<T> *) | |
988 { | |
989 } | |
990 | |
991 template<typename T> | |
992 void | |
993 gt_pch_nx (pod_mode<T> *) | |
994 { | |
995 } | |
996 | |
997 template<typename T> | |
998 void | |
999 gt_pch_nx (pod_mode<T> *, void (*) (void *, void *), void *) | |
1000 { | |
1001 } | |
1002 | |
278 #endif /* not HAVE_MACHINE_MODES */ | 1003 #endif /* not HAVE_MACHINE_MODES */ |