Re: [Qemu-devel] [PATCH for-2.5 12/30] m68k: Manage divw overflow

2015-08-12 Thread Richard Henderson

On 08/09/2015 01:13 PM, Laurent Vivier wrote:

Overflow may be detected and set before the instruction completes.
If the instruction detects an overflow, it sets the overflow condition
code, and the operands are unaffected.


May also implies may not.  I presume this is important for matching hardware? 
Is there some program you know of that depends on this?



+/* dest.l / src.w */
+
+dest = DREG(insn, 9);
+tcg_gen_mov_i32(QREG_DIV1, dest);
+
  SRC_EA(env, src, OS_WORD, sign, NULL);
  tcg_gen_mov_i32(QREG_DIV2, src);
+
+/* div1 / div2 */
+
  if (sign) {
  gen_helper_divs(cpu_env, tcg_const_i32(1));
  } else {
  gen_helper_divu(cpu_env, tcg_const_i32(1));
  }

+set_cc_op(s, CC_OP_FLAGS);
+
+l1 = gen_new_label();
+gen_jmpcc(s, 9 /* V */, l1);
  tmp = tcg_temp_new();
  src = tcg_temp_new();
  tcg_gen_ext16u_i32(tmp, QREG_DIV1);
  tcg_gen_shli_i32(src, QREG_DIV2, 16);
-tcg_gen_or_i32(reg, tmp, src);
-set_cc_op(s, CC_OP_FLAGS);
+tcg_gen_or_i32(dest, tmp, src);
+gen_set_label(l1);


All that said, it's possible to implement this branch inside the helper via 
exception.  Or simply return the inputs to effect no change.



r~



[Qemu-devel] [PATCH for-2.5 12/30] m68k: Manage divw overflow

2015-08-09 Thread Laurent Vivier
Overflow may be detected and set before the instruction completes.
If the instruction detects an overflow, it sets the overflow condition
code, and the operands are unaffected.

Signed-off-by: Laurent Vivier laur...@vivier.eu
---
 target-m68k/translate.c | 26 +-
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 8a3d315..370a2f0 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -1034,32 +1034,40 @@ DISAS_INSN(mulw)
 
 DISAS_INSN(divw)
 {
-TCGv reg;
+TCGv dest;
 TCGv tmp;
 TCGv src;
 int sign;
+TCGLabel *l1;
 
 sign = (insn  0x100) != 0;
-reg = DREG(insn, 9);
-if (sign) {
-tcg_gen_ext16s_i32(QREG_DIV1, reg);
-} else {
-tcg_gen_ext16u_i32(QREG_DIV1, reg);
-}
+
+/* dest.l / src.w */
+
+dest = DREG(insn, 9);
+tcg_gen_mov_i32(QREG_DIV1, dest);
+
 SRC_EA(env, src, OS_WORD, sign, NULL);
 tcg_gen_mov_i32(QREG_DIV2, src);
+
+/* div1 / div2 */
+
 if (sign) {
 gen_helper_divs(cpu_env, tcg_const_i32(1));
 } else {
 gen_helper_divu(cpu_env, tcg_const_i32(1));
 }
 
+set_cc_op(s, CC_OP_FLAGS);
+
+l1 = gen_new_label();
+gen_jmpcc(s, 9 /* V */, l1);
 tmp = tcg_temp_new();
 src = tcg_temp_new();
 tcg_gen_ext16u_i32(tmp, QREG_DIV1);
 tcg_gen_shli_i32(src, QREG_DIV2, 16);
-tcg_gen_or_i32(reg, tmp, src);
-set_cc_op(s, CC_OP_FLAGS);
+tcg_gen_or_i32(dest, tmp, src);
+gen_set_label(l1);
 }
 
 DISAS_INSN(divl)
-- 
2.4.3