| OLD | NEW |
| 1 //===- subzero/src/IceAssemblerX86Base.h - base x86 assembler -*- C++ -*---===// | 1 //===- subzero/src/IceAssemblerX86Base.h - base x86 assembler -*- C++ -*---===// |
| 2 // | 2 // |
| 3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 4 // for details. All rights reserved. Use of this source code is governed by a | 4 // for details. All rights reserved. Use of this source code is governed by a |
| 5 // BSD-style license that can be found in the LICENSE file. | 5 // BSD-style license that can be found in the LICENSE file. |
| 6 // | 6 // |
| 7 // Modified by the Subzero authors. | 7 // Modified by the Subzero authors. |
| 8 // | 8 // |
| 9 //===----------------------------------------------------------------------===// | 9 //===----------------------------------------------------------------------===// |
| 10 // | 10 // |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 | 307 |
| 308 TypedEmitRegRegImm RegRegImm; | 308 TypedEmitRegRegImm RegRegImm; |
| 309 TypedEmitRegAddrImm RegAddrImm; | 309 TypedEmitRegAddrImm RegAddrImm; |
| 310 }; | 310 }; |
| 311 | 311 |
| 312 /* | 312 /* |
| 313 * Emit Machine Instructions. | 313 * Emit Machine Instructions. |
| 314 */ | 314 */ |
| 315 void call(typename Traits::GPRRegister reg); | 315 void call(typename Traits::GPRRegister reg); |
| 316 void call(const typename Traits::Address &address); | 316 void call(const typename Traits::Address &address); |
| 317 void call(const ConstantRelocatable *label); | 317 void call(const ConstantRelocatable *label); // not testable. |
| 318 void call(const Immediate &abs_address); | 318 void call(const Immediate &abs_address); |
| 319 | 319 |
| 320 static const intptr_t kCallExternalLabelSize = 5; | 320 static const intptr_t kCallExternalLabelSize = 5; |
| 321 | 321 |
| 322 void pushl(typename Traits::GPRRegister reg); | 322 void pushl(typename Traits::GPRRegister reg); |
| 323 | 323 |
| 324 void popl(typename Traits::GPRRegister reg); | 324 void popl(typename Traits::GPRRegister reg); |
| 325 void popl(const typename Traits::Address &address); | 325 void popl(const typename Traits::Address &address); |
| 326 | 326 |
| 327 template <typename T = Traits, |
| 328 typename = typename std::enable_if<T::HasPusha>::type> |
| 327 void pushal(); | 329 void pushal(); |
| 330 template <typename T = Traits, |
| 331 typename = typename std::enable_if<T::HasPopa>::type> |
| 328 void popal(); | 332 void popal(); |
| 329 | 333 |
| 330 void setcc(typename Traits::Cond::BrCond condition, | 334 void setcc(typename Traits::Cond::BrCond condition, |
| 331 typename Traits::ByteRegister dst); | 335 typename Traits::ByteRegister dst); |
| 332 void setcc(typename Traits::Cond::BrCond condition, | 336 void setcc(typename Traits::Cond::BrCond condition, |
| 333 const typename Traits::Address &address); | 337 const typename Traits::Address &address); |
| 334 | 338 |
| 335 // All mov() overloads are tested. | |
| 336 void mov(Type Ty, typename Traits::GPRRegister dst, const Immediate &src); | 339 void mov(Type Ty, typename Traits::GPRRegister dst, const Immediate &src); |
| 337 void mov(Type Ty, typename Traits::GPRRegister dst, | 340 void mov(Type Ty, typename Traits::GPRRegister dst, |
| 338 typename Traits::GPRRegister src); | 341 typename Traits::GPRRegister src); |
| 339 void mov(Type Ty, typename Traits::GPRRegister dst, | 342 void mov(Type Ty, typename Traits::GPRRegister dst, |
| 340 const typename Traits::Address &src); | 343 const typename Traits::Address &src); |
| 341 void mov(Type Ty, const typename Traits::Address &dst, | 344 void mov(Type Ty, const typename Traits::Address &dst, |
| 342 typename Traits::GPRRegister src); | 345 typename Traits::GPRRegister src); |
| 343 void mov(Type Ty, const typename Traits::Address &dst, const Immediate &imm); | 346 void mov(Type Ty, const typename Traits::Address &dst, const Immediate &imm); |
| 344 | 347 |
| 348 void movFromAh(const typename Traits::GPRRegister dst); |
| 349 |
| 345 void movzx(Type Ty, typename Traits::GPRRegister dst, | 350 void movzx(Type Ty, typename Traits::GPRRegister dst, |
| 346 typename Traits::GPRRegister src); | 351 typename Traits::GPRRegister src); |
| 347 void movzx(Type Ty, typename Traits::GPRRegister dst, | 352 void movzx(Type Ty, typename Traits::GPRRegister dst, |
| 348 const typename Traits::Address &src); | 353 const typename Traits::Address &src); |
| 349 void movsx(Type Ty, typename Traits::GPRRegister dst, | 354 void movsx(Type Ty, typename Traits::GPRRegister dst, |
| 350 typename Traits::GPRRegister src); | 355 typename Traits::GPRRegister src); |
| 351 void movsx(Type Ty, typename Traits::GPRRegister dst, | 356 void movsx(Type Ty, typename Traits::GPRRegister dst, |
| 352 const typename Traits::Address &src); | 357 const typename Traits::Address &src); |
| 353 | 358 |
| 354 void lea(Type Ty, typename Traits::GPRRegister dst, | 359 void lea(Type Ty, typename Traits::GPRRegister dst, |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 496 | 501 |
| 497 void cmpps(typename Traits::XmmRegister dst, typename Traits::XmmRegister src, | 502 void cmpps(typename Traits::XmmRegister dst, typename Traits::XmmRegister src, |
| 498 typename Traits::Cond::CmppsCond CmpCondition); | 503 typename Traits::Cond::CmppsCond CmpCondition); |
| 499 void cmpps(typename Traits::XmmRegister dst, | 504 void cmpps(typename Traits::XmmRegister dst, |
| 500 const typename Traits::Address &src, | 505 const typename Traits::Address &src, |
| 501 typename Traits::Cond::CmppsCond CmpCondition); | 506 typename Traits::Cond::CmppsCond CmpCondition); |
| 502 | 507 |
| 503 void sqrtps(typename Traits::XmmRegister dst); | 508 void sqrtps(typename Traits::XmmRegister dst); |
| 504 void rsqrtps(typename Traits::XmmRegister dst); | 509 void rsqrtps(typename Traits::XmmRegister dst); |
| 505 void reciprocalps(typename Traits::XmmRegister dst); | 510 void reciprocalps(typename Traits::XmmRegister dst); |
| 511 |
| 506 void movhlps(typename Traits::XmmRegister dst, | 512 void movhlps(typename Traits::XmmRegister dst, |
| 507 typename Traits::XmmRegister src); | 513 typename Traits::XmmRegister src); |
| 508 void movlhps(typename Traits::XmmRegister dst, | 514 void movlhps(typename Traits::XmmRegister dst, |
| 509 typename Traits::XmmRegister src); | 515 typename Traits::XmmRegister src); |
| 510 void unpcklps(typename Traits::XmmRegister dst, | 516 void unpcklps(typename Traits::XmmRegister dst, |
| 511 typename Traits::XmmRegister src); | 517 typename Traits::XmmRegister src); |
| 512 void unpckhps(typename Traits::XmmRegister dst, | 518 void unpckhps(typename Traits::XmmRegister dst, |
| 513 typename Traits::XmmRegister src); | 519 typename Traits::XmmRegister src); |
| 514 void unpcklpd(typename Traits::XmmRegister dst, | 520 void unpcklpd(typename Traits::XmmRegister dst, |
| 515 typename Traits::XmmRegister src); | 521 typename Traits::XmmRegister src); |
| 516 void unpckhpd(typename Traits::XmmRegister dst, | 522 void unpckhpd(typename Traits::XmmRegister dst, |
| 517 typename Traits::XmmRegister src); | 523 typename Traits::XmmRegister src); |
| 518 | 524 |
| 519 void set1ps(typename Traits::XmmRegister dst, | 525 void set1ps(typename Traits::XmmRegister dst, |
| 520 typename Traits::GPRRegister tmp, const Immediate &imm); | 526 typename Traits::GPRRegister tmp, const Immediate &imm); |
| 521 void shufps(typename Traits::XmmRegister dst, | |
| 522 typename Traits::XmmRegister src, const Immediate &mask); | |
| 523 | 527 |
| 524 void minpd(typename Traits::XmmRegister dst, | 528 void minpd(typename Traits::XmmRegister dst, |
| 525 typename Traits::XmmRegister src); | 529 typename Traits::XmmRegister src); |
| 526 void maxpd(typename Traits::XmmRegister dst, | 530 void maxpd(typename Traits::XmmRegister dst, |
| 527 typename Traits::XmmRegister src); | 531 typename Traits::XmmRegister src); |
| 528 void sqrtpd(typename Traits::XmmRegister dst); | 532 void sqrtpd(typename Traits::XmmRegister dst); |
| 529 void shufpd(typename Traits::XmmRegister dst, | 533 |
| 530 typename Traits::XmmRegister src, const Immediate &mask); | 534 /* |
| 535 void shufpd(typename Traits::XmmRegister dst, |
| 536 typename Traits::XmmRegister src, const Immediate &mask); |
| 537 */ |
| 531 | 538 |
| 532 void pshufd(Type Ty, typename Traits::XmmRegister dst, | 539 void pshufd(Type Ty, typename Traits::XmmRegister dst, |
| 533 typename Traits::XmmRegister src, const Immediate &mask); | 540 typename Traits::XmmRegister src, const Immediate &mask); |
| 534 void pshufd(Type Ty, typename Traits::XmmRegister dst, | 541 void pshufd(Type Ty, typename Traits::XmmRegister dst, |
| 535 const typename Traits::Address &src, const Immediate &mask); | 542 const typename Traits::Address &src, const Immediate &mask); |
| 536 void shufps(Type Ty, typename Traits::XmmRegister dst, | 543 void shufps(Type Ty, typename Traits::XmmRegister dst, |
| 537 typename Traits::XmmRegister src, const Immediate &mask); | 544 typename Traits::XmmRegister src, const Immediate &mask); |
| 538 void shufps(Type Ty, typename Traits::XmmRegister dst, | 545 void shufps(Type Ty, typename Traits::XmmRegister dst, |
| 539 const typename Traits::Address &src, const Immediate &mask); | 546 const typename Traits::Address &src, const Immediate &mask); |
| 540 | 547 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 599 void insertps(Type Ty, typename Traits::XmmRegister dst, | 606 void insertps(Type Ty, typename Traits::XmmRegister dst, |
| 600 const typename Traits::Address &src, const Immediate &imm); | 607 const typename Traits::Address &src, const Immediate &imm); |
| 601 | 608 |
| 602 void pinsr(Type Ty, typename Traits::XmmRegister dst, | 609 void pinsr(Type Ty, typename Traits::XmmRegister dst, |
| 603 typename Traits::GPRRegister src, const Immediate &imm); | 610 typename Traits::GPRRegister src, const Immediate &imm); |
| 604 void pinsr(Type Ty, typename Traits::XmmRegister dst, | 611 void pinsr(Type Ty, typename Traits::XmmRegister dst, |
| 605 const typename Traits::Address &src, const Immediate &imm); | 612 const typename Traits::Address &src, const Immediate &imm); |
| 606 | 613 |
| 607 void pextr(Type Ty, typename Traits::GPRRegister dst, | 614 void pextr(Type Ty, typename Traits::GPRRegister dst, |
| 608 typename Traits::XmmRegister src, const Immediate &imm); | 615 typename Traits::XmmRegister src, const Immediate &imm); |
| 609 void pextr(Type Ty, typename Traits::GPRRegister dst, | |
| 610 const typename Traits::Address &src, const Immediate &imm); | |
| 611 | 616 |
| 612 void pmovsxdq(typename Traits::XmmRegister dst, | 617 void pmovsxdq(typename Traits::XmmRegister dst, |
| 613 typename Traits::XmmRegister src); | 618 typename Traits::XmmRegister src); |
| 614 | 619 |
| 615 void pcmpeq(Type Ty, typename Traits::XmmRegister dst, | 620 void pcmpeq(Type Ty, typename Traits::XmmRegister dst, |
| 616 typename Traits::XmmRegister src); | 621 typename Traits::XmmRegister src); |
| 617 void pcmpeq(Type Ty, typename Traits::XmmRegister dst, | 622 void pcmpeq(Type Ty, typename Traits::XmmRegister dst, |
| 618 const typename Traits::Address &src); | 623 const typename Traits::Address &src); |
| 619 void pcmpgt(Type Ty, typename Traits::XmmRegister dst, | 624 void pcmpgt(Type Ty, typename Traits::XmmRegister dst, |
| 620 typename Traits::XmmRegister src); | 625 typename Traits::XmmRegister src); |
| 621 void pcmpgt(Type Ty, typename Traits::XmmRegister dst, | 626 void pcmpgt(Type Ty, typename Traits::XmmRegister dst, |
| 622 const typename Traits::Address &src); | 627 const typename Traits::Address &src); |
| 623 | 628 |
| 624 enum RoundingMode { | 629 enum RoundingMode { |
| 625 kRoundToNearest = 0x0, | 630 kRoundToNearest = 0x0, |
| 626 kRoundDown = 0x1, | 631 kRoundDown = 0x1, |
| 627 kRoundUp = 0x2, | 632 kRoundUp = 0x2, |
| 628 kRoundToZero = 0x3 | 633 kRoundToZero = 0x3 |
| 629 }; | 634 }; |
| 630 void roundsd(typename Traits::XmmRegister dst, | 635 void roundsd(typename Traits::XmmRegister dst, |
| 631 typename Traits::XmmRegister src, RoundingMode mode); | 636 typename Traits::XmmRegister src, RoundingMode mode); |
| 632 | 637 |
| 633 void fld(Type Ty, const typename Traits::Address &src); | 638 //---------------------------------------------------------------------------- |
| 634 void fstp(Type Ty, const typename Traits::Address &dst); | 639 // |
| 635 void fstp(typename Traits::X87STRegister st); | 640 // Begin: X87 instructions. Only available when Traits::UsesX87. |
| 641 // |
| 642 //---------------------------------------------------------------------------- |
| 643 template <typename T = Traits, |
| 644 typename = typename std::enable_if<T::UsesX87>::type> |
| 645 void fld(Type Ty, const typename T::Address &src); |
| 646 template <typename T = Traits, |
| 647 typename = typename std::enable_if<T::UsesX87>::type> |
| 648 void fstp(Type Ty, const typename T::Address &dst); |
| 649 template <typename T = Traits, |
| 650 typename = typename std::enable_if<T::UsesX87>::type> |
| 651 void fstp(typename T::X87STRegister st); |
| 636 | 652 |
| 637 void fnstcw(const typename Traits::Address &dst); | 653 template <typename T = Traits, |
| 638 void fldcw(const typename Traits::Address &src); | 654 typename = typename std::enable_if<T::UsesX87>::type> |
| 655 void fnstcw(const typename T::Address &dst); |
| 656 template <typename T = Traits, |
| 657 typename = typename std::enable_if<T::UsesX87>::type> |
| 658 void fldcw(const typename T::Address &src); |
| 639 | 659 |
| 640 void fistpl(const typename Traits::Address &dst); | 660 template <typename T = Traits, |
| 641 void fistps(const typename Traits::Address &dst); | 661 typename = typename std::enable_if<T::UsesX87>::type> |
| 642 void fildl(const typename Traits::Address &src); | 662 void fistpl(const typename T::Address &dst); |
| 643 void filds(const typename Traits::Address &src); | 663 template <typename T = Traits, |
| 664 typename = typename std::enable_if<T::UsesX87>::type> |
| 665 void fistps(const typename T::Address &dst); |
| 666 template <typename T = Traits, |
| 667 typename = typename std::enable_if<T::UsesX87>::type> |
| 668 void fildl(const typename T::Address &src); |
| 669 template <typename T = Traits, |
| 670 typename = typename std::enable_if<T::UsesX87>::type> |
| 671 void filds(const typename T::Address &src); |
| 644 | 672 |
| 673 template <typename T = Traits, |
| 674 typename = typename std::enable_if<T::UsesX87>::type> |
| 645 void fincstp(); | 675 void fincstp(); |
| 676 //---------------------------------------------------------------------------- |
| 677 // |
| 678 // End: X87 instructions. |
| 679 // |
| 680 //---------------------------------------------------------------------------- |
| 646 | 681 |
| 647 void cmp(Type Ty, typename Traits::GPRRegister reg0, | 682 void cmp(Type Ty, typename Traits::GPRRegister reg0, |
| 648 typename Traits::GPRRegister reg1); | 683 typename Traits::GPRRegister reg1); |
| 649 void cmp(Type Ty, typename Traits::GPRRegister reg, | 684 void cmp(Type Ty, typename Traits::GPRRegister reg, |
| 650 const typename Traits::Address &address); | 685 const typename Traits::Address &address); |
| 651 void cmp(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm); | 686 void cmp(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm); |
| 652 void cmp(Type Ty, const typename Traits::Address &address, | 687 void cmp(Type Ty, const typename Traits::Address &address, |
| 653 typename Traits::GPRRegister reg); | 688 typename Traits::GPRRegister reg); |
| 654 void cmp(Type Ty, const typename Traits::Address &address, | 689 void cmp(Type Ty, const typename Traits::Address &address, |
| 655 const Immediate &imm); | 690 const Immediate &imm); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 747 void imul(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm); | 782 void imul(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm); |
| 748 void imul(Type Ty, typename Traits::GPRRegister reg, | 783 void imul(Type Ty, typename Traits::GPRRegister reg, |
| 749 const typename Traits::Address &address); | 784 const typename Traits::Address &address); |
| 750 | 785 |
| 751 void imul(Type Ty, typename Traits::GPRRegister reg); | 786 void imul(Type Ty, typename Traits::GPRRegister reg); |
| 752 void imul(Type Ty, const typename Traits::Address &address); | 787 void imul(Type Ty, const typename Traits::Address &address); |
| 753 | 788 |
| 754 void mul(Type Ty, typename Traits::GPRRegister reg); | 789 void mul(Type Ty, typename Traits::GPRRegister reg); |
| 755 void mul(Type Ty, const typename Traits::Address &address); | 790 void mul(Type Ty, const typename Traits::Address &address); |
| 756 | 791 |
| 792 template <class T = Traits, |
| 793 typename = typename std::enable_if<!T::Is64Bit>::type> |
| 757 void incl(typename Traits::GPRRegister reg); | 794 void incl(typename Traits::GPRRegister reg); |
| 758 void incl(const typename Traits::Address &address); | 795 void incl(const typename Traits::Address &address); |
| 759 | 796 |
| 797 template <class T = Traits, |
| 798 typename = typename std::enable_if<!T::Is64Bit>::type> |
| 760 void decl(typename Traits::GPRRegister reg); | 799 void decl(typename Traits::GPRRegister reg); |
| 761 void decl(const typename Traits::Address &address); | 800 void decl(const typename Traits::Address &address); |
| 762 | 801 |
| 763 void rol(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm); | 802 void rol(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm); |
| 764 void rol(Type Ty, typename Traits::GPRRegister operand, | 803 void rol(Type Ty, typename Traits::GPRRegister operand, |
| 765 typename Traits::GPRRegister shifter); | 804 typename Traits::GPRRegister shifter); |
| 766 void rol(Type Ty, const typename Traits::Address &operand, | 805 void rol(Type Ty, const typename Traits::Address &operand, |
| 767 typename Traits::GPRRegister shifter); | 806 typename Traits::GPRRegister shifter); |
| 768 | 807 |
| 769 void shl(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm); | 808 void shl(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 818 void ret(); | 857 void ret(); |
| 819 void ret(const Immediate &imm); | 858 void ret(const Immediate &imm); |
| 820 | 859 |
| 821 // 'size' indicates size in bytes and must be in the range 1..8. | 860 // 'size' indicates size in bytes and must be in the range 1..8. |
| 822 void nop(int size = 1); | 861 void nop(int size = 1); |
| 823 void int3(); | 862 void int3(); |
| 824 void hlt(); | 863 void hlt(); |
| 825 void ud2(); | 864 void ud2(); |
| 826 | 865 |
| 827 // j(Label) is fully tested. | 866 // j(Label) is fully tested. |
| 828 // j(ConstantRelocatable) is not tested as the test can not easily create such | |
| 829 // an argument. | |
| 830 void j(typename Traits::Cond::BrCond condition, Label *label, | 867 void j(typename Traits::Cond::BrCond condition, Label *label, |
| 831 bool near = kFarJump); | 868 bool near = kFarJump); |
| 832 void j(typename Traits::Cond::BrCond condition, | 869 void j(typename Traits::Cond::BrCond condition, |
| 833 const ConstantRelocatable *label); | 870 const ConstantRelocatable *label); // not testable. |
| 834 | 871 |
| 835 void jmp(typename Traits::GPRRegister reg); | 872 void jmp(typename Traits::GPRRegister reg); |
| 836 void jmp(Label *label, bool near = kFarJump); | 873 void jmp(Label *label, bool near = kFarJump); |
| 837 void jmp(const ConstantRelocatable *label); | 874 void jmp(const ConstantRelocatable *label); // not testable. |
| 838 | 875 |
| 839 void mfence(); | 876 void mfence(); |
| 840 | 877 |
| 841 void lock(); | 878 void lock(); |
| 842 void cmpxchg(Type Ty, const typename Traits::Address &address, | 879 void cmpxchg(Type Ty, const typename Traits::Address &address, |
| 843 typename Traits::GPRRegister reg, bool Locked); | 880 typename Traits::GPRRegister reg, bool Locked); |
| 844 void cmpxchg8b(const typename Traits::Address &address, bool Locked); | 881 void cmpxchg8b(const typename Traits::Address &address, bool Locked); |
| 845 void xadd(Type Ty, const typename Traits::Address &address, | 882 void xadd(Type Ty, const typename Traits::Address &address, |
| 846 typename Traits::GPRRegister reg, bool Locked); | 883 typename Traits::GPRRegister reg, bool Locked); |
| 847 void xchg(Type Ty, const typename Traits::Address &address, | 884 void xchg(Type Ty, const typename Traits::Address &address, |
| 848 typename Traits::GPRRegister reg); | 885 typename Traits::GPRRegister reg); |
| 849 | 886 |
| 850 void emitSegmentOverride(uint8_t prefix); | 887 void emitSegmentOverride(uint8_t prefix); |
| 851 | 888 |
| 852 intptr_t preferredLoopAlignment() { return 16; } | 889 intptr_t preferredLoopAlignment() { return 16; } |
| 853 void align(intptr_t alignment, intptr_t offset); | 890 void align(intptr_t alignment, intptr_t offset); |
| 854 void bind(Label *label); | 891 void bind(Label *label); |
| 855 | 892 |
| 856 intptr_t CodeSize() const { return Buffer.size(); } | 893 intptr_t CodeSize() const { return Buffer.size(); } |
| 857 | 894 |
| 895 protected: |
| 896 inline void emitUint8(uint8_t value); |
| 897 |
| 858 private: | 898 private: |
| 859 inline void emitUint8(uint8_t value); | 899 static constexpr Type IceType_Irrelevant = IceType_i32; |
| 900 static constexpr Type IceType_ForceRexW = IceType_i64; |
| 901 static constexpr typename Traits::GPRRegister Encoded_Reg_Irrelevant = |
| 902 Traits::GPRRegister::Encoded_Reg_eax; |
| 903 |
| 860 inline void emitInt16(int16_t value); | 904 inline void emitInt16(int16_t value); |
| 861 inline void emitInt32(int32_t value); | 905 inline void emitInt32(int32_t value); |
| 862 inline void emitRegisterOperand(int rm, int reg); | 906 inline void emitRegisterOperand(int rm, int reg); |
| 863 inline void emitXmmRegisterOperand(int rm, typename Traits::XmmRegister reg); | 907 template <typename RegType, typename RmType> |
| 908 inline void emitXmmRegisterOperand(RegType reg, RmType rm); |
| 864 inline void emitFixup(AssemblerFixup *fixup); | 909 inline void emitFixup(AssemblerFixup *fixup); |
| 865 inline void emitOperandSizeOverride(); | 910 inline void emitOperandSizeOverride(); |
| 866 | 911 |
| 867 void emitOperand(int rm, const typename Traits::Operand &operand); | 912 void emitOperand(int rm, const typename Traits::Operand &operand); |
| 868 void emitImmediate(Type ty, const Immediate &imm); | 913 void emitImmediate(Type ty, const Immediate &imm); |
| 869 void emitComplexI8(int rm, const typename Traits::Operand &operand, | 914 void emitComplexI8(int rm, const typename Traits::Operand &operand, |
| 870 const Immediate &immediate); | 915 const Immediate &immediate); |
| 871 void emitComplex(Type Ty, int rm, const typename Traits::Operand &operand, | 916 void emitComplex(Type Ty, int rm, const typename Traits::Operand &operand, |
| 872 const Immediate &immediate); | 917 const Immediate &immediate); |
| 873 void emitLabel(Label *label, intptr_t instruction_size); | 918 void emitLabel(Label *label, intptr_t instruction_size); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 903 void arith_int(Type Ty, typename Traits::GPRRegister reg, | 948 void arith_int(Type Ty, typename Traits::GPRRegister reg, |
| 904 const typename Traits::Address &address); | 949 const typename Traits::Address &address); |
| 905 | 950 |
| 906 template <uint32_t Tag> | 951 template <uint32_t Tag> |
| 907 void arith_int(Type Ty, const typename Traits::Address &address, | 952 void arith_int(Type Ty, const typename Traits::Address &address, |
| 908 typename Traits::GPRRegister reg); | 953 typename Traits::GPRRegister reg); |
| 909 | 954 |
| 910 template <uint32_t Tag> | 955 template <uint32_t Tag> |
| 911 void arith_int(Type Ty, const typename Traits::Address &address, | 956 void arith_int(Type Ty, const typename Traits::Address &address, |
| 912 const Immediate &imm); | 957 const Immediate &imm); |
| 958 |
| 959 // gprEncoding returns Reg encoding for operand emission. For x86-64 we mask |
| 960 // out the 4th bit as it is encoded in the REX.[RXB] bits. No other bits are |
| 961 // touched because we don't want to mask errors. |
| 962 template <typename RegType, typename T = Traits> |
| 963 typename std::enable_if<T::Is64Bit, typename T::GPRRegister>::type |
| 964 gprEncoding(const RegType Reg) { |
| 965 return static_cast<typename Traits::GPRRegister>(static_cast<uint8_t>(Reg) & |
| 966 ~0x08); |
| 967 } |
| 968 |
| 969 template <typename RegType, typename T = Traits> |
| 970 typename std::enable_if<!T::Is64Bit, typename T::GPRRegister>::type |
| 971 gprEncoding(const RegType Reg) { |
| 972 return static_cast<typename T::GPRRegister>(Reg); |
| 973 } |
| 974 |
| 975 template <typename RegType> |
| 976 bool is8BitRegisterRequiringRex(const Type Ty, const RegType Reg) { |
| 977 static constexpr bool IsGPR = |
| 978 std::is_same<typename std::decay<RegType>::type, |
| 979 typename Traits::ByteRegister>::value || |
| 980 std::is_same<typename std::decay<RegType>::type, |
| 981 typename Traits::GPRRegister>::value; |
| 982 |
| 983 return IsGPR && (Reg & 0x04) != 0 && (Reg & 0x08) == 0 && |
| 984 isByteSizedArithType(Ty); |
| 985 }; |
| 986 |
| 987 // assembleAndEmitRex is used for determining which (if any) rex prefix should |
| 988 // be emitted for the current instruction. It allows different types for Reg |
| 989 // and Rm because they could be of different types (e.g., in mov[sz]x |
| 990 // instrutions.) If Addr is not nullptr, then Rm is ignored, and Rex.B is |
| 991 // determined by Addr instead. TyRm is still used to determine Addr's size. |
| 992 template <typename RegType, typename RmType, typename T = Traits> |
| 993 typename std::enable_if<T::Is64Bit, void>::type |
| 994 assembleAndEmitRex(const Type TyReg, const RegType Reg, const Type TyRm, |
| 995 const RmType Rm, |
| 996 const typename T::Address *Addr = nullptr) { |
| 997 const uint8_t W = (TyReg == IceType_i64 || TyRm == IceType_i64) |
| 998 ? T::Operand::RexW |
| 999 : T::Operand::RexNone; |
| 1000 const uint8_t R = (Reg & 0x08) ? T::Operand::RexR : T::Operand::RexNone; |
| 1001 const uint8_t X = (Addr != nullptr) ? Addr->rexX() : T::Operand::RexNone; |
| 1002 const uint8_t B = |
| 1003 (Addr != nullptr) ? Addr->rexB() : (Rm & 0x08) ? T::Operand::RexB |
| 1004 : T::Operand::RexNone; |
| 1005 const uint8_t Prefix = W | R | X | B; |
| 1006 if (Prefix != T::Operand::RexNone) { |
| 1007 emitUint8(Prefix); |
| 1008 } else if (is8BitRegisterRequiringRex(TyReg, Reg) || |
| 1009 (Addr == nullptr && is8BitRegisterRequiringRex(TyRm, Rm))) { |
| 1010 emitUint8(T::Operand::RexBase); |
| 1011 } |
| 1012 } |
| 1013 |
| 1014 template <typename RegType, typename RmType, typename T = Traits> |
| 1015 typename std::enable_if<!T::Is64Bit, void>::type |
| 1016 assembleAndEmitRex(const Type, const RegType, const Type, const RmType, |
| 1017 const typename T::Address * = nullptr) {} |
| 1018 |
| 1019 // emitRexRB is used for emitting a Rex prefix instructions with two explicit |
| 1020 // register operands in its mod-rm byte. |
| 1021 template <typename RegType, typename RmType> |
| 1022 void emitRexRB(const Type Ty, const RegType Reg, const RmType Rm) { |
| 1023 assembleAndEmitRex(Ty, Reg, Ty, Rm); |
| 1024 } |
| 1025 |
| 1026 template <typename RegType, typename RmType> |
| 1027 void emitRexRB(const Type TyReg, const RegType Reg, const Type TyRm, |
| 1028 const RmType Rm) { |
| 1029 assembleAndEmitRex(TyReg, Reg, TyRm, Rm); |
| 1030 } |
| 1031 |
| 1032 // emitRexB is used for emitting a Rex prefix if one is needed on encoding the |
| 1033 // Reg field in an x86 instruction. It is invoked by the template when Reg is |
| 1034 // the single register operand in the instruction (e.g., push Reg.) |
| 1035 template <typename RmType> void emitRexB(const Type Ty, const RmType Rm) { |
| 1036 emitRexRB(Ty, Encoded_Reg_Irrelevant, Ty, Rm); |
| 1037 } |
| 1038 |
| 1039 // emitRex is used for emitting a Rex prefix for an address and a GPR. The |
| 1040 // address may contain zero, one, or two registers. |
| 1041 template <typename RegType> |
| 1042 void emitRex(const Type Ty, const typename Traits::Address &Addr, |
| 1043 const RegType Reg) { |
| 1044 assembleAndEmitRex(Ty, Reg, Ty, Encoded_Reg_Irrelevant, &Addr); |
| 1045 } |
| 1046 |
| 1047 template <typename RegType> |
| 1048 void emitRex(const Type AddrTy, const typename Traits::Address &Addr, |
| 1049 const Type TyReg, const RegType Reg) { |
| 1050 assembleAndEmitRex(TyReg, Reg, AddrTy, Encoded_Reg_Irrelevant, &Addr); |
| 1051 } |
| 913 }; | 1052 }; |
| 914 | 1053 |
| 915 template <class Machine> | 1054 template <class Machine> |
| 916 inline void AssemblerX86Base<Machine>::emitUint8(uint8_t value) { | 1055 inline void AssemblerX86Base<Machine>::emitUint8(uint8_t value) { |
| 917 Buffer.emit<uint8_t>(value); | 1056 Buffer.emit<uint8_t>(value); |
| 918 } | 1057 } |
| 919 | 1058 |
| 920 template <class Machine> | 1059 template <class Machine> |
| 921 inline void AssemblerX86Base<Machine>::emitInt16(int16_t value) { | 1060 inline void AssemblerX86Base<Machine>::emitInt16(int16_t value) { |
| 922 Buffer.emit<int16_t>(value); | 1061 Buffer.emit<int16_t>(value); |
| 923 } | 1062 } |
| 924 | 1063 |
| 925 template <class Machine> | 1064 template <class Machine> |
| 926 inline void AssemblerX86Base<Machine>::emitInt32(int32_t value) { | 1065 inline void AssemblerX86Base<Machine>::emitInt32(int32_t value) { |
| 927 Buffer.emit<int32_t>(value); | 1066 Buffer.emit<int32_t>(value); |
| 928 } | 1067 } |
| 929 | 1068 |
| 930 template <class Machine> | 1069 template <class Machine> |
| 931 inline void AssemblerX86Base<Machine>::emitRegisterOperand(int rm, int reg) { | 1070 inline void AssemblerX86Base<Machine>::emitRegisterOperand(int reg, int rm) { |
| 1071 assert(reg >= 0 && reg < 8); |
| 932 assert(rm >= 0 && rm < 8); | 1072 assert(rm >= 0 && rm < 8); |
| 933 Buffer.emit<uint8_t>(0xC0 + (rm << 3) + reg); | 1073 Buffer.emit<uint8_t>(0xC0 + (reg << 3) + rm); |
| 934 } | 1074 } |
| 935 | 1075 |
| 936 template <class Machine> | 1076 template <class Machine> |
| 937 inline void AssemblerX86Base<Machine>::emitXmmRegisterOperand( | 1077 template <typename RegType, typename RmType> |
| 938 int rm, typename Traits::XmmRegister reg) { | 1078 inline void AssemblerX86Base<Machine>::emitXmmRegisterOperand(RegType reg, |
| 939 emitRegisterOperand(rm, static_cast<typename Traits::GPRRegister>(reg)); | 1079 RmType rm) { |
| 1080 emitRegisterOperand(gprEncoding(reg), gprEncoding(rm)); |
| 940 } | 1081 } |
| 941 | 1082 |
| 942 template <class Machine> | 1083 template <class Machine> |
| 943 inline void AssemblerX86Base<Machine>::emitFixup(AssemblerFixup *fixup) { | 1084 inline void AssemblerX86Base<Machine>::emitFixup(AssemblerFixup *fixup) { |
| 944 Buffer.emitFixup(fixup); | 1085 Buffer.emitFixup(fixup); |
| 945 } | 1086 } |
| 946 | 1087 |
| 947 template <class Machine> | 1088 template <class Machine> |
| 948 inline void AssemblerX86Base<Machine>::emitOperandSizeOverride() { | 1089 inline void AssemblerX86Base<Machine>::emitOperandSizeOverride() { |
| 949 emitUint8(0x66); | 1090 emitUint8(0x66); |
| 950 } | 1091 } |
| 951 | 1092 |
| 952 } // end of namespace X86Internal | 1093 } // end of namespace X86Internal |
| 953 | 1094 |
| 954 } // end of namespace Ice | 1095 } // end of namespace Ice |
| 955 | 1096 |
| 956 #include "IceAssemblerX86BaseImpl.h" | 1097 #include "IceAssemblerX86BaseImpl.h" |
| 957 | 1098 |
| 958 #endif // SUBZERO_SRC_ICEASSEMBLERX86BASE_H | 1099 #endif // SUBZERO_SRC_ICEASSEMBLERX86BASE_H |
| OLD | NEW |