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

Unified Diff: runtime/vm/assembler_mips.h

Issue 12634030: Adds branch instructions and labels to the MIPS simulator, assembler, disassembler. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | runtime/vm/assembler_mips.cc » ('j') | runtime/vm/assembler_mips.cc » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/assembler_mips.h
===================================================================
--- runtime/vm/assembler_mips.h (revision 20394)
+++ runtime/vm/assembler_mips.h (working copy)
@@ -147,9 +147,7 @@
UNIMPLEMENTED();
}
- void Bind(Label* label) {
- UNIMPLEMENTED();
- }
+ void Bind(Label* label);
// Misc. functionality
int CodeSize() const { return buffer_.Size(); }
@@ -245,6 +243,96 @@
EmitIType(ANDI, rs, rt, imm_value);
}
+ // Branch if equal.
+ void beq(Register rs, Register rt, Label* l) {
+ ASSERT(!in_delay_slot_); // Jump within a delay slot is not supported.
regis 2013/03/22 19:51:16 Either remove this comment or add it consistently
zra 2013/03/22 20:16:01 Done.
+ EmitBranch(BEQ, rs, rt, l);
+ EmitBranchDelayNop();
+ }
+
+ // Branch if equal, likely taken.
+ // Delay slot executed only when branch taken.
+ void beql(Register rs, Register rt, Label* l) {
+ ASSERT(!in_delay_slot_); // Jump within a delay slot is not supported.
+ EmitBranch(BEQL, rs, rt, l);
+ EmitBranchDelayNop();
+ }
+
+ // Brach if rs >= 0.
regis 2013/03/22 19:51:16 Branch
zra 2013/03/22 20:16:01 Done.
+ void bgez(Register rs, Label* l) {
+ ASSERT(!in_delay_slot_);
+ EmitRegImmBranch(BGEZ, rs, l);
+ EmitBranchDelayNop();
+ }
+
+ // Branch if rs >= 0, likely taken.
+ // Delay slot executed only when branch taken.
+ void bgezl(Register rs, Label* l) {
+ ASSERT(!in_delay_slot_);
+ EmitRegImmBranch(BGEZL, rs, l);
+ EmitBranchDelayNop();
+ }
+
+ // Brach if rs > 0.
regis 2013/03/22 19:51:16 Branch
zra 2013/03/22 20:16:01 Done.
+ void bgtz(Register rs, Label* l) {
+ ASSERT(!in_delay_slot_);
+ EmitBranch(BGTZ, rs, R0, l);
+ EmitBranchDelayNop();
+ }
+
+ // Branch if rs > 0, likely taken.
+ // Delay slot executed only when branch taken.
+ void bgtzl(Register rs, Label* l) {
+ ASSERT(!in_delay_slot_);
+ EmitBranch(BGTZL, rs, R0, l);
+ EmitBranchDelayNop();
+ }
+
+ // Brach if rs <= 0.
regis 2013/03/22 19:51:16 Branch
zra 2013/03/22 20:16:01 Done.
+ void blez(Register rs, Label* l) {
+ ASSERT(!in_delay_slot_);
+ EmitBranch(BLEZ, rs, R0, l);
+ EmitBranchDelayNop();
+ }
+
+ // Branch if rs <= 0, likely taken.
+ // Delay slot executed only when branch taken.
+ void blezl(Register rs, Label* l) {
+ ASSERT(!in_delay_slot_);
+ EmitBranch(BLEZL, rs, R0, l);
+ EmitBranchDelayNop();
+ }
+
+ // Brach if rs < 0.
regis 2013/03/22 19:51:16 Branch
zra 2013/03/22 20:16:01 Done.
+ void bltz(Register rs, Label* l) {
+ ASSERT(!in_delay_slot_);
+ EmitRegImmBranch(BLTZ, rs, l);
+ EmitBranchDelayNop();
+ }
+
+ // Branch if rs < 0, likely taken.
+ // Delay slot executed only when branch taken.
+ void bltzl(Register rs, Label* l) {
+ ASSERT(!in_delay_slot_);
+ EmitRegImmBranch(BLTZL, rs, l);
+ EmitBranchDelayNop();
+ }
+
+ // Branch if not equal.
+ void bne(Register rs, Register rt, Label* l) {
+ ASSERT(!in_delay_slot_); // Jump within a delay slot is not supported.
+ EmitBranch(BNE, rs, rt, l);
+ EmitBranchDelayNop();
+ }
+
+ // Branch if not equal, likely taken.
+ // Delay slot executed only when branch taken.
+ void bnel(Register rs, Register rt, Label* l) {
+ ASSERT(!in_delay_slot_); // Jump within a delay slot is not supported.
+ EmitBranch(BNEL, rs, rt, l);
+ EmitBranchDelayNop();
+ }
+
void break_(int32_t code) {
ASSERT(Utils::IsUint(20, code));
Emit(SPECIAL << kOpcodeShift |
@@ -402,6 +490,12 @@
}
// Macros in alphabetical order.
+
+ // Unconditional branch.
+ void B(Label* l) {
regis 2013/03/22 19:51:16 I would use a lower case 'b', since the MIPS assem
zra 2013/03/22 20:16:01 That makes sense. I've made it lowercase and moved
+ beq(R0, R0, l);
+ }
+
void LoadImmediate(Register rd, int32_t value) {
if (Utils::IsInt(16, value)) {
addiu(rd, ZR, Immediate(value));
@@ -415,6 +509,10 @@
or_(rd, rs, ZR);
}
+ void Nop() {
regis 2013/03/22 19:51:16 nop?
zra 2013/03/22 20:16:01 Same as with mov.
+ Emit(Instr::kNopInstruction);
+ }
+
private:
AssemblerBuffer buffer_;
GrowableObjectArray& object_pool_; // Objects and patchable jump targets.
@@ -496,6 +594,31 @@
func << kFunctionShift);
}
+ void EmitBranch(Opcode b, Register rs, Register rt, Label* label) {
+ if (label->IsBound()) {
+ uint16_t dest = EncodeBranchOffset(label->Position() - buffer_.Size(), 0);
+ EmitIType(b, rs, rt, dest);
+ } else {
+ int position = buffer_.Size();
+ EmitIType(b, rs, rt, label->position_);
+ label->LinkTo(position);
+ }
+ }
+
+ void EmitRegImmBranch(RtRegImm b, Register rs, Label* label) {
+ if (label->IsBound()) {
+ uint16_t dest = EncodeBranchOffset(label->Position() - buffer_.Size(), 0);
+ EmitRegImmType(REGIMM, rs, b, dest);
+ } else {
+ int position = buffer_.Size();
+ EmitRegImmType(REGIMM, rs, b, label->position_);
+ label->LinkTo(position);
+ }
+ }
+
+ static int32_t EncodeBranchOffset(int32_t offset, int32_t inst);
regis 2013/03/22 19:51:16 inst -> instr
zra 2013/03/22 20:16:01 Done.
+ static int DecodeBranchOffset(int32_t inst);
regis 2013/03/22 19:51:16 inst -> instr
zra 2013/03/22 20:16:01 Done.
+
void EmitBranchDelayNop() {
Emit(Instr::kNopInstruction); // Branch delay NOP.
delay_slot_available_ = true;
« no previous file with comments | « no previous file | runtime/vm/assembler_mips.cc » ('j') | runtime/vm/assembler_mips.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698