118334Speter/* Sets (bit vectors) of hard registers, and operations on them. 2169689Skan Copyright (C) 1987, 1992, 1994, 2000, 2003, 2004, 2005 3169689Skan Free Software Foundation, Inc. 418334Speter 590075SobrienThis file is part of GCC 618334Speter 790075SobrienGCC is free software; you can redistribute it and/or modify it under 890075Sobrienthe terms of the GNU General Public License as published by the Free 990075SobrienSoftware Foundation; either version 2, or (at your option) any later 1090075Sobrienversion. 1118334Speter 1290075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY 1390075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or 1490075SobrienFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1590075Sobrienfor more details. 1618334Speter 1718334SpeterYou should have received a copy of the GNU General Public License 1890075Sobrienalong with GCC; see the file COPYING. If not, write to the Free 19169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 20169689Skan02110-1301, USA. */ 2118334Speter 2290075Sobrien#ifndef GCC_HARD_REG_SET_H 2390075Sobrien#define GCC_HARD_REG_SET_H 2418334Speter 2518334Speter/* Define the type of a set of hard registers. */ 2618334Speter 2718334Speter/* HARD_REG_ELT_TYPE is a typedef of the unsigned integral type which 2818334Speter will be used for hard reg sets, either alone or in an array. 2918334Speter 3018334Speter If HARD_REG_SET is a macro, its definition is HARD_REG_ELT_TYPE, 3118334Speter and it has enough bits to represent all the target machine's hard 3218334Speter registers. Otherwise, it is a typedef for a suitably sized array 3318334Speter of HARD_REG_ELT_TYPEs. HARD_REG_SET_LONGS is defined as how many. 3418334Speter 3518334Speter Note that lots of code assumes that the first part of a regset is 3618334Speter the same format as a HARD_REG_SET. To help make sure this is true, 37169689Skan we only try the widest fast integer mode (HOST_WIDEST_FAST_INT) 38169689Skan instead of all the smaller types. This approach loses only if 39169689Skan there are very few registers and then only in the few cases where 40169689Skan we have an array of HARD_REG_SETs, so it needn't be as complex as 41169689Skan it used to be. */ 4218334Speter 43169689Skantypedef unsigned HOST_WIDEST_FAST_INT HARD_REG_ELT_TYPE; 4418334Speter 45169689Skan#if FIRST_PSEUDO_REGISTER <= HOST_BITS_PER_WIDEST_FAST_INT 4618334Speter 4718334Speter#define HARD_REG_SET HARD_REG_ELT_TYPE 4818334Speter 4918334Speter#else 5018334Speter 5118334Speter#define HARD_REG_SET_LONGS \ 52169689Skan ((FIRST_PSEUDO_REGISTER + HOST_BITS_PER_WIDEST_FAST_INT - 1) \ 53169689Skan / HOST_BITS_PER_WIDEST_FAST_INT) 5418334Spetertypedef HARD_REG_ELT_TYPE HARD_REG_SET[HARD_REG_SET_LONGS]; 5518334Speter 5618334Speter#endif 5718334Speter 5818334Speter/* HARD_CONST is used to cast a constant to the appropriate type 5918334Speter for use with a HARD_REG_SET. */ 6018334Speter 6118334Speter#define HARD_CONST(X) ((HARD_REG_ELT_TYPE) (X)) 6218334Speter 6318334Speter/* Define macros SET_HARD_REG_BIT, CLEAR_HARD_REG_BIT and TEST_HARD_REG_BIT 6418334Speter to set, clear or test one bit in a hard reg set of type HARD_REG_SET. 6518334Speter All three take two arguments: the set and the register number. 6618334Speter 6718334Speter In the case where sets are arrays of longs, the first argument 6818334Speter is actually a pointer to a long. 6918334Speter 7018334Speter Define two macros for initializing a set: 7118334Speter CLEAR_HARD_REG_SET and SET_HARD_REG_SET. 7218334Speter These take just one argument. 7318334Speter 7418334Speter Also define macros for copying hard reg sets: 7518334Speter COPY_HARD_REG_SET and COMPL_HARD_REG_SET. 7618334Speter These take two arguments TO and FROM; they read from FROM 7718334Speter and store into TO. COMPL_HARD_REG_SET complements each bit. 7818334Speter 7918334Speter Also define macros for combining hard reg sets: 8018334Speter IOR_HARD_REG_SET and AND_HARD_REG_SET. 8118334Speter These take two arguments TO and FROM; they read from FROM 8218334Speter and combine bitwise into TO. Define also two variants 8318334Speter IOR_COMPL_HARD_REG_SET and AND_COMPL_HARD_REG_SET 8418334Speter which use the complement of the set FROM. 8518334Speter 8618334Speter Also define GO_IF_HARD_REG_SUBSET (X, Y, TO): 8718334Speter if X is a subset of Y, go to TO. 8818334Speter*/ 8918334Speter 9018334Speter#ifdef HARD_REG_SET 9118334Speter 9218334Speter#define SET_HARD_REG_BIT(SET, BIT) \ 9318334Speter ((SET) |= HARD_CONST (1) << (BIT)) 9418334Speter#define CLEAR_HARD_REG_BIT(SET, BIT) \ 9518334Speter ((SET) &= ~(HARD_CONST (1) << (BIT))) 9618334Speter#define TEST_HARD_REG_BIT(SET, BIT) \ 97117395Skan (!!((SET) & (HARD_CONST (1) << (BIT)))) 9818334Speter 9918334Speter#define CLEAR_HARD_REG_SET(TO) ((TO) = HARD_CONST (0)) 10018334Speter#define SET_HARD_REG_SET(TO) ((TO) = ~ HARD_CONST (0)) 10118334Speter 10218334Speter#define COPY_HARD_REG_SET(TO, FROM) ((TO) = (FROM)) 10318334Speter#define COMPL_HARD_REG_SET(TO, FROM) ((TO) = ~(FROM)) 10418334Speter 10518334Speter#define IOR_HARD_REG_SET(TO, FROM) ((TO) |= (FROM)) 10618334Speter#define IOR_COMPL_HARD_REG_SET(TO, FROM) ((TO) |= ~ (FROM)) 10718334Speter#define AND_HARD_REG_SET(TO, FROM) ((TO) &= (FROM)) 10818334Speter#define AND_COMPL_HARD_REG_SET(TO, FROM) ((TO) &= ~ (FROM)) 10918334Speter 11018334Speter#define GO_IF_HARD_REG_SUBSET(X,Y,TO) if (HARD_CONST (0) == ((X) & ~(Y))) goto TO 11118334Speter 11218334Speter#define GO_IF_HARD_REG_EQUAL(X,Y,TO) if ((X) == (Y)) goto TO 11318334Speter 11418334Speter#else 11518334Speter 116169689Skan#define UHOST_BITS_PER_WIDE_INT ((unsigned) HOST_BITS_PER_WIDEST_FAST_INT) 11718334Speter 11818334Speter#define SET_HARD_REG_BIT(SET, BIT) \ 11918334Speter ((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT] \ 12018334Speter |= HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT)) 12118334Speter 12218334Speter#define CLEAR_HARD_REG_BIT(SET, BIT) \ 12318334Speter ((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT] \ 12418334Speter &= ~(HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT))) 12518334Speter 12618334Speter#define TEST_HARD_REG_BIT(SET, BIT) \ 127117395Skan (!!((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT] \ 128117395Skan & (HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT)))) 12918334Speter 130169689Skan#if FIRST_PSEUDO_REGISTER <= 2*HOST_BITS_PER_WIDEST_FAST_INT 13118334Speter#define CLEAR_HARD_REG_SET(TO) \ 13290075Sobriendo { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ 13350397Sobrien scan_tp_[0] = 0; \ 13450397Sobrien scan_tp_[1] = 0; } while (0) 13550397Sobrien 13650397Sobrien#define SET_HARD_REG_SET(TO) \ 13790075Sobriendo { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ 13850397Sobrien scan_tp_[0] = -1; \ 13950397Sobrien scan_tp_[1] = -1; } while (0) 14050397Sobrien 14150397Sobrien#define COPY_HARD_REG_SET(TO, FROM) \ 14290075Sobriendo { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ 14350397Sobrien scan_tp_[0] = scan_fp_[0]; \ 14450397Sobrien scan_tp_[1] = scan_fp_[1]; } while (0) 14550397Sobrien 14650397Sobrien#define COMPL_HARD_REG_SET(TO, FROM) \ 14790075Sobriendo { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ 14850397Sobrien scan_tp_[0] = ~ scan_fp_[0]; \ 14950397Sobrien scan_tp_[1] = ~ scan_fp_[1]; } while (0) 15050397Sobrien 15150397Sobrien#define AND_HARD_REG_SET(TO, FROM) \ 15290075Sobriendo { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ 15390075Sobrien scan_tp_[0] &= scan_fp_[0]; \ 15450397Sobrien scan_tp_[1] &= scan_fp_[1]; } while (0) 15550397Sobrien 15650397Sobrien#define AND_COMPL_HARD_REG_SET(TO, FROM) \ 15790075Sobriendo { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ 15850397Sobrien scan_tp_[0] &= ~ scan_fp_[0]; \ 15950397Sobrien scan_tp_[1] &= ~ scan_fp_[1]; } while (0) 16050397Sobrien 16150397Sobrien#define IOR_HARD_REG_SET(TO, FROM) \ 16290075Sobriendo { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ 16350397Sobrien scan_tp_[0] |= scan_fp_[0]; \ 16450397Sobrien scan_tp_[1] |= scan_fp_[1]; } while (0) 16550397Sobrien 16650397Sobrien#define IOR_COMPL_HARD_REG_SET(TO, FROM) \ 16790075Sobriendo { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ 16850397Sobrien scan_tp_[0] |= ~ scan_fp_[0]; \ 16950397Sobrien scan_tp_[1] |= ~ scan_fp_[1]; } while (0) 17050397Sobrien 17150397Sobrien#define GO_IF_HARD_REG_SUBSET(X,Y,TO) \ 17290075Sobriendo { HARD_REG_ELT_TYPE *scan_xp_ = (X), *scan_yp_ = (Y); \ 17350397Sobrien if ((0 == (scan_xp_[0] & ~ scan_yp_[0])) \ 17450397Sobrien && (0 == (scan_xp_[1] & ~ scan_yp_[1]))) \ 17550397Sobrien goto TO; } while (0) 17650397Sobrien 17750397Sobrien#define GO_IF_HARD_REG_EQUAL(X,Y,TO) \ 17890075Sobriendo { HARD_REG_ELT_TYPE *scan_xp_ = (X), *scan_yp_ = (Y); \ 17950397Sobrien if ((scan_xp_[0] == scan_yp_[0]) \ 18050397Sobrien && (scan_xp_[1] == scan_yp_[1])) \ 18150397Sobrien goto TO; } while (0) 18250397Sobrien 18350397Sobrien#else 184169689Skan#if FIRST_PSEUDO_REGISTER <= 3*HOST_BITS_PER_WIDEST_FAST_INT 18550397Sobrien#define CLEAR_HARD_REG_SET(TO) \ 18690075Sobriendo { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ 18750397Sobrien scan_tp_[0] = 0; \ 18850397Sobrien scan_tp_[1] = 0; \ 18950397Sobrien scan_tp_[2] = 0; } while (0) 19050397Sobrien 19150397Sobrien#define SET_HARD_REG_SET(TO) \ 19290075Sobriendo { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ 19350397Sobrien scan_tp_[0] = -1; \ 19450397Sobrien scan_tp_[1] = -1; \ 19550397Sobrien scan_tp_[2] = -1; } while (0) 19650397Sobrien 19750397Sobrien#define COPY_HARD_REG_SET(TO, FROM) \ 19890075Sobriendo { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ 19950397Sobrien scan_tp_[0] = scan_fp_[0]; \ 20050397Sobrien scan_tp_[1] = scan_fp_[1]; \ 20150397Sobrien scan_tp_[2] = scan_fp_[2]; } while (0) 20250397Sobrien 20350397Sobrien#define COMPL_HARD_REG_SET(TO, FROM) \ 20490075Sobriendo { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ 20550397Sobrien scan_tp_[0] = ~ scan_fp_[0]; \ 20650397Sobrien scan_tp_[1] = ~ scan_fp_[1]; \ 20750397Sobrien scan_tp_[2] = ~ scan_fp_[2]; } while (0) 20850397Sobrien 20950397Sobrien#define AND_HARD_REG_SET(TO, FROM) \ 21090075Sobriendo { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ 21190075Sobrien scan_tp_[0] &= scan_fp_[0]; \ 21290075Sobrien scan_tp_[1] &= scan_fp_[1]; \ 21350397Sobrien scan_tp_[2] &= scan_fp_[2]; } while (0) 21450397Sobrien 21550397Sobrien#define AND_COMPL_HARD_REG_SET(TO, FROM) \ 21690075Sobriendo { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ 21750397Sobrien scan_tp_[0] &= ~ scan_fp_[0]; \ 21850397Sobrien scan_tp_[1] &= ~ scan_fp_[1]; \ 21950397Sobrien scan_tp_[2] &= ~ scan_fp_[2]; } while (0) 22050397Sobrien 22150397Sobrien#define IOR_HARD_REG_SET(TO, FROM) \ 22290075Sobriendo { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ 22350397Sobrien scan_tp_[0] |= scan_fp_[0]; \ 22450397Sobrien scan_tp_[1] |= scan_fp_[1]; \ 22550397Sobrien scan_tp_[2] |= scan_fp_[2]; } while (0) 22650397Sobrien 22750397Sobrien#define IOR_COMPL_HARD_REG_SET(TO, FROM) \ 22890075Sobriendo { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ 22950397Sobrien scan_tp_[0] |= ~ scan_fp_[0]; \ 23050397Sobrien scan_tp_[1] |= ~ scan_fp_[1]; \ 23150397Sobrien scan_tp_[2] |= ~ scan_fp_[2]; } while (0) 23250397Sobrien 23350397Sobrien#define GO_IF_HARD_REG_SUBSET(X,Y,TO) \ 23490075Sobriendo { HARD_REG_ELT_TYPE *scan_xp_ = (X), *scan_yp_ = (Y); \ 23550397Sobrien if ((0 == (scan_xp_[0] & ~ scan_yp_[0])) \ 23650397Sobrien && (0 == (scan_xp_[1] & ~ scan_yp_[1])) \ 23750397Sobrien && (0 == (scan_xp_[2] & ~ scan_yp_[2]))) \ 23850397Sobrien goto TO; } while (0) 23950397Sobrien 24050397Sobrien#define GO_IF_HARD_REG_EQUAL(X,Y,TO) \ 24190075Sobriendo { HARD_REG_ELT_TYPE *scan_xp_ = (X), *scan_yp_ = (Y); \ 24250397Sobrien if ((scan_xp_[0] == scan_yp_[0]) \ 24350397Sobrien && (scan_xp_[1] == scan_yp_[1]) \ 24450397Sobrien && (scan_xp_[2] == scan_yp_[2])) \ 24550397Sobrien goto TO; } while (0) 24650397Sobrien 24750397Sobrien#else 248169689Skan#if FIRST_PSEUDO_REGISTER <= 4*HOST_BITS_PER_WIDEST_FAST_INT 24950397Sobrien#define CLEAR_HARD_REG_SET(TO) \ 25090075Sobriendo { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ 25150397Sobrien scan_tp_[0] = 0; \ 25250397Sobrien scan_tp_[1] = 0; \ 25350397Sobrien scan_tp_[2] = 0; \ 25450397Sobrien scan_tp_[3] = 0; } while (0) 25550397Sobrien 25650397Sobrien#define SET_HARD_REG_SET(TO) \ 25790075Sobriendo { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ 25850397Sobrien scan_tp_[0] = -1; \ 25950397Sobrien scan_tp_[1] = -1; \ 26050397Sobrien scan_tp_[2] = -1; \ 26150397Sobrien scan_tp_[3] = -1; } while (0) 26250397Sobrien 26350397Sobrien#define COPY_HARD_REG_SET(TO, FROM) \ 26490075Sobriendo { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ 26550397Sobrien scan_tp_[0] = scan_fp_[0]; \ 26650397Sobrien scan_tp_[1] = scan_fp_[1]; \ 26750397Sobrien scan_tp_[2] = scan_fp_[2]; \ 26850397Sobrien scan_tp_[3] = scan_fp_[3]; } while (0) 26950397Sobrien 27050397Sobrien#define COMPL_HARD_REG_SET(TO, FROM) \ 27190075Sobriendo { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ 27250397Sobrien scan_tp_[0] = ~ scan_fp_[0]; \ 27350397Sobrien scan_tp_[1] = ~ scan_fp_[1]; \ 27450397Sobrien scan_tp_[2] = ~ scan_fp_[2]; \ 27550397Sobrien scan_tp_[3] = ~ scan_fp_[3]; } while (0) 27650397Sobrien 27750397Sobrien#define AND_HARD_REG_SET(TO, FROM) \ 27890075Sobriendo { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ 27990075Sobrien scan_tp_[0] &= scan_fp_[0]; \ 28090075Sobrien scan_tp_[1] &= scan_fp_[1]; \ 28190075Sobrien scan_tp_[2] &= scan_fp_[2]; \ 28250397Sobrien scan_tp_[3] &= scan_fp_[3]; } while (0) 28350397Sobrien 28450397Sobrien#define AND_COMPL_HARD_REG_SET(TO, FROM) \ 28590075Sobriendo { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ 28650397Sobrien scan_tp_[0] &= ~ scan_fp_[0]; \ 28750397Sobrien scan_tp_[1] &= ~ scan_fp_[1]; \ 28850397Sobrien scan_tp_[2] &= ~ scan_fp_[2]; \ 28950397Sobrien scan_tp_[3] &= ~ scan_fp_[3]; } while (0) 29050397Sobrien 29150397Sobrien#define IOR_HARD_REG_SET(TO, FROM) \ 29290075Sobriendo { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ 29350397Sobrien scan_tp_[0] |= scan_fp_[0]; \ 29450397Sobrien scan_tp_[1] |= scan_fp_[1]; \ 29550397Sobrien scan_tp_[2] |= scan_fp_[2]; \ 29650397Sobrien scan_tp_[3] |= scan_fp_[3]; } while (0) 29750397Sobrien 29850397Sobrien#define IOR_COMPL_HARD_REG_SET(TO, FROM) \ 29990075Sobriendo { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ 30050397Sobrien scan_tp_[0] |= ~ scan_fp_[0]; \ 30150397Sobrien scan_tp_[1] |= ~ scan_fp_[1]; \ 30250397Sobrien scan_tp_[2] |= ~ scan_fp_[2]; \ 30350397Sobrien scan_tp_[3] |= ~ scan_fp_[3]; } while (0) 30450397Sobrien 30550397Sobrien#define GO_IF_HARD_REG_SUBSET(X,Y,TO) \ 30690075Sobriendo { HARD_REG_ELT_TYPE *scan_xp_ = (X), *scan_yp_ = (Y); \ 30750397Sobrien if ((0 == (scan_xp_[0] & ~ scan_yp_[0])) \ 30850397Sobrien && (0 == (scan_xp_[1] & ~ scan_yp_[1])) \ 30950397Sobrien && (0 == (scan_xp_[2] & ~ scan_yp_[2])) \ 31050397Sobrien && (0 == (scan_xp_[3] & ~ scan_yp_[3]))) \ 31150397Sobrien goto TO; } while (0) 31250397Sobrien 31350397Sobrien#define GO_IF_HARD_REG_EQUAL(X,Y,TO) \ 31490075Sobriendo { HARD_REG_ELT_TYPE *scan_xp_ = (X), *scan_yp_ = (Y); \ 31550397Sobrien if ((scan_xp_[0] == scan_yp_[0]) \ 31650397Sobrien && (scan_xp_[1] == scan_yp_[1]) \ 31750397Sobrien && (scan_xp_[2] == scan_yp_[2]) \ 31850397Sobrien && (scan_xp_[3] == scan_yp_[3])) \ 31950397Sobrien goto TO; } while (0) 32050397Sobrien 321169689Skan#else /* FIRST_PSEUDO_REGISTER > 3*HOST_BITS_PER_WIDEST_FAST_INT */ 32250397Sobrien 32350397Sobrien#define CLEAR_HARD_REG_SET(TO) \ 32490075Sobriendo { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ 32590075Sobrien int i; \ 32618334Speter for (i = 0; i < HARD_REG_SET_LONGS; i++) \ 32718334Speter *scan_tp_++ = 0; } while (0) 32818334Speter 32918334Speter#define SET_HARD_REG_SET(TO) \ 33090075Sobriendo { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ 33190075Sobrien int i; \ 33218334Speter for (i = 0; i < HARD_REG_SET_LONGS; i++) \ 33318334Speter *scan_tp_++ = -1; } while (0) 33418334Speter 33518334Speter#define COPY_HARD_REG_SET(TO, FROM) \ 33690075Sobriendo { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ 33790075Sobrien int i; \ 33818334Speter for (i = 0; i < HARD_REG_SET_LONGS; i++) \ 33918334Speter *scan_tp_++ = *scan_fp_++; } while (0) 34018334Speter 34118334Speter#define COMPL_HARD_REG_SET(TO, FROM) \ 34290075Sobriendo { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ 34390075Sobrien int i; \ 34418334Speter for (i = 0; i < HARD_REG_SET_LONGS; i++) \ 34518334Speter *scan_tp_++ = ~ *scan_fp_++; } while (0) 34618334Speter 34718334Speter#define AND_HARD_REG_SET(TO, FROM) \ 34890075Sobriendo { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ 34990075Sobrien int i; \ 35018334Speter for (i = 0; i < HARD_REG_SET_LONGS; i++) \ 35118334Speter *scan_tp_++ &= *scan_fp_++; } while (0) 35218334Speter 35318334Speter#define AND_COMPL_HARD_REG_SET(TO, FROM) \ 35490075Sobriendo { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ 35590075Sobrien int i; \ 35618334Speter for (i = 0; i < HARD_REG_SET_LONGS; i++) \ 35718334Speter *scan_tp_++ &= ~ *scan_fp_++; } while (0) 35818334Speter 35918334Speter#define IOR_HARD_REG_SET(TO, FROM) \ 36090075Sobriendo { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ 36190075Sobrien int i; \ 36218334Speter for (i = 0; i < HARD_REG_SET_LONGS; i++) \ 36318334Speter *scan_tp_++ |= *scan_fp_++; } while (0) 36418334Speter 36518334Speter#define IOR_COMPL_HARD_REG_SET(TO, FROM) \ 36690075Sobriendo { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ 36790075Sobrien int i; \ 36818334Speter for (i = 0; i < HARD_REG_SET_LONGS; i++) \ 36918334Speter *scan_tp_++ |= ~ *scan_fp_++; } while (0) 37018334Speter 37118334Speter#define GO_IF_HARD_REG_SUBSET(X,Y,TO) \ 37290075Sobriendo { HARD_REG_ELT_TYPE *scan_xp_ = (X), *scan_yp_ = (Y); \ 37390075Sobrien int i; \ 37418334Speter for (i = 0; i < HARD_REG_SET_LONGS; i++) \ 37518334Speter if (0 != (*scan_xp_++ & ~ *scan_yp_++)) break; \ 37618334Speter if (i == HARD_REG_SET_LONGS) goto TO; } while (0) 37718334Speter 37818334Speter#define GO_IF_HARD_REG_EQUAL(X,Y,TO) \ 37990075Sobriendo { HARD_REG_ELT_TYPE *scan_xp_ = (X), *scan_yp_ = (Y); \ 38090075Sobrien int i; \ 38118334Speter for (i = 0; i < HARD_REG_SET_LONGS; i++) \ 38218334Speter if (*scan_xp_++ != *scan_yp_++) break; \ 38318334Speter if (i == HARD_REG_SET_LONGS) goto TO; } while (0) 38418334Speter 38518334Speter#endif 38650397Sobrien#endif 38750397Sobrien#endif 38850397Sobrien#endif 38918334Speter 39018334Speter/* Define some standard sets of registers. */ 39118334Speter 39218334Speter/* Indexed by hard register number, contains 1 for registers 39318334Speter that are fixed use (stack pointer, pc, frame pointer, etc.). 39418334Speter These are the registers that cannot be used to allocate 39518334Speter a pseudo reg whose life does not cross calls. */ 39618334Speter 39718334Speterextern char fixed_regs[FIRST_PSEUDO_REGISTER]; 39818334Speter 39918334Speter/* The same info as a HARD_REG_SET. */ 40018334Speter 40118334Speterextern HARD_REG_SET fixed_reg_set; 40218334Speter 40318334Speter/* Indexed by hard register number, contains 1 for registers 40418334Speter that are fixed use or are clobbered by function calls. 40518334Speter These are the registers that cannot be used to allocate 40618334Speter a pseudo reg whose life crosses calls. */ 40718334Speter 40818334Speterextern char call_used_regs[FIRST_PSEUDO_REGISTER]; 40918334Speter 410117395Skan#ifdef CALL_REALLY_USED_REGISTERS 411117395Skanextern char call_really_used_regs[]; 412117395Skan#endif 413117395Skan 41418334Speter/* The same info as a HARD_REG_SET. */ 41518334Speter 41618334Speterextern HARD_REG_SET call_used_reg_set; 41718334Speter 41850397Sobrien/* Registers that we don't want to caller save. */ 41950397Sobrienextern HARD_REG_SET losing_caller_save_reg_set; 42050397Sobrien 42118334Speter/* Indexed by hard register number, contains 1 for registers that are 42218334Speter fixed use -- i.e. in fixed_regs -- or a function value return register 423132718Skan or TARGET_STRUCT_VALUE_RTX or STATIC_CHAIN_REGNUM. These are the 42418334Speter registers that cannot hold quantities across calls even if we are 42518334Speter willing to save and restore them. */ 42618334Speter 42718334Speterextern char call_fixed_regs[FIRST_PSEUDO_REGISTER]; 42818334Speter 42918334Speter/* The same info as a HARD_REG_SET. */ 43018334Speter 43118334Speterextern HARD_REG_SET call_fixed_reg_set; 43218334Speter 43318334Speter/* Indexed by hard register number, contains 1 for registers 43418334Speter that are being used for global register decls. 43518334Speter These must be exempt from ordinary flow analysis 43618334Speter and are also considered fixed. */ 43718334Speter 43818334Speterextern char global_regs[FIRST_PSEUDO_REGISTER]; 43918334Speter 44090075Sobrien/* Contains 1 for registers that are set or clobbered by calls. */ 44190075Sobrien/* ??? Ideally, this would be just call_used_regs plus global_regs, but 44290075Sobrien for someone's bright idea to have call_used_regs strictly include 44390075Sobrien fixed_regs. Which leaves us guessing as to the set of fixed_regs 44490075Sobrien that are actually preserved. We know for sure that those associated 44590075Sobrien with the local stack frame are safe, but scant others. */ 44690075Sobrien 44790075Sobrienextern HARD_REG_SET regs_invalidated_by_call; 44890075Sobrien 44990075Sobrien#ifdef REG_ALLOC_ORDER 45018334Speter/* Table of register numbers in the order in which to try to use them. */ 45118334Speter 45218334Speterextern int reg_alloc_order[FIRST_PSEUDO_REGISTER]; 45390075Sobrien 45490075Sobrien/* The inverse of reg_alloc_order. */ 45590075Sobrien 45690075Sobrienextern int inv_reg_alloc_order[FIRST_PSEUDO_REGISTER]; 45718334Speter#endif 45818334Speter 45918334Speter/* For each reg class, a HARD_REG_SET saying which registers are in it. */ 46018334Speter 46190075Sobrienextern HARD_REG_SET reg_class_contents[N_REG_CLASSES]; 46218334Speter 46318334Speter/* For each reg class, number of regs it contains. */ 46418334Speter 46590075Sobrienextern unsigned int reg_class_size[N_REG_CLASSES]; 46618334Speter 46718334Speter/* For each pair of reg classes, 46818334Speter a largest reg class contained in their union. */ 46918334Speter 47018334Speterextern enum reg_class reg_class_subunion[N_REG_CLASSES][N_REG_CLASSES]; 47118334Speter 47218334Speter/* For each pair of reg classes, 47318334Speter the smallest reg class that contains their union. */ 47418334Speter 47518334Speterextern enum reg_class reg_class_superunion[N_REG_CLASSES][N_REG_CLASSES]; 47618334Speter 47718334Speter/* Vector indexed by hardware reg giving its name. */ 47818334Speter 47990075Sobrienextern const char * reg_names[FIRST_PSEUDO_REGISTER]; 48090075Sobrien 481169689Skan/* Vector indexed by reg class giving its name. */ 482169689Skan 483169689Skanextern const char * reg_class_names[]; 484169689Skan 485117395Skan/* Given a hard REGN a FROM mode and a TO mode, return nonzero if 486117395Skan REGN cannot change modes between the specified modes. */ 487117395Skan#define REG_CANNOT_CHANGE_MODE_P(REGN, FROM, TO) \ 488117395Skan CANNOT_CHANGE_MODE_CLASS (FROM, TO, REGNO_REG_CLASS (REGN)) 489117395Skan 49090075Sobrien#endif /* ! GCC_HARD_REG_SET_H */ 491