From patchwork Tue Feb 7 00:59:23 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Vivier X-Patchwork-Id: 724833 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 3vHR4d3YHCz9s2s for ; Tue, 7 Feb 2017 12:06:41 +1100 (AEDT) Received: from localhost ([::1]:51351 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cauEx-0001Mw-0s for incoming@patchwork.ozlabs.org; Mon, 06 Feb 2017 20:06:39 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33084) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cau95-0005E3-Rb for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:37 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cau90-0006BT-Vc for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:35 -0500 Received: from mout.kundenserver.de ([212.227.126.134]:52800) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cau90-0006As-JQ for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:30 -0500 Received: from localhost.localdomain ([78.238.229.36]) by mrelayeu.kundenserver.de (mreue004 [212.227.15.167]) with ESMTPSA (Nemesis) id 0MP3ch-1cXrad0bxv-006QeC; Tue, 07 Feb 2017 01:59:40 +0100 From: Laurent Vivier To: qemu-devel@nongnu.org Date: Tue, 7 Feb 2017 01:59:23 +0100 Message-Id: <20170207005930.28327-10-laurent@vivier.eu> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170207005930.28327-1-laurent@vivier.eu> References: <20170207005930.28327-1-laurent@vivier.eu> X-Provags-ID: V03:K0:t4bxdVULYW+vO4ebKxxwNp78eoxJHdJu/H5glUwrvRCH4GFyf/C w5zpoXX49jOX/8Ul+IhBEeMPYrQUIsnSMpycUGX2WRYjq9zyKpTaea64HOv/of6oU83wUZ2 Ob9cp0ibIadRdzNCdoN3/yvSdEli7caZWHPFtIfuXyvcC7xNKla0lR/AukrPj8dH9F/Ys2X uQ5r8UIXHCjvFB4lfUOow== X-UI-Out-Filterresults: notjunk:1; V01:K0:kpqe6iR3Cm8=:ReR3wHP65yIENOQV40YsZM C9dPnL88RLmeWaDvSEUHTcJt5DxV97bnjFHtTEL9saOobCcJ9pxzvstDSk+bgWxlmcPmvKE1n sP1LfuNwFBrXxamx0xW/9vFsKm6EkrjYZbzUsTcRiYjV3H8qG9Nx4pLHwvy4MU86ykRBWikTW 2aikSaBOx7Od/wNWqB0cnqfy7Q713SK2L0bxyLpWDHoEcjEmN/klMi4AZw1lQz0YoSzaHIIuF 80Djo2YR/IeY85v9A1vpcoe6mGQ8lKRDExPxefUyUktIBEhBsOeKN7wUvyu83fzg+OyIwl8nK K3gTlJKdbYsat501cWWq6ftU2SsiLPqtKyfOaSvu4rQ4/ZM0YTwiLM+sPsVZYE0K4FXIWmMJh wdiHVt/PtDiUr1n5hhT2378F/5uAHZD5O8pbHxPuvY8LPx5DltvBSI4aoeKMMirBQznzDZzpG hRO0vVLvwT4BjMy1r9eSGqo3sWBfNQ/aNiuCeuYvUWI7KpTQRb2mNtex5mhd0mayyF8rlyJQT Kq5Ts1XASud1bgOCs4Jnl0D5RYzyCzSMUSxu/K8cBxituJHbUEpu8zrS0UxHTq0/jb2IC8FH5 kGi9u5EM5za0MLvTXd9QU3MxWRacleymweQhonG5TeuIk3uFxhrcYNPNJQGFTOmZZihMd899t CEDMZ7IqqATkHLvvr2HsmUI1ZmGQWqOEvfZKYunVXgwadgAjWsD+iXNsRjP+k9y8d+SQ= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.126.134 Subject: [Qemu-devel] [PATCH v3 09/16] 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 1e68c41..aadfc82 100644 --- a/target/m68k/fpu_helper.c +++ b/target/m68k/fpu_helper.c @@ -421,3 +421,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 f9c64ff..ac60f1a 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)) {