|
|
1.1 ! root 1: /* Sets (bit vectors) of hard registers, and operations on them. ! 2: Copyright (C) 1987, 1992 Free Software Foundation, Inc. ! 3: ! 4: This file is part of GNU CC ! 5: ! 6: GNU CC is free software; you can redistribute it and/or modify ! 7: it under the terms of the GNU General Public License as published by ! 8: the Free Software Foundation; either version 2, or (at your option) ! 9: any later version. ! 10: ! 11: GNU CC is distributed in the hope that it will be useful, ! 12: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 14: GNU General Public License for more details. ! 15: ! 16: You should have received a copy of the GNU General Public License ! 17: along with GNU CC; see the file COPYING. If not, write to ! 18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! 19: ! 20: ! 21: /* Define the type of a set of hard registers. */ ! 22: ! 23: /* HARD_REG_ELT_TYPE is a typedef of the unsigned integral type which ! 24: will be used for hard reg sets, either alone or in an array. ! 25: ! 26: If HARD_REG_SET is a macro, its definition is HARD_REG_ELT_TYPE, ! 27: and it has enough bits to represent all the target machine's hard ! 28: registers. Otherwise, it is a typedef for a suitably sized array ! 29: of HARD_REG_ELT_TYPEs. HARD_REG_SET_LONGS is defined as how many. ! 30: ! 31: Note that lots of code assumes that the first part of a regset is ! 32: the same format as a HARD_REG_SET. To help make sure this is true, ! 33: we only try the widest integer mode (HOST_WIDE_INT) instead of all the ! 34: smaller types. This approach loses only if there are a very few ! 35: registers and then only in the few cases where we have an array of ! 36: HARD_REG_SETs, so it needn't be as complex as it used to be. */ ! 37: ! 38: typedef unsigned HOST_WIDE_INT HARD_REG_ELT_TYPE; ! 39: ! 40: #if FIRST_PSEUDO_REGISTER <= HOST_BITS_PER_WIDE_INT ! 41: ! 42: #define HARD_REG_SET HARD_REG_ELT_TYPE ! 43: ! 44: #else ! 45: ! 46: #define HARD_REG_SET_LONGS \ ! 47: ((FIRST_PSEUDO_REGISTER + HOST_BITS_PER_WIDE_INT - 1) \ ! 48: / HOST_BITS_PER_WIDE_INT) ! 49: typedef HARD_REG_ELT_TYPE HARD_REG_SET[HARD_REG_SET_LONGS]; ! 50: ! 51: #endif ! 52: ! 53: /* HARD_CONST is used to cast a constant to the appropriate type ! 54: for use with a HARD_REG_SET. */ ! 55: ! 56: #define HARD_CONST(X) ((HARD_REG_ELT_TYPE) (X)) ! 57: ! 58: /* Define macros SET_HARD_REG_BIT, CLEAR_HARD_REG_BIT and TEST_HARD_REG_BIT ! 59: to set, clear or test one bit in a hard reg set of type HARD_REG_SET. ! 60: All three take two arguments: the set and the register number. ! 61: ! 62: In the case where sets are arrays of longs, the first argument ! 63: is actually a pointer to a long. ! 64: ! 65: Define two macros for initializing a set: ! 66: CLEAR_HARD_REG_SET and SET_HARD_REG_SET. ! 67: These take just one argument. ! 68: ! 69: Also define macros for copying hard reg sets: ! 70: COPY_HARD_REG_SET and COMPL_HARD_REG_SET. ! 71: These take two arguments TO and FROM; they read from FROM ! 72: and store into TO. COMPL_HARD_REG_SET complements each bit. ! 73: ! 74: Also define macros for combining hard reg sets: ! 75: IOR_HARD_REG_SET and AND_HARD_REG_SET. ! 76: These take two arguments TO and FROM; they read from FROM ! 77: and combine bitwise into TO. Define also two variants ! 78: IOR_COMPL_HARD_REG_SET and AND_COMPL_HARD_REG_SET ! 79: which use the complement of the set FROM. ! 80: ! 81: Also define GO_IF_HARD_REG_SUBSET (X, Y, TO): ! 82: if X is a subset of Y, go to TO. ! 83: */ ! 84: ! 85: #ifdef HARD_REG_SET ! 86: ! 87: #define SET_HARD_REG_BIT(SET, BIT) \ ! 88: ((SET) |= HARD_CONST (1) << (BIT)) ! 89: #define CLEAR_HARD_REG_BIT(SET, BIT) \ ! 90: ((SET) &= ~(HARD_CONST (1) << (BIT))) ! 91: #define TEST_HARD_REG_BIT(SET, BIT) \ ! 92: ((SET) & (HARD_CONST (1) << (BIT))) ! 93: ! 94: #define CLEAR_HARD_REG_SET(TO) ((TO) = HARD_CONST (0)) ! 95: #define SET_HARD_REG_SET(TO) ((TO) = ~ HARD_CONST (0)) ! 96: ! 97: #define COPY_HARD_REG_SET(TO, FROM) ((TO) = (FROM)) ! 98: #define COMPL_HARD_REG_SET(TO, FROM) ((TO) = ~(FROM)) ! 99: ! 100: #define IOR_HARD_REG_SET(TO, FROM) ((TO) |= (FROM)) ! 101: #define IOR_COMPL_HARD_REG_SET(TO, FROM) ((TO) |= ~ (FROM)) ! 102: #define AND_HARD_REG_SET(TO, FROM) ((TO) &= (FROM)) ! 103: #define AND_COMPL_HARD_REG_SET(TO, FROM) ((TO) &= ~ (FROM)) ! 104: ! 105: #define GO_IF_HARD_REG_SUBSET(X,Y,TO) if (HARD_CONST (0) == ((X) & ~(Y))) goto TO ! 106: ! 107: #define GO_IF_HARD_REG_EQUAL(X,Y,TO) if ((X) == (Y)) goto TO ! 108: ! 109: #else ! 110: ! 111: #define UHOST_BITS_PER_WIDE_INT ((unsigned) HOST_BITS_PER_WIDE_INT) ! 112: ! 113: #define SET_HARD_REG_BIT(SET, BIT) \ ! 114: ((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT] \ ! 115: |= HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT)) ! 116: ! 117: #define CLEAR_HARD_REG_BIT(SET, BIT) \ ! 118: ((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT] \ ! 119: &= ~(HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT))) ! 120: ! 121: #define TEST_HARD_REG_BIT(SET, BIT) \ ! 122: ((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT] \ ! 123: & (HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT))) ! 124: ! 125: #define CLEAR_HARD_REG_SET(TO) \ ! 126: do { register HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ ! 127: register int i; \ ! 128: for (i = 0; i < HARD_REG_SET_LONGS; i++) \ ! 129: *scan_tp_++ = 0; } while (0) ! 130: ! 131: #define SET_HARD_REG_SET(TO) \ ! 132: do { register HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ ! 133: register int i; \ ! 134: for (i = 0; i < HARD_REG_SET_LONGS; i++) \ ! 135: *scan_tp_++ = -1; } while (0) ! 136: ! 137: #define COPY_HARD_REG_SET(TO, FROM) \ ! 138: do { register HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ ! 139: register int i; \ ! 140: for (i = 0; i < HARD_REG_SET_LONGS; i++) \ ! 141: *scan_tp_++ = *scan_fp_++; } while (0) ! 142: ! 143: #define COMPL_HARD_REG_SET(TO, FROM) \ ! 144: do { register HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ ! 145: register int i; \ ! 146: for (i = 0; i < HARD_REG_SET_LONGS; i++) \ ! 147: *scan_tp_++ = ~ *scan_fp_++; } while (0) ! 148: ! 149: #define AND_HARD_REG_SET(TO, FROM) \ ! 150: do { register HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ ! 151: register int i; \ ! 152: for (i = 0; i < HARD_REG_SET_LONGS; i++) \ ! 153: *scan_tp_++ &= *scan_fp_++; } while (0) ! 154: ! 155: #define AND_COMPL_HARD_REG_SET(TO, FROM) \ ! 156: do { register HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ ! 157: register int i; \ ! 158: for (i = 0; i < HARD_REG_SET_LONGS; i++) \ ! 159: *scan_tp_++ &= ~ *scan_fp_++; } while (0) ! 160: ! 161: #define IOR_HARD_REG_SET(TO, FROM) \ ! 162: do { register HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ ! 163: register int i; \ ! 164: for (i = 0; i < HARD_REG_SET_LONGS; i++) \ ! 165: *scan_tp_++ |= *scan_fp_++; } while (0) ! 166: ! 167: #define IOR_COMPL_HARD_REG_SET(TO, FROM) \ ! 168: do { register HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ ! 169: register int i; \ ! 170: for (i = 0; i < HARD_REG_SET_LONGS; i++) \ ! 171: *scan_tp_++ |= ~ *scan_fp_++; } while (0) ! 172: ! 173: #define GO_IF_HARD_REG_SUBSET(X,Y,TO) \ ! 174: do { register HARD_REG_ELT_TYPE *scan_xp_ = (X), *scan_yp_ = (Y); \ ! 175: register int i; \ ! 176: for (i = 0; i < HARD_REG_SET_LONGS; i++) \ ! 177: if (0 != (*scan_xp_++ & ~ *scan_yp_++)) break; \ ! 178: if (i == HARD_REG_SET_LONGS) goto TO; } while (0) ! 179: ! 180: #define GO_IF_HARD_REG_EQUAL(X,Y,TO) \ ! 181: do { register HARD_REG_ELT_TYPE *scan_xp_ = (X), *scan_yp_ = (Y); \ ! 182: register int i; \ ! 183: for (i = 0; i < HARD_REG_SET_LONGS; i++) \ ! 184: if (*scan_xp_++ != ~ *scan_yp_++)) break; \ ! 185: if (i == HARD_REG_SET_LONGS) goto TO; } while (0) ! 186: ! 187: #endif ! 188: ! 189: /* Define some standard sets of registers. */ ! 190: ! 191: /* Indexed by hard register number, contains 1 for registers ! 192: that are fixed use (stack pointer, pc, frame pointer, etc.). ! 193: These are the registers that cannot be used to allocate ! 194: a pseudo reg whose life does not cross calls. */ ! 195: ! 196: extern char fixed_regs[FIRST_PSEUDO_REGISTER]; ! 197: ! 198: /* The same info as a HARD_REG_SET. */ ! 199: ! 200: extern HARD_REG_SET fixed_reg_set; ! 201: ! 202: /* Indexed by hard register number, contains 1 for registers ! 203: that are fixed use or are clobbered by function calls. ! 204: These are the registers that cannot be used to allocate ! 205: a pseudo reg whose life crosses calls. */ ! 206: ! 207: extern char call_used_regs[FIRST_PSEUDO_REGISTER]; ! 208: ! 209: /* The same info as a HARD_REG_SET. */ ! 210: ! 211: extern HARD_REG_SET call_used_reg_set; ! 212: ! 213: /* Indexed by hard register number, contains 1 for registers that are ! 214: fixed use -- i.e. in fixed_regs -- or a function value return register ! 215: or STRUCT_VALUE_REGNUM or STATIC_CHAIN_REGNUM. These are the ! 216: registers that cannot hold quantities across calls even if we are ! 217: willing to save and restore them. */ ! 218: ! 219: extern char call_fixed_regs[FIRST_PSEUDO_REGISTER]; ! 220: ! 221: /* The same info as a HARD_REG_SET. */ ! 222: ! 223: extern HARD_REG_SET call_fixed_reg_set; ! 224: ! 225: /* Indexed by hard register number, contains 1 for registers ! 226: that are being used for global register decls. ! 227: These must be exempt from ordinary flow analysis ! 228: and are also considered fixed. */ ! 229: ! 230: extern char global_regs[FIRST_PSEUDO_REGISTER]; ! 231: ! 232: /* Table of register numbers in the order in which to try to use them. */ ! 233: ! 234: #ifdef REG_ALLOC_ORDER /* Avoid undef symbol in certain broken linkers. */ ! 235: extern int reg_alloc_order[FIRST_PSEUDO_REGISTER]; ! 236: #endif ! 237: ! 238: /* For each reg class, a HARD_REG_SET saying which registers are in it. */ ! 239: ! 240: extern HARD_REG_SET reg_class_contents[]; ! 241: ! 242: /* For each reg class, number of regs it contains. */ ! 243: ! 244: extern int reg_class_size[N_REG_CLASSES]; ! 245: ! 246: /* For each reg class, table listing all the containing classes. */ ! 247: ! 248: extern enum reg_class reg_class_superclasses[N_REG_CLASSES][N_REG_CLASSES]; ! 249: ! 250: /* For each reg class, table listing all the classes contained in it. */ ! 251: ! 252: extern enum reg_class reg_class_subclasses[N_REG_CLASSES][N_REG_CLASSES]; ! 253: ! 254: /* For each pair of reg classes, ! 255: a largest reg class contained in their union. */ ! 256: ! 257: extern enum reg_class reg_class_subunion[N_REG_CLASSES][N_REG_CLASSES]; ! 258: ! 259: /* For each pair of reg classes, ! 260: the smallest reg class that contains their union. */ ! 261: ! 262: extern enum reg_class reg_class_superunion[N_REG_CLASSES][N_REG_CLASSES]; ! 263: ! 264: /* Number of non-fixed registers. */ ! 265: ! 266: extern int n_non_fixed_regs; ! 267: ! 268: /* Vector indexed by hardware reg giving its name. */ ! 269: ! 270: extern char *reg_names[FIRST_PSEUDO_REGISTER];
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.