From 92af06d216857de77bcadaf86cf9675cce9f1d3c Mon Sep 17 00:00:00 2001 From: ths Date: Fri, 20 Jun 2008 14:35:19 +0000 Subject: [PATCH] Convert vr54xx multiply instructions to TCG. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4756 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-mips/helper.h | 15 +++ target-mips/op.c | 317 +++++++----------------------------------------- target-mips/op_helper.c | 6 +- target-mips/translate.c | 28 ++--- 4 files changed, 79 insertions(+), 287 deletions(-) rewrite target-mips/op.c (73%) diff --git a/target-mips/helper.h b/target-mips/helper.h index cba9cd7ebf..617e6d4242 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -15,6 +15,21 @@ DEF_HELPER(void, do_dmult, (void)) DEF_HELPER(void, do_dmultu, (void)) #endif +DEF_HELPER(void, do_muls, (void)) +DEF_HELPER(void, do_mulsu, (void)) +DEF_HELPER(void, do_macc, (void)) +DEF_HELPER(void, do_maccu, (void)) +DEF_HELPER(void, do_msac, (void)) +DEF_HELPER(void, do_msacu, (void)) +DEF_HELPER(void, do_mulhi, (void)) +DEF_HELPER(void, do_mulhiu, (void)) +DEF_HELPER(void, do_mulshi, (void)) +DEF_HELPER(void, do_mulshiu, (void)) +DEF_HELPER(void, do_macchi, (void)) +DEF_HELPER(void, do_macchiu, (void)) +DEF_HELPER(void, do_msachi, (void)) +DEF_HELPER(void, do_msachiu, (void)) + /* CP0 helpers */ #ifndef CONFIG_USER_ONLY DEF_HELPER(void, do_mfc0_mvpcontrol, (void)) diff --git a/target-mips/op.c b/target-mips/op.c dissimilarity index 73% index 89ee9ce458..d617a076d5 100644 --- a/target-mips/op.c +++ b/target-mips/op.c @@ -1,270 +1,47 @@ -/* - * MIPS emulation micro-operations for qemu. - * - * Copyright (c) 2004-2005 Jocelyn Mayer - * Copyright (c) 2006 Marius Groeger (FPU operations) - * Copyright (c) 2007 Thiemo Seufer (64-bit FPU support) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "config.h" -#include "exec.h" -#include "host-utils.h" - -#ifndef CALL_FROM_TB0 -#define CALL_FROM_TB0(func) func() -#endif - -/* Load and store */ -#define MEMSUFFIX _raw -#include "op_mem.c" -#undef MEMSUFFIX -#if !defined(CONFIG_USER_ONLY) -#define MEMSUFFIX _user -#include "op_mem.c" -#undef MEMSUFFIX - -#define MEMSUFFIX _super -#include "op_mem.c" -#undef MEMSUFFIX - -#define MEMSUFFIX _kernel -#include "op_mem.c" -#undef MEMSUFFIX -#endif - -/* 64 bits arithmetic */ -#if TARGET_LONG_BITS > HOST_LONG_BITS -void op_madd (void) -{ - CALL_FROM_TB0(do_madd); - FORCE_RET(); -} - -void op_maddu (void) -{ - CALL_FROM_TB0(do_maddu); - FORCE_RET(); -} - -void op_msub (void) -{ - CALL_FROM_TB0(do_msub); - FORCE_RET(); -} - -void op_msubu (void) -{ - CALL_FROM_TB0(do_msubu); - FORCE_RET(); -} - -/* Multiplication variants of the vr54xx. */ -void op_muls (void) -{ - CALL_FROM_TB0(do_muls); - FORCE_RET(); -} - -void op_mulsu (void) -{ - CALL_FROM_TB0(do_mulsu); - FORCE_RET(); -} - -void op_macc (void) -{ - CALL_FROM_TB0(do_macc); - FORCE_RET(); -} - -void op_macchi (void) -{ - CALL_FROM_TB0(do_macchi); - FORCE_RET(); -} - -void op_maccu (void) -{ - CALL_FROM_TB0(do_maccu); - FORCE_RET(); -} -void op_macchiu (void) -{ - CALL_FROM_TB0(do_macchiu); - FORCE_RET(); -} - -void op_msac (void) -{ - CALL_FROM_TB0(do_msac); - FORCE_RET(); -} - -void op_msachi (void) -{ - CALL_FROM_TB0(do_msachi); - FORCE_RET(); -} - -void op_msacu (void) -{ - CALL_FROM_TB0(do_msacu); - FORCE_RET(); -} - -void op_msachiu (void) -{ - CALL_FROM_TB0(do_msachiu); - FORCE_RET(); -} - -void op_mulhi (void) -{ - CALL_FROM_TB0(do_mulhi); - FORCE_RET(); -} - -void op_mulhiu (void) -{ - CALL_FROM_TB0(do_mulhiu); - FORCE_RET(); -} - -void op_mulshi (void) -{ - CALL_FROM_TB0(do_mulshi); - FORCE_RET(); -} - -void op_mulshiu (void) -{ - CALL_FROM_TB0(do_mulshiu); - FORCE_RET(); -} - -#else /* TARGET_LONG_BITS > HOST_LONG_BITS */ - -static always_inline uint64_t get_HILO (void) -{ - return ((uint64_t)env->HI[env->current_tc][0] << 32) | - ((uint64_t)(uint32_t)env->LO[env->current_tc][0]); -} - -static always_inline void set_HILO (uint64_t HILO) -{ - env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF); - env->HI[env->current_tc][0] = (int32_t)(HILO >> 32); -} - -static always_inline void set_HIT0_LO (uint64_t HILO) -{ - env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF); - T0 = env->HI[env->current_tc][0] = (int32_t)(HILO >> 32); -} - -static always_inline void set_HI_LOT0 (uint64_t HILO) -{ - T0 = env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF); - env->HI[env->current_tc][0] = (int32_t)(HILO >> 32); -} - -/* Multiplication variants of the vr54xx. */ -void op_muls (void) -{ - set_HI_LOT0(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1)); - FORCE_RET(); -} - -void op_mulsu (void) -{ - set_HI_LOT0(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1)); - FORCE_RET(); -} - -void op_macc (void) -{ - set_HI_LOT0(get_HILO() + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1)); - FORCE_RET(); -} - -void op_macchi (void) -{ - set_HIT0_LO(get_HILO() + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1)); - FORCE_RET(); -} - -void op_maccu (void) -{ - set_HI_LOT0(get_HILO() + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1)); - FORCE_RET(); -} - -void op_macchiu (void) -{ - set_HIT0_LO(get_HILO() + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1)); - FORCE_RET(); -} - -void op_msac (void) -{ - set_HI_LOT0(get_HILO() - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1)); - FORCE_RET(); -} - -void op_msachi (void) -{ - set_HIT0_LO(get_HILO() - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1)); - FORCE_RET(); -} - -void op_msacu (void) -{ - set_HI_LOT0(get_HILO() - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1)); - FORCE_RET(); -} - -void op_msachiu (void) -{ - set_HIT0_LO(get_HILO() - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1)); - FORCE_RET(); -} - -void op_mulhi (void) -{ - set_HIT0_LO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1); - FORCE_RET(); -} - -void op_mulhiu (void) -{ - set_HIT0_LO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1); - FORCE_RET(); -} - -void op_mulshi (void) -{ - set_HIT0_LO(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1)); - FORCE_RET(); -} - -void op_mulshiu (void) -{ - set_HIT0_LO(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1)); - FORCE_RET(); -} - -#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */ +/* + * MIPS emulation micro-operations for qemu. + * + * Copyright (c) 2004-2005 Jocelyn Mayer + * Copyright (c) 2006 Marius Groeger (FPU operations) + * Copyright (c) 2007 Thiemo Seufer (64-bit FPU support) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" +#include "exec.h" +#include "host-utils.h" + +#ifndef CALL_FROM_TB0 +#define CALL_FROM_TB0(func) func() +#endif + +/* Load and store */ +#define MEMSUFFIX _raw +#include "op_mem.c" +#undef MEMSUFFIX +#if !defined(CONFIG_USER_ONLY) +#define MEMSUFFIX _user +#include "op_mem.c" +#undef MEMSUFFIX + +#define MEMSUFFIX _super +#include "op_mem.c" +#undef MEMSUFFIX + +#define MEMSUFFIX _kernel +#include "op_mem.c" +#undef MEMSUFFIX +#endif diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 696295b904..16d3023a45 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -168,10 +168,9 @@ void do_dclz (void) #endif /* TARGET_MIPS64 */ /* 64 bits arithmetic for 32 bits hosts */ -#if TARGET_LONG_BITS > HOST_LONG_BITS static always_inline uint64_t get_HILO (void) { - return (env->HI[env->current_tc][0] << 32) | (uint32_t)env->LO[env->current_tc][0]; + return ((uint64_t)(env->HI[env->current_tc][0]) << 32) | (uint32_t)env->LO[env->current_tc][0]; } static always_inline void set_HILO (uint64_t HILO) @@ -192,6 +191,7 @@ static always_inline void set_HI_LOT0 (uint64_t HILO) env->HI[env->current_tc][0] = (int32_t)(HILO >> 32); } +#if TARGET_LONG_BITS > HOST_LONG_BITS void do_madd (void) { int64_t tmp; @@ -223,6 +223,7 @@ void do_msubu (void) tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1); set_HILO(get_HILO() - tmp); } +#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */ /* Multiplication variants of the vr54xx. */ void do_muls (void) @@ -294,7 +295,6 @@ void do_mulshiu (void) { set_HIT0_LO(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1)); } -#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */ #ifdef TARGET_MIPS64 void do_dmult (void) diff --git a/target-mips/translate.c b/target-mips/translate.c index 56984147e6..d441f2bdff 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -2204,59 +2204,59 @@ static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc, switch (opc) { case OPC_VR54XX_MULS: - gen_op_muls(); + tcg_gen_helper_0_0(do_muls); opn = "muls"; break; case OPC_VR54XX_MULSU: - gen_op_mulsu(); + tcg_gen_helper_0_0(do_mulsu); opn = "mulsu"; break; case OPC_VR54XX_MACC: - gen_op_macc(); + tcg_gen_helper_0_0(do_macc); opn = "macc"; break; case OPC_VR54XX_MACCU: - gen_op_maccu(); + tcg_gen_helper_0_0(do_maccu); opn = "maccu"; break; case OPC_VR54XX_MSAC: - gen_op_msac(); + tcg_gen_helper_0_0(do_msac); opn = "msac"; break; case OPC_VR54XX_MSACU: - gen_op_msacu(); + tcg_gen_helper_0_0(do_msacu); opn = "msacu"; break; case OPC_VR54XX_MULHI: - gen_op_mulhi(); + tcg_gen_helper_0_0(do_mulhi); opn = "mulhi"; break; case OPC_VR54XX_MULHIU: - gen_op_mulhiu(); + tcg_gen_helper_0_0(do_mulhiu); opn = "mulhiu"; break; case OPC_VR54XX_MULSHI: - gen_op_mulshi(); + tcg_gen_helper_0_0(do_mulshi); opn = "mulshi"; break; case OPC_VR54XX_MULSHIU: - gen_op_mulshiu(); + tcg_gen_helper_0_0(do_mulshiu); opn = "mulshiu"; break; case OPC_VR54XX_MACCHI: - gen_op_macchi(); + tcg_gen_helper_0_0(do_macchi); opn = "macchi"; break; case OPC_VR54XX_MACCHIU: - gen_op_macchiu(); + tcg_gen_helper_0_0(do_macchiu); opn = "macchiu"; break; case OPC_VR54XX_MSACHI: - gen_op_msachi(); + tcg_gen_helper_0_0(do_msachi); opn = "msachi"; break; case OPC_VR54XX_MSACHIU: - gen_op_msachiu(); + tcg_gen_helper_0_0(do_msachiu); opn = "msachiu"; break; default: -- 2.11.4.GIT