xref: /openbmc/qemu/target/mips/tcg/ldst_helper.c (revision 08ae519ab8eb6c9abbd97156cb3678f372521501)
1a2b0a27dSPhilippe Mathieu-Daudé /*
2a2b0a27dSPhilippe Mathieu-Daudé  *  MIPS emulation load/store helpers for QEMU.
3a2b0a27dSPhilippe Mathieu-Daudé  *
4a2b0a27dSPhilippe Mathieu-Daudé  *  Copyright (c) 2004-2005 Jocelyn Mayer
5a2b0a27dSPhilippe Mathieu-Daudé  *
6a2b0a27dSPhilippe Mathieu-Daudé  * SPDX-License-Identifier: LGPL-2.1-or-later
7a2b0a27dSPhilippe Mathieu-Daudé  *
8a2b0a27dSPhilippe Mathieu-Daudé  * This library is free software; you can redistribute it and/or
9a2b0a27dSPhilippe Mathieu-Daudé  * modify it under the terms of the GNU Lesser General Public
10a2b0a27dSPhilippe Mathieu-Daudé  * License as published by the Free Software Foundation; either
11a2b0a27dSPhilippe Mathieu-Daudé  * version 2.1 of the License, or (at your option) any later version.
12a2b0a27dSPhilippe Mathieu-Daudé  *
13a2b0a27dSPhilippe Mathieu-Daudé  * This library is distributed in the hope that it will be useful,
14a2b0a27dSPhilippe Mathieu-Daudé  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15a2b0a27dSPhilippe Mathieu-Daudé  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16a2b0a27dSPhilippe Mathieu-Daudé  * Lesser General Public License for more details.
17a2b0a27dSPhilippe Mathieu-Daudé  *
18a2b0a27dSPhilippe Mathieu-Daudé  * You should have received a copy of the GNU Lesser General Public
19a2b0a27dSPhilippe Mathieu-Daudé  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
20a2b0a27dSPhilippe Mathieu-Daudé  *
21a2b0a27dSPhilippe Mathieu-Daudé  */
22a2b0a27dSPhilippe Mathieu-Daudé 
23a2b0a27dSPhilippe Mathieu-Daudé #include "qemu/osdep.h"
24a2b0a27dSPhilippe Mathieu-Daudé #include "cpu.h"
25a2b0a27dSPhilippe Mathieu-Daudé #include "exec/helper-proto.h"
26a2b0a27dSPhilippe Mathieu-Daudé #include "exec/exec-all.h"
2709b07f28SPhilippe Mathieu-Daudé #include "exec/cpu_ldst.h"
28a2b0a27dSPhilippe Mathieu-Daudé #include "exec/memop.h"
29a2b0a27dSPhilippe Mathieu-Daudé #include "internal.h"
30a2b0a27dSPhilippe Mathieu-Daudé 
31a2b0a27dSPhilippe Mathieu-Daudé #ifndef CONFIG_USER_ONLY
32a2b0a27dSPhilippe Mathieu-Daudé 
33a2b0a27dSPhilippe Mathieu-Daudé #define HELPER_LD_ATOMIC(name, insn, almask, do_cast)                         \
34a2b0a27dSPhilippe Mathieu-Daudé target_ulong helper_##name(CPUMIPSState *env, target_ulong arg, int mem_idx)  \
35a2b0a27dSPhilippe Mathieu-Daudé {                                                                             \
36a2b0a27dSPhilippe Mathieu-Daudé     if (arg & almask) {                                                       \
37a2b0a27dSPhilippe Mathieu-Daudé         if (!(env->hflags & MIPS_HFLAG_DM)) {                                 \
38a2b0a27dSPhilippe Mathieu-Daudé             env->CP0_BadVAddr = arg;                                          \
39a2b0a27dSPhilippe Mathieu-Daudé         }                                                                     \
40a2b0a27dSPhilippe Mathieu-Daudé         do_raise_exception(env, EXCP_AdEL, GETPC());                          \
41a2b0a27dSPhilippe Mathieu-Daudé     }                                                                         \
42a2b0a27dSPhilippe Mathieu-Daudé     env->CP0_LLAddr = cpu_mips_translate_address(env, arg, MMU_DATA_LOAD,     \
43a2b0a27dSPhilippe Mathieu-Daudé                                                  GETPC());                    \
44a2b0a27dSPhilippe Mathieu-Daudé     env->lladdr = arg;                                                        \
45a2b0a27dSPhilippe Mathieu-Daudé     env->llval = do_cast cpu_##insn##_mmuidx_ra(env, arg, mem_idx, GETPC());  \
46a2b0a27dSPhilippe Mathieu-Daudé     return env->llval;                                                        \
47a2b0a27dSPhilippe Mathieu-Daudé }
48a2b0a27dSPhilippe Mathieu-Daudé HELPER_LD_ATOMIC(ll, ldl, 0x3, (target_long)(int32_t))
49a2b0a27dSPhilippe Mathieu-Daudé #ifdef TARGET_MIPS64
50a2b0a27dSPhilippe Mathieu-Daudé HELPER_LD_ATOMIC(lld, ldq, 0x7, (target_ulong))
51a2b0a27dSPhilippe Mathieu-Daudé #endif
52a2b0a27dSPhilippe Mathieu-Daudé #undef HELPER_LD_ATOMIC
53a2b0a27dSPhilippe Mathieu-Daudé 
54a2b0a27dSPhilippe Mathieu-Daudé #endif /* !CONFIG_USER_ONLY */
55a2b0a27dSPhilippe Mathieu-Daudé 
get_lmask(CPUMIPSState * env,target_ulong value,unsigned bits)564885b99aSPhilippe Mathieu-Daudé static inline target_ulong get_lmask(CPUMIPSState *env,
574885b99aSPhilippe Mathieu-Daudé                                      target_ulong value, unsigned bits)
584885b99aSPhilippe Mathieu-Daudé {
594885b99aSPhilippe Mathieu-Daudé     unsigned mask = (bits / BITS_PER_BYTE) - 1;
604885b99aSPhilippe Mathieu-Daudé 
614885b99aSPhilippe Mathieu-Daudé     value &= mask;
624885b99aSPhilippe Mathieu-Daudé 
63*5375bc16SPhilippe Mathieu-Daudé     if (!mips_env_is_bigendian(env)) {
644885b99aSPhilippe Mathieu-Daudé         value ^= mask;
654885b99aSPhilippe Mathieu-Daudé     }
664885b99aSPhilippe Mathieu-Daudé 
674885b99aSPhilippe Mathieu-Daudé     return value;
684885b99aSPhilippe Mathieu-Daudé }
69a2b0a27dSPhilippe Mathieu-Daudé 
helper_swl(CPUMIPSState * env,target_ulong arg1,target_ulong arg2,int mem_idx)70a2b0a27dSPhilippe Mathieu-Daudé void helper_swl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
71a2b0a27dSPhilippe Mathieu-Daudé                 int mem_idx)
72a2b0a27dSPhilippe Mathieu-Daudé {
734885b99aSPhilippe Mathieu-Daudé     target_ulong lmask = get_lmask(env, arg2, 32);
74*5375bc16SPhilippe Mathieu-Daudé     int dir = mips_env_is_bigendian(env) ? 1 : -1;
755b3cc34cSPhilippe Mathieu-Daudé 
76a2b0a27dSPhilippe Mathieu-Daudé     cpu_stb_mmuidx_ra(env, arg2, (uint8_t)(arg1 >> 24), mem_idx, GETPC());
77a2b0a27dSPhilippe Mathieu-Daudé 
784885b99aSPhilippe Mathieu-Daudé     if (lmask <= 2) {
795b3cc34cSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, arg2 + 1 * dir, (uint8_t)(arg1 >> 16),
80a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
81a2b0a27dSPhilippe Mathieu-Daudé     }
82a2b0a27dSPhilippe Mathieu-Daudé 
834885b99aSPhilippe Mathieu-Daudé     if (lmask <= 1) {
845b3cc34cSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, arg2 + 2 * dir, (uint8_t)(arg1 >> 8),
85a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
86a2b0a27dSPhilippe Mathieu-Daudé     }
87a2b0a27dSPhilippe Mathieu-Daudé 
884885b99aSPhilippe Mathieu-Daudé     if (lmask == 0) {
895b3cc34cSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, arg2 + 3 * dir, (uint8_t)arg1,
90a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
91a2b0a27dSPhilippe Mathieu-Daudé     }
92a2b0a27dSPhilippe Mathieu-Daudé }
93a2b0a27dSPhilippe Mathieu-Daudé 
helper_swr(CPUMIPSState * env,target_ulong arg1,target_ulong arg2,int mem_idx)94a2b0a27dSPhilippe Mathieu-Daudé void helper_swr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
95a2b0a27dSPhilippe Mathieu-Daudé                 int mem_idx)
96a2b0a27dSPhilippe Mathieu-Daudé {
974885b99aSPhilippe Mathieu-Daudé     target_ulong lmask = get_lmask(env, arg2, 32);
98*5375bc16SPhilippe Mathieu-Daudé     int dir = mips_env_is_bigendian(env) ? 1 : -1;
995b3cc34cSPhilippe Mathieu-Daudé 
100a2b0a27dSPhilippe Mathieu-Daudé     cpu_stb_mmuidx_ra(env, arg2, (uint8_t)arg1, mem_idx, GETPC());
101a2b0a27dSPhilippe Mathieu-Daudé 
1024885b99aSPhilippe Mathieu-Daudé     if (lmask >= 1) {
1035b3cc34cSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, arg2 - 1 * dir, (uint8_t)(arg1 >> 8),
104a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
105a2b0a27dSPhilippe Mathieu-Daudé     }
106a2b0a27dSPhilippe Mathieu-Daudé 
1074885b99aSPhilippe Mathieu-Daudé     if (lmask >= 2) {
1085b3cc34cSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, arg2 - 2 * dir, (uint8_t)(arg1 >> 16),
109a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
110a2b0a27dSPhilippe Mathieu-Daudé     }
111a2b0a27dSPhilippe Mathieu-Daudé 
1124885b99aSPhilippe Mathieu-Daudé     if (lmask == 3) {
1135b3cc34cSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, arg2 - 3 * dir, (uint8_t)(arg1 >> 24),
114a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
115a2b0a27dSPhilippe Mathieu-Daudé     }
116a2b0a27dSPhilippe Mathieu-Daudé }
117a2b0a27dSPhilippe Mathieu-Daudé 
118a2b0a27dSPhilippe Mathieu-Daudé #if defined(TARGET_MIPS64)
119a2b0a27dSPhilippe Mathieu-Daudé /*
120a2b0a27dSPhilippe Mathieu-Daudé  * "half" load and stores.  We must do the memory access inline,
121a2b0a27dSPhilippe Mathieu-Daudé  * or fault handling won't work.
122a2b0a27dSPhilippe Mathieu-Daudé  */
123a2b0a27dSPhilippe Mathieu-Daudé 
helper_sdl(CPUMIPSState * env,target_ulong arg1,target_ulong arg2,int mem_idx)124a2b0a27dSPhilippe Mathieu-Daudé void helper_sdl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
125a2b0a27dSPhilippe Mathieu-Daudé                 int mem_idx)
126a2b0a27dSPhilippe Mathieu-Daudé {
12723a04dcdSPhilippe Mathieu-Daudé     target_ulong lmask = get_lmask(env, arg2, 64);
128*5375bc16SPhilippe Mathieu-Daudé     int dir = mips_env_is_bigendian(env) ? 1 : -1;
1295b3cc34cSPhilippe Mathieu-Daudé 
130a2b0a27dSPhilippe Mathieu-Daudé     cpu_stb_mmuidx_ra(env, arg2, (uint8_t)(arg1 >> 56), mem_idx, GETPC());
131a2b0a27dSPhilippe Mathieu-Daudé 
13223a04dcdSPhilippe Mathieu-Daudé     if (lmask <= 6) {
1335b3cc34cSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, arg2 + 1 * dir, (uint8_t)(arg1 >> 48),
134a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
135a2b0a27dSPhilippe Mathieu-Daudé     }
136a2b0a27dSPhilippe Mathieu-Daudé 
13723a04dcdSPhilippe Mathieu-Daudé     if (lmask <= 5) {
1385b3cc34cSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, arg2 + 2 * dir, (uint8_t)(arg1 >> 40),
139a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
140a2b0a27dSPhilippe Mathieu-Daudé     }
141a2b0a27dSPhilippe Mathieu-Daudé 
14223a04dcdSPhilippe Mathieu-Daudé     if (lmask <= 4) {
1435b3cc34cSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, arg2 + 3 * dir, (uint8_t)(arg1 >> 32),
144a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
145a2b0a27dSPhilippe Mathieu-Daudé     }
146a2b0a27dSPhilippe Mathieu-Daudé 
14723a04dcdSPhilippe Mathieu-Daudé     if (lmask <= 3) {
1485b3cc34cSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, arg2 + 4 * dir, (uint8_t)(arg1 >> 24),
149a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
150a2b0a27dSPhilippe Mathieu-Daudé     }
151a2b0a27dSPhilippe Mathieu-Daudé 
15223a04dcdSPhilippe Mathieu-Daudé     if (lmask <= 2) {
1535b3cc34cSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, arg2 + 5 * dir, (uint8_t)(arg1 >> 16),
154a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
155a2b0a27dSPhilippe Mathieu-Daudé     }
156a2b0a27dSPhilippe Mathieu-Daudé 
15723a04dcdSPhilippe Mathieu-Daudé     if (lmask <= 1) {
1585b3cc34cSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, arg2 + 6 * dir, (uint8_t)(arg1 >> 8),
159a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
160a2b0a27dSPhilippe Mathieu-Daudé     }
161a2b0a27dSPhilippe Mathieu-Daudé 
16223a04dcdSPhilippe Mathieu-Daudé     if (lmask <= 0) {
1635b3cc34cSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, arg2 + 7 * dir, (uint8_t)arg1,
164a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
165a2b0a27dSPhilippe Mathieu-Daudé     }
166a2b0a27dSPhilippe Mathieu-Daudé }
167a2b0a27dSPhilippe Mathieu-Daudé 
helper_sdr(CPUMIPSState * env,target_ulong arg1,target_ulong arg2,int mem_idx)168a2b0a27dSPhilippe Mathieu-Daudé void helper_sdr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
169a2b0a27dSPhilippe Mathieu-Daudé                 int mem_idx)
170a2b0a27dSPhilippe Mathieu-Daudé {
17123a04dcdSPhilippe Mathieu-Daudé     target_ulong lmask = get_lmask(env, arg2, 64);
172*5375bc16SPhilippe Mathieu-Daudé     int dir = mips_env_is_bigendian(env) ? 1 : -1;
1735b3cc34cSPhilippe Mathieu-Daudé 
174a2b0a27dSPhilippe Mathieu-Daudé     cpu_stb_mmuidx_ra(env, arg2, (uint8_t)arg1, mem_idx, GETPC());
175a2b0a27dSPhilippe Mathieu-Daudé 
17623a04dcdSPhilippe Mathieu-Daudé     if (lmask >= 1) {
1775b3cc34cSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, arg2 - 1 * dir, (uint8_t)(arg1 >> 8),
178a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
179a2b0a27dSPhilippe Mathieu-Daudé     }
180a2b0a27dSPhilippe Mathieu-Daudé 
18123a04dcdSPhilippe Mathieu-Daudé     if (lmask >= 2) {
1825b3cc34cSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, arg2 - 2 * dir, (uint8_t)(arg1 >> 16),
183a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
184a2b0a27dSPhilippe Mathieu-Daudé     }
185a2b0a27dSPhilippe Mathieu-Daudé 
18623a04dcdSPhilippe Mathieu-Daudé     if (lmask >= 3) {
1875b3cc34cSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, arg2 - 3 * dir, (uint8_t)(arg1 >> 24),
188a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
189a2b0a27dSPhilippe Mathieu-Daudé     }
190a2b0a27dSPhilippe Mathieu-Daudé 
19123a04dcdSPhilippe Mathieu-Daudé     if (lmask >= 4) {
1925b3cc34cSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, arg2 - 4 * dir, (uint8_t)(arg1 >> 32),
193a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
194a2b0a27dSPhilippe Mathieu-Daudé     }
195a2b0a27dSPhilippe Mathieu-Daudé 
19623a04dcdSPhilippe Mathieu-Daudé     if (lmask >= 5) {
1975b3cc34cSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, arg2 - 5 * dir, (uint8_t)(arg1 >> 40),
198a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
199a2b0a27dSPhilippe Mathieu-Daudé     }
200a2b0a27dSPhilippe Mathieu-Daudé 
20123a04dcdSPhilippe Mathieu-Daudé     if (lmask >= 6) {
2025b3cc34cSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, arg2 - 6 * dir, (uint8_t)(arg1 >> 48),
203a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
204a2b0a27dSPhilippe Mathieu-Daudé     }
205a2b0a27dSPhilippe Mathieu-Daudé 
20623a04dcdSPhilippe Mathieu-Daudé     if (lmask == 7) {
2075b3cc34cSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, arg2 - 7 * dir, (uint8_t)(arg1 >> 56),
208a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
209a2b0a27dSPhilippe Mathieu-Daudé     }
210a2b0a27dSPhilippe Mathieu-Daudé }
211a2b0a27dSPhilippe Mathieu-Daudé #endif /* TARGET_MIPS64 */
212a2b0a27dSPhilippe Mathieu-Daudé 
213a2b0a27dSPhilippe Mathieu-Daudé static const int multiple_regs[] = { 16, 17, 18, 19, 20, 21, 22, 23, 30 };
214a2b0a27dSPhilippe Mathieu-Daudé 
helper_lwm(CPUMIPSState * env,target_ulong addr,target_ulong reglist,uint32_t mem_idx)215a2b0a27dSPhilippe Mathieu-Daudé void helper_lwm(CPUMIPSState *env, target_ulong addr, target_ulong reglist,
216a2b0a27dSPhilippe Mathieu-Daudé                 uint32_t mem_idx)
217a2b0a27dSPhilippe Mathieu-Daudé {
218a2b0a27dSPhilippe Mathieu-Daudé     target_ulong base_reglist = reglist & 0xf;
219a2b0a27dSPhilippe Mathieu-Daudé     target_ulong do_r31 = reglist & 0x10;
220a2b0a27dSPhilippe Mathieu-Daudé 
221a2b0a27dSPhilippe Mathieu-Daudé     if (base_reglist > 0 && base_reglist <= ARRAY_SIZE(multiple_regs)) {
222a2b0a27dSPhilippe Mathieu-Daudé         target_ulong i;
223a2b0a27dSPhilippe Mathieu-Daudé 
224a2b0a27dSPhilippe Mathieu-Daudé         for (i = 0; i < base_reglist; i++) {
225a2b0a27dSPhilippe Mathieu-Daudé             env->active_tc.gpr[multiple_regs[i]] =
226a2b0a27dSPhilippe Mathieu-Daudé                 (target_long)cpu_ldl_mmuidx_ra(env, addr, mem_idx, GETPC());
227a2b0a27dSPhilippe Mathieu-Daudé             addr += 4;
228a2b0a27dSPhilippe Mathieu-Daudé         }
229a2b0a27dSPhilippe Mathieu-Daudé     }
230a2b0a27dSPhilippe Mathieu-Daudé 
231a2b0a27dSPhilippe Mathieu-Daudé     if (do_r31) {
232a2b0a27dSPhilippe Mathieu-Daudé         env->active_tc.gpr[31] =
233a2b0a27dSPhilippe Mathieu-Daudé             (target_long)cpu_ldl_mmuidx_ra(env, addr, mem_idx, GETPC());
234a2b0a27dSPhilippe Mathieu-Daudé     }
235a2b0a27dSPhilippe Mathieu-Daudé }
236a2b0a27dSPhilippe Mathieu-Daudé 
helper_swm(CPUMIPSState * env,target_ulong addr,target_ulong reglist,uint32_t mem_idx)237a2b0a27dSPhilippe Mathieu-Daudé void helper_swm(CPUMIPSState *env, target_ulong addr, target_ulong reglist,
238a2b0a27dSPhilippe Mathieu-Daudé                 uint32_t mem_idx)
239a2b0a27dSPhilippe Mathieu-Daudé {
240a2b0a27dSPhilippe Mathieu-Daudé     target_ulong base_reglist = reglist & 0xf;
241a2b0a27dSPhilippe Mathieu-Daudé     target_ulong do_r31 = reglist & 0x10;
242a2b0a27dSPhilippe Mathieu-Daudé 
243a2b0a27dSPhilippe Mathieu-Daudé     if (base_reglist > 0 && base_reglist <= ARRAY_SIZE(multiple_regs)) {
244a2b0a27dSPhilippe Mathieu-Daudé         target_ulong i;
245a2b0a27dSPhilippe Mathieu-Daudé 
246a2b0a27dSPhilippe Mathieu-Daudé         for (i = 0; i < base_reglist; i++) {
2477c00edb9SMarcin Nowakowski             cpu_stl_mmuidx_ra(env, addr, env->active_tc.gpr[multiple_regs[i]],
248a2b0a27dSPhilippe Mathieu-Daudé                               mem_idx, GETPC());
249a2b0a27dSPhilippe Mathieu-Daudé             addr += 4;
250a2b0a27dSPhilippe Mathieu-Daudé         }
251a2b0a27dSPhilippe Mathieu-Daudé     }
252a2b0a27dSPhilippe Mathieu-Daudé 
253a2b0a27dSPhilippe Mathieu-Daudé     if (do_r31) {
2547c00edb9SMarcin Nowakowski         cpu_stl_mmuidx_ra(env, addr, env->active_tc.gpr[31], mem_idx, GETPC());
255a2b0a27dSPhilippe Mathieu-Daudé     }
256a2b0a27dSPhilippe Mathieu-Daudé }
257a2b0a27dSPhilippe Mathieu-Daudé 
258a2b0a27dSPhilippe Mathieu-Daudé #if defined(TARGET_MIPS64)
helper_ldm(CPUMIPSState * env,target_ulong addr,target_ulong reglist,uint32_t mem_idx)259a2b0a27dSPhilippe Mathieu-Daudé void helper_ldm(CPUMIPSState *env, target_ulong addr, target_ulong reglist,
260a2b0a27dSPhilippe Mathieu-Daudé                 uint32_t mem_idx)
261a2b0a27dSPhilippe Mathieu-Daudé {
262a2b0a27dSPhilippe Mathieu-Daudé     target_ulong base_reglist = reglist & 0xf;
263a2b0a27dSPhilippe Mathieu-Daudé     target_ulong do_r31 = reglist & 0x10;
264a2b0a27dSPhilippe Mathieu-Daudé 
265a2b0a27dSPhilippe Mathieu-Daudé     if (base_reglist > 0 && base_reglist <= ARRAY_SIZE(multiple_regs)) {
266a2b0a27dSPhilippe Mathieu-Daudé         target_ulong i;
267a2b0a27dSPhilippe Mathieu-Daudé 
268a2b0a27dSPhilippe Mathieu-Daudé         for (i = 0; i < base_reglist; i++) {
269a2b0a27dSPhilippe Mathieu-Daudé             env->active_tc.gpr[multiple_regs[i]] =
270a2b0a27dSPhilippe Mathieu-Daudé                 cpu_ldq_mmuidx_ra(env, addr, mem_idx, GETPC());
271a2b0a27dSPhilippe Mathieu-Daudé             addr += 8;
272a2b0a27dSPhilippe Mathieu-Daudé         }
273a2b0a27dSPhilippe Mathieu-Daudé     }
274a2b0a27dSPhilippe Mathieu-Daudé 
275a2b0a27dSPhilippe Mathieu-Daudé     if (do_r31) {
276a2b0a27dSPhilippe Mathieu-Daudé         env->active_tc.gpr[31] =
277a2b0a27dSPhilippe Mathieu-Daudé             cpu_ldq_mmuidx_ra(env, addr, mem_idx, GETPC());
278a2b0a27dSPhilippe Mathieu-Daudé     }
279a2b0a27dSPhilippe Mathieu-Daudé }
280a2b0a27dSPhilippe Mathieu-Daudé 
helper_sdm(CPUMIPSState * env,target_ulong addr,target_ulong reglist,uint32_t mem_idx)281a2b0a27dSPhilippe Mathieu-Daudé void helper_sdm(CPUMIPSState *env, target_ulong addr, target_ulong reglist,
282a2b0a27dSPhilippe Mathieu-Daudé                 uint32_t mem_idx)
283a2b0a27dSPhilippe Mathieu-Daudé {
284a2b0a27dSPhilippe Mathieu-Daudé     target_ulong base_reglist = reglist & 0xf;
285a2b0a27dSPhilippe Mathieu-Daudé     target_ulong do_r31 = reglist & 0x10;
286a2b0a27dSPhilippe Mathieu-Daudé 
287a2b0a27dSPhilippe Mathieu-Daudé     if (base_reglist > 0 && base_reglist <= ARRAY_SIZE(multiple_regs)) {
288a2b0a27dSPhilippe Mathieu-Daudé         target_ulong i;
289a2b0a27dSPhilippe Mathieu-Daudé 
290a2b0a27dSPhilippe Mathieu-Daudé         for (i = 0; i < base_reglist; i++) {
291a2b0a27dSPhilippe Mathieu-Daudé             cpu_stq_mmuidx_ra(env, addr, env->active_tc.gpr[multiple_regs[i]],
292a2b0a27dSPhilippe Mathieu-Daudé                               mem_idx, GETPC());
293a2b0a27dSPhilippe Mathieu-Daudé             addr += 8;
294a2b0a27dSPhilippe Mathieu-Daudé         }
295a2b0a27dSPhilippe Mathieu-Daudé     }
296a2b0a27dSPhilippe Mathieu-Daudé 
297a2b0a27dSPhilippe Mathieu-Daudé     if (do_r31) {
298a2b0a27dSPhilippe Mathieu-Daudé         cpu_stq_mmuidx_ra(env, addr, env->active_tc.gpr[31], mem_idx, GETPC());
299a2b0a27dSPhilippe Mathieu-Daudé     }
300a2b0a27dSPhilippe Mathieu-Daudé }
301a2b0a27dSPhilippe Mathieu-Daudé 
302a2b0a27dSPhilippe Mathieu-Daudé #endif /* TARGET_MIPS64 */
303