Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(210)

Side by Side Diff: src/IceAssemblerX86Base.h

Issue 1224173006: Adds the x86-64 assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Addresses comments; make format Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceAssemblerX8664.cpp ('k') | src/IceAssemblerX86BaseImpl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/IceAssemblerX8664.cpp ('k') | src/IceAssemblerX86BaseImpl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698