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

Side by Side Diff: src/assembler_ia32.h

Issue 643903006: Subzero: Do class definition cleanups for assembler files too. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: stuff Created 6 years, 2 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
« no previous file with comments | « src/assembler.cpp ('k') | src/assembler_ia32.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/assembler_ia32.h - Assembler for x86-32 ------*- C++ -*-===//
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 2 // 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 3 // 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. 4 // BSD-style license that can be found in the LICENSE file.
4 // 5 //
5 // Modified by the Subzero authors. 6 // Modified by the Subzero authors.
6 // 7 //
7 //===- subzero/src/assembler_ia32.h - Assembler for x86-32 ----------------===// 8 //===----------------------------------------------------------------------===//
8 // 9 //
9 // The Subzero Code Generator 10 // The Subzero Code Generator
10 // 11 //
11 // This file is distributed under the University of Illinois Open Source 12 // This file is distributed under the University of Illinois Open Source
12 // License. See LICENSE.TXT for details. 13 // License. See LICENSE.TXT for details.
13 // 14 //
14 //===----------------------------------------------------------------------===// 15 //===----------------------------------------------------------------------===//
15 // 16 //
16 // This file implements the Assembler class for x86-32. 17 // This file implements the Assembler class for x86-32.
17 // 18 //
(...skipping 20 matching lines...) Expand all
38 using RegX8632::ByteRegister; 39 using RegX8632::ByteRegister;
39 using RegX8632::X87STRegister; 40 using RegX8632::X87STRegister;
40 41
41 namespace x86 { 42 namespace x86 {
42 43
43 const int MAX_NOP_SIZE = 8; 44 const int MAX_NOP_SIZE = 8;
44 45
45 enum ScaleFactor { TIMES_1 = 0, TIMES_2 = 1, TIMES_4 = 2, TIMES_8 = 3 }; 46 enum ScaleFactor { TIMES_1 = 0, TIMES_2 = 1, TIMES_4 = 2, TIMES_8 = 3 };
46 47
47 class DisplacementRelocation : public AssemblerFixup { 48 class DisplacementRelocation : public AssemblerFixup {
49 DisplacementRelocation(const DisplacementRelocation &) = delete;
50 DisplacementRelocation &operator=(const DisplacementRelocation &) = delete;
51
48 public: 52 public:
49 static DisplacementRelocation *create(Assembler *Asm, FixupKind Kind, 53 static DisplacementRelocation *create(Assembler *Asm, FixupKind Kind,
50 const ConstantRelocatable *Sym) { 54 const ConstantRelocatable *Sym) {
51 return new (Asm->Allocate<DisplacementRelocation>()) 55 return new (Asm->Allocate<DisplacementRelocation>())
52 DisplacementRelocation(Kind, Sym); 56 DisplacementRelocation(Kind, Sym);
53 } 57 }
54 58
55 void Process(const MemoryRegion &region, intptr_t position) override { 59 void Process(const MemoryRegion &region, intptr_t position) override {
56 (void)region; 60 (void)region;
57 (void)position; 61 (void)position;
58 llvm_unreachable("We might not be using this Process() method later."); 62 llvm_unreachable("We might not be using this Process() method later.");
59 } 63 }
60 64
61 private: 65 private:
62 DisplacementRelocation(FixupKind Kind, const ConstantRelocatable *Sym) 66 DisplacementRelocation(FixupKind Kind, const ConstantRelocatable *Sym)
63 : AssemblerFixup(Kind, Sym) {} 67 : AssemblerFixup(Kind, Sym) {}
64 DisplacementRelocation(const DisplacementRelocation &) = delete;
65 DisplacementRelocation &operator=(const DisplacementRelocation &) = delete;
66 }; 68 };
67 69
68 class Immediate { 70 class Immediate {
71 Immediate(const Immediate &) = delete;
72 Immediate &operator=(const Immediate &) = delete;
73
69 public: 74 public:
70 explicit Immediate(int32_t value) : value_(value), fixup_(NULL) {} 75 explicit Immediate(int32_t value) : value_(value), fixup_(NULL) {}
71 76
72 explicit Immediate(const Immediate &other)
73 : value_(other.value_), fixup_(other.fixup_) {}
74
75 explicit Immediate(AssemblerFixup *fixup) 77 explicit Immediate(AssemblerFixup *fixup)
76 : value_(fixup->value()->getOffset()), fixup_(fixup) { 78 : value_(fixup->value()->getOffset()), fixup_(fixup) {
77 // Use the Offset in the "value" for now. If the symbol is part of 79 // Use the Offset in the "value" for now. If the symbol is part of
78 // ".bss", then the relocation's symbol will be plain ".bss" and 80 // ".bss", then the relocation's symbol will be plain ".bss" and
79 // the value will need to be adjusted further to be sym's 81 // the value will need to be adjusted further to be sym's
80 // bss offset + Offset. 82 // bss offset + Offset.
81 } 83 }
82 84
83 int32_t value() const { return value_; } 85 int32_t value() const { return value_; }
84 AssemblerFixup *fixup() const { return fixup_; } 86 AssemblerFixup *fixup() const { return fixup_; }
85 87
86 bool is_int8() const { 88 bool is_int8() const {
87 // We currently only allow 32-bit fixups, and they usually have value = 0, 89 // We currently only allow 32-bit fixups, and they usually have value = 0,
88 // so if fixup_ != NULL, it shouldn't be classified as int8/16. 90 // so if fixup_ != NULL, it shouldn't be classified as int8/16.
89 return fixup_ == NULL && Utils::IsInt(8, value_); 91 return fixup_ == NULL && Utils::IsInt(8, value_);
90 } 92 }
91 bool is_uint8() const { return fixup_ == NULL && Utils::IsUint(8, value_); } 93 bool is_uint8() const { return fixup_ == NULL && Utils::IsUint(8, value_); }
92 bool is_uint16() const { return fixup_ == NULL && Utils::IsUint(16, value_); } 94 bool is_uint16() const { return fixup_ == NULL && Utils::IsUint(16, value_); }
93 95
94 private: 96 private:
95 const int32_t value_; 97 const int32_t value_;
96 AssemblerFixup *fixup_; 98 AssemblerFixup *fixup_;
97 }; 99 };
98 100
99 class Operand { 101 class Operand {
100 public: 102 public:
103 Operand(const Operand &other) : length_(other.length_), fixup_(other.fixup_) {
104 memmove(&encoding_[0], &other.encoding_[0], other.length_);
105 }
106
107 Operand &operator=(const Operand &other) {
108 length_ = other.length_;
109 fixup_ = other.fixup_;
110 memmove(&encoding_[0], &other.encoding_[0], other.length_);
111 return *this;
112 }
113
101 uint8_t mod() const { return (encoding_at(0) >> 6) & 3; } 114 uint8_t mod() const { return (encoding_at(0) >> 6) & 3; }
102 115
103 GPRRegister rm() const { 116 GPRRegister rm() const {
104 return static_cast<GPRRegister>(encoding_at(0) & 7); 117 return static_cast<GPRRegister>(encoding_at(0) & 7);
105 } 118 }
106 119
107 ScaleFactor scale() const { 120 ScaleFactor scale() const {
108 return static_cast<ScaleFactor>((encoding_at(1) >> 6) & 3); 121 return static_cast<ScaleFactor>((encoding_at(1) >> 6) & 3);
109 } 122 }
110 123
(...skipping 10 matching lines...) Expand all
121 return static_cast<int8_t>(encoding_[length_ - 1]); 134 return static_cast<int8_t>(encoding_[length_ - 1]);
122 } 135 }
123 136
124 int32_t disp32() const { 137 int32_t disp32() const {
125 assert(length_ >= 5); 138 assert(length_ >= 5);
126 return bit_copy<int32_t>(encoding_[length_ - 4]); 139 return bit_copy<int32_t>(encoding_[length_ - 4]);
127 } 140 }
128 141
129 AssemblerFixup *fixup() const { return fixup_; } 142 AssemblerFixup *fixup() const { return fixup_; }
130 143
131 Operand(const Operand &other) : length_(other.length_), fixup_(other.fixup_) {
132 memmove(&encoding_[0], &other.encoding_[0], other.length_);
133 }
134
135 Operand &operator=(const Operand &other) {
136 length_ = other.length_;
137 fixup_ = other.fixup_;
138 memmove(&encoding_[0], &other.encoding_[0], other.length_);
139 return *this;
140 }
141
142 protected: 144 protected:
143 Operand() : length_(0), fixup_(NULL) {} // Needed by subclass Address. 145 Operand() : length_(0), fixup_(NULL) {} // Needed by subclass Address.
144 146
145 void SetModRM(int mod, GPRRegister rm) { 147 void SetModRM(int mod, GPRRegister rm) {
146 assert((mod & ~3) == 0); 148 assert((mod & ~3) == 0);
147 encoding_[0] = (mod << 6) | rm; 149 encoding_[0] = (mod << 6) | rm;
148 length_ = 1; 150 length_ = 1;
149 } 151 }
150 152
151 void SetSIB(ScaleFactor scale, GPRRegister index, GPRRegister base) { 153 void SetSIB(ScaleFactor scale, GPRRegister index, GPRRegister base) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 bool IsRegister(GPRRegister reg) const { 189 bool IsRegister(GPRRegister reg) const {
188 return ((encoding_[0] & 0xF8) == 0xC0) // Addressing mode is register only. 190 return ((encoding_[0] & 0xF8) == 0xC0) // Addressing mode is register only.
189 && ((encoding_[0] & 0x07) == reg); // Register codes match. 191 && ((encoding_[0] & 0x07) == reg); // Register codes match.
190 } 192 }
191 193
192 friend class AssemblerX86; 194 friend class AssemblerX86;
193 }; 195 };
194 196
195 class Address : public Operand { 197 class Address : public Operand {
196 public: 198 public:
199 Address(const Address &other) : Operand(other) {}
200
201 Address &operator=(const Address &other) {
202 Operand::operator=(other);
203 return *this;
204 }
205
197 Address(GPRRegister base, int32_t disp) { 206 Address(GPRRegister base, int32_t disp) {
198 if (disp == 0 && base != RegX8632::Encoded_Reg_ebp) { 207 if (disp == 0 && base != RegX8632::Encoded_Reg_ebp) {
199 SetModRM(0, base); 208 SetModRM(0, base);
200 if (base == RegX8632::Encoded_Reg_esp) 209 if (base == RegX8632::Encoded_Reg_esp)
201 SetSIB(TIMES_1, RegX8632::Encoded_Reg_esp, base); 210 SetSIB(TIMES_1, RegX8632::Encoded_Reg_esp, base);
202 } else if (Utils::IsInt(8, disp)) { 211 } else if (Utils::IsInt(8, disp)) {
203 SetModRM(1, base); 212 SetModRM(1, base);
204 if (base == RegX8632::Encoded_Reg_esp) 213 if (base == RegX8632::Encoded_Reg_esp)
205 SetSIB(TIMES_1, RegX8632::Encoded_Reg_esp, base); 214 SetSIB(TIMES_1, RegX8632::Encoded_Reg_esp, base);
206 SetDisp8(disp); 215 SetDisp8(disp);
(...skipping 22 matching lines...) Expand all
229 SetModRM(1, RegX8632::Encoded_Reg_esp); 238 SetModRM(1, RegX8632::Encoded_Reg_esp);
230 SetSIB(scale, index, base); 239 SetSIB(scale, index, base);
231 SetDisp8(disp); 240 SetDisp8(disp);
232 } else { 241 } else {
233 SetModRM(2, RegX8632::Encoded_Reg_esp); 242 SetModRM(2, RegX8632::Encoded_Reg_esp);
234 SetSIB(scale, index, base); 243 SetSIB(scale, index, base);
235 SetDisp32(disp); 244 SetDisp32(disp);
236 } 245 }
237 } 246 }
238 247
239 Address(const Address &other) : Operand(other) {}
240
241 Address &operator=(const Address &other) {
242 Operand::operator=(other);
243 return *this;
244 }
245
246 static Address Absolute(const uintptr_t addr) { 248 static Address Absolute(const uintptr_t addr) {
247 Address result; 249 Address result;
248 result.SetModRM(0, RegX8632::Encoded_Reg_ebp); 250 result.SetModRM(0, RegX8632::Encoded_Reg_ebp);
249 result.SetDisp32(addr); 251 result.SetDisp32(addr);
250 return result; 252 return result;
251 } 253 }
252 254
253 static Address Absolute(AssemblerFixup *fixup) { 255 static Address Absolute(AssemblerFixup *fixup) {
254 Address result; 256 Address result;
255 result.SetModRM(0, RegX8632::Encoded_Reg_ebp); 257 result.SetModRM(0, RegX8632::Encoded_Reg_ebp);
256 // Use the Offset in the displacement for now. If the symbol is part of 258 // Use the Offset in the displacement for now. If the symbol is part of
257 // ".bss", then the relocation's symbol will be plain .bss and the 259 // ".bss", then the relocation's symbol will be plain .bss and the
258 // displacement will need to be adjusted further to be sym's 260 // displacement will need to be adjusted further to be sym's
259 // bss offset + Offset. 261 // bss offset + Offset.
260 result.SetDisp32(fixup->value()->getOffset()); 262 result.SetDisp32(fixup->value()->getOffset());
261 result.SetFixup(fixup); 263 result.SetFixup(fixup);
262 return result; 264 return result;
263 } 265 }
264 266
265 static Address ofConstPool(GlobalContext *Ctx, Assembler *Asm, 267 static Address ofConstPool(GlobalContext *Ctx, Assembler *Asm,
266 const Constant *Imm); 268 const Constant *Imm);
267 269
268 private: 270 private:
269 Address() {} // Needed by Address::Absolute. 271 Address() {} // Needed by Address::Absolute.
270 }; 272 };
271 273
272 class Label { 274 class Label {
275 Label(const Label &) = delete;
276 Label &operator=(const Label &) = delete;
277
273 public: 278 public:
274 Label() : position_(0), num_unresolved_(0) { 279 Label() : position_(0), num_unresolved_(0) {
275 #ifdef DEBUG 280 #ifndef NDEBUG
276 for (int i = 0; i < kMaxUnresolvedBranches; i++) { 281 for (int i = 0; i < kMaxUnresolvedBranches; i++) {
277 unresolved_near_positions_[i] = -1; 282 unresolved_near_positions_[i] = -1;
278 } 283 }
279 #endif // DEBUG 284 #endif // !NDEBUG
280 } 285 }
281 286
282 ~Label() { 287 ~Label() {
283 // Assert if label is being destroyed with unresolved branches pending. 288 // Assert if label is being destroyed with unresolved branches pending.
284 assert(!IsLinked()); 289 assert(!IsLinked());
285 assert(!HasNear()); 290 assert(!HasNear());
286 } 291 }
287 292
288 // TODO(jvoung): why are labels offset by this? 293 // TODO(jvoung): why are labels offset by this?
289 static const uint32_t kWordSize = sizeof(uint32_t); 294 static const uint32_t kWordSize = sizeof(uint32_t);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 unresolved_near_positions_[num_unresolved_++] = position; 344 unresolved_near_positions_[num_unresolved_++] = position;
340 } 345 }
341 346
342 static const int kMaxUnresolvedBranches = 20; 347 static const int kMaxUnresolvedBranches = 20;
343 348
344 intptr_t position_; 349 intptr_t position_;
345 intptr_t num_unresolved_; 350 intptr_t num_unresolved_;
346 intptr_t unresolved_near_positions_[kMaxUnresolvedBranches]; 351 intptr_t unresolved_near_positions_[kMaxUnresolvedBranches];
347 352
348 friend class AssemblerX86; 353 friend class AssemblerX86;
349 Label(const Label &) = delete;
350 Label &operator=(const Label &) = delete;
351 }; 354 };
352 355
353 class AssemblerX86 : public Assembler { 356 class AssemblerX86 : public Assembler {
357 AssemblerX86(const AssemblerX86 &) = delete;
358 AssemblerX86 &operator=(const AssemblerX86 &) = delete;
359
354 public: 360 public:
355 explicit AssemblerX86(bool use_far_branches = false) : buffer_(*this) { 361 explicit AssemblerX86(bool use_far_branches = false) : buffer_(*this) {
356 // This mode is only needed and implemented for MIPS and ARM. 362 // This mode is only needed and implemented for MIPS and ARM.
357 assert(!use_far_branches); 363 assert(!use_far_branches);
358 (void)use_far_branches; 364 (void)use_far_branches;
359 } 365 }
360 ~AssemblerX86() {} 366 ~AssemblerX86() {}
361 367
362 static const bool kNearJump = true; 368 static const bool kNearJump = true;
363 static const bool kFarJump = false; 369 static const bool kFarJump = false;
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
793 void cmpxchg(Type Ty, const Address &address, GPRRegister reg); 799 void cmpxchg(Type Ty, const Address &address, GPRRegister reg);
794 void cmpxchg8b(const Address &address); 800 void cmpxchg8b(const Address &address);
795 void xadd(Type Ty, const Address &address, GPRRegister reg); 801 void xadd(Type Ty, const Address &address, GPRRegister reg);
796 void xchg(Type Ty, const Address &address, GPRRegister reg); 802 void xchg(Type Ty, const Address &address, GPRRegister reg);
797 803
798 void LockCmpxchg(Type Ty, const Address &address, GPRRegister reg) { 804 void LockCmpxchg(Type Ty, const Address &address, GPRRegister reg) {
799 lock(); 805 lock();
800 cmpxchg(Ty, address, reg); 806 cmpxchg(Ty, address, reg);
801 } 807 }
802 808
803 void EmitSegmentOverride(uint8_t prefix) { EmitUint8(prefix); } 809 void EmitSegmentOverride(uint8_t prefix);
804 810
805 intptr_t PreferredLoopAlignment() { return 16; } 811 intptr_t PreferredLoopAlignment() { return 16; }
806 void Align(intptr_t alignment, intptr_t offset); 812 void Align(intptr_t alignment, intptr_t offset);
807 void Bind(Label *label); 813 void Bind(Label *label);
808 814
809 intptr_t CodeSize() const { return buffer_.Size(); } 815 intptr_t CodeSize() const { return buffer_.Size(); }
810 816
811 void FinalizeInstructions(const MemoryRegion &region) { 817 void FinalizeInstructions(const MemoryRegion &region) {
812 buffer_.FinalizeInstructions(region); 818 buffer_.FinalizeInstructions(region);
813 } 819 }
(...skipping 22 matching lines...) Expand all
836 const Immediate &immediate); 842 const Immediate &immediate);
837 void EmitLabel(Label *label, intptr_t instruction_size); 843 void EmitLabel(Label *label, intptr_t instruction_size);
838 void EmitLabelLink(Label *label); 844 void EmitLabelLink(Label *label);
839 void EmitNearLabelLink(Label *label); 845 void EmitNearLabelLink(Label *label);
840 846
841 void EmitGenericShift(int rm, Type Ty, GPRRegister reg, const Immediate &imm); 847 void EmitGenericShift(int rm, Type Ty, GPRRegister reg, const Immediate &imm);
842 void EmitGenericShift(int rm, Type Ty, const Operand &operand, 848 void EmitGenericShift(int rm, Type Ty, const Operand &operand,
843 GPRRegister shifter); 849 GPRRegister shifter);
844 850
845 AssemblerBuffer buffer_; 851 AssemblerBuffer buffer_;
846
847 AssemblerX86(const AssemblerX86 &) = delete;
848 AssemblerX86 &operator=(const AssemblerX86 &) = delete;
849 }; 852 };
850 853
851 inline void AssemblerX86::EmitUint8(uint8_t value) { 854 inline void AssemblerX86::EmitUint8(uint8_t value) {
852 buffer_.Emit<uint8_t>(value); 855 buffer_.Emit<uint8_t>(value);
853 } 856 }
854 857
855 inline void AssemblerX86::EmitInt16(int16_t value) { 858 inline void AssemblerX86::EmitInt16(int16_t value) {
856 buffer_.Emit<int16_t>(value); 859 buffer_.Emit<int16_t>(value);
857 } 860 }
858 861
(...skipping 13 matching lines...) Expand all
872 inline void AssemblerX86::EmitFixup(AssemblerFixup *fixup) { 875 inline void AssemblerX86::EmitFixup(AssemblerFixup *fixup) {
873 buffer_.EmitFixup(fixup); 876 buffer_.EmitFixup(fixup);
874 } 877 }
875 878
876 inline void AssemblerX86::EmitOperandSizeOverride() { EmitUint8(0x66); } 879 inline void AssemblerX86::EmitOperandSizeOverride() { EmitUint8(0x66); }
877 880
878 } // end of namespace x86 881 } // end of namespace x86
879 } // end of namespace Ice 882 } // end of namespace Ice
880 883
881 #endif // SUBZERO_SRC_ASSEMBLER_IA32_H_ 884 #endif // SUBZERO_SRC_ASSEMBLER_IA32_H_
OLDNEW
« no previous file with comments | « src/assembler.cpp ('k') | src/assembler_ia32.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698