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