mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-08 02:03:56 -06:00
target-openrisc: Write back result before FPE exception
The architecture manual is unclear about this, but the or1ksim does writeback before the exception. This requires splitting the helpers in half, with the exception raised by the second. Acked-by: Stafford Horne <shorne@gmail.com> Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de> Signed-off-by: Richard Henderson <rth@twiddle.net>
This commit is contained in:
parent
bbd87423ea
commit
4e2d30079c
3 changed files with 125 additions and 251 deletions
|
@ -1293,180 +1293,209 @@ static void dec_float(DisasContext *dc, uint32_t insn)
|
|||
rd = extract32(insn, 21, 5);
|
||||
|
||||
switch (op0) {
|
||||
case 0x00: /* lf.add.s */
|
||||
case 0x00: /* lf.add.s */
|
||||
LOG_DIS("lf.add.s r%d, r%d, r%d\n", rd, ra, rb);
|
||||
check_r0_write(rd);
|
||||
gen_helper_float_add_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
|
||||
gen_helper_update_fpcsr(cpu_env);
|
||||
break;
|
||||
|
||||
case 0x01: /* lf.sub.s */
|
||||
case 0x01: /* lf.sub.s */
|
||||
LOG_DIS("lf.sub.s r%d, r%d, r%d\n", rd, ra, rb);
|
||||
check_r0_write(rd);
|
||||
gen_helper_float_sub_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
|
||||
gen_helper_update_fpcsr(cpu_env);
|
||||
break;
|
||||
|
||||
case 0x02: /* lf.mul.s */
|
||||
LOG_DIS("lf.mul.s r%d, r%d, r%d\n", rd, ra, rb);
|
||||
check_r0_write(rd);
|
||||
gen_helper_float_mul_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
|
||||
gen_helper_update_fpcsr(cpu_env);
|
||||
break;
|
||||
|
||||
case 0x03: /* lf.div.s */
|
||||
case 0x03: /* lf.div.s */
|
||||
LOG_DIS("lf.div.s r%d, r%d, r%d\n", rd, ra, rb);
|
||||
check_r0_write(rd);
|
||||
gen_helper_float_div_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
|
||||
gen_helper_update_fpcsr(cpu_env);
|
||||
break;
|
||||
|
||||
case 0x04: /* lf.itof.s */
|
||||
case 0x04: /* lf.itof.s */
|
||||
LOG_DIS("lf.itof r%d, r%d\n", rd, ra);
|
||||
check_r0_write(rd);
|
||||
gen_helper_itofs(cpu_R[rd], cpu_env, cpu_R[ra]);
|
||||
gen_helper_update_fpcsr(cpu_env);
|
||||
break;
|
||||
|
||||
case 0x05: /* lf.ftoi.s */
|
||||
case 0x05: /* lf.ftoi.s */
|
||||
LOG_DIS("lf.ftoi r%d, r%d\n", rd, ra);
|
||||
check_r0_write(rd);
|
||||
gen_helper_ftois(cpu_R[rd], cpu_env, cpu_R[ra]);
|
||||
gen_helper_update_fpcsr(cpu_env);
|
||||
break;
|
||||
|
||||
case 0x06: /* lf.rem.s */
|
||||
case 0x06: /* lf.rem.s */
|
||||
LOG_DIS("lf.rem.s r%d, r%d, r%d\n", rd, ra, rb);
|
||||
check_r0_write(rd);
|
||||
gen_helper_float_rem_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
|
||||
gen_helper_update_fpcsr(cpu_env);
|
||||
break;
|
||||
|
||||
case 0x07: /* lf.madd.s */
|
||||
case 0x07: /* lf.madd.s */
|
||||
LOG_DIS("lf.madd.s r%d, r%d, r%d\n", rd, ra, rb);
|
||||
check_r0_write(rd);
|
||||
gen_helper_float_madd_s(cpu_R[rd], cpu_env, cpu_R[rd],
|
||||
cpu_R[ra], cpu_R[rb]);
|
||||
gen_helper_update_fpcsr(cpu_env);
|
||||
break;
|
||||
|
||||
case 0x08: /* lf.sfeq.s */
|
||||
case 0x08: /* lf.sfeq.s */
|
||||
LOG_DIS("lf.sfeq.s r%d, r%d\n", ra, rb);
|
||||
gen_helper_float_eq_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
|
||||
gen_helper_update_fpcsr(cpu_env);
|
||||
break;
|
||||
|
||||
case 0x09: /* lf.sfne.s */
|
||||
case 0x09: /* lf.sfne.s */
|
||||
LOG_DIS("lf.sfne.s r%d, r%d\n", ra, rb);
|
||||
gen_helper_float_ne_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
|
||||
gen_helper_float_eq_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
|
||||
tcg_gen_xori_tl(cpu_sr_f, cpu_sr_f, 1);
|
||||
gen_helper_update_fpcsr(cpu_env);
|
||||
break;
|
||||
|
||||
case 0x0a: /* lf.sfgt.s */
|
||||
case 0x0a: /* lf.sfgt.s */
|
||||
LOG_DIS("lf.sfgt.s r%d, r%d\n", ra, rb);
|
||||
gen_helper_float_gt_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
|
||||
gen_helper_float_lt_s(cpu_sr_f, cpu_env, cpu_R[rb], cpu_R[ra]);
|
||||
gen_helper_update_fpcsr(cpu_env);
|
||||
break;
|
||||
|
||||
case 0x0b: /* lf.sfge.s */
|
||||
case 0x0b: /* lf.sfge.s */
|
||||
LOG_DIS("lf.sfge.s r%d, r%d\n", ra, rb);
|
||||
gen_helper_float_ge_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
|
||||
gen_helper_float_le_s(cpu_sr_f, cpu_env, cpu_R[rb], cpu_R[ra]);
|
||||
gen_helper_update_fpcsr(cpu_env);
|
||||
break;
|
||||
|
||||
case 0x0c: /* lf.sflt.s */
|
||||
case 0x0c: /* lf.sflt.s */
|
||||
LOG_DIS("lf.sflt.s r%d, r%d\n", ra, rb);
|
||||
gen_helper_float_lt_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
|
||||
gen_helper_update_fpcsr(cpu_env);
|
||||
break;
|
||||
|
||||
case 0x0d: /* lf.sfle.s */
|
||||
case 0x0d: /* lf.sfle.s */
|
||||
LOG_DIS("lf.sfle.s r%d, r%d\n", ra, rb);
|
||||
gen_helper_float_le_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
|
||||
gen_helper_update_fpcsr(cpu_env);
|
||||
break;
|
||||
|
||||
/* not used yet, open it when we need or64. */
|
||||
/*#ifdef TARGET_OPENRISC64
|
||||
case 0x10: lf.add.d
|
||||
#ifdef TARGET_OPENRISC64
|
||||
case 0x10: /* lf.add.d */
|
||||
LOG_DIS("lf.add.d r%d, r%d, r%d\n", rd, ra, rb);
|
||||
check_of64s(dc);
|
||||
check_r0_write(rd);
|
||||
gen_helper_float_add_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
|
||||
gen_helper_update_fpcsr(cpu_env);
|
||||
break;
|
||||
|
||||
case 0x11: lf.sub.d
|
||||
case 0x11: /* lf.sub.d */
|
||||
LOG_DIS("lf.sub.d r%d, r%d, r%d\n", rd, ra, rb);
|
||||
check_of64s(dc);
|
||||
check_r0_write(rd);
|
||||
gen_helper_float_sub_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
|
||||
gen_helper_update_fpcsr(cpu_env);
|
||||
break;
|
||||
|
||||
case 0x12: lf.mul.d
|
||||
case 0x12: /* lf.mul.d */
|
||||
LOG_DIS("lf.mul.d r%d, r%d, r%d\n", rd, ra, rb);
|
||||
check_of64s(dc);
|
||||
check_r0_write(rd);
|
||||
gen_helper_float_mul_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
|
||||
gen_helper_update_fpcsr(cpu_env);
|
||||
break;
|
||||
|
||||
case 0x13: lf.div.d
|
||||
case 0x13: /* lf.div.d */
|
||||
LOG_DIS("lf.div.d r%d, r%d, r%d\n", rd, ra, rb);
|
||||
check_of64s(dc);
|
||||
check_r0_write(rd);
|
||||
gen_helper_float_div_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
|
||||
gen_helper_update_fpcsr(cpu_env);
|
||||
break;
|
||||
|
||||
case 0x14: lf.itof.d
|
||||
case 0x14: /* lf.itof.d */
|
||||
LOG_DIS("lf.itof r%d, r%d\n", rd, ra);
|
||||
check_of64s(dc);
|
||||
check_r0_write(rd);
|
||||
gen_helper_itofd(cpu_R[rd], cpu_env, cpu_R[ra]);
|
||||
gen_helper_update_fpcsr(cpu_env);
|
||||
break;
|
||||
|
||||
case 0x15: lf.ftoi.d
|
||||
case 0x15: /* lf.ftoi.d */
|
||||
LOG_DIS("lf.ftoi r%d, r%d\n", rd, ra);
|
||||
check_of64s(dc);
|
||||
check_r0_write(rd);
|
||||
gen_helper_ftoid(cpu_R[rd], cpu_env, cpu_R[ra]);
|
||||
gen_helper_update_fpcsr(cpu_env);
|
||||
break;
|
||||
|
||||
case 0x16: lf.rem.d
|
||||
case 0x16: /* lf.rem.d */
|
||||
LOG_DIS("lf.rem.d r%d, r%d, r%d\n", rd, ra, rb);
|
||||
check_of64s(dc);
|
||||
check_r0_write(rd);
|
||||
gen_helper_float_rem_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
|
||||
gen_helper_update_fpcsr(cpu_env);
|
||||
break;
|
||||
|
||||
case 0x17: lf.madd.d
|
||||
case 0x17: /* lf.madd.d */
|
||||
LOG_DIS("lf.madd.d r%d, r%d, r%d\n", rd, ra, rb);
|
||||
check_of64s(dc);
|
||||
check_r0_write(rd);
|
||||
gen_helper_float_madd_d(cpu_R[rd], cpu_env, cpu_R[rd],
|
||||
cpu_R[ra], cpu_R[rb]);
|
||||
gen_helper_update_fpcsr(cpu_env);
|
||||
break;
|
||||
|
||||
case 0x18: lf.sfeq.d
|
||||
case 0x18: /* lf.sfeq.d */
|
||||
LOG_DIS("lf.sfeq.d r%d, r%d\n", ra, rb);
|
||||
check_of64s(dc);
|
||||
gen_helper_float_eq_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
|
||||
gen_helper_update_fpcsr(cpu_env);
|
||||
break;
|
||||
|
||||
case 0x1a: lf.sfgt.d
|
||||
case 0x1a: /* lf.sfgt.d */
|
||||
LOG_DIS("lf.sfgt.d r%d, r%d\n", ra, rb);
|
||||
check_of64s(dc);
|
||||
gen_helper_float_gt_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
|
||||
gen_helper_float_lt_d(cpu_sr_f, cpu_env, cpu_R[rb], cpu_R[ra]);
|
||||
gen_helper_update_fpcsr(cpu_env);
|
||||
break;
|
||||
|
||||
case 0x1b: lf.sfge.d
|
||||
case 0x1b: /* lf.sfge.d */
|
||||
LOG_DIS("lf.sfge.d r%d, r%d\n", ra, rb);
|
||||
check_of64s(dc);
|
||||
gen_helper_float_ge_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
|
||||
gen_helper_float_le_d(cpu_sr_f, cpu_env, cpu_R[rb], cpu_R[ra]);
|
||||
gen_helper_update_fpcsr(cpu_env);
|
||||
break;
|
||||
|
||||
case 0x19: lf.sfne.d
|
||||
case 0x19: /* lf.sfne.d */
|
||||
LOG_DIS("lf.sfne.d r%d, r%d\n", ra, rb);
|
||||
check_of64s(dc);
|
||||
gen_helper_float_ne_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
|
||||
gen_helper_float_eq_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
|
||||
tcg_gen_xori_tl(cpu_sr_f, cpu_sr_f, 1);
|
||||
gen_helper_update_fpcsr(cpu_env);
|
||||
break;
|
||||
|
||||
case 0x1c: lf.sflt.d
|
||||
case 0x1c: /* lf.sflt.d */
|
||||
LOG_DIS("lf.sflt.d r%d, r%d\n", ra, rb);
|
||||
check_of64s(dc);
|
||||
gen_helper_float_lt_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
|
||||
gen_helper_update_fpcsr(cpu_env);
|
||||
break;
|
||||
|
||||
case 0x1d: lf.sfle.d
|
||||
case 0x1d: /* lf.sfle.d */
|
||||
LOG_DIS("lf.sfle.d r%d, r%d\n", ra, rb);
|
||||
check_of64s(dc);
|
||||
gen_helper_float_le_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
|
||||
gen_helper_update_fpcsr(cpu_env);
|
||||
break;
|
||||
#endif*/
|
||||
#endif
|
||||
|
||||
default:
|
||||
gen_illegal_exception(dc);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue