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

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: 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
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 // Modified by the Subzero authors. 5 // Modified by the Subzero authors.
6 // 6 //
7 //===- subzero/src/assembler_ia32.h - Assembler for x86-32 ----------------===// 7 //===- subzero/src/assembler_ia32.h - Assembler for x86-32 ----------------===//
Jim Stichnoth 2014/10/16 18:19:53 Add the emacs c++-mode marker here? *- C++ -*
jvoung (off chromium) 2014/10/16 19:02:37 Done. I think technically it should be on the firs
8 // 8 //
9 // The Subzero Code Generator 9 // The Subzero Code Generator
10 // 10 //
11 // This file is distributed under the University of Illinois Open Source 11 // This file is distributed under the University of Illinois Open Source
12 // License. See LICENSE.TXT for details. 12 // License. See LICENSE.TXT for details.
13 // 13 //
14 //===----------------------------------------------------------------------===// 14 //===----------------------------------------------------------------------===//
15 // 15 //
16 // This file implements the Assembler class for x86-32. 16 // This file implements the Assembler class for x86-32.
17 // 17 //
(...skipping 20 matching lines...) Expand all
38 using RegX8632::ByteRegister; 38 using RegX8632::ByteRegister;
39 using RegX8632::X87STRegister; 39 using RegX8632::X87STRegister;
40 40
41 namespace x86 { 41 namespace x86 {
42 42
43 const int MAX_NOP_SIZE = 8; 43 const int MAX_NOP_SIZE = 8;
44 44
45 enum ScaleFactor { TIMES_1 = 0, TIMES_2 = 1, TIMES_4 = 2, TIMES_8 = 3 }; 45 enum ScaleFactor { TIMES_1 = 0, TIMES_2 = 1, TIMES_4 = 2, TIMES_8 = 3 };
46 46
47 class DisplacementRelocation : public AssemblerFixup { 47 class DisplacementRelocation : public AssemblerFixup {
48 DisplacementRelocation(const DisplacementRelocation &) = delete;
49 DisplacementRelocation &operator=(const DisplacementRelocation &) = delete;
50
48 public: 51 public:
49 static DisplacementRelocation *create(Assembler *Asm, FixupKind Kind, 52 static DisplacementRelocation *create(Assembler *Asm, FixupKind Kind,
50 const ConstantRelocatable *Sym) { 53 const ConstantRelocatable *Sym) {
51 return new (Asm->Allocate<DisplacementRelocation>()) 54 return new (Asm->Allocate<DisplacementRelocation>())
52 DisplacementRelocation(Kind, Sym); 55 DisplacementRelocation(Kind, Sym);
53 } 56 }
54 57
55 void Process(const MemoryRegion &region, intptr_t position) override { 58 void Process(const MemoryRegion &region, intptr_t position) override {
56 (void)region; 59 (void)region;
57 (void)position; 60 (void)position;
58 llvm_unreachable("We might not be using this Process() method later."); 61 llvm_unreachable("We might not be using this Process() method later.");
59 } 62 }
60 63
61 private: 64 private:
62 DisplacementRelocation(FixupKind Kind, const ConstantRelocatable *Sym) 65 DisplacementRelocation(FixupKind Kind, const ConstantRelocatable *Sym)
63 : AssemblerFixup(Kind, Sym) {} 66 : AssemblerFixup(Kind, Sym) {}
64 DisplacementRelocation(const DisplacementRelocation &) = delete;
65 DisplacementRelocation &operator=(const DisplacementRelocation &) = delete;
66 }; 67 };
67 68
68 class Immediate { 69 class Immediate {
70 Immediate(const Immediate &) = delete;
71 Immediate &operator=(const Immediate &) = delete;
72
69 public: 73 public:
70 explicit Immediate(int32_t value) : value_(value), fixup_(NULL) {} 74 explicit Immediate(int32_t value) : value_(value), fixup_(NULL) {}
71 75
72 explicit Immediate(const Immediate &other)
73 : value_(other.value_), fixup_(other.fixup_) {}
74
75 explicit Immediate(AssemblerFixup *fixup) 76 explicit Immediate(AssemblerFixup *fixup)
76 : value_(fixup->value()->getOffset()), fixup_(fixup) { 77 : value_(fixup->value()->getOffset()), fixup_(fixup) {
77 // Use the Offset in the "value" for now. If the symbol is part of 78 // 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 79 // ".bss", then the relocation's symbol will be plain ".bss" and
79 // the value will need to be adjusted further to be sym's 80 // the value will need to be adjusted further to be sym's
80 // bss offset + Offset. 81 // bss offset + Offset.
81 } 82 }
82 83
83 int32_t value() const { return value_; } 84 int32_t value() const { return value_; }
84 AssemblerFixup *fixup() const { return fixup_; } 85 AssemblerFixup *fixup() const { return fixup_; }
85 86
86 bool is_int8() const { 87 bool is_int8() const {
87 // We currently only allow 32-bit fixups, and they usually have value = 0, 88 // 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. 89 // so if fixup_ != NULL, it shouldn't be classified as int8/16.
89 return fixup_ == NULL && Utils::IsInt(8, value_); 90 return fixup_ == NULL && Utils::IsInt(8, value_);
90 } 91 }
91 bool is_uint8() const { return fixup_ == NULL && Utils::IsUint(8, value_); } 92 bool is_uint8() const { return fixup_ == NULL && Utils::IsUint(8, value_); }
92 bool is_uint16() const { return fixup_ == NULL && Utils::IsUint(16, value_); } 93 bool is_uint16() const { return fixup_ == NULL && Utils::IsUint(16, value_); }
93 94
94 private: 95 private:
95 const int32_t value_; 96 const int32_t value_;
96 AssemblerFixup *fixup_; 97 AssemblerFixup *fixup_;
97 }; 98 };
98 99
99 class Operand { 100 class Operand {
100 public: 101 public:
102 Operand(const Operand &other) : length_(other.length_), fixup_(other.fixup_) {
Karl 2014/10/16 17:23:26 Jim suggested doing // Operand(const Operand
Jim Stichnoth 2014/10/16 18:19:53 True, but here we're explicitly not using the defa
jvoung (off chromium) 2014/10/16 19:02:37 Right, it doesn't quite need to memmove everything
103 memmove(&encoding_[0], &other.encoding_[0], other.length_);
104 }
105
106 Operand &operator=(const Operand &other) {
107 length_ = other.length_;
108 fixup_ = other.fixup_;
109 memmove(&encoding_[0], &other.encoding_[0], other.length_);
110 return *this;
111 }
112
101 uint8_t mod() const { return (encoding_at(0) >> 6) & 3; } 113 uint8_t mod() const { return (encoding_at(0) >> 6) & 3; }
102 114
103 GPRRegister rm() const { 115 GPRRegister rm() const {
104 return static_cast<GPRRegister>(encoding_at(0) & 7); 116 return static_cast<GPRRegister>(encoding_at(0) & 7);
105 } 117 }
106 118
107 ScaleFactor scale() const { 119 ScaleFactor scale() const {
108 return static_cast<ScaleFactor>((encoding_at(1) >> 6) & 3); 120 return static_cast<ScaleFactor>((encoding_at(1) >> 6) & 3);
109 } 121 }
110 122
(...skipping 10 matching lines...) Expand all
121 return static_cast<int8_t>(encoding_[length_ - 1]); 133 return static_cast<int8_t>(encoding_[length_ - 1]);
122 } 134 }
123 135
124 int32_t disp32() const { 136 int32_t disp32() const {
125 assert(length_ >= 5); 137 assert(length_ >= 5);
126 return bit_copy<int32_t>(encoding_[length_ - 4]); 138 return bit_copy<int32_t>(encoding_[length_ - 4]);
127 } 139 }
128 140
129 AssemblerFixup *fixup() const { return fixup_; } 141 AssemblerFixup *fixup() const { return fixup_; }
130 142
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: 143 protected:
143 Operand() : length_(0), fixup_(NULL) {} // Needed by subclass Address. 144 Operand() : length_(0), fixup_(NULL) {} // Needed by subclass Address.
144 145
145 void SetModRM(int mod, GPRRegister rm) { 146 void SetModRM(int mod, GPRRegister rm) {
146 assert((mod & ~3) == 0); 147 assert((mod & ~3) == 0);
147 encoding_[0] = (mod << 6) | rm; 148 encoding_[0] = (mod << 6) | rm;
148 length_ = 1; 149 length_ = 1;
149 } 150 }
150 151
151 void SetSIB(ScaleFactor scale, GPRRegister index, GPRRegister base) { 152 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 { 188 bool IsRegister(GPRRegister reg) const {
188 return ((encoding_[0] & 0xF8) == 0xC0) // Addressing mode is register only. 189 return ((encoding_[0] & 0xF8) == 0xC0) // Addressing mode is register only.
189 && ((encoding_[0] & 0x07) == reg); // Register codes match. 190 && ((encoding_[0] & 0x07) == reg); // Register codes match.
190 } 191 }
191 192
192 friend class AssemblerX86; 193 friend class AssemblerX86;
193 }; 194 };
194 195
195 class Address : public Operand { 196 class Address : public Operand {
196 public: 197 public:
198 Address(const Address &other) : Operand(other) {}
199
200 Address &operator=(const Address &other) {
201 Operand::operator=(other);
202 return *this;
203 }
204
197 Address(GPRRegister base, int32_t disp) { 205 Address(GPRRegister base, int32_t disp) {
198 if (disp == 0 && base != RegX8632::Encoded_Reg_ebp) { 206 if (disp == 0 && base != RegX8632::Encoded_Reg_ebp) {
199 SetModRM(0, base); 207 SetModRM(0, base);
200 if (base == RegX8632::Encoded_Reg_esp) 208 if (base == RegX8632::Encoded_Reg_esp)
201 SetSIB(TIMES_1, RegX8632::Encoded_Reg_esp, base); 209 SetSIB(TIMES_1, RegX8632::Encoded_Reg_esp, base);
202 } else if (Utils::IsInt(8, disp)) { 210 } else if (Utils::IsInt(8, disp)) {
203 SetModRM(1, base); 211 SetModRM(1, base);
204 if (base == RegX8632::Encoded_Reg_esp) 212 if (base == RegX8632::Encoded_Reg_esp)
205 SetSIB(TIMES_1, RegX8632::Encoded_Reg_esp, base); 213 SetSIB(TIMES_1, RegX8632::Encoded_Reg_esp, base);
206 SetDisp8(disp); 214 SetDisp8(disp);
(...skipping 22 matching lines...) Expand all
229 SetModRM(1, RegX8632::Encoded_Reg_esp); 237 SetModRM(1, RegX8632::Encoded_Reg_esp);
230 SetSIB(scale, index, base); 238 SetSIB(scale, index, base);
231 SetDisp8(disp); 239 SetDisp8(disp);
232 } else { 240 } else {
233 SetModRM(2, RegX8632::Encoded_Reg_esp); 241 SetModRM(2, RegX8632::Encoded_Reg_esp);
234 SetSIB(scale, index, base); 242 SetSIB(scale, index, base);
235 SetDisp32(disp); 243 SetDisp32(disp);
236 } 244 }
237 } 245 }
238 246
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) { 247 static Address Absolute(const uintptr_t addr) {
247 Address result; 248 Address result;
248 result.SetModRM(0, RegX8632::Encoded_Reg_ebp); 249 result.SetModRM(0, RegX8632::Encoded_Reg_ebp);
249 result.SetDisp32(addr); 250 result.SetDisp32(addr);
250 return result; 251 return result;
251 } 252 }
252 253
253 static Address Absolute(AssemblerFixup *fixup) { 254 static Address Absolute(AssemblerFixup *fixup) {
254 Address result; 255 Address result;
255 result.SetModRM(0, RegX8632::Encoded_Reg_ebp); 256 result.SetModRM(0, RegX8632::Encoded_Reg_ebp);
256 // Use the Offset in the displacement for now. If the symbol is part of 257 // 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 258 // ".bss", then the relocation's symbol will be plain .bss and the
258 // displacement will need to be adjusted further to be sym's 259 // displacement will need to be adjusted further to be sym's
259 // bss offset + Offset. 260 // bss offset + Offset.
260 result.SetDisp32(fixup->value()->getOffset()); 261 result.SetDisp32(fixup->value()->getOffset());
261 result.SetFixup(fixup); 262 result.SetFixup(fixup);
262 return result; 263 return result;
263 } 264 }
264 265
265 static Address ofConstPool(GlobalContext *Ctx, Assembler *Asm, 266 static Address ofConstPool(GlobalContext *Ctx, Assembler *Asm,
266 const Constant *Imm); 267 const Constant *Imm);
267 268
268 private: 269 private:
269 Address() {} // Needed by Address::Absolute. 270 Address() {} // Needed by Address::Absolute.
270 }; 271 };
271 272
272 class Label { 273 class Label {
274 Label(const Label &) = delete;
275 Label &operator=(const Label &) = delete;
276
273 public: 277 public:
274 Label() : position_(0), num_unresolved_(0) { 278 Label() : position_(0), num_unresolved_(0) {
275 #ifdef DEBUG 279 #ifdef DEBUG
276 for (int i = 0; i < kMaxUnresolvedBranches; i++) { 280 for (int i = 0; i < kMaxUnresolvedBranches; i++) {
277 unresolved_near_positions_[i] = -1; 281 unresolved_near_positions_[i] = -1;
278 } 282 }
279 #endif // DEBUG 283 #endif // DEBUG
280 } 284 }
281 285
282 ~Label() { 286 ~Label() {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 unresolved_near_positions_[num_unresolved_++] = position; 343 unresolved_near_positions_[num_unresolved_++] = position;
340 } 344 }
341 345
342 static const int kMaxUnresolvedBranches = 20; 346 static const int kMaxUnresolvedBranches = 20;
343 347
344 intptr_t position_; 348 intptr_t position_;
345 intptr_t num_unresolved_; 349 intptr_t num_unresolved_;
346 intptr_t unresolved_near_positions_[kMaxUnresolvedBranches]; 350 intptr_t unresolved_near_positions_[kMaxUnresolvedBranches];
347 351
348 friend class AssemblerX86; 352 friend class AssemblerX86;
349 Label(const Label &) = delete;
350 Label &operator=(const Label &) = delete;
351 }; 353 };
352 354
353 class AssemblerX86 : public Assembler { 355 class AssemblerX86 : public Assembler {
356 AssemblerX86(const AssemblerX86 &) = delete;
357 AssemblerX86 &operator=(const AssemblerX86 &) = delete;
358
354 public: 359 public:
355 explicit AssemblerX86(bool use_far_branches = false) : buffer_(*this) { 360 explicit AssemblerX86(bool use_far_branches = false) : buffer_(*this) {
356 // This mode is only needed and implemented for MIPS and ARM. 361 // This mode is only needed and implemented for MIPS and ARM.
357 assert(!use_far_branches); 362 assert(!use_far_branches);
358 (void)use_far_branches; 363 (void)use_far_branches;
359 } 364 }
360 ~AssemblerX86() {} 365 ~AssemblerX86() {}
361 366
362 static const bool kNearJump = true; 367 static const bool kNearJump = true;
363 static const bool kFarJump = false; 368 static const bool kFarJump = false;
(...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after
836 const Immediate &immediate); 841 const Immediate &immediate);
837 void EmitLabel(Label *label, intptr_t instruction_size); 842 void EmitLabel(Label *label, intptr_t instruction_size);
838 void EmitLabelLink(Label *label); 843 void EmitLabelLink(Label *label);
839 void EmitNearLabelLink(Label *label); 844 void EmitNearLabelLink(Label *label);
840 845
841 void EmitGenericShift(int rm, Type Ty, GPRRegister reg, const Immediate &imm); 846 void EmitGenericShift(int rm, Type Ty, GPRRegister reg, const Immediate &imm);
842 void EmitGenericShift(int rm, Type Ty, const Operand &operand, 847 void EmitGenericShift(int rm, Type Ty, const Operand &operand,
843 GPRRegister shifter); 848 GPRRegister shifter);
844 849
845 AssemblerBuffer buffer_; 850 AssemblerBuffer buffer_;
846
847 AssemblerX86(const AssemblerX86 &) = delete;
848 AssemblerX86 &operator=(const AssemblerX86 &) = delete;
849 }; 851 };
850 852
851 inline void AssemblerX86::EmitUint8(uint8_t value) { 853 inline void AssemblerX86::EmitUint8(uint8_t value) {
852 buffer_.Emit<uint8_t>(value); 854 buffer_.Emit<uint8_t>(value);
853 } 855 }
854 856
855 inline void AssemblerX86::EmitInt16(int16_t value) { 857 inline void AssemblerX86::EmitInt16(int16_t value) {
856 buffer_.Emit<int16_t>(value); 858 buffer_.Emit<int16_t>(value);
857 } 859 }
858 860
(...skipping 13 matching lines...) Expand all
872 inline void AssemblerX86::EmitFixup(AssemblerFixup *fixup) { 874 inline void AssemblerX86::EmitFixup(AssemblerFixup *fixup) {
873 buffer_.EmitFixup(fixup); 875 buffer_.EmitFixup(fixup);
874 } 876 }
875 877
876 inline void AssemblerX86::EmitOperandSizeOverride() { EmitUint8(0x66); } 878 inline void AssemblerX86::EmitOperandSizeOverride() { EmitUint8(0x66); }
877 879
878 } // end of namespace x86 880 } // end of namespace x86
879 } // end of namespace Ice 881 } // end of namespace Ice
880 882
881 #endif // SUBZERO_SRC_ASSEMBLER_IA32_H_ 883 #endif // SUBZERO_SRC_ASSEMBLER_IA32_H_
OLDNEW
« src/assembler.h ('K') | « src/assembler.h ('k') | src/assembler_ia32.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698