source: arduino-1-6-7/trunk/fuentes/arduino-ide-amd64/hardware/tools/avr/lib/gcc/avr/4.9.2/plugin/include/hard-reg-set.h @ 4837

Last change on this file since 4837 was 4837, checked in by daduve, 2 years ago

Adding new version

File size: 22.7 KB
Line 
1/* Sets (bit vectors) of hard registers, and operations on them.
2   Copyright (C) 1987-2014 Free Software Foundation, Inc.
3
4This file is part of GCC
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 3, or (at your option) any later
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING3.  If not see
18<http://www.gnu.org/licenses/>.  */
19
20#ifndef GCC_HARD_REG_SET_H
21#define GCC_HARD_REG_SET_H
22
23/* Define the type of a set of hard registers.  */
24
25/* HARD_REG_ELT_TYPE is a typedef of the unsigned integral type which
26   will be used for hard reg sets, either alone or in an array.
27
28   If HARD_REG_SET is a macro, its definition is HARD_REG_ELT_TYPE,
29   and it has enough bits to represent all the target machine's hard
30   registers.  Otherwise, it is a typedef for a suitably sized array
31   of HARD_REG_ELT_TYPEs.  HARD_REG_SET_LONGS is defined as how many.
32
33   Note that lots of code assumes that the first part of a regset is
34   the same format as a HARD_REG_SET.  To help make sure this is true,
35   we only try the widest fast integer mode (HOST_WIDEST_FAST_INT)
36   instead of all the smaller types.  This approach loses only if
37   there are very few registers and then only in the few cases where
38   we have an array of HARD_REG_SETs, so it needn't be as complex as
39   it used to be.  */
40
41typedef unsigned HOST_WIDEST_FAST_INT HARD_REG_ELT_TYPE;
42
43#if FIRST_PSEUDO_REGISTER <= HOST_BITS_PER_WIDEST_FAST_INT
44
45#define HARD_REG_SET HARD_REG_ELT_TYPE
46
47#else
48
49#define HARD_REG_SET_LONGS \
50 ((FIRST_PSEUDO_REGISTER + HOST_BITS_PER_WIDEST_FAST_INT - 1)   \
51  / HOST_BITS_PER_WIDEST_FAST_INT)
52typedef HARD_REG_ELT_TYPE HARD_REG_SET[HARD_REG_SET_LONGS];
53
54#endif
55
56/* HARD_REG_SET wrapped into a structure, to make it possible to
57   use HARD_REG_SET even in APIs that should not include
58   hard-reg-set.h.  */
59struct hard_reg_set_container
60{
61  HARD_REG_SET set;
62};
63
64/* HARD_CONST is used to cast a constant to the appropriate type
65   for use with a HARD_REG_SET.  */
66
67#define HARD_CONST(X) ((HARD_REG_ELT_TYPE) (X))
68
69/* Define macros SET_HARD_REG_BIT, CLEAR_HARD_REG_BIT and TEST_HARD_REG_BIT
70   to set, clear or test one bit in a hard reg set of type HARD_REG_SET.
71   All three take two arguments: the set and the register number.
72
73   In the case where sets are arrays of longs, the first argument
74   is actually a pointer to a long.
75
76   Define two macros for initializing a set:
77   CLEAR_HARD_REG_SET and SET_HARD_REG_SET.
78   These take just one argument.
79
80   Also define macros for copying hard reg sets:
81   COPY_HARD_REG_SET and COMPL_HARD_REG_SET.
82   These take two arguments TO and FROM; they read from FROM
83   and store into TO.  COMPL_HARD_REG_SET complements each bit.
84
85   Also define macros for combining hard reg sets:
86   IOR_HARD_REG_SET and AND_HARD_REG_SET.
87   These take two arguments TO and FROM; they read from FROM
88   and combine bitwise into TO.  Define also two variants
89   IOR_COMPL_HARD_REG_SET and AND_COMPL_HARD_REG_SET
90   which use the complement of the set FROM.
91
92   Also define:
93
94   hard_reg_set_subset_p (X, Y), which returns true if X is a subset of Y.
95   hard_reg_set_equal_p (X, Y), which returns true if X and Y are equal.
96   hard_reg_set_intersect_p (X, Y), which returns true if X and Y intersect.
97   hard_reg_set_empty_p (X), which returns true if X is empty.  */
98
99#define UHOST_BITS_PER_WIDE_INT ((unsigned) HOST_BITS_PER_WIDEST_FAST_INT)
100
101#ifdef HARD_REG_SET
102
103#define SET_HARD_REG_BIT(SET, BIT)  \
104 ((SET) |= HARD_CONST (1) << (BIT))
105#define CLEAR_HARD_REG_BIT(SET, BIT)  \
106 ((SET) &= ~(HARD_CONST (1) << (BIT)))
107#define TEST_HARD_REG_BIT(SET, BIT)  \
108 (!!((SET) & (HARD_CONST (1) << (BIT))))
109
110#define CLEAR_HARD_REG_SET(TO) ((TO) = HARD_CONST (0))
111#define SET_HARD_REG_SET(TO) ((TO) = ~ HARD_CONST (0))
112
113#define COPY_HARD_REG_SET(TO, FROM) ((TO) = (FROM))
114#define COMPL_HARD_REG_SET(TO, FROM) ((TO) = ~(FROM))
115
116#define IOR_HARD_REG_SET(TO, FROM) ((TO) |= (FROM))
117#define IOR_COMPL_HARD_REG_SET(TO, FROM) ((TO) |= ~ (FROM))
118#define AND_HARD_REG_SET(TO, FROM) ((TO) &= (FROM))
119#define AND_COMPL_HARD_REG_SET(TO, FROM) ((TO) &= ~ (FROM))
120
121static inline bool
122hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)
123{
124  return (x & ~y) == HARD_CONST (0);
125}
126
127static inline bool
128hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)
129{
130  return x == y;
131}
132
133static inline bool
134hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)
135{
136  return (x & y) != HARD_CONST (0);
137}
138
139static inline bool
140hard_reg_set_empty_p (const HARD_REG_SET x)
141{
142  return x == HARD_CONST (0);
143}
144
145#else
146
147#define SET_HARD_REG_BIT(SET, BIT)              \
148  ((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT]       \
149   |= HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT))
150
151#define CLEAR_HARD_REG_BIT(SET, BIT)            \
152  ((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT]       \
153   &= ~(HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT)))
154
155#define TEST_HARD_REG_BIT(SET, BIT)             \
156  (!!((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT]    \
157      & (HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT))))
158
159#if FIRST_PSEUDO_REGISTER <= 2*HOST_BITS_PER_WIDEST_FAST_INT
160#define CLEAR_HARD_REG_SET(TO)  \
161do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);                        \
162     scan_tp_[0] = 0;                                           \
163     scan_tp_[1] = 0; } while (0)
164
165#define SET_HARD_REG_SET(TO)  \
166do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);                        \
167     scan_tp_[0] = -1;                                          \
168     scan_tp_[1] = -1; } while (0)
169
170#define COPY_HARD_REG_SET(TO, FROM)  \
171do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
172     scan_tp_[0] = scan_fp_[0];                                 \
173     scan_tp_[1] = scan_fp_[1]; } while (0)
174
175#define COMPL_HARD_REG_SET(TO, FROM)  \
176do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
177     scan_tp_[0] = ~ scan_fp_[0];                               \
178     scan_tp_[1] = ~ scan_fp_[1]; } while (0)
179
180#define AND_HARD_REG_SET(TO, FROM)  \
181do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
182     scan_tp_[0] &= scan_fp_[0];                                \
183     scan_tp_[1] &= scan_fp_[1]; } while (0)
184
185#define AND_COMPL_HARD_REG_SET(TO, FROM)  \
186do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
187     scan_tp_[0] &= ~ scan_fp_[0];                              \
188     scan_tp_[1] &= ~ scan_fp_[1]; } while (0)
189
190#define IOR_HARD_REG_SET(TO, FROM)  \
191do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
192     scan_tp_[0] |= scan_fp_[0];                                \
193     scan_tp_[1] |= scan_fp_[1]; } while (0)
194
195#define IOR_COMPL_HARD_REG_SET(TO, FROM)  \
196do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
197     scan_tp_[0] |= ~ scan_fp_[0];                              \
198     scan_tp_[1] |= ~ scan_fp_[1]; } while (0)
199
200static inline bool
201hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)
202{
203  return (x[0] & ~y[0]) == 0 && (x[1] & ~y[1]) == 0;
204}
205
206static inline bool
207hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)
208{
209  return x[0] == y[0] && x[1] == y[1];
210}
211
212static inline bool
213hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)
214{
215  return (x[0] & y[0]) != 0 || (x[1] & y[1]) != 0;
216}
217
218static inline bool
219hard_reg_set_empty_p (const HARD_REG_SET x)
220{
221  return x[0] == 0 && x[1] == 0;
222}
223
224#else
225#if FIRST_PSEUDO_REGISTER <= 3*HOST_BITS_PER_WIDEST_FAST_INT
226#define CLEAR_HARD_REG_SET(TO)  \
227do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);                        \
228     scan_tp_[0] = 0;                                           \
229     scan_tp_[1] = 0;                                           \
230     scan_tp_[2] = 0; } while (0)
231
232#define SET_HARD_REG_SET(TO)  \
233do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);                        \
234     scan_tp_[0] = -1;                                          \
235     scan_tp_[1] = -1;                                          \
236     scan_tp_[2] = -1; } while (0)
237
238#define COPY_HARD_REG_SET(TO, FROM)  \
239do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
240     scan_tp_[0] = scan_fp_[0];                                 \
241     scan_tp_[1] = scan_fp_[1];                                 \
242     scan_tp_[2] = scan_fp_[2]; } while (0)
243
244#define COMPL_HARD_REG_SET(TO, FROM)  \
245do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
246     scan_tp_[0] = ~ scan_fp_[0];                               \
247     scan_tp_[1] = ~ scan_fp_[1];                               \
248     scan_tp_[2] = ~ scan_fp_[2]; } while (0)
249
250#define AND_HARD_REG_SET(TO, FROM)  \
251do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
252     scan_tp_[0] &= scan_fp_[0];                                \
253     scan_tp_[1] &= scan_fp_[1];                                \
254     scan_tp_[2] &= scan_fp_[2]; } while (0)
255
256#define AND_COMPL_HARD_REG_SET(TO, FROM)  \
257do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
258     scan_tp_[0] &= ~ scan_fp_[0];                              \
259     scan_tp_[1] &= ~ scan_fp_[1];                              \
260     scan_tp_[2] &= ~ scan_fp_[2]; } while (0)
261
262#define IOR_HARD_REG_SET(TO, FROM)  \
263do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
264     scan_tp_[0] |= scan_fp_[0];                                \
265     scan_tp_[1] |= scan_fp_[1];                                \
266     scan_tp_[2] |= scan_fp_[2]; } while (0)
267
268#define IOR_COMPL_HARD_REG_SET(TO, FROM)  \
269do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
270     scan_tp_[0] |= ~ scan_fp_[0];                              \
271     scan_tp_[1] |= ~ scan_fp_[1];                              \
272     scan_tp_[2] |= ~ scan_fp_[2]; } while (0)
273
274static inline bool
275hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)
276{
277  return ((x[0] & ~y[0]) == 0
278          && (x[1] & ~y[1]) == 0
279          && (x[2] & ~y[2]) == 0);
280}
281
282static inline bool
283hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)
284{
285  return x[0] == y[0] && x[1] == y[1] && x[2] == y[2];
286}
287
288static inline bool
289hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)
290{
291  return ((x[0] & y[0]) != 0
292          || (x[1] & y[1]) != 0
293          || (x[2] & y[2]) != 0);
294}
295
296static inline bool
297hard_reg_set_empty_p (const HARD_REG_SET x)
298{
299  return x[0] == 0 && x[1] == 0 && x[2] == 0;
300}
301
302#else
303#if FIRST_PSEUDO_REGISTER <= 4*HOST_BITS_PER_WIDEST_FAST_INT
304#define CLEAR_HARD_REG_SET(TO)  \
305do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);                        \
306     scan_tp_[0] = 0;                                           \
307     scan_tp_[1] = 0;                                           \
308     scan_tp_[2] = 0;                                           \
309     scan_tp_[3] = 0; } while (0)
310
311#define SET_HARD_REG_SET(TO)  \
312do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);                        \
313     scan_tp_[0] = -1;                                          \
314     scan_tp_[1] = -1;                                          \
315     scan_tp_[2] = -1;                                          \
316     scan_tp_[3] = -1; } while (0)
317
318#define COPY_HARD_REG_SET(TO, FROM)  \
319do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
320     scan_tp_[0] = scan_fp_[0];                                 \
321     scan_tp_[1] = scan_fp_[1];                                 \
322     scan_tp_[2] = scan_fp_[2];                                 \
323     scan_tp_[3] = scan_fp_[3]; } while (0)
324
325#define COMPL_HARD_REG_SET(TO, FROM)  \
326do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
327     scan_tp_[0] = ~ scan_fp_[0];                               \
328     scan_tp_[1] = ~ scan_fp_[1];                               \
329     scan_tp_[2] = ~ scan_fp_[2];                               \
330     scan_tp_[3] = ~ scan_fp_[3]; } while (0)
331
332#define AND_HARD_REG_SET(TO, FROM)  \
333do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
334     scan_tp_[0] &= scan_fp_[0];                                \
335     scan_tp_[1] &= scan_fp_[1];                                \
336     scan_tp_[2] &= scan_fp_[2];                                \
337     scan_tp_[3] &= scan_fp_[3]; } while (0)
338
339#define AND_COMPL_HARD_REG_SET(TO, FROM)  \
340do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
341     scan_tp_[0] &= ~ scan_fp_[0];                              \
342     scan_tp_[1] &= ~ scan_fp_[1];                              \
343     scan_tp_[2] &= ~ scan_fp_[2];                              \
344     scan_tp_[3] &= ~ scan_fp_[3]; } while (0)
345
346#define IOR_HARD_REG_SET(TO, FROM)  \
347do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
348     scan_tp_[0] |= scan_fp_[0];                                \
349     scan_tp_[1] |= scan_fp_[1];                                \
350     scan_tp_[2] |= scan_fp_[2];                                \
351     scan_tp_[3] |= scan_fp_[3]; } while (0)
352
353#define IOR_COMPL_HARD_REG_SET(TO, FROM)  \
354do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
355     scan_tp_[0] |= ~ scan_fp_[0];                              \
356     scan_tp_[1] |= ~ scan_fp_[1];                              \
357     scan_tp_[2] |= ~ scan_fp_[2];                              \
358     scan_tp_[3] |= ~ scan_fp_[3]; } while (0)
359
360static inline bool
361hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)
362{
363  return ((x[0] & ~y[0]) == 0
364          && (x[1] & ~y[1]) == 0
365          && (x[2] & ~y[2]) == 0
366          && (x[3] & ~y[3]) == 0);
367}
368
369static inline bool
370hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)
371{
372  return x[0] == y[0] && x[1] == y[1] && x[2] == y[2] && x[3] == y[3];
373}
374
375static inline bool
376hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)
377{
378  return ((x[0] & y[0]) != 0
379          || (x[1] & y[1]) != 0
380          || (x[2] & y[2]) != 0
381          || (x[3] & y[3]) != 0);
382}
383
384static inline bool
385hard_reg_set_empty_p (const HARD_REG_SET x)
386{
387  return x[0] == 0 && x[1] == 0 && x[2] == 0 && x[3] == 0;
388}
389
390#else /* FIRST_PSEUDO_REGISTER > 4*HOST_BITS_PER_WIDEST_FAST_INT */
391
392#define CLEAR_HARD_REG_SET(TO)  \
393do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);                        \
394     int i;                                                     \
395     for (i = 0; i < HARD_REG_SET_LONGS; i++)                   \
396       *scan_tp_++ = 0; } while (0)
397
398#define SET_HARD_REG_SET(TO)  \
399do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);                        \
400     int i;                                                     \
401     for (i = 0; i < HARD_REG_SET_LONGS; i++)                   \
402       *scan_tp_++ = -1; } while (0)
403
404#define COPY_HARD_REG_SET(TO, FROM)  \
405do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
406     int i;                                                     \
407     for (i = 0; i < HARD_REG_SET_LONGS; i++)                   \
408       *scan_tp_++ = *scan_fp_++; } while (0)
409
410#define COMPL_HARD_REG_SET(TO, FROM)  \
411do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
412     int i;                                                     \
413     for (i = 0; i < HARD_REG_SET_LONGS; i++)                   \
414       *scan_tp_++ = ~ *scan_fp_++; } while (0)
415
416#define AND_HARD_REG_SET(TO, FROM)  \
417do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
418     int i;                                                     \
419     for (i = 0; i < HARD_REG_SET_LONGS; i++)                   \
420       *scan_tp_++ &= *scan_fp_++; } while (0)
421
422#define AND_COMPL_HARD_REG_SET(TO, FROM)  \
423do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
424     int i;                                                     \
425     for (i = 0; i < HARD_REG_SET_LONGS; i++)                   \
426       *scan_tp_++ &= ~ *scan_fp_++; } while (0)
427
428#define IOR_HARD_REG_SET(TO, FROM)  \
429do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
430     int i;                                                     \
431     for (i = 0; i < HARD_REG_SET_LONGS; i++)                   \
432       *scan_tp_++ |= *scan_fp_++; } while (0)
433
434#define IOR_COMPL_HARD_REG_SET(TO, FROM)  \
435do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
436     int i;                                                     \
437     for (i = 0; i < HARD_REG_SET_LONGS; i++)                   \
438       *scan_tp_++ |= ~ *scan_fp_++; } while (0)
439
440static inline bool
441hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)
442{
443  int i;
444
445  for (i = 0; i < HARD_REG_SET_LONGS; i++)
446    if ((x[i] & ~y[i]) != 0)
447      return false;
448  return true;
449}
450
451static inline bool
452hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)
453{
454  int i;
455
456  for (i = 0; i < HARD_REG_SET_LONGS; i++)
457    if (x[i] != y[i])
458      return false;
459  return true;
460}
461
462static inline bool
463hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)
464{
465  int i;
466
467  for (i = 0; i < HARD_REG_SET_LONGS; i++)
468    if ((x[i] & y[i]) != 0)
469      return true;
470  return false;
471}
472
473static inline bool
474hard_reg_set_empty_p (const HARD_REG_SET x)
475{
476  int i;
477
478  for (i = 0; i < HARD_REG_SET_LONGS; i++)
479    if (x[i] != 0)
480      return false;
481  return true;
482}
483
484#endif
485#endif
486#endif
487#endif
488
489/* Iterator for hard register sets.  */
490
491struct hard_reg_set_iterator
492{
493  /* Pointer to the current element.  */
494  HARD_REG_ELT_TYPE *pelt;
495
496  /* The length of the set.  */
497  unsigned short length;
498
499  /* Word within the current element.  */
500  unsigned short word_no;
501
502  /* Contents of the actually processed word.  When finding next bit
503     it is shifted right, so that the actual bit is always the least
504     significant bit of ACTUAL.  */
505  HARD_REG_ELT_TYPE bits;
506};
507
508#define HARD_REG_ELT_BITS UHOST_BITS_PER_WIDE_INT
509
510/* The implementation of the iterator functions is fully analogous to
511   the bitmap iterators.  */
512static inline void
513hard_reg_set_iter_init (hard_reg_set_iterator *iter, HARD_REG_SET set,
514                        unsigned min, unsigned *regno)
515{
516#ifdef HARD_REG_SET_LONGS
517  iter->pelt = set;
518  iter->length = HARD_REG_SET_LONGS;
519#else
520  iter->pelt = &set;
521  iter->length = 1;
522#endif
523  iter->word_no = min / HARD_REG_ELT_BITS;
524  if (iter->word_no < iter->length)
525    {
526      iter->bits = iter->pelt[iter->word_no];
527      iter->bits >>= min % HARD_REG_ELT_BITS;
528
529      /* This is required for correct search of the next bit.  */
530      min += !iter->bits;
531    }
532  *regno = min;
533}
534
535static inline bool
536hard_reg_set_iter_set (hard_reg_set_iterator *iter, unsigned *regno)
537{
538  while (1)
539    {
540      /* Return false when we're advanced past the end of the set.  */
541      if (iter->word_no >= iter->length)
542        return false;
543
544      if (iter->bits)
545        {
546          /* Find the correct bit and return it.  */
547          while (!(iter->bits & 1))
548            {
549              iter->bits >>= 1;
550              *regno += 1;
551            }
552          return (*regno < FIRST_PSEUDO_REGISTER);
553        }
554
555      /* Round to the beginning of the next word.  */
556      *regno = (*regno + HARD_REG_ELT_BITS - 1);
557      *regno -= *regno % HARD_REG_ELT_BITS;
558
559      /* Find the next non-zero word.  */
560      while (++iter->word_no < iter->length)
561        {
562          iter->bits = iter->pelt[iter->word_no];
563          if (iter->bits)
564            break;
565          *regno += HARD_REG_ELT_BITS;
566        }
567    }
568}
569
570static inline void
571hard_reg_set_iter_next (hard_reg_set_iterator *iter, unsigned *regno)
572{
573  iter->bits >>= 1;
574  *regno += 1;
575}
576
577#define EXECUTE_IF_SET_IN_HARD_REG_SET(SET, MIN, REGNUM, ITER)          \
578  for (hard_reg_set_iter_init (&(ITER), (SET), (MIN), &(REGNUM));       \
579       hard_reg_set_iter_set (&(ITER), &(REGNUM));                      \
580       hard_reg_set_iter_next (&(ITER), &(REGNUM)))
581
582
583/* Define some standard sets of registers.  */
584
585/* Indexed by hard register number, contains 1 for registers
586   that are being used for global register decls.
587   These must be exempt from ordinary flow analysis
588   and are also considered fixed.  */
589
590extern char global_regs[FIRST_PSEUDO_REGISTER];
591
592struct target_hard_regs {
593  /* The set of registers that actually exist on the current target.  */
594  HARD_REG_SET x_accessible_reg_set;
595
596  /* The set of registers that should be considered to be register
597     operands.  It is a subset of x_accessible_reg_set.  */
598  HARD_REG_SET x_operand_reg_set;
599
600  /* Indexed by hard register number, contains 1 for registers
601     that are fixed use (stack pointer, pc, frame pointer, etc.;.
602     These are the registers that cannot be used to allocate
603     a pseudo reg whose life does not cross calls.  */
604  char x_fixed_regs[FIRST_PSEUDO_REGISTER];
605
606  /* The same info as a HARD_REG_SET.  */
607  HARD_REG_SET x_fixed_reg_set;
608
609  /* Indexed by hard register number, contains 1 for registers
610     that are fixed use or are clobbered by function calls.
611     These are the registers that cannot be used to allocate
612     a pseudo reg whose life crosses calls.  */
613  char x_call_used_regs[FIRST_PSEUDO_REGISTER];
614
615  char x_call_really_used_regs[FIRST_PSEUDO_REGISTER];
616
617  /* The same info as a HARD_REG_SET.  */
618  HARD_REG_SET x_call_used_reg_set;
619
620  /* Contains registers that are fixed use -- i.e. in fixed_reg_set -- or
621     a function value return register or TARGET_STRUCT_VALUE_RTX or
622     STATIC_CHAIN_REGNUM.  These are the registers that cannot hold quantities
623     across calls even if we are willing to save and restore them.  */
624  HARD_REG_SET x_call_fixed_reg_set;
625
626  /* Contains 1 for registers that are set or clobbered by calls.  */
627  /* ??? Ideally, this would be just call_used_regs plus global_regs, but
628     for someone's bright idea to have call_used_regs strictly include
629     fixed_regs.  Which leaves us guessing as to the set of fixed_regs
630     that are actually preserved.  We know for sure that those associated
631     with the local stack frame are safe, but scant others.  */
632  HARD_REG_SET x_regs_invalidated_by_call;
633
634  /* Call used hard registers which can not be saved because there is no
635     insn for this.  */
636  HARD_REG_SET x_no_caller_save_reg_set;
637
638  /* Table of register numbers in the order in which to try to use them.  */
639  int x_reg_alloc_order[FIRST_PSEUDO_REGISTER];
640
641  /* The inverse of reg_alloc_order.  */
642  int x_inv_reg_alloc_order[FIRST_PSEUDO_REGISTER];
643
644  /* For each reg class, a HARD_REG_SET saying which registers are in it.  */
645  HARD_REG_SET x_reg_class_contents[N_REG_CLASSES];
646
647  /* For each reg class, a boolean saying whether the class contains only
648     fixed registers.  */
649  bool x_class_only_fixed_regs[N_REG_CLASSES];
650
651  /* For each reg class, number of regs it contains.  */
652  unsigned int x_reg_class_size[N_REG_CLASSES];
653
654  /* For each reg class, table listing all the classes contained in it.  */
655  enum reg_class x_reg_class_subclasses[N_REG_CLASSES][N_REG_CLASSES];
656
657  /* For each pair of reg classes,
658     a largest reg class contained in their union.  */
659  enum reg_class x_reg_class_subunion[N_REG_CLASSES][N_REG_CLASSES];
660
661  /* For each pair of reg classes,
662     the smallest reg class that contains their union.  */
663  enum reg_class x_reg_class_superunion[N_REG_CLASSES][N_REG_CLASSES];
664
665  /* Vector indexed by hardware reg giving its name.  */
666  const char *x_reg_names[FIRST_PSEUDO_REGISTER];
667};
668
669extern struct target_hard_regs default_target_hard_regs;
670#if SWITCHABLE_TARGET
671extern struct target_hard_regs *this_target_hard_regs;
672#else
673#define this_target_hard_regs (&default_target_hard_regs)
674#endif
675
676#define accessible_reg_set \
677  (this_target_hard_regs->x_accessible_reg_set)
678#define operand_reg_set \
679  (this_target_hard_regs->x_operand_reg_set)
680#define fixed_regs \
681  (this_target_hard_regs->x_fixed_regs)
682#define fixed_reg_set \
683  (this_target_hard_regs->x_fixed_reg_set)
684#define call_used_regs \
685  (this_target_hard_regs->x_call_used_regs)
686#define call_really_used_regs \
687  (this_target_hard_regs->x_call_really_used_regs)
688#define call_used_reg_set \
689  (this_target_hard_regs->x_call_used_reg_set)
690#define call_fixed_reg_set \
691  (this_target_hard_regs->x_call_fixed_reg_set)
692#define regs_invalidated_by_call \
693  (this_target_hard_regs->x_regs_invalidated_by_call)
694#define no_caller_save_reg_set \
695  (this_target_hard_regs->x_no_caller_save_reg_set)
696#define reg_alloc_order \
697  (this_target_hard_regs->x_reg_alloc_order)
698#define inv_reg_alloc_order \
699  (this_target_hard_regs->x_inv_reg_alloc_order)
700#define reg_class_contents \
701  (this_target_hard_regs->x_reg_class_contents)
702#define class_only_fixed_regs \
703  (this_target_hard_regs->x_class_only_fixed_regs)
704#define reg_class_size \
705  (this_target_hard_regs->x_reg_class_size)
706#define reg_class_subclasses \
707  (this_target_hard_regs->x_reg_class_subclasses)
708#define reg_class_subunion \
709  (this_target_hard_regs->x_reg_class_subunion)
710#define reg_class_superunion \
711  (this_target_hard_regs->x_reg_class_superunion)
712#define reg_names \
713  (this_target_hard_regs->x_reg_names)
714
715/* Vector indexed by reg class giving its name.  */
716
717extern const char * reg_class_names[];
718
719/* Given a hard REGN a FROM mode and a TO mode, return nonzero if
720   REGN cannot change modes between the specified modes.  */
721#define REG_CANNOT_CHANGE_MODE_P(REGN, FROM, TO)                          \
722         CANNOT_CHANGE_MODE_CLASS (FROM, TO, REGNO_REG_CLASS (REGN))
723
724#endif /* ! GCC_HARD_REG_SET_H */
Note: See TracBrowser for help on using the repository browser.