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_IA32_H_ | 5 #ifndef VM_ASSEMBLER_IA32_H_ |
6 #define VM_ASSEMBLER_IA32_H_ | 6 #define VM_ASSEMBLER_IA32_H_ |
7 | 7 |
8 #ifndef VM_ASSEMBLER_H_ | 8 #ifndef VM_ASSEMBLER_H_ |
9 #error Do not include assembler_ia32.h directly; use assembler.h instead. | 9 #error Do not include assembler_ia32.h directly; use assembler.h instead. |
10 #endif | 10 #endif |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 #endif | 304 #endif |
305 }; | 305 }; |
306 | 306 |
307 | 307 |
308 class Assembler : public ValueObject { | 308 class Assembler : public ValueObject { |
309 public: | 309 public: |
310 explicit Assembler(bool use_far_branches = false) | 310 explicit Assembler(bool use_far_branches = false) |
311 : buffer_(), | 311 : buffer_(), |
312 object_pool_(GrowableObjectArray::Handle()), | 312 object_pool_(GrowableObjectArray::Handle()), |
313 prologue_offset_(-1), | 313 prologue_offset_(-1), |
314 comments_(), | 314 comments_() { |
315 jit_cookie_(1017109444) { | |
316 // This mode is only needed and implemented for MIPS and ARM. | 315 // This mode is only needed and implemented for MIPS and ARM. |
317 ASSERT(!use_far_branches); | 316 ASSERT(!use_far_branches); |
318 } | 317 } |
319 ~Assembler() { } | 318 ~Assembler() { } |
320 | 319 |
321 static const bool kNearJump = true; | 320 static const bool kNearJump = true; |
322 static const bool kFarJump = false; | 321 static const bool kFarJump = false; |
323 | 322 |
324 /* | 323 /* |
325 * Emit Machine Instructions. | 324 * Emit Machine Instructions. |
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
630 // Issues a move instruction if 'to' is not the same as 'from'. | 629 // Issues a move instruction if 'to' is not the same as 'from'. |
631 void MoveRegister(Register to, Register from); | 630 void MoveRegister(Register to, Register from); |
632 void PopRegister(Register r); | 631 void PopRegister(Register r); |
633 | 632 |
634 void AddImmediate(Register reg, const Immediate& imm); | 633 void AddImmediate(Register reg, const Immediate& imm); |
635 | 634 |
636 void Drop(intptr_t stack_elements); | 635 void Drop(intptr_t stack_elements); |
637 | 636 |
638 void LoadObject(Register dst, const Object& object); | 637 void LoadObject(Register dst, const Object& object); |
639 | 638 |
640 // If 'object' is a large Smi, xor it with a per-assembler cookie value to | |
641 // prevent user-controlled immediates from appearing in the code stream. | |
642 void LoadObjectSafely(Register dst, const Object& object); | |
643 | |
644 void PushObject(const Object& object); | 639 void PushObject(const Object& object); |
645 void CompareObject(Register reg, const Object& object); | 640 void CompareObject(Register reg, const Object& object); |
646 void LoadDoubleConstant(XmmRegister dst, double value); | 641 void LoadDoubleConstant(XmmRegister dst, double value); |
647 | 642 |
648 void StoreIntoObject(Register object, // Object we are storing into. | 643 void StoreIntoObject(Register object, // Object we are storing into. |
649 const Address& dest, // Where we are storing into. | 644 const Address& dest, // Where we are storing into. |
650 Register value, // Value we are storing. | 645 Register value, // Value we are storing. |
651 bool can_value_be_smi = true); | 646 bool can_value_be_smi = true); |
652 | 647 |
653 void StoreIntoObjectNoBarrier(Register object, | 648 void StoreIntoObjectNoBarrier(Register object, |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
780 void Unreachable(const char* message); | 775 void Unreachable(const char* message); |
781 | 776 |
782 static void InitializeMemoryWithBreakpoints(uword data, intptr_t length); | 777 static void InitializeMemoryWithBreakpoints(uword data, intptr_t length); |
783 | 778 |
784 void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3); | 779 void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3); |
785 const Code::Comments& GetCodeComments() const; | 780 const Code::Comments& GetCodeComments() const; |
786 | 781 |
787 static const char* RegisterName(Register reg); | 782 static const char* RegisterName(Register reg); |
788 static const char* FpuRegisterName(FpuRegister reg); | 783 static const char* FpuRegisterName(FpuRegister reg); |
789 | 784 |
790 // Smis that do not fit into 17 bits (16 bits of payload) are unsafe. | |
791 static bool IsSafe(const Object& object) { | |
792 return !object.IsSmi() || | |
793 Utils::IsInt(17, reinterpret_cast<intptr_t>(object.raw())); | |
794 } | |
795 static bool IsSafeSmi(const Object& object) { | |
796 return object.IsSmi() && | |
797 Utils::IsInt(17, reinterpret_cast<intptr_t>(object.raw())); | |
798 } | |
799 | |
800 private: | 785 private: |
801 AssemblerBuffer buffer_; | 786 AssemblerBuffer buffer_; |
802 GrowableObjectArray& object_pool_; // Object pool is not used on ia32. | 787 GrowableObjectArray& object_pool_; // Object pool is not used on ia32. |
803 intptr_t prologue_offset_; | 788 intptr_t prologue_offset_; |
804 | 789 |
805 class CodeComment : public ZoneAllocated { | 790 class CodeComment : public ZoneAllocated { |
806 public: | 791 public: |
807 CodeComment(intptr_t pc_offset, const String& comment) | 792 CodeComment(intptr_t pc_offset, const String& comment) |
808 : pc_offset_(pc_offset), comment_(comment) { } | 793 : pc_offset_(pc_offset), comment_(comment) { } |
809 | 794 |
810 intptr_t pc_offset() const { return pc_offset_; } | 795 intptr_t pc_offset() const { return pc_offset_; } |
811 const String& comment() const { return comment_; } | 796 const String& comment() const { return comment_; } |
812 | 797 |
813 private: | 798 private: |
814 intptr_t pc_offset_; | 799 intptr_t pc_offset_; |
815 const String& comment_; | 800 const String& comment_; |
816 | 801 |
817 DISALLOW_COPY_AND_ASSIGN(CodeComment); | 802 DISALLOW_COPY_AND_ASSIGN(CodeComment); |
818 }; | 803 }; |
819 | 804 |
820 GrowableArray<CodeComment*> comments_; | 805 GrowableArray<CodeComment*> comments_; |
821 | 806 |
822 int32_t jit_cookie_; | |
823 | |
824 inline void EmitUint8(uint8_t value); | 807 inline void EmitUint8(uint8_t value); |
825 inline void EmitInt32(int32_t value); | 808 inline void EmitInt32(int32_t value); |
826 inline void EmitRegisterOperand(int rm, int reg); | 809 inline void EmitRegisterOperand(int rm, int reg); |
827 inline void EmitXmmRegisterOperand(int rm, XmmRegister reg); | 810 inline void EmitXmmRegisterOperand(int rm, XmmRegister reg); |
828 inline void EmitFixup(AssemblerFixup* fixup); | 811 inline void EmitFixup(AssemblerFixup* fixup); |
829 inline void EmitOperandSizeOverride(); | 812 inline void EmitOperandSizeOverride(); |
830 | 813 |
831 void EmitOperand(int rm, const Operand& operand); | 814 void EmitOperand(int rm, const Operand& operand); |
832 void EmitImmediate(const Immediate& imm); | 815 void EmitImmediate(const Immediate& imm); |
833 void EmitComplex(int rm, const Operand& operand, const Immediate& immediate); | 816 void EmitComplex(int rm, const Operand& operand, const Immediate& immediate); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
876 } | 859 } |
877 | 860 |
878 | 861 |
879 inline void Assembler::EmitOperandSizeOverride() { | 862 inline void Assembler::EmitOperandSizeOverride() { |
880 EmitUint8(0x66); | 863 EmitUint8(0x66); |
881 } | 864 } |
882 | 865 |
883 } // namespace dart | 866 } // namespace dart |
884 | 867 |
885 #endif // VM_ASSEMBLER_IA32_H_ | 868 #endif // VM_ASSEMBLER_IA32_H_ |
OLD | NEW |