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