OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [hard-reg-set.h] - Blame information for rev 867

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 684 jeremybenn
/* Sets (bit vectors) of hard registers, and operations on them.
2
   Copyright (C) 1987, 1992, 1994, 2000, 2003, 2004, 2005, 2007, 2008, 2009,
3
   2010, 2012 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_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.  */
60
struct hard_reg_set_container
61
{
62
  HARD_REG_SET set;
63
};
64
 
65
/* HARD_CONST is used to cast a constant to the appropriate type
66
   for use with a HARD_REG_SET.  */
67
 
68
#define HARD_CONST(X) ((HARD_REG_ELT_TYPE) (X))
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
 
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.  */
99
 
100
#define UHOST_BITS_PER_WIDE_INT ((unsigned) HOST_BITS_PER_WIDEST_FAST_INT)
101
 
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)  \
109
 (!!((SET) & (HARD_CONST (1) << (BIT))))
110
 
111
#define CLEAR_HARD_REG_SET(TO) ((TO) = HARD_CONST (0))
112
#define SET_HARD_REG_SET(TO) ((TO) = ~ HARD_CONST (0))
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
 
122
static inline bool
123
hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)
124
{
125
  return (x & ~y) == HARD_CONST (0);
126
}
127
 
128
static inline bool
129
hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)
130
{
131
  return x == y;
132
}
133
 
134
static inline bool
135
hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)
136
{
137
  return (x & y) != HARD_CONST (0);
138
}
139
 
140
static inline bool
141
hard_reg_set_empty_p (const HARD_REG_SET x)
142
{
143
  return x == HARD_CONST (0);
144
}
145
 
146
#else
147
 
148
#define SET_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
#define CLEAR_HARD_REG_BIT(SET, BIT)            \
153
  ((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT]       \
154
   &= ~(HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT)))
155
 
156
#define TEST_HARD_REG_BIT(SET, BIT)             \
157
  (!!((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT]    \
158
      & (HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT))))
159
 
160
#if FIRST_PSEUDO_REGISTER <= 2*HOST_BITS_PER_WIDEST_FAST_INT
161
#define CLEAR_HARD_REG_SET(TO)  \
162
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);                        \
163
     scan_tp_[0] = 0;                                             \
164
     scan_tp_[1] = 0; } while (0)
165
 
166
#define SET_HARD_REG_SET(TO)  \
167
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);                        \
168
     scan_tp_[0] = -1;                                           \
169
     scan_tp_[1] = -1; } while (0)
170
 
171
#define COPY_HARD_REG_SET(TO, FROM)  \
172
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
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)  \
177
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
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)  \
182
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
183
     scan_tp_[0] &= scan_fp_[0];                          \
184
     scan_tp_[1] &= scan_fp_[1]; } while (0)
185
 
186
#define AND_COMPL_HARD_REG_SET(TO, FROM)  \
187
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
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)  \
192
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
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)  \
197
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
198
     scan_tp_[0] |= ~ scan_fp_[0];                                \
199
     scan_tp_[1] |= ~ scan_fp_[1]; } while (0)
200
 
201
static inline bool
202
hard_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
 
207
static inline bool
208
hard_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
 
213
static inline bool
214
hard_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
 
219
static inline bool
220
hard_reg_set_empty_p (const HARD_REG_SET x)
221
{
222
  return x[0] == 0 && x[1] == 0;
223
}
224
 
225
#else
226
#if FIRST_PSEUDO_REGISTER <= 3*HOST_BITS_PER_WIDEST_FAST_INT
227
#define CLEAR_HARD_REG_SET(TO)  \
228
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);                        \
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)  \
234
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);                        \
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)  \
240
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
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)  \
246
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
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)  \
252
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
253
     scan_tp_[0] &= scan_fp_[0];                          \
254
     scan_tp_[1] &= scan_fp_[1];                                \
255
     scan_tp_[2] &= scan_fp_[2]; } while (0)
256
 
257
#define AND_COMPL_HARD_REG_SET(TO, FROM)  \
258
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
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)  \
264
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
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)  \
270
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
271
     scan_tp_[0] |= ~ scan_fp_[0];                                \
272
     scan_tp_[1] |= ~ scan_fp_[1];                              \
273
     scan_tp_[2] |= ~ scan_fp_[2]; } while (0)
274
 
275
static inline bool
276
hard_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
 
283
static inline bool
284
hard_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
 
289
static inline bool
290
hard_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
 
297
static inline bool
298
hard_reg_set_empty_p (const HARD_REG_SET x)
299
{
300
  return x[0] == 0 && x[1] == 0 && x[2] == 0;
301
}
302
 
