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