Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===- subzero/src/IceTargetLoweringX8632Traits.h - x86-32 traits -*- C++ -*-=// | 1 //===- subzero/src/IceTargetLoweringX8632Traits.h - x86-32 traits -*- C++ -*-=// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 /// | 9 /// |
| 10 /// \file | 10 /// \file |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 264 // SSE2 is the PNaCl baseline instruction set. | 264 // SSE2 is the PNaCl baseline instruction set. |
| 265 SSE2 = Begin, | 265 SSE2 = Begin, |
| 266 SSE4_1, | 266 SSE4_1, |
| 267 End | 267 End |
| 268 }; | 268 }; |
| 269 | 269 |
| 270 static const char *TargetName; | 270 static const char *TargetName; |
| 271 static constexpr Type WordType = IceType_i32; | 271 static constexpr Type WordType = IceType_i32; |
| 272 | 272 |
| 273 static IceString getRegName(int32_t RegNum) { | 273 static IceString getRegName(int32_t RegNum) { |
| 274 static const char *const RegNames[] = { | 274 static const char *const RegNames[] = {{/* Empty for Reg_Invalid */}, |
| 275 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 275 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
| 276 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 276 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
| 277 isTrunc8Rcvr, isAhRcvr, aliases) \ | 277 isTrunc8Rcvr, isAhRcvr, aliases) \ |
| 278 name, | 278 name, |
| 279 REGX8632_TABLE | 279 REGX8632_TABLE |
| 280 #undef X | 280 #undef X |
| 281 }; | 281 }; |
| 282 assert(RegNum >= 0); | 282 assert(RegNum >= 0); |
| 283 assert(RegNum < RegisterSet::Reg_NUM); | 283 assert(RegNum < RegisterSet::Reg_NUM); |
| 284 return RegNames[RegNum]; | 284 return RegNames[RegNum]; |
| 285 } | 285 } |
| 286 | 286 |
| 287 static GPRRegister getEncodedGPR(int32_t RegNum) { | 287 static GPRRegister getEncodedGPR(int32_t RegNum) { |
| 288 static const GPRRegister GPRRegs[] = { | 288 static const GPRRegister GPRRegs[] = {{/* Empty for Reg_Invalid */}, |
| 289 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 289 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
| 290 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 290 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
| 291 isTrunc8Rcvr, isAhRcvr, aliases) \ | 291 isTrunc8Rcvr, isAhRcvr, aliases) \ |
| 292 GPRRegister(isGPR ? encode : GPRRegister::Encoded_Not_GPR), | 292 GPRRegister(isGPR ? encode : GPRRegister::Encoded_Not_GPR), |
| 293 REGX8632_TABLE | 293 REGX8632_TABLE |
| 294 #undef X | 294 #undef X |
| 295 }; | 295 }; |
| 296 assert(RegNum >= 0); | 296 assert(RegNum >= 0); |
| 297 assert(RegNum < RegisterSet::Reg_NUM); | 297 assert(RegNum < RegisterSet::Reg_NUM); |
| 298 assert(GPRRegs[RegNum] != GPRRegister::Encoded_Not_GPR); | 298 assert(GPRRegs[RegNum] != GPRRegister::Encoded_Not_GPR); |
| 299 return GPRRegs[RegNum]; | 299 return GPRRegs[RegNum]; |
| 300 } | 300 } |
| 301 | 301 |
| 302 static ByteRegister getEncodedByteReg(int32_t RegNum) { | 302 static ByteRegister getEncodedByteReg(int32_t RegNum) { |
| 303 static const ByteRegister ByteRegs[] = { | 303 static const ByteRegister ByteRegs[] = {{/* Empty for Reg_Invalid */}, |
| 304 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 304 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
| 305 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 305 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
| 306 isTrunc8Rcvr, isAhRcvr, aliases) \ | 306 isTrunc8Rcvr, isAhRcvr, aliases) \ |
| 307 ByteRegister(is8 ? encode : ByteRegister::Encoded_Not_ByteReg), | 307 ByteRegister(is8 ? encode : ByteRegister::Encoded_Not_ByteReg), |
| 308 REGX8632_TABLE | 308 REGX8632_TABLE |
| 309 #undef X | 309 #undef X |
| 310 }; | 310 }; |
| 311 assert(RegNum >= 0); | 311 assert(RegNum >= 0); |
| 312 assert(RegNum < RegisterSet::Reg_NUM); | 312 assert(RegNum < RegisterSet::Reg_NUM); |
| 313 assert(ByteRegs[RegNum] != ByteRegister::Encoded_Not_ByteReg); | 313 assert(ByteRegs[RegNum] != ByteRegister::Encoded_Not_ByteReg); |
| 314 return ByteRegs[RegNum]; | 314 return ByteRegs[RegNum]; |
| 315 } | 315 } |
| 316 | 316 |
| 317 static XmmRegister getEncodedXmm(int32_t RegNum) { | 317 static XmmRegister getEncodedXmm(int32_t RegNum) { |
| 318 static const XmmRegister XmmRegs[] = { | 318 static const XmmRegister XmmRegs[] = {{/* Empty for Reg_Invalid */}, |
| 319 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 319 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
| 320 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 320 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
| 321 isTrunc8Rcvr, isAhRcvr, aliases) \ | 321 isTrunc8Rcvr, isAhRcvr, aliases) \ |
| 322 XmmRegister(isXmm ? encode : XmmRegister::Encoded_Not_Xmm), | 322 XmmRegister(isXmm ? encode : XmmRegister::Encoded_Not_Xmm), |
| 323 REGX8632_TABLE | 323 REGX8632_TABLE |
| 324 #undef X | 324 #undef X |
| 325 }; | 325 }; |
| 326 assert(RegNum >= 0); | 326 assert(RegNum >= 0); |
| 327 assert(RegNum < RegisterSet::Reg_NUM); | 327 assert(RegNum < RegisterSet::Reg_NUM); |
| 328 assert(XmmRegs[RegNum] != XmmRegister::Encoded_Not_Xmm); | 328 assert(XmmRegs[RegNum] != XmmRegister::Encoded_Not_Xmm); |
| 329 return XmmRegs[RegNum]; | 329 return XmmRegs[RegNum]; |
| 330 } | 330 } |
| 331 | 331 |
| 332 static uint32_t getEncoding(int32_t RegNum) { | 332 static uint32_t getEncoding(int32_t RegNum) { |
| 333 static const uint32_t Encoding[] = { | 333 static const uint32_t Encoding[] = {{/* Empty for Reg_Invalid */}, |
| 334 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 334 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
| 335 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 335 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
| 336 isTrunc8Rcvr, isAhRcvr, aliases) \ | 336 isTrunc8Rcvr, isAhRcvr, aliases) \ |
| 337 encode, | 337 encode, |
| 338 REGX8632_TABLE | 338 REGX8632_TABLE |
| 339 #undef X | 339 #undef X |
| 340 }; | 340 }; |
| 341 assert(RegNum >= 0); | 341 assert(RegNum >= 0); |
| 342 assert(RegNum < RegisterSet::Reg_NUM); | 342 assert(RegNum < RegisterSet::Reg_NUM); |
| 343 return Encoding[RegNum]; | 343 return Encoding[RegNum]; |
| 344 } | 344 } |
| 345 | 345 |
| 346 static int32_t getBaseReg(int32_t RegNum) { | 346 static int32_t getBaseReg(int32_t RegNum) { |
| 347 static const int32_t BaseRegs[] = { | 347 static const int32_t BaseRegs[] = {{/* Empty for Reg_Invalid */}, |
| 348 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 348 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
| 349 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 349 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
| 350 isTrunc8Rcvr, isAhRcvr, aliases) \ | 350 isTrunc8Rcvr, isAhRcvr, aliases) \ |
| 351 RegisterSet::base, | 351 RegisterSet::base, |
| 352 REGX8632_TABLE | 352 REGX8632_TABLE |
| 353 #undef X | 353 #undef X |
| 354 }; | 354 }; |
| 355 assert(RegNum >= 0); | 355 assert(RegNum >= 0); |
| 356 assert(RegNum < RegisterSet::Reg_NUM); | 356 assert(RegNum < RegisterSet::Reg_NUM); |
| 357 return BaseRegs[RegNum]; | 357 return BaseRegs[RegNum]; |
| 358 } | 358 } |
| 359 | 359 |
| 360 // Return a register in RegNum's alias set that is suitable for Ty. | 360 // Return a register in RegNum's alias set that is suitable for Ty. |
| 361 static int32_t getGprForType(Type Ty, int32_t RegNum) { | 361 static int32_t getGprForType(Type Ty, int32_t RegNum) { |
| 362 assert(RegNum != Variable::NoRegister); | 362 assert(RegNum != Variable::NoRegister); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 409 llvm::SmallBitVector IntegerRegistersI8(RegisterSet::Reg_NUM); | 409 llvm::SmallBitVector IntegerRegistersI8(RegisterSet::Reg_NUM); |
| 410 llvm::SmallBitVector FloatRegisters(RegisterSet::Reg_NUM); | 410 llvm::SmallBitVector FloatRegisters(RegisterSet::Reg_NUM); |
| 411 llvm::SmallBitVector VectorRegisters(RegisterSet::Reg_NUM); | 411 llvm::SmallBitVector VectorRegisters(RegisterSet::Reg_NUM); |
| 412 llvm::SmallBitVector Trunc64To8Registers(RegisterSet::Reg_NUM); | 412 llvm::SmallBitVector Trunc64To8Registers(RegisterSet::Reg_NUM); |
| 413 llvm::SmallBitVector Trunc32To8Registers(RegisterSet::Reg_NUM); | 413 llvm::SmallBitVector Trunc32To8Registers(RegisterSet::Reg_NUM); |
| 414 llvm::SmallBitVector Trunc16To8Registers(RegisterSet::Reg_NUM); | 414 llvm::SmallBitVector Trunc16To8Registers(RegisterSet::Reg_NUM); |
| 415 llvm::SmallBitVector Trunc8RcvrRegisters(RegisterSet::Reg_NUM); | 415 llvm::SmallBitVector Trunc8RcvrRegisters(RegisterSet::Reg_NUM); |
| 416 llvm::SmallBitVector AhRcvrRegisters(RegisterSet::Reg_NUM); | 416 llvm::SmallBitVector AhRcvrRegisters(RegisterSet::Reg_NUM); |
| 417 llvm::SmallBitVector InvalidRegisters(RegisterSet::Reg_NUM); | 417 llvm::SmallBitVector InvalidRegisters(RegisterSet::Reg_NUM); |
| 418 ScratchRegs->resize(RegisterSet::Reg_NUM); | 418 ScratchRegs->resize(RegisterSet::Reg_NUM); |
| 419 | |
| 420 static struct { | |
| 421 uint16_t Val; | |
| 422 int Is64 : 1; | |
| 423 int Is32 : 1; | |
| 424 int Is16 : 1; | |
| 425 int Is8 : 1; | |
| 426 int IsXmm : 1; | |
| 427 int Is64To8 : 1; | |
| 428 int Is32To8 : 1; | |
| 429 int Is16To8 : 1; | |
| 430 int IsTrunc8Rcvr : 1; | |
| 431 int IsAhRcvr : 1; | |
| 432 int Scratch : 1; | |
| 433 uint16_t Aliases[4]; | |
| 434 } X8632RegTable[RegisterSet::Reg_NUM] = { | |
| 435 {/* Empty entry for RegInvalid. */}, | |
| 419 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 436 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
| 420 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 437 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
| 421 isTrunc8Rcvr, isAhRcvr, aliases) \ | 438 isTrunc8Rcvr, isAhRcvr, aliases) \ |
| 422 (IntegerRegistersI32)[RegisterSet::val] = is32; \ | 439 { \ |
| 423 (IntegerRegistersI16)[RegisterSet::val] = is16; \ | 440 RegisterSet::val, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
| 424 (IntegerRegistersI8)[RegisterSet::val] = is8; \ | 441 isTrunc8Rcvr, isAhRcvr, scratch, aliases \ |
| 425 (FloatRegisters)[RegisterSet::val] = isXmm; \ | |
| 426 (VectorRegisters)[RegisterSet::val] = isXmm; \ | |
| 427 (Trunc64To8Registers)[RegisterSet::val] = is64To8; \ | |
| 428 (Trunc32To8Registers)[RegisterSet::val] = is32To8; \ | |
| 429 (Trunc16To8Registers)[RegisterSet::val] = is16To8; \ | |
| 430 (Trunc8RcvrRegisters)[RegisterSet::val] = isTrunc8Rcvr; \ | |
| 431 (AhRcvrRegisters)[RegisterSet::val] = isAhRcvr; \ | |
| 432 (*RegisterAliases)[RegisterSet::val].resize(RegisterSet::Reg_NUM); \ | |
| 433 for (SizeT RegAlias : aliases) { \ | |
| 434 assert(!(*RegisterAliases)[RegisterSet::val][RegAlias] && \ | |
| 435 "Duplicate alias for " #val); \ | |
| 436 (*RegisterAliases)[RegisterSet::val].set(RegAlias); \ | |
| 437 } \ | 442 } \ |
| 438 (*RegisterAliases)[RegisterSet::val].set(RegisterSet::val); \ | 443 , |
| 439 (*ScratchRegs)[RegisterSet::val] = scratch; | 444 REGX8632_TABLE |
| 440 REGX8632_TABLE; | |
| 441 #undef X | 445 #undef X |
| 446 }; | |
| 447 | |
| 448 for (SizeT ii = 1; ii < llvm::array_lengthof(X8632RegTable); ++ii) { | |
| 449 const auto &Entry = X8632RegTable[ii]; | |
| 450 (IntegerRegistersI32)[Entry.Val] = Entry.Is32; | |
| 451 (IntegerRegistersI16)[Entry.Val] = Entry.Is16; | |
| 452 (IntegerRegistersI8)[Entry.Val] = Entry.Is8; | |
| 453 (FloatRegisters)[Entry.Val] = Entry.IsXmm; | |
| 454 (VectorRegisters)[Entry.Val] = Entry.IsXmm; | |
| 455 (Trunc64To8Registers)[Entry.Val] = Entry.Is64To8; | |
| 456 (Trunc32To8Registers)[Entry.Val] = Entry.Is32To8; | |
| 457 (Trunc16To8Registers)[Entry.Val] = Entry.Is16To8; | |
| 458 (Trunc8RcvrRegisters)[Entry.Val] = Entry.IsTrunc8Rcvr; | |
| 459 (AhRcvrRegisters)[Entry.Val] = Entry.IsAhRcvr; | |
| 460 (*RegisterAliases)[Entry.Val].resize(RegisterSet::Reg_NUM); | |
| 461 for (SizeT Alias : Entry.Aliases) { | |
| 462 if (Alias == 0) { | |
| 463 break; | |
| 464 } | |
| 465 assert(!(*RegisterAliases)[Entry.Val][Alias] && "Duplicate alias"); | |
| 466 (*RegisterAliases)[Entry.Val].set(Alias); | |
| 467 } | |
| 468 (*RegisterAliases)[Entry.Val].set(Entry.Val); | |
| 469 (*ScratchRegs)[Entry.Val] = Entry.Scratch; | |
| 470 } | |
| 442 | 471 |
| 443 (*TypeToRegisterSet)[RC_void] = InvalidRegisters; | 472 (*TypeToRegisterSet)[RC_void] = InvalidRegisters; |
| 444 (*TypeToRegisterSet)[RC_i1] = IntegerRegistersI8; | 473 (*TypeToRegisterSet)[RC_i1] = IntegerRegistersI8; |
| 445 (*TypeToRegisterSet)[RC_i8] = IntegerRegistersI8; | 474 (*TypeToRegisterSet)[RC_i8] = IntegerRegistersI8; |
| 446 (*TypeToRegisterSet)[RC_i16] = IntegerRegistersI16; | 475 (*TypeToRegisterSet)[RC_i16] = IntegerRegistersI16; |
| 447 (*TypeToRegisterSet)[RC_i32] = IntegerRegistersI32; | 476 (*TypeToRegisterSet)[RC_i32] = IntegerRegistersI32; |
| 448 (*TypeToRegisterSet)[RC_i64] = IntegerRegistersI32; | 477 (*TypeToRegisterSet)[RC_i64] = IntegerRegistersI32; |
| 449 (*TypeToRegisterSet)[RC_f32] = FloatRegisters; | 478 (*TypeToRegisterSet)[RC_f32] = FloatRegisters; |
| 450 (*TypeToRegisterSet)[RC_f64] = FloatRegisters; | 479 (*TypeToRegisterSet)[RC_f64] = FloatRegisters; |
| 451 (*TypeToRegisterSet)[RC_v4i1] = VectorRegisters; | 480 (*TypeToRegisterSet)[RC_v4i1] = VectorRegisters; |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 551 for (auto I : EquivalenceClasses) { | 580 for (auto I : EquivalenceClasses) { |
| 552 const RegisterList &List = I.second; | 581 const RegisterList &List = I.second; |
| 553 RegisterList Shuffled(List); | 582 RegisterList Shuffled(List); |
| 554 RandomShuffle(Shuffled.begin(), Shuffled.end(), RNGW); | 583 RandomShuffle(Shuffled.begin(), Shuffled.end(), RNGW); |
| 555 for (size_t SI = 0, SE = Shuffled.size(); SI < SE; ++SI) { | 584 for (size_t SI = 0, SE = Shuffled.size(); SI < SE; ++SI) { |
| 556 Permutation[List[SI]] = Shuffled[SI]; | 585 Permutation[List[SI]] = Shuffled[SI]; |
| 557 ++NumShuffled; | 586 ++NumShuffled; |
| 558 } | 587 } |
| 559 } | 588 } |
| 560 | 589 |
| 561 assert(NumShuffled + NumPreserved == RegisterSet::Reg_NUM); | 590 // We need to subtract one to account for Reg_Invalid. |
|
Jim Stichnoth
2015/12/30 02:50:24
Any chance this would be unnecessary, and everythi
John
2015/12/30 17:55:36
Yes, and no. I don't know anyway of telling the li
| |
| 591 assert(NumShuffled + NumPreserved == RegisterSet::Reg_NUM - 1); | |
| 562 | 592 |
| 563 if (Func->isVerbose(IceV_Random)) { | 593 if (Func->isVerbose(IceV_Random)) { |
| 564 OstreamLocker L(Func->getContext()); | 594 OstreamLocker L(Func->getContext()); |
| 565 Ostream &Str = Func->getContext()->getStrDump(); | 595 Ostream &Str = Func->getContext()->getStrDump(); |
| 566 Str << "Register equivalence classes:\n"; | 596 Str << "Register equivalence classes:\n"; |
| 567 for (auto I : EquivalenceClasses) { | 597 for (auto I : EquivalenceClasses) { |
| 568 Str << "{"; | 598 Str << "{"; |
| 569 const RegisterList &List = I.second; | 599 const RegisterList &List = I.second; |
| 570 bool First = true; | 600 bool First = true; |
| 571 for (int32_t Register : List) { | 601 for (int32_t Register : List) { |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 877 | 907 |
| 878 } // end of namespace X86Internal | 908 } // end of namespace X86Internal |
| 879 | 909 |
| 880 namespace X8632 { | 910 namespace X8632 { |
| 881 using Traits = ::Ice::X86Internal::MachineTraits<TargetX8632>; | 911 using Traits = ::Ice::X86Internal::MachineTraits<TargetX8632>; |
| 882 } // end of namespace X8632 | 912 } // end of namespace X8632 |
| 883 | 913 |
| 884 } // end of namespace Ice | 914 } // end of namespace Ice |
| 885 | 915 |
| 886 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8632TRAITS_H | 916 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8632TRAITS_H |
| OLD | NEW |