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