303
#else
304
#if FIRST_PSEUDO_REGISTER <= 4*HOST_BITS_PER_WIDEST_FAST_INT
305
#define CLEAR_HARD_REG_SET(TO)  \
306
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);                        \
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)  \
313
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);                        \
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)  \
320
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
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)  \
327
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
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)  \
334
do { 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];                                \
338
     scan_tp_[3] &= scan_fp_[3]; } while (0)
339
 
340
#define AND_COMPL_HARD_REG_SET(TO, FROM)  \
341
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
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)  \
348
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
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)  \
355
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
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
 
361
static inline bool
362
hard_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
 
370
static inline bool
371
hard_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
 
376
static inline bool
377
hard_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
 
385
static inline bool
386
hard_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
}
390
 
391
#else /* FIRST_PSEUDO_REGISTER > 4*HOST_BITS_PER_WIDEST_FAST_INT */
392
 
393
#define CLEAR_HARD_REG_SET(TO)  \
394
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);                        \
395
     int i;                                                     \
396
     for (i = 0; i < HARD_REG_SET_LONGS; i++)                    \
397
       *scan_tp_++ = 0; } while (0)
398
 
399
#define SET_HARD_REG_SET(TO)  \
400
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);                        \
401
     int i;                                                     \
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)  \
406
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
407
     int i;                                                     \
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)  \
412
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
413
     int i;                                                     \
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)  \
418
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
419
     int i;                                                     \
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)  \
424
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
425
     int i;                                                     \
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)  \
430
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
431
     int i;                                                     \
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)  \
436
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
437
     int i;                                                     \
438
     for (i = 0; i < HARD_REG_SET_LONGS; i++)                    \
439
       *scan_tp_++ |= ~ *scan_fp_++; } while (0)
440
 
441
static inline bool
442
hard_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
 
452
static inline bool
453
hard_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
 
463
static inline bool
464
hard_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
 
474
static inline bool
475
hard_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
}
484
 
485
#endif
486
#endif
487
#endif
488
#endif
489
 
490
/* Iterator for hard register sets.  */
491
 
492
typedef 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
 
511
/* The implementation of the iterator functions is fully analogous to
512
   the bitmap iterators.  */
513
static inline void
514
hard_reg_set_iter_init (hard_reg_set_iterator *iter, HARD_REG_SET set,
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
 
536
static inline bool
537
hard_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
        }
555
 
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
 
571
static inline void
572
hard_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
 
584
/* Define some standard sets of registers.  */
585
 
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
 
591
extern char global_regs[FIRST_PSEUDO_REGISTER];
592
 
593
struct target_hard_regs {
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
 
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];
606
 
607
  /* The same info as a HARD_REG_SET.  */
608
  HARD_REG_SET x_fixed_reg_set;
609
 
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];
615
 
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;
620
 
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;
626
 
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;
634
 
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
 
639
  /* Table of register numbers in the order in which to try to use them.  */
640
  int x_reg_alloc_order[FIRST_PSEUDO_REGISTER];
641
 
642
  /* The inverse of reg_alloc_order.  */
643
  int x_inv_reg_alloc_order[FIRST_PSEUDO_REGISTER];
644
 
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];
647
 
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];
651
 
652
  /* For each reg class, number of regs it contains.  */
653
  unsigned int x_reg_class_size[N_REG_CLASSES];
654
 
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];
657
 
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];
661
 
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];
665
 
666
  /* Vector indexed by hardware reg giving its name.  */
667
  const char *x_reg_names[FIRST_PSEUDO_REGISTER];
668
};
669
 
670
extern struct target_hard_regs default_target_hard_regs;
671
#if SWITCHABLE_TARGET
672
extern struct target_hard_regs *this_target_hard_regs;
673
#else
674
#define this_target_hard_regs (&default_target_hard_regs)
675
#endif
676
 
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)
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)
695
#define no_caller_save_reg_set \
696
  (this_target_hard_regs->x_no_caller_save_reg_set)
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)
715
 
716
/* Vector indexed by reg class giving its name.  */
717
 
718
extern const char * reg_class_names[];
719
 
720
/* Given a hard REGN a FROM mode and a TO mode, return nonzero if
721
   REGN cannot change modes between the specified modes.  */
722
#define REG_CANNOT_CHANGE_MODE_P(REGN, FROM, TO)                          \
723
         CANNOT_CHANGE_MODE_CLASS (FROM, TO, REGNO_REG_CLASS (REGN))
724
 
725
#endif /* ! GCC_HARD_REG_SET_H */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.