diff options
Diffstat (limited to 'chromium/v8/src/mips/simulator-mips.cc')
-rw-r--r-- | chromium/v8/src/mips/simulator-mips.cc | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/chromium/v8/src/mips/simulator-mips.cc b/chromium/v8/src/mips/simulator-mips.cc index ea8b65948af..acc65251e23 100644 --- a/chromium/v8/src/mips/simulator-mips.cc +++ b/chromium/v8/src/mips/simulator-mips.cc @@ -1722,6 +1722,7 @@ void Simulator::ConfigureTypeRegister(Instruction* instr, int64_t& i64hilo, uint64_t& u64hilo, int32_t& next_pc, + int32_t& return_addr_reg, bool& do_interrupt) { // Every local variable declared here needs to be const. // This is to make sure that changed values are sent back to @@ -1782,6 +1783,7 @@ void Simulator::ConfigureTypeRegister(Instruction* instr, case JR: case JALR: next_pc = get_register(instr->RsValue()); + return_addr_reg = instr->RdValue(); break; case SLL: alu_out = rt << sa; @@ -1986,6 +1988,7 @@ void Simulator::DecodeTypeRegister(Instruction* instr) { int32_t current_pc = get_pc(); // Next pc int32_t next_pc = 0; + int32_t return_addr_reg = 31; // Set up the variables if needed before executing the instruction. ConfigureTypeRegister(instr, @@ -1993,6 +1996,7 @@ void Simulator::DecodeTypeRegister(Instruction* instr) { i64hilo, u64hilo, next_pc, + return_addr_reg, do_interrupt); // ---------- Raise exceptions triggered. @@ -2258,7 +2262,8 @@ void Simulator::DecodeTypeRegister(Instruction* instr) { Instruction* branch_delay_instr = reinterpret_cast<Instruction*>( current_pc+Instruction::kInstrSize); BranchDelayInstructionDecode(branch_delay_instr); - set_register(31, current_pc + 2 * Instruction::kInstrSize); + set_register(return_addr_reg, + current_pc + 2 * Instruction::kInstrSize); set_pc(next_pc); pc_modified_ = true; break; @@ -2274,9 +2279,13 @@ void Simulator::DecodeTypeRegister(Instruction* instr) { break; case DIV: // Divide by zero and overflow was not checked in the configuration - // step - div and divu do not raise exceptions. On division by 0 and - // on overflow (INT_MIN/-1), the result will be UNPREDICTABLE. - if (rt != 0 && !(rs == INT_MIN && rt == -1)) { + // step - div and divu do not raise exceptions. On division by 0 + // the result will be UNPREDICTABLE. On overflow (INT_MIN/-1), + // return INT_MIN which is what the hardware does. + if (rs == INT_MIN && rt == -1) { + set_register(LO, INT_MIN); + set_register(HI, 0); + } else if (rt != 0) { set_register(LO, rs / rt); set_register(HI, rs % rt); } |