| 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, | |
| 530 typename Traits::XmmRegister src, const Immediate &mask); | |
| 531 | 533 |
| 532 void pshufd(Type Ty, typename Traits::XmmRegister dst, | 534 void pshufd(Type Ty, typename Traits::XmmRegister dst, |
| 533 typename Traits::XmmRegister src, const Immediate &mask); | 535 typename Traits::XmmRegister src, const Immediate &mask); |
| 534 void pshufd(Type Ty, typename Traits::XmmRegister dst, | 536 void pshufd(Type Ty, typename Traits::XmmRegister dst, |
| 535 const typename Traits::Address &src, const Immediate &mask); | 537 const typename Traits::Address &src, const Immediate &mask); |
| 536 void shufps(Type Ty, typename Traits::XmmRegister dst, | 538 void shufps(Type Ty, typename Traits::XmmRegister dst, |
| 537 typename Traits::XmmRegister src, const Immediate &mask); | 539 typename Traits::XmmRegister src, const Immediate &mask); |
| 538 void shufps(Type Ty, typename Traits::XmmRegister dst, | 540 void shufps(Type Ty, typename Traits::XmmRegister dst, |
| 539 const typename Traits::Address &src, const Immediate &mask); | 541 const typename Traits::Address &src, const Immediate &mask); |
| 540 | 542 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 599 void insertps(Type Ty, typename Traits::XmmRegister dst, | 601 void insertps(Type Ty, typename Traits::XmmRegister dst, |
| 600 const typename Traits::Address &src, const Immediate &imm); | 602 const typename Traits::Address &src, const Immediate &imm); |
| 601 | 603 |
| 602 void pinsr(Type Ty, typename Traits::XmmRegister dst, | 604 void pinsr(Type Ty, typename Traits::XmmRegister dst, |
| 603 typename Traits::GPRRegister src, const Immediate &imm); | 605 typename Traits::GPRRegister src, const Immediate &imm); |
| 604 void pinsr(Type Ty, typename Traits::XmmRegister dst, | 606 void pinsr(Type Ty, typename Traits::XmmRegister dst, |
| 605 const typename Traits::Address &src, const Immediate &imm); | 607 const typename Traits::Address &src, const Immediate &imm); |
| 606 | 608 |
| 607 void pextr(Type Ty, typename Traits::GPRRegister dst, | 609 void pextr(Type Ty, typename Traits::GPRRegister dst, |
| 608 typename Traits::XmmRegister src, const Immediate &imm); | 610 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 | 611 |
| 612 void pmovsxdq(typename Traits::XmmRegister dst, | 612 void pmovsxdq(typename Traits::XmmRegister dst, |
| 613 typename Traits::XmmRegister src); | 613 typename Traits::XmmRegister src); |
| 614 | 614 |
| 615 void pcmpeq(Type Ty, typename Traits::XmmRegister dst, | 615 void pcmpeq(Type Ty, typename Traits::XmmRegister dst, |
| 616 typename Traits::XmmRegister src); | 616 typename Traits::XmmRegister src); |
| 617 void pcmpeq(Type Ty, typename Traits::XmmRegister dst, | 617 void pcmpeq(Type Ty, typename Traits::XmmRegister dst, |
| 618 const typename Traits::Address &src); | 618 const typename Traits::Address &src); |
| 619 void pcmpgt(Type Ty, typename Traits::XmmRegister dst, | 619 void pcmpgt(Type Ty, typename Traits::XmmRegister dst, |
| 620 typename Traits::XmmRegister src); | 620 typename Traits::XmmRegister src); |
| 621 void pcmpgt(Type Ty, typename Traits::XmmRegister dst, | 621 void pcmpgt(Type Ty, typename Traits::XmmRegister dst, |
| 622 const typename Traits::Address &src); | 622 const typename Traits::Address &src); |
| 623 | 623 |
| 624 enum RoundingMode { | 624 enum RoundingMode { |
| 625 kRoundToNearest = 0x0, | 625 kRoundToNearest = 0x0, |
| 626 kRoundDown = 0x1, | 626 kRoundDown = 0x1, |
| 627 kRoundUp = 0x2, | 627 kRoundUp = 0x2, |
| 628 kRoundToZero = 0x3 | 628 kRoundToZero = 0x3 |
| 629 }; | 629 }; |
| 630 void roundsd(typename Traits::XmmRegister dst, | 630 void roundsd(typename Traits::XmmRegister dst, |
| 631 typename Traits::XmmRegister src, RoundingMode mode); | 631 typename Traits::XmmRegister src, RoundingMode mode); |
| 632 | 632 |
| 633 void fld(Type Ty, const typename Traits::Address &src); | 633 //---------------------------------------------------------------------------- |
| 634 void fstp(Type Ty, const typename Traits::Address &dst); | 634 // |
| 635 void fstp(typename Traits::X87STRegister st); | 635 // Begin: X87 instructions. Only available when Traits::UsesX87. |
| 636 // |
| 637 //---------------------------------------------------------------------------- |
| 638 template <typename T = Traits, |
| 639 typename = typename std::enable_if<T::UsesX87>::type> |
| 640 void fld(Type Ty, const typename T::Address &src); |
| 641 template <typename T = Traits, |
| 642 typename = typename std::enable_if<T::UsesX87>::type> |
| 643 void fstp(Type Ty, const typename T::Address &dst); |
| 644 template <typename T = Traits, |
| 645 typename = typename std::enable_if<T::UsesX87>::type> |
| 646 void fstp(typename T::X87STRegister st); |
| 636 | 647 |
| 637 void fnstcw(const typename Traits::Address &dst); | 648 template <typename T = Traits, |
| 638 void fldcw(const typename Traits::Address &src); | 649 typename = typename std::enable_if<T::UsesX87>::type> |
| 650 void fnstcw(const typename T::Address &dst); |
| 651 template <typename T = Traits, |
| 652 typename = typename std::enable_if<T::UsesX87>::type> |
| 653 void fldcw(const typename T::Address &src); |
| 639 | 654 |
| 640 void fistpl(const typename Traits::Address &dst); | 655 template <typename T = Traits, |
| 641 void fistps(const typename Traits::Address &dst); | 656 typename = typename std::enable_if<T::UsesX87>::type> |
| 642 void fildl(const typename Traits::Address &src); | 657 void fistpl(const typename T::Address &dst); |
| 643 void filds(const typename Traits::Address &src); | 658 template <typename T = Traits, |
| 659 typename = typename std::enable_if<T::UsesX87>::type> |
| 660 void fistps(const typename T::Address &dst); |
| 661 template <typename T = Traits, |
| 662 typename = typename std::enable_if<T::UsesX87>::type> |
| 663 void fildl(const typename T::Address &src); |
| 664 template <typename T = Traits, |
| 665 typename = typename std::enable_if<T::UsesX87>::type> |
| 666 void filds(const typename T::Address &src); |
| 644 | 667 |
| 668 template <typename T = Traits, |
| 669 typename = typename std::enable_if<T::UsesX87>::type> |
| 645 void fincstp(); | 670 void fincstp(); |
| 671 //---------------------------------------------------------------------------- |
| 672 // |
| 673 // End: X87 instructions. |
| 674 // |
| 675 //---------------------------------------------------------------------------- |
| 646 | 676 |
| 647 void cmp(Type Ty, typename Traits::GPRRegister reg0, | 677 void cmp(Type Ty, typename Traits::GPRRegister reg0, |
| 648 typename Traits::GPRRegister reg1); | 678 typename Traits::GPRRegister reg1); |
| 649 void cmp(Type Ty, typename Traits::GPRRegister reg, | 679 void cmp(Type Ty, typename Traits::GPRRegister reg, |
| 650 const typename Traits::Address &address); | 680 const typename Traits::Address &address); |
| 651 void cmp(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm); | 681 void cmp(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm); |
| 652 void cmp(Type Ty, const typename Traits::Address &address, | 682 void cmp(Type Ty, const typename Traits::Address &address, |
| 653 typename Traits::GPRRegister reg); | 683 typename Traits::GPRRegister reg); |
| 654 void cmp(Type Ty, const typename Traits::Address &address, | 684 void cmp(Type Ty, const typename Traits::Address &address, |
| 655 const Immediate &imm); | 685 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); | 777 void imul(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm); |
| 748 void imul(Type Ty, typename Traits::GPRRegister reg, | 778 void imul(Type Ty, typename Traits::GPRRegister reg, |
| 749 const typename Traits::Address &address); | 779 const typename Traits::Address &address); |
| 750 | 780 |
| 751 void imul(Type Ty, typename Traits::GPRRegister reg); | 781 void imul(Type Ty, typename Traits::GPRRegister reg); |
| 752 void imul(Type Ty, const typename Traits::Address &address); | 782 void imul(Type Ty, const typename Traits::Address &address); |
| 753 | 783 |
| 754 void mul(Type Ty, typename Traits::GPRRegister reg); | 784 void mul(Type Ty, typename Traits::GPRRegister reg); |
| 755 void mul(Type Ty, const typename Traits::Address &address); | 785 void mul(Type Ty, const typename Traits::Address &address); |
| 756 | 786 |
| 787 template <class T = Traits, |
| 788 typename = typename std::enable_if<!T::Is64Bit>::type> |
| 757 void incl(typename Traits::GPRRegister reg); | 789 void incl(typename Traits::GPRRegister reg); |
| 758 void incl(const typename Traits::Address &address); | 790 void incl(const typename Traits::Address &address); |
| 759 | 791 |
| 792 template <class T = Traits, |
| 793 typename = typename std::enable_if<!T::Is64Bit>::type> |
| 760 void decl(typename Traits::GPRRegister reg); | 794 void decl(typename Traits::GPRRegister reg); |
| 761 void decl(const typename Traits::Address &address); | 795 void decl(const typename Traits::Address &address); |
| 762 | 796 |
| 763 void rol(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm); | 797 void rol(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm); |
| 764 void rol(Type Ty, typename Traits::GPRRegister operand, | 798 void rol(Type Ty, typename Traits::GPRRegister operand, |
| 765 typename Traits::GPRRegister shifter); | 799 typename Traits::GPRRegister shifter); |
| 766 void rol(Type Ty, const typename Traits::Address &operand, | 800 void rol(Type Ty, const typename Traits::Address &operand, |
| 767 typename Traits::GPRRegister shifter); | 801 typename Traits::GPRRegister shifter); |
| 768 | 802 |
| 769 void shl(Type Ty, typename Traits::GPRRegister reg, const Immediate &imm); | 803 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(); | 852 void ret(); |
| 819 void ret(const Immediate &imm); | 853 void ret(const Immediate &imm); |
| 820 | 854 |
| 821 // 'size' indicates size in bytes and must be in the range 1..8. | 855 // 'size' indicates size in bytes and must be in the range 1..8. |
| 822 void nop(int size = 1); | 856 void nop(int size = 1); |
| 823 void int3(); | 857 void int3(); |
| 824 void hlt(); | 858 void hlt(); |
| 825 void ud2(); | 859 void ud2(); |
| 826 | 860 |
| 827 // j(Label) is fully tested. | 861 // 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, | 862 void j(typename Traits::Cond::BrCond condition, Label *label, |
| 831 bool near = kFarJump); | 863 bool near = kFarJump); |
| 832 void j(typename Traits::Cond::BrCond condition, | 864 void j(typename Traits::Cond::BrCond condition, |
| 833 const ConstantRelocatable *label); | 865 const ConstantRelocatable *label); // not testable. |
| 834 | 866 |
| 835 void jmp(typename Traits::GPRRegister reg); | 867 void jmp(typename Traits::GPRRegister reg); |
| 836 void jmp(Label *label, bool near = kFarJump); | 868 void jmp(Label *label, bool near = kFarJump); |
| 837 void jmp(const ConstantRelocatable *label); | 869 void jmp(const ConstantRelocatable *label); // not testable. |
| 838 | 870 |
| 839 void mfence(); | 871 void mfence(); |
| 840 | 872 |
| 841 void lock(); | 873 void lock(); |
| 842 void cmpxchg(Type Ty, const typename Traits::Address &address, | 874 void cmpxchg(Type Ty, const typename Traits::Address &address, |
| 843 typename Traits::GPRRegister reg, bool Locked); | 875 typename Traits::GPRRegister reg, bool Locked); |
| 844 void cmpxchg8b(const typename Traits::Address &address, bool Locked); | 876 void cmpxchg8b(const typename Traits::Address &address, bool Locked); |
| 845 void xadd(Type Ty, const typename Traits::Address &address, | 877 void xadd(Type Ty, const typename Traits::Address &address, |
| 846 typename Traits::GPRRegister reg, bool Locked); | 878 typename Traits::GPRRegister reg, bool Locked); |
| 847 void xchg(Type Ty, const typename Traits::Address &address, | 879 void xchg(Type Ty, const typename Traits::Address &address, |
| 848 typename Traits::GPRRegister reg); | 880 typename Traits::GPRRegister reg); |
| 849 | 881 |
| 850 void emitSegmentOverride(uint8_t prefix); | 882 void emitSegmentOverride(uint8_t prefix); |
| 851 | 883 |
| 852 intptr_t preferredLoopAlignment() { return 16; } | 884 intptr_t preferredLoopAlignment() { return 16; } |
| 853 void align(intptr_t alignment, intptr_t offset); | 885 void align(intptr_t alignment, intptr_t offset); |
| 854 void bind(Label *label); | 886 void bind(Label *label); |
| 855 | 887 |
| 856 intptr_t CodeSize() const { return Buffer.size(); } | 888 intptr_t CodeSize() const { return Buffer.size(); } |
| 857 | 889 |
| 890 protected: |
| 891 inline void emitUint8(uint8_t value); |
| 892 |
| 858 private: | 893 private: |
| 859 inline void emitUint8(uint8_t value); | 894 static constexpr Type RexTypeIrrelevant = IceType_i32; |
| 895 static constexpr Type IceType_ForceRexW = IceType_i64; |
| 896 static constexpr typename Traits::GPRRegister RexRegIrrelevant = |
| 897 Traits::GPRRegister::Encoded_Reg_eax; |
| 898 |
| 860 inline void emitInt16(int16_t value); | 899 inline void emitInt16(int16_t value); |
| 861 inline void emitInt32(int32_t value); | 900 inline void emitInt32(int32_t value); |
| 862 inline void emitRegisterOperand(int rm, int reg); | 901 inline void emitRegisterOperand(int rm, int reg); |
| 863 inline void emitXmmRegisterOperand(int rm, typename Traits::XmmRegister reg); | 902 template <typename RegType, typename RmType> |
| 903 inline void emitXmmRegisterOperand(RegType reg, RmType rm); |
| 864 inline void emitFixup(AssemblerFixup *fixup); | 904 inline void emitFixup(AssemblerFixup *fixup); |
| 865 inline void emitOperandSizeOverride(); | 905 inline void emitOperandSizeOverride(); |
| 866 | 906 |
| 867 void emitOperand(int rm, const typename Traits::Operand &operand); | 907 void emitOperand(int rm, const typename Traits::Operand &operand); |
| 868 void emitImmediate(Type ty, const Immediate &imm); | 908 void emitImmediate(Type ty, const Immediate &imm); |
| 869 void emitComplexI8(int rm, const typename Traits::Operand &operand, | 909 void emitComplexI8(int rm, const typename Traits::Operand &operand, |
| 870 const Immediate &immediate); | 910 const Immediate &immediate); |
| 871 void emitComplex(Type Ty, int rm, const typename Traits::Operand &operand, | 911 void emitComplex(Type Ty, int rm, const typename Traits::Operand &operand, |
| 872 const Immediate &immediate); | 912 const Immediate &immediate); |
| 873 void emitLabel(Label *label, intptr_t instruction_size); | 913 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, | 943 void arith_int(Type Ty, typename Traits::GPRRegister reg, |
| 904 const typename Traits::Address &address); | 944 const typename Traits::Address &address); |
| 905 | 945 |
| 906 template <uint32_t Tag> | 946 template <uint32_t Tag> |
| 907 void arith_int(Type Ty, const typename Traits::Address &address, | 947 void arith_int(Type Ty, const typename Traits::Address &address, |
| 908 typename Traits::GPRRegister reg); | 948 typename Traits::GPRRegister reg); |
| 909 | 949 |
| 910 template <uint32_t Tag> | 950 template <uint32_t Tag> |
| 911 void arith_int(Type Ty, const typename Traits::Address &address, | 951 void arith_int(Type Ty, const typename Traits::Address &address, |
| 912 const Immediate &imm); | 952 const Immediate &imm); |
| 953 |
| 954 // gprEncoding returns Reg encoding for operand emission. For x86-64 we mask |
| 955 // out the 4th bit as it is encoded in the REX.[RXB] bits. No other bits are |
| 956 // touched because we don't want to mask errors. |
| 957 template <typename RegType, typename T = Traits> |
| 958 typename std::enable_if<T::Is64Bit, typename T::GPRRegister>::type |
| 959 gprEncoding(const RegType Reg) { |
| 960 return static_cast<typename Traits::GPRRegister>(static_cast<uint8_t>(Reg) & |
| 961 ~0x08); |
| 962 } |
| 963 |
| 964 template <typename RegType, typename T = Traits> |
| 965 typename std::enable_if<!T::Is64Bit, typename T::GPRRegister>::type |
| 966 gprEncoding(const RegType Reg) { |
| 967 return static_cast<typename T::GPRRegister>(Reg); |
| 968 } |
| 969 |
| 970 template <typename RegType> |
| 971 bool is8BitRegisterRequiringRex(const Type Ty, const RegType Reg) { |
| 972 static constexpr bool IsGPR = |
| 973 std::is_same<typename std::decay<RegType>::type, |
| 974 typename Traits::ByteRegister>::value || |
| 975 std::is_same<typename std::decay<RegType>::type, |
| 976 typename Traits::GPRRegister>::value; |
| 977 |
| 978 return IsGPR && (Reg & 0x04) != 0 && (Reg & 0x08) == 0 && |
| 979 isByteSizedArithType(Ty); |
| 980 }; |
| 981 |
| 982 // assembleAndEmitRex is used for determining which (if any) rex prefix should |
| 983 // be emitted for the current instruction. It allows different types for Reg |
| 984 // and Rm because they could be of different types (e.g., in mov[sz]x |
| 985 // instrutions.) If Addr is not nullptr, then Rm is ignored, and Rex.B is |
| 986 // determined by Addr instead. TyRm is still used to determine Addr's size. |
| 987 template <typename RegType, typename RmType, typename T = Traits> |
| 988 typename std::enable_if<T::Is64Bit, void>::type |
| 989 assembleAndEmitRex(const Type TyReg, const RegType Reg, const Type TyRm, |
| 990 const RmType Rm, |
| 991 const typename T::Address *Addr = nullptr) { |
| 992 const uint8_t W = (TyReg == IceType_i64 || TyRm == IceType_i64) |
| 993 ? T::Operand::RexW |
| 994 : T::Operand::RexNone; |
| 995 const uint8_t R = (Reg & 0x08) ? T::Operand::RexR : T::Operand::RexNone; |
| 996 const uint8_t X = (Addr != nullptr) ? Addr->rexX() : T::Operand::RexNone; |
| 997 const uint8_t B = |
| 998 (Addr != nullptr) ? Addr->rexB() : (Rm & 0x08) ? T::Operand::RexB |
| 999 : T::Operand::RexNone; |
| 1000 const uint8_t Prefix = W | R | X | B; |
| 1001 if (Prefix != T::Operand::RexNone) { |
| 1002 emitUint8(Prefix); |
| 1003 } else if (is8BitRegisterRequiringRex(TyReg, Reg) || |
| 1004 (Addr == nullptr && is8BitRegisterRequiringRex(TyRm, Rm))) { |
| 1005 emitUint8(T::Operand::RexBase); |
| 1006 } |
| 1007 } |
| 1008 |
| 1009 template <typename RegType, typename RmType, typename T = Traits> |
| 1010 typename std::enable_if<!T::Is64Bit, void>::type |
| 1011 assembleAndEmitRex(const Type, const RegType, const Type, const RmType, |
| 1012 const typename T::Address * = nullptr) {} |
| 1013 |
| 1014 // emitRexRB is used for emitting a Rex prefix instructions with two explicit |
| 1015 // register operands in its mod-rm byte. |
| 1016 template <typename RegType, typename RmType> |
| 1017 void emitRexRB(const Type Ty, const RegType Reg, const RmType Rm) { |
| 1018 assembleAndEmitRex(Ty, Reg, Ty, Rm); |
| 1019 } |
| 1020 |
| 1021 template <typename RegType, typename RmType> |
| 1022 void emitRexRB(const Type TyReg, const RegType Reg, const Type TyRm, |
| 1023 const RmType Rm) { |
| 1024 assembleAndEmitRex(TyReg, Reg, TyRm, Rm); |
| 1025 } |
| 1026 |
| 1027 // emitRexB is used for emitting a Rex prefix if one is needed on encoding the |
| 1028 // Reg field in an x86 instruction. It is invoked by the template when Reg is |
| 1029 // the single register operand in the instruction (e.g., push Reg.) |
| 1030 template <typename RmType> void emitRexB(const Type Ty, const RmType Rm) { |
| 1031 emitRexRB(Ty, RexRegIrrelevant, Ty, Rm); |
| 1032 } |
| 1033 |
| 1034 // emitRex is used for emitting a Rex prefix for an address and a GPR. The |
| 1035 // address may contain zero, one, or two registers. |
| 1036 template <typename RegType> |
| 1037 void emitRex(const Type Ty, const typename Traits::Address &Addr, |
| 1038 const RegType Reg) { |
| 1039 assembleAndEmitRex(Ty, Reg, Ty, RexRegIrrelevant, &Addr); |
| 1040 } |
| 1041 |
| 1042 template <typename RegType> |
| 1043 void emitRex(const Type AddrTy, const typename Traits::Address &Addr, |
| 1044 const Type TyReg, const RegType Reg) { |
| 1045 assembleAndEmitRex(TyReg, Reg, AddrTy, RexRegIrrelevant, &Addr); |
| 1046 } |
| 913 }; | 1047 }; |
| 914 | 1048 |
| 915 template <class Machine> | 1049 template <class Machine> |
| 916 inline void AssemblerX86Base<Machine>::emitUint8(uint8_t value) { | 1050 inline void AssemblerX86Base<Machine>::emitUint8(uint8_t value) { |
| 917 Buffer.emit<uint8_t>(value); | 1051 Buffer.emit<uint8_t>(value); |
| 918 } | 1052 } |
| 919 | 1053 |
| 920 template <class Machine> | 1054 template <class Machine> |
| 921 inline void AssemblerX86Base<Machine>::emitInt16(int16_t value) { | 1055 inline void AssemblerX86Base<Machine>::emitInt16(int16_t value) { |
| 922 Buffer.emit<int16_t>(value); | 1056 Buffer.emit<int16_t>(value); |
| 923 } | 1057 } |
| 924 | 1058 |
| 925 template <class Machine> | 1059 template <class Machine> |
| 926 inline void AssemblerX86Base<Machine>::emitInt32(int32_t value) { | 1060 inline void AssemblerX86Base<Machine>::emitInt32(int32_t value) { |
| 927 Buffer.emit<int32_t>(value); | 1061 Buffer.emit<int32_t>(value); |
| 928 } | 1062 } |
| 929 | 1063 |
| 930 template <class Machine> | 1064 template <class Machine> |
| 931 inline void AssemblerX86Base<Machine>::emitRegisterOperand(int rm, int reg) { | 1065 inline void AssemblerX86Base<Machine>::emitRegisterOperand(int reg, int rm) { |
| 1066 assert(reg >= 0 && reg < 8); |
| 932 assert(rm >= 0 && rm < 8); | 1067 assert(rm >= 0 && rm < 8); |
| 933 Buffer.emit<uint8_t>(0xC0 + (rm << 3) + reg); | 1068 Buffer.emit<uint8_t>(0xC0 + (reg << 3) + rm); |
| 934 } | 1069 } |
| 935 | 1070 |
| 936 template <class Machine> | 1071 template <class Machine> |
| 937 inline void AssemblerX86Base<Machine>::emitXmmRegisterOperand( | 1072 template <typename RegType, typename RmType> |
| 938 int rm, typename Traits::XmmRegister reg) { | 1073 inline void AssemblerX86Base<Machine>::emitXmmRegisterOperand(RegType reg, |
| 939 emitRegisterOperand(rm, static_cast<typename Traits::GPRRegister>(reg)); | 1074 RmType rm) { |
| 1075 emitRegisterOperand(gprEncoding(reg), gprEncoding(rm)); |
| 940 } | 1076 } |
| 941 | 1077 |
| 942 template <class Machine> | 1078 template <class Machine> |
| 943 inline void AssemblerX86Base<Machine>::emitFixup(AssemblerFixup *fixup) { | 1079 inline void AssemblerX86Base<Machine>::emitFixup(AssemblerFixup *fixup) { |
| 944 Buffer.emitFixup(fixup); | 1080 Buffer.emitFixup(fixup); |
| 945 } | 1081 } |
| 946 | 1082 |
| 947 template <class Machine> | 1083 template <class Machine> |
| 948 inline void AssemblerX86Base<Machine>::emitOperandSizeOverride() { | 1084 inline void AssemblerX86Base<Machine>::emitOperandSizeOverride() { |
| 949 emitUint8(0x66); | 1085 emitUint8(0x66); |
| 950 } | 1086 } |
| 951 | 1087 |
| 952 } // end of namespace X86Internal | 1088 } // end of namespace X86Internal |
| 953 | 1089 |
| 954 } // end of namespace Ice | 1090 } // end of namespace Ice |
| 955 | 1091 |
| 956 #include "IceAssemblerX86BaseImpl.h" | 1092 #include "IceAssemblerX86BaseImpl.h" |
| 957 | 1093 |
| 958 #endif // SUBZERO_SRC_ICEASSEMBLERX86BASE_H | 1094 #endif // SUBZERO_SRC_ICEASSEMBLERX86BASE_H |
| OLD | NEW |