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_MIPS_H_ | 5 #ifndef VM_ASSEMBLER_MIPS_H_ |
6 #define VM_ASSEMBLER_MIPS_H_ | 6 #define VM_ASSEMBLER_MIPS_H_ |
7 | 7 |
8 #ifndef VM_ASSEMBLER_H_ | 8 #ifndef VM_ASSEMBLER_H_ |
9 #error Do not include assembler_mips.h directly; use assembler.h instead. | 9 #error Do not include assembler_mips.h directly; use assembler.h instead. |
10 #endif | 10 #endif |
11 | 11 |
12 #include "platform/assert.h" | 12 #include "platform/assert.h" |
13 #include "vm/constants_mips.h" | 13 #include "vm/constants_mips.h" |
14 | 14 |
15 namespace dart { | 15 namespace dart { |
16 | 16 |
17 class Operand : public ValueObject { | 17 class Immediate : public ValueObject { |
18 public: | 18 public: |
19 Operand(const Operand& other) : ValueObject() { | 19 explicit Immediate(int32_t value) : value_(value) { } |
20 | |
21 Immediate(const Immediate& other) : ValueObject(), value_(other.value_) { } | |
22 Immediate& operator=(const Immediate& other) { | |
23 value_ = other.value_; | |
24 return *this; | |
25 } | |
26 | |
27 private: | |
28 int32_t value_; | |
29 | |
30 int32_t value() const { return value_; } | |
31 | |
32 friend class Assembler; | |
33 }; | |
34 | |
35 | |
36 class Address : public ValueObject { | |
37 public: | |
38 Address(Register base, int32_t offset) { | |
20 UNIMPLEMENTED(); | 39 UNIMPLEMENTED(); |
21 } | 40 } |
22 | 41 |
23 Operand& operator=(const Operand& other) { | 42 Address(const Address& other) |
24 UNIMPLEMENTED(); | 43 : ValueObject(), base_(other.base_), offset_(other.offset_) { } |
44 Address& operator=(const Address& other) { | |
45 base_ = other.base_; | |
46 offset_ = other.offset_; | |
25 return *this; | 47 return *this; |
26 } | 48 } |
27 | 49 |
28 protected: | 50 private: |
29 Operand() { } // Needed by subclass Address. | 51 Register base_; |
52 int32_t offset_; | |
30 }; | 53 }; |
31 | 54 |
32 | 55 |
33 class Address : public Operand { | |
34 public: | |
35 Address(Register base, int32_t disp) { | |
36 UNIMPLEMENTED(); | |
37 } | |
38 | |
39 Address(const Address& other) : Operand(other) { } | |
40 | |
41 Address& operator=(const Address& other) { | |
42 Operand::operator=(other); | |
43 return *this; | |
44 } | |
45 }; | |
46 | |
47 | |
48 class FieldAddress : public Address { | 56 class FieldAddress : public Address { |
49 public: | 57 public: |
50 FieldAddress(Register base, int32_t disp) | 58 FieldAddress(Register base, int32_t disp) |
51 : Address(base, disp - kHeapObjectTag) { } | 59 : Address(base, disp - kHeapObjectTag) { } |
52 | 60 |
53 FieldAddress(const FieldAddress& other) : Address(other) { } | 61 FieldAddress(const FieldAddress& other) : Address(other) { } |
54 | 62 |
55 FieldAddress& operator=(const FieldAddress& other) { | 63 FieldAddress& operator=(const FieldAddress& other) { |
56 Address::operator=(other); | 64 Address::operator=(other); |
57 return *this; | 65 return *this; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
124 | 132 |
125 void PopRegister(Register r) { | 133 void PopRegister(Register r) { |
126 UNIMPLEMENTED(); | 134 UNIMPLEMENTED(); |
127 } | 135 } |
128 | 136 |
129 void Bind(Label* label) { | 137 void Bind(Label* label) { |
130 UNIMPLEMENTED(); | 138 UNIMPLEMENTED(); |
131 } | 139 } |
132 | 140 |
133 // Misc. functionality | 141 // Misc. functionality |
134 int CodeSize() const { | 142 int CodeSize() const { return buffer_.Size(); } |
135 UNIMPLEMENTED(); | 143 int prologue_offset() const { return -1; } |
136 return 0; | 144 const ZoneGrowableArray<int>& GetPointerOffsets() const { |
145 return buffer_.pointer_offsets(); | |
137 } | 146 } |
138 int prologue_offset() const { | 147 const GrowableObjectArray& object_pool() const { return object_pool_; } |
139 UNIMPLEMENTED(); | |
140 return 0; | |
141 } | |
142 const ZoneGrowableArray<int>& GetPointerOffsets() const { | |
143 UNIMPLEMENTED(); | |
144 return *pointer_offsets_; | |
145 } | |
146 const GrowableObjectArray& object_pool() const { | |
147 UNIMPLEMENTED(); | |
148 return object_pool_; | |
149 } | |
150 void FinalizeInstructions(const MemoryRegion& region) { | 148 void FinalizeInstructions(const MemoryRegion& region) { |
151 UNIMPLEMENTED(); | 149 buffer_.FinalizeInstructions(region); |
152 } | 150 } |
153 | 151 |
154 // Set up a Dart frame on entry with a frame pointer and PC information to | 152 // Set up a Dart frame on entry with a frame pointer and PC information to |
155 // enable easy access to the RawInstruction object of code corresponding | 153 // enable easy access to the RawInstruction object of code corresponding |
156 // to this frame. | 154 // to this frame. |
157 void EnterDartFrame(intptr_t frame_size) { | 155 void EnterDartFrame(intptr_t frame_size) { |
158 UNIMPLEMENTED(); | 156 UNIMPLEMENTED(); |
159 } | 157 } |
160 | 158 |
161 // Set up a stub frame so that the stack traversal code can easily identify | 159 // Set up a stub frame so that the stack traversal code can easily identify |
(...skipping 17 matching lines...) Expand all Loading... | |
179 Register instance_reg) { | 177 Register instance_reg) { |
180 UNIMPLEMENTED(); | 178 UNIMPLEMENTED(); |
181 } | 179 } |
182 | 180 |
183 // Debugging and bringup support. | 181 // Debugging and bringup support. |
184 void Stop(const char* message) { UNIMPLEMENTED(); } | 182 void Stop(const char* message) { UNIMPLEMENTED(); } |
185 void Unimplemented(const char* message); | 183 void Unimplemented(const char* message); |
186 void Untested(const char* message); | 184 void Untested(const char* message); |
187 void Unreachable(const char* message); | 185 void Unreachable(const char* message); |
188 | 186 |
189 static void InitializeMemoryWithBreakpoints(uword data, int length) { | 187 static void InitializeMemoryWithBreakpoints(uword data, int length); |
190 UNIMPLEMENTED(); | |
191 } | |
192 | 188 |
193 void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3); | 189 void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3); |
194 | 190 |
195 const Code::Comments& GetCodeComments() const; | 191 const Code::Comments& GetCodeComments() const; |
196 | 192 |
197 static const char* RegisterName(Register reg) { | 193 static const char* RegisterName(Register reg) { |
198 UNIMPLEMENTED(); | 194 UNIMPLEMENTED(); |
199 return NULL; | 195 return NULL; |
200 } | 196 } |
201 | 197 |
202 static const char* FpuRegisterName(FpuRegister reg) { | 198 static const char* FpuRegisterName(FpuRegister reg) { |
203 UNIMPLEMENTED(); | 199 UNIMPLEMENTED(); |
204 return NULL; | 200 return NULL; |
205 } | 201 } |
206 | 202 |
203 // CPU instructions. | |
204 void ori(Register rt, Register rs, const Immediate& imm) { | |
regis
2013/03/06 21:18:42
Are we accepting negative immediate values? See co
Ivan Posva
2013/03/07 11:03:22
I fixed the imm parameter of EmitIType to be uint1
| |
205 EmitIType(ORI, rs, rt, imm); | |
regis
2013/03/06 21:18:42
The body should be moved to the cc file. Ditto for
Ivan Posva
2013/03/07 11:03:22
There is no reason to prevent inlining this functi
| |
206 } | |
207 | |
208 void jr(Register rs) { | |
regis
2013/03/06 21:18:42
This should be Jr, with a capital letter, because
Ivan Posva
2013/03/07 11:03:22
As discussed offline the only sane way to look at
| |
209 EmitRType(SPECIAL, rs, R0, R0, Immediate(0), JR); | |
210 Emit(0); // Branch delay NOP. | |
211 } | |
212 | |
207 private: | 213 private: |
208 AssemblerBuffer buffer_; | 214 AssemblerBuffer buffer_; |
209 GrowableObjectArray& object_pool_; // Objects and patchable jump targets. | 215 GrowableObjectArray& object_pool_; // Objects and patchable jump targets. |
210 ZoneGrowableArray<int>* pointer_offsets_; | |
211 int prologue_offset_; | 216 int prologue_offset_; |
212 | 217 |
213 class CodeComment : public ZoneAllocated { | 218 class CodeComment : public ZoneAllocated { |
214 public: | 219 public: |
215 CodeComment(intptr_t pc_offset, const String& comment) | 220 CodeComment(intptr_t pc_offset, const String& comment) |
216 : pc_offset_(pc_offset), comment_(comment) { } | 221 : pc_offset_(pc_offset), comment_(comment) { } |
217 | 222 |
218 intptr_t pc_offset() const { return pc_offset_; } | 223 intptr_t pc_offset() const { return pc_offset_; } |
219 const String& comment() const { return comment_; } | 224 const String& comment() const { return comment_; } |
220 | 225 |
221 private: | 226 private: |
222 intptr_t pc_offset_; | 227 intptr_t pc_offset_; |
223 const String& comment_; | 228 const String& comment_; |
224 | 229 |
225 DISALLOW_COPY_AND_ASSIGN(CodeComment); | 230 DISALLOW_COPY_AND_ASSIGN(CodeComment); |
226 }; | 231 }; |
227 | 232 |
228 GrowableArray<CodeComment*> comments_; | 233 GrowableArray<CodeComment*> comments_; |
229 | 234 |
235 void Emit(int32_t value) { | |
236 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | |
237 buffer_.Emit<int32_t>(value); | |
238 } | |
239 | |
240 // Encode CPU instructions according to the types specified in | |
241 // Figures 4-1, 4-2 and 4-3. | |
regis
2013/03/06 21:18:42
What figures are you referring to?
Ivan Posva
2013/03/07 11:03:22
Done.
regis
2013/03/07 17:56:57
Done what?
| |
242 void EmitIType(Opcode opcode, | |
243 Register rs, | |
244 Register rt, | |
245 const Immediate& imm) { | |
246 int32_t imm_value = imm.value(); | |
247 ASSERT(Utils::IsInt(16, imm_value)); | |
regis
2013/03/06 21:18:42
I am not sure this is correct. It depends on what
Ivan Posva
2013/03/07 11:03:22
Fixed. EmitIType expects a uint16_t imm now.
| |
248 Emit(opcode << kOpcodeShift | | |
249 rs << kRsShift | | |
250 rt << kRtShift | | |
251 imm_value); | |
regis
2013/03/06 21:18:42
imm_value & 0xffff
| |
252 } | |
253 | |
254 void EmitJType(Opcode opcode, Label* label) { | |
255 UNIMPLEMENTED(); | |
256 } | |
257 | |
258 void EmitRType(Opcode opcode, | |
259 Register rs, | |
260 Register rt, | |
261 Register rd, | |
262 Immediate sa, | |
263 SpecialFunction func) { | |
264 int32_t sa_value = sa.value(); | |
265 ASSERT(Utils::IsInt(5, sa_value)); | |
regis
2013/03/06 21:18:42
IsUint()?
Ivan Posva
2013/03/07 11:03:22
Done.
| |
266 Emit(opcode << kOpcodeShift | | |
267 rs << kRsShift | | |
268 rt << kRtShift | | |
269 rd << kRdShift | | |
270 sa_value << kSaShift | | |
regis
2013/03/06 21:18:42
(sa_value & 0x1f) << kSaShift
Ivan Posva
2013/03/07 11:03:22
Similar fix to EmitIType. We now pass sa as a uint
| |
271 func << kFunctionShift); | |
272 } | |
273 | |
230 DISALLOW_ALLOCATION(); | 274 DISALLOW_ALLOCATION(); |
231 DISALLOW_COPY_AND_ASSIGN(Assembler); | 275 DISALLOW_COPY_AND_ASSIGN(Assembler); |
232 }; | 276 }; |
233 | 277 |
234 } // namespace dart | 278 } // namespace dart |
235 | 279 |
236 #endif // VM_ASSEMBLER_MIPS_H_ | 280 #endif // VM_ASSEMBLER_MIPS_H_ |
OLD | NEW |