| 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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 | 61 |
| 62 enum ScaleFactor { TIMES_1 = 0, TIMES_2 = 1, TIMES_4 = 2, TIMES_8 = 3 }; | 62 enum ScaleFactor { TIMES_1 = 0, TIMES_2 = 1, TIMES_4 = 2, TIMES_8 = 3 }; |
| 63 | 63 |
| 64 using GPRRegister = ::Ice::RegX8664::GPRRegister; | 64 using GPRRegister = ::Ice::RegX8664::GPRRegister; |
| 65 using ByteRegister = ::Ice::RegX8664::ByteRegister; | 65 using ByteRegister = ::Ice::RegX8664::ByteRegister; |
| 66 using XmmRegister = ::Ice::RegX8664::XmmRegister; | 66 using XmmRegister = ::Ice::RegX8664::XmmRegister; |
| 67 | 67 |
| 68 using Cond = ::Ice::CondX8664; | 68 using Cond = ::Ice::CondX8664; |
| 69 | 69 |
| 70 using RegisterSet = ::Ice::RegX8664; | 70 using RegisterSet = ::Ice::RegX8664; |
| 71 static constexpr SizeT StackPtr = RegX8664::Reg_rsp; | 71 static constexpr RegisterSet::AllRegisters StackPtr = RegX8664::Reg_rsp; |
| 72 static constexpr SizeT FramePtr = RegX8664::Reg_rbp; | 72 static constexpr RegisterSet::AllRegisters FramePtr = RegX8664::Reg_rbp; |
| 73 static constexpr GPRRegister Encoded_Reg_Accumulator = | 73 static constexpr GPRRegister Encoded_Reg_Accumulator = |
| 74 RegX8664::Encoded_Reg_eax; | 74 RegX8664::Encoded_Reg_eax; |
| 75 static constexpr GPRRegister Encoded_Reg_Counter = RegX8664::Encoded_Reg_ecx; | 75 static constexpr GPRRegister Encoded_Reg_Counter = RegX8664::Encoded_Reg_ecx; |
| 76 static constexpr FixupKind FK_PcRel = llvm::ELF::R_X86_64_PC32; | 76 static constexpr FixupKind FK_PcRel = llvm::ELF::R_X86_64_PC32; |
| 77 static constexpr FixupKind FK_Abs = llvm::ELF::R_X86_64_32S; | 77 static constexpr FixupKind FK_Abs = llvm::ELF::R_X86_64_32S; |
| 78 static constexpr FixupKind FK_Gotoff = llvm::ELF::R_X86_64_GOTOFF64; | 78 static constexpr FixupKind FK_Gotoff = llvm::ELF::R_X86_64_GOTOFF64; |
| 79 static constexpr FixupKind FK_GotPC = llvm::ELF::R_X86_64_GOTPC32; | 79 static constexpr FixupKind FK_GotPC = llvm::ELF::R_X86_64_GOTPC32; |
| 80 | 80 |
| 81 class Operand { | 81 class Operand { |
| 82 public: | 82 public: |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 Begin, | 294 Begin, |
| 295 // SSE2 is the PNaCl baseline instruction set. | 295 // SSE2 is the PNaCl baseline instruction set. |
| 296 SSE2 = Begin, | 296 SSE2 = Begin, |
| 297 SSE4_1, | 297 SSE4_1, |
| 298 End | 298 End |
| 299 }; | 299 }; |
| 300 | 300 |
| 301 static const char *TargetName; | 301 static const char *TargetName; |
| 302 static constexpr Type WordType = IceType_i64; | 302 static constexpr Type WordType = IceType_i64; |
| 303 | 303 |
| 304 static IceString getRegName(int32_t RegNum) { | 304 static IceString getRegName(RegNumT RegNum) { |
| 305 static const char *const RegNames[RegisterSet::Reg_NUM] = { | 305 static const char *const RegNames[RegisterSet::Reg_NUM] = { |
| 306 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 306 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
| 307 sboxres, isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, \ | 307 sboxres, isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, \ |
| 308 is16To8, isTrunc8Rcvr, isAhRcvr, aliases) \ | 308 is16To8, isTrunc8Rcvr, isAhRcvr, aliases) \ |
| 309 name, | 309 name, |
| 310 REGX8664_TABLE | 310 REGX8664_TABLE |
| 311 #undef X | 311 #undef X |
| 312 }; | 312 }; |
| 313 assert(RegNum >= 0); | 313 RegNum.assertIsValid(); |
| 314 assert(RegNum < RegisterSet::Reg_NUM); | |
| 315 return RegNames[RegNum]; | 314 return RegNames[RegNum]; |
| 316 } | 315 } |
| 317 | 316 |
| 318 static GPRRegister getEncodedGPR(int32_t RegNum) { | 317 static GPRRegister getEncodedGPR(RegNumT RegNum) { |
| 319 static const GPRRegister GPRRegs[RegisterSet::Reg_NUM] = { | 318 static const GPRRegister GPRRegs[RegisterSet::Reg_NUM] = { |
| 320 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 319 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
| 321 sboxres, isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, \ | 320 sboxres, isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, \ |
| 322 is16To8, isTrunc8Rcvr, isAhRcvr, aliases) \ | 321 is16To8, isTrunc8Rcvr, isAhRcvr, aliases) \ |
| 323 GPRRegister(isGPR ? encode : GPRRegister::Encoded_Not_GPR), | 322 GPRRegister(isGPR ? encode : GPRRegister::Encoded_Not_GPR), |
| 324 REGX8664_TABLE | 323 REGX8664_TABLE |
| 325 #undef X | 324 #undef X |
| 326 }; | 325 }; |
| 327 assert(RegNum >= 0); | 326 RegNum.assertIsValid(); |
| 328 assert(RegNum < RegisterSet::Reg_NUM); | |
| 329 assert(GPRRegs[RegNum] != GPRRegister::Encoded_Not_GPR); | 327 assert(GPRRegs[RegNum] != GPRRegister::Encoded_Not_GPR); |
| 330 return GPRRegs[RegNum]; | 328 return GPRRegs[RegNum]; |
| 331 } | 329 } |
| 332 | 330 |
| 333 static ByteRegister getEncodedByteReg(int32_t RegNum) { | 331 static ByteRegister getEncodedByteReg(RegNumT RegNum) { |
| 334 static const ByteRegister ByteRegs[RegisterSet::Reg_NUM] = { | 332 static const ByteRegister ByteRegs[RegisterSet::Reg_NUM] = { |
| 335 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 333 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
| 336 sboxres, isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, \ | 334 sboxres, isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, \ |
| 337 is16To8, isTrunc8Rcvr, isAhRcvr, aliases) \ | 335 is16To8, isTrunc8Rcvr, isAhRcvr, aliases) \ |
| 338 ByteRegister(is8 ? encode : ByteRegister::Encoded_Not_ByteReg), | 336 ByteRegister(is8 ? encode : ByteRegister::Encoded_Not_ByteReg), |
| 339 REGX8664_TABLE | 337 REGX8664_TABLE |
| 340 #undef X | 338 #undef X |
| 341 }; | 339 }; |
| 342 assert(RegNum >= 0); | 340 RegNum.assertIsValid(); |
| 343 assert(RegNum < RegisterSet::Reg_NUM); | |
| 344 assert(ByteRegs[RegNum] != ByteRegister::Encoded_Not_ByteReg); | 341 assert(ByteRegs[RegNum] != ByteRegister::Encoded_Not_ByteReg); |
| 345 return ByteRegs[RegNum]; | 342 return ByteRegs[RegNum]; |
| 346 } | 343 } |
| 347 | 344 |
| 348 static XmmRegister getEncodedXmm(int32_t RegNum) { | 345 static XmmRegister getEncodedXmm(RegNumT RegNum) { |
| 349 static const XmmRegister XmmRegs[RegisterSet::Reg_NUM] = { | 346 static const XmmRegister XmmRegs[RegisterSet::Reg_NUM] = { |
| 350 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 347 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
| 351 sboxres, isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, \ | 348 sboxres, isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, \ |
| 352 is16To8, isTrunc8Rcvr, isAhRcvr, aliases) \ | 349 is16To8, isTrunc8Rcvr, isAhRcvr, aliases) \ |
| 353 XmmRegister(isXmm ? encode : XmmRegister::Encoded_Not_Xmm), | 350 XmmRegister(isXmm ? encode : XmmRegister::Encoded_Not_Xmm), |
| 354 REGX8664_TABLE | 351 REGX8664_TABLE |
| 355 #undef X | 352 #undef X |
| 356 }; | 353 }; |
| 357 assert(RegNum >= 0); | 354 RegNum.assertIsValid(); |
| 358 assert(RegNum < RegisterSet::Reg_NUM); | |
| 359 assert(XmmRegs[RegNum] != XmmRegister::Encoded_Not_Xmm); | 355 assert(XmmRegs[RegNum] != XmmRegister::Encoded_Not_Xmm); |
| 360 return XmmRegs[RegNum]; | 356 return XmmRegs[RegNum]; |
| 361 } | 357 } |
| 362 | 358 |
| 363 static uint32_t getEncoding(int32_t RegNum) { | 359 static uint32_t getEncoding(RegNumT RegNum) { |
| 364 static const uint32_t Encoding[RegisterSet::Reg_NUM] = { | 360 static const uint32_t Encoding[RegisterSet::Reg_NUM] = { |
| 365 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 361 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
| 366 sboxres, isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, \ | 362 sboxres, isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, \ |
| 367 is16To8, isTrunc8Rcvr, isAhRcvr, aliases) \ | 363 is16To8, isTrunc8Rcvr, isAhRcvr, aliases) \ |
| 368 encode, | 364 encode, |
| 369 REGX8664_TABLE | 365 REGX8664_TABLE |
| 370 #undef X | 366 #undef X |
| 371 }; | 367 }; |
| 372 assert(RegNum >= 0); | 368 RegNum.assertIsValid(); |
| 373 assert(RegNum < RegisterSet::Reg_NUM); | |
| 374 return Encoding[RegNum]; | 369 return Encoding[RegNum]; |
| 375 } | 370 } |
| 376 | 371 |
| 377 static inline int32_t getBaseReg(int32_t RegNum) { | 372 static inline RegNumT getBaseReg(RegNumT RegNum) { |
| 378 static const int32_t BaseRegs[RegisterSet::Reg_NUM] = { | 373 static const RegNumT BaseRegs[RegisterSet::Reg_NUM] = { |
| 379 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 374 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
| 380 sboxres, isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, \ | 375 sboxres, isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, \ |
| 381 is16To8, isTrunc8Rcvr, isAhRcvr, aliases) \ | 376 is16To8, isTrunc8Rcvr, isAhRcvr, aliases) \ |
| 382 encode, | 377 RegisterSet::base, |
| 383 REGX8664_TABLE | 378 REGX8664_TABLE |
| 384 #undef X | 379 #undef X |
| 385 }; | 380 }; |
| 386 assert(RegNum >= 0); | 381 RegNum.assertIsValid(); |
| 387 assert(RegNum < RegisterSet::Reg_NUM); | |
| 388 return BaseRegs[RegNum]; | 382 return BaseRegs[RegNum]; |
| 389 } | 383 } |
| 390 | 384 |
| 391 private: | 385 private: |
| 392 static int32_t getFirstGprForType(Type Ty) { | 386 static RegNumT getFirstGprForType(Type Ty) { |
| 393 switch (Ty) { | 387 switch (Ty) { |
| 394 default: | 388 default: |
| 395 llvm_unreachable("Invalid type for GPR."); | 389 llvm_unreachable("Invalid type for GPR."); |
| 396 case IceType_i1: | 390 case IceType_i1: |
| 397 case IceType_i8: | 391 case IceType_i8: |
| 398 return RegisterSet::Reg_al; | 392 return RegisterSet::Reg_al; |
| 399 case IceType_i16: | 393 case IceType_i16: |
| 400 return RegisterSet::Reg_ax; | 394 return RegisterSet::Reg_ax; |
| 401 case IceType_i32: | 395 case IceType_i32: |
| 402 return RegisterSet::Reg_eax; | 396 return RegisterSet::Reg_eax; |
| 403 case IceType_i64: | 397 case IceType_i64: |
| 404 return RegisterSet::Reg_rax; | 398 return RegisterSet::Reg_rax; |
| 405 } | 399 } |
| 406 } | 400 } |
| 407 | 401 |
| 408 public: | 402 public: |
| 409 static int32_t getGprForType(Type Ty, int32_t RegNum) { | 403 static RegNumT getGprForType(Type Ty, RegNumT RegNum) { |
| 410 assert(RegNum != Variable::NoRegister); | 404 assert(RegNum != RegNumT::NoRegister); |
| 411 | 405 |
| 412 if (!isScalarIntegerType(Ty)) { | 406 if (!isScalarIntegerType(Ty)) { |
| 413 return RegNum; | 407 return RegNum; |
| 414 } | 408 } |
| 415 | 409 |
| 416 assert(Ty == IceType_i1 || Ty == IceType_i8 || Ty == IceType_i16 || | 410 assert(Ty == IceType_i1 || Ty == IceType_i8 || Ty == IceType_i16 || |
| 417 Ty == IceType_i32 || Ty == IceType_i64); | 411 Ty == IceType_i32 || Ty == IceType_i64); |
| 418 | 412 |
| 419 if (RegNum == RegisterSet::Reg_ah) { | 413 if (RegNum == RegisterSet::Reg_ah) { |
| 420 assert(Ty == IceType_i8); | 414 assert(Ty == IceType_i8); |
| 421 return RegNum; | 415 return RegNum; |
| 422 } | 416 } |
| 423 | 417 |
| 424 assert(RegNum != RegisterSet::Reg_bh); | 418 assert(RegNum != RegisterSet::Reg_bh); |
| 425 assert(RegNum != RegisterSet::Reg_ch); | 419 assert(RegNum != RegisterSet::Reg_ch); |
| 426 assert(RegNum != RegisterSet::Reg_dh); | 420 assert(RegNum != RegisterSet::Reg_dh); |
| 427 | 421 |
| 428 const int32_t FirstGprForType = getFirstGprForType(Ty); | 422 const RegNumT FirstGprForType = getFirstGprForType(Ty); |
| 429 | 423 |
| 430 switch (RegNum) { | 424 switch (RegNum) { |
| 431 default: | 425 default: |
| 432 llvm::report_fatal_error("Unknown register."); | 426 llvm::report_fatal_error("Unknown register."); |
| 433 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 427 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
| 434 sboxres, isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, \ | 428 sboxres, isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, \ |
| 435 is16To8, isTrunc8Rcvr, isAhRcvr, aliases) \ | 429 is16To8, isTrunc8Rcvr, isAhRcvr, aliases) \ |
| 436 case RegisterSet::val: { \ | 430 case RegisterSet::val: { \ |
| 437 if (!isGPR) \ | 431 if (!isGPR) \ |
| 438 return RegisterSet::val; \ | 432 return RegisterSet::val; \ |
| 439 assert((is64) || (is32) || (is16) || (is8) || \ | 433 assert((is64) || (is32) || (is16) || (is8) || \ |
| 440 getBaseReg(RegisterSet::val) == RegisterSet::Reg_rsp); \ | 434 getBaseReg(RegisterSet::val) == RegisterSet::Reg_rsp); \ |
| 441 constexpr int32_t FirstGprWithRegNumSize = \ | 435 constexpr RegisterSet::AllRegisters FirstGprWithRegNumSize = \ |
| 442 ((is64) || RegisterSet::val == RegisterSet::Reg_rsp) \ | 436 ((is64) || RegisterSet::val == RegisterSet::Reg_rsp) \ |
| 443 ? RegisterSet::Reg_rax \ | 437 ? RegisterSet::Reg_rax \ |
| 444 : (((is32) || RegisterSet::val == RegisterSet::Reg_esp) \ | 438 : (((is32) || RegisterSet::val == RegisterSet::Reg_esp) \ |
| 445 ? RegisterSet::Reg_eax \ | 439 ? RegisterSet::Reg_eax \ |
| 446 : (((is16) || RegisterSet::val == RegisterSet::Reg_sp) \ | 440 : (((is16) || RegisterSet::val == RegisterSet::Reg_sp) \ |
| 447 ? RegisterSet::Reg_ax \ | 441 ? RegisterSet::Reg_ax \ |
| 448 : RegisterSet::Reg_al)); \ | 442 : RegisterSet::Reg_al)); \ |
| 449 const int32_t NewRegNum = \ | 443 const auto NewRegNum = \ |
| 450 RegNum - FirstGprWithRegNumSize + FirstGprForType; \ | 444 RegNumT::fixme(RegNum - FirstGprWithRegNumSize + FirstGprForType); \ |
| 451 assert(getBaseReg(RegNum) == getBaseReg(NewRegNum) && \ | 445 assert(getBaseReg(RegNum) == getBaseReg(NewRegNum) && \ |
| 452 "Error involving " #val); \ | 446 "Error involving " #val); \ |
| 453 return NewRegNum; \ | 447 return NewRegNum; \ |
| 454 } | 448 } |
| 455 REGX8664_TABLE | 449 REGX8664_TABLE |
| 456 #undef X | 450 #undef X |
| 457 } | 451 } |
| 458 } | 452 } |
| 459 | 453 |
| 460 private: | 454 private: |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 617 | 611 |
| 618 REGX8664_TABLE | 612 REGX8664_TABLE |
| 619 | 613 |
| 620 #undef X | 614 #undef X |
| 621 | 615 |
| 622 return Registers; | 616 return Registers; |
| 623 } | 617 } |
| 624 | 618 |
| 625 static void | 619 static void |
| 626 makeRandomRegisterPermutation(GlobalContext *Ctx, Cfg *Func, | 620 makeRandomRegisterPermutation(GlobalContext *Ctx, Cfg *Func, |
| 627 llvm::SmallVectorImpl<int32_t> &Permutation, | 621 llvm::SmallVectorImpl<RegNumT> &Permutation, |
| 628 const llvm::SmallBitVector &ExcludeRegisters, | 622 const llvm::SmallBitVector &ExcludeRegisters, |
| 629 uint64_t Salt) { | 623 uint64_t Salt) { |
| 630 // TODO(stichnot): Declaring Permutation this way loses type/size | 624 // TODO(stichnot): Declaring Permutation this way loses type/size |
| 631 // information. Fix this in conjunction with the caller-side TODO. | 625 // information. Fix this in conjunction with the caller-side TODO. |
| 632 assert(Permutation.size() >= RegisterSet::Reg_NUM); | 626 assert(Permutation.size() >= RegisterSet::Reg_NUM); |
| 633 // Expected upper bound on the number of registers in a single equivalence | 627 // Expected upper bound on the number of registers in a single equivalence |
| 634 // class. For x86-64, this would comprise the 16 XMM registers. This is | 628 // class. For x86-64, this would comprise the 16 XMM registers. This is |
| 635 // for performance, not correctness. | 629 // for performance, not correctness. |
| 636 static const unsigned MaxEquivalenceClassSize = 8; | 630 static const unsigned MaxEquivalenceClassSize = 8; |
| 637 using RegisterList = llvm::SmallVector<int32_t, MaxEquivalenceClassSize>; | 631 using RegisterList = llvm::SmallVector<RegNumT, MaxEquivalenceClassSize>; |
| 638 using EquivalenceClassMap = std::map<uint32_t, RegisterList>; | 632 using EquivalenceClassMap = std::map<uint32_t, RegisterList>; |
| 639 EquivalenceClassMap EquivalenceClasses; | 633 EquivalenceClassMap EquivalenceClasses; |
| 640 SizeT NumShuffled = 0, NumPreserved = 0; | 634 SizeT NumShuffled = 0, NumPreserved = 0; |
| 641 | 635 |
| 642 // Build up the equivalence classes of registers by looking at the register | 636 // Build up the equivalence classes of registers by looking at the register |
| 643 // properties as well as whether the registers should be explicitly excluded | 637 // properties as well as whether the registers should be explicitly excluded |
| 644 // from shuffling. | 638 // from shuffling. |
| 645 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 639 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
| 646 sboxres, isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, \ | 640 sboxres, isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, \ |
| 647 is16To8, isTrunc8Rcvr, isAhRcvr, aliases) \ | 641 is16To8, isTrunc8Rcvr, isAhRcvr, aliases) \ |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 689 assert(NumShuffled + NumPreserved == RegisterSet::Reg_NUM); | 683 assert(NumShuffled + NumPreserved == RegisterSet::Reg_NUM); |
| 690 | 684 |
| 691 if (Func->isVerbose(IceV_Random)) { | 685 if (Func->isVerbose(IceV_Random)) { |
| 692 OstreamLocker L(Func->getContext()); | 686 OstreamLocker L(Func->getContext()); |
| 693 Ostream &Str = Func->getContext()->getStrDump(); | 687 Ostream &Str = Func->getContext()->getStrDump(); |
| 694 Str << "Register equivalence classes:\n"; | 688 Str << "Register equivalence classes:\n"; |
| 695 for (auto I : EquivalenceClasses) { | 689 for (auto I : EquivalenceClasses) { |
| 696 Str << "{"; | 690 Str << "{"; |
| 697 const RegisterList &List = I.second; | 691 const RegisterList &List = I.second; |
| 698 bool First = true; | 692 bool First = true; |
| 699 for (int32_t Register : List) { | 693 for (RegNumT Register : List) { |
| 700 if (!First) | 694 if (!First) |
| 701 Str << " "; | 695 Str << " "; |
| 702 First = false; | 696 First = false; |
| 703 Str << getRegName(Register); | 697 Str << getRegName(Register); |
| 704 } | 698 } |
| 705 Str << "}\n"; | 699 Str << "}\n"; |
| 706 } | 700 } |
| 707 } | 701 } |
| 708 } | 702 } |
| 709 | 703 |
| 710 static int32_t getRaxOrDie() { return RegisterSet::Reg_rax; } | 704 static RegNumT getRaxOrDie() { return RegisterSet::Reg_rax; } |
| 711 | 705 |
| 712 static int32_t getRdxOrDie() { return RegisterSet::Reg_rdx; } | 706 static RegNumT getRdxOrDie() { return RegisterSet::Reg_rdx; } |
| 713 | 707 |
| 714 // x86-64 calling convention: | 708 // x86-64 calling convention: |
| 715 // | 709 // |
| 716 // * The first eight arguments of vector/fp type, regardless of their | 710 // * The first eight arguments of vector/fp type, regardless of their |
| 717 // position relative to the other arguments in the argument list, are placed | 711 // position relative to the other arguments in the argument list, are placed |
| 718 // in registers %xmm0 - %xmm7. | 712 // in registers %xmm0 - %xmm7. |
| 719 // | 713 // |
| 720 // * The first six arguments of integer types, regardless of their position | 714 // * The first six arguments of integer types, regardless of their position |
| 721 // relative to the other arguments in the argument list, are placed in | 715 // relative to the other arguments in the argument list, are placed in |
| 722 // registers %rdi, %rsi, %rdx, %rcx, %r8, and %r9. | 716 // registers %rdi, %rsi, %rdx, %rcx, %r8, and %r9. |
| 723 // | 717 // |
| 724 // This intends to match the section "Function Calling Sequence" of the | 718 // This intends to match the section "Function Calling Sequence" of the |
| 725 // document "System V Application Binary Interface." | 719 // document "System V Application Binary Interface." |
| 726 | 720 |
| 727 /// The maximum number of arguments to pass in XMM registers | 721 /// The maximum number of arguments to pass in XMM registers |
| 728 static constexpr uint32_t X86_MAX_XMM_ARGS = 8; | 722 static constexpr uint32_t X86_MAX_XMM_ARGS = 8; |
| 729 /// The maximum number of arguments to pass in GPR registers | 723 /// The maximum number of arguments to pass in GPR registers |
| 730 static constexpr uint32_t X86_MAX_GPR_ARGS = 6; | 724 static constexpr uint32_t X86_MAX_GPR_ARGS = 6; |
| 731 /// Whether scalar floating point arguments are passed in XMM registers | 725 /// Whether scalar floating point arguments are passed in XMM registers |
| 732 static constexpr bool X86_PASS_SCALAR_FP_IN_XMM = true; | 726 static constexpr bool X86_PASS_SCALAR_FP_IN_XMM = true; |
| 733 /// Get the register for a given argument slot in the XMM registers. | 727 /// Get the register for a given argument slot in the XMM registers. |
| 734 static int32_t getRegisterForXmmArgNum(uint32_t ArgNum) { | 728 static RegNumT getRegisterForXmmArgNum(uint32_t ArgNum) { |
| 735 // TODO(sehr): Change to use the CCArg technique used in ARM32. | 729 // TODO(sehr): Change to use the CCArg technique used in ARM32. |
| 736 static_assert(RegisterSet::Reg_xmm0 + 1 == RegisterSet::Reg_xmm1, | 730 static_assert(RegisterSet::Reg_xmm0 + 1 == RegisterSet::Reg_xmm1, |
| 737 "Inconsistency between XMM register numbers and ordinals"); | 731 "Inconsistency between XMM register numbers and ordinals"); |
| 738 if (ArgNum >= X86_MAX_XMM_ARGS) { | 732 if (ArgNum >= X86_MAX_XMM_ARGS) { |
| 739 return Variable::NoRegister; | 733 return RegNumT::NoRegister; |
| 740 } | 734 } |
| 741 return static_cast<int32_t>(RegisterSet::Reg_xmm0 + ArgNum); | 735 return RegNumT::fixme(RegisterSet::Reg_xmm0 + ArgNum); |
| 742 } | 736 } |
| 743 /// Get the register for a given argument slot in the GPRs. | 737 /// Get the register for a given argument slot in the GPRs. |
| 744 static int32_t getRegisterForGprArgNum(Type Ty, uint32_t ArgNum) { | 738 static RegNumT getRegisterForGprArgNum(Type Ty, uint32_t ArgNum) { |
| 745 if (ArgNum >= X86_MAX_GPR_ARGS) { | 739 if (ArgNum >= X86_MAX_GPR_ARGS) { |
| 746 return Variable::NoRegister; | 740 return RegNumT::NoRegister; |
| 747 } | 741 } |
| 748 static const RegisterSet::AllRegisters GprForArgNum[] = { | 742 static const RegisterSet::AllRegisters GprForArgNum[] = { |
| 749 RegisterSet::Reg_rdi, RegisterSet::Reg_rsi, RegisterSet::Reg_rdx, | 743 RegisterSet::Reg_rdi, RegisterSet::Reg_rsi, RegisterSet::Reg_rdx, |
| 750 RegisterSet::Reg_rcx, RegisterSet::Reg_r8, RegisterSet::Reg_r9, | 744 RegisterSet::Reg_rcx, RegisterSet::Reg_r8, RegisterSet::Reg_r9, |
| 751 }; | 745 }; |
| 752 static_assert(llvm::array_lengthof(GprForArgNum) == X86_MAX_GPR_ARGS, | 746 static_assert(llvm::array_lengthof(GprForArgNum) == X86_MAX_GPR_ARGS, |
| 753 "Mismatch between MAX_GPR_ARGS and GprForArgNum."); | 747 "Mismatch between MAX_GPR_ARGS and GprForArgNum."); |
| 754 assert(Ty == IceType_i64 || Ty == IceType_i32); | 748 assert(Ty == IceType_i64 || Ty == IceType_i32); |
| 755 return static_cast<int32_t>(getGprForType(Ty, GprForArgNum[ArgNum])); | 749 return getGprForType(Ty, GprForArgNum[ArgNum]); |
| 756 } | 750 } |
| 757 | 751 |
| 758 /// The number of bits in a byte | 752 /// The number of bits in a byte |
| 759 static constexpr uint32_t X86_CHAR_BIT = 8; | 753 static constexpr uint32_t X86_CHAR_BIT = 8; |
| 760 /// Stack alignment. This is defined in IceTargetLoweringX8664.cpp because it | 754 /// Stack alignment. This is defined in IceTargetLoweringX8664.cpp because it |
| 761 /// is used as an argument to std::max(), and the default std::less<T> has an | 755 /// is used as an argument to std::max(), and the default std::less<T> has an |
| 762 /// operator(T const&, T const&) which requires this member to have an | 756 /// operator(T const&, T const&) which requires this member to have an |
| 763 /// address. | 757 /// address. |
| 764 static const uint32_t X86_STACK_ALIGNMENT_BYTES; | 758 static const uint32_t X86_STACK_ALIGNMENT_BYTES; |
| 765 /// Size of the return address on the stack | 759 /// Size of the return address on the stack |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1038 const char *FldString; // s, l, or <blank> | 1032 const char *FldString; // s, l, or <blank> |
| 1039 } TypeAttributes[]; | 1033 } TypeAttributes[]; |
| 1040 }; | 1034 }; |
| 1041 | 1035 |
| 1042 using Traits = ::Ice::X8664::TargetX8664Traits; | 1036 using Traits = ::Ice::X8664::TargetX8664Traits; |
| 1043 } // end of namespace X8664 | 1037 } // end of namespace X8664 |
| 1044 | 1038 |
| 1045 } // end of namespace Ice | 1039 } // end of namespace Ice |
| 1046 | 1040 |
| 1047 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8664TRAITS_H | 1041 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8664TRAITS_H |
| OLD | NEW |