Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef VM_ASSEMBLER_X64_H_ | 5 #ifndef VM_ASSEMBLER_X64_H_ |
| 6 #define VM_ASSEMBLER_X64_H_ | 6 #define VM_ASSEMBLER_X64_H_ |
| 7 | 7 |
| 8 #ifndef VM_ASSEMBLER_H_ | 8 #ifndef VM_ASSEMBLER_H_ |
| 9 #error Do not include assembler_x64.h directly; use assembler.h instead. | 9 #error Do not include assembler_x64.h directly; use assembler.h instead. |
| 10 #endif | 10 #endif |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 176 SetDisp8(disp); | 176 SetDisp8(disp); |
| 177 } else { | 177 } else { |
| 178 SetModRM(2, base); | 178 SetModRM(2, base); |
| 179 if ((base & 7) == RSP) { | 179 if ((base & 7) == RSP) { |
| 180 SetSIB(TIMES_1, RSP, base); | 180 SetSIB(TIMES_1, RSP, base); |
| 181 } | 181 } |
| 182 SetDisp32(disp); | 182 SetDisp32(disp); |
| 183 } | 183 } |
| 184 } | 184 } |
| 185 | 185 |
| 186 Address(Register base, int32_t disp, bool fixed) { | |
|
Florian Schneider
2013/09/05 10:57:45
Please add a test to assembler_x64_test.cc for thi
Florian Schneider
2013/09/05 10:57:45
Consider making this private and add Assembler as
zra
2013/09/05 20:29:26
Done.
zra
2013/09/05 20:29:26
Done.
| |
| 187 ASSERT(fixed); | |
| 188 SetModRM(2, base); | |
| 189 if ((base & 7) == RSP) { | |
| 190 SetSIB(TIMES_1, RSP, base); | |
| 191 } | |
| 192 SetDisp32(disp); | |
| 193 } | |
| 194 | |
| 186 Address(Register index, ScaleFactor scale, int32_t disp) { | 195 Address(Register index, ScaleFactor scale, int32_t disp) { |
| 187 ASSERT(index != RSP); // Illegal addressing mode. | 196 ASSERT(index != RSP); // Illegal addressing mode. |
| 188 SetModRM(0, RSP); | 197 SetModRM(0, RSP); |
| 189 SetSIB(scale, index, RBP); | 198 SetSIB(scale, index, RBP); |
| 190 SetDisp32(disp); | 199 SetDisp32(disp); |
| 191 } | 200 } |
| 192 | 201 |
| 193 Address(Register base, Register index, ScaleFactor scale, int32_t disp) { | 202 Address(Register base, Register index, ScaleFactor scale, int32_t disp) { |
| 194 ASSERT(index != RSP); // Illegal addressing mode. | 203 ASSERT(index != RSP); // Illegal addressing mode. |
| 195 if ((disp == 0) && ((base & 7) != RBP)) { | 204 if ((disp == 0) && ((base & 7) != RBP)) { |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 314 | 323 |
| 315 static bool sse4_1_supported_; | 324 static bool sse4_1_supported_; |
| 316 #ifdef DEBUG | 325 #ifdef DEBUG |
| 317 static bool initialized_; | 326 static bool initialized_; |
| 318 #endif | 327 #endif |
| 319 }; | 328 }; |
| 320 | 329 |
| 321 | 330 |
| 322 class Assembler : public ValueObject { | 331 class Assembler : public ValueObject { |
| 323 public: | 332 public: |
| 324 explicit Assembler(bool use_far_branches = false) | 333 explicit Assembler(bool use_far_branches = false); |
| 325 : buffer_(), | 334 |
| 326 object_pool_(GrowableObjectArray::Handle()), | |
| 327 prologue_offset_(-1), | |
| 328 comments_() { | |
| 329 // This mode is only needed and implemented for MIPS and ARM. | |
| 330 ASSERT(!use_far_branches); | |
| 331 } | |
| 332 ~Assembler() { } | 335 ~Assembler() { } |
| 333 | 336 |
| 334 static const bool kNearJump = true; | 337 static const bool kNearJump = true; |
| 335 static const bool kFarJump = false; | 338 static const bool kFarJump = false; |
| 336 | 339 |
| 337 /* | 340 /* |
| 338 * Emit Machine Instructions. | 341 * Emit Machine Instructions. |
| 339 */ | 342 */ |
| 340 void call(Register reg); | 343 void call(Register reg); |
| 341 void call(const Address& address); | 344 void call(const Address& address); |
| 342 void call(Label* label); | 345 void call(Label* label); |
| 343 void call(const ExternalLabel* label); | 346 void call(const ExternalLabel* label); |
| 344 | 347 |
| 345 static const intptr_t kCallExternalLabelSize = 13; | 348 static const intptr_t kCallExternalLabelSize = 10; |
| 346 | 349 |
| 347 void pushq(Register reg); | 350 void pushq(Register reg); |
| 348 void pushq(const Address& address); | 351 void pushq(const Address& address); |
| 349 void pushq(const Immediate& imm); | 352 void pushq(const Immediate& imm); |
| 350 | 353 |
| 351 void popq(Register reg); | 354 void popq(Register reg); |
| 352 void popq(const Address& address); | 355 void popq(const Address& address); |
| 353 | 356 |
| 354 void setcc(Condition condition, ByteRegister dst); | 357 void setcc(Condition condition, ByteRegister dst); |
| 355 | 358 |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 645 void CompareRegisters(Register a, Register b); | 648 void CompareRegisters(Register a, Register b); |
| 646 | 649 |
| 647 // Issues a move instruction if 'to' is not the same as 'from'. | 650 // Issues a move instruction if 'to' is not the same as 'from'. |
| 648 void MoveRegister(Register to, Register from); | 651 void MoveRegister(Register to, Register from); |
| 649 void PopRegister(Register r); | 652 void PopRegister(Register r); |
| 650 | 653 |
| 651 void AddImmediate(Register reg, const Immediate& imm); | 654 void AddImmediate(Register reg, const Immediate& imm); |
| 652 | 655 |
| 653 void Drop(intptr_t stack_elements); | 656 void Drop(intptr_t stack_elements); |
| 654 | 657 |
| 655 void LoadObject(Register dst, const Object& object); | 658 enum Patchability { |
| 659 kPatchable, | |
| 660 kNotPatchable, | |
| 661 }; | |
| 662 | |
| 663 void LoadObjectFromPool(Register dst, const Object& obj, Register pp); | |
|
Florian Schneider
2013/09/05 10:57:45
You really only need
LoadObject(Register dst, co
zra
2013/09/05 20:29:26
LoadObject is used in arch generic code. Changing
Florian Schneider
2013/09/06 09:58:15
Ok. But here is only one arch-independent place in
zra
2013/09/06 17:53:26
Done with pool pointer argument added.
| |
| 664 void LoadObject(Register dst, const Object& object) { | |
| 665 LoadObjectFromPool(dst, object, PP); | |
| 666 } | |
| 667 void JumpPatchable(const ExternalLabel* label, Register pp); | |
| 668 void JumpFromPool(const ExternalLabel* label, Register pp); | |
| 669 void ConditionalJumpFromPool(Condition condition, const ExternalLabel* label, | |
| 670 Register pp); | |
| 671 void CallPatchable(const ExternalLabel* label); | |
| 672 void CallFromPool(const ExternalLabel* label); | |
| 656 void StoreObject(const Address& dst, const Object& obj); | 673 void StoreObject(const Address& dst, const Object& obj); |
| 657 void PushObject(const Object& object); | 674 void PushObject(const Object& object); |
| 658 void CompareObject(Register reg, const Object& object); | 675 void CompareObject(Register reg, const Object& object); |
| 659 void LoadDoubleConstant(XmmRegister dst, double value); | 676 void LoadDoubleConstant(XmmRegister dst, double value); |
| 660 | 677 |
| 661 // Destroys value. | 678 // Destroys value. |
| 662 void StoreIntoObject(Register object, // Object we are storing into. | 679 void StoreIntoObject(Register object, // Object we are storing into. |
| 663 const Address& dest, // Where we are storing into. | 680 const Address& dest, // Where we are storing into. |
| 664 Register value, // Value we are storing. | 681 Register value, // Value we are storing. |
| 665 bool can_value_be_smi = true); | 682 bool can_value_be_smi = true); |
| 666 | 683 |
| 667 void StoreIntoObjectNoBarrier(Register object, | 684 void StoreIntoObjectNoBarrier(Register object, |
| 668 const Address& dest, | 685 const Address& dest, |
| 669 Register value); | 686 Register value); |
| 670 | 687 |
| 671 void DoubleNegate(XmmRegister d); | 688 void DoubleNegate(XmmRegister d); |
| 672 void FloatNegate(XmmRegister f); | 689 void FloatNegate(XmmRegister f); |
| 673 | 690 |
| 674 void DoubleAbs(XmmRegister reg); | 691 void DoubleAbs(XmmRegister reg); |
| 675 | 692 |
| 676 void LockCmpxchgl(const Address& address, Register reg) { | 693 void LockCmpxchgl(const Address& address, Register reg) { |
| 677 lock(); | 694 lock(); |
| 678 cmpxchgl(address, reg); | 695 cmpxchgl(address, reg); |
| 679 } | 696 } |
| 680 | 697 |
| 681 void EnterFrame(intptr_t frame_space); | 698 void EnterFrame(intptr_t frame_space); |
| 682 void LeaveFrame(); | 699 void LeaveFrame(); |
| 700 void LeaveFrameWithPP(); | |
| 683 void ReserveAlignedFrameSpace(intptr_t frame_space); | 701 void ReserveAlignedFrameSpace(intptr_t frame_space); |
| 684 | 702 |
| 685 // Create a frame for calling into runtime that preserves all volatile | 703 // Create a frame for calling into runtime that preserves all volatile |
| 686 // registers. Frame's RSP is guaranteed to be correctly aligned and | 704 // registers. Frame's RSP is guaranteed to be correctly aligned and |
| 687 // frame_space bytes are reserved under it. | 705 // frame_space bytes are reserved under it. |
| 688 void EnterCallRuntimeFrame(intptr_t frame_space); | 706 void EnterCallRuntimeFrame(intptr_t frame_space); |
| 689 void LeaveCallRuntimeFrame(); | 707 void LeaveCallRuntimeFrame(); |
| 690 | 708 |
| 691 | 709 |
| 692 void CallRuntime(const RuntimeEntry& entry, intptr_t argument_count); | 710 void CallRuntime(const RuntimeEntry& entry, intptr_t argument_count); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 724 int prologue_offset() const { return prologue_offset_; } | 742 int prologue_offset() const { return prologue_offset_; } |
| 725 const ZoneGrowableArray<int>& GetPointerOffsets() const { | 743 const ZoneGrowableArray<int>& GetPointerOffsets() const { |
| 726 return buffer_.pointer_offsets(); | 744 return buffer_.pointer_offsets(); |
| 727 } | 745 } |
| 728 const GrowableObjectArray& object_pool() const { return object_pool_; } | 746 const GrowableObjectArray& object_pool() const { return object_pool_; } |
| 729 | 747 |
| 730 void FinalizeInstructions(const MemoryRegion& region) { | 748 void FinalizeInstructions(const MemoryRegion& region) { |
| 731 buffer_.FinalizeInstructions(region); | 749 buffer_.FinalizeInstructions(region); |
| 732 } | 750 } |
| 733 | 751 |
| 752 void LoadPoolPointer(Register pp); | |
| 753 | |
| 734 // Set up a Dart frame on entry with a frame pointer and PC information to | 754 // Set up a Dart frame on entry with a frame pointer and PC information to |
| 735 // enable easy access to the RawInstruction object of code corresponding | 755 // enable easy access to the RawInstruction object of code corresponding |
| 736 // to this frame. | 756 // to this frame. |
| 737 // The dart frame layout is as follows: | 757 // The dart frame layout is as follows: |
| 738 // .... | 758 // .... |
| 739 // ret PC | 759 // ret PC |
| 740 // saved RBP <=== RBP | 760 // saved RBP <=== RBP |
| 741 // pc (used to derive the RawInstruction Object of the dart code) | 761 // pc (used to derive the RawInstruction Object of the dart code) |
| 762 // saved PP | |
| 742 // locals space <=== RSP | 763 // locals space <=== RSP |
| 743 // ..... | 764 // ..... |
| 744 // This code sets this up with the sequence: | 765 // This code sets this up with the sequence: |
| 745 // pushq rbp | 766 // pushq rbp |
| 746 // movq rbp, rsp | 767 // movq rbp, rsp |
| 747 // call L | 768 // call L |
| 748 // L: <code to adjust saved pc if there is any intrinsification code> | 769 // L: <code to adjust saved pc if there is any intrinsification code> |
| 770 // ... | |
| 771 // pushq r15 | |
| 749 // ..... | 772 // ..... |
| 750 void EnterDartFrame(intptr_t frame_size); | 773 void EnterDartFrame(intptr_t frame_size, Register new_pp, Register new_pc); |
| 751 | 774 |
| 752 // Set up a Dart frame for a function compiled for on-stack replacement. | 775 // Set up a Dart frame for a function compiled for on-stack replacement. |
| 753 // The frame layout is a normal Dart frame, but the frame is partially set | 776 // The frame layout is a normal Dart frame, but the frame is partially set |
| 754 // up on entry (it is the frame of the unoptimized code). | 777 // up on entry (it is the frame of the unoptimized code). |
| 755 void EnterOsrFrame(intptr_t extra_size); | 778 void EnterOsrFrame(intptr_t extra_size, Register new_pp, Register new_pc); |
| 756 | 779 |
| 757 // Set up a stub frame so that the stack traversal code can easily identify | 780 // Set up a stub frame so that the stack traversal code can easily identify |
| 758 // a stub frame. | 781 // a stub frame. |
| 759 // The stub frame layout is as follows: | 782 // The stub frame layout is as follows: |
| 760 // .... | 783 // .... |
| 761 // ret PC | 784 // ret PC |
| 762 // saved RBP | 785 // saved RBP |
| 763 // pc (used to derive the RawInstruction Object of the stub) | 786 // pc (used to derive the RawInstruction Object of the stub) |
| 764 // ..... | 787 // ..... |
| 765 // This code sets this up with the sequence: | 788 // This code sets this up with the sequence: |
| 766 // pushq rbp | 789 // pushq rbp |
| 767 // movq rbp, rsp | 790 // movq rbp, rsp |
| 768 // pushq immediate(0) | 791 // pushq immediate(0) |
| 769 // ..... | 792 // ..... |
| 770 void EnterStubFrame(); | 793 void EnterStubFrame(); |
| 794 void EnterStubFrameWithPP(); | |
| 771 | 795 |
| 772 // Instruction pattern from entrypoint is used in dart frame prologs | 796 // Instruction pattern from entrypoint is used in dart frame prologues |
| 773 // to set up the frame and save a PC which can be used to figure out the | 797 // to set up the frame and save a PC which can be used to figure out the |
| 774 // RawInstruction object corresponding to the code running in the frame. | 798 // RawInstruction object corresponding to the code running in the frame. |
| 775 // entrypoint: | 799 // entrypoint: |
| 776 // pushq rbp (size is 1 byte) | 800 // pushq rbp (size is 1 byte) |
| 777 // movq rbp, rsp (size is 3 bytes) | 801 // movq rbp, rsp (size is 3 bytes) |
| 778 // call L (size is 5 bytes) | 802 // call L (size is 5 bytes) |
| 779 // L: | 803 // L: |
| 780 static const intptr_t kEntryPointToPcMarkerOffset = 9; | 804 static const intptr_t kEntryPointToPcMarkerOffset = 9; |
| 781 | 805 |
| 782 // Inlined allocation of an instance of class 'cls', code has no runtime | 806 // Inlined allocation of an instance of class 'cls', code has no runtime |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 795 void Unreachable(const char* message); | 819 void Unreachable(const char* message); |
| 796 | 820 |
| 797 static void InitializeMemoryWithBreakpoints(uword data, int length); | 821 static void InitializeMemoryWithBreakpoints(uword data, int length); |
| 798 | 822 |
| 799 static const char* RegisterName(Register reg); | 823 static const char* RegisterName(Register reg); |
| 800 | 824 |
| 801 static const char* FpuRegisterName(FpuRegister reg); | 825 static const char* FpuRegisterName(FpuRegister reg); |
| 802 | 826 |
| 803 private: | 827 private: |
| 804 AssemblerBuffer buffer_; | 828 AssemblerBuffer buffer_; |
| 805 GrowableObjectArray& object_pool_; // Object pool is not used on x64. | 829 GrowableObjectArray& object_pool_; // Objects and patchable jump targets. |
| 806 int prologue_offset_; | 830 int prologue_offset_; |
| 807 | 831 |
| 808 class CodeComment : public ZoneAllocated { | 832 class CodeComment : public ZoneAllocated { |
| 809 public: | 833 public: |
| 810 CodeComment(intptr_t pc_offset, const String& comment) | 834 CodeComment(intptr_t pc_offset, const String& comment) |
| 811 : pc_offset_(pc_offset), comment_(comment) { } | 835 : pc_offset_(pc_offset), comment_(comment) { } |
| 812 | 836 |
| 813 intptr_t pc_offset() const { return pc_offset_; } | 837 intptr_t pc_offset() const { return pc_offset_; } |
| 814 const String& comment() const { return comment_; } | 838 const String& comment() const { return comment_; } |
| 815 | 839 |
| 816 private: | 840 private: |
| 817 intptr_t pc_offset_; | 841 intptr_t pc_offset_; |
| 818 const String& comment_; | 842 const String& comment_; |
| 819 | 843 |
| 820 DISALLOW_COPY_AND_ASSIGN(CodeComment); | 844 DISALLOW_COPY_AND_ASSIGN(CodeComment); |
| 821 }; | 845 }; |
| 822 | 846 |
| 823 GrowableArray<CodeComment*> comments_; | 847 GrowableArray<CodeComment*> comments_; |
| 824 | 848 |
| 849 intptr_t AddObject(const Object& obj); | |
| 850 intptr_t AddExternalLabel(const ExternalLabel* label, Patchability patchable); | |
| 851 void LoadExternalLabel(Register dst, | |
| 852 const ExternalLabel* label, | |
| 853 Patchability patchabe, | |
|
Florian Schneider
2013/09/05 10:57:45
s/patchabe/patchable/
zra
2013/09/05 20:29:26
Done.
| |
| 854 Register pp); | |
| 855 bool CanLoadFromObjectPool(const Object& object); | |
| 856 void LoadWordFromPoolOffset(Register dst, Register pp, int32_t offset); | |
| 857 | |
| 825 inline void EmitUint8(uint8_t value); | 858 inline void EmitUint8(uint8_t value); |
| 826 inline void EmitInt32(int32_t value); | 859 inline void EmitInt32(int32_t value); |
| 827 inline void EmitInt64(int64_t value); | 860 inline void EmitInt64(int64_t value); |
| 828 | 861 |
| 829 inline void EmitRegisterREX(Register reg, uint8_t rex); | 862 inline void EmitRegisterREX(Register reg, uint8_t rex); |
| 830 inline void EmitRegisterOperand(int rm, int reg); | 863 inline void EmitRegisterOperand(int rm, int reg); |
| 831 inline void EmitOperandREX(int rm, const Operand& operand, uint8_t rex); | 864 inline void EmitOperandREX(int rm, const Operand& operand, uint8_t rex); |
| 832 inline void EmitXmmRegisterOperand(int rm, XmmRegister reg); | 865 inline void EmitXmmRegisterOperand(int rm, XmmRegister reg); |
| 833 inline void EmitFixup(AssemblerFixup* fixup); | 866 inline void EmitFixup(AssemblerFixup* fixup); |
| 834 inline void EmitOperandSizeOverride(); | 867 inline void EmitOperandSizeOverride(); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 937 } | 970 } |
| 938 | 971 |
| 939 | 972 |
| 940 inline void Assembler::EmitOperandSizeOverride() { | 973 inline void Assembler::EmitOperandSizeOverride() { |
| 941 EmitUint8(0x66); | 974 EmitUint8(0x66); |
| 942 } | 975 } |
| 943 | 976 |
| 944 } // namespace dart | 977 } // namespace dart |
| 945 | 978 |
| 946 #endif // VM_ASSEMBLER_X64_H_ | 979 #endif // VM_ASSEMBLER_X64_H_ |
| OLD | NEW |