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

Unified Diff: runtime/vm/simulator_mips.cc

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 | « runtime/vm/simulator_mips.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/simulator_mips.cc
===================================================================
--- runtime/vm/simulator_mips.cc (revision 20399)
+++ runtime/vm/simulator_mips.cc (working copy)
@@ -990,6 +990,65 @@
}
+void Simulator::DoBranch(Instr* instr, bool taken, bool likely) {
+ ASSERT(!delay_slot_);
+ int32_t imm_val = instr->SImmField() << 2;
+
+ uword next_pc;
+ if (taken) {
+ // imm_val is added to the address of the instruction following the branch.
+ next_pc = pc_ + imm_val + Instr::kInstrSize;
+ if (likely) {
+ ExecuteDelaySlot();
+ }
+ } else {
+ next_pc = pc_ + (2 * Instr::kInstrSize); // Next after delay slot.
+ }
+ if (!likely) {
+ ExecuteDelaySlot();
+ }
+ pc_ = next_pc - Instr::kInstrSize;
+
+ return;
+}
+
+
+void Simulator::DecodeRegImm(Instr* instr) {
+ ASSERT(instr->OpcodeField() == REGIMM);
+ switch (instr->RegImmFnField()) {
+ case BGEZ: {
+ // Format(instr, "bgez 'rs, 'dest");
+ int32_t rs_val = get_register(instr->RsField());
+ DoBranch(instr, rs_val >= 0, false);
+ break;
+ }
+ case BGEZL: {
+ // Format(instr, "bgezl 'rs, 'dest");
+ int32_t rs_val = get_register(instr->RsField());
+ DoBranch(instr, rs_val >= 0, true);
+ break;
+ }
+ case BLTZ: {
+ // Format(instr, "bltz 'rs, 'dest");
+ int32_t rs_val = get_register(instr->RsField());
+ DoBranch(instr, rs_val < 0, false);
+ break;
+ }
+ case BLTZL: {
+ // Format(instr, "bltzl 'rs, 'dest");
+ int32_t rs_val = get_register(instr->RsField());
+ DoBranch(instr, rs_val < 0, true);
+ break;
+ }
+ default: {
+ OS::PrintErr("DecodeRegImm: 0x%x\n", instr->InstructionBits());
+ UnimplementedInstruction(instr);
+ break;
+ }
+ }
+}
+
+
void Simulator::InstructionDecode(Instr* instr) {
switch (instr->OpcodeField()) {
case SPECIAL: {
@@ -1000,6 +1059,10 @@
DecodeSpecial2(instr);
break;
}
+ case REGIMM: {
+ DecodeRegImm(instr);
+ break;
+ }
case ADDIU: {
// Format(instr, "addiu 'rt, 'rs, 'imms");
int32_t rs_val = get_register(instr->RsField());
@@ -1015,6 +1078,62 @@
set_register(instr->RtField(), rs_val & instr->UImmField());
break;
}
+ case BEQ: {
+ // Format(instr, "beq 'rs, 'rt, 'dest");
+ int32_t rs_val = get_register(instr->RsField());
+ int32_t rt_val = get_register(instr->RtField());
+ DoBranch(instr, rs_val == rt_val, false);
+ break;
+ }
+ case BEQL: {
+ // Format(instr, "beql 'rs, 'rt, 'dest");
+ int32_t rs_val = get_register(instr->RsField());
+ int32_t rt_val = get_register(instr->RtField());
+ DoBranch(instr, rs_val == rt_val, true);
+ break;
+ }
+ case BGTZ: {
+ ASSERT(instr->RtField() == R0);
+ // Format(instr, "bgtz 'rs, 'dest");
+ int32_t rs_val = get_register(instr->RsField());
+ DoBranch(instr, rs_val > 0, false);
+ break;
+ }
+ case BGTZL: {
+ ASSERT(instr->RtField() == R0);
+ // Format(instr, "bgtzl 'rs, 'dest");
+ int32_t rs_val = get_register(instr->RsField());
+ DoBranch(instr, rs_val > 0, true);
+ break;
+ }
+ case BLEZ: {
+ ASSERT(instr->RtField() == R0);
+ // Format(instr, "blez 'rs, 'dest");
+ int32_t rs_val = get_register(instr->RsField());
+ DoBranch(instr, rs_val <= 0, false);
+ break;
+ }
+ case BLEZL: {
+ ASSERT(instr->RtField() == R0);
+ // Format(instr, "blezl 'rs, 'dest");
+ int32_t rs_val = get_register(instr->RsField());
+ DoBranch(instr, rs_val <= 0, true);
+ break;
+ }
+ case BNE: {
+ // Format(instr, "bne 'rs, 'rt, 'dest");
+ int32_t rs_val = get_register(instr->RsField());
+ int32_t rt_val = get_register(instr->RtField());
+ DoBranch(instr, rs_val != rt_val, false);
+ break;
+ }
+ case BNEL: {
+ // Format(instr, "bnel 'rs, 'rt, 'dest");
+ int32_t rs_val = get_register(instr->RsField());
+ int32_t rt_val = get_register(instr->RtField());
+ DoBranch(instr, rs_val != rt_val, true);
+ break;
+ }
case LB: {
// Format(instr, "lb 'rt, 'imms('rs)");
int32_t base_val = get_register(instr->RsField());
« no previous file with comments | « runtime/vm/simulator_mips.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698