qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Bryce Lanham <blanham@gmail.com>
To: qemu-devel@nongnu.org
Cc: Andreas Schwab <schwab@linux-m68k.org>,
	Laurent Vivier <laurent@vivier.eu>
Subject: [Qemu-devel] [PATCH 016/111] m68k: add 64bit divide.
Date: Wed, 17 Aug 2011 15:46:21 -0500	[thread overview]
Message-ID: <1313614076-28878-17-git-send-email-blanham@gmail.com> (raw)
In-Reply-To: <1313614076-28878-1-git-send-email-blanham@gmail.com>

From: Laurent Vivier <laurent@vivier.eu>

This patch modifies "divl" to support 64bit operands (QUAD_MULDIV
feature).

Signed-off-by: Andreas Schwab <schwab@linux-m68k.org>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 target-m68k/cpu.h       |    3 ++
 target-m68k/helpers.h   |    2 +
 target-m68k/op_helper.c |   77 ++++++++++++++++++++++++++++++++++++++++++++--
 target-m68k/qregs.def   |    1 +
 target-m68k/translate.c |   34 ++++++++++++++++----
 5 files changed, 106 insertions(+), 11 deletions(-)

diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
index 688642f..ff57564 100644
--- a/target-m68k/cpu.h
+++ b/target-m68k/cpu.h
@@ -91,6 +91,9 @@ typedef struct CPUM68KState {
     uint32_t div1;
     uint32_t div2;
 
+    /* Upper 32 bits of a 64bit operand for quad MUL/DIV.  */
+    uint32_t quadh;
+
     /* MMU status.  */
     struct {
         uint32_t ar;
diff --git a/target-m68k/helpers.h b/target-m68k/helpers.h
index cb8a0c7..a158aee 100644
--- a/target-m68k/helpers.h
+++ b/target-m68k/helpers.h
@@ -5,6 +5,8 @@ DEF_HELPER_1(ff1, i32, i32)
 DEF_HELPER_2(sats, i32, i32, i32)
 DEF_HELPER_2(divu, void, env, i32)
 DEF_HELPER_2(divs, void, env, i32)
+DEF_HELPER_1(divu64, void, env)
+DEF_HELPER_1(divs64, void, env)
 DEF_HELPER_3(addx_cc, i32, env, i32, i32)
 DEF_HELPER_3(subx_cc, i32, env, i32, i32)
 DEF_HELPER_3(shl_cc, i32, env, i32, i32)
diff --git a/target-m68k/op_helper.c b/target-m68k/op_helper.c
index c66fa0c..1bffe5d 100644
--- a/target-m68k/op_helper.c
+++ b/target-m68k/op_helper.c
@@ -219,8 +219,11 @@ void HELPER(divu)(CPUState *env, uint32_t word)
         flags |= CCF_Z;
     else if ((int32_t)quot < 0)
         flags |= CCF_N;
-    env->div1 = quot;
-    env->div2 = rem;
+    /* Don't modify destination if overflow occured.  */
+    if ((flags & CCF_V) == 0) {
+        env->div1 = quot;
+        env->div2 = rem;
+    }
     env->cc_dest = flags;
 }
 
@@ -245,7 +248,73 @@ void HELPER(divs)(CPUState *env, uint32_t word)
         flags |= CCF_Z;
     else if (quot < 0)
         flags |= CCF_N;
-    env->div1 = quot;
-    env->div2 = rem;
+    /* Don't modify destination if overflow occured.  */
+    if ((flags & CCF_V) == 0) {
+        env->div1 = quot;
+        env->div2 = rem;
+    }
+    env->cc_dest = flags;
+}
+
+void HELPER(divu64)(CPUState *env)
+{
+    uint32_t num;
+    uint32_t den;
+    uint32_t quot;
+    uint32_t rem;
+    uint32_t flags;
+
+    num = env->div1;
+    den = env->div2;
+    /* ??? This needs to make sure the throwing location is accurate.  */
+    if (den == 0)
+        raise_exception(EXCP_DIV0);
+    quot = (num | ((uint64_t)env->quadh << 32)) / den;
+    rem = (num | ((uint64_t)env->quadh << 32)) % den;
+    flags = 0;
+    /* Avoid using a PARAM1 of zero.  This breaks dyngen because it uses
+       the address of a symbol, and gcc knows symbols can't have address
+       zero.  */
+    if (quot > 0xffffffff)
+        flags |= CCF_V;
+    if (quot == 0)
+        flags |= CCF_Z;
+    else if ((int32_t)quot < 0)
+        flags |= CCF_N;
+    /* Don't modify destination if overflow occured.  */
+    if ((flags & CCF_V) == 0) {
+        env->div1 = quot;
+        env->div2 = rem;
+    }
+    env->cc_dest = flags;
+}
+
+void HELPER(divs64)(CPUState *env)
+{
+    int32_t num;
+    int32_t den;
+    int32_t quot;
+    int32_t rem;
+    int32_t flags;
+
+    num = env->div1;
+    den = env->div2;
+    if (den == 0)
+        raise_exception(EXCP_DIV0);
+    quot = (num | ((int64_t)env->quadh << 32)) / den;
+    rem = (num | ((int64_t)env->quadh << 32)) % den;
+    rem = num % den;
+    flags = 0;
+    if (quot != (int32_t)quot)
+        flags |= CCF_V;
+    if (quot == 0)
+        flags |= CCF_Z;
+    else if (quot < 0)
+        flags |= CCF_N;
+    /* Don't modify destination if overflow occured.  */
+    if ((flags & CCF_V) == 0) {
+        env->div1 = quot;
+        env->div2 = rem;
+    }
     env->cc_dest = flags;
 }
diff --git a/target-m68k/qregs.def b/target-m68k/qregs.def
index 49400c4..76e0236 100644
--- a/target-m68k/qregs.def
+++ b/target-m68k/qregs.def
@@ -7,6 +7,7 @@ DEFO32(CC_SRC, cc_src)
 DEFO32(CC_X, cc_x)
 DEFO32(DIV1, div1)
 DEFO32(DIV2, div2)
+DEFO32(QUADH, quadh)
 DEFO32(EXCEPTION, exception_index)
 DEFO32(HALTED, halted)
 DEFO32(MACSR, macsr)
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 0f9b4eb..1d84081 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -1020,10 +1020,27 @@ DISAS_INSN(divl)
     TCGv reg;
     uint16_t ext;
 
-    ext = lduw_code(s->pc);
-    s->pc += 2;
-    if (ext & 0x87f8) {
-        gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
+    ext = read_im16(s);
+    if (ext & 0x400) {
+        if (!m68k_feature(s->env, M68K_FEATURE_QUAD_MULDIV)) {
+            gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
+            return;
+        }
+        num = DREG(ext, 12);
+        reg = DREG(ext, 0);
+        tcg_gen_mov_i32(QREG_DIV1, num);
+        tcg_gen_mov_i32(QREG_QUADH, reg);
+        SRC_EA(den, OS_LONG, 0, NULL);
+        tcg_gen_mov_i32(QREG_DIV2, den);
+        if (ext & 0x0800) {
+            gen_helper_divs64(cpu_env);
+        } else {
+            gen_helper_divu64(cpu_env);
+        }
+        tcg_gen_mov_i32(num, QREG_DIV1);
+        if (!TCGV_EQUAL(num, reg))
+            tcg_gen_mov_i32(reg, QREG_DIV2);
+        s->cc_op = CC_OP_FLAGS;
         return;
     }
     num = DREG(ext, 12);
@@ -1036,10 +1053,12 @@ DISAS_INSN(divl)
     } else {
         gen_helper_divu(cpu_env, tcg_const_i32(0));
     }
