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); |
}; |