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

Side by Side Diff: runtime/vm/assembler_ia32.h

Issue 2481873005: clang-format runtime/vm (Closed)
Patch Set: Merge Created 4 years, 1 month 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 | « runtime/vm/assembler_dbc_test.cc ('k') | runtime/vm/assembler_ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 RUNTIME_VM_ASSEMBLER_IA32_H_ 5 #ifndef RUNTIME_VM_ASSEMBLER_IA32_H_
6 #define RUNTIME_VM_ASSEMBLER_IA32_H_ 6 #define RUNTIME_VM_ASSEMBLER_IA32_H_
7 7
8 #ifndef RUNTIME_VM_ASSEMBLER_H_ 8 #ifndef RUNTIME_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
11 11
12 #include "platform/assert.h" 12 #include "platform/assert.h"
13 #include "platform/utils.h" 13 #include "platform/utils.h"
14 #include "vm/constants_ia32.h" 14 #include "vm/constants_ia32.h"
15 15
16 namespace dart { 16 namespace dart {
17 17
18 // Forward declarations. 18 // Forward declarations.
19 class RuntimeEntry; 19 class RuntimeEntry;
20 class StubEntry; 20 class StubEntry;
21 21
22 class Immediate : public ValueObject { 22 class Immediate : public ValueObject {
23 public: 23 public:
24 explicit Immediate(int32_t value) : value_(value) { } 24 explicit Immediate(int32_t value) : value_(value) {}
25 25
26 Immediate(const Immediate& other) : ValueObject(), value_(other.value_) { } 26 Immediate(const Immediate& other) : ValueObject(), value_(other.value_) {}
27 27
28 int32_t value() const { return value_; } 28 int32_t value() const { return value_; }
29 29
30 bool is_int8() const { return Utils::IsInt(8, value_); } 30 bool is_int8() const { return Utils::IsInt(8, value_); }
31 bool is_uint8() const { return Utils::IsUint(8, value_); } 31 bool is_uint8() const { return Utils::IsUint(8, value_); }
32 bool is_uint16() const { return Utils::IsUint(16, value_); } 32 bool is_uint16() const { return Utils::IsUint(16, value_); }
33 33
34 private: 34 private:
35 const int32_t value_; 35 const int32_t value_;
36 36
37 // TODO(5411081): Add DISALLOW_COPY_AND_ASSIGN(Immediate) once the mac 37 // TODO(5411081): Add DISALLOW_COPY_AND_ASSIGN(Immediate) once the mac
38 // build issue is resolved. 38 // build issue is resolved.
39 // And remove the unnecessary copy constructor. 39 // And remove the unnecessary copy constructor.
40 }; 40 };
41 41
42 42
43 class Operand : public ValueObject { 43 class Operand : public ValueObject {
44 public: 44 public:
45 uint8_t mod() const { 45 uint8_t mod() const { return (encoding_at(0) >> 6) & 3; }
46 return (encoding_at(0) >> 6) & 3;
47 }
48 46
49 Register rm() const { 47 Register rm() const { return static_cast<Register>(encoding_at(0) & 7); }
50 return static_cast<Register>(encoding_at(0) & 7);
51 }
52 48
53 ScaleFactor scale() const { 49 ScaleFactor scale() const {
54 return static_cast<ScaleFactor>((encoding_at(1) >> 6) & 3); 50 return static_cast<ScaleFactor>((encoding_at(1) >> 6) & 3);
55 } 51 }
56 52
57 Register index() const { 53 Register index() const {
58 return static_cast<Register>((encoding_at(1) >> 3) & 7); 54 return static_cast<Register>((encoding_at(1) >> 3) & 7);
59 } 55 }
60 56
61 Register base() const { 57 Register base() const { return static_cast<Register>(encoding_at(1) & 7); }
62 return static_cast<Register>(encoding_at(1) & 7);
63 }
64 58
65 int8_t disp8() const { 59 int8_t disp8() const {
66 ASSERT(length_ >= 2); 60 ASSERT(length_ >= 2);
67 return static_cast<int8_t>(encoding_[length_ - 1]); 61 return static_cast<int8_t>(encoding_[length_ - 1]);
68 } 62 }
69 63
70 int32_t disp32() const { 64 int32_t disp32() const {
71 ASSERT(length_ >= 5); 65 ASSERT(length_ >= 5);
72 return bit_copy<int32_t>(encoding_[length_ - 4]); 66 return bit_copy<int32_t>(encoding_[length_ - 4]);
73 } 67 }
(...skipping 10 matching lines...) Expand all
84 78
85 bool Equals(const Operand& other) const { 79 bool Equals(const Operand& other) const {
86 if (length_ != other.length_) return false; 80 if (length_ != other.length_) return false;
87 for (uint8_t i = 0; i < length_; i++) { 81 for (uint8_t i = 0; i < length_; i++) {
88 if (encoding_[i] != other.encoding_[i]) return false; 82 if (encoding_[i] != other.encoding_[i]) return false;
89 } 83 }
90 return true; 84 return true;
91 } 85 }
92 86
93 protected: 87 protected:
94 Operand() : length_(0) { } // Needed by subclass Address. 88 Operand() : length_(0) {} // Needed by subclass Address.
95 89
96 void SetModRM(int mod, Register rm) { 90 void SetModRM(int mod, Register rm) {
97 ASSERT((mod & ~3) == 0); 91 ASSERT((mod & ~3) == 0);
98 encoding_[0] = (mod << 6) | rm; 92 encoding_[0] = (mod << 6) | rm;
99 length_ = 1; 93 length_ = 1;
100 } 94 }
101 95
102 void SetSIB(ScaleFactor scale, Register index, Register base) { 96 void SetSIB(ScaleFactor scale, Register index, Register base) {
103 ASSERT(length_ == 1); 97 ASSERT(length_ == 1);
104 ASSERT((scale & ~3) == 0); 98 ASSERT((scale & ~3) == 0);
(...skipping 23 matching lines...) Expand all
128 // Get the operand encoding byte at the given index. 122 // Get the operand encoding byte at the given index.
129 uint8_t encoding_at(intptr_t index) const { 123 uint8_t encoding_at(intptr_t index) const {
130 ASSERT(index >= 0 && index < length_); 124 ASSERT(index >= 0 && index < length_);
131 return encoding_[index]; 125 return encoding_[index];
132 } 126 }
133 127
134 // Returns whether or not this operand is really the given register in 128 // Returns whether or not this operand is really the given register in
135 // disguise. Used from the assembler to generate better encodings. 129 // disguise. Used from the assembler to generate better encodings.
136 bool IsRegister(Register reg) const { 130 bool IsRegister(Register reg) const {
137 return ((encoding_[0] & 0xF8) == 0xC0) // Addressing mode is register only. 131 return ((encoding_[0] & 0xF8) == 0xC0) // Addressing mode is register only.
138 && ((encoding_[0] & 0x07) == reg); // Register codes match. 132 && ((encoding_[0] & 0x07) == reg); // Register codes match.
139 } 133 }
140 134
141 friend class Assembler; 135 friend class Assembler;
142 }; 136 };
143 137
144 138
145 class Address : public Operand { 139 class Address : public Operand {
146 public: 140 public:
147 Address(Register base, int32_t disp) { 141 Address(Register base, int32_t disp) {
148 if (disp == 0 && base != EBP) { 142 if (disp == 0 && base != EBP) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 } else { 175 } else {
182 SetModRM(2, ESP); 176 SetModRM(2, ESP);
183 SetSIB(scale, index, base); 177 SetSIB(scale, index, base);
184 SetDisp32(disp); 178 SetDisp32(disp);
185 } 179 }
186 } 180 }
187 181
188 // This addressing mode does not exist. 182 // This addressing mode does not exist.
189 Address(Register base, Register index, ScaleFactor scale, Register r); 183 Address(Register base, Register index, ScaleFactor scale, Register r);
190 184
191 Address(const Address& other) : Operand(other) { } 185 Address(const Address& other) : Operand(other) {}
192 186
193 Address& operator=(const Address& other) { 187 Address& operator=(const Address& other) {
194 Operand::operator=(other); 188 Operand::operator=(other);
195 return *this; 189 return *this;
196 } 190 }
197 191
198 static Address Absolute(const uword addr) { 192 static Address Absolute(const uword addr) {
199 Address result; 193 Address result;
200 result.SetModRM(0, EBP); 194 result.SetModRM(0, EBP);
201 result.SetDisp32(addr); 195 result.SetDisp32(addr);
202 return result; 196 return result;
203 } 197 }
204 198
205 private: 199 private:
206 Address() { } // Needed by Address::Absolute. 200 Address() {} // Needed by Address::Absolute.
207 }; 201 };
208 202
209 203
210 class FieldAddress : public Address { 204 class FieldAddress : public Address {
211 public: 205 public:
212 FieldAddress(Register base, int32_t disp) 206 FieldAddress(Register base, int32_t disp)
213 : Address(base, disp - kHeapObjectTag) { } 207 : Address(base, disp - kHeapObjectTag) {}
214 208
215 // This addressing mode does not exist. 209 // This addressing mode does not exist.
216 FieldAddress(Register base, Register r); 210 FieldAddress(Register base, Register r);
217 211
218 FieldAddress(Register base, Register index, ScaleFactor scale, int32_t disp) 212 FieldAddress(Register base, Register index, ScaleFactor scale, int32_t disp)
219 : Address(base, index, scale, disp - kHeapObjectTag) { } 213 : Address(base, index, scale, disp - kHeapObjectTag) {}
220 214
221 // This addressing mode does not exist. 215 // This addressing mode does not exist.
222 FieldAddress(Register base, Register index, ScaleFactor scale, Register r); 216 FieldAddress(Register base, Register index, ScaleFactor scale, Register r);
223 217
224 FieldAddress(const FieldAddress& other) : Address(other) { } 218 FieldAddress(const FieldAddress& other) : Address(other) {}
225 219
226 FieldAddress& operator=(const FieldAddress& other) { 220 FieldAddress& operator=(const FieldAddress& other) {
227 Address::operator=(other); 221 Address::operator=(other);
228 return *this; 222 return *this;
229 } 223 }
230 }; 224 };
231 225
232 226
233 class Label : public ValueObject { 227 class Label : public ValueObject {
234 public: 228 public:
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 public: 297 public:
304 explicit Assembler(bool use_far_branches = false) 298 explicit Assembler(bool use_far_branches = false)
305 : buffer_(), 299 : buffer_(),
306 prologue_offset_(-1), 300 prologue_offset_(-1),
307 jit_cookie_(0), 301 jit_cookie_(0),
308 comments_(), 302 comments_(),
309 code_(Code::ZoneHandle()) { 303 code_(Code::ZoneHandle()) {
310 // This mode is only needed and implemented for MIPS and ARM. 304 // This mode is only needed and implemented for MIPS and ARM.
311 ASSERT(!use_far_branches); 305 ASSERT(!use_far_branches);
312 } 306 }
313 ~Assembler() { } 307 ~Assembler() {}
314 308
315 static const bool kNearJump = true; 309 static const bool kNearJump = true;
316 static const bool kFarJump = false; 310 static const bool kFarJump = false;
317 311
318 /* 312 /*
319 * Emit Machine Instructions. 313 * Emit Machine Instructions.
320 */ 314 */
321 void call(Register reg); 315 void call(Register reg);
322 void call(const Address& address); 316 void call(const Address& address);
323 void call(Label* label); 317 void call(Label* label);
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 void orpd(XmmRegister dst, XmmRegister src); 485 void orpd(XmmRegister dst, XmmRegister src);
492 486
493 void pextrd(Register dst, XmmRegister src, const Immediate& imm); 487 void pextrd(Register dst, XmmRegister src, const Immediate& imm);
494 void pmovsxdq(XmmRegister dst, XmmRegister src); 488 void pmovsxdq(XmmRegister dst, XmmRegister src);
495 void pcmpeqq(XmmRegister dst, XmmRegister src); 489 void pcmpeqq(XmmRegister dst, XmmRegister src);
496 490
497 void pxor(XmmRegister dst, XmmRegister src); 491 void pxor(XmmRegister dst, XmmRegister src);
498 492
499 enum RoundingMode { 493 enum RoundingMode {
500 kRoundToNearest = 0x0, 494 kRoundToNearest = 0x0,
501 kRoundDown = 0x1, 495 kRoundDown = 0x1,
502 kRoundUp = 0x2, 496 kRoundUp = 0x2,
503 kRoundToZero = 0x3 497 kRoundToZero = 0x3
504 }; 498 };
505 void roundsd(XmmRegister dst, XmmRegister src, RoundingMode mode); 499 void roundsd(XmmRegister dst, XmmRegister src, RoundingMode mode);
506 500
507 void flds(const Address& src); 501 void flds(const Address& src);
508 void fstps(const Address& dst); 502 void fstps(const Address& dst);
509 503
510 void fldl(const Address& src); 504 void fldl(const Address& src);
511 void fstpl(const Address& dst); 505 void fstpl(const Address& dst);
512 506
513 void fnstcw(const Address& dst); 507 void fnstcw(const Address& dst);
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 void leave(); 619 void leave();
626 620
627 void ret(); 621 void ret();
628 void ret(const Immediate& imm); 622 void ret(const Immediate& imm);
629 623
630 // 'size' indicates size in bytes and must be in the range 1..8. 624 // 'size' indicates size in bytes and must be in the range 1..8.
631 void nop(int size = 1); 625 void nop(int size = 1);
632 void int3(); 626 void int3();
633 void hlt(); 627 void hlt();
634 628
635 static uword GetBreakInstructionFiller() { 629 static uword GetBreakInstructionFiller() { return 0xCCCCCCCC; }
636 return 0xCCCCCCCC;
637 }
638 630
639 void j(Condition condition, Label* label, bool near = kFarJump); 631 void j(Condition condition, Label* label, bool near = kFarJump);
640 void j(Condition condition, const ExternalLabel* label); 632 void j(Condition condition, const ExternalLabel* label);
641 633
642 void jmp(Register reg); 634 void jmp(Register reg);
643 void jmp(Label* label, bool near = kFarJump); 635 void jmp(Label* label, bool near = kFarJump);
644 void jmp(const ExternalLabel* label); 636 void jmp(const ExternalLabel* label);
645 637
646 void lock(); 638 void lock();
647 void cmpxchgl(const Address& address, Register reg); 639 void cmpxchgl(const Address& address, Register reg);
(...skipping 20 matching lines...) Expand all
668 void LoadObject(Register dst, const Object& object); 660 void LoadObject(Register dst, const Object& object);
669 661
670 // If 'object' is a large Smi, xor it with a per-assembler cookie value to 662 // If 'object' is a large Smi, xor it with a per-assembler cookie value to
671 // prevent user-controlled immediates from appearing in the code stream. 663 // prevent user-controlled immediates from appearing in the code stream.
672 void LoadObjectSafely(Register dst, const Object& object); 664 void LoadObjectSafely(Register dst, const Object& object);
673 665
674 void PushObject(const Object& object); 666 void PushObject(const Object& object);
675 void CompareObject(Register reg, const Object& object); 667 void CompareObject(Register reg, const Object& object);
676 void LoadDoubleConstant(XmmRegister dst, double value); 668 void LoadDoubleConstant(XmmRegister dst, double value);
677 669
678 void StoreIntoObject(Register object, // Object we are storing into. 670 void StoreIntoObject(Register object, // Object we are storing into.
679 const Address& dest, // Where we are storing into. 671 const Address& dest, // Where we are storing into.
680 Register value, // Value we are storing. 672 Register value, // Value we are storing.
681 bool can_value_be_smi = true); 673 bool can_value_be_smi = true);
682 674
683 void StoreIntoObjectNoBarrier(Register object, 675 void StoreIntoObjectNoBarrier(Register object,
684 const Address& dest, 676 const Address& dest,
685 Register value); 677 Register value);
686 void StoreIntoObjectNoBarrier(Register object, 678 void StoreIntoObjectNoBarrier(Register object,
687 const Address& dest, 679 const Address& dest,
688 const Object& value); 680 const Object& value);
689 681
690 // Stores a Smi value into a heap object field that always contains a Smi. 682 // Stores a Smi value into a heap object field that always contains a Smi.
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
752 Register array, 744 Register array,
753 Register index); 745 Register index);
754 746
755 static Address VMTagAddress() { 747 static Address VMTagAddress() {
756 return Address(THR, Thread::vm_tag_offset()); 748 return Address(THR, Thread::vm_tag_offset());
757 } 749 }
758 750
759 /* 751 /*
760 * Misc. functionality 752 * Misc. functionality
761 */ 753 */
762 void SmiTag(Register reg) { 754 void SmiTag(Register reg) { addl(reg, reg); }
763 addl(reg, reg);
764 }
765 755
766 void SmiUntag(Register reg) { 756 void SmiUntag(Register reg) { sarl(reg, Immediate(kSmiTagSize)); }
767 sarl(reg, Immediate(kSmiTagSize));
768 }
769 757
770 void BranchIfNotSmi(Register reg, Label* label) { 758 void BranchIfNotSmi(Register reg, Label* label) {
771 testl(reg, Immediate(kSmiTagMask)); 759 testl(reg, Immediate(kSmiTagMask));
772 j(NOT_ZERO, label); 760 j(NOT_ZERO, label);
773 } 761 }
774 762
775 void Align(intptr_t alignment, intptr_t offset); 763 void Align(intptr_t alignment, intptr_t offset);
776 void Bind(Label* label); 764 void Bind(Label* label);
777 void Jump(Label* label) { jmp(label); } 765 void Jump(Label* label) { jmp(label); }
778 766
779 // Address of code at offset. 767 // Address of code at offset.
780 uword CodeAddress(intptr_t offset) { 768 uword CodeAddress(intptr_t offset) { return buffer_.Address(offset); }
781 return buffer_.Address(offset);
782 }
783 769
784 intptr_t CodeSize() const { return buffer_.Size(); } 770 intptr_t CodeSize() const { return buffer_.Size(); }
785 intptr_t prologue_offset() const { return prologue_offset_; } 771 intptr_t prologue_offset() const { return prologue_offset_; }
786 bool has_single_entry_point() const { return true; } 772 bool has_single_entry_point() const { return true; }
787 773
788 // Count the fixups that produce a pointer offset, without processing 774 // Count the fixups that produce a pointer offset, without processing
789 // the fixups. 775 // the fixups.
790 intptr_t CountPointerOffsets() const { 776 intptr_t CountPointerOffsets() const { return buffer_.CountPointerOffsets(); }
791 return buffer_.CountPointerOffsets();
792 }
793 const ZoneGrowableArray<intptr_t>& GetPointerOffsets() const { 777 const ZoneGrowableArray<intptr_t>& GetPointerOffsets() const {
794 return buffer_.pointer_offsets(); 778 return buffer_.pointer_offsets();
795 } 779 }
796 780
797 ObjectPoolWrapper& object_pool_wrapper() { return object_pool_wrapper_; } 781 ObjectPoolWrapper& object_pool_wrapper() { return object_pool_wrapper_; }
798 782
799 RawObjectPool* MakeObjectPool() { 783 RawObjectPool* MakeObjectPool() {
800 return object_pool_wrapper_.MakeObjectPool(); 784 return object_pool_wrapper_.MakeObjectPool();
801 } 785 }
802 786
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
925 if (Utils::IsPowerOfTwo(value) || Utils::IsPowerOfTwo(value + 1)) { 909 if (Utils::IsPowerOfTwo(value) || Utils::IsPowerOfTwo(value + 1)) {
926 return true; 910 return true;
927 } 911 }
928 912
929 return false; 913 return false;
930 } 914 }
931 static bool IsSafe(const Object& object) { 915 static bool IsSafe(const Object& object) {
932 return !object.IsSmi() || IsSafeSmi(object); 916 return !object.IsSmi() || IsSafeSmi(object);
933 } 917 }
934 918
935 void set_code_object(const Code& code) { 919 void set_code_object(const Code& code) { code_ ^= code.raw(); }
936 code_ ^= code.raw();
937 }
938 920
939 void PushCodeObject(); 921 void PushCodeObject();
940 922
941 private: 923 private:
942 class CodeComment : public ZoneAllocated { 924 class CodeComment : public ZoneAllocated {
943 public: 925 public:
944 CodeComment(intptr_t pc_offset, const String& comment) 926 CodeComment(intptr_t pc_offset, const String& comment)
945 : pc_offset_(pc_offset), comment_(comment) { } 927 : pc_offset_(pc_offset), comment_(comment) {}
946 928
947 intptr_t pc_offset() const { return pc_offset_; } 929 intptr_t pc_offset() const { return pc_offset_; }
948 const String& comment() const { return comment_; } 930 const String& comment() const { return comment_; }
949 931
950 private: 932 private:
951 intptr_t pc_offset_; 933 intptr_t pc_offset_;
952 const String& comment_; 934 const String& comment_;
953 935
954 DISALLOW_COPY_AND_ASSIGN(CodeComment); 936 DISALLOW_COPY_AND_ASSIGN(CodeComment);
955 }; 937 };
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1020 } 1002 }
1021 1003
1022 1004
1023 inline void Assembler::EmitOperandSizeOverride() { 1005 inline void Assembler::EmitOperandSizeOverride() {
1024 EmitUint8(0x66); 1006 EmitUint8(0x66);
1025 } 1007 }
1026 1008
1027 } // namespace dart 1009 } // namespace dart
1028 1010
1029 #endif // RUNTIME_VM_ASSEMBLER_IA32_H_ 1011 #endif // RUNTIME_VM_ASSEMBLER_IA32_H_
OLDNEW
« no previous file with comments | « runtime/vm/assembler_dbc_test.cc ('k') | runtime/vm/assembler_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698