143 lines
4.9 KiB
C
143 lines
4.9 KiB
C
|
/*
|
||
|
* MIPS VR5432 emulation helpers
|
||
|
*
|
||
|
* Copyright (c) 2004-2005 Jocelyn Mayer
|
||
|
*
|
||
|
* 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.1 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, see <http://www.gnu.org/licenses/>.
|
||
|
*
|
||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||
|
*/
|
||
|
|
||
|
#include "qemu/osdep.h"
|
||
|
#include "cpu.h"
|
||
|
#include "exec/helper-proto.h"
|
||
|
|
||
|
/* 64 bits arithmetic for 32 bits hosts */
|
||
|
static inline uint64_t get_HILO(CPUMIPSState *env)
|
||
|
{
|
||
|
return ((uint64_t)(env->active_tc.HI[0]) << 32) |
|
||
|
(uint32_t)env->active_tc.LO[0];
|
||
|
}
|
||
|
|
||
|
static inline target_ulong set_HIT0_LO(CPUMIPSState *env, uint64_t HILO)
|
||
|
{
|
||
|
env->active_tc.LO[0] = (int32_t)(HILO & 0xFFFFFFFF);
|
||
|
return env->active_tc.HI[0] = (int32_t)(HILO >> 32);
|
||
|
}
|
||
|
|
||
|
static inline target_ulong set_HI_LOT0(CPUMIPSState *env, uint64_t HILO)
|
||
|
{
|
||
|
target_ulong tmp = env->active_tc.LO[0] = (int32_t)(HILO & 0xFFFFFFFF);
|
||
|
env->active_tc.HI[0] = (int32_t)(HILO >> 32);
|
||
|
return tmp;
|
||
|
}
|
||
|
|
||
|
/* Multiplication variants of the vr54xx. */
|
||
|
target_ulong helper_muls(CPUMIPSState *env, target_ulong arg1,
|
||
|
target_ulong arg2)
|
||
|
{
|
||
|
return set_HI_LOT0(env, 0 - ((int64_t)(int32_t)arg1 *
|
||
|
(int64_t)(int32_t)arg2));
|
||
|
}
|
||
|
|
||
|
target_ulong helper_mulsu(CPUMIPSState *env, target_ulong arg1,
|
||
|
target_ulong arg2)
|
||
|
{
|
||
|
return set_HI_LOT0(env, 0 - (uint64_t)(uint32_t)arg1 *
|
||
|
(uint64_t)(uint32_t)arg2);
|
||
|
}
|
||
|
|
||
|
target_ulong helper_macc(CPUMIPSState *env, target_ulong arg1,
|
||
|
target_ulong arg2)
|
||
|
{
|
||
|
return set_HI_LOT0(env, (int64_t)get_HILO(env) + (int64_t)(int32_t)arg1 *
|
||
|
(int64_t)(int32_t)arg2);
|
||
|
}
|
||
|
|
||
|
target_ulong helper_macchi(CPUMIPSState *env, target_ulong arg1,
|
||
|
target_ulong arg2)
|
||
|
{
|
||
|
return set_HIT0_LO(env, (int64_t)get_HILO(env) + (int64_t)(int32_t)arg1 *
|
||
|
(int64_t)(int32_t)arg2);
|
||
|
}
|
||
|
|
||
|
target_ulong helper_maccu(CPUMIPSState *env, target_ulong arg1,
|
||
|
target_ulong arg2)
|
||
|
{
|
||
|
return set_HI_LOT0(env, (uint64_t)get_HILO(env) + (uint64_t)(uint32_t)arg1 *
|
||
|
(uint64_t)(uint32_t)arg2);
|
||
|
}
|
||
|
|
||
|
target_ulong helper_macchiu(CPUMIPSState *env, target_ulong arg1,
|
||
|
target_ulong arg2)
|
||
|
{
|
||
|
return set_HIT0_LO(env, (uint64_t)get_HILO(env) + (uint64_t)(uint32_t)arg1 *
|
||
|
(uint64_t)(uint32_t)arg2);
|
||
|
}
|
||
|
|
||
|
target_ulong helper_msac(CPUMIPSState *env, target_ulong arg1,
|
||
|
target_ulong arg2)
|
||
|
{
|
||
|
return set_HI_LOT0(env, (int64_t)get_HILO(env) - (int64_t)(int32_t)arg1 *
|
||
|
(int64_t)(int32_t)arg2);
|
||
|
}
|
||
|
|
||
|
target_ulong helper_msachi(CPUMIPSState *env, target_ulong arg1,
|
||
|
target_ulong arg2)
|
||
|
{
|
||
|
return set_HIT0_LO(env, (int64_t)get_HILO(env) - (int64_t)(int32_t)arg1 *
|
||
|
(int64_t)(int32_t)arg2);
|
||
|
}
|
||
|
|
||
|
target_ulong helper_msacu(CPUMIPSState *env, target_ulong arg1,
|
||
|
target_ulong arg2)
|
||
|
{
|
||
|
return set_HI_LOT0(env, (uint64_t)get_HILO(env) - (uint64_t)(uint32_t)arg1 *
|
||
|
(uint64_t)(uint32_t)arg2);
|
||
|
}
|
||
|
|
||
|
target_ulong helper_msachiu(CPUMIPSState *env, target_ulong arg1,
|
||
|
target_ulong arg2)
|
||
|
{
|
||
|
return set_HIT0_LO(env, (uint64_t)get_HILO(env) - (uint64_t)(uint32_t)arg1 *
|
||
|
(uint64_t)(uint32_t)arg2);
|
||
|
}
|
||
|
|
||
|
target_ulong helper_mulhi(CPUMIPSState *env, target_ulong arg1,
|
||
|
target_ulong arg2)
|
||
|
{
|
||
|
return set_HIT0_LO(env, (int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2);
|
||
|
}
|
||
|
|
||
|
target_ulong helper_mulhiu(CPUMIPSState *env, target_ulong arg1,
|
||
|
target_ulong arg2)
|
||
|
{
|
||
|
return set_HIT0_LO(env, (uint64_t)(uint32_t)arg1 *
|
||
|
(uint64_t)(uint32_t)arg2);
|
||
|
}
|
||
|
|
||
|
target_ulong helper_mulshi(CPUMIPSState *env, target_ulong arg1,
|
||
|
target_ulong arg2)
|
||
|
{
|
||
|
return set_HIT0_LO(env, 0 - (int64_t)(int32_t)arg1 *
|
||
|
(int64_t)(int32_t)arg2);
|
||
|
}
|
||
|
|
||
|
target_ulong helper_mulshiu(CPUMIPSState *env, target_ulong arg1,
|
||
|
target_ulong arg2)
|
||
|
{
|
||
|
return set_HIT0_LO(env, 0 - (uint64_t)(uint32_t)arg1 *
|
||
|
(uint64_t)(uint32_t)arg2);
|
||
|
}
|