qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/7] target/m68k: implement 680x0 FPU (part 2)
@ 2017-06-25 19:21 Laurent Vivier
  2017-06-25 19:21 ` [Qemu-devel] [PATCH 1/7] target/m68k: add fscc Laurent Vivier
                   ` (6 more replies)
  0 siblings, 7 replies; 18+ messages in thread
From: Laurent Vivier @ 2017-06-25 19:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno, Richard Henderson, Laurent Vivier

Second part of patches submitted in the v3.

This series adds a subset of single precision and
double precision instructions using
set_floatx80_rounding_precision() to round the result.

For some other instructions, we introduce a new
function, floatx80_round(), to round them manually.

It also adds instructions fsglmul, fsgldiv,
fmovecr and fscc (since v3, use tcg_gen_setcond())

fmovem manages static and dynamic register list,
all the code has been moved to an helper.

Laurent Vivier (7):
  target/m68k: add fscc.
  target/m68k: add fmovecr
  target/m68k: add fsglmul and fsgldiv
  target/m68k: add explicit single and double precision operations
  softfloat: define floatx80_round()
  target/m68k: add explicit single and double precision operations (part
    2)
  target/m68k: add fmovem

 fpu/softfloat.c          |  15 ++
 include/fpu/softfloat.h  |   1 +
 target/m68k/fpu_helper.c | 283 ++++++++++++++++++++++++++++++++++++-
 target/m68k/helper.h     |  22 ++-
 target/m68k/translate.c  | 357 +++++++++++++++++++++++++++++++----------------
 5 files changed, 555 insertions(+), 123 deletions(-)

-- 
2.9.4

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [Qemu-devel] [PATCH 1/7] target/m68k: add fscc.
  2017-06-25 19:21 [Qemu-devel] [PATCH 0/7] target/m68k: implement 680x0 FPU (part 2) Laurent Vivier
@ 2017-06-25 19:21 ` Laurent Vivier
  2017-06-25 20:42   ` Richard Henderson
  2017-06-25 19:21 ` [Qemu-devel] [PATCH 2/7] target/m68k: add fmovecr Laurent Vivier
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 18+ messages in thread
From: Laurent Vivier @ 2017-06-25 19:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno, Richard Henderson, Laurent Vivier

use DisasCompare with FPU conditions in fscc and fbcc.

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 target/m68k/translate.c | 213 ++++++++++++++++++++++++++++++------------------
 1 file changed, 134 insertions(+), 79 deletions(-)

diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index 7aa0fdc..099cb69 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -4633,142 +4633,196 @@ undef:
     disas_undef_fpu(env, s, insn);
 }
 
-DISAS_INSN(fbcc)
+static void gen_fcc_cond(DisasCompare *c, DisasContext *s, int cond)
 {
-    uint32_t offset;
-    uint32_t addr;
-    TCGLabel *l1;
-    TCGv tmp, fpsr;
-
-    addr = s->pc;
-    offset = cpu_ldsw_code(env, s->pc);
-    s->pc += 2;
-    if (insn & (1 << 6)) {
-        offset = (offset << 16) | read_im16(env, s);
-    }
+    TCGv fpsr;
 
+    c->g1 = 0;
+    c->v2 = tcg_const_i32(0);
+    c->g2 = 1;
+    /* TODO: Raise BSUN exception.  */
     fpsr = tcg_temp_new();
     gen_load_fcr(s, fpsr, M68K_FPSR);
-    l1 = gen_new_label();
-    /* TODO: Raise BSUN exception.  */
-    /* Jump to l1 if condition is true.  */
-    switch (insn & 0x3f)  {
+    switch (cond) {
     case 0:  /* False */
     case 16: /* Signaling False */
+        c->v1 = c->v2;
+        c->tcond = TCG_COND_NEVER;
         break;
     case 1:  /* EQual Z */
     case 17: /* Signaling EQual Z */
-        tmp = tcg_temp_new();
-        tcg_gen_andi_i32(tmp, fpsr, FPSR_CC_Z);
-        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
+        c->v1 = tcg_temp_new();
+        c->g1 = 1;
+        tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_Z);
+        c->tcond = TCG_COND_NE;
         break;
     case 2:  /* Ordered Greater Than !(A || Z || N) */
     case 18: /* Greater Than !(A || Z || N) */
-        tmp = tcg_temp_new();
-        tcg_gen_andi_i32(tmp, fpsr,
+        c->v1 = tcg_temp_new();
+        c->g1 = 1;
+        tcg_gen_andi_i32(c->v1, fpsr,
                          FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N);
-        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
+        c->tcond = TCG_COND_EQ;
         break;
     case 3:  /* Ordered Greater than or Equal Z || !(A || N) */
     case 19: /* Greater than or Equal Z || !(A || N) */
-        assert(FPSR_CC_A == (FPSR_CC_N >> 3));
-        tmp = tcg_temp_new();
-        tcg_gen_shli_i32(tmp, fpsr, 3);
-        tcg_gen_or_i32(tmp, tmp, fpsr);
-        tcg_gen_xori_i32(tmp, tmp, FPSR_CC_N);
-        tcg_gen_andi_i32(tmp, tmp, FPSR_CC_N | FPSR_CC_Z);
-        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
+        g_assert(FPSR_CC_A == (FPSR_CC_N >> 3));
+        c->v1 = tcg_temp_new();
+        c->g1 = 1;
+        tcg_gen_shli_i32(c->v1, fpsr, 3);
+        tcg_gen_or_i32(c->v1, c->v1, fpsr);
+        tcg_gen_xori_i32(c->v1, c->v1, FPSR_CC_N);
+        tcg_gen_andi_i32(c->v1, c->v1, FPSR_CC_N | FPSR_CC_Z);
+        c->tcond = TCG_COND_NE;
         break;
     case 4:  /* Ordered Less Than !(!N || A || Z); */
     case 20: /* Less Than !(!N || A || Z); */
-        tmp = tcg_temp_new();
-        tcg_gen_xori_i32(tmp, fpsr, FPSR_CC_N);
-        tcg_gen_andi_i32(tmp, tmp, FPSR_CC_N | FPSR_CC_A | FPSR_CC_Z);
-        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
+        c->v1 = tcg_temp_new();
+        c->g1 = 1;
+        tcg_gen_xori_i32(c->v1, fpsr, FPSR_CC_N);
+        tcg_gen_andi_i32(c->v1, c->v1, FPSR_CC_N | FPSR_CC_A | FPSR_CC_Z);
+        c->tcond = TCG_COND_EQ;
         break;
     case 5:  /* Ordered Less than or Equal Z || (N && !A) */
     case 21: /* Less than or Equal Z || (N && !A) */
-        assert(FPSR_CC_A == (FPSR_CC_N >> 3));
-        tmp = tcg_temp_new();
-        tcg_gen_xori_i32(tmp, fpsr, FPSR_CC_A);
-        tcg_gen_shli_i32(tmp, tmp, 3);
-        tcg_gen_ori_i32(tmp, tmp, FPSR_CC_Z);
-        tcg_gen_and_i32(tmp, tmp, fpsr);
-        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
+        g_assert(FPSR_CC_A == (FPSR_CC_N >> 3));
+        c->v1 = tcg_temp_new();
+        c->g1 = 1;
+        tcg_gen_xori_i32(c->v1, fpsr, FPSR_CC_A);
+        tcg_gen_shli_i32(c->v1, c->v1, 3);
+        tcg_gen_ori_i32(c->v1, c->v1, FPSR_CC_Z);
+        tcg_gen_and_i32(c->v1, c->v1, fpsr);
+        c->tcond = TCG_COND_NE;
         break;
     case 6:  /* Ordered Greater or Less than !(A || Z) */
     case 22: /* Greater or Less than !(A || Z) */
-        tmp = tcg_temp_new();
-        tcg_gen_andi_i32(tmp, fpsr, FPSR_CC_A | FPSR_CC_Z);
-        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
+        c->v1 = tcg_temp_new();
+        c->g1 = 1;
+        tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A | FPSR_CC_Z);
+        c->tcond = TCG_COND_EQ;
         break;
     case 7:  /* Ordered !A */
     case 23: /* Greater, Less or Equal !A */
-        tmp = tcg_temp_new();
-        tcg_gen_andi_i32(tmp, fpsr, FPSR_CC_A);
-        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
+        c->v1 = tcg_temp_new();
+        c->g1 = 1;
+        tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A);
+        c->tcond = TCG_COND_EQ;
         break;
     case 8:  /* Unordered A */
     case 24: /* Not Greater, Less or Equal A */
-        tmp = tcg_temp_new();
-        tcg_gen_andi_i32(tmp, fpsr, FPSR_CC_A);
-        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
+        c->v1 = tcg_temp_new();
+        c->g1 = 1;
+        tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A);
+        c->tcond = TCG_COND_NE;
         break;
     case 9:  /* Unordered or Equal A || Z */
     case 25: /* Not Greater or Less then A || Z */
-        tmp = tcg_temp_new();
-        tcg_gen_andi_i32(tmp, fpsr, FPSR_CC_A | FPSR_CC_Z);
-        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
+        c->v1 = tcg_temp_new();
+        c->g1 = 1;
+        tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A | FPSR_CC_Z);
+        c->tcond = TCG_COND_NE;
         break;
     case 10: /* Unordered or Greater Than A || !(N || Z)) */
     case 26: /* Not Less or Equal A || !(N || Z)) */
-        assert(FPSR_CC_Z == (FPSR_CC_N >> 1));
-        tmp = tcg_temp_new();
-        tcg_gen_shli_i32(tmp, fpsr, 1);
-        tcg_gen_or_i32(tmp, tmp, fpsr);
-        tcg_gen_xori_i32(tmp, tmp, FPSR_CC_N);
-        tcg_gen_andi_i32(tmp, tmp, FPSR_CC_N | FPSR_CC_A);
-        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
+        g_assert(FPSR_CC_Z == (FPSR_CC_N >> 1));
+        c->v1 = tcg_temp_new();
+        c->g1 = 1;
+        tcg_gen_shli_i32(c->v1, fpsr, 1);
+        tcg_gen_or_i32(c->v1, c->v1, fpsr);
+        tcg_gen_xori_i32(c->v1, c->v1, FPSR_CC_N);
+        tcg_gen_andi_i32(c->v1, c->v1, FPSR_CC_N | FPSR_CC_A);
+        c->tcond = TCG_COND_NE;
         break;
     case 11: /* Unordered or Greater or Equal A || Z || !N */
     case 27: /* Not Less Than A || Z || !N */
-        tmp = tcg_temp_new();
-        tcg_gen_andi_i32(tmp, fpsr, FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N);
-        tcg_gen_xori_i32(tmp, tmp, FPSR_CC_N);
-        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
+        c->v1 = tcg_temp_new();
+        c->g1 = 1;
+        tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N);
+        tcg_gen_xori_i32(c->v1, c->v1, FPSR_CC_N);
+        c->tcond = TCG_COND_NE;
         break;
     case 12: /* Unordered or Less Than A || (N && !Z) */
     case 28: /* Not Greater than or Equal A || (N && !Z) */
-        assert(FPSR_CC_Z == (FPSR_CC_N >> 1));
-        tmp = tcg_temp_new();
-        tcg_gen_xori_i32(tmp, fpsr, FPSR_CC_Z);
-        tcg_gen_shli_i32(tmp, tmp, 1);
-        tcg_gen_ori_i32(tmp, tmp, FPSR_CC_A);
-        tcg_gen_and_i32(tmp, tmp, fpsr);
-        tcg_gen_andi_i32(tmp, tmp, FPSR_CC_A | FPSR_CC_N);
-        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
+        g_assert(FPSR_CC_Z == (FPSR_CC_N >> 1));
+        c->v1 = tcg_temp_new();
+        c->g1 = 1;
+        tcg_gen_xori_i32(c->v1, fpsr, FPSR_CC_Z);
+        tcg_gen_shli_i32(c->v1, c->v1, 1);
+        tcg_gen_ori_i32(c->v1, c->v1, FPSR_CC_A);
+        tcg_gen_and_i32(c->v1, c->v1, fpsr);
+        tcg_gen_andi_i32(c->v1, c->v1, FPSR_CC_A | FPSR_CC_N);
+        c->tcond = TCG_COND_NE;
         break;
     case 13: /* Unordered or Less or Equal A || Z || N */
     case 29: /* Not Greater Than A || Z || N */
-        tmp = tcg_temp_new();
-        tcg_gen_andi_i32(tmp, fpsr, FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N);
-        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
+        c->v1 = tcg_temp_new();
+        c->g1 = 1;
+        tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N);
+        c->tcond = TCG_COND_NE;
         break;
     case 14: /* Not Equal !Z */
     case 30: /* Signaling Not Equal !Z */
-        tmp = tcg_temp_new();
-        tcg_gen_andi_i32(tmp, fpsr, FPSR_CC_Z);
-        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
+        c->v1 = tcg_temp_new();
+        c->g1 = 1;
+        tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_Z);
+        c->tcond = TCG_COND_EQ;
         break;
     case 15: /* True */
     case 31: /* Signaling True */
-        tcg_gen_br(l1);
+        c->v1 = c->v2;
+        c->tcond = TCG_COND_ALWAYS;
         break;
     }
     tcg_temp_free(fpsr);
+}
+
+static void gen_fjmpcc(DisasContext *s, int cond, TCGLabel *l1)
+{
+    DisasCompare c;
+
+    gen_fcc_cond(&c, s, cond);
+    tcg_gen_brcond_i32(c.tcond, c.v1, c.v2, l1);
+    free_cond(&c);
+}
+
+DISAS_INSN(fbcc)
+{
+    uint32_t offset;
+    uint32_t base;
+    TCGLabel *l1;
+
+    base = s->pc;
+    offset = (int16_t)read_im16(env, s);
+    if (insn & (1 << 6)) {
+        offset = (offset << 16) | read_im16(env, s);
+    }
+
+    l1 = gen_new_label();
+    update_cc_op(s);
+    gen_fjmpcc(s, insn & 0x3f, l1);
     gen_jmp_tb(s, 0, s->pc);
     gen_set_label(l1);
-    gen_jmp_tb(s, 1, addr + offset);
+    gen_jmp_tb(s, 1, base + offset);
+}
+
+DISAS_INSN(fscc)
+{
+    DisasCompare c;
+    int cond;
+    TCGv tmp;
+    uint16_t ext;
+
+    ext = read_im16(env, s);
+    cond = ext & 0x3f;
+    gen_fcc_cond(&c, s, cond);
+
+    tmp = tcg_temp_new();
+    tcg_gen_setcond_i32(c.tcond, tmp, c.v1, c.v2);
+    free_cond(&c);
+
+    tcg_gen_neg_i32(tmp, tmp);
+    DEST_EA(env, insn, OS_BYTE, tmp, NULL);
+    tcg_temp_free(tmp);
 }
 
 DISAS_INSN(frestore)
@@ -5349,6 +5403,7 @@ void register_m68k_insns (CPUM68KState *env)
     INSN(frestore,  f340, ffc0, CF_FPU);
     INSN(fsave,     f300, ffc0, CF_FPU);
     INSN(fpu,       f200, ffc0, FPU);
+    INSN(fscc,      f240, ffc0, FPU);
     INSN(fbcc,      f280, ff80, FPU);
     INSN(frestore,  f340, ffc0, FPU);
     INSN(fsave,     f300, ffc0, FPU);
-- 
2.9.4

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Qemu-devel] [PATCH 2/7] target/m68k: add fmovecr
  2017-06-25 19:21 [Qemu-devel] [PATCH 0/7] target/m68k: implement 680x0 FPU (part 2) Laurent Vivier
  2017-06-25 19:21 ` [Qemu-devel] [PATCH 1/7] target/m68k: add fscc Laurent Vivier
@ 2017-06-25 19:21 ` Laurent Vivier
  2017-06-26 18:15   ` Richard Henderson
  2017-06-25 19:21 ` [Qemu-devel] [PATCH 3/7] target/m68k: add fsglmul and fsgldiv Laurent Vivier
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 18+ messages in thread
From: Laurent Vivier @ 2017-06-25 19:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno, Richard Henderson, Laurent Vivier

fmovecr moves a floating point constant from the
FPU ROM to a floating point register.

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 target/m68k/fpu_helper.c | 30 ++++++++++++++++++++++++++++++
 target/m68k/helper.h     |  1 +
 target/m68k/translate.c  | 13 ++++++++++++-
 3 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
index a9e17f5..912c0b7 100644
--- a/target/m68k/fpu_helper.c
+++ b/target/m68k/fpu_helper.c
@@ -23,6 +23,31 @@
 #include "exec/helper-proto.h"
 #include "exec/exec-all.h"
 
+static const floatx80 fpu_rom[128] = {
+    [0x00] = floatx80_pi,                                   /* Pi */
+    [0x0b] = make_floatx80(0x3ffd, 0x9a209a84fbcff798ULL),  /* Log10(2) */
+    [0x0c] = make_floatx80(0x4000, 0xadf85458a2bb4a9aULL),  /* e        */
+    [0x0d] = make_floatx80(0x3fff, 0xb8aa3b295c17f0bcULL),  /* Log2(e)  */
+    [0x0e] = make_floatx80(0x3ffd, 0xde5bd8a937287195ULL),  /* Log10(e) */
+    [0x0f] = floatx80_zero,                                 /* Zero     */
+    [0x30] = floatx80_ln2,                                  /* ln(2)    */
+    [0x31] = make_floatx80(0x4000, 0x935d8dddaaa8ac17ULL),  /* ln(10)   */
+    [0x32] = floatx80_one,                                  /* 10^0     */
+    [0x33] = make_floatx80(0x4002, 0xa000000000000000ULL),  /* 10^1     */
+    [0x34] = make_floatx80(0x4005, 0xc800000000000000ULL),  /* 10^2     */
+    [0x35] = make_floatx80(0x400c, 0x9c40000000000000ULL),  /* 10^4     */
+    [0x36] = make_floatx80(0x4019, 0xbebc200000000000ULL),  /* 10^8     */
+    [0x37] = make_floatx80(0x4034, 0x8e1bc9bf04000000ULL),  /* 10^16    */
+    [0x38] = make_floatx80(0x4069, 0x9dc5ada82b70b59eULL),  /* 10^32    */
+    [0x39] = make_floatx80(0x40d3, 0xc2781f49ffcfa6d5ULL),  /* 10^64    */
+    [0x3a] = make_floatx80(0x41a8, 0x93ba47c980e98ce0ULL),  /* 10^128   */
+    [0x3b] = make_floatx80(0x4351, 0xaa7eebfb9df9de8eULL),  /* 10^256   */
+    [0x3c] = make_floatx80(0x46a3, 0xe319a0aea60e91c7ULL),  /* 10^512   */
+    [0x3d] = make_floatx80(0x4d48, 0xc976758681750c17ULL),  /* 10^1024  */
+    [0x3e] = make_floatx80(0x5a92, 0x9e8b3b5dc53d5de5ULL),  /* 10^2048  */
+    [0x3f] = make_floatx80(0x7525, 0xc46052028a20979bULL),  /* 10^4096  */
+};
+
 int32_t HELPER(reds32)(CPUM68KState *env, FPReg *val)
 {
     return floatx80_to_int32(val->d, &env->fp_status);
@@ -204,3 +229,8 @@ void HELPER(ftst)(CPUM68KState *env, FPReg *val)
     }
     env->fpsr = (env->fpsr & ~FPSR_CC_MASK) | cc;
 }
+
+void HELPER(fconst)(CPUM68KState *env, FPReg *val, uint32_t offset)
+{
+    val->d = fpu_rom[offset];
+}
diff --git a/target/m68k/helper.h b/target/m68k/helper.h
index 98cbf18..d6e80e4 100644
--- a/target/m68k/helper.h
+++ b/target/m68k/helper.h
@@ -35,6 +35,7 @@ DEF_HELPER_4(fdiv, void, env, fp, fp, fp)
 DEF_HELPER_FLAGS_3(fcmp, TCG_CALL_NO_RWG, void, env, fp, fp)
 DEF_HELPER_FLAGS_2(set_fpcr, TCG_CALL_NO_RWG, void, env, i32)
 DEF_HELPER_FLAGS_2(ftst, TCG_CALL_NO_RWG, void, env, fp)
+DEF_HELPER_3(fconst, void, env, fp, i32)
 
 DEF_HELPER_3(mac_move, void, env, i32, i32)
 DEF_HELPER_3(macmulf, i64, env, i32, i32)
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index 099cb69..a54da87 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -4510,6 +4510,7 @@ static void gen_op_fmove_fcr(CPUM68KState *env, DisasContext *s,
 DISAS_INSN(fpu)
 {
     uint16_t ext;
+    uint8_t rom_offset;
     int opmode;
     TCGv tmp32;
     int opsize;
@@ -4518,10 +4519,20 @@ DISAS_INSN(fpu)
     ext = read_im16(env, s);
     opmode = ext & 0x7f;
     switch ((ext >> 13) & 7) {
-    case 0: case 2:
+    case 0:
         break;
     case 1:
         goto undef;
+    case 2:
+        if (insn == 0xf200 && (ext & 0xfc00) == 0x5c00) {
+            /* fmovecr */
+            rom_offset = ext & 0x7f;
+            cpu_dest = gen_fp_ptr(REG(ext, 7));
+            gen_helper_fconst(cpu_env, cpu_dest, tcg_const_i32(rom_offset));
+            tcg_temp_free_ptr(cpu_dest);
+            return;
+        }
+        break;
     case 3: /* fmove out */
         cpu_src = gen_fp_ptr(REG(ext, 7));
         opsize = ext_opsize(ext, 10);
-- 
2.9.4

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Qemu-devel] [PATCH 3/7] target/m68k: add fsglmul and fsgldiv
  2017-06-25 19:21 [Qemu-devel] [PATCH 0/7] target/m68k: implement 680x0 FPU (part 2) Laurent Vivier
  2017-06-25 19:21 ` [Qemu-devel] [PATCH 1/7] target/m68k: add fscc Laurent Vivier
  2017-06-25 19:21 ` [Qemu-devel] [PATCH 2/7] target/m68k: add fmovecr Laurent Vivier
@ 2017-06-25 19:21 ` Laurent Vivier
  2017-06-25 19:44   ` Philippe Mathieu-Daudé
  2017-06-25 19:21 ` [Qemu-devel] [PATCH 4/7] target/m68k: add explicit single and double precision operations Laurent Vivier
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 18+ messages in thread
From: Laurent Vivier @ 2017-06-25 19:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno, Richard Henderson, Laurent Vivier

fsglmul and fsgldiv truncate data to single precision before computing
results.

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 target/m68k/fpu_helper.c | 22 ++++++++++++++++++++++
 target/m68k/helper.h     |  2 ++
 target/m68k/translate.c  |  6 ++++++
 3 files changed, 30 insertions(+)

diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
index 912c0b7..0d83925 100644
--- a/target/m68k/fpu_helper.c
+++ b/target/m68k/fpu_helper.c
@@ -183,11 +183,33 @@ void HELPER(fmul)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
     res->d = floatx80_mul(val0->d, val1->d, &env->fp_status);
 }
 
+void HELPER(fsglmul)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
+{
+    float32 a, b, c;
+
+    a = floatx80_to_float32(val0->d, &env->fp_status);
+    b = floatx80_to_float32(val1->d, &env->fp_status);
+    c = float32_mul(a, b, &env->fp_status);
+
+    res->d = float32_to_floatx80(c, &env->fp_status);
+}
+
 void HELPER(fdiv)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
 {
     res->d = floatx80_div(val1->d, val0->d, &env->fp_status);
 }
 
+void HELPER(fsgldiv)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
+{
+    float32 a, b, c;
+
+    a = floatx80_to_float32(val1->d, &env->fp_status);
+    b = floatx80_to_float32(val0->d, &env->fp_status);
+    c = float32_div(a, b, &env->fp_status);
+
+    res->d = float32_to_floatx80(c, &env->fp_status);
+}
+
 static int float_comp_to_cc(int float_compare)
 {
     switch (float_compare) {
diff --git a/target/m68k/helper.h b/target/m68k/helper.h
index d6e80e4..5a006de 100644
--- a/target/m68k/helper.h
+++ b/target/m68k/helper.h
@@ -31,7 +31,9 @@ DEF_HELPER_3(fchs, void, env, fp, fp)
 DEF_HELPER_4(fadd, void, env, fp, fp, fp)
 DEF_HELPER_4(fsub, void, env, fp, fp, fp)
 DEF_HELPER_4(fmul, void, env, fp, fp, fp)
+DEF_HELPER_4(fsglmul, void, env, fp, fp, fp)
 DEF_HELPER_4(fdiv, void, env, fp, fp, fp)
+DEF_HELPER_4(fsgldiv, void, env, fp, fp, fp)
 DEF_HELPER_FLAGS_3(fcmp, TCG_CALL_NO_RWG, void, env, fp, fp)
 DEF_HELPER_FLAGS_2(set_fpcr, TCG_CALL_NO_RWG, void, env, i32)
 DEF_HELPER_FLAGS_2(ftst, TCG_CALL_NO_RWG, void, env, fp)
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index a54da87..a50bf5f 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -4622,6 +4622,12 @@ DISAS_INSN(fpu)
     case 0x23: case 0x63: case 0x67: /* fmul */
         gen_helper_fmul(cpu_env, cpu_dest, cpu_src, cpu_dest);
         break;
+    case 0x24: /* fsgldiv */
+        gen_helper_fsgldiv(cpu_env, cpu_dest, cpu_src, cpu_dest);
+        break;
+    case 0x27: /* fsglmul */
+        gen_helper_fsglmul(cpu_env, cpu_dest, cpu_src, cpu_dest);
+        break;
     case 0x28: case 0x68: case 0x6c: /* fsub */
         gen_helper_fsub(cpu_env, cpu_dest, cpu_src, cpu_dest);
         break;
-- 
2.9.4

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Qemu-devel] [PATCH 4/7] target/m68k: add explicit single and double precision operations
  2017-06-25 19:21 [Qemu-devel] [PATCH 0/7] target/m68k: implement 680x0 FPU (part 2) Laurent Vivier
                   ` (2 preceding siblings ...)
  2017-06-25 19:21 ` [Qemu-devel] [PATCH 3/7] target/m68k: add fsglmul and fsgldiv Laurent Vivier
@ 2017-06-25 19:21 ` Laurent Vivier
  2017-06-26 18:26   ` Richard Henderson
  2017-06-25 19:21 ` [Qemu-devel] [PATCH 5/7] softfloat: define floatx80_round() Laurent Vivier
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 18+ messages in thread
From: Laurent Vivier @ 2017-06-25 19:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno, Richard Henderson, Laurent Vivier

Add fssqrt, fdsqrt, fsadd, fdadd, fssub, fdsub, fsmul, fdmul,
fsdiv, fddiv.

The precision is managed using set_floatx80_rounding_precision().

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 target/m68k/fpu_helper.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++
 target/m68k/helper.h     | 10 ++++++
 target/m68k/translate.c  | 40 +++++++++++++++++++++---
 3 files changed, 125 insertions(+), 5 deletions(-)

diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
index 0d83925..3518863 100644
--- a/target/m68k/fpu_helper.c
+++ b/target/m68k/fpu_helper.c
@@ -153,11 +153,35 @@ void HELPER(set_fpcr)(CPUM68KState *env, uint32_t val)
     cpu_m68k_set_fpcr(env, val);
 }
 
+#define PREC_BEGIN(prec)                                        \
+    do {                                                        \
+        int old;                                                \
+        old = get_floatx80_rounding_precision(&env->fp_status); \
+        set_floatx80_rounding_precision(prec, &env->fp_status)  \
+
+#define PREC_END()                                              \
+        set_floatx80_rounding_precision(old, &env->fp_status);  \
+    } while (0)
+
 void HELPER(fsqrt)(CPUM68KState *env, FPReg *res, FPReg *val)
 {
     res->d = floatx80_sqrt(val->d, &env->fp_status);
 }
 
+void HELPER(fssqrt)(CPUM68KState *env, FPReg *res, FPReg *val)
+{
+    PREC_BEGIN(32);
+    res->d = floatx80_sqrt(val->d, &env->fp_status);
+    PREC_END();
+}
+
+void HELPER(fdsqrt)(CPUM68KState *env, FPReg *res, FPReg *val)
+{
+    PREC_BEGIN(64);
+    res->d = floatx80_sqrt(val->d, &env->fp_status);
+    PREC_END();
+}
+
 void HELPER(fabs)(CPUM68KState *env, FPReg *res, FPReg *val)
 {
     res->d = floatx80_abs(val->d);
@@ -173,16 +197,58 @@ void HELPER(fadd)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
     res->d = floatx80_add(val0->d, val1->d, &env->fp_status);
 }
 
+void HELPER(fsadd)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
+{
+    PREC_BEGIN(32);
+    res->d = floatx80_add(val0->d, val1->d, &env->fp_status);
+    PREC_END();
+}
+
+void HELPER(fdadd)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
+{
+    PREC_BEGIN(64);
+    res->d = floatx80_add(val0->d, val1->d, &env->fp_status);
+    PREC_END();
+}
+
 void HELPER(fsub)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
 {
     res->d = floatx80_sub(val1->d, val0->d, &env->fp_status);
 }
 
+void HELPER(fssub)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
+{
+    PREC_BEGIN(32);
+    res->d = floatx80_sub(val1->d, val0->d, &env->fp_status);
+    PREC_END();
+}
+
+void HELPER(fdsub)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
+{
+    PREC_BEGIN(64);
+    res->d = floatx80_sub(val1->d, val0->d, &env->fp_status);
+    PREC_END();
+}
+
 void HELPER(fmul)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
 {
     res->d = floatx80_mul(val0->d, val1->d, &env->fp_status);
 }
 
+void HELPER(fsmul)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
+{
+    PREC_BEGIN(32);
+    res->d = floatx80_mul(val0->d, val1->d, &env->fp_status);
+    PREC_END();
+}
+
+void HELPER(fdmul)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
+{
+    PREC_BEGIN(64);
+    res->d = floatx80_mul(val0->d, val1->d, &env->fp_status);
+    PREC_END();
+}
+
 void HELPER(fsglmul)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
 {
     float32 a, b, c;
@@ -199,6 +265,20 @@ void HELPER(fdiv)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
     res->d = floatx80_div(val1->d, val0->d, &env->fp_status);
 }
 
+void HELPER(fsdiv)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
+{
+    PREC_BEGIN(32);
+    res->d = floatx80_div(val1->d, val0->d, &env->fp_status);
+    PREC_END();
+}
+
+void HELPER(fddiv)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
+{
+    PREC_BEGIN(64);
+    res->d = floatx80_div(val1->d, val0->d, &env->fp_status);
+    PREC_END();
+}
+
 void HELPER(fsgldiv)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
 {
     float32 a, b, c;
diff --git a/target/m68k/helper.h b/target/m68k/helper.h
index 5a006de..f05191b 100644
--- a/target/m68k/helper.h
+++ b/target/m68k/helper.h
@@ -26,13 +26,23 @@ DEF_HELPER_2(reds32, s32, env, fp)
 DEF_HELPER_3(firound, void, env, fp, fp)
 DEF_HELPER_3(fitrunc, void, env, fp, fp)
 DEF_HELPER_3(fsqrt, void, env, fp, fp)
+DEF_HELPER_3(fssqrt, void, env, fp, fp)
+DEF_HELPER_3(fdsqrt, void, env, fp, fp)
 DEF_HELPER_3(fabs, void, env, fp, fp)
 DEF_HELPER_3(fchs, void, env, fp, fp)
 DEF_HELPER_4(fadd, void, env, fp, fp, fp)
+DEF_HELPER_4(fsadd, void, env, fp, fp, fp)
+DEF_HELPER_4(fdadd, void, env, fp, fp, fp)
 DEF_HELPER_4(fsub, void, env, fp, fp, fp)
+DEF_HELPER_4(fssub, void, env, fp, fp, fp)
+DEF_HELPER_4(fdsub, void, env, fp, fp, fp)
 DEF_HELPER_4(fmul, void, env, fp, fp, fp)
+DEF_HELPER_4(fsmul, void, env, fp, fp, fp)
+DEF_HELPER_4(fdmul, void, env, fp, fp, fp)
 DEF_HELPER_4(fsglmul, void, env, fp, fp, fp)
 DEF_HELPER_4(fdiv, void, env, fp, fp, fp)
+DEF_HELPER_4(fsdiv, void, env, fp, fp, fp)
+DEF_HELPER_4(fddiv, void, env, fp, fp, fp)
 DEF_HELPER_4(fsgldiv, void, env, fp, fp, fp)
 DEF_HELPER_FLAGS_3(fcmp, TCG_CALL_NO_RWG, void, env, fp, fp)
 DEF_HELPER_FLAGS_2(set_fpcr, TCG_CALL_NO_RWG, void, env, i32)
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index a50bf5f..22d499f 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -4604,33 +4604,63 @@ DISAS_INSN(fpu)
     case 3: /* fintrz */
         gen_helper_fitrunc(cpu_env, cpu_dest, cpu_src);
         break;
-    case 4: case 0x41: case 0x45: /* fsqrt */
+    case 4: /* fsqrt */
         gen_helper_fsqrt(cpu_env, cpu_dest, cpu_src);
         break;
+    case 0x41: /* fssqrt */
+        gen_helper_fssqrt(cpu_env, cpu_dest, cpu_src);
+        break;
+    case 0x45: /* fdsqrt */
+        gen_helper_fdsqrt(cpu_env, cpu_dest, cpu_src);
+        break;
     case 0x18: case 0x58: case 0x5c: /* fabs */
         gen_helper_fabs(cpu_env, cpu_dest, cpu_src);
         break;
     case 0x1a: case 0x5a: case 0x5e: /* fneg */
         gen_helper_fchs(cpu_env, cpu_dest, cpu_src);
         break;
-    case 0x20: case 0x60: case 0x64: /* fdiv */
+    case 0x20: /* fdiv */
         gen_helper_fdiv(cpu_env, cpu_dest, cpu_src, cpu_dest);
         break;
-    case 0x22: case 0x62: case 0x66: /* fadd */
+    case 0x60: /* fsdiv */
+        gen_helper_fsdiv(cpu_env, cpu_dest, cpu_src, cpu_dest);
+        break;
+    case 0x64: /* fddiv */
+        gen_helper_fddiv(cpu_env, cpu_dest, cpu_src, cpu_dest);
+        break;
+    case 0x22: /* fadd */
         gen_helper_fadd(cpu_env, cpu_dest, cpu_src, cpu_dest);
         break;
-    case 0x23: case 0x63: case 0x67: /* fmul */
+    case 0x62: /* fsadd */
+        gen_helper_fsadd(cpu_env, cpu_dest, cpu_src, cpu_dest);
+        break;
+    case 0x66: /* fdadd */
+        gen_helper_fdadd(cpu_env, cpu_dest, cpu_src, cpu_dest);
+        break;
+    case 0x23: /* fmul */
         gen_helper_fmul(cpu_env, cpu_dest, cpu_src, cpu_dest);
         break;
+    case 0x63: /* fsmul */
+        gen_helper_fsmul(cpu_env, cpu_dest, cpu_src, cpu_dest);
+        break;
+    case 0x67: /* fdmul */
+        gen_helper_fdmul(cpu_env, cpu_dest, cpu_src, cpu_dest);
+        break;
     case 0x24: /* fsgldiv */
         gen_helper_fsgldiv(cpu_env, cpu_dest, cpu_src, cpu_dest);
         break;
     case 0x27: /* fsglmul */
         gen_helper_fsglmul(cpu_env, cpu_dest, cpu_src, cpu_dest);
         break;
-    case 0x28: case 0x68: case 0x6c: /* fsub */
+    case 0x28: /* fsub */
         gen_helper_fsub(cpu_env, cpu_dest, cpu_src, cpu_dest);
         break;
+    case 0x68: /* fssub */
+        gen_helper_fssub(cpu_env, cpu_dest, cpu_src, cpu_dest);
+        break;
+    case 0x6c: /* fdsub */
+        gen_helper_fdsub(cpu_env, cpu_dest, cpu_src, cpu_dest);
+        break;
     case 0x38: /* fcmp */
         gen_helper_fcmp(cpu_env, cpu_src, cpu_dest);
         return;
-- 
2.9.4

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Qemu-devel] [PATCH 5/7] softfloat: define floatx80_round()
  2017-06-25 19:21 [Qemu-devel] [PATCH 0/7] target/m68k: implement 680x0 FPU (part 2) Laurent Vivier
                   ` (3 preceding siblings ...)
  2017-06-25 19:21 ` [Qemu-devel] [PATCH 4/7] target/m68k: add explicit single and double precision operations Laurent Vivier
@ 2017-06-25 19:21 ` Laurent Vivier
  2017-06-26 18:29   ` Richard Henderson
  2017-06-26 19:07   ` Richard Henderson
  2017-06-25 19:21 ` [Qemu-devel] [PATCH 6/7] target/m68k: add explicit single and double precision operations (part 2) Laurent Vivier
  2017-06-25 19:21 ` [Qemu-devel] [PATCH 7/7] target/m68k: add fmovem Laurent Vivier
  6 siblings, 2 replies; 18+ messages in thread
From: Laurent Vivier @ 2017-06-25 19:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno, Richard Henderson, Laurent Vivier

Add a function to round a floatx80 to the defined precision
(floatx80_rounding_precision)

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 fpu/softfloat.c         | 15 +++++++++++++++
 include/fpu/softfloat.h |  1 +
 2 files changed, 16 insertions(+)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 7af14e2..e9bf359 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -5086,6 +5086,21 @@ float128 floatx80_to_float128(floatx80 a, float_status *status)
 }
 
 /*----------------------------------------------------------------------------
+| Rounds the extended double-precision floating-point value `a'
+| and returns the result as an extended double-precision floating-point
+| value.  The operation is performed according to the IEC/IEEE Standard for
+| Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+floatx80 floatx80_round(floatx80 a, float_status *status)
+{
+    return roundAndPackFloatx80(status->floatx80_rounding_precision,
+                                extractFloatx80Sign(a),
+                                extractFloatx80Exp(a),
+                                extractFloatx80Frac(a), 0, status);
+}
+
+/*----------------------------------------------------------------------------
 | Rounds the extended double-precision floating-point value `a' to an integer,
 | and returns the result as an extended quadruple-precision floating-point
 | value.  The operation is performed according to the IEC/IEEE Standard for
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index f1288ef..d9689ec 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -621,6 +621,7 @@ float128 floatx80_to_float128(floatx80, float_status *status);
 /*----------------------------------------------------------------------------
 | Software IEC/IEEE extended double-precision operations.
 *----------------------------------------------------------------------------*/
+floatx80 floatx80_round(floatx80 a, float_status *status);
 floatx80 floatx80_round_to_int(floatx80, float_status *status);
 floatx80 floatx80_add(floatx80, floatx80, float_status *status);
 floatx80 floatx80_sub(floatx80, floatx80, float_status *status);
-- 
2.9.4

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Qemu-devel] [PATCH 6/7] target/m68k: add explicit single and double precision operations (part 2)
  2017-06-25 19:21 [Qemu-devel] [PATCH 0/7] target/m68k: implement 680x0 FPU (part 2) Laurent Vivier
                   ` (4 preceding siblings ...)
  2017-06-25 19:21 ` [Qemu-devel] [PATCH 5/7] softfloat: define floatx80_round() Laurent Vivier
@ 2017-06-25 19:21 ` Laurent Vivier
  2017-06-26 18:30   ` Richard Henderson
  2017-06-25 19:21 ` [Qemu-devel] [PATCH 7/7] target/m68k: add fmovem Laurent Vivier
  6 siblings, 1 reply; 18+ messages in thread
From: Laurent Vivier @ 2017-06-25 19:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno, Richard Henderson, Laurent Vivier

Add fsabs, fdabs, fsneg, fdneg, fsmove and fdmove.

The value is converted using the new floatx80_round() function.

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 target/m68k/fpu_helper.c | 48 +++++++++++++++++++++++++++++++++++++++++++++---
 target/m68k/helper.h     |  8 +++++++-
 target/m68k/translate.c  | 26 ++++++++++++++++++++++----
 3 files changed, 74 insertions(+), 8 deletions(-)

diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
index 3518863..38370d0 100644
--- a/target/m68k/fpu_helper.c
+++ b/target/m68k/fpu_helper.c
@@ -163,6 +163,20 @@ void HELPER(set_fpcr)(CPUM68KState *env, uint32_t val)
         set_floatx80_rounding_precision(old, &env->fp_status);  \
     } while (0)
 
+void HELPER(fsround)(CPUM68KState *env, FPReg *res, FPReg *val)
+{
+    PREC_BEGIN(32);
+    res->d = floatx80_round(val->d, &env->fp_status);
+    PREC_END();
+}
+
+void HELPER(fdround)(CPUM68KState *env, FPReg *res, FPReg *val)
+{
+    PREC_BEGIN(64);
+    res->d = floatx80_round(val->d, &env->fp_status);
+    PREC_END();
+}
+
 void HELPER(fsqrt)(CPUM68KState *env, FPReg *res, FPReg *val)
 {
     res->d = floatx80_sqrt(val->d, &env->fp_status);
@@ -184,12 +198,40 @@ void HELPER(fdsqrt)(CPUM68KState *env, FPReg *res, FPReg *val)
 
 void HELPER(fabs)(CPUM68KState *env, FPReg *res, FPReg *val)
 {
-    res->d = floatx80_abs(val->d);
+    res->d = floatx80_round(floatx80_abs(val->d), &env->fp_status);
+}
+
+void HELPER(fsabs)(CPUM68KState *env, FPReg *res, FPReg *val)
+{
+    PREC_BEGIN(32);
+    res->d = floatx80_round(floatx80_abs(val->d), &env->fp_status);
+    PREC_END();
+}
+
+void HELPER(fdabs)(CPUM68KState *env, FPReg *res, FPReg *val)
+{
+    PREC_BEGIN(64);
+    res->d = floatx80_round(floatx80_abs(val->d), &env->fp_status);
+    PREC_END();
+}
+
+void HELPER(fneg)(CPUM68KState *env, FPReg *res, FPReg *val)
+{
+    res->d = floatx80_round(floatx80_chs(val->d), &env->fp_status);
 }
 
-void HELPER(fchs)(CPUM68KState *env, FPReg *res, FPReg *val)
+void HELPER(fsneg)(CPUM68KState *env, FPReg *res, FPReg *val)
 {
-    res->d = floatx80_chs(val->d);
+    PREC_BEGIN(32);
+    res->d = floatx80_round(floatx80_chs(val->d), &env->fp_status);
+    PREC_END();
+}
+
+void HELPER(fdneg)(CPUM68KState *env, FPReg *res, FPReg *val)
+{
+    PREC_BEGIN(64);
+    res->d = floatx80_round(floatx80_chs(val->d), &env->fp_status);
+    PREC_END();
 }
 
 void HELPER(fadd)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
diff --git a/target/m68k/helper.h b/target/m68k/helper.h
index f05191b..b396899 100644
--- a/target/m68k/helper.h
+++ b/target/m68k/helper.h
@@ -23,13 +23,19 @@ DEF_HELPER_2(redf32, f32, env, fp)
 DEF_HELPER_2(redf64, f64, env, fp)
 DEF_HELPER_2(reds32, s32, env, fp)
 
+DEF_HELPER_3(fsround, void, env, fp, fp)
+DEF_HELPER_3(fdround, void, env, fp, fp)
 DEF_HELPER_3(firound, void, env, fp, fp)
 DEF_HELPER_3(fitrunc, void, env, fp, fp)
 DEF_HELPER_3(fsqrt, void, env, fp, fp)
 DEF_HELPER_3(fssqrt, void, env, fp, fp)
 DEF_HELPER_3(fdsqrt, void, env, fp, fp)
 DEF_HELPER_3(fabs, void, env, fp, fp)
-DEF_HELPER_3(fchs, void, env, fp, fp)
+DEF_HELPER_3(fsabs, void, env, fp, fp)
+DEF_HELPER_3(fdabs, void, env, fp, fp)
+DEF_HELPER_3(fneg, void, env, fp, fp)
+DEF_HELPER_3(fsneg, void, env, fp, fp)
+DEF_HELPER_3(fdneg, void, env, fp, fp)
 DEF_HELPER_4(fadd, void, env, fp, fp, fp)
 DEF_HELPER_4(fsadd, void, env, fp, fp, fp)
 DEF_HELPER_4(fdadd, void, env, fp, fp, fp)
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index 22d499f..3a1bdc1 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -4595,9 +4595,15 @@ DISAS_INSN(fpu)
     }
     cpu_dest = gen_fp_ptr(REG(ext, 7));
     switch (opmode) {
-    case 0: case 0x40: case 0x44: /* fmove */
+    case 0: /* fmove */
         gen_fp_move(cpu_dest, cpu_src);
         break;
+    case 0x40: /* fsmove */
+        gen_helper_fsround(cpu_env, cpu_dest, cpu_src);
+        break;
+    case 0x44: /* fdmove */
+        gen_helper_fdround(cpu_env, cpu_dest, cpu_src);
+        break;
     case 1: /* fint */
         gen_helper_firound(cpu_env, cpu_dest, cpu_src);
         break;
@@ -4613,11 +4619,23 @@ DISAS_INSN(fpu)
     case 0x45: /* fdsqrt */
         gen_helper_fdsqrt(cpu_env, cpu_dest, cpu_src);
         break;
-    case 0x18: case 0x58: case 0x5c: /* fabs */
+    case 0x18: /* fabs */
         gen_helper_fabs(cpu_env, cpu_dest, cpu_src);
         break;
-    case 0x1a: case 0x5a: case 0x5e: /* fneg */
-        gen_helper_fchs(cpu_env, cpu_dest, cpu_src);
+    case 0x58: /* fsabs */
+        gen_helper_fsabs(cpu_env, cpu_dest, cpu_src);
+        break;
+    case 0x5c: /* fdabs */
+        gen_helper_fdabs(cpu_env, cpu_dest, cpu_src);
+        break;
+    case 0x1a: /* fneg */
+        gen_helper_fneg(cpu_env, cpu_dest, cpu_src);
+        break;
+    case 0x5a: /* fsneg */
+        gen_helper_fsneg(cpu_env, cpu_dest, cpu_src);
+        break;
+    case 0x5e: /* fdneg */
+        gen_helper_fdneg(cpu_env, cpu_dest, cpu_src);
         break;
     case 0x20: /* fdiv */
         gen_helper_fdiv(cpu_env, cpu_dest, cpu_src, cpu_dest);
-- 
2.9.4

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Qemu-devel] [PATCH 7/7] target/m68k: add fmovem
  2017-06-25 19:21 [Qemu-devel] [PATCH 0/7] target/m68k: implement 680x0 FPU (part 2) Laurent Vivier
                   ` (5 preceding siblings ...)
  2017-06-25 19:21 ` [Qemu-devel] [PATCH 6/7] target/m68k: add explicit single and double precision operations (part 2) Laurent Vivier
@ 2017-06-25 19:21 ` Laurent Vivier
  2017-06-26 18:40   ` Richard Henderson
  6 siblings, 1 reply; 18+ messages in thread
From: Laurent Vivier @ 2017-06-25 19:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno, Richard Henderson, Laurent Vivier

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 target/m68k/fpu_helper.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++
 target/m68k/helper.h     |   1 +
 target/m68k/translate.c  |  59 +++++++++++++--------------
 3 files changed, 133 insertions(+), 30 deletions(-)

diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
index 38370d0..3e765d6 100644
--- a/target/m68k/fpu_helper.c
+++ b/target/m68k/fpu_helper.c
@@ -22,6 +22,7 @@
 #include "cpu.h"
 #include "exec/helper-proto.h"
 #include "exec/exec-all.h"
+#include "exec/cpu_ldst.h"
 
 static const floatx80 fpu_rom[128] = {
     [0x00] = floatx80_pi,                                   /* Pi */
@@ -378,3 +379,105 @@ void HELPER(fconst)(CPUM68KState *env, FPReg *val, uint32_t offset)
 {
     val->d = fpu_rom[offset];
 }
+
+static void cpu_ld_floatx80_ra(CPUM68KState *env, FPReg *fp,  uint32_t addr,
+                               uintptr_t ra)
+{
+    uint32_t high;
+    uint64_t low;
+
+    high = cpu_ldl_data_ra(env, addr, ra);
+    low = cpu_ldq_data_ra(env, addr + 4, ra);
+
+    fp->l.upper = high >> 16;
+    fp->l.lower = low;
+}
+
+static void cpu_st_floatx80_ra(CPUM68KState *env, uint32_t addr, FPReg *fp,
+                               uintptr_t ra)
+{
+    cpu_stl_data_ra(env, addr, fp->l.upper << 16, ra);
+    cpu_stq_data_ra(env, addr + 4, fp->l.lower, ra);
+}
+
+static void cpu_ld_float64_ra(CPUM68KState *env, FPReg *fp,  uint32_t addr,
+                              uintptr_t ra)
+{
+    uint64_t val;
+
+    val = cpu_ldq_data_ra(env, addr, ra);
+    fp->d = float64_to_floatx80(*(float64 *)&val, &env->fp_status);
+}
+
+static void cpu_st_float64_ra(CPUM68KState *env, uint32_t addr, FPReg *fp,
+                              uintptr_t ra)
+{
+    float64 val;
+
+    val = floatx80_to_float64(fp->d, &env->fp_status);
+    cpu_stq_data_ra(env, addr, *(uint64_t *)&val, ra);
+}
+
+uint32_t HELPER(fmovem)(CPUM68KState *env, uint32_t addr, uint32_t ext)
+{
+    uintptr_t ra = GETPC();
+    int mode = (ext >> 11) & 0x3;
+    int is_load = ((ext & 0x2000) == 0);
+    uint16_t mask;
+    int incr, i;
+
+    if (m68k_feature(env, M68K_FEATURE_FPU)) {
+        incr = 12;
+    } else {
+        incr = 8;
+    }
+
+    if ((mode & 0x1) == 1) {
+        /* Dynamic register list */
+        int reg = extract32(ext, 4, 3);
+        mask = env->dregs[reg] & 0x00FF;
+    } else {
+        /* Static register list */
+        mask = ext & 0x00FF;
+    }
+
+    if (!is_load && (mode & 2) == 0) {
+        /* predecrement addressing mode
+         * only available to store register to memory
+         */
+        for (i = 7; i >= 0; i--, mask <<= 1) {
+            if (mask & 0x80) {
+                if (incr == 8) {
+                    cpu_st_float64_ra(env, addr, &env->fregs[i], ra);
+                } else {
+                    cpu_st_floatx80_ra(env, addr, &env->fregs[i], ra);
+                }
+                if ((mask & 0xff) != 0x80) {
+                    addr -= incr;
+                }
+            }
+        }
+        return addr;
+    }
+    /* postincrement addressing mode */
+    for (i = 0; i < 8; i++, mask <<= 1) {
+        if (mask & 0x80) {
+            if (is_load) {
+                if (incr == 8) {
+                    cpu_ld_float64_ra(env, &env->fregs[i], addr, ra);
+                } else {
+                    cpu_ld_floatx80_ra(env, &env->fregs[i], addr, ra);
+                }
+            } else {
+                if (incr == 8) {
+                    cpu_st_float64_ra(env, addr, &env->fregs[i], ra);
+                } else {
+                    cpu_st_floatx80_ra(env, addr, &env->fregs[i], ra);
+                }
+            }
+            addr += incr;
+        }
+    }
+
+    return addr;
+}
diff --git a/target/m68k/helper.h b/target/m68k/helper.h
index b396899..eb3d243 100644
--- a/target/m68k/helper.h
+++ b/target/m68k/helper.h
@@ -54,6 +54,7 @@ DEF_HELPER_FLAGS_3(fcmp, TCG_CALL_NO_RWG, void, env, fp, fp)
 DEF_HELPER_FLAGS_2(set_fpcr, TCG_CALL_NO_RWG, void, env, i32)
 DEF_HELPER_FLAGS_2(ftst, TCG_CALL_NO_RWG, void, env, fp)
 DEF_HELPER_3(fconst, void, env, fp, i32)
+DEF_HELPER_3(fmovem, i32, env, i32, i32)
 
 DEF_HELPER_3(mac_move, void, env, i32, i32)
 DEF_HELPER_3(macmulf, i64, env, i32, i32)
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index 3a1bdc1..5061619 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -4505,6 +4505,32 @@ static void gen_op_fmove_fcr(CPUM68KState *env, DisasContext *s,
     tcg_temp_free_i32(addr);
 }
 
+static void gen_op_fmovem(CPUM68KState *env, DisasContext *s,
+                          uint32_t insn, uint32_t ext)
+{
+    int opsize;
+    TCGv addr, tmp;
+
+    if (m68k_feature(s->env, M68K_FEATURE_FPU)) {
+        opsize = OS_EXTENDED;
+    } else {
+        opsize = OS_DOUBLE;  /* FIXME */
+    }
+
+    addr = gen_lea(env, s, insn, opsize);
+    if (IS_NULL_QREG(addr)) {
+        gen_addr_fault(s);
+        return;
+    }
+
+    tmp = tcg_const_i32(ext);
+    gen_helper_fmovem(tmp, cpu_env, addr, tmp);
+    if ((insn & 070) == 030 || (insn & 070) == 040) {
+        tcg_gen_mov_i32(AREG(insn, 0), tmp);
+    }
+    tcg_temp_free(tmp);
+}
+
 /* ??? FP exceptions are not implemented.  Most exceptions are deferred until
    immediately before the next FP instruction is executed.  */
 DISAS_INSN(fpu)
@@ -4512,7 +4538,6 @@ DISAS_INSN(fpu)
     uint16_t ext;
     uint8_t rom_offset;
     int opmode;
-    TCGv tmp32;
     int opsize;
     TCGv_ptr cpu_src, cpu_dest;
 
@@ -4548,36 +4573,10 @@ DISAS_INSN(fpu)
         return;
     case 6: /* fmovem */
     case 7:
-        {
-            TCGv addr;
-            TCGv_ptr fp;
-            uint16_t mask;
-            int i;
-            if ((ext & 0x1f00) != 0x1000 || (ext & 0xff) == 0)
-                goto undef;
-            tmp32 = gen_lea(env, s, insn, OS_LONG);
-            if (IS_NULL_QREG(tmp32)) {
-                gen_addr_fault(s);
-                return;
-            }
-            addr = tcg_temp_new_i32();
-            tcg_gen_mov_i32(addr, tmp32);
-            mask = 0x80;
-            fp = tcg_temp_new_ptr();
-            for (i = 0; i < 8; i++) {
-                if (ext & mask) {
-                    tcg_gen_addi_ptr(fp, cpu_env,
-                                     offsetof(CPUM68KState, fregs[i]));
-                    gen_ldst_fp(s, OS_DOUBLE, addr, fp,
-                                (ext & (1 << 13)) ?  EA_STORE : EA_LOADS);
-                    if (ext & (mask - 1))
-                        tcg_gen_addi_i32(addr, addr, 8);
-                }
-                mask >>= 1;
-            }
-            tcg_temp_free_i32(addr);
-            tcg_temp_free_ptr(fp);
+        if ((ext & 0x1000) == 0 && !m68k_feature(s->env, M68K_FEATURE_FPU)) {
+            goto undef;
         }
+        gen_op_fmovem(env, s, insn, ext);
         return;
     }
     if (ext & (1 << 14)) {
-- 
2.9.4

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH 3/7] target/m68k: add fsglmul and fsgldiv
  2017-06-25 19:21 ` [Qemu-devel] [PATCH 3/7] target/m68k: add fsglmul and fsgldiv Laurent Vivier
@ 2017-06-25 19:44   ` Philippe Mathieu-Daudé
  2017-06-26  8:05     ` Laurent Vivier
  0 siblings, 1 reply; 18+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-06-25 19:44 UTC (permalink / raw)
  To: Laurent Vivier, qemu-devel; +Cc: Aurelien Jarno, Richard Henderson

Hi Laurent,

On 06/25/2017 04:21 PM, Laurent Vivier wrote:
> fsglmul and fsgldiv truncate data to single precision before computing
> results.
> 
> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
> ---
>   target/m68k/fpu_helper.c | 22 ++++++++++++++++++++++
>   target/m68k/helper.h     |  2 ++
>   target/m68k/translate.c  |  6 ++++++
>   3 files changed, 30 insertions(+)
> 
> diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
> index 912c0b7..0d83925 100644
> --- a/target/m68k/fpu_helper.c
> +++ b/target/m68k/fpu_helper.c
> @@ -183,11 +183,33 @@ void HELPER(fmul)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
>       res->d = floatx80_mul(val0->d, val1->d, &env->fp_status);
>   }
>   
> +void HELPER(fsglmul)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
> +{
> +    float32 a, b, c;
> +
> +    a = floatx80_to_float32(val0->d, &env->fp_status);
> +    b = floatx80_to_float32(val1->d, &env->fp_status);
> +    c = float32_mul(a, b, &env->fp_status);

Why not use floatx80_mul() directly?

> +
> +    res->d = float32_to_floatx80(c, &env->fp_status);
> +}
> +
>   void HELPER(fdiv)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
>   {
>       res->d = floatx80_div(val1->d, val0->d, &env->fp_status);
>   }
>   
> +void HELPER(fsgldiv)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
> +{
> +    float32 a, b, c;
> +
> +    a = floatx80_to_float32(val1->d, &env->fp_status);
> +    b = floatx80_to_float32(val0->d, &env->fp_status);
> +    c = float32_div(a, b, &env->fp_status);

floatx80_div()?

> +
> +    res->d = float32_to_floatx80(c, &env->fp_status);
> +}
> +
>   static int float_comp_to_cc(int float_compare)
>   {
>       switch (float_compare) {
> diff --git a/target/m68k/helper.h b/target/m68k/helper.h
> index d6e80e4..5a006de 100644
> --- a/target/m68k/helper.h
> +++ b/target/m68k/helper.h
> @@ -31,7 +31,9 @@ DEF_HELPER_3(fchs, void, env, fp, fp)
>   DEF_HELPER_4(fadd, void, env, fp, fp, fp)
>   DEF_HELPER_4(fsub, void, env, fp, fp, fp)
>   DEF_HELPER_4(fmul, void, env, fp, fp, fp)
> +DEF_HELPER_4(fsglmul, void, env, fp, fp, fp)
>   DEF_HELPER_4(fdiv, void, env, fp, fp, fp)
> +DEF_HELPER_4(fsgldiv, void, env, fp, fp, fp)
>   DEF_HELPER_FLAGS_3(fcmp, TCG_CALL_NO_RWG, void, env, fp, fp)
>   DEF_HELPER_FLAGS_2(set_fpcr, TCG_CALL_NO_RWG, void, env, i32)
>   DEF_HELPER_FLAGS_2(ftst, TCG_CALL_NO_RWG, void, env, fp)
> diff --git a/target/m68k/translate.c b/target/m68k/translate.c
> index a54da87..a50bf5f 100644
> --- a/target/m68k/translate.c
> +++ b/target/m68k/translate.c
> @@ -4622,6 +4622,12 @@ DISAS_INSN(fpu)
>       case 0x23: case 0x63: case 0x67: /* fmul */
>           gen_helper_fmul(cpu_env, cpu_dest, cpu_src, cpu_dest);
>           break;
> +    case 0x24: /* fsgldiv */
> +        gen_helper_fsgldiv(cpu_env, cpu_dest, cpu_src, cpu_dest);
> +        break;
> +    case 0x27: /* fsglmul */
> +        gen_helper_fsglmul(cpu_env, cpu_dest, cpu_src, cpu_dest);
> +        break;
>       case 0x28: case 0x68: case 0x6c: /* fsub */
>           gen_helper_fsub(cpu_env, cpu_dest, cpu_src, cpu_dest);
>           break;
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH 1/7] target/m68k: add fscc.
  2017-06-25 19:21 ` [Qemu-devel] [PATCH 1/7] target/m68k: add fscc Laurent Vivier
@ 2017-06-25 20:42   ` Richard Henderson
  0 siblings, 0 replies; 18+ messages in thread
From: Richard Henderson @ 2017-06-25 20:42 UTC (permalink / raw)
  To: Laurent Vivier, qemu-devel; +Cc: Aurelien Jarno

On 06/25/2017 12:21 PM, Laurent Vivier wrote:
> +    c->g1 = 0;
> +    c->v2 = tcg_const_i32(0);
> +    c->g2 = 1;
> +    /* TODO: Raise BSUN exception.  */
>       fpsr = tcg_temp_new();
>       gen_load_fcr(s, fpsr, M68K_FPSR);
> -    l1 = gen_new_label();
> -    /* TODO: Raise BSUN exception.  */
> -    /* Jump to l1 if condition is true.  */
> -    switch (insn & 0x3f)  {
> +    switch (cond) {
>       case 0:  /* False */
>       case 16: /* Signaling False */
> +        c->v1 = c->v2;
> +        c->tcond = TCG_COND_NEVER;
>           break;
>       case 1:  /* EQual Z */
>       case 17: /* Signaling EQual Z */
> -        tmp = tcg_temp_new();
> -        tcg_gen_andi_i32(tmp, fpsr, FPSR_CC_Z);
> -        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
> +        c->v1 = tcg_temp_new();
> +        c->g1 = 1;

g[12] means "global", i.e. don't free the temp in free_cond.
Which is not true of any of the temps that you allocate here.


r~

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH 3/7] target/m68k: add fsglmul and fsgldiv
  2017-06-25 19:44   ` Philippe Mathieu-Daudé
@ 2017-06-26  8:05     ` Laurent Vivier
  2017-06-26 13:34       ` Richard Henderson
  0 siblings, 1 reply; 18+ messages in thread
From: Laurent Vivier @ 2017-06-26  8:05 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel; +Cc: Aurelien Jarno, Richard Henderson

Le 25/06/2017 à 21:44, Philippe Mathieu-Daudé a écrit :
> Hi Laurent,
> 
> On 06/25/2017 04:21 PM, Laurent Vivier wrote:
>> fsglmul and fsgldiv truncate data to single precision before computing
>> results.
>>
>> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
>> ---
>>   target/m68k/fpu_helper.c | 22 ++++++++++++++++++++++
>>   target/m68k/helper.h     |  2 ++
>>   target/m68k/translate.c  |  6 ++++++
>>   3 files changed, 30 insertions(+)
>>
>> diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
>> index 912c0b7..0d83925 100644
>> --- a/target/m68k/fpu_helper.c
>> +++ b/target/m68k/fpu_helper.c
>> @@ -183,11 +183,33 @@ void HELPER(fmul)(CPUM68KState *env, FPReg *res,
>> FPReg *val0, FPReg *val1)
>>       res->d = floatx80_mul(val0->d, val1->d, &env->fp_status);
>>   }
>>   +void HELPER(fsglmul)(CPUM68KState *env, FPReg *res, FPReg *val0,
>> FPReg *val1)
>> +{
>> +    float32 a, b, c;
>> +
>> +    a = floatx80_to_float32(val0->d, &env->fp_status);
>> +    b = floatx80_to_float32(val1->d, &env->fp_status);
>> +    c = float32_mul(a, b, &env->fp_status);
> 
> Why not use floatx80_mul() directly?
> 
>> +
>> +    res->d = float32_to_floatx80(c, &env->fp_status);
>> +}
>> +
>>   void HELPER(fdiv)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg
>> *val1)
>>   {
>>       res->d = floatx80_div(val1->d, val0->d, &env->fp_status);
>>   }
>>   +void HELPER(fsgldiv)(CPUM68KState *env, FPReg *res, FPReg *val0,
>> FPReg *val1)
>> +{
>> +    float32 a, b, c;
>> +
>> +    a = floatx80_to_float32(val1->d, &env->fp_status);
>> +    b = floatx80_to_float32(val0->d, &env->fp_status);
>> +    c = float32_div(a, b, &env->fp_status);
> 
> floatx80_div()?
> 

Just to follow the spec of the instruction:

"if either operand requires more than 24 bits of mantissa to be
accurately represented, the extraneous mantissa bits are truncated prior
to the multiplication;"

Do you think I should keep them in floatx80 and use the floatx80_round()
(I introduce latter in the series) to reduce the precision prior the
floatx80_mul()?

Thanks,
Laurent

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH 3/7] target/m68k: add fsglmul and fsgldiv
  2017-06-26  8:05     ` Laurent Vivier
@ 2017-06-26 13:34       ` Richard Henderson
  0 siblings, 0 replies; 18+ messages in thread
From: Richard Henderson @ 2017-06-26 13:34 UTC (permalink / raw)
  To: Laurent Vivier, Philippe Mathieu-Daudé, qemu-devel; +Cc: Aurelien Jarno

On 06/26/2017 01:05 AM, Laurent Vivier wrote:
>> floatx80_div()?
>>
> 
> Just to follow the spec of the instruction:
> 
> "if either operand requires more than 24 bits of mantissa to be
> accurately represented, the extraneous mantissa bits are truncated prior
> to the multiplication;"
> 
> Do you think I should keep them in floatx80 and use the floatx80_round()
> (I introduce latter in the series) to reduce the precision prior the
> floatx80_mul()?

Actually, yes.  The spec explicitly says that the exponent will be in extended 
precision.


r~

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH 2/7] target/m68k: add fmovecr
  2017-06-25 19:21 ` [Qemu-devel] [PATCH 2/7] target/m68k: add fmovecr Laurent Vivier
@ 2017-06-26 18:15   ` Richard Henderson
  0 siblings, 0 replies; 18+ messages in thread
From: Richard Henderson @ 2017-06-26 18:15 UTC (permalink / raw)
  To: Laurent Vivier, qemu-devel; +Cc: Aurelien Jarno

On 06/25/2017 12:21 PM, Laurent Vivier wrote:
> fmovecr moves a floating point constant from the
> FPU ROM to a floating point register.
> 
> Signed-off-by: Laurent Vivier<laurent@vivier.eu>
> ---
>   target/m68k/fpu_helper.c | 30 ++++++++++++++++++++++++++++++
>   target/m68k/helper.h     |  1 +
>   target/m68k/translate.c  | 13 ++++++++++++-
>   3 files changed, 43 insertions(+), 1 deletion(-)

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH 4/7] target/m68k: add explicit single and double precision operations
  2017-06-25 19:21 ` [Qemu-devel] [PATCH 4/7] target/m68k: add explicit single and double precision operations Laurent Vivier
@ 2017-06-26 18:26   ` Richard Henderson
  0 siblings, 0 replies; 18+ messages in thread
From: Richard Henderson @ 2017-06-26 18:26 UTC (permalink / raw)
  To: Laurent Vivier, qemu-devel; +Cc: Aurelien Jarno

On 06/25/2017 12:21 PM, Laurent Vivier wrote:
> Add fssqrt, fdsqrt, fsadd, fdadd, fssub, fdsub, fsmul, fdmul,
> fsdiv, fddiv.
> 
> The precision is managed using set_floatx80_rounding_precision().
> 
> Signed-off-by: Laurent Vivier<laurent@vivier.eu>
> ---
>   target/m68k/fpu_helper.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++
>   target/m68k/helper.h     | 10 ++++++
>   target/m68k/translate.c  | 40 +++++++++++++++++++++---
>   3 files changed, 125 insertions(+), 5 deletions(-)

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH 5/7] softfloat: define floatx80_round()
  2017-06-25 19:21 ` [Qemu-devel] [PATCH 5/7] softfloat: define floatx80_round() Laurent Vivier
@ 2017-06-26 18:29   ` Richard Henderson
  2017-06-26 19:07   ` Richard Henderson
  1 sibling, 0 replies; 18+ messages in thread
From: Richard Henderson @ 2017-06-26 18:29 UTC (permalink / raw)
  To: Laurent Vivier, qemu-devel; +Cc: Aurelien Jarno

On 06/25/2017 12:21 PM, Laurent Vivier wrote:
> Add a function to round a floatx80 to the defined precision
> (floatx80_rounding_precision)
> 
> Signed-off-by: Laurent Vivier<laurent@vivier.eu>
> ---
>   fpu/softfloat.c         | 15 +++++++++++++++
>   include/fpu/softfloat.h |  1 +
>   2 files changed, 16 insertions(+)

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH 6/7] target/m68k: add explicit single and double precision operations (part 2)
  2017-06-25 19:21 ` [Qemu-devel] [PATCH 6/7] target/m68k: add explicit single and double precision operations (part 2) Laurent Vivier
@ 2017-06-26 18:30   ` Richard Henderson
  0 siblings, 0 replies; 18+ messages in thread
From: Richard Henderson @ 2017-06-26 18:30 UTC (permalink / raw)
  To: Laurent Vivier, qemu-devel; +Cc: Aurelien Jarno

On 06/25/2017 12:21 PM, Laurent Vivier wrote:
> Add fsabs, fdabs, fsneg, fdneg, fsmove and fdmove.
> 
> The value is converted using the new floatx80_round() function.
> 
> Signed-off-by: Laurent Vivier<laurent@vivier.eu>
> ---
>   target/m68k/fpu_helper.c | 48 +++++++++++++++++++++++++++++++++++++++++++++---
>   target/m68k/helper.h     |  8 +++++++-
>   target/m68k/translate.c  | 26 ++++++++++++++++++++++----
>   3 files changed, 74 insertions(+), 8 deletions(-)

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH 7/7] target/m68k: add fmovem
  2017-06-25 19:21 ` [Qemu-devel] [PATCH 7/7] target/m68k: add fmovem Laurent Vivier
@ 2017-06-26 18:40   ` Richard Henderson
  0 siblings, 0 replies; 18+ messages in thread
From: Richard Henderson @ 2017-06-26 18:40 UTC (permalink / raw)
  To: Laurent Vivier, qemu-devel; +Cc: Aurelien Jarno

On 06/25/2017 12:21 PM, Laurent Vivier wrote:
> +uint32_t HELPER(fmovem)(CPUM68KState *env, uint32_t addr, uint32_t ext)
> +{
> +    uintptr_t ra = GETPC();
> +    int mode = (ext >> 11) & 0x3;
> +    int is_load = ((ext & 0x2000) == 0);
> +    uint16_t mask;
> +    int incr, i;
> +
> +    if (m68k_feature(env, M68K_FEATURE_FPU)) {
> +        incr = 12;
> +    } else {
> +        incr = 8;
> +    }
> +
> +    if ((mode & 0x1) == 1) {
> +        /* Dynamic register list */
> +        int reg = extract32(ext, 4, 3);
> +        mask = env->dregs[reg] & 0x00FF;
> +    } else {
> +        /* Static register list */
> +        mask = ext & 0x00FF;
> +    }
> +
> +    if (!is_load && (mode & 2) == 0) {

There's too much decoding being done in the helper.

I think it would be better to split this into 6 helpers:

   fmovem{d,x}_st_predec
   fmovem{d,x}_st_postdec
   fmovem{d,x}_ld_postdec

It should be easy to share code for these via inline functions.

Pass in the mask as an argument.  This will either be a constant loaded via 
tcg_const_i32 or the zero-extended contents of the register.


r~

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH 5/7] softfloat: define floatx80_round()
  2017-06-25 19:21 ` [Qemu-devel] [PATCH 5/7] softfloat: define floatx80_round() Laurent Vivier
  2017-06-26 18:29   ` Richard Henderson
@ 2017-06-26 19:07   ` Richard Henderson
  1 sibling, 0 replies; 18+ messages in thread
From: Richard Henderson @ 2017-06-26 19:07 UTC (permalink / raw)
  To: Laurent Vivier, qemu-devel; +Cc: Aurelien Jarno

On 06/25/2017 12:21 PM, Laurent Vivier wrote:
> Add a function to round a floatx80 to the defined precision
> (floatx80_rounding_precision)
> 
> Signed-off-by: Laurent Vivier<laurent@vivier.eu>
> ---
>   fpu/softfloat.c         | 15 +++++++++++++++
>   include/fpu/softfloat.h |  1 +
>   2 files changed, 16 insertions(+)

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2017-06-26 19:07 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-06-25 19:21 [Qemu-devel] [PATCH 0/7] target/m68k: implement 680x0 FPU (part 2) Laurent Vivier
2017-06-25 19:21 ` [Qemu-devel] [PATCH 1/7] target/m68k: add fscc Laurent Vivier
2017-06-25 20:42   ` Richard Henderson
2017-06-25 19:21 ` [Qemu-devel] [PATCH 2/7] target/m68k: add fmovecr Laurent Vivier
2017-06-26 18:15   ` Richard Henderson
2017-06-25 19:21 ` [Qemu-devel] [PATCH 3/7] target/m68k: add fsglmul and fsgldiv Laurent Vivier
2017-06-25 19:44   ` Philippe Mathieu-Daudé
2017-06-26  8:05     ` Laurent Vivier
2017-06-26 13:34       ` Richard Henderson
2017-06-25 19:21 ` [Qemu-devel] [PATCH 4/7] target/m68k: add explicit single and double precision operations Laurent Vivier
2017-06-26 18:26   ` Richard Henderson
2017-06-25 19:21 ` [Qemu-devel] [PATCH 5/7] softfloat: define floatx80_round() Laurent Vivier
2017-06-26 18:29   ` Richard Henderson
2017-06-26 19:07   ` Richard Henderson
2017-06-25 19:21 ` [Qemu-devel] [PATCH 6/7] target/m68k: add explicit single and double precision operations (part 2) Laurent Vivier
2017-06-26 18:30   ` Richard Henderson
2017-06-25 19:21 ` [Qemu-devel] [PATCH 7/7] target/m68k: add fmovem Laurent Vivier
2017-06-26 18:40   ` Richard Henderson

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).