| OLD | NEW |
| 1 //===- subzero/src/IceTargetLoweringX8664Traits.h - x86-64 traits -*- C++ -*-=// | 1 //===- subzero/src/IceTargetLoweringX8664Traits.h - x86-64 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 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 // SSE2 is the PNaCl baseline instruction set. | 289 // SSE2 is the PNaCl baseline instruction set. |
| 290 SSE2 = Begin, | 290 SSE2 = Begin, |
| 291 SSE4_1, | 291 SSE4_1, |
| 292 End | 292 End |
| 293 }; | 293 }; |
| 294 | 294 |
| 295 static const char *TargetName; | 295 static const char *TargetName; |
| 296 static constexpr Type WordType = IceType_i64; | 296 static constexpr Type WordType = IceType_i64; |
| 297 | 297 |
| 298 static IceString getRegName(int32_t RegNum) { | 298 static IceString getRegName(int32_t RegNum) { |
| 299 static const char *const RegNames[] = { | 299 static const char *const RegNames[] = {{/*Empty for Reg_Invalid */}, |
| 300 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 300 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
| 301 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 301 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
| 302 isTrunc8Rcvr, isAhRcvr, aliases) \ | 302 isTrunc8Rcvr, isAhRcvr, aliases) \ |
| 303 name, | 303 name, |
| 304 REGX8664_TABLE | 304 REGX8664_TABLE |
| 305 #undef X | 305 #undef X |
| 306 }; | 306 }; |
| 307 assert(RegNum >= 0); | 307 assert(RegNum >= 0); |
| 308 assert(RegNum < RegisterSet::Reg_NUM); | 308 assert(RegNum < RegisterSet::Reg_NUM); |
| 309 return RegNames[RegNum]; | 309 return RegNames[RegNum]; |
| 310 } | 310 } |
| 311 | 311 |
| 312 static GPRRegister getEncodedGPR(int32_t RegNum) { | 312 static GPRRegister getEncodedGPR(int32_t RegNum) { |
| 313 static const GPRRegister GPRRegs[] = { | 313 static const GPRRegister GPRRegs[] = {{/*Empty for Reg_Invalid */}, |
| 314 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 314 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
| 315 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 315 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
| 316 isTrunc8Rcvr, isAhRcvr, aliases) \ | 316 isTrunc8Rcvr, isAhRcvr, aliases) \ |
| 317 GPRRegister(isGPR ? encode : GPRRegister::Encoded_Not_GPR), | 317 GPRRegister(isGPR ? encode : GPRRegister::Encoded_Not_GPR), |
| 318 REGX8664_TABLE | 318 REGX8664_TABLE |
| 319 #undef X | 319 #undef X |
| 320 }; | 320 }; |
| 321 assert(RegNum >= 0); | 321 assert(RegNum >= 0); |
| 322 assert(RegNum < RegisterSet::Reg_NUM); | 322 assert(RegNum < RegisterSet::Reg_NUM); |
| 323 assert(GPRRegs[RegNum] != GPRRegister::Encoded_Not_GPR); | 323 assert(GPRRegs[RegNum] != GPRRegister::Encoded_Not_GPR); |
| 324 return GPRRegs[RegNum]; | 324 return GPRRegs[RegNum]; |
| 325 } | 325 } |
| 326 | 326 |
| 327 static ByteRegister getEncodedByteReg(int32_t RegNum) { | 327 static ByteRegister getEncodedByteReg(int32_t RegNum) { |
| 328 static const ByteRegister ByteRegs[] = { | 328 static const ByteRegister ByteRegs[] = {{/*Empty for Reg_Invalid */}, |
| 329 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 329 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
| 330 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 330 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
| 331 isTrunc8Rcvr, isAhRcvr, aliases) \ | 331 isTrunc8Rcvr, isAhRcvr, aliases) \ |
| 332 ByteRegister(is8 ? encode : ByteRegister::Encoded_Not_ByteReg), | 332 ByteRegister(is8 ? encode : ByteRegister::Encoded_Not_ByteReg), |
| 333 REGX8664_TABLE | 333 REGX8664_TABLE |
| 334 #undef X | 334 #undef X |
| 335 }; | 335 }; |
| 336 assert(RegNum >= 0); | 336 assert(RegNum >= 0); |
| 337 assert(RegNum < RegisterSet::Reg_NUM); | 337 assert(RegNum < RegisterSet::Reg_NUM); |
| 338 assert(ByteRegs[RegNum] != ByteRegister::Encoded_Not_ByteReg); | 338 assert(ByteRegs[RegNum] != ByteRegister::Encoded_Not_ByteReg); |
| 339 return ByteRegs[RegNum]; | 339 return ByteRegs[RegNum]; |
| 340 } | 340 } |
| 341 | 341 |
| 342 static XmmRegister getEncodedXmm(int32_t RegNum) { | 342 static XmmRegister getEncodedXmm(int32_t RegNum) { |
| 343 static const XmmRegister XmmRegs[] = { | 343 static const XmmRegister XmmRegs[] = {{/*Empty for Reg_Invalid */}, |
| 344 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 344 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
| 345 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 345 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
| 346 isTrunc8Rcvr, isAhRcvr, aliases) \ | 346 isTrunc8Rcvr, isAhRcvr, aliases) \ |
| 347 XmmRegister(isXmm ? encode : XmmRegister::Encoded_Not_Xmm), | 347 XmmRegister(isXmm ? encode : XmmRegister::Encoded_Not_Xmm), |
| 348 REGX8664_TABLE | 348 REGX8664_TABLE |
| 349 #undef X | 349 #undef X |
| 350 }; | 350 }; |
| 351 assert(RegNum >= 0); | 351 assert(RegNum >= 0); |
| 352 assert(RegNum < RegisterSet::Reg_NUM); | 352 assert(RegNum < RegisterSet::Reg_NUM); |
| 353 assert(XmmRegs[RegNum] != XmmRegister::Encoded_Not_Xmm); | 353 assert(XmmRegs[RegNum] != XmmRegister::Encoded_Not_Xmm); |
| 354 return XmmRegs[RegNum]; | 354 return XmmRegs[RegNum]; |
| 355 } | 355 } |
| 356 | 356 |
| 357 static uint32_t getEncoding(int32_t RegNum) { | 357 static uint32_t getEncoding(int32_t RegNum) { |
| 358 static const uint32_t Encoding[] = { | 358 static const uint32_t Encoding[] = {{/*Empty for Reg_Invalid */}, |
| 359 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 359 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
| 360 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 360 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
| 361 isTrunc8Rcvr, isAhRcvr, aliases) \ | 361 isTrunc8Rcvr, isAhRcvr, aliases) \ |
| 362 encode, | 362 encode, |
| 363 REGX8664_TABLE | 363 REGX8664_TABLE |
| 364 #undef X | 364 #undef X |
| 365 }; | 365 }; |
| 366 assert(RegNum >= 0); | 366 assert(RegNum >= 0); |
| 367 assert(RegNum < RegisterSet::Reg_NUM); | 367 assert(RegNum < RegisterSet::Reg_NUM); |
| 368 return Encoding[RegNum]; | 368 return Encoding[RegNum]; |
| 369 } | 369 } |
| 370 | 370 |
| 371 static inline int32_t getBaseReg(int32_t RegNum) { | 371 static inline int32_t getBaseReg(int32_t RegNum) { |
| 372 static const int32_t BaseRegs[] = { | 372 static const int32_t BaseRegs[] = {{/*empty for Reg_Invalid */}, |
| 373 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 373 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
| 374 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 374 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
| 375 isTrunc8Rcvr, isAhRcvr, aliases) \ | 375 isTrunc8Rcvr, isAhRcvr, aliases) \ |
| 376 RegisterSet::base, | 376 RegisterSet::base, |
| 377 REGX8664_TABLE | 377 REGX8664_TABLE |
| 378 #undef X | 378 #undef X |
| 379 }; | 379 }; |
| 380 assert(RegNum >= 0); | 380 assert(RegNum >= 0); |
| 381 assert(RegNum < RegisterSet::Reg_NUM); | 381 assert(RegNum < RegisterSet::Reg_NUM); |
| 382 return BaseRegs[RegNum]; | 382 return BaseRegs[RegNum]; |
| 383 } | 383 } |
| 384 | 384 |
| 385 private: | 385 private: |
| 386 static int32_t getFirstGprForType(Type Ty) { | 386 static int32_t getFirstGprForType(Type Ty) { |
| 387 switch (Ty) { | 387 switch (Ty) { |
| 388 default: | 388 default: |
| 389 llvm_unreachable("Invalid type for GPR."); | 389 llvm_unreachable("Invalid type for GPR."); |
| 390 case IceType_i1: | 390 case IceType_i1: |
| 391 case IceType_i8: | 391 case IceType_i8: |
| 392 return RegisterSet::Reg_al; | 392 return RegisterSet::Reg_al; |
| 393 case IceType_i16: | 393 case IceType_i16: |
| 394 return RegisterSet::Reg_ax; | 394 return RegisterSet::Reg_ax; |
| 395 case IceType_i32: | 395 case IceType_i32: |
| 396 return RegisterSet::Reg_eax; | 396 return RegisterSet::Reg_eax; |
| 397 case IceType_i64: | 397 case IceType_i64: |
| 398 return RegisterSet::Reg_rax; | 398 return RegisterSet::Reg_rax; |
| 399 } | 399 } |
| 400 } | 400 } |
| 401 | 401 |
| 402 public: | 402 public: |
| 403 static int32_t getGprForType(Type Ty, int32_t RegNum) { | 403 static int32_t getGprForType(Type Ty, int32_t RegNum) { |
| 404 assert(RegNum != Variable::NoRegister); | 404 assert(RegNum != Variable::NoRegister); |
| 405 assert(RegNum != RegisterSet::Reg_Invalid); |
| 405 | 406 |
| 406 if (!isScalarIntegerType(Ty)) { | 407 if (!isScalarIntegerType(Ty)) { |
| 407 return RegNum; | 408 return RegNum; |
| 408 } | 409 } |
| 409 | 410 |
| 410 assert(Ty == IceType_i1 || Ty == IceType_i8 || Ty == IceType_i16 || | 411 assert(Ty == IceType_i1 || Ty == IceType_i8 || Ty == IceType_i16 || |
| 411 Ty == IceType_i32 || Ty == IceType_i64); | 412 Ty == IceType_i32 || Ty == IceType_i64); |
| 412 | 413 |
| 413 if (RegNum == RegisterSet::Reg_ah) { | 414 if (RegNum == RegisterSet::Reg_ah) { |
| 414 assert(Ty == IceType_i8); | 415 assert(Ty == IceType_i8); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 461 llvm::SmallBitVector FloatRegisters(RegisterSet::Reg_NUM); | 462 llvm::SmallBitVector FloatRegisters(RegisterSet::Reg_NUM); |
| 462 llvm::SmallBitVector VectorRegisters(RegisterSet::Reg_NUM); | 463 llvm::SmallBitVector VectorRegisters(RegisterSet::Reg_NUM); |
| 463 llvm::SmallBitVector Trunc64To8Registers(RegisterSet::Reg_NUM); | 464 llvm::SmallBitVector Trunc64To8Registers(RegisterSet::Reg_NUM); |
| 464 llvm::SmallBitVector Trunc32To8Registers(RegisterSet::Reg_NUM); | 465 llvm::SmallBitVector Trunc32To8Registers(RegisterSet::Reg_NUM); |
| 465 llvm::SmallBitVector Trunc16To8Registers(RegisterSet::Reg_NUM); | 466 llvm::SmallBitVector Trunc16To8Registers(RegisterSet::Reg_NUM); |
| 466 llvm::SmallBitVector Trunc8RcvrRegisters(RegisterSet::Reg_NUM); | 467 llvm::SmallBitVector Trunc8RcvrRegisters(RegisterSet::Reg_NUM); |
| 467 llvm::SmallBitVector AhRcvrRegisters(RegisterSet::Reg_NUM); | 468 llvm::SmallBitVector AhRcvrRegisters(RegisterSet::Reg_NUM); |
| 468 llvm::SmallBitVector InvalidRegisters(RegisterSet::Reg_NUM); | 469 llvm::SmallBitVector InvalidRegisters(RegisterSet::Reg_NUM); |
| 469 ScratchRegs->resize(RegisterSet::Reg_NUM); | 470 ScratchRegs->resize(RegisterSet::Reg_NUM); |
| 470 | 471 |
| 472 static struct { |
| 473 uint16_t Val; |
| 474 int Is64 : 1; |
| 475 int Is32 : 1; |
| 476 int Is16 : 1; |
| 477 int Is8 : 1; |
| 478 int IsXmm : 1; |
| 479 int Is64To8 : 1; |
| 480 int Is32To8 : 1; |
| 481 int Is16To8 : 1; |
| 482 int IsTrunc8Rcvr : 1; |
| 483 int IsAhRcvr : 1; |
| 484 int Scratch : 1; |
| 485 uint16_t Aliases[4]; |
| 486 } X8664RegTable[RegisterSet::Reg_NUM] = { |
| 487 {/* Empty entry for RegInvalid. */}, |
| 471 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 488 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
| 472 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 489 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
| 473 isTrunc8Rcvr, isAhRcvr, aliases) \ | 490 isTrunc8Rcvr, isAhRcvr, aliases) \ |
| 474 (IntegerRegistersI64)[RegisterSet::val] = is64; \ | 491 { \ |
| 475 (IntegerRegistersI32)[RegisterSet::val] = is32; \ | 492 RegisterSet::val, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
| 476 (IntegerRegistersI16)[RegisterSet::val] = is16; \ | 493 isTrunc8Rcvr, isAhRcvr, scratch, aliases \ |
| 477 (IntegerRegistersI8)[RegisterSet::val] = is8; \ | |
| 478 (FloatRegisters)[RegisterSet::val] = isXmm; \ | |
| 479 (VectorRegisters)[RegisterSet::val] = isXmm; \ | |
| 480 (Trunc64To8Registers)[RegisterSet::val] = is64To8; \ | |
| 481 (Trunc32To8Registers)[RegisterSet::val] = is32To8; \ | |
| 482 (Trunc16To8Registers)[RegisterSet::val] = is16To8; \ | |
| 483 (Trunc8RcvrRegisters)[RegisterSet::val] = isTrunc8Rcvr; \ | |
| 484 (AhRcvrRegisters)[RegisterSet::val] = isAhRcvr; \ | |
| 485 (*RegisterAliases)[RegisterSet::val].resize(RegisterSet::Reg_NUM); \ | |
| 486 for (SizeT RegAlias : aliases) { \ | |
| 487 assert(!(*RegisterAliases)[RegisterSet::val][RegAlias] && \ | |
| 488 "Duplicate alias for " #val); \ | |
| 489 (*RegisterAliases)[RegisterSet::val].set(RegAlias); \ | |
| 490 } \ | 494 } \ |
| 491 (*RegisterAliases)[RegisterSet::val].set(RegisterSet::val); \ | 495 , |
| 492 (*ScratchRegs)[RegisterSet::val] = scratch; | 496 REGX8664_TABLE |
| 493 REGX8664_TABLE; | |
| 494 #undef X | 497 #undef X |
| 498 }; |
| 499 |
| 500 for (SizeT ii = 1; ii < llvm::array_lengthof(X8664RegTable); ++ii) { |
| 501 const auto &Entry = X8664RegTable[ii]; |
| 502 (IntegerRegistersI64)[Entry.Val] = Entry.Is64; |
| 503 (IntegerRegistersI32)[Entry.Val] = Entry.Is32; |
| 504 (IntegerRegistersI16)[Entry.Val] = Entry.Is16; |
| 505 (IntegerRegistersI8)[Entry.Val] = Entry.Is8; |
| 506 (FloatRegisters)[Entry.Val] = Entry.IsXmm; |
| 507 (VectorRegisters)[Entry.Val] = Entry.IsXmm; |
| 508 (Trunc64To8Registers)[Entry.Val] = Entry.Is64To8; |
| 509 (Trunc32To8Registers)[Entry.Val] = Entry.Is32To8; |
| 510 (Trunc16To8Registers)[Entry.Val] = Entry.Is16To8; |
| 511 (Trunc8RcvrRegisters)[Entry.Val] = Entry.IsTrunc8Rcvr; |
| 512 (AhRcvrRegisters)[Entry.Val] = Entry.IsAhRcvr; |
| 513 (*RegisterAliases)[Entry.Val].resize(RegisterSet::Reg_NUM); |
| 514 for (SizeT Alias : Entry.Aliases) { |
| 515 if (Alias == 0) { |
| 516 break; |
| 517 } |
| 518 assert(!(*RegisterAliases)[Entry.Val][Alias] && "Duplicate alias"); |
| 519 (*RegisterAliases)[Entry.Val].set(Alias); |
| 520 } |
| 521 (*RegisterAliases)[Entry.Val].set(Entry.Val); |
| 522 (*ScratchRegs)[Entry.Val] = Entry.Scratch; |
| 523 } |
| 495 | 524 |
| 496 (*TypeToRegisterSet)[RC_void] = InvalidRegisters; | 525 (*TypeToRegisterSet)[RC_void] = InvalidRegisters; |
| 497 (*TypeToRegisterSet)[RC_i1] = IntegerRegistersI8; | 526 (*TypeToRegisterSet)[RC_i1] = IntegerRegistersI8; |
| 498 (*TypeToRegisterSet)[RC_i8] = IntegerRegistersI8; | 527 (*TypeToRegisterSet)[RC_i8] = IntegerRegistersI8; |
| 499 (*TypeToRegisterSet)[RC_i16] = IntegerRegistersI16; | 528 (*TypeToRegisterSet)[RC_i16] = IntegerRegistersI16; |
| 500 (*TypeToRegisterSet)[RC_i32] = IntegerRegistersI32; | 529 (*TypeToRegisterSet)[RC_i32] = IntegerRegistersI32; |
| 501 (*TypeToRegisterSet)[RC_i64] = IntegerRegistersI64; | 530 (*TypeToRegisterSet)[RC_i64] = IntegerRegistersI64; |
| 502 (*TypeToRegisterSet)[RC_f32] = FloatRegisters; | 531 (*TypeToRegisterSet)[RC_f32] = FloatRegisters; |
| 503 (*TypeToRegisterSet)[RC_f64] = FloatRegisters; | 532 (*TypeToRegisterSet)[RC_f64] = FloatRegisters; |
| 504 (*TypeToRegisterSet)[RC_v4i1] = VectorRegisters; | 533 (*TypeToRegisterSet)[RC_v4i1] = VectorRegisters; |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 604 for (auto I : EquivalenceClasses) { | 633 for (auto I : EquivalenceClasses) { |
| 605 const RegisterList &List = I.second; | 634 const RegisterList &List = I.second; |
| 606 RegisterList Shuffled(List); | 635 RegisterList Shuffled(List); |
| 607 RandomShuffle(Shuffled.begin(), Shuffled.end(), RNGW); | 636 RandomShuffle(Shuffled.begin(), Shuffled.end(), RNGW); |
| 608 for (size_t SI = 0, SE = Shuffled.size(); SI < SE; ++SI) { | 637 for (size_t SI = 0, SE = Shuffled.size(); SI < SE; ++SI) { |
| 609 Permutation[List[SI]] = Shuffled[SI]; | 638 Permutation[List[SI]] = Shuffled[SI]; |
| 610 ++NumShuffled; | 639 ++NumShuffled; |
| 611 } | 640 } |
| 612 } | 641 } |
| 613 | 642 |
| 614 assert(NumShuffled + NumPreserved == RegisterSet::Reg_NUM); | 643 // We need to subtract one to account for Reg_Invalid. |
| 644 assert(NumShuffled + NumPreserved == RegisterSet::Reg_NUM - 1); |
| 615 | 645 |
| 616 if (Func->isVerbose(IceV_Random)) { | 646 if (Func->isVerbose(IceV_Random)) { |
| 617 OstreamLocker L(Func->getContext()); | 647 OstreamLocker L(Func->getContext()); |
| 618 Ostream &Str = Func->getContext()->getStrDump(); | 648 Ostream &Str = Func->getContext()->getStrDump(); |
| 619 Str << "Register equivalence classes:\n"; | 649 Str << "Register equivalence classes:\n"; |
| 620 for (auto I : EquivalenceClasses) { | 650 for (auto I : EquivalenceClasses) { |
| 621 Str << "{"; | 651 Str << "{"; |
| 622 const RegisterList &List = I.second; | 652 const RegisterList &List = I.second; |
| 623 bool First = true; | 653 bool First = true; |
| 624 for (int32_t Register : List) { | 654 for (int32_t Register : List) { |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 917 | 947 |
| 918 } // end of namespace X86Internal | 948 } // end of namespace X86Internal |
| 919 | 949 |
| 920 namespace X8664 { | 950 namespace X8664 { |
| 921 using Traits = ::Ice::X86Internal::MachineTraits<TargetX8664>; | 951 using Traits = ::Ice::X86Internal::MachineTraits<TargetX8664>; |
| 922 } // end of namespace X8664 | 952 } // end of namespace X8664 |
| 923 | 953 |
| 924 } // end of namespace Ice | 954 } // end of namespace Ice |
| 925 | 955 |
| 926 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8664TRAITS_H | 956 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8664TRAITS_H |
| OLD | NEW |