xref: /openbmc/qemu/target/mips/tcg/ldst_helper.c (revision a2b0a27d33e9b1079698cee04ff029a0555b5ea5)
1*a2b0a27dSPhilippe Mathieu-Daudé /*
2*a2b0a27dSPhilippe Mathieu-Daudé  *  MIPS emulation load/store helpers for QEMU.
3*a2b0a27dSPhilippe Mathieu-Daudé  *
4*a2b0a27dSPhilippe Mathieu-Daudé  *  Copyright (c) 2004-2005 Jocelyn Mayer
5*a2b0a27dSPhilippe Mathieu-Daudé  *
6*a2b0a27dSPhilippe Mathieu-Daudé  * SPDX-License-Identifier: LGPL-2.1-or-later
7*a2b0a27dSPhilippe Mathieu-Daudé  *
8*a2b0a27dSPhilippe Mathieu-Daudé  * This library is free software; you can redistribute it and/or
9*a2b0a27dSPhilippe Mathieu-Daudé  * modify it under the terms of the GNU Lesser General Public
10*a2b0a27dSPhilippe Mathieu-Daudé  * License as published by the Free Software Foundation; either
11*a2b0a27dSPhilippe Mathieu-Daudé  * version 2.1 of the License, or (at your option) any later version.
12*a2b0a27dSPhilippe Mathieu-Daudé  *
13*a2b0a27dSPhilippe Mathieu-Daudé  * This library is distributed in the hope that it will be useful,
14*a2b0a27dSPhilippe Mathieu-Daudé  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15*a2b0a27dSPhilippe Mathieu-Daudé  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16*a2b0a27dSPhilippe Mathieu-Daudé  * Lesser General Public License for more details.
17*a2b0a27dSPhilippe Mathieu-Daudé  *
18*a2b0a27dSPhilippe Mathieu-Daudé  * You should have received a copy of the GNU Lesser General Public
19*a2b0a27dSPhilippe Mathieu-Daudé  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
20*a2b0a27dSPhilippe Mathieu-Daudé  *
21*a2b0a27dSPhilippe Mathieu-Daudé  */
22*a2b0a27dSPhilippe Mathieu-Daudé 
23*a2b0a27dSPhilippe Mathieu-Daudé #include "qemu/osdep.h"
24*a2b0a27dSPhilippe Mathieu-Daudé #include "cpu.h"
25*a2b0a27dSPhilippe Mathieu-Daudé #include "exec/helper-proto.h"
26*a2b0a27dSPhilippe Mathieu-Daudé #include "exec/exec-all.h"
27*a2b0a27dSPhilippe Mathieu-Daudé #include "exec/memop.h"
28*a2b0a27dSPhilippe Mathieu-Daudé #include "internal.h"
29*a2b0a27dSPhilippe Mathieu-Daudé 
30*a2b0a27dSPhilippe Mathieu-Daudé #ifndef CONFIG_USER_ONLY
31*a2b0a27dSPhilippe Mathieu-Daudé 
32*a2b0a27dSPhilippe Mathieu-Daudé #define HELPER_LD_ATOMIC(name, insn, almask, do_cast)                         \
33*a2b0a27dSPhilippe Mathieu-Daudé target_ulong helper_##name(CPUMIPSState *env, target_ulong arg, int mem_idx)  \
34*a2b0a27dSPhilippe Mathieu-Daudé {                                                                             \
35*a2b0a27dSPhilippe Mathieu-Daudé     if (arg & almask) {                                                       \
36*a2b0a27dSPhilippe Mathieu-Daudé         if (!(env->hflags & MIPS_HFLAG_DM)) {                                 \
37*a2b0a27dSPhilippe Mathieu-Daudé             env->CP0_BadVAddr = arg;                                          \
38*a2b0a27dSPhilippe Mathieu-Daudé         }                                                                     \
39*a2b0a27dSPhilippe Mathieu-Daudé         do_raise_exception(env, EXCP_AdEL, GETPC());                          \
40*a2b0a27dSPhilippe Mathieu-Daudé     }                                                                         \
41*a2b0a27dSPhilippe Mathieu-Daudé     env->CP0_LLAddr = cpu_mips_translate_address(env, arg, MMU_DATA_LOAD,     \
42*a2b0a27dSPhilippe Mathieu-Daudé                                                  GETPC());                    \
43*a2b0a27dSPhilippe Mathieu-Daudé     env->lladdr = arg;                                                        \
44*a2b0a27dSPhilippe Mathieu-Daudé     env->llval = do_cast cpu_##insn##_mmuidx_ra(env, arg, mem_idx, GETPC());  \
45*a2b0a27dSPhilippe Mathieu-Daudé     return env->llval;                                                        \
46*a2b0a27dSPhilippe Mathieu-Daudé }
47*a2b0a27dSPhilippe Mathieu-Daudé HELPER_LD_ATOMIC(ll, ldl, 0x3, (target_long)(int32_t))
48*a2b0a27dSPhilippe Mathieu-Daudé #ifdef TARGET_MIPS64
49*a2b0a27dSPhilippe Mathieu-Daudé HELPER_LD_ATOMIC(lld, ldq, 0x7, (target_ulong))
50*a2b0a27dSPhilippe Mathieu-Daudé #endif
51*a2b0a27dSPhilippe Mathieu-Daudé #undef HELPER_LD_ATOMIC
52*a2b0a27dSPhilippe Mathieu-Daudé 
53*a2b0a27dSPhilippe Mathieu-Daudé #endif /* !CONFIG_USER_ONLY */
54*a2b0a27dSPhilippe Mathieu-Daudé 
55*a2b0a27dSPhilippe Mathieu-Daudé #ifdef TARGET_WORDS_BIGENDIAN
56*a2b0a27dSPhilippe Mathieu-Daudé #define GET_LMASK(v) ((v) & 3)
57*a2b0a27dSPhilippe Mathieu-Daudé #define GET_OFFSET(addr, offset) (addr + (offset))
58*a2b0a27dSPhilippe Mathieu-Daudé #else
59*a2b0a27dSPhilippe Mathieu-Daudé #define GET_LMASK(v) (((v) & 3) ^ 3)
60*a2b0a27dSPhilippe Mathieu-Daudé #define GET_OFFSET(addr, offset) (addr - (offset))
61*a2b0a27dSPhilippe Mathieu-Daudé #endif
62*a2b0a27dSPhilippe Mathieu-Daudé 
63*a2b0a27dSPhilippe Mathieu-Daudé void helper_swl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
64*a2b0a27dSPhilippe Mathieu-Daudé                 int mem_idx)
65*a2b0a27dSPhilippe Mathieu-Daudé {
66*a2b0a27dSPhilippe Mathieu-Daudé     cpu_stb_mmuidx_ra(env, arg2, (uint8_t)(arg1 >> 24), mem_idx, GETPC());
67*a2b0a27dSPhilippe Mathieu-Daudé 
68*a2b0a27dSPhilippe Mathieu-Daudé     if (GET_LMASK(arg2) <= 2) {
69*a2b0a27dSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 1), (uint8_t)(arg1 >> 16),
70*a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
71*a2b0a27dSPhilippe Mathieu-Daudé     }
72*a2b0a27dSPhilippe Mathieu-Daudé 
73*a2b0a27dSPhilippe Mathieu-Daudé     if (GET_LMASK(arg2) <= 1) {
74*a2b0a27dSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 2), (uint8_t)(arg1 >> 8),
75*a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
76*a2b0a27dSPhilippe Mathieu-Daudé     }
77*a2b0a27dSPhilippe Mathieu-Daudé 
78*a2b0a27dSPhilippe Mathieu-Daudé     if (GET_LMASK(arg2) == 0) {
79*a2b0a27dSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 3), (uint8_t)arg1,
80*a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
81*a2b0a27dSPhilippe Mathieu-Daudé     }
82*a2b0a27dSPhilippe Mathieu-Daudé }
83*a2b0a27dSPhilippe Mathieu-Daudé 
84*a2b0a27dSPhilippe Mathieu-Daudé void helper_swr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
85*a2b0a27dSPhilippe Mathieu-Daudé                 int mem_idx)
86*a2b0a27dSPhilippe Mathieu-Daudé {
87*a2b0a27dSPhilippe Mathieu-Daudé     cpu_stb_mmuidx_ra(env, arg2, (uint8_t)arg1, mem_idx, GETPC());
88*a2b0a27dSPhilippe Mathieu-Daudé 
89*a2b0a27dSPhilippe Mathieu-Daudé     if (GET_LMASK(arg2) >= 1) {
90*a2b0a27dSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, -1), (uint8_t)(arg1 >> 8),
91*a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
92*a2b0a27dSPhilippe Mathieu-Daudé     }
93*a2b0a27dSPhilippe Mathieu-Daudé 
94*a2b0a27dSPhilippe Mathieu-Daudé     if (GET_LMASK(arg2) >= 2) {
95*a2b0a27dSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, -2), (uint8_t)(arg1 >> 16),
96*a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
97*a2b0a27dSPhilippe Mathieu-Daudé     }
98*a2b0a27dSPhilippe Mathieu-Daudé 
99*a2b0a27dSPhilippe Mathieu-Daudé     if (GET_LMASK(arg2) == 3) {
100*a2b0a27dSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, -3), (uint8_t)(arg1 >> 24),
101*a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
102*a2b0a27dSPhilippe Mathieu-Daudé     }
103*a2b0a27dSPhilippe Mathieu-Daudé }
104*a2b0a27dSPhilippe Mathieu-Daudé 
105*a2b0a27dSPhilippe Mathieu-Daudé #if defined(TARGET_MIPS64)
106*a2b0a27dSPhilippe Mathieu-Daudé /*
107*a2b0a27dSPhilippe Mathieu-Daudé  * "half" load and stores.  We must do the memory access inline,
108*a2b0a27dSPhilippe Mathieu-Daudé  * or fault handling won't work.
109*a2b0a27dSPhilippe Mathieu-Daudé  */
110*a2b0a27dSPhilippe Mathieu-Daudé #ifdef TARGET_WORDS_BIGENDIAN
111*a2b0a27dSPhilippe Mathieu-Daudé #define GET_LMASK64(v) ((v) & 7)
112*a2b0a27dSPhilippe Mathieu-Daudé #else
113*a2b0a27dSPhilippe Mathieu-Daudé #define GET_LMASK64(v) (((v) & 7) ^ 7)
114*a2b0a27dSPhilippe Mathieu-Daudé #endif
115*a2b0a27dSPhilippe Mathieu-Daudé 
116*a2b0a27dSPhilippe Mathieu-Daudé void helper_sdl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
117*a2b0a27dSPhilippe Mathieu-Daudé                 int mem_idx)
118*a2b0a27dSPhilippe Mathieu-Daudé {
119*a2b0a27dSPhilippe Mathieu-Daudé     cpu_stb_mmuidx_ra(env, arg2, (uint8_t)(arg1 >> 56), mem_idx, GETPC());
120*a2b0a27dSPhilippe Mathieu-Daudé 
121*a2b0a27dSPhilippe Mathieu-Daudé     if (GET_LMASK64(arg2) <= 6) {
122*a2b0a27dSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 1), (uint8_t)(arg1 >> 48),
123*a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
124*a2b0a27dSPhilippe Mathieu-Daudé     }
125*a2b0a27dSPhilippe Mathieu-Daudé 
126*a2b0a27dSPhilippe Mathieu-Daudé     if (GET_LMASK64(arg2) <= 5) {
127*a2b0a27dSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 2), (uint8_t)(arg1 >> 40),
128*a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
129*a2b0a27dSPhilippe Mathieu-Daudé     }
130*a2b0a27dSPhilippe Mathieu-Daudé 
131*a2b0a27dSPhilippe Mathieu-Daudé     if (GET_LMASK64(arg2) <= 4) {
132*a2b0a27dSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 3), (uint8_t)(arg1 >> 32),
133*a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
134*a2b0a27dSPhilippe Mathieu-Daudé     }
135*a2b0a27dSPhilippe Mathieu-Daudé 
136*a2b0a27dSPhilippe Mathieu-Daudé     if (GET_LMASK64(arg2) <= 3) {
137*a2b0a27dSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 4), (uint8_t)(arg1 >> 24),
138*a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
139*a2b0a27dSPhilippe Mathieu-Daudé     }
140*a2b0a27dSPhilippe Mathieu-Daudé 
141*a2b0a27dSPhilippe Mathieu-Daudé     if (GET_LMASK64(arg2) <= 2) {
142*a2b0a27dSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 5), (uint8_t)(arg1 >> 16),
143*a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
144*a2b0a27dSPhilippe Mathieu-Daudé     }
145*a2b0a27dSPhilippe Mathieu-Daudé 
146*a2b0a27dSPhilippe Mathieu-Daudé     if (GET_LMASK64(arg2) <= 1) {
147*a2b0a27dSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 6), (uint8_t)(arg1 >> 8),
148*a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
149*a2b0a27dSPhilippe Mathieu-Daudé     }
150*a2b0a27dSPhilippe Mathieu-Daudé 
151*a2b0a27dSPhilippe Mathieu-Daudé     if (GET_LMASK64(arg2) <= 0) {
152*a2b0a27dSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 7), (uint8_t)arg1,
153*a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
154*a2b0a27dSPhilippe Mathieu-Daudé     }
155*a2b0a27dSPhilippe Mathieu-Daudé }
156*a2b0a27dSPhilippe Mathieu-Daudé 
157*a2b0a27dSPhilippe Mathieu-Daudé void helper_sdr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
158*a2b0a27dSPhilippe Mathieu-Daudé                 int mem_idx)
159*a2b0a27dSPhilippe Mathieu-Daudé {
160*a2b0a27dSPhilippe Mathieu-Daudé     cpu_stb_mmuidx_ra(env, arg2, (uint8_t)arg1, mem_idx, GETPC());
161*a2b0a27dSPhilippe Mathieu-Daudé 
162*a2b0a27dSPhilippe Mathieu-Daudé     if (GET_LMASK64(arg2) >= 1) {
163*a2b0a27dSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, -1), (uint8_t)(arg1 >> 8),
164*a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
165*a2b0a27dSPhilippe Mathieu-Daudé     }
166*a2b0a27dSPhilippe Mathieu-Daudé 
167*a2b0a27dSPhilippe Mathieu-Daudé     if (GET_LMASK64(arg2) >= 2) {
168*a2b0a27dSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, -2), (uint8_t)(arg1 >> 16),
169*a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
170*a2b0a27dSPhilippe Mathieu-Daudé     }
171*a2b0a27dSPhilippe Mathieu-Daudé 
172*a2b0a27dSPhilippe Mathieu-Daudé     if (GET_LMASK64(arg2) >= 3) {
173*a2b0a27dSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, -3), (uint8_t)(arg1 >> 24),
174*a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
175*a2b0a27dSPhilippe Mathieu-Daudé     }
176*a2b0a27dSPhilippe Mathieu-Daudé 
177*a2b0a27dSPhilippe Mathieu-Daudé     if (GET_LMASK64(arg2) >= 4) {
178*a2b0a27dSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, -4), (uint8_t)(arg1 >> 32),
179*a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
180*a2b0a27dSPhilippe Mathieu-Daudé     }
181*a2b0a27dSPhilippe Mathieu-Daudé 
182*a2b0a27dSPhilippe Mathieu-Daudé     if (GET_LMASK64(arg2) >= 5) {
183*a2b0a27dSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, -5), (uint8_t)(arg1 >> 40),
184*a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
185*a2b0a27dSPhilippe Mathieu-Daudé     }
186*a2b0a27dSPhilippe Mathieu-Daudé 
187*a2b0a27dSPhilippe Mathieu-Daudé     if (GET_LMASK64(arg2) >= 6) {
188*a2b0a27dSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, -6), (uint8_t)(arg1 >> 48),
189*a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
190*a2b0a27dSPhilippe Mathieu-Daudé     }
191*a2b0a27dSPhilippe Mathieu-Daudé 
192*a2b0a27dSPhilippe Mathieu-Daudé     if (GET_LMASK64(arg2) == 7) {
193*a2b0a27dSPhilippe Mathieu-Daudé         cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, -7), (uint8_t)(arg1 >> 56),
194*a2b0a27dSPhilippe Mathieu-Daudé                           mem_idx, GETPC());
195*a2b0a27dSPhilippe Mathieu-Daudé     }
196*a2b0a27dSPhilippe Mathieu-Daudé }
197*a2b0a27dSPhilippe Mathieu-Daudé #endif /* TARGET_MIPS64 */
198*a2b0a27dSPhilippe Mathieu-Daudé 
199*a2b0a27dSPhilippe Mathieu-Daudé static const int multiple_regs[] = { 16, 17, 18, 19, 20, 21, 22, 23, 30 };
200*a2b0a27dSPhilippe Mathieu-Daudé 
201*a2b0a27dSPhilippe Mathieu-Daudé void helper_lwm(CPUMIPSState *env, target_ulong addr, target_ulong reglist,
202*a2b0a27dSPhilippe Mathieu-Daudé                 uint32_t mem_idx)
203*a2b0a27dSPhilippe Mathieu-Daudé {
204*a2b0a27dSPhilippe Mathieu-Daudé     target_ulong base_reglist = reglist & 0xf;
205*a2b0a27dSPhilippe Mathieu-Daudé     target_ulong do_r31 = reglist & 0x10;
206*a2b0a27dSPhilippe Mathieu-Daudé 
207*a2b0a27dSPhilippe Mathieu-Daudé     if (base_reglist > 0 && base_reglist <= ARRAY_SIZE(multiple_regs)) {
208*a2b0a27dSPhilippe Mathieu-Daudé         target_ulong i;
209*a2b0a27dSPhilippe Mathieu-Daudé 
210*a2b0a27dSPhilippe Mathieu-Daudé         for (i = 0; i < base_reglist; i++) {
211*a2b0a27dSPhilippe Mathieu-Daudé             env->active_tc.gpr[multiple_regs[i]] =
212*a2b0a27dSPhilippe Mathieu-Daudé                 (target_long)cpu_ldl_mmuidx_ra(env, addr, mem_idx, GETPC());
213*a2b0a27dSPhilippe Mathieu-Daudé             addr += 4;
214*a2b0a27dSPhilippe Mathieu-Daudé         }
215*a2b0a27dSPhilippe Mathieu-Daudé     }
216*a2b0a27dSPhilippe Mathieu-Daudé 
217*a2b0a27dSPhilippe Mathieu-Daudé     if (do_r31) {
218*a2b0a27dSPhilippe Mathieu-Daudé         env->active_tc.gpr[31] =
219*a2b0a27dSPhilippe Mathieu-Daudé             (target_long)cpu_ldl_mmuidx_ra(env, addr, mem_idx, GETPC());
220*a2b0a27dSPhilippe Mathieu-Daudé     }
221*a2b0a27dSPhilippe Mathieu-Daudé }
222*a2b0a27dSPhilippe Mathieu-Daudé 
223*a2b0a27dSPhilippe Mathieu-Daudé void helper_swm(CPUMIPSState *env, target_ulong addr, target_ulong reglist,
224*a2b0a27dSPhilippe Mathieu-Daudé                 uint32_t mem_idx)
225*a2b0a27dSPhilippe Mathieu-Daudé {
226*a2b0a27dSPhilippe Mathieu-Daudé     target_ulong base_reglist = reglist & 0xf;
227*a2b0a27dSPhilippe Mathieu-Daudé     target_ulong do_r31 = reglist & 0x10;
228*a2b0a27dSPhilippe Mathieu-Daudé 
229*a2b0a27dSPhilippe Mathieu-Daudé     if (base_reglist > 0 && base_reglist <= ARRAY_SIZE(multiple_regs)) {
230*a2b0a27dSPhilippe Mathieu-Daudé         target_ulong i;
231*a2b0a27dSPhilippe Mathieu-Daudé 
232*a2b0a27dSPhilippe Mathieu-Daudé         for (i = 0; i < base_reglist; i++) {
233*a2b0a27dSPhilippe Mathieu-Daudé             cpu_stw_mmuidx_ra(env, addr, env->active_tc.gpr[multiple_regs[i]],
234*a2b0a27dSPhilippe Mathieu-Daudé                               mem_idx, GETPC());
235*a2b0a27dSPhilippe Mathieu-Daudé             addr += 4;
236*a2b0a27dSPhilippe Mathieu-Daudé         }
237*a2b0a27dSPhilippe Mathieu-Daudé     }
238*a2b0a27dSPhilippe Mathieu-Daudé 
239*a2b0a27dSPhilippe Mathieu-Daudé     if (do_r31) {
240*a2b0a27dSPhilippe Mathieu-Daudé         cpu_stw_mmuidx_ra(env, addr, env->active_tc.gpr[31], mem_idx, GETPC());
241*a2b0a27dSPhilippe Mathieu-Daudé     }
242*a2b0a27dSPhilippe Mathieu-Daudé }
243*a2b0a27dSPhilippe Mathieu-Daudé 
244*a2b0a27dSPhilippe Mathieu-Daudé #if defined(TARGET_MIPS64)
245*a2b0a27dSPhilippe Mathieu-Daudé void helper_ldm(CPUMIPSState *env, target_ulong addr, target_ulong reglist,
246*a2b0a27dSPhilippe Mathieu-Daudé                 uint32_t mem_idx)
247*a2b0a27dSPhilippe Mathieu-Daudé {
248*a2b0a27dSPhilippe Mathieu-Daudé     target_ulong base_reglist = reglist & 0xf;
249*a2b0a27dSPhilippe Mathieu-Daudé     target_ulong do_r31 = reglist & 0x10;
250*a2b0a27dSPhilippe Mathieu-Daudé 
251*a2b0a27dSPhilippe Mathieu-Daudé     if (base_reglist > 0 && base_reglist <= ARRAY_SIZE(multiple_regs)) {
252*a2b0a27dSPhilippe Mathieu-Daudé         target_ulong i;
253*a2b0a27dSPhilippe Mathieu-Daudé 
254*a2b0a27dSPhilippe Mathieu-Daudé         for (i = 0; i < base_reglist; i++) {
255*a2b0a27dSPhilippe Mathieu-Daudé             env->active_tc.gpr[multiple_regs[i]] =
256*a2b0a27dSPhilippe Mathieu-Daudé                 cpu_ldq_mmuidx_ra(env, addr, mem_idx, GETPC());
257*a2b0a27dSPhilippe Mathieu-Daudé             addr += 8;
258*a2b0a27dSPhilippe Mathieu-Daudé         }
259*a2b0a27dSPhilippe Mathieu-Daudé     }
260*a2b0a27dSPhilippe Mathieu-Daudé 
261*a2b0a27dSPhilippe Mathieu-Daudé     if (do_r31) {
262*a2b0a27dSPhilippe Mathieu-Daudé         env->active_tc.gpr[31] =
263*a2b0a27dSPhilippe Mathieu-Daudé             cpu_ldq_mmuidx_ra(env, addr, mem_idx, GETPC());
264*a2b0a27dSPhilippe Mathieu-Daudé     }
265*a2b0a27dSPhilippe Mathieu-Daudé }
266*a2b0a27dSPhilippe Mathieu-Daudé 
267*a2b0a27dSPhilippe Mathieu-Daudé void helper_sdm(CPUMIPSState *env, target_ulong addr, target_ulong reglist,
268*a2b0a27dSPhilippe Mathieu-Daudé                 uint32_t mem_idx)
269*a2b0a27dSPhilippe Mathieu-Daudé {
270*a2b0a27dSPhilippe Mathieu-Daudé     target_ulong base_reglist = reglist & 0xf;
271*a2b0a27dSPhilippe Mathieu-Daudé     target_ulong do_r31 = reglist & 0x10;
272*a2b0a27dSPhilippe Mathieu-Daudé 
273*a2b0a27dSPhilippe Mathieu-Daudé     if (base_reglist > 0 && base_reglist <= ARRAY_SIZE(multiple_regs)) {
274*a2b0a27dSPhilippe Mathieu-Daudé         target_ulong i;
275*a2b0a27dSPhilippe Mathieu-Daudé 
276*a2b0a27dSPhilippe Mathieu-Daudé         for (i = 0; i < base_reglist; i++) {
277*a2b0a27dSPhilippe Mathieu-Daudé             cpu_stq_mmuidx_ra(env, addr, env->active_tc.gpr[multiple_regs[i]],
278*a2b0a27dSPhilippe Mathieu-Daudé                               mem_idx, GETPC());
279*a2b0a27dSPhilippe Mathieu-Daudé             addr += 8;
280*a2b0a27dSPhilippe Mathieu-Daudé         }
281*a2b0a27dSPhilippe Mathieu-Daudé     }
282*a2b0a27dSPhilippe Mathieu-Daudé 
283*a2b0a27dSPhilippe Mathieu-Daudé     if (do_r31) {
284*a2b0a27dSPhilippe Mathieu-Daudé         cpu_stq_mmuidx_ra(env, addr, env->active_tc.gpr[31], mem_idx, GETPC());
285*a2b0a27dSPhilippe Mathieu-Daudé     }
286*a2b0a27dSPhilippe Mathieu-Daudé }
287*a2b0a27dSPhilippe Mathieu-Daudé 
288*a2b0a27dSPhilippe Mathieu-Daudé #endif /* TARGET_MIPS64 */
289