1 /* 2 * MIPS VR5432 emulation helpers 3 * 4 * Copyright (c) 2004-2005 Jocelyn Mayer 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 * 19 * SPDX-License-Identifier: LGPL-2.1-or-later 20 */ 21 22 #include "qemu/osdep.h" 23 #include "cpu.h" 24 #include "exec/helper-proto.h" 25 26 /* 64 bits arithmetic for 32 bits hosts */ 27 static inline uint64_t get_HILO(CPUMIPSState *env) 28 { 29 return ((uint64_t)(env->active_tc.HI[0]) << 32) | 30 (uint32_t)env->active_tc.LO[0]; 31 } 32 33 static inline target_ulong set_HIT0_LO(CPUMIPSState *env, uint64_t HILO) 34 { 35 env->active_tc.LO[0] = (int32_t)(HILO & 0xFFFFFFFF); 36 return env->active_tc.HI[0] = (int32_t)(HILO >> 32); 37 } 38 39 static inline target_ulong set_HI_LOT0(CPUMIPSState *env, uint64_t HILO) 40 { 41 target_ulong tmp = env->active_tc.LO[0] = (int32_t)(HILO & 0xFFFFFFFF); 42 env->active_tc.HI[0] = (int32_t)(HILO >> 32); 43 return tmp; 44 } 45 46 /* Multiplication variants of the vr54xx. */ 47 target_ulong helper_muls(CPUMIPSState *env, target_ulong arg1, 48 target_ulong arg2) 49 { 50 return set_HI_LOT0(env, 0 - ((int64_t)(int32_t)arg1 * 51 (int64_t)(int32_t)arg2)); 52 } 53 54 target_ulong helper_mulsu(CPUMIPSState *env, target_ulong arg1, 55 target_ulong arg2) 56 { 57 return set_HI_LOT0(env, 0 - (uint64_t)(uint32_t)arg1 * 58 (uint64_t)(uint32_t)arg2); 59 } 60 61 target_ulong helper_macc(CPUMIPSState *env, target_ulong arg1, 62 target_ulong arg2) 63 { 64 return set_HI_LOT0(env, (int64_t)get_HILO(env) + (int64_t)(int32_t)arg1 * 65 (int64_t)(int32_t)arg2); 66 } 67 68 target_ulong helper_macchi(CPUMIPSState *env, target_ulong arg1, 69 target_ulong arg2) 70 { 71 return set_HIT0_LO(env, (int64_t)get_HILO(env) + (int64_t)(int32_t)arg1 * 72 (int64_t)(int32_t)arg2); 73 } 74 75 target_ulong helper_maccu(CPUMIPSState *env, target_ulong arg1, 76 target_ulong arg2) 77 { 78 return set_HI_LOT0(env, (uint64_t)get_HILO(env) + (uint64_t)(uint32_t)arg1 * 79 (uint64_t)(uint32_t)arg2); 80 } 81 82 target_ulong helper_macchiu(CPUMIPSState *env, target_ulong arg1, 83 target_ulong arg2) 84 { 85 return set_HIT0_LO(env, (uint64_t)get_HILO(env) + (uint64_t)(uint32_t)arg1 * 86 (uint64_t)(uint32_t)arg2); 87 } 88 89 target_ulong helper_msac(CPUMIPSState *env, target_ulong arg1, 90 target_ulong arg2) 91 { 92 return set_HI_LOT0(env, (int64_t)get_HILO(env) - (int64_t)(int32_t)arg1 * 93 (int64_t)(int32_t)arg2); 94 } 95 96 target_ulong helper_msachi(CPUMIPSState *env, target_ulong arg1, 97 target_ulong arg2) 98 { 99 return set_HIT0_LO(env, (int64_t)get_HILO(env) - (int64_t)(int32_t)arg1 * 100 (int64_t)(int32_t)arg2); 101 } 102 103 target_ulong helper_msacu(CPUMIPSState *env, target_ulong arg1, 104 target_ulong arg2) 105 { 106 return set_HI_LOT0(env, (uint64_t)get_HILO(env) - (uint64_t)(uint32_t)arg1 * 107 (uint64_t)(uint32_t)arg2); 108 } 109 110 target_ulong helper_msachiu(CPUMIPSState *env, target_ulong arg1, 111 target_ulong arg2) 112 { 113 return set_HIT0_LO(env, (uint64_t)get_HILO(env) - (uint64_t)(uint32_t)arg1 * 114 (uint64_t)(uint32_t)arg2); 115 } 116 117 target_ulong helper_mulhi(CPUMIPSState *env, target_ulong arg1, 118 target_ulong arg2) 119 { 120 return set_HIT0_LO(env, (int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2); 121 } 122 123 target_ulong helper_mulhiu(CPUMIPSState *env, target_ulong arg1, 124 target_ulong arg2) 125 { 126 return set_HIT0_LO(env, (uint64_t)(uint32_t)arg1 * 127 (uint64_t)(uint32_t)arg2); 128 } 129 130 target_ulong helper_mulshi(CPUMIPSState *env, target_ulong arg1, 131 target_ulong arg2) 132 { 133 return set_HIT0_LO(env, 0 - (int64_t)(int32_t)arg1 * 134 (int64_t)(int32_t)arg2); 135 } 136 137 target_ulong helper_mulshiu(CPUMIPSState *env, target_ulong arg1, 138 target_ulong arg2) 139 { 140 return set_HIT0_LO(env, 0 - (uint64_t)(uint32_t)arg1 * 141 (uint64_t)(uint32_t)arg2); 142 } 143