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 */
get_HILO(CPUMIPSState * env)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
set_HIT0_LO(CPUMIPSState * env,uint64_t HILO)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
set_HI_LOT0(CPUMIPSState * env,uint64_t HILO)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. */
helper_muls(CPUMIPSState * env,target_ulong arg1,target_ulong arg2)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
helper_mulsu(CPUMIPSState * env,target_ulong arg1,target_ulong arg2)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
helper_macc(CPUMIPSState * env,target_ulong arg1,target_ulong arg2)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
helper_macchi(CPUMIPSState * env,target_ulong arg1,target_ulong arg2)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
helper_maccu(CPUMIPSState * env,target_ulong arg1,target_ulong arg2)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
helper_macchiu(CPUMIPSState * env,target_ulong arg1,target_ulong arg2)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
helper_msac(CPUMIPSState * env,target_ulong arg1,target_ulong arg2)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
helper_msachi(CPUMIPSState * env,target_ulong arg1,target_ulong arg2)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
helper_msacu(CPUMIPSState * env,target_ulong arg1,target_ulong arg2)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
helper_msachiu(CPUMIPSState * env,target_ulong arg1,target_ulong arg2)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
helper_mulhi(CPUMIPSState * env,target_ulong arg1,target_ulong arg2)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
helper_mulhiu(CPUMIPSState * env,target_ulong arg1,target_ulong arg2)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
helper_mulshi(CPUMIPSState * env,target_ulong arg1,target_ulong arg2)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
helper_mulshiu(CPUMIPSState * env,target_ulong arg1,target_ulong arg2)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