[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH 4/8] target-mips: microMIPS ASE support
From: |
Aurelien Jarno |
Subject: |
Re: [Qemu-devel] [PATCH 4/8] target-mips: microMIPS ASE support |
Date: |
Wed, 9 Jun 2010 16:08:40 +0200 |
User-agent: |
Mutt/1.5.18 (2008-05-17) |
On Tue, Jun 08, 2010 at 01:29:59PM -0700, Nathan Froyd wrote:
> Add instruction decoding for the microMIPS ASE. All we do is decode and
> then forward to the existing gen_* routines.
>
> Signed-off-by: Nathan Froyd <address@hidden>
> ---
> target-mips/helper.h | 9 +
> target-mips/mips-defs.h | 1 +
> target-mips/op_helper.c | 136 +++
> target-mips/translate.c | 2390
> ++++++++++++++++++++++++++++++++++++++++++++++-
> 4 files changed, 2531 insertions(+), 5 deletions(-)
>
> diff --git a/target-mips/helper.h b/target-mips/helper.h
> index ab47b1a..a6ba75d 100644
> --- a/target-mips/helper.h
> +++ b/target-mips/helper.h
> @@ -160,6 +160,15 @@ DEF_HELPER_1(emt, tl, tl)
> DEF_HELPER_1(dvpe, tl, tl)
> DEF_HELPER_1(evpe, tl, tl)
> #endif /* !CONFIG_USER_ONLY */
> +
> +/* microMIPS functions */
> +DEF_HELPER_3(lwm, void, tl, tl, i32);
> +DEF_HELPER_3(swm, void, tl, tl, i32);
> +#ifdef TARGET_MIPS64
> +DEF_HELPER_3(ldm, void, tl, tl, i32);
> +DEF_HELPER_3(sdm, void, tl, tl, i32);
> +#endif
> +
> DEF_HELPER_2(fork, void, tl, tl)
> DEF_HELPER_1(yield, tl, tl)
>
> diff --git a/target-mips/mips-defs.h b/target-mips/mips-defs.h
> index c57de02..a7f4697 100644
> --- a/target-mips/mips-defs.h
> +++ b/target-mips/mips-defs.h
> @@ -38,6 +38,7 @@
> #define ASE_DSPR2 0x00010000
> #define ASE_MT 0x00020000
> #define ASE_SMARTMIPS 0x00040000
> +#define ASE_MICROMIPS 0x00080000
>
> /* Chip specific instructions. */
> #define INSN_VR54XX 0x80000000
> diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
> index 2bfdd50..56c5e59 100644
> --- a/target-mips/op_helper.c
> +++ b/target-mips/op_helper.c
> @@ -565,6 +565,142 @@ void helper_sdr(target_ulong arg1, target_ulong arg2,
> int mem_idx)
> }
> #endif /* TARGET_MIPS64 */
>
> +static const int multiple_regs[] = { 16, 17, 18, 19, 20, 21, 22, 23, 30 };
> +
> +void helper_lwm (target_ulong addr, target_ulong reglist, uint32_t mem_idx)
> +{
> + target_ulong base_reglist = reglist & 0xf;
> + target_ulong do_r31 = reglist & 0x10;
> +#ifdef CONFIG_USER_ONLY
> +#undef ldfun
> +#define ldfun ldl_raw
> +#else
> + uint32_t (*ldfun)(target_ulong);
> +
> + switch (mem_idx)
> + {
> + case 0: ldfun = ldl_kernel; break;
> + case 1: ldfun = ldl_super; break;
> + default:
> + case 2: ldfun = ldl_user; break;
> + }
> +#endif
> +
> + if (base_reglist > 0 && base_reglist <= ARRAY_SIZE (multiple_regs)) {
> + target_ulong i;
> +
> + for (i = 0; i < base_reglist; i++) {
> + env->active_tc.gpr[multiple_regs[i]] = (target_long) ldfun(addr);
> + addr += 4;
> + }
> + }
> +
> + if (do_r31) {
> + env->active_tc.gpr[31] = (target_long) ldfun(addr);
> + }
> +}
> +
> +void helper_swm (target_ulong addr, target_ulong reglist, uint32_t mem_idx)
> +{
> + target_ulong base_reglist = reglist & 0xf;
> + target_ulong do_r31 = reglist & 0x10;
> +#ifdef CONFIG_USER_ONLY
> +#undef stfun
> +#define stfun stl_raw
> +#else
> + void (*stfun)(target_ulong, uint32_t);
> +
> + switch (mem_idx)
> + {
> + case 0: stfun = stl_kernel; break;
> + case 1: stfun = stl_super; break;
> + default:
> + case 2: stfun = stl_user; break;
> + }
> +#endif
> +
> + if (base_reglist > 0 && base_reglist <= ARRAY_SIZE (multiple_regs)) {
> + target_ulong i;
> +
> + for (i = 0; i < base_reglist; i++) {
> + stfun(addr, env->active_tc.gpr[multiple_regs[i]]);
> + addr += 4;
> + }
> + }
> +
> + if (do_r31) {
> + stfun(addr, env->active_tc.gpr[31]);
> + }
> +}
> +
> +#if defined(TARGET_MIPS64)
> +void helper_ldm (target_ulong addr, target_ulong reglist, uint32_t mem_idx)
> +{
> + target_ulong base_reglist = reglist & 0xf;
> + target_ulong do_r31 = reglist & 0x10;
> +#ifdef CONFIG_USER_ONLY
> +#undef ldfun
> +#define ldfun ldq_raw
> +#else
> + uint64_t (*ldfun)(target_ulong);
> +
> + switch (mem_idx)
> + {
> + case 0: ldfun = ldq_kernel; break;
> + case 1: ldfun = ldq_super; break;
> + default:
> + case 2: ldfun = ldq_user; break;
> + }
> +#endif
> +
> + if (base_reglist > 0 && base_reglist <= ARRAY_SIZE (multiple_regs)) {
> + target_ulong i;
> +
> + for (i = 0; i < base_reglist; i++) {
> + env->active_tc.gpr[multiple_regs[i]] = ldfun(addr);
> + addr += 8;
> + }
> + }
> +
> + if (do_r31) {
> + env->active_tc.gpr[31] = ldfun(addr);
> + }
> +}
> +
> +void helper_sdm (target_ulong addr, target_ulong reglist, uint32_t mem_idx)
> +{
> + target_ulong base_reglist = reglist & 0xf;
> + target_ulong do_r31 = reglist & 0x10;
> +#ifdef CONFIG_USER_ONLY
> +#undef stfun
> +#define stfun stq_raw
> +#else
> + void (*stfun)(target_ulong, uint64_t);
> +
> + switch (mem_idx)
> + {
> + case 0: stfun = stq_kernel; break;
> + case 1: stfun = stq_super; break;
> + default:
> + case 2: stfun = stq_user; break;
> + }
> +#endif
> +
> + if (base_reglist > 0 && base_reglist <= ARRAY_SIZE (multiple_regs)) {
> + target_ulong i;
> +
> + for (i = 0; i < base_reglist; i++) {
> + stfun(addr, env->active_tc.gpr[multiple_regs[i]]);
> + addr += 8;
> + }
> + }
> +
> + if (do_r31) {
> + stfun(addr, env->active_tc.gpr[31]);
> + }
> +}
> +#endif
> +
> #ifndef CONFIG_USER_ONLY
> /* CP0 helpers */
> target_ulong helper_mfc0_mvpcontrol (void)
As the list of registers is included in the opcode, I do wonder if it
wouldn't be better to do this directly in translate.c as TCG code.
--
Aurelien Jarno GPG: 1024D/F1BCDB73
address@hidden http://www.aurel32.net
- [Qemu-devel] [PATCH 0/8] target-mips: add microMIPS ASE support, v3, Nathan Froyd, 2010/06/08
- [Qemu-devel] [PATCH 7/8] linux-user: honor low bit of entry PC for MIPS, Nathan Froyd, 2010/06/08
- [Qemu-devel] [PATCH 2/8] target-mips: refactor c{, abs}.cond.fmt insns, Nathan Froyd, 2010/06/08
- [Qemu-devel] [PATCH 8/8] hw: honor low bit in mipssim machine, Nathan Froyd, 2010/06/08
- [Qemu-devel] [PATCH 1/8] target-mips: define constants for magic numbers, Nathan Froyd, 2010/06/08
- [Qemu-devel] [PATCH 5/8] target-mips: add microMIPS CPUs, Nathan Froyd, 2010/06/08
- [Qemu-devel] [PATCH 3/8] target-mips: mips16 cleanups, Nathan Froyd, 2010/06/08
- [Qemu-devel] [PATCH 4/8] target-mips: microMIPS ASE support, Nathan Froyd, 2010/06/08
- Re: [Qemu-devel] [PATCH 4/8] target-mips: microMIPS ASE support,
Aurelien Jarno <=
- [Qemu-devel] [PATCH 6/8] target-mips: add microMIPS exception handler support, Nathan Froyd, 2010/06/08
- Re: [Qemu-devel] [PATCH 0/8] target-mips: add microMIPS ASE support, v3, Aurelien Jarno, 2010/06/09