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" 27*09b07f28SPhilippe 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é 565b3cc34cSPhilippe Mathieu-Daudé static inline bool cpu_is_bigendian(CPUMIPSState *env) 575b3cc34cSPhilippe Mathieu-Daudé { 585b3cc34cSPhilippe Mathieu-Daudé return extract32(env->CP0_Config0, CP0C0_BE, 1); 595b3cc34cSPhilippe Mathieu-Daudé } 605b3cc34cSPhilippe Mathieu-Daudé 614885b99aSPhilippe Mathieu-Daudé static inline target_ulong get_lmask(CPUMIPSState *env, 624885b99aSPhilippe Mathieu-Daudé target_ulong value, unsigned bits) 634885b99aSPhilippe Mathieu-Daudé { 644885b99aSPhilippe Mathieu-Daudé unsigned mask = (bits / BITS_PER_BYTE) - 1; 654885b99aSPhilippe Mathieu-Daudé 664885b99aSPhilippe Mathieu-Daudé value &= mask; 674885b99aSPhilippe Mathieu-Daudé 684885b99aSPhilippe Mathieu-Daudé if (!cpu_is_bigendian(env)) { 694885b99aSPhilippe Mathieu-Daudé value ^= mask; 704885b99aSPhilippe Mathieu-Daudé } 714885b99aSPhilippe Mathieu-Daudé 724885b99aSPhilippe Mathieu-Daudé return value; 734885b99aSPhilippe Mathieu-Daudé } 74a2b0a27dSPhilippe Mathieu-Daudé 75a2b0a27dSPhilippe Mathieu-Daudé void helper_swl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2, 76a2b0a27dSPhilippe Mathieu-Daudé int mem_idx) 77a2b0a27dSPhilippe Mathieu-Daudé { 784885b99aSPhilippe Mathieu-Daudé target_ulong lmask = get_lmask(env, arg2, 32); 795b3cc34cSPhilippe Mathieu-Daudé int dir = cpu_is_bigendian(env) ? 1 : -1; 805b3cc34cSPhilippe Mathieu-Daudé 81a2b0a27dSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2, (uint8_t)(arg1 >> 24), mem_idx, GETPC()); 82a2b0a27dSPhilippe Mathieu-Daudé 834885b99aSPhilippe Mathieu-Daudé if (lmask <= 2) { 845b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 + 1 * dir, (uint8_t)(arg1 >> 16), 85a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 86a2b0a27dSPhilippe Mathieu-Daudé } 87a2b0a27dSPhilippe Mathieu-Daudé 884885b99aSPhilippe Mathieu-Daudé if (lmask <= 1) { 895b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 + 2 * dir, (uint8_t)(arg1 >> 8), 90a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 91a2b0a27dSPhilippe Mathieu-Daudé } 92a2b0a27dSPhilippe Mathieu-Daudé 934885b99aSPhilippe Mathieu-Daudé if (lmask == 0) { 945b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 + 3 * dir, (uint8_t)arg1, 95a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 96a2b0a27dSPhilippe Mathieu-Daudé } 97a2b0a27dSPhilippe Mathieu-Daudé } 98a2b0a27dSPhilippe Mathieu-Daudé 99a2b0a27dSPhilippe Mathieu-Daudé void helper_swr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2, 100a2b0a27dSPhilippe Mathieu-Daudé int mem_idx) 101a2b0a27dSPhilippe Mathieu-Daudé { 1024885b99aSPhilippe Mathieu-Daudé target_ulong lmask = get_lmask(env, arg2, 32); 1035b3cc34cSPhilippe Mathieu-Daudé int dir = cpu_is_bigendian(env) ? 1 : -1; 1045b3cc34cSPhilippe Mathieu-Daudé 105a2b0a27dSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2, (uint8_t)arg1, mem_idx, GETPC()); 106a2b0a27dSPhilippe Mathieu-Daudé 1074885b99aSPhilippe Mathieu-Daudé if (lmask >= 1) { 1085b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 - 1 * dir, (uint8_t)(arg1 >> 8), 109a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 110a2b0a27dSPhilippe Mathieu-Daudé } 111a2b0a27dSPhilippe Mathieu-Daudé 1124885b99aSPhilippe Mathieu-Daudé if (lmask >= 2) { 1135b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 - 2 * dir, (uint8_t)(arg1 >> 16), 114a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 115a2b0a27dSPhilippe Mathieu-Daudé } 116a2b0a27dSPhilippe Mathieu-Daudé 1174885b99aSPhilippe Mathieu-Daudé if (lmask == 3) { 1185b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 - 3 * dir, (uint8_t)(arg1 >> 24), 119a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 120a2b0a27dSPhilippe Mathieu-Daudé } 121a2b0a27dSPhilippe Mathieu-Daudé } 122a2b0a27dSPhilippe Mathieu-Daudé 123a2b0a27dSPhilippe Mathieu-Daudé #if defined(TARGET_MIPS64) 124a2b0a27dSPhilippe Mathieu-Daudé /* 125a2b0a27dSPhilippe Mathieu-Daudé * "half" load and stores. We must do the memory access inline, 126a2b0a27dSPhilippe Mathieu-Daudé * or fault handling won't work. 127a2b0a27dSPhilippe Mathieu-Daudé */ 128a2b0a27dSPhilippe Mathieu-Daudé 129a2b0a27dSPhilippe Mathieu-Daudé void helper_sdl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2, 130a2b0a27dSPhilippe Mathieu-Daudé int mem_idx) 131a2b0a27dSPhilippe Mathieu-Daudé { 13223a04dcdSPhilippe Mathieu-Daudé target_ulong lmask = get_lmask(env, arg2, 64); 1335b3cc34cSPhilippe Mathieu-Daudé int dir = cpu_is_bigendian(env) ? 1 : -1; 1345b3cc34cSPhilippe Mathieu-Daudé 135a2b0a27dSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2, (uint8_t)(arg1 >> 56), mem_idx, GETPC()); 136a2b0a27dSPhilippe Mathieu-Daudé 13723a04dcdSPhilippe Mathieu-Daudé if (lmask <= 6) { 1385b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 + 1 * dir, (uint8_t)(arg1 >> 48), 139a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 140a2b0a27dSPhilippe Mathieu-Daudé } 141a2b0a27dSPhilippe Mathieu-Daudé 14223a04dcdSPhilippe Mathieu-Daudé if (lmask <= 5) { 1435b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 + 2 * dir, (uint8_t)(arg1 >> 40), 144a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 145a2b0a27dSPhilippe Mathieu-Daudé } 146a2b0a27dSPhilippe Mathieu-Daudé 14723a04dcdSPhilippe Mathieu-Daudé if (lmask <= 4) { 1485b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 + 3 * dir, (uint8_t)(arg1 >> 32), 149a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 150a2b0a27dSPhilippe Mathieu-Daudé } 151a2b0a27dSPhilippe Mathieu-Daudé 15223a04dcdSPhilippe Mathieu-Daudé if (lmask <= 3) { 1535b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 + 4 * dir, (uint8_t)(arg1 >> 24), 154a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 155a2b0a27dSPhilippe Mathieu-Daudé } 156a2b0a27dSPhilippe Mathieu-Daudé 15723a04dcdSPhilippe Mathieu-Daudé if (lmask <= 2) { 1585b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 + 5 * dir, (uint8_t)(arg1 >> 16), 159a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 160a2b0a27dSPhilippe Mathieu-Daudé } 161a2b0a27dSPhilippe Mathieu-Daudé 16223a04dcdSPhilippe Mathieu-Daudé if (lmask <= 1) { 1635b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 + 6 * dir, (uint8_t)(arg1 >> 8), 164a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 165a2b0a27dSPhilippe Mathieu-Daudé } 166a2b0a27dSPhilippe Mathieu-Daudé 16723a04dcdSPhilippe Mathieu-Daudé if (lmask <= 0) { 1685b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 + 7 * dir, (uint8_t)arg1, 169a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 170a2b0a27dSPhilippe Mathieu-Daudé } 171a2b0a27dSPhilippe Mathieu-Daudé } 172a2b0a27dSPhilippe Mathieu-Daudé 173a2b0a27dSPhilippe Mathieu-Daudé void helper_sdr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2, 174a2b0a27dSPhilippe Mathieu-Daudé int mem_idx) 175a2b0a27dSPhilippe Mathieu-Daudé { 17623a04dcdSPhilippe Mathieu-Daudé target_ulong lmask = get_lmask(env, arg2, 64); 1775b3cc34cSPhilippe Mathieu-Daudé int dir = cpu_is_bigendian(env) ? 1 : -1; 1785b3cc34cSPhilippe Mathieu-Daudé 179a2b0a27dSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2, (uint8_t)arg1, mem_idx, GETPC()); 180a2b0a27dSPhilippe Mathieu-Daudé 18123a04dcdSPhilippe Mathieu-Daudé if (lmask >= 1) { 1825b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 - 1 * dir, (uint8_t)(arg1 >> 8), 183a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 184a2b0a27dSPhilippe Mathieu-Daudé } 185a2b0a27dSPhilippe Mathieu-Daudé 18623a04dcdSPhilippe Mathieu-Daudé if (lmask >= 2) { 1875b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 - 2 * dir, (uint8_t)(arg1 >> 16), 188a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 189a2b0a27dSPhilippe Mathieu-Daudé } 190a2b0a27dSPhilippe Mathieu-Daudé 19123a04dcdSPhilippe Mathieu-Daudé if (lmask >= 3) { 1925b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 - 3 * dir, (uint8_t)(arg1 >> 24), 193a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 194a2b0a27dSPhilippe Mathieu-Daudé } 195a2b0a27dSPhilippe Mathieu-Daudé 19623a04dcdSPhilippe Mathieu-Daudé if (lmask >= 4) { 1975b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 - 4 * dir, (uint8_t)(arg1 >> 32), 198a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 199a2b0a27dSPhilippe Mathieu-Daudé } 200a2b0a27dSPhilippe Mathieu-Daudé 20123a04dcdSPhilippe Mathieu-Daudé if (lmask >= 5) { 2025b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 - 5 * dir, (uint8_t)(arg1 >> 40), 203a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 204a2b0a27dSPhilippe Mathieu-Daudé } 205a2b0a27dSPhilippe Mathieu-Daudé 20623a04dcdSPhilippe Mathieu-Daudé if (lmask >= 6) { 2075b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 - 6 * dir, (uint8_t)(arg1 >> 48), 208a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 209a2b0a27dSPhilippe Mathieu-Daudé } 210a2b0a27dSPhilippe Mathieu-Daudé 21123a04dcdSPhilippe Mathieu-Daudé if (lmask == 7) { 2125b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 - 7 * dir, (uint8_t)(arg1 >> 56), 213a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 214a2b0a27dSPhilippe Mathieu-Daudé } 215a2b0a27dSPhilippe Mathieu-Daudé } 216a2b0a27dSPhilippe Mathieu-Daudé #endif /* TARGET_MIPS64 */ 217a2b0a27dSPhilippe Mathieu-Daudé 218a2b0a27dSPhilippe Mathieu-Daudé static const int multiple_regs[] = { 16, 17, 18, 19, 20, 21, 22, 23, 30 }; 219a2b0a27dSPhilippe Mathieu-Daudé 220a2b0a27dSPhilippe Mathieu-Daudé void helper_lwm(CPUMIPSState *env, target_ulong addr, target_ulong reglist, 221a2b0a27dSPhilippe Mathieu-Daudé uint32_t mem_idx) 222a2b0a27dSPhilippe Mathieu-Daudé { 223a2b0a27dSPhilippe Mathieu-Daudé target_ulong base_reglist = reglist & 0xf; 224a2b0a27dSPhilippe Mathieu-Daudé target_ulong do_r31 = reglist & 0x10; 225a2b0a27dSPhilippe Mathieu-Daudé 226a2b0a27dSPhilippe Mathieu-Daudé if (base_reglist > 0 && base_reglist <= ARRAY_SIZE(multiple_regs)) { 227a2b0a27dSPhilippe Mathieu-Daudé target_ulong i; 228a2b0a27dSPhilippe Mathieu-Daudé 229a2b0a27dSPhilippe Mathieu-Daudé for (i = 0; i < base_reglist; i++) { 230a2b0a27dSPhilippe Mathieu-Daudé env->active_tc.gpr[multiple_regs[i]] = 231a2b0a27dSPhilippe Mathieu-Daudé (target_long)cpu_ldl_mmuidx_ra(env, addr, mem_idx, GETPC()); 232a2b0a27dSPhilippe Mathieu-Daudé addr += 4; 233a2b0a27dSPhilippe Mathieu-Daudé } 234a2b0a27dSPhilippe Mathieu-Daudé } 235a2b0a27dSPhilippe Mathieu-Daudé 236a2b0a27dSPhilippe Mathieu-Daudé if (do_r31) { 237a2b0a27dSPhilippe Mathieu-Daudé env->active_tc.gpr[31] = 238a2b0a27dSPhilippe Mathieu-Daudé (target_long)cpu_ldl_mmuidx_ra(env, addr, mem_idx, GETPC()); 239a2b0a27dSPhilippe Mathieu-Daudé } 240a2b0a27dSPhilippe Mathieu-Daudé } 241a2b0a27dSPhilippe Mathieu-Daudé 242a2b0a27dSPhilippe Mathieu-Daudé void helper_swm(CPUMIPSState *env, target_ulong addr, target_ulong reglist, 243a2b0a27dSPhilippe Mathieu-Daudé uint32_t mem_idx) 244a2b0a27dSPhilippe Mathieu-Daudé { 245a2b0a27dSPhilippe Mathieu-Daudé target_ulong base_reglist = reglist & 0xf; 246a2b0a27dSPhilippe Mathieu-Daudé target_ulong do_r31 = reglist & 0x10; 247a2b0a27dSPhilippe Mathieu-Daudé 248a2b0a27dSPhilippe Mathieu-Daudé if (base_reglist > 0 && base_reglist <= ARRAY_SIZE(multiple_regs)) { 249a2b0a27dSPhilippe Mathieu-Daudé target_ulong i; 250a2b0a27dSPhilippe Mathieu-Daudé 251a2b0a27dSPhilippe Mathieu-Daudé for (i = 0; i < base_reglist; i++) { 2527c00edb9SMarcin Nowakowski cpu_stl_mmuidx_ra(env, addr, env->active_tc.gpr[multiple_regs[i]], 253a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 254a2b0a27dSPhilippe Mathieu-Daudé addr += 4; 255a2b0a27dSPhilippe Mathieu-Daudé } 256a2b0a27dSPhilippe Mathieu-Daudé } 257a2b0a27dSPhilippe Mathieu-Daudé 258a2b0a27dSPhilippe Mathieu-Daudé if (do_r31) { 2597c00edb9SMarcin Nowakowski cpu_stl_mmuidx_ra(env, addr, env->active_tc.gpr[31], mem_idx, GETPC()); 260a2b0a27dSPhilippe Mathieu-Daudé } 261a2b0a27dSPhilippe Mathieu-Daudé } 262a2b0a27dSPhilippe Mathieu-Daudé 263a2b0a27dSPhilippe Mathieu-Daudé #if defined(TARGET_MIPS64) 264a2b0a27dSPhilippe Mathieu-Daudé void helper_ldm(CPUMIPSState *env, target_ulong addr, target_ulong reglist, 265a2b0a27dSPhilippe Mathieu-Daudé uint32_t mem_idx) 266a2b0a27dSPhilippe Mathieu-Daudé { 267a2b0a27dSPhilippe Mathieu-Daudé target_ulong base_reglist = reglist & 0xf; 268a2b0a27dSPhilippe Mathieu-Daudé target_ulong do_r31 = reglist & 0x10; 269a2b0a27dSPhilippe Mathieu-Daudé 270a2b0a27dSPhilippe Mathieu-Daudé if (base_reglist > 0 && base_reglist <= ARRAY_SIZE(multiple_regs)) { 271a2b0a27dSPhilippe Mathieu-Daudé target_ulong i; 272a2b0a27dSPhilippe Mathieu-Daudé 273a2b0a27dSPhilippe Mathieu-Daudé for (i = 0; i < base_reglist; i++) { 274a2b0a27dSPhilippe Mathieu-Daudé env->active_tc.gpr[multiple_regs[i]] = 275a2b0a27dSPhilippe Mathieu-Daudé cpu_ldq_mmuidx_ra(env, addr, mem_idx, GETPC()); 276a2b0a27dSPhilippe Mathieu-Daudé addr += 8; 277a2b0a27dSPhilippe Mathieu-Daudé } 278a2b0a27dSPhilippe Mathieu-Daudé } 279a2b0a27dSPhilippe Mathieu-Daudé 280a2b0a27dSPhilippe Mathieu-Daudé if (do_r31) { 281a2b0a27dSPhilippe Mathieu-Daudé env->active_tc.gpr[31] = 282a2b0a27dSPhilippe Mathieu-Daudé cpu_ldq_mmuidx_ra(env, addr, mem_idx, GETPC()); 283a2b0a27dSPhilippe Mathieu-Daudé } 284a2b0a27dSPhilippe Mathieu-Daudé } 285a2b0a27dSPhilippe Mathieu-Daudé 286a2b0a27dSPhilippe Mathieu-Daudé void helper_sdm(CPUMIPSState *env, target_ulong addr, target_ulong reglist, 287a2b0a27dSPhilippe Mathieu-Daudé uint32_t mem_idx) 288a2b0a27dSPhilippe Mathieu-Daudé { 289a2b0a27dSPhilippe Mathieu-Daudé target_ulong base_reglist = reglist & 0xf; 290a2b0a27dSPhilippe Mathieu-Daudé target_ulong do_r31 = reglist & 0x10; 291a2b0a27dSPhilippe Mathieu-Daudé 292a2b0a27dSPhilippe Mathieu-Daudé if (base_reglist > 0 && base_reglist <= ARRAY_SIZE(multiple_regs)) { 293a2b0a27dSPhilippe Mathieu-Daudé target_ulong i; 294a2b0a27dSPhilippe Mathieu-Daudé 295a2b0a27dSPhilippe Mathieu-Daudé for (i = 0; i < base_reglist; i++) { 296a2b0a27dSPhilippe Mathieu-Daudé cpu_stq_mmuidx_ra(env, addr, env->active_tc.gpr[multiple_regs[i]], 297a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 298a2b0a27dSPhilippe Mathieu-Daudé addr += 8; 299a2b0a27dSPhilippe Mathieu-Daudé } 300a2b0a27dSPhilippe Mathieu-Daudé } 301a2b0a27dSPhilippe Mathieu-Daudé 302a2b0a27dSPhilippe Mathieu-Daudé if (do_r31) { 303a2b0a27dSPhilippe Mathieu-Daudé cpu_stq_mmuidx_ra(env, addr, env->active_tc.gpr[31], mem_idx, GETPC()); 304a2b0a27dSPhilippe Mathieu-Daudé } 305a2b0a27dSPhilippe Mathieu-Daudé } 306a2b0a27dSPhilippe Mathieu-Daudé 307a2b0a27dSPhilippe Mathieu-Daudé #endif /* TARGET_MIPS64 */ 308