| 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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 enum ScaleFactor { TIMES_1 = 0, TIMES_2 = 1, TIMES_4 = 2, TIMES_8 = 3 }; | 61 enum ScaleFactor { TIMES_1 = 0, TIMES_2 = 1, TIMES_4 = 2, TIMES_8 = 3 }; |
| 62 | 62 |
| 63 using GPRRegister = ::Ice::RegX8632::GPRRegister; | 63 using GPRRegister = ::Ice::RegX8632::GPRRegister; |
| 64 using ByteRegister = ::Ice::RegX8632::ByteRegister; | 64 using ByteRegister = ::Ice::RegX8632::ByteRegister; |
| 65 using XmmRegister = ::Ice::RegX8632::XmmRegister; | 65 using XmmRegister = ::Ice::RegX8632::XmmRegister; |
| 66 using X87STRegister = ::Ice::RegX8632::X87STRegister; | 66 using X87STRegister = ::Ice::RegX8632::X87STRegister; |
| 67 | 67 |
| 68 using Cond = ::Ice::CondX86; | 68 using Cond = ::Ice::CondX86; |
| 69 | 69 |
| 70 using RegisterSet = ::Ice::RegX8632; | 70 using RegisterSet = ::Ice::RegX8632; |
| 71 static constexpr SizeT StackPtr = RegX8632::Reg_esp; | 71 static constexpr auto StackPtr = RegX8632::Reg_esp; |
| 72 static constexpr SizeT FramePtr = RegX8632::Reg_ebp; | 72 static constexpr auto FramePtr = RegX8632::Reg_ebp; |
| 73 static constexpr GPRRegister Encoded_Reg_Accumulator = | 73 static constexpr GPRRegister Encoded_Reg_Accumulator = |
| 74 RegX8632::Encoded_Reg_eax; | 74 RegX8632::Encoded_Reg_eax; |
| 75 static constexpr GPRRegister Encoded_Reg_Counter = RegX8632::Encoded_Reg_ecx; | 75 static constexpr GPRRegister Encoded_Reg_Counter = RegX8632::Encoded_Reg_ecx; |
| 76 static constexpr FixupKind FK_PcRel = llvm::ELF::R_386_PC32; | 76 static constexpr FixupKind FK_PcRel = llvm::ELF::R_386_PC32; |
| 77 static constexpr FixupKind FK_Abs = llvm::ELF::R_386_32; | 77 static constexpr FixupKind FK_Abs = llvm::ELF::R_386_32; |
| 78 static constexpr FixupKind FK_Gotoff = llvm::ELF::R_386_GOTOFF; | 78 static constexpr FixupKind FK_Gotoff = llvm::ELF::R_386_GOTOFF; |
| 79 static constexpr FixupKind FK_GotPC = llvm::ELF::R_386_GOTPC; | 79 static constexpr FixupKind FK_GotPC = llvm::ELF::R_386_GOTPC; |
| 80 | 80 |
| 81 class Operand { | 81 class Operand { |
| 82 public: | 82 public: |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 269 Begin, | 269 Begin, |
| 270 // SSE2 is the PNaCl baseline instruction set. | 270 // SSE2 is the PNaCl baseline instruction set. |
| 271 SSE2 = Begin, | 271 SSE2 = Begin, |
| 272 SSE4_1, | 272 SSE4_1, |
| 273 End | 273 End |
| 274 }; | 274 }; |
| 275 | 275 |
| 276 static const char *TargetName; | 276 static const char *TargetName; |
| 277 static constexpr Type WordType = IceType_i32; | 277 static constexpr Type WordType = IceType_i32; |
| 278 | 278 |
| 279 static IceString getRegName(int32_t RegNum) { | 279 static inline void assertValidRegNum(RegNumT RegNum) { |
| 280 (void)RegNum; |
| 281 assert(RegNum != RegNumT::NoRegister); |
| 282 assert(unsigned(RegNum) < RegisterSet::Reg_NUM); |
| 283 } |
| 284 |
| 285 static IceString getRegName(RegNumT RegNum) { |
| 280 static const char *const RegNames[RegisterSet::Reg_NUM] = { | 286 static const char *const RegNames[RegisterSet::Reg_NUM] = { |
| 281 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 287 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
| 282 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 288 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
| 283 isTrunc8Rcvr, isAhRcvr, aliases) \ | 289 isTrunc8Rcvr, isAhRcvr, aliases) \ |
| 284 name, | 290 name, |
| 285 REGX8632_TABLE | 291 REGX8632_TABLE |
| 286 #undef X | 292 #undef X |
| 287 }; | 293 }; |
| 288 assert(RegNum >= 0); | 294 assertValidRegNum(RegNum); |
| 289 assert(RegNum < RegisterSet::Reg_NUM); | |
| 290 return RegNames[RegNum]; | 295 return RegNames[RegNum]; |
| 291 } | 296 } |
| 292 | 297 |
| 293 static GPRRegister getEncodedGPR(int32_t RegNum) { | 298 static GPRRegister getEncodedGPR(RegNumT RegNum) { |
| 294 static const GPRRegister GPRRegs[RegisterSet::Reg_NUM] = { | 299 static const GPRRegister GPRRegs[RegisterSet::Reg_NUM] = { |
| 295 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 300 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
| 296 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 301 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
| 297 isTrunc8Rcvr, isAhRcvr, aliases) \ | 302 isTrunc8Rcvr, isAhRcvr, aliases) \ |
| 298 GPRRegister(isGPR ? encode : GPRRegister::Encoded_Not_GPR), | 303 GPRRegister(isGPR ? encode : GPRRegister::Encoded_Not_GPR), |
| 299 REGX8632_TABLE | 304 REGX8632_TABLE |
| 300 #undef X | 305 #undef X |
| 301 }; | 306 }; |
| 302 assert(RegNum >= 0); | 307 assertValidRegNum(RegNum); |
| 303 assert(RegNum < RegisterSet::Reg_NUM); | |
| 304 assert(GPRRegs[RegNum] != GPRRegister::Encoded_Not_GPR); | 308 assert(GPRRegs[RegNum] != GPRRegister::Encoded_Not_GPR); |
| 305 return GPRRegs[RegNum]; | 309 return GPRRegs[RegNum]; |
| 306 } | 310 } |
| 307 | 311 |
| 308 static ByteRegister getEncodedByteReg(int32_t RegNum) { | 312 static ByteRegister getEncodedByteReg(RegNumT RegNum) { |
| 309 static const ByteRegister ByteRegs[RegisterSet::Reg_NUM] = { | 313 static const ByteRegister ByteRegs[RegisterSet::Reg_NUM] = { |
| 310 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 314 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
| 311 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 315 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
| 312 isTrunc8Rcvr, isAhRcvr, aliases) \ | 316 isTrunc8Rcvr, isAhRcvr, aliases) \ |
| 313 ByteRegister(is8 ? encode : ByteRegister::Encoded_Not_ByteReg), | 317 ByteRegister(is8 ? encode : ByteRegister::Encoded_Not_ByteReg), |
| 314 REGX8632_TABLE | 318 REGX8632_TABLE |
| 315 #undef X | 319 #undef X |
| 316 }; | 320 }; |
| 317 assert(RegNum >= 0); | 321 assertValidRegNum(RegNum); |
| 318 assert(RegNum < RegisterSet::Reg_NUM); | |
| 319 assert(ByteRegs[RegNum] != ByteRegister::Encoded_Not_ByteReg); | 322 assert(ByteRegs[RegNum] != ByteRegister::Encoded_Not_ByteReg); |
| 320 return ByteRegs[RegNum]; | 323 return ByteRegs[RegNum]; |
| 321 } | 324 } |
| 322 | 325 |
| 323 static XmmRegister getEncodedXmm(int32_t RegNum) { | 326 static XmmRegister getEncodedXmm(RegNumT RegNum) { |
| 324 static const XmmRegister XmmRegs[RegisterSet::Reg_NUM] = { | 327 static const XmmRegister XmmRegs[RegisterSet::Reg_NUM] = { |
| 325 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 328 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
| 326 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 329 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
| 327 isTrunc8Rcvr, isAhRcvr, aliases) \ | 330 isTrunc8Rcvr, isAhRcvr, aliases) \ |
| 328 XmmRegister(isXmm ? encode : XmmRegister::Encoded_Not_Xmm), | 331 XmmRegister(isXmm ? encode : XmmRegister::Encoded_Not_Xmm), |
| 329 REGX8632_TABLE | 332 REGX8632_TABLE |
| 330 #undef X | 333 #undef X |
| 331 }; | 334 }; |
| 332 assert(RegNum >= 0); | 335 assertValidRegNum(RegNum); |
| 333 assert(RegNum < RegisterSet::Reg_NUM); | |
| 334 assert(XmmRegs[RegNum] != XmmRegister::Encoded_Not_Xmm); | 336 assert(XmmRegs[RegNum] != XmmRegister::Encoded_Not_Xmm); |
| 335 return XmmRegs[RegNum]; | 337 return XmmRegs[RegNum]; |
| 336 } | 338 } |
| 337 | 339 |
| 338 static uint32_t getEncoding(int32_t RegNum) { | 340 static uint32_t getEncoding(RegNumT RegNum) { |
| 339 static const uint32_t Encoding[RegisterSet::Reg_NUM] = { | 341 static const uint32_t Encoding[RegisterSet::Reg_NUM] = { |
| 340 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 342 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
| 341 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 343 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
| 342 isTrunc8Rcvr, isAhRcvr, aliases) \ | 344 isTrunc8Rcvr, isAhRcvr, aliases) \ |
| 343 encode, | 345 encode, |
| 344 REGX8632_TABLE | 346 REGX8632_TABLE |
| 345 #undef X | 347 #undef X |
| 346 }; | 348 }; |
| 347 assert(RegNum >= 0); | 349 assertValidRegNum(RegNum); |
| 348 assert(RegNum < RegisterSet::Reg_NUM); | |
| 349 return Encoding[RegNum]; | 350 return Encoding[RegNum]; |
| 350 } | 351 } |
| 351 | 352 |
| 352 static int32_t getBaseReg(int32_t RegNum) { | 353 static RegNumT getBaseReg(RegNumT RegNum) { |
| 353 static const int32_t BaseRegs[RegisterSet::Reg_NUM] = { | 354 static const RegNumT BaseRegs[RegisterSet::Reg_NUM] = { |
| 354 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 355 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
| 355 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 356 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
| 356 isTrunc8Rcvr, isAhRcvr, aliases) \ | 357 isTrunc8Rcvr, isAhRcvr, aliases) \ |
| 357 RegisterSet::base, | 358 RegisterSet::base, |
| 358 REGX8632_TABLE | 359 REGX8632_TABLE |
| 359 #undef X | 360 #undef X |
| 360 }; | 361 }; |
| 361 assert(RegNum >= 0); | 362 assertValidRegNum(RegNum); |
| 362 assert(RegNum < RegisterSet::Reg_NUM); | |
| 363 return BaseRegs[RegNum]; | 363 return BaseRegs[RegNum]; |
| 364 } | 364 } |
| 365 | 365 |
| 366 private: | 366 private: |
| 367 static int32_t getFirstGprForType(Type Ty) { | 367 static RegisterSet::AllRegisters getFirstGprForType(Type Ty) { |
| 368 switch (Ty) { | 368 switch (Ty) { |
| 369 default: | 369 default: |
| 370 llvm_unreachable("Invalid type for GPR."); | 370 llvm_unreachable("Invalid type for GPR."); |
| 371 case IceType_i1: | 371 case IceType_i1: |
| 372 case IceType_i8: | 372 case IceType_i8: |
| 373 return RegisterSet::Reg_al; | 373 return RegisterSet::Reg_al; |
| 374 case IceType_i16: | 374 case IceType_i16: |
| 375 return RegisterSet::Reg_ax; | 375 return RegisterSet::Reg_ax; |
| 376 case IceType_i32: | 376 case IceType_i32: |
| 377 return RegisterSet::Reg_eax; | 377 return RegisterSet::Reg_eax; |
| 378 } | 378 } |
| 379 } | 379 } |
| 380 | 380 |
| 381 public: | 381 public: |
| 382 // Return a register in RegNum's alias set that is suitable for Ty. | 382 // Return a register in RegNum's alias set that is suitable for Ty. |
| 383 static int32_t getGprForType(Type Ty, int32_t RegNum) { | 383 static RegNumT getGprForType(Type Ty, RegNumT RegNum) { |
| 384 assert(RegNum != Variable::NoRegister); | 384 assert(RegNum != RegNumT::NoRegister); |
| 385 | 385 |
| 386 if (!isScalarIntegerType(Ty)) { | 386 if (!isScalarIntegerType(Ty)) { |
| 387 return RegNum; | 387 return RegNum; |
| 388 } | 388 } |
| 389 | 389 |
| 390 // [abcd]h registers are not convertible to their ?l, ?x, and e?x versions. | 390 // [abcd]h registers are not convertible to their ?l, ?x, and e?x versions. |
| 391 switch (RegNum) { | 391 switch (RegNum) { |
| 392 default: | 392 default: |
| 393 break; | 393 break; |
| 394 case RegisterSet::Reg_ah: | 394 case RegisterSet::Reg_ah: |
| 395 case RegisterSet::Reg_bh: | 395 case RegisterSet::Reg_bh: |
| 396 case RegisterSet::Reg_ch: | 396 case RegisterSet::Reg_ch: |
| 397 case RegisterSet::Reg_dh: | 397 case RegisterSet::Reg_dh: |
| 398 assert(isByteSizedType(Ty)); | 398 assert(isByteSizedType(Ty)); |
| 399 return RegNum; | 399 return RegNum; |
| 400 } | 400 } |
| 401 | 401 |
| 402 const int32_t FirstGprForType = getFirstGprForType(Ty); | 402 const RegisterSet::AllRegisters FirstGprForType = getFirstGprForType(Ty); |
| 403 | 403 |
| 404 switch (RegNum) { | 404 switch (RegNum) { |
| 405 default: | 405 default: |
| 406 llvm::report_fatal_error("Unknown register."); | 406 llvm::report_fatal_error("Unknown register."); |
| 407 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 407 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
| 408 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 408 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
| 409 isTrunc8Rcvr, isAhRcvr, aliases) \ | 409 isTrunc8Rcvr, isAhRcvr, aliases) \ |
| 410 case RegisterSet::val: { \ | 410 case RegisterSet::val: { \ |
| 411 if (!isGPR) \ | 411 if (!isGPR) \ |
| 412 return RegisterSet::val; \ | 412 return RegisterSet::val; \ |
| 413 assert((is32) || (is16) || (is8) || \ | 413 assert((is32) || (is16) || (is8) || \ |
| 414 getBaseReg(RegisterSet::val) == RegisterSet::Reg_esp); \ | 414 getBaseReg(RegisterSet::val) == RegisterSet::Reg_esp); \ |
| 415 constexpr int32_t FirstGprWithRegNumSize = \ | 415 constexpr RegisterSet::AllRegisters FirstGprWithRegNumSize = \ |
| 416 (((is32) || RegisterSet::val == RegisterSet::Reg_esp) \ | 416 (((is32) || RegisterSet::val == RegisterSet::Reg_esp) \ |
| 417 ? RegisterSet::Reg_eax \ | 417 ? RegisterSet::Reg_eax \ |
| 418 : (((is16) || RegisterSet::val == RegisterSet::Reg_sp) \ | 418 : (((is16) || RegisterSet::val == RegisterSet::Reg_sp) \ |
| 419 ? RegisterSet::Reg_ax \ | 419 ? RegisterSet::Reg_ax \ |
| 420 : RegisterSet::Reg_al)); \ | 420 : RegisterSet::Reg_al)); \ |
| 421 const int32_t NewRegNum = \ | 421 const RegNumT NewRegNum = \ |
| 422 RegNum - FirstGprWithRegNumSize + FirstGprForType; \ | 422 RegNumT::fixme(RegNum - FirstGprWithRegNumSize + FirstGprForType); \ |
| 423 assert(getBaseReg(RegNum) == getBaseReg(NewRegNum) && \ | 423 assert(getBaseReg(RegNum) == getBaseReg(NewRegNum) && \ |
| 424 "Error involving " #val); \ | 424 "Error involving " #val); \ |
| 425 return NewRegNum; \ | 425 return NewRegNum; \ |
| 426 } | 426 } |
| 427 REGX8632_TABLE | 427 REGX8632_TABLE |
| 428 #undef X | 428 #undef X |
| 429 } | 429 } |
| 430 } | 430 } |
| 431 | 431 |
| 432 private: | 432 private: |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 | 573 |
| 574 REGX8632_TABLE | 574 REGX8632_TABLE |
| 575 | 575 |
| 576 #undef X | 576 #undef X |
| 577 | 577 |
| 578 return Registers; | 578 return Registers; |
| 579 } | 579 } |
| 580 | 580 |
| 581 static void | 581 static void |
| 582 makeRandomRegisterPermutation(GlobalContext *Ctx, Cfg *Func, | 582 makeRandomRegisterPermutation(GlobalContext *Ctx, Cfg *Func, |
| 583 llvm::SmallVectorImpl<int32_t> &Permutation, | 583 llvm::SmallVectorImpl<RegNumT> &Permutation, |
| 584 const llvm::SmallBitVector &ExcludeRegisters, | 584 const llvm::SmallBitVector &ExcludeRegisters, |
| 585 uint64_t Salt) { | 585 uint64_t Salt) { |
| 586 // TODO(stichnot): Declaring Permutation this way loses type/size | 586 // TODO(stichnot): Declaring Permutation this way loses type/size |
| 587 // information. Fix this in conjunction with the caller-side TODO. | 587 // information. Fix this in conjunction with the caller-side TODO. |
| 588 assert(Permutation.size() >= RegisterSet::Reg_NUM); | 588 assert(Permutation.size() >= RegisterSet::Reg_NUM); |
| 589 // Expected upper bound on the number of registers in a single equivalence | 589 // Expected upper bound on the number of registers in a single equivalence |
| 590 // class. For x86-32, this would comprise the 8 XMM registers. This is for | 590 // class. For x86-32, this would comprise the 8 XMM registers. This is for |
| 591 // performance, not correctness. | 591 // performance, not correctness. |
| 592 static const unsigned MaxEquivalenceClassSize = 8; | 592 static const unsigned MaxEquivalenceClassSize = 8; |
| 593 using RegisterList = llvm::SmallVector<int32_t, MaxEquivalenceClassSize>; | 593 using RegisterList = llvm::SmallVector<RegNumT, MaxEquivalenceClassSize>; |
| 594 using EquivalenceClassMap = std::map<uint32_t, RegisterList>; | 594 using EquivalenceClassMap = std::map<uint32_t, RegisterList>; |
| 595 EquivalenceClassMap EquivalenceClasses; | 595 EquivalenceClassMap EquivalenceClasses; |
| 596 SizeT NumShuffled = 0, NumPreserved = 0; | 596 SizeT NumShuffled = 0, NumPreserved = 0; |
| 597 | 597 |
| 598 // Build up the equivalence classes of registers by looking at the register | 598 // Build up the equivalence classes of registers by looking at the register |
| 599 // properties as well as whether the registers should be explicitly excluded | 599 // properties as well as whether the registers should be explicitly excluded |
| 600 // from shuffling. | 600 // from shuffling. |
| 601 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ | 601 #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ |
| 602 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ | 602 isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ |
| 603 isTrunc8Rcvr, isAhRcvr, aliases) \ | 603 isTrunc8Rcvr, isAhRcvr, aliases) \ |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 645 assert(NumShuffled + NumPreserved == RegisterSet::Reg_NUM); | 645 assert(NumShuffled + NumPreserved == RegisterSet::Reg_NUM); |
| 646 | 646 |
| 647 if (Func->isVerbose(IceV_Random)) { | 647 if (Func->isVerbose(IceV_Random)) { |
| 648 OstreamLocker L(Func->getContext()); | 648 OstreamLocker L(Func->getContext()); |
| 649 Ostream &Str = Func->getContext()->getStrDump(); | 649 Ostream &Str = Func->getContext()->getStrDump(); |
| 650 Str << "Register equivalence classes:\n"; | 650 Str << "Register equivalence classes:\n"; |
| 651 for (auto I : EquivalenceClasses) { | 651 for (auto I : EquivalenceClasses) { |
| 652 Str << "{"; | 652 Str << "{"; |
| 653 const RegisterList &List = I.second; | 653 const RegisterList &List = I.second; |
| 654 bool First = true; | 654 bool First = true; |
| 655 for (int32_t Register : List) { | 655 for (RegNumT Register : List) { |
| 656 if (!First) | 656 if (!First) |
| 657 Str << " "; | 657 Str << " "; |
| 658 First = false; | 658 First = false; |
| 659 Str << getRegName(Register); | 659 Str << getRegName(Register); |
| 660 } | 660 } |
| 661 Str << "}\n"; | 661 Str << "}\n"; |
| 662 } | 662 } |
| 663 } | 663 } |
| 664 } | 664 } |
| 665 | 665 |
| 666 static int32_t getRaxOrDie() { | 666 static RegNumT getRaxOrDie() { |
| 667 llvm::report_fatal_error("no rax in non-64-bit mode."); | 667 llvm::report_fatal_error("no rax in non-64-bit mode."); |
| 668 } | 668 } |
| 669 | 669 |
| 670 static int32_t getRdxOrDie() { | 670 static RegNumT getRdxOrDie() { |
| 671 llvm::report_fatal_error("no rdx in non-64-bit mode."); | 671 llvm::report_fatal_error("no rdx in non-64-bit mode."); |
| 672 } | 672 } |
| 673 | 673 |
| 674 // x86-32 calling convention: | 674 // x86-32 calling convention: |
| 675 // | 675 // |
| 676 // * The first four arguments of vector type, regardless of their position | 676 // * The first four arguments of vector type, regardless of their position |
| 677 // relative to the other arguments in the argument list, are placed in | 677 // relative to the other arguments in the argument list, are placed in |
| 678 // registers xmm0 - xmm3. | 678 // registers xmm0 - xmm3. |
| 679 // | 679 // |
| 680 // This intends to match the section "IA-32 Function Calling Convention" of | 680 // This intends to match the section "IA-32 Function Calling Convention" of |
| 681 // the document "OS X ABI Function Call Guide" by Apple. | 681 // the document "OS X ABI Function Call Guide" by Apple. |
| 682 | 682 |
| 683 /// The maximum number of arguments to pass in XMM registers | 683 /// The maximum number of arguments to pass in XMM registers |
| 684 static constexpr uint32_t X86_MAX_XMM_ARGS = 4; | 684 static constexpr uint32_t X86_MAX_XMM_ARGS = 4; |
| 685 /// The maximum number of arguments to pass in GPR registers | 685 /// The maximum number of arguments to pass in GPR registers |
| 686 static constexpr uint32_t X86_MAX_GPR_ARGS = 0; | 686 static constexpr uint32_t X86_MAX_GPR_ARGS = 0; |
| 687 /// Whether scalar floating point arguments are passed in XMM registers | 687 /// Whether scalar floating point arguments are passed in XMM registers |
| 688 static constexpr bool X86_PASS_SCALAR_FP_IN_XMM = false; | 688 static constexpr bool X86_PASS_SCALAR_FP_IN_XMM = false; |
| 689 /// Get the register for a given argument slot in the XMM registers. | 689 /// Get the register for a given argument slot in the XMM registers. |
| 690 static int32_t getRegisterForXmmArgNum(uint32_t ArgNum) { | 690 static RegNumT getRegisterForXmmArgNum(uint32_t ArgNum) { |
| 691 // TODO(sehr): Change to use the CCArg technique used in ARM32. | 691 // TODO(sehr): Change to use the CCArg technique used in ARM32. |
| 692 static_assert(RegisterSet::Reg_xmm0 + 1 == RegisterSet::Reg_xmm1, | 692 static_assert(RegisterSet::Reg_xmm0 + 1 == RegisterSet::Reg_xmm1, |
| 693 "Inconsistency between XMM register numbers and ordinals"); | 693 "Inconsistency between XMM register numbers and ordinals"); |
| 694 if (ArgNum >= X86_MAX_XMM_ARGS) { | 694 if (ArgNum >= X86_MAX_XMM_ARGS) { |
| 695 return Variable::NoRegister; | 695 return RegNumT::NoRegister; |
| 696 } | 696 } |
| 697 return static_cast<int32_t>(RegisterSet::Reg_xmm0 + ArgNum); | 697 return RegNumT::fixme(RegisterSet::Reg_xmm0 + ArgNum); |
| 698 } | 698 } |
| 699 /// Get the register for a given argument slot in the GPRs. | 699 /// Get the register for a given argument slot in the GPRs. |
| 700 static int32_t getRegisterForGprArgNum(Type Ty, uint32_t ArgNum) { | 700 static RegNumT getRegisterForGprArgNum(Type Ty, uint32_t ArgNum) { |
| 701 assert(Ty == IceType_i64 || Ty == IceType_i32); | 701 assert(Ty == IceType_i64 || Ty == IceType_i32); |
| 702 (void)Ty; | 702 (void)Ty; |
| 703 (void)ArgNum; | 703 (void)ArgNum; |
| 704 return Variable::NoRegister; | 704 return RegNumT::NoRegister; |
| 705 } | 705 } |
| 706 | 706 |
| 707 /// The number of bits in a byte | 707 /// The number of bits in a byte |
| 708 static constexpr uint32_t X86_CHAR_BIT = 8; | 708 static constexpr uint32_t X86_CHAR_BIT = 8; |
| 709 /// Stack alignment. This is defined in IceTargetLoweringX8632.cpp because it | 709 /// Stack alignment. This is defined in IceTargetLoweringX8632.cpp because it |
| 710 /// is used as an argument to std::max(), and the default std::less<T> has an | 710 /// is used as an argument to std::max(), and the default std::less<T> has an |
| 711 /// operator(T const&, T const&) which requires this member to have an | 711 /// operator(T const&, T const&) which requires this member to have an |
| 712 /// address. | 712 /// address. |
| 713 static const uint32_t X86_STACK_ALIGNMENT_BYTES; | 713 static const uint32_t X86_STACK_ALIGNMENT_BYTES; |
| 714 /// Size of the return address on the stack | 714 /// Size of the return address on the stack |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 997 | 997 |
| 998 static uint8_t InstSegmentPrefixes[]; | 998 static uint8_t InstSegmentPrefixes[]; |
| 999 }; | 999 }; |
| 1000 | 1000 |
| 1001 using Traits = ::Ice::X8632::TargetX8632Traits; | 1001 using Traits = ::Ice::X8632::TargetX8632Traits; |
| 1002 } // end of namespace X8632 | 1002 } // end of namespace X8632 |
| 1003 | 1003 |
| 1004 } // end of namespace Ice | 1004 } // end of namespace Ice |
| 1005 | 1005 |
| 1006 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8632TRAITS_H | 1006 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8632TRAITS_H |
| OLD | NEW |