mirror of https://gitee.com/openkylin/qemu.git
target-mips: microMIPS ASE support
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 <froydnj@codesourcery.com> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
parent
620e48f663
commit
3c824109da
|
@ -160,6 +160,15 @@ DEF_HELPER_1(emt, tl, tl)
|
||||||
DEF_HELPER_1(dvpe, tl, tl)
|
DEF_HELPER_1(dvpe, tl, tl)
|
||||||
DEF_HELPER_1(evpe, tl, tl)
|
DEF_HELPER_1(evpe, tl, tl)
|
||||||
#endif /* !CONFIG_USER_ONLY */
|
#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_2(fork, void, tl, tl)
|
||||||
DEF_HELPER_1(yield, tl, tl)
|
DEF_HELPER_1(yield, tl, tl)
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#define ASE_DSPR2 0x00010000
|
#define ASE_DSPR2 0x00010000
|
||||||
#define ASE_MT 0x00020000
|
#define ASE_MT 0x00020000
|
||||||
#define ASE_SMARTMIPS 0x00040000
|
#define ASE_SMARTMIPS 0x00040000
|
||||||
|
#define ASE_MICROMIPS 0x00080000
|
||||||
|
|
||||||
/* Chip specific instructions. */
|
/* Chip specific instructions. */
|
||||||
#define INSN_VR54XX 0x80000000
|
#define INSN_VR54XX 0x80000000
|
||||||
|
|
|
@ -565,6 +565,142 @@ void helper_sdr(target_ulong arg1, target_ulong arg2, int mem_idx)
|
||||||
}
|
}
|
||||||
#endif /* TARGET_MIPS64 */
|
#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
|
#ifndef CONFIG_USER_ONLY
|
||||||
/* CP0 helpers */
|
/* CP0 helpers */
|
||||||
target_ulong helper_mfc0_mvpcontrol (void)
|
target_ulong helper_mfc0_mvpcontrol (void)
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue