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é 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é 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é 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é 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é 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é 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é 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) 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é 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