| 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 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 | 341 |
| 342 intptr_t position_; | 342 intptr_t position_; |
| 343 intptr_t unresolved_; | 343 intptr_t unresolved_; |
| 344 intptr_t unresolved_near_positions_[kMaxUnresolvedBranches]; | 344 intptr_t unresolved_near_positions_[kMaxUnresolvedBranches]; |
| 345 | 345 |
| 346 friend class Assembler; | 346 friend class Assembler; |
| 347 DISALLOW_COPY_AND_ASSIGN(Label); | 347 DISALLOW_COPY_AND_ASSIGN(Label); |
| 348 }; | 348 }; |
| 349 | 349 |
| 350 | 350 |
| 351 enum RestorePP { |
| 352 kRestoreCallerPP, |
| 353 kKeepCalleePP |
| 354 }; |
| 355 |
| 356 |
| 351 class Assembler : public ValueObject { | 357 class Assembler : public ValueObject { |
| 352 public: | 358 public: |
| 353 explicit Assembler(bool use_far_branches = false); | 359 explicit Assembler(bool use_far_branches = false); |
| 354 | 360 |
| 355 ~Assembler() { } | 361 ~Assembler() { } |
| 356 | 362 |
| 357 static const bool kNearJump = true; | 363 static const bool kNearJump = true; |
| 358 static const bool kFarJump = false; | 364 static const bool kFarJump = false; |
| 359 | 365 |
| 360 /* | 366 /* |
| 361 * Emit Machine Instructions. | 367 * Emit Machine Instructions. |
| 362 */ | 368 */ |
| 363 void call(Register reg); | 369 void call(Register reg); |
| 364 void call(const Address& address); | 370 void call(const Address& address); |
| 365 void call(Label* label); | 371 void call(Label* label); |
| 366 void call(const ExternalLabel* label); | 372 void call(const ExternalLabel* label); |
| 367 | 373 |
| 368 static const intptr_t kCallExternalLabelSize = 7; | 374 static const intptr_t kCallExternalLabelSize = 19; |
| 369 | 375 |
| 370 void pushq(Register reg); | 376 void pushq(Register reg); |
| 371 void pushq(const Address& address); | 377 void pushq(const Address& address); |
| 372 void pushq(const Immediate& imm); | 378 void pushq(const Immediate& imm); |
| 373 void PushImmediate(const Immediate& imm, Register pp); | 379 void PushImmediate(const Immediate& imm, Register pp); |
| 374 | 380 |
| 375 void popq(Register reg); | 381 void popq(Register reg); |
| 376 void popq(const Address& address); | 382 void popq(const Address& address); |
| 377 | 383 |
| 378 void setcc(Condition condition, ByteRegister dst); | 384 void setcc(Condition condition, ByteRegister dst); |
| (...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 679 void fsin(); | 685 void fsin(); |
| 680 void fcos(); | 686 void fcos(); |
| 681 | 687 |
| 682 // 'size' indicates size in bytes and must be in the range 1..8. | 688 // 'size' indicates size in bytes and must be in the range 1..8. |
| 683 void nop(int size = 1); | 689 void nop(int size = 1); |
| 684 void int3(); | 690 void int3(); |
| 685 void hlt(); | 691 void hlt(); |
| 686 | 692 |
| 687 // Note: verified_mem mode forces far jumps. | 693 // Note: verified_mem mode forces far jumps. |
| 688 void j(Condition condition, Label* label, bool near = kFarJump); | 694 void j(Condition condition, Label* label, bool near = kFarJump); |
| 689 void j(Condition condition, const ExternalLabel* label); | |
| 690 | 695 |
| 691 void jmp(Register reg); | 696 void jmp(Register reg); |
| 692 void jmp(const Address& address); | 697 void jmp(const Address& address); |
| 693 // Note: verified_mem mode forces far jumps. | 698 // Note: verified_mem mode forces far jumps. |
| 694 void jmp(Label* label, bool near = kFarJump); | 699 void jmp(Label* label, bool near = kFarJump); |
| 695 void jmp(const ExternalLabel* label); | 700 void jmp(const ExternalLabel* label); |
| 696 | 701 |
| 697 void lock(); | 702 void lock(); |
| 698 void cmpxchgl(const Address& address, Register reg); | 703 void cmpxchgl(const Address& address, Register reg); |
| 699 void lock_cmpxchgl(const Address& address, Register reg) { | 704 void lock_cmpxchgl(const Address& address, Register reg) { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 759 } | 764 } |
| 760 | 765 |
| 761 bool CanLoadImmediateFromPool(const Immediate& imm, Register pp); | 766 bool CanLoadImmediateFromPool(const Immediate& imm, Register pp); |
| 762 void LoadImmediate(Register reg, const Immediate& imm, Register pp); | 767 void LoadImmediate(Register reg, const Immediate& imm, Register pp); |
| 763 void LoadIsolate(Register dst); | 768 void LoadIsolate(Register dst); |
| 764 void LoadObject(Register dst, const Object& obj, Register pp); | 769 void LoadObject(Register dst, const Object& obj, Register pp); |
| 765 void LoadExternalLabel(Register dst, | 770 void LoadExternalLabel(Register dst, |
| 766 const ExternalLabel* label, | 771 const ExternalLabel* label, |
| 767 Patchability patchable, | 772 Patchability patchable, |
| 768 Register pp); | 773 Register pp); |
| 769 void JmpPatchable(const ExternalLabel* label, Register pp); | 774 void JmpPatchable(const Code& target, Register pp); |
| 770 void Jmp(const ExternalLabel* label, Register pp); | 775 void Jmp(const Code& target, Register pp); |
| 771 void J(Condition condition, const ExternalLabel* label, Register pp); | 776 void J(Condition condition, const Code& target, Register pp); |
| 772 void CallPatchable(const ExternalLabel* label); | 777 void CallPatchable(const Code& target); |
| 773 void Call(const ExternalLabel* label, Register pp); | 778 void Call(const Code& target, Register pp); |
| 774 // Unaware of write barrier (use StoreInto* methods for storing to objects). | 779 // Unaware of write barrier (use StoreInto* methods for storing to objects). |
| 775 // TODO(koda): Add StackAddress/HeapAddress types to prevent misuse. | 780 // TODO(koda): Add StackAddress/HeapAddress types to prevent misuse. |
| 776 void StoreObject(const Address& dst, const Object& obj, Register pp); | 781 void StoreObject(const Address& dst, const Object& obj, Register pp); |
| 777 void PushObject(const Object& object, Register pp); | 782 void PushObject(const Object& object, Register pp); |
| 778 void CompareObject(Register reg, const Object& object, Register pp); | 783 void CompareObject(Register reg, const Object& object, Register pp); |
| 779 | 784 |
| 780 // When storing into a heap object field, knowledge of the previous content | 785 // When storing into a heap object field, knowledge of the previous content |
| 781 // is expressed through these constants. | 786 // is expressed through these constants. |
| 782 enum FieldContent { | 787 enum FieldContent { |
| 783 kEmptyOrSmiOrNull, // Empty = garbage/zapped in release/debug mode. | 788 kEmptyOrSmiOrNull, // Empty = garbage/zapped in release/debug mode. |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 824 void DoubleAbs(XmmRegister reg); | 829 void DoubleAbs(XmmRegister reg); |
| 825 | 830 |
| 826 void LockCmpxchgq(const Address& address, Register reg) { | 831 void LockCmpxchgq(const Address& address, Register reg) { |
| 827 lock(); | 832 lock(); |
| 828 cmpxchgq(address, reg); | 833 cmpxchgq(address, reg); |
| 829 } | 834 } |
| 830 | 835 |
| 831 void PushRegisters(intptr_t cpu_register_set, intptr_t xmm_register_set); | 836 void PushRegisters(intptr_t cpu_register_set, intptr_t xmm_register_set); |
| 832 void PopRegisters(intptr_t cpu_register_set, intptr_t xmm_register_set); | 837 void PopRegisters(intptr_t cpu_register_set, intptr_t xmm_register_set); |
| 833 | 838 |
| 839 void CheckCodePointer(); |
| 840 |
| 834 void EnterFrame(intptr_t frame_space); | 841 void EnterFrame(intptr_t frame_space); |
| 835 void LeaveFrame(); | 842 void LeaveFrame(); |
| 836 void ReserveAlignedFrameSpace(intptr_t frame_space); | 843 void ReserveAlignedFrameSpace(intptr_t frame_space); |
| 837 | 844 |
| 838 // Create a frame for calling into runtime that preserves all volatile | 845 // Create a frame for calling into runtime that preserves all volatile |
| 839 // registers. Frame's RSP is guaranteed to be correctly aligned and | 846 // registers. Frame's RSP is guaranteed to be correctly aligned and |
| 840 // frame_space bytes are reserved under it. | 847 // frame_space bytes are reserved under it. |
| 841 void EnterCallRuntimeFrame(intptr_t frame_space); | 848 void EnterCallRuntimeFrame(intptr_t frame_space); |
| 842 void LeaveCallRuntimeFrame(); | 849 void LeaveCallRuntimeFrame(); |
| 843 | 850 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 914 ObjectPoolWrapper& object_pool_wrapper() { return object_pool_wrapper_; } | 921 ObjectPoolWrapper& object_pool_wrapper() { return object_pool_wrapper_; } |
| 915 | 922 |
| 916 RawObjectPool* MakeObjectPool() { | 923 RawObjectPool* MakeObjectPool() { |
| 917 return object_pool_wrapper_.MakeObjectPool(); | 924 return object_pool_wrapper_.MakeObjectPool(); |
| 918 } | 925 } |
| 919 | 926 |
| 920 void FinalizeInstructions(const MemoryRegion& region) { | 927 void FinalizeInstructions(const MemoryRegion& region) { |
| 921 buffer_.FinalizeInstructions(region); | 928 buffer_.FinalizeInstructions(region); |
| 922 } | 929 } |
| 923 | 930 |
| 931 void RestoreCodePointer(); |
| 924 void LoadPoolPointer(Register pp); | 932 void LoadPoolPointer(Register pp); |
| 925 | 933 |
| 926 // Set up a Dart frame on entry with a frame pointer and PC information to | 934 // Set up a Dart frame on entry with a frame pointer and PC information to |
| 927 // enable easy access to the RawInstruction object of code corresponding | 935 // enable easy access to the RawInstruction object of code corresponding |
| 928 // to this frame. | 936 // to this frame. |
| 929 // The dart frame layout is as follows: | 937 // The dart frame layout is as follows: |
| 930 // .... | 938 // .... |
| 931 // locals space <=== RSP | 939 // locals space <=== RSP |
| 932 // saved PP | 940 // saved PP |
| 933 // pc (used to derive the RawInstruction Object of the dart code) | 941 // pc (used to derive the RawInstruction Object of the dart code) |
| 934 // saved RBP <=== RBP | 942 // saved RBP <=== RBP |
| 935 // ret PC | 943 // ret PC |
| 936 // ..... | 944 // ..... |
| 937 // This code sets this up with the sequence: | 945 // This code sets this up with the sequence: |
| 938 // pushq rbp | 946 // pushq rbp |
| 939 // movq rbp, rsp | 947 // movq rbp, rsp |
| 940 // call L | 948 // call L |
| 941 // L: <code to adjust saved pc if there is any intrinsification code> | 949 // L: <code to adjust saved pc if there is any intrinsification code> |
| 942 // ... | 950 // ... |
| 943 // pushq r15 | 951 // pushq r15 |
| 944 // ..... | 952 // ..... |
| 945 void EnterDartFrame(intptr_t frame_size); | 953 void EnterDartFrame(intptr_t frame_size, Register new_pp); |
| 946 void EnterDartFrameWithInfo(intptr_t frame_size, | 954 void LeaveDartFrame(RestorePP restore_pp = kRestoreCallerPP); |
| 947 Register new_pp, Register pc_marker_override); | |
| 948 void LeaveDartFrame(); | |
| 949 | 955 |
| 950 // Set up a Dart frame for a function compiled for on-stack replacement. | 956 // Set up a Dart frame for a function compiled for on-stack replacement. |
| 951 // The frame layout is a normal Dart frame, but the frame is partially set | 957 // The frame layout is a normal Dart frame, but the frame is partially set |
| 952 // up on entry (it is the frame of the unoptimized code). | 958 // up on entry (it is the frame of the unoptimized code). |
| 953 void EnterOsrFrame(intptr_t extra_size, | 959 void EnterOsrFrame(intptr_t extra_size); |
| 954 Register new_pp, Register pc_marker_override); | |
| 955 | 960 |
| 956 // Set up a stub frame so that the stack traversal code can easily identify | 961 // Set up a stub frame so that the stack traversal code can easily identify |
| 957 // a stub frame. | 962 // a stub frame. |
| 958 // The stub frame layout is as follows: | 963 // The stub frame layout is as follows: |
| 959 // .... <=== RSP | 964 // .... <=== RSP |
| 960 // pc (used to derive the RawInstruction Object of the stub) | 965 // pc (used to derive the RawInstruction Object of the stub) |
| 961 // saved RBP <=== RBP | 966 // saved RBP <=== RBP |
| 962 // ret PC | 967 // ret PC |
| 963 // ..... | 968 // ..... |
| 964 // This code sets this up with the sequence: | 969 // This code sets this up with the sequence: |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1199 } | 1204 } |
| 1200 | 1205 |
| 1201 | 1206 |
| 1202 inline void Assembler::EmitOperandSizeOverride() { | 1207 inline void Assembler::EmitOperandSizeOverride() { |
| 1203 EmitUint8(0x66); | 1208 EmitUint8(0x66); |
| 1204 } | 1209 } |
| 1205 | 1210 |
| 1206 } // namespace dart | 1211 } // namespace dart |
| 1207 | 1212 |
| 1208 #endif // VM_ASSEMBLER_X64_H_ | 1213 #endif // VM_ASSEMBLER_X64_H_ |
| OLD | NEW |