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