From 126076206780ae85cee541ed01678f45ad26e118 Mon Sep 17 00:00:00 2001 From: Kito Cheng Date: Tue, 9 Aug 2016 17:36:44 +0800 Subject: [PATCH] Fix wrong behavior for divw and remw - According spec result is -2^31 is only when divisor is -1 AND dividend is -2^31 for divw. - According spec result is 0 is only when divisor is -1 AND dividend is -2^31 for remw. --- sim/riscv/sim-main.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sim/riscv/sim-main.c b/sim/riscv/sim-main.c index 0228ddb220cb..496414715b35 100644 --- a/sim/riscv/sim-main.c +++ b/sim/riscv/sim-main.c @@ -653,9 +653,11 @@ execute_m (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op) const char *rs1_name = riscv_gpr_names_abi[rs1]; const char *rs2_name = riscv_gpr_names_abi[rs2]; unsigned_word tmp, dividend_max; + signed_word dividend32_max; sim_cia pc = cpu->pc + 4; dividend_max = -((unsigned_word)1 << (WITH_TARGET_WORD_BITSIZE - 1)); + dividend32_max = INT32_MIN; switch (op->match) { @@ -674,7 +676,8 @@ execute_m (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op) TRACE_INSN (cpu, "divw %s, %s, %s; // %s = %s / %s", rd_name, rs1_name, rs2_name, rd_name, rs1_name, rs2_name); RISCV_ASSERT_RV64 (cpu, "insn: %s", op->name); - if (EXTEND32 (cpu->regs[rs2]) == -1) + if (EXTEND32 (cpu->regs[rs1]) == dividend32_max + && EXTEND32 (cpu->regs[rs2]) == -1) tmp = 1 << 31; else if (EXTEND32 (cpu->regs[rs2])) tmp = EXTEND32 (cpu->regs[rs1]) / EXTEND32 (cpu->regs[rs2]); @@ -755,7 +758,8 @@ execute_m (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op) TRACE_INSN (cpu, "remw %s, %s, %s; // %s = %s %% %s", rd_name, rs1_name, rs2_name, rd_name, rs1_name, rs2_name); RISCV_ASSERT_RV64 (cpu, "insn: %s", op->name); - if (EXTEND32 (cpu->regs[rs2]) == -1) + if (EXTEND32 (cpu->regs[rs1]) == dividend32_max + && EXTEND32 (cpu->regs[rs2]) == -1) tmp = 0; else if (EXTEND32 (cpu->regs[rs2])) tmp = EXTEND32 (cpu->regs[rs1]) % EXTEND32 (cpu->regs[rs2]);