-    if ((ext & 7) == ((ext >> 12) & 7)) {
+    if (TCGV_EQUAL(num, reg) ||
+        m68k_feature(s->env, M68K_FEATURE_LONG_MULDIV)) {
         /* div */
-        tcg_gen_mov_i32 (reg, QREG_DIV1);
-    } else {
+        tcg_gen_mov_i32 (num, QREG_DIV1);
+    }
+    if (!TCGV_EQUAL(num, reg)) {
         /* rem */
         tcg_gen_mov_i32 (reg, QREG_DIV2);
     }
@@ -3010,6 +3029,7 @@ void register_m68k_insns (CPUM68KState *env)
     INSN(illegal,   4afc, ffff, M68000);
     INSN(mull,      4c00, ffc0, CF_ISA_A);
     INSN(divl,      4c40, ffc0, CF_ISA_A);
+    INSN(divl,      4c40, ffc0, LONG_MULDIV);
     INSN(sats,      4c80, fff8, CF_ISA_B);
     INSN(trap,      4e40, fff0, CF_ISA_A);
     INSN(trap,      4e40, fff0, M68000);
-- 
1.7.2.3

  parent reply	other threads:[~2011-08-17 20:48 UTC|newest]

Thread overview: 125+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-08-17 20:46 [Qemu-devel] [RFC][PATCH 000/111] QEMU m68k core additions Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 001/111] linux-user: Signals processing is not thread-safe Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 002/111] linux-user: add qemu-wrapper Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 003/111] linux-user: define default cpu model in configure instead of linux-user/main.c Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 004/111] linux-user: specify the cpu model during configure Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 005/111] linux-user,m68k: display default cpu Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 006/111] linux-user: define new environment variables Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 007/111] linux-user: define a script to set binfmt using debian flavored tools Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 008/111] linux-user: define default cpu model in configure instead of linux-user/main.c Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 009/111] m68k: add tcg_gen_debug_insn_start() Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 010/111] m68k: define m680x0 CPUs and features Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 011/111] m68k: add missing accessing modes for some instructions Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 012/111] m68k: add Motorola 680x0 family common instructions Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 013/111] m68k: add Scc instruction with memory operand Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 014/111] m68k: add DBcc instruction Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 015/111] m68k: modify movem instruction to manage word Bryce Lanham
2011-08-17 20:46 ` Bryce Lanham [this message]
2011-08-17 20:46 ` [Qemu-devel] [PATCH 017/111] m68k: add 32bit and 64bit multiply Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 018/111] m68k: add word data size for suba/adda Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 019/111] m68k: add fpu Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 020/111] m68k: add "byte", "word" and memory shift Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 021/111] m68k: add "byte", "word" and memory rotate Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 022/111] m68k: add bitfield_mem, bitfield_reg Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 023/111] m68k: add variable offset/width to bitfield_reg/bitfield_mem Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 024/111] m68k: add cas Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 025/111] " Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 026/111] m68k: define fcntl constants Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 027/111] m68k: add DBcc instruction Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 028/111] m68k: allow fpu to manage double data type Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 029/111] m68k: allow fpu to manage double data type with fmove to <ea> Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 030/111] m68k: add FScc instruction Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 031/111] m68k: add single data type to gen_ea Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 032/111] m68k: add linkl instruction Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 033/111] m68k: Add fmovecr Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 034/111] m68k: correct typo on f64_to_i32() return type Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 035/111] m68k: improve CC_OP_LOGIC Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 036/111] m68k: correct neg condition code flags computation Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 037/111] Correct invalid use of "const void *" with "const uint8_t *" Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 038/111] m68k: add EA support for negx Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 039/111] m68k: add abcd instruction Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 040/111] m68k: add sbcd instruction Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 041/111] mm68k: add nbcd instruction Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 042/111] m68k: set X flag according size of operand Set X flag correctly for addsub, arith_im, addsubq Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 043/111] m68k: on 0 bit shift, don't update X flag Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 044/111] m68k: improve addx instructions Add (byte, word) opsize Add memory access Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 045/111] m68k: improve subx, negx instructions Add (byte, word) opsize Add memory access (subx) Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 046/111] m68k: improve asl/asr evaluate correclty the missing V flag Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 047/111] m68k: use read_imm1() when it is possible Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 048/111] m68k: correct shift side effect for roxrl and roxll Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 049/111] m68k: asl/asr, clear C flag if shift count is 0 Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 050/111] m68k: lsl/lsr, " Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 051/111] m68k: correct divs.w and divu.w Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 052/111] m68k: correct flags with negl Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 053/111] m68k: for bitfield opcodes, correct operands corruption Bryce Lanham
2011-08-17 20:46 ` [Qemu-devel] [PATCH 054/111] m68k: Added ULL to 64 bit integer in helper.c Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 055/111] m68k: Correct bfclr in register case Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 056/111] m68k-linux-user: add '--enable-emulop' Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 057/111] m68k: correctly compute divsl Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 058/111] m68k: correctly compute divul Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 059/111] m68k: add m68030 definition Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 060/111] m68k: remove dead code Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 061/111] m68k: remove useless file m68k-qreg.h Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 062/111] m68k: FPU rework (draft) Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 063/111] m68k: some FPU debugging macros Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 064/111] m68k: more tests Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 065/111] m68k: correct compute gen_bitfield_cc() Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 066/111] m68k: add fgetexp Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 067/111] m68k: add fscale Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 068/111] m68k: correct addsubq Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 069/111] m68k: add fetox and flogn Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 070/111] m68k: initialize FRegs, define pickNaN() Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 071/111] m68k: correct cmpa comparison datatype Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 072/111] m68k: add flog10 Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 073/111] m68k: add cmpm instruction Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 074/111] m68k: add ftwotox instruction Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 075/111] m68k: better fpu traces Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 076/111] m68k: register source operand is always in extended size Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 077/111] m68k: add facos instruction Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 078/111] m68k: add ftan instruction Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 079/111] m68k: add fsin instruction Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 080/111] m68k: add fcos instruction Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 081/111] m68k: correct fpcr update Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 082/111] m68k: add fmod instruction Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 083/111] m68k: flush flags before negx instruction Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 084/111] m68k: correct fmovemx FP registers order Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 085/111] m68k: add fatan instruction Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 086/111] m68k: correct bfins instruction Bryce Lanham
2011-08-17 20:47 ` [Qemu-devel] [PATCH 087/111] m68k: fcmp correctly compares infinity Bryce Lanham
2011-08-17 22:35 ` [Qemu-devel] [RFC][PATCH 000/111] QEMU m68k core additions Anthony Liguori
2011-08-17 23:30   ` Bryce Lanham
2011-08-17 23:36     ` Peter Maydell
2011-08-18 16:05     ` Michael Roth
2011-08-18  7:02   ` Laurent Vivier
2011-08-18 11:12     ` François Revol
2011-08-18 14:02       ` Laurent Vivier
2011-08-18 19:42         ` Natalia Portillo
2011-08-18 19:57           ` Laurent Vivier
2011-08-18 20:13             ` Natalia Portillo
2011-08-18 20:51               ` Laurent Vivier
2011-08-19  2:14                 ` Natalia Portillo
2011-08-19  8:55                   ` François Revol
2011-08-19 15:52                     ` Natalia Portillo
2011-08-19 16:07                       ` Laurent Vivier
2011-08-19 20:08                         ` Anthony Liguori
2011-08-20 22:12                           ` Rob Landley
2011-08-20 22:12                     ` Rob Landley
2011-08-20 22:16                 ` Rob Landley
2011-08-20 21:06           ` Rob Landley
2011-08-20 20:57       ` Rob Landley
2011-08-20 21:16         ` Laurent Vivier
2011-08-20 22:28           ` Rob Landley
2011-08-20 22:39           ` Rob Landley
2011-08-20 23:24           ` Rob Landley
2011-08-20 20:55 ` Rob Landley
2011-08-20 23:17   ` Natalia Portillo
2011-08-20 23:42     ` Rob Landley
2011-08-21  0:23       ` Natalia Portillo
2011-08-21  0:50         ` Rob Landley
2011-08-21  2:02           ` Natalia Portillo
2011-08-21 22:14             ` Rob Landley
2011-08-22  2:15               ` Natalia Portillo
2011-08-23 12:30                 ` Rob Landley
2011-08-21 10:04       ` Laurent Vivier
2011-08-21 13:11         ` Natalia Portillo
2011-08-21 22:23         ` Rob Landley

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1313614076-28878-17-git-send-email-blanham@gmail.com \
    --to=blanham@gmail.com \
    --cc=laurent@vivier.eu \
    --cc=qemu-devel@nongnu.org \
    --cc=schwab@linux-m68k.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).