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