Chromium Code Reviews| 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 |