Chromium Code Reviews| Index: runtime/vm/assembler_mips.h |
| =================================================================== |
| --- runtime/vm/assembler_mips.h (revision 19556) |
| +++ runtime/vm/assembler_mips.h (working copy) |
| @@ -14,34 +14,42 @@ |
| namespace dart { |
| -class Operand : public ValueObject { |
| +class Immediate : public ValueObject { |
| public: |
| - Operand(const Operand& other) : ValueObject() { |
| - UNIMPLEMENTED(); |
| - } |
| + explicit Immediate(int32_t value) : value_(value) { } |
| - Operand& operator=(const Operand& other) { |
| - UNIMPLEMENTED(); |
| + Immediate(const Immediate& other) : ValueObject(), value_(other.value_) { } |
| + Immediate& operator=(const Immediate& other) { |
| + value_ = other.value_; |
| return *this; |
| } |
| - protected: |
| - Operand() { } // Needed by subclass Address. |
| + private: |
| + int32_t value_; |
| + |
| + int32_t value() const { return value_; } |
| + |
| + friend class Assembler; |
| }; |
| -class Address : public Operand { |
| +class Address : public ValueObject { |
| public: |
| - Address(Register base, int32_t disp) { |
| + Address(Register base, int32_t offset) { |
| UNIMPLEMENTED(); |
| } |
| - Address(const Address& other) : Operand(other) { } |
| - |
| + Address(const Address& other) |
| + : ValueObject(), base_(other.base_), offset_(other.offset_) { } |
| Address& operator=(const Address& other) { |
| - Operand::operator=(other); |
| + base_ = other.base_; |
| + offset_ = other.offset_; |
| return *this; |
| } |
| + |
| + private: |
| + Register base_; |
| + int32_t offset_; |
| }; |
| @@ -131,24 +139,14 @@ |
| } |
| // Misc. functionality |
| - int CodeSize() const { |
| - UNIMPLEMENTED(); |
| - return 0; |
| - } |
| - int prologue_offset() const { |
| - UNIMPLEMENTED(); |
| - return 0; |
| - } |
| + int CodeSize() const { return buffer_.Size(); } |
| + int prologue_offset() const { return -1; } |
| const ZoneGrowableArray<int>& GetPointerOffsets() const { |
| - UNIMPLEMENTED(); |
| - return *pointer_offsets_; |
| + return buffer_.pointer_offsets(); |
| } |
| - const GrowableObjectArray& object_pool() const { |
| - UNIMPLEMENTED(); |
| - return object_pool_; |
| - } |
| + const GrowableObjectArray& object_pool() const { return object_pool_; } |
| void FinalizeInstructions(const MemoryRegion& region) { |
| - UNIMPLEMENTED(); |
| + buffer_.FinalizeInstructions(region); |
| } |
| // Set up a Dart frame on entry with a frame pointer and PC information to |
| @@ -186,9 +184,7 @@ |
| void Untested(const char* message); |
| void Unreachable(const char* message); |
| - static void InitializeMemoryWithBreakpoints(uword data, int length) { |
| - UNIMPLEMENTED(); |
| - } |
| + static void InitializeMemoryWithBreakpoints(uword data, int length); |
| void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3); |
| @@ -204,10 +200,19 @@ |
| return NULL; |
| } |
| + // CPU instructions. |
| + 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
|
| + 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
|
| + } |
| + |
| + 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
|
| + EmitRType(SPECIAL, rs, R0, R0, Immediate(0), JR); |
| + Emit(0); // Branch delay NOP. |
| + } |
| + |
| private: |
| AssemblerBuffer buffer_; |
| GrowableObjectArray& object_pool_; // Objects and patchable jump targets. |
| - ZoneGrowableArray<int>* pointer_offsets_; |
| int prologue_offset_; |
| class CodeComment : public ZoneAllocated { |
| @@ -227,6 +232,45 @@ |
| GrowableArray<CodeComment*> comments_; |
| + void Emit(int32_t value) { |
| + AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| + buffer_.Emit<int32_t>(value); |
| + } |
| + |
| + // Encode CPU instructions according to the types specified in |
| + // 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?
|
| + void EmitIType(Opcode opcode, |
| + Register rs, |
| + Register rt, |
| + const Immediate& imm) { |
| + int32_t imm_value = imm.value(); |
| + 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.
|
| + Emit(opcode << kOpcodeShift | |
| + rs << kRsShift | |
| + rt << kRtShift | |
| + imm_value); |
|
regis
2013/03/06 21:18:42
imm_value & 0xffff
|
| + } |
| + |
| + void EmitJType(Opcode opcode, Label* label) { |
| + UNIMPLEMENTED(); |
| + } |
| + |
| + void EmitRType(Opcode opcode, |
| + Register rs, |
| + Register rt, |
| + Register rd, |
| + Immediate sa, |
| + SpecialFunction func) { |
| + int32_t sa_value = sa.value(); |
| + ASSERT(Utils::IsInt(5, sa_value)); |
|
regis
2013/03/06 21:18:42
IsUint()?
Ivan Posva
2013/03/07 11:03:22
Done.
|
| + Emit(opcode << kOpcodeShift | |
| + rs << kRsShift | |
| + rt << kRtShift | |
| + rd << kRdShift | |
| + 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
|
| + func << kFunctionShift); |
| + } |
| + |
| DISALLOW_ALLOCATION(); |
| DISALLOW_COPY_AND_ASSIGN(Assembler); |
| }; |