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" 27a2b0a27dSPhilippe Mathieu-Daudé #include "exec/memop.h" 28a2b0a27dSPhilippe Mathieu-Daudé #include "internal.h" 29a2b0a27dSPhilippe Mathieu-Daudé 30a2b0a27dSPhilippe Mathieu-Daudé #ifndef CONFIG_USER_ONLY 31a2b0a27dSPhilippe Mathieu-Daudé 32a2b0a27dSPhilippe Mathieu-Daudé #define HELPER_LD_ATOMIC(name, insn, almask, do_cast) \ 33a2b0a27dSPhilippe Mathieu-Daudé target_ulong helper_##name(CPUMIPSState *env, target_ulong arg, int mem_idx) \ 34a2b0a27dSPhilippe Mathieu-Daudé { \ 35a2b0a27dSPhilippe Mathieu-Daudé if (arg & almask) { \ 36a2b0a27dSPhilippe Mathieu-Daudé if (!(env->hflags & MIPS_HFLAG_DM)) { \ 37a2b0a27dSPhilippe Mathieu-Daudé env->CP0_BadVAddr = arg; \ 38a2b0a27dSPhilippe Mathieu-Daudé } \ 39a2b0a27dSPhilippe Mathieu-Daudé do_raise_exception(env, EXCP_AdEL, GETPC()); \ 40a2b0a27dSPhilippe Mathieu-Daudé } \ 41a2b0a27dSPhilippe Mathieu-Daudé env->CP0_LLAddr = cpu_mips_translate_address(env, arg, MMU_DATA_LOAD, \ 42a2b0a27dSPhilippe Mathieu-Daudé GETPC()); \ 43a2b0a27dSPhilippe Mathieu-Daudé env->lladdr = arg; \ 44a2b0a27dSPhilippe Mathieu-Daudé env->llval = do_cast cpu_##insn##_mmuidx_ra(env, arg, mem_idx, GETPC()); \ 45a2b0a27dSPhilippe Mathieu-Daudé return env->llval; \ 46a2b0a27dSPhilippe Mathieu-Daudé } 47a2b0a27dSPhilippe Mathieu-Daudé HELPER_LD_ATOMIC(ll, ldl, 0x3, (target_long)(int32_t)) 48a2b0a27dSPhilippe Mathieu-Daudé #ifdef TARGET_MIPS64 49a2b0a27dSPhilippe Mathieu-Daudé HELPER_LD_ATOMIC(lld, ldq, 0x7, (target_ulong)) 50a2b0a27dSPhilippe Mathieu-Daudé #endif 51a2b0a27dSPhilippe Mathieu-Daudé #undef HELPER_LD_ATOMIC 52a2b0a27dSPhilippe Mathieu-Daudé 53a2b0a27dSPhilippe Mathieu-Daudé #endif /* !CONFIG_USER_ONLY */ 54a2b0a27dSPhilippe Mathieu-Daudé 555b3cc34cSPhilippe Mathieu-Daudé static inline bool cpu_is_bigendian(CPUMIPSState *env) 565b3cc34cSPhilippe Mathieu-Daudé { 575b3cc34cSPhilippe Mathieu-Daudé return extract32(env->CP0_Config0, CP0C0_BE, 1); 585b3cc34cSPhilippe Mathieu-Daudé } 595b3cc34cSPhilippe Mathieu-Daudé 60*4885b99aSPhilippe Mathieu-Daudé static inline target_ulong get_lmask(CPUMIPSState *env, 61*4885b99aSPhilippe Mathieu-Daudé target_ulong value, unsigned bits) 62*4885b99aSPhilippe Mathieu-Daudé { 63*4885b99aSPhilippe Mathieu-Daudé unsigned mask = (bits / BITS_PER_BYTE) - 1; 64*4885b99aSPhilippe Mathieu-Daudé 65*4885b99aSPhilippe Mathieu-Daudé value &= mask; 66*4885b99aSPhilippe Mathieu-Daudé 67*4885b99aSPhilippe Mathieu-Daudé if (!cpu_is_bigendian(env)) { 68*4885b99aSPhilippe Mathieu-Daudé value ^= mask; 69*4885b99aSPhilippe Mathieu-Daudé } 70*4885b99aSPhilippe Mathieu-Daudé 71*4885b99aSPhilippe Mathieu-Daudé return value; 72*4885b99aSPhilippe Mathieu-Daudé } 73a2b0a27dSPhilippe Mathieu-Daudé 74a2b0a27dSPhilippe Mathieu-Daudé void helper_swl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2, 75a2b0a27dSPhilippe Mathieu-Daudé int mem_idx) 76a2b0a27dSPhilippe Mathieu-Daudé { 77*4885b99aSPhilippe Mathieu-Daudé target_ulong lmask = get_lmask(env, arg2, 32); 785b3cc34cSPhilippe Mathieu-Daudé int dir = cpu_is_bigendian(env) ? 1 : -1; 795b3cc34cSPhilippe Mathieu-Daudé 80a2b0a27dSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2, (uint8_t)(arg1 >> 24), mem_idx, GETPC()); 81a2b0a27dSPhilippe Mathieu-Daudé 82*4885b99aSPhilippe Mathieu-Daudé if (lmask <= 2) { 835b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 + 1 * dir, (uint8_t)(arg1 >> 16), 84a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 85a2b0a27dSPhilippe Mathieu-Daudé } 86a2b0a27dSPhilippe Mathieu-Daudé 87*4885b99aSPhilippe Mathieu-Daudé if (lmask <= 1) { 885b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 + 2 * dir, (uint8_t)(arg1 >> 8), 89a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 90a2b0a27dSPhilippe Mathieu-Daudé } 91a2b0a27dSPhilippe Mathieu-Daudé 92*4885b99aSPhilippe Mathieu-Daudé if (lmask == 0) { 935b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 + 3 * dir, (uint8_t)arg1, 94a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 95a2b0a27dSPhilippe Mathieu-Daudé } 96a2b0a27dSPhilippe Mathieu-Daudé } 97a2b0a27dSPhilippe Mathieu-Daudé 98a2b0a27dSPhilippe Mathieu-Daudé void helper_swr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2, 99a2b0a27dSPhilippe Mathieu-Daudé int mem_idx) 100a2b0a27dSPhilippe Mathieu-Daudé { 101*4885b99aSPhilippe Mathieu-Daudé target_ulong lmask = get_lmask(env, arg2, 32); 1025b3cc34cSPhilippe Mathieu-Daudé int dir = cpu_is_bigendian(env) ? 1 : -1; 1035b3cc34cSPhilippe Mathieu-Daudé 104a2b0a27dSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2, (uint8_t)arg1, mem_idx, GETPC()); 105a2b0a27dSPhilippe Mathieu-Daudé 106*4885b99aSPhilippe Mathieu-Daudé if (lmask >= 1) { 1075b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 - 1 * dir, (uint8_t)(arg1 >> 8), 108a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 109a2b0a27dSPhilippe Mathieu-Daudé } 110a2b0a27dSPhilippe Mathieu-Daudé 111*4885b99aSPhilippe Mathieu-Daudé if (lmask >= 2) { 1125b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 - 2 * dir, (uint8_t)(arg1 >> 16), 113a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 114a2b0a27dSPhilippe Mathieu-Daudé } 115a2b0a27dSPhilippe Mathieu-Daudé 116*4885b99aSPhilippe Mathieu-Daudé if (lmask == 3) { 1175b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 - 3 * dir, (uint8_t)(arg1 >> 24), 118a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 119a2b0a27dSPhilippe Mathieu-Daudé } 120a2b0a27dSPhilippe Mathieu-Daudé } 121a2b0a27dSPhilippe Mathieu-Daudé 122a2b0a27dSPhilippe Mathieu-Daudé #if defined(TARGET_MIPS64) 123a2b0a27dSPhilippe Mathieu-Daudé /* 124a2b0a27dSPhilippe Mathieu-Daudé * "half" load and stores. We must do the memory access inline, 125a2b0a27dSPhilippe Mathieu-Daudé * or fault handling won't work. 126a2b0a27dSPhilippe Mathieu-Daudé */ 127a2b0a27dSPhilippe Mathieu-Daudé #ifdef TARGET_WORDS_BIGENDIAN 128a2b0a27dSPhilippe Mathieu-Daudé #define GET_LMASK64(v) ((v) & 7) 129a2b0a27dSPhilippe Mathieu-Daudé #else 130a2b0a27dSPhilippe Mathieu-Daudé #define GET_LMASK64(v) (((v) & 7) ^ 7) 131a2b0a27dSPhilippe Mathieu-Daudé #endif 132a2b0a27dSPhilippe Mathieu-Daudé 133a2b0a27dSPhilippe Mathieu-Daudé void helper_sdl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2, 134a2b0a27dSPhilippe Mathieu-Daudé int mem_idx) 135a2b0a27dSPhilippe Mathieu-Daudé { 1365b3cc34cSPhilippe Mathieu-Daudé int dir = cpu_is_bigendian(env) ? 1 : -1; 1375b3cc34cSPhilippe Mathieu-Daudé 138a2b0a27dSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2, (uint8_t)(arg1 >> 56), mem_idx, GETPC()); 139a2b0a27dSPhilippe Mathieu-Daudé 140a2b0a27dSPhilippe Mathieu-Daudé if (GET_LMASK64(arg2) <= 6) { 1415b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 + 1 * dir, (uint8_t)(arg1 >> 48), 142a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 143a2b0a27dSPhilippe Mathieu-Daudé } 144a2b0a27dSPhilippe Mathieu-Daudé 145a2b0a27dSPhilippe Mathieu-Daudé if (GET_LMASK64(arg2) <= 5) { 1465b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 + 2 * dir, (uint8_t)(arg1 >> 40), 147a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 148a2b0a27dSPhilippe Mathieu-Daudé } 149a2b0a27dSPhilippe Mathieu-Daudé 150a2b0a27dSPhilippe Mathieu-Daudé if (GET_LMASK64(arg2) <= 4) { 1515b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 + 3 * dir, (uint8_t)(arg1 >> 32), 152a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 153a2b0a27dSPhilippe Mathieu-Daudé } 154a2b0a27dSPhilippe Mathieu-Daudé 155a2b0a27dSPhilippe Mathieu-Daudé if (GET_LMASK64(arg2) <= 3) { 1565b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 + 4 * dir, (uint8_t)(arg1 >> 24), 157a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 158a2b0a27dSPhilippe Mathieu-Daudé } 159a2b0a27dSPhilippe Mathieu-Daudé 160a2b0a27dSPhilippe Mathieu-Daudé if (GET_LMASK64(arg2) <= 2) { 1615b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 + 5 * dir, (uint8_t)(arg1 >> 16), 162a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 163a2b0a27dSPhilippe Mathieu-Daudé } 164a2b0a27dSPhilippe Mathieu-Daudé 165a2b0a27dSPhilippe Mathieu-Daudé if (GET_LMASK64(arg2) <= 1) { 1665b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 + 6 * dir, (uint8_t)(arg1 >> 8), 167a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 168a2b0a27dSPhilippe Mathieu-Daudé } 169a2b0a27dSPhilippe Mathieu-Daudé 170a2b0a27dSPhilippe Mathieu-Daudé if (GET_LMASK64(arg2) <= 0) { 1715b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 + 7 * dir, (uint8_t)arg1, 172a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 173a2b0a27dSPhilippe Mathieu-Daudé } 174a2b0a27dSPhilippe Mathieu-Daudé } 175a2b0a27dSPhilippe Mathieu-Daudé 176a2b0a27dSPhilippe Mathieu-Daudé void helper_sdr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2, 177a2b0a27dSPhilippe Mathieu-Daudé int mem_idx) 178a2b0a27dSPhilippe Mathieu-Daudé { 1795b3cc34cSPhilippe Mathieu-Daudé int dir = cpu_is_bigendian(env) ? 1 : -1; 1805b3cc34cSPhilippe Mathieu-Daudé 181a2b0a27dSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2, (uint8_t)arg1, mem_idx, GETPC()); 182a2b0a27dSPhilippe Mathieu-Daudé 183a2b0a27dSPhilippe Mathieu-Daudé if (GET_LMASK64(arg2) >= 1) { 1845b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 - 1 * dir, (uint8_t)(arg1 >> 8), 185a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 186a2b0a27dSPhilippe Mathieu-Daudé } 187a2b0a27dSPhilippe Mathieu-Daudé 188a2b0a27dSPhilippe Mathieu-Daudé if (GET_LMASK64(arg2) >= 2) { 1895b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 - 2 * dir, (uint8_t)(arg1 >> 16), 190a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 191a2b0a27dSPhilippe Mathieu-Daudé } 192a2b0a27dSPhilippe Mathieu-Daudé 193a2b0a27dSPhilippe Mathieu-Daudé if (GET_LMASK64(arg2) >= 3) { 1945b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 - 3 * dir, (uint8_t)(arg1 >> 24), 195a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 196a2b0a27dSPhilippe Mathieu-Daudé } 197a2b0a27dSPhilippe Mathieu-Daudé 198a2b0a27dSPhilippe Mathieu-Daudé if (GET_LMASK64(arg2) >= 4) { 1995b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 - 4 * dir, (uint8_t)(arg1 >> 32), 200a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 201a2b0a27dSPhilippe Mathieu-Daudé } 202a2b0a27dSPhilippe Mathieu-Daudé 203a2b0a27dSPhilippe Mathieu-Daudé if (GET_LMASK64(arg2) >= 5) { 2045b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 - 5 * dir, (uint8_t)(arg1 >> 40), 205a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 206a2b0a27dSPhilippe Mathieu-Daudé } 207a2b0a27dSPhilippe Mathieu-Daudé 208a2b0a27dSPhilippe Mathieu-Daudé if (GET_LMASK64(arg2) >= 6) { 2095b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 - 6 * dir, (uint8_t)(arg1 >> 48), 210a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 211a2b0a27dSPhilippe Mathieu-Daudé } 212a2b0a27dSPhilippe Mathieu-Daudé 213a2b0a27dSPhilippe Mathieu-Daudé if (GET_LMASK64(arg2) == 7) { 2145b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 - 7 * dir, (uint8_t)(arg1 >> 56), 215a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 216a2b0a27dSPhilippe Mathieu-Daudé } 217a2b0a27dSPhilippe Mathieu-Daudé } 218a2b0a27dSPhilippe Mathieu-Daudé #endif /* TARGET_MIPS64 */ 219a2b0a27dSPhilippe Mathieu-Daudé 220a2b0a27dSPhilippe Mathieu-Daudé static const int multiple_regs[] = { 16, 17, 18, 19, 20, 21, 22, 23, 30 }; 221a2b0a27dSPhilippe Mathieu-Daudé 222a2b0a27dSPhilippe Mathieu-Daudé void helper_lwm(CPUMIPSState *env, target_ulong addr, target_ulong reglist, 223a2b0a27dSPhilippe Mathieu-Daudé uint32_t mem_idx) 224a2b0a27dSPhilippe Mathieu-Daudé { 225a2b0a27dSPhilippe Mathieu-Daudé target_ulong base_reglist = reglist & 0xf; 226a2b0a27dSPhilippe Mathieu-Daudé target_ulong do_r31 = reglist & 0x10; 227a2b0a27dSPhilippe Mathieu-Daudé 228a2b0a27dSPhilippe Mathieu-Daudé if (base_reglist > 0 && base_reglist <= ARRAY_SIZE(multiple_regs)) { 229a2b0a27dSPhilippe Mathieu-Daudé target_ulong i; 230a2b0a27dSPhilippe Mathieu-Daudé 231a2b0a27dSPhilippe Mathieu-Daudé for (i = 0; i < base_reglist; i++) { 232a2b0a27dSPhilippe Mathieu-Daudé env->active_tc.gpr[multiple_regs[i]] = 233a2b0a27dSPhilippe Mathieu-Daudé (target_long)cpu_ldl_mmuidx_ra(env, addr, mem_idx, GETPC()); 234a2b0a27dSPhilippe Mathieu-Daudé addr += 4; 235a2b0a27dSPhilippe Mathieu-Daudé } 236a2b0a27dSPhilippe Mathieu-Daudé } 237a2b0a27dSPhilippe Mathieu-Daudé 238a2b0a27dSPhilippe Mathieu-Daudé if (do_r31) { 239a2b0a27dSPhilippe Mathieu-Daudé env->active_tc.gpr[31] = 240a2b0a27dSPhilippe Mathieu-Daudé (target_long)cpu_ldl_mmuidx_ra(env, addr, mem_idx, GETPC()); 241a2b0a27dSPhilippe Mathieu-Daudé } 242a2b0a27dSPhilippe Mathieu-Daudé } 243a2b0a27dSPhilippe Mathieu-Daudé 244a2b0a27dSPhilippe Mathieu-Daudé void helper_swm(CPUMIPSState *env, target_ulong addr, target_ulong reglist, 245a2b0a27dSPhilippe Mathieu-Daudé uint32_t mem_idx) 246a2b0a27dSPhilippe Mathieu-Daudé { 247a2b0a27dSPhilippe Mathieu-Daudé target_ulong base_reglist = reglist & 0xf; 248a2b0a27dSPhilippe Mathieu-Daudé target_ulong do_r31 = reglist & 0x10; 249a2b0a27dSPhilippe Mathieu-Daudé 250a2b0a27dSPhilippe Mathieu-Daudé if (base_reglist > 0 && base_reglist <= ARRAY_SIZE(multiple_regs)) { 251a2b0a27dSPhilippe Mathieu-Daudé target_ulong i; 252a2b0a27dSPhilippe Mathieu-Daudé 253a2b0a27dSPhilippe Mathieu-Daudé for (i = 0; i < base_reglist; i++) { 254a2b0a27dSPhilippe Mathieu-Daudé cpu_stw_mmuidx_ra(env, addr, env->active_tc.gpr[multiple_regs[i]], 255a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 256a2b0a27dSPhilippe Mathieu-Daudé addr += 4; 257a2b0a27dSPhilippe Mathieu-Daudé } 258a2b0a27dSPhilippe Mathieu-Daudé } 259a2b0a27dSPhilippe Mathieu-Daudé 260a2b0a27dSPhilippe Mathieu-Daudé if (do_r31) { 261a2b0a27dSPhilippe Mathieu-Daudé cpu_stw_mmuidx_ra(env, addr, env->active_tc.gpr[31], mem_idx, GETPC()); 262a2b0a27dSPhilippe Mathieu-Daudé } 263a2b0a27dSPhilippe Mathieu-Daudé } 264a2b0a27dSPhilippe Mathieu-Daudé 265a2b0a27dSPhilippe Mathieu-Daudé #if defined(TARGET_MIPS64) 266a2b0a27dSPhilippe Mathieu-Daudé void helper_ldm(CPUMIPSState *env, target_ulong addr, target_ulong reglist, 267a2b0a27dSPhilippe Mathieu-Daudé uint32_t mem_idx) 268a2b0a27dSPhilippe Mathieu-Daudé { 269a2b0a27dSPhilippe Mathieu-Daudé target_ulong base_reglist = reglist & 0xf; 270a2b0a27dSPhilippe Mathieu-Daudé target_ulong do_r31 = reglist & 0x10; 271a2b0a27dSPhilippe Mathieu-Daudé 272a2b0a27dSPhilippe Mathieu-Daudé if (base_reglist > 0 && base_reglist <= ARRAY_SIZE(multiple_regs)) { 273a2b0a27dSPhilippe Mathieu-Daudé target_ulong i; 274a2b0a27dSPhilippe Mathieu-Daudé 275a2b0a27dSPhilippe Mathieu-Daudé for (i = 0; i < base_reglist; i++) { 276a2b0a27dSPhilippe Mathieu-Daudé env->active_tc.gpr[multiple_regs[i]] = 277a2b0a27dSPhilippe Mathieu-Daudé cpu_ldq_mmuidx_ra(env, addr, mem_idx, GETPC()); 278a2b0a27dSPhilippe Mathieu-Daudé addr += 8; 279a2b0a27dSPhilippe Mathieu-Daudé } 280a2b0a27dSPhilippe Mathieu-Daudé } 281a2b0a27dSPhilippe Mathieu-Daudé 282a2b0a27dSPhilippe Mathieu-Daudé if (do_r31) { 283a2b0a27dSPhilippe Mathieu-Daudé env->active_tc.gpr[31] = 284a2b0a27dSPhilippe Mathieu-Daudé cpu_ldq_mmuidx_ra(env, addr, mem_idx, GETPC()); 285a2b0a27dSPhilippe Mathieu-Daudé } 286a2b0a27dSPhilippe Mathieu-Daudé } 287a2b0a27dSPhilippe Mathieu-Daudé 288a2b0a27dSPhilippe Mathieu-Daudé void helper_sdm(CPUMIPSState *env, target_ulong addr, target_ulong reglist, 289a2b0a27dSPhilippe Mathieu-Daudé uint32_t mem_idx) 290a2b0a27dSPhilippe Mathieu-Daudé { 291a2b0a27dSPhilippe Mathieu-Daudé target_ulong base_reglist = reglist & 0xf; 292a2b0a27dSPhilippe Mathieu-Daudé target_ulong do_r31 = reglist & 0x10; 293a2b0a27dSPhilippe Mathieu-Daudé 294a2b0a27dSPhilippe Mathieu-Daudé if (base_reglist > 0 && base_reglist <= ARRAY_SIZE(multiple_regs)) { 295a2b0a27dSPhilippe Mathieu-Daudé target_ulong i; 296a2b0a27dSPhilippe Mathieu-Daudé 297a2b0a27dSPhilippe Mathieu-Daudé for (i = 0; i < base_reglist; i++) { 298a2b0a27dSPhilippe Mathieu-Daudé cpu_stq_mmuidx_ra(env, addr, env->active_tc.gpr[multiple_regs[i]], 299a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 300a2b0a27dSPhilippe Mathieu-Daudé addr += 8; 301a2b0a27dSPhilippe Mathieu-Daudé } 302a2b0a27dSPhilippe Mathieu-Daudé } 303a2b0a27dSPhilippe Mathieu-Daudé 304a2b0a27dSPhilippe Mathieu-Daudé if (do_r31) { 305a2b0a27dSPhilippe Mathieu-Daudé cpu_stq_mmuidx_ra(env, addr, env->active_tc.gpr[31], mem_idx, GETPC()); 306a2b0a27dSPhilippe Mathieu-Daudé } 307a2b0a27dSPhilippe Mathieu-Daudé } 308a2b0a27dSPhilippe Mathieu-Daudé 309a2b0a27dSPhilippe Mathieu-Daudé #endif /* TARGET_MIPS64 */ 310