Chromium Code Reviews| Index: runtime/vm/simulator_mips.cc |
| =================================================================== |
| --- runtime/vm/simulator_mips.cc (revision 19730) |
| +++ runtime/vm/simulator_mips.cc (working copy) |
| @@ -101,6 +101,73 @@ |
| } |
| +int8_t Simulator::ReadB(uword addr) { |
| + int8_t* ptr = reinterpret_cast<int8_t*>(addr); |
| + return *ptr; |
| +} |
| + |
| + |
| +uint8_t Simulator::ReadBU(uword addr) { |
| + uint8_t* ptr = reinterpret_cast<uint8_t*>(addr); |
| + return *ptr; |
| +} |
| + |
| + |
| +int16_t Simulator::ReadH(uword addr, Instr* instr) { |
| + if ((addr & 1) == 0) { |
| + int16_t* ptr = reinterpret_cast<int16_t*>(addr); |
| + return *ptr; |
| + } |
| + // TODO(zra) unaligned access. Trap into debugger. |
|
Ivan Posva
2013/03/11 17:29:04
Please use UNIMPLEMENTED() until it is.
ditto bel
zra
2013/03/11 18:36:06
Done.
|
| + return 0; |
| +} |
| + |
| + |
| +uint16_t Simulator::ReadHU(uword addr, Instr* instr) { |
| + if ((addr & 1) == 0) { |
| + uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); |
| + return *ptr; |
| + } |
| + // TODO(zra) unaligned access. Trap into debugger. |
| + return 0; |
| +} |
| + |
| + |
| +int Simulator::ReadW(uword addr, Instr* instr) { |
| + if ((addr & 3) == 0) { |
| + intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); |
| + return *ptr; |
| + } |
| + // TODO(zra) unaligned access. Trap into debugger. |
| + return 0; |
| +} |
| + |
| + |
| +void Simulator::WriteB(uword addr, uint8_t value) { |
| + uint8_t* ptr = reinterpret_cast<uint8_t*>(addr); |
| + *ptr = value; |
| +} |
| + |
| + |
| +void Simulator::WriteH(uword addr, uint16_t value, Instr* instr) { |
| + if ((addr & 1) == 0) { |
| + uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); |
| + *ptr = value; |
| + } |
| + // TODO(zra) unaligned access. Trap into debugger. |
| +} |
| + |
| + |
| +void Simulator::WriteW(uword addr, int value, Instr* instr) { |
| + if ((addr & 3) == 0) { |
| + intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); |
| + *ptr = value; |
| + return; |
| + } |
| + // TODO(zra) unaligned access. Trap into debugger. |
| +} |
| + |
| + |
| bool Simulator::OverflowFrom(int32_t alu_out, |
| int32_t left, int32_t right, bool addition) { |
| bool overflow; |
| @@ -120,6 +187,7 @@ |
| void Simulator::DecodeSpecial(Instr* instr) { |
| + ASSERT(instr->OpcodeField() == SPECIAL); |
| switch (instr->FunctionField()) { |
| case ADDU: { |
| ASSERT(instr->SaField() == 0); |
| @@ -229,6 +297,7 @@ |
| void Simulator::DecodeSpecial2(Instr* instr) { |
| + ASSERT(instr->OpcodeField() == SPECIAL2); |
| switch (instr->FunctionField()) { |
| case CLO: { |
| ASSERT(instr->SaField() == 0); |
| @@ -269,6 +338,42 @@ |
| } |
| +void Simulator::DecodeSpecial3(Instr* instr) { |
| + ASSERT(instr->OpcodeField() == SPECIAL3); |
| + switch (instr->FunctionField()) { |
| + case EXT: { |
| + int32_t rs_val = get_register(instr->RsField()); |
| + int32_t pos = instr->SaField(); |
| + int32_t size = instr->Bits(11, 5) + 1; |
|
Ivan Posva
2013/03/11 17:29:04
What are Bits(11,5)? In the assembler you did cast
|
| + ASSERT((0 < pos + size) && (pos + size <=32)); |
|
regis
2013/03/11 17:31:11
Use Utils::IsUint. See my other comments.
|
| + |
| + int32_t mask = ((1 << size) - 1) << (pos - 1); |
|
regis
2013/03/11 17:31:11
It should be pos, instead of pos - 1.
|
| + set_register(instr->RtField(), (rs_val & mask) >> (pos - 1)); |
| + break; |
| + } |
| + case INS: { |
| + int32_t rs_val = get_register(instr->RsField()); |
| + int32_t rt_val = get_register(instr->RtField()); |
| + int32_t pos = instr->SaField(); |
| + int32_t size = instr->Bits(11, 5) - pos + 1; |
|
Ivan Posva
2013/03/11 17:29:04
ditto.
|
| + ASSERT((0 < pos + size) && (pos + size <=32)); |
|
regis
2013/03/11 17:31:11
Use Utils::IsUint.
|
| + |
| + int32_t rs_mask = ((1 << size) - 1); |
|
regis
2013/03/11 17:31:11
Outer () not needed.
|
| + int32_t rt_mask = rs_mask << (pos - 1); |
|
regis
2013/03/11 17:31:11
pos, not pos - 1.
|
| + int32_t rt_tmp = rt_val & ~rt_mask; |
| + set_register(instr->RtField(), |
| + rt_tmp | ((rs_val & rs_mask) << (pos - 1))); |
|
regis
2013/03/11 17:31:11
pos, not pos - 1.
|
| + break; |
| + } |
| + default: { |
| + OS::PrintErr("DecodeSpecial3: 0x%x\n", instr->InstructionBits()); |
| + UNREACHABLE(); |
| + break; |
| + } |
| + } |
| +} |
| + |
| + |
| void Simulator::InstructionDecode(Instr* instr) { |
| switch (instr->OpcodeField()) { |
| case SPECIAL: { |
| @@ -279,8 +384,12 @@ |
| DecodeSpecial2(instr); |
| break; |
| } |
| + case SPECIAL3: { |
| + DecodeSpecial3(instr); |
| + break; |
| + } |
| case ADDI: { |
| - // Format(instr, "addi 'rt, 'rs, 'immu"); |
| + // Format(instr, "addi 'rt, 'rs, 'imms"); |
| int32_t rs_val = get_register(instr->RsField()); |
| int32_t imm_val = instr->SImmField(); |
| int32_t res = rs_val + imm_val; |
| @@ -288,10 +397,11 @@ |
| if (!OverflowFrom(res, rs_val, imm_val, true)) { |
| set_register(instr->RtField(), res); |
| } |
| + // TODO(zra): trap into debugger on overflow. |
|
Ivan Posva
2013/03/11 17:29:04
Personally I would remove this instruction entirel
zra
2013/03/11 18:36:06
Done.
|
| break; |
| } |
| case ADDIU: { |
| - // Format(instr, "addiu 'rt, 'rs, 'immu"); |
| + // Format(instr, "addiu 'rt, 'rs, 'imms"); |
| int32_t rs_val = get_register(instr->RsField()); |
| int32_t imm_val = instr->SImmField(); |
| int32_t res = rs_val + imm_val; |
| @@ -305,17 +415,121 @@ |
| set_register(instr->RtField(), rs_val & instr->UImmField()); |
| break; |
| } |
| + case LB: { |
| + // Format(instr, "lb 'rt, 'imms('rs)"); |
| + int32_t base_val = get_register(instr->RsField()); |
| + int32_t imm_val = instr->SImmField(); |
| + uword addr = base_val + imm_val; |
| + if (Simulator::IsIllegalAddress(addr)) { |
| + // TODO(zra) trap into debugger. |
|
Ivan Posva
2013/03/11 17:29:04
UNIMPLEMENTED() here and other places.
zra
2013/03/11 18:36:06
Done.
|
| + } else { |
| + int32_t res = ReadB(addr); |
| + set_register(instr->RtField(), res); |
| + } |
| + break; |
| + } |
| + case LBU: { |
| + // Format(instr, "lbu 'rt, 'imms('rs)"); |
| + int32_t base_val = get_register(instr->RsField()); |
| + int32_t imm_val = instr->SImmField(); |
| + uword addr = base_val + imm_val; |
| + if (Simulator::IsIllegalAddress(addr)) { |
| + // TODO(zra) trap into debugger. |
| + } else { |
| + int32_t res = ReadBU(addr); |
| + set_register(instr->RtField(), res); |
| + } |
| + break; |
| + } |
| + case LH: { |
| + // Format(instr, "lh 'rt, 'imms('rs)"); |
| + int32_t base_val = get_register(instr->RsField()); |
| + int32_t imm_val = instr->SImmField(); |
| + uword addr = base_val + imm_val; |
| + if (Simulator::IsIllegalAddress(addr)) { |
| + // TODO(zra) trap into debugger. |
| + } else { |
| + int32_t res = ReadH(addr, instr); |
| + set_register(instr->RtField(), res); |
| + } |
| + break; |
| + } |
| + case LHU: { |
| + // Format(instr, "lhu 'rt, 'imms('rs)"); |
| + int32_t base_val = get_register(instr->RsField()); |
| + int32_t imm_val = instr->SImmField(); |
| + uword addr = base_val + imm_val; |
| + if (Simulator::IsIllegalAddress(addr)) { |
| + // TODO(zra) trap into debugger. |
| + } else { |
| + int32_t res = ReadHU(addr, instr); |
| + set_register(instr->RtField(), res); |
| + } |
| + break; |
| + } |
| case LUI: { |
| ASSERT(instr->RsField() == 0); |
| set_register(instr->RtField(), instr->UImmField() << 16); |
| break; |
| } |
| + case LW: { |
| + // Format(instr, "lw 'rt, 'imms('rs)"); |
| + int32_t base_val = get_register(instr->RsField()); |
| + int32_t imm_val = instr->SImmField(); |
| + uword addr = base_val + imm_val; |
| + if (Simulator::IsIllegalAddress(addr)) { |
| + // TODO(zra) trap into debugger. |
| + } else { |
| + int32_t res = ReadW(addr, instr); |
| + set_register(instr->RtField(), res); |
| + } |
| + break; |
| + } |
| case ORI: { |
| // Format(instr, "ori 'rt, 'rs, 'immu"); |
| int32_t rs_val = get_register(instr->RsField()); |
| set_register(instr->RtField(), rs_val | instr->UImmField()); |
| break; |
| } |
| + case SB: { |
| + // Format(instr, "sb 'rt, 'imms('rs)"); |
| + int32_t rt_val = get_register(instr->RtField()); |
| + int32_t base_val = get_register(instr->RsField()); |
| + int32_t imm_val = instr->SImmField(); |
| + uword addr = base_val + imm_val; |
| + if (Simulator::IsIllegalAddress(addr)) { |
| + // TODO(zra) trap into debugger. |
| + } else { |
| + WriteB(addr, rt_val & 0xff); |
| + } |
| + break; |
| + } |
| + case SH: { |
| + // Format(instr, "sh 'rt, 'imms('rs)"); |
| + int32_t rt_val = get_register(instr->RtField()); |
| + int32_t base_val = get_register(instr->RsField()); |
| + int32_t imm_val = instr->SImmField(); |
| + uword addr = base_val + imm_val; |
| + if (Simulator::IsIllegalAddress(addr)) { |
| + // TODO(zra) trap into debugger. |
| + } else { |
| + WriteH(addr, rt_val & 0xffff, instr); |
| + } |
| + break; |
| + } |
| + case SW: { |
| + // Format(instr, "sw 'rt, 'imms('rs)"); |
| + int32_t rt_val = get_register(instr->RtField()); |
| + int32_t base_val = get_register(instr->RsField()); |
| + int32_t imm_val = instr->SImmField(); |
| + uword addr = base_val + imm_val; |
| + if (Simulator::IsIllegalAddress(addr)) { |
| + // TODO(zra) trap into debugger. |
| + } else { |
| + WriteW(addr, rt_val, instr); |
| + } |
| + break; |
| + } |
| default: { |
| OS::PrintErr("Undecoded instruction: 0x%x\n", instr->InstructionBits()); |
| UNREACHABLE(); |