From patchwork Wed Jan 18 21:05:19 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Vivier X-Patchwork-Id: 716849 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3v3fr60NCQz9sf9 for ; Thu, 19 Jan 2017 08:15:02 +1100 (AEDT) Received: from localhost ([::1]:44367 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cTxZL-0001Dd-Om for incoming@patchwork.ozlabs.org; Wed, 18 Jan 2017 16:14:59 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46421) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cTxQa-0002Pq-3e for qemu-devel@nongnu.org; Wed, 18 Jan 2017 16:05:57 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cTxQW-0006qq-0x for qemu-devel@nongnu.org; Wed, 18 Jan 2017 16:05:56 -0500 Received: from mout.kundenserver.de ([212.227.126.187]:59135) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cTxQV-0006pv-Nc for qemu-devel@nongnu.org; Wed, 18 Jan 2017 16:05:51 -0500 Received: from Quad.localdomain ([78.238.229.36]) by mrelayeu.kundenserver.de (mreue005 [212.227.15.167]) with ESMTPSA (Nemesis) id 0LqYLt-1cyKHu2GYb-00e0sD; Wed, 18 Jan 2017 22:05:27 +0100 From: Laurent Vivier To: qemu-devel@nongnu.org Date: Wed, 18 Jan 2017 22:05:19 +0100 Message-Id: <1484773521-16530-6-git-send-email-laurent@vivier.eu> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1484773521-16530-1-git-send-email-laurent@vivier.eu> References: <1484773521-16530-1-git-send-email-laurent@vivier.eu> X-Provags-ID: V03:K0:I0HkQ+4BJG8YuiLO+pw4bc8NKZd16sFvRv5++xVKFapRHVu9Nte /9gXBaXNMh8Adz9JUcYQSkltPHrdh2R9ZJVgvtc2RD8DxogAUoHgOvXlbOGsi7qK/uWMpWK FXoG6+Puk2LVBou+KGaSB7A4PgKU9ssfBn7hWsCc32bNMJ5axGfCNWIkt8B6EFUOnREYK34 ot60r+Si1aPajb5yEuNig== X-UI-Out-Filterresults: notjunk:1; V01:K0:12rdDlFEP9c=:AQnTIIPFkwWhnefg3g5Sr2 5Q/xvWpeKo005++i4qxT9jPh6d2E3nN0I5/VOZF0UY+ywSa89gRrC9A05kgpslv/UCImtYczg FU400/SJAloJArIyq1Bc9YkBwc31NlYD8OcEbQmz5x/X0XaOrLl64hvOplrsOKO4K1AfK2qpZ DgJ6ryY6J6rJ1HD5yF8wSNRfZYbzoR4B7HQEys6AZbGSdh1nfZQ3cBgYA0XfZGihGHiRctCR1 G6qxKIq6g9ZIOZE6eaUUDE6QalB/KlUl4ui0O6mL9IRCq4hWhr4+JjYOD4b+5u3QcJZ23Ig5p oJHt4rgw1bbZmQh8j32aidguuQDoWFBb7US57/PifJnfVQarISxa7K8yKxrGg2zy9SsHSe5QL 4LUmJzuU2pSEGtWtxGthqqHjWkP5sRjVu+dSTZrCahHze1pP+IFyIRRzuGuLvYnpw1yp2Yvnz g7ITbIC1RX3Pm2ibGpPMSy4NTxX7lgJMNUls/5nMgxKYLW2+xVMCxK/NwnXWn6XFwyK4Wwwlm eFnOn/gVonM/b7KaFU2MLEmOqhIl7jZR8ny1bn9Zs0rB2F9eiHhAZKHEsCYoSedZu5sFojjr4 6TQ69epgf8TK+tIsLyTIEIaznfd1nQGKlSNTMK/1W7qeVu1xRSYQcvCvM5dYUf/1XRhngTOOS IloHMxvXCtIm/V1iDJoS26pBm2c9mbkmZ/WIpb+gMSSdKLzi/aCYJ+MldGeKIIA0/TyM= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.126.187 Subject: [Qemu-devel] [PATCH 5/7] target-m68k: add fmovem X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Laurent Vivier , Aurelien Jarno , Richard Henderson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Laurent Vivier --- target/m68k/fpu_helper.c | 6 +++ target/m68k/helper.h | 1 + target/m68k/translate.c | 99 +++++++++++++++++++++++++++++++++++------------- 3 files changed, 80 insertions(+), 26 deletions(-) diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c index b308364..126535f 100644 --- a/target/m68k/fpu_helper.c +++ b/target/m68k/fpu_helper.c @@ -409,3 +409,9 @@ void HELPER(update_fpstatus)(CPUM68KState *env) set_float_exception_flags(flags, &env->fp_status); } + +void HELPER(fmovem)(CPUM68KState *env, uint32_t opsize, + uint32_t mode, uint32_t mask) +{ + fprintf(stderr, "MISSING HELPER fmovem\n"); +} diff --git a/target/m68k/helper.h b/target/m68k/helper.h index 072a6d0..58bc273 100644 --- a/target/m68k/helper.h +++ b/target/m68k/helper.h @@ -31,6 +31,7 @@ DEF_HELPER_1(cmp_FP0_FP1, void, env) DEF_HELPER_2(set_fpcr, void, env, i32) DEF_HELPER_1(tst_FP0, void, env) DEF_HELPER_1(update_fpstatus, void, env) +DEF_HELPER_4(fmovem, void, env, i32, 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 70fd680..49c0b06 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c @@ -4483,13 +4483,79 @@ 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; + uint16_t mask; + int i; + uint32_t mode; + int32_t incr; + TCGv addr, tmp; + int is_load; + + if (m68k_feature(s->env, M68K_FEATURE_FPU)) { + opsize = OS_EXTENDED; + } else { + opsize = OS_DOUBLE; /* FIXME */ + } + + mode = (ext >> 11) & 0x3; + if ((mode & 0x1) == 1) { + gen_helper_fmovem(cpu_env, tcg_const_i32(opsize), + tcg_const_i32(mode), DREG(ext, 0)); + return; + } + + tmp = gen_lea(env, s, insn, opsize); + if (IS_NULL_QREG(tmp)) { + gen_addr_fault(s); + return; + } + + addr = tcg_temp_new(); + tcg_gen_mov_i32(addr, tmp); + is_load = ((ext & 0x2000) == 0); + incr = opsize_bytes(opsize); + mask = ext & 0x00FF; + + if (!is_load && (mode & 2) == 0) { + for (i = 7; i >= 0; i--, mask <<= 1) { + if (mask & 0x80) { + gen_op_load_fpr_FP0(i); + gen_store_FP0(s, opsize, addr); + if ((mask & 0xff) != 0x80) { + tcg_gen_subi_i32(addr, addr, incr); + } + } + } + tcg_gen_mov_i32(AREG(insn, 0), addr); + } else { + for (i = 0; i < 8; i++, mask <<= 1) { + if (mask & 0x80) { + if (is_load) { + gen_load_FP0(s, opsize, addr); + gen_op_store_fpr_FP0(i); + } else { + gen_op_load_fpr_FP0(i); + gen_store_FP0(s, opsize, addr); + } + tcg_gen_addi_i32(addr, addr, incr); + } + } + if ((insn & 070) == 030) { + tcg_gen_mov_i32(AREG(insn, 0), addr); + } + } + tcg_temp_free_i32(addr); +} + /* ??? FP exceptions are not implemented. Most exceptions are deferred until immediately before the next FP instruction is executed. */ DISAS_INSN(fpu) { uint16_t ext; int opmode; - TCGv tmp32; int opsize; ext = read_im16(env, s); @@ -4514,32 +4580,13 @@ DISAS_INSN(fpu) return; case 6: /* fmovem */ case 7: - { - TCGv addr; - 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; - for (i = 0; i < 8; i++) { - if (ext & mask) { - gen_op_load_fpr_FP0(REG(i, 0)); - gen_ldst_FP0(s, OS_DOUBLE, addr, (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); + if ((ext & 0xf00) != 0 || (ext & 0xff) == 0) { + goto undef; + } + 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)) {