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

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; changes emitRex.* logic. 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
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, 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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698