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é 604885b99aSPhilippe Mathieu-Daudé static inline target_ulong get_lmask(CPUMIPSState *env, 614885b99aSPhilippe Mathieu-Daudé target_ulong value, unsigned bits) 624885b99aSPhilippe Mathieu-Daudé { 634885b99aSPhilippe Mathieu-Daudé unsigned mask = (bits / BITS_PER_BYTE) - 1; 644885b99aSPhilippe Mathieu-Daudé 654885b99aSPhilippe Mathieu-Daudé value &= mask; 664885b99aSPhilippe Mathieu-Daudé 674885b99aSPhilippe Mathieu-Daudé if (!cpu_is_bigendian(env)) { 684885b99aSPhilippe Mathieu-Daudé value ^= mask; 694885b99aSPhilippe Mathieu-Daudé } 704885b99aSPhilippe Mathieu-Daudé 714885b99aSPhilippe Mathieu-Daudé return value; 724885b99aSPhilippe 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é { 774885b99aSPhilippe 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é 824885b99aSPhilippe 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é 874885b99aSPhilippe 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é 924885b99aSPhilippe 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é { 1014885b99aSPhilippe 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é 1064885b99aSPhilippe 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é 1114885b99aSPhilippe 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é 1164885b99aSPhilippe 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é 128a2b0a27dSPhilippe Mathieu-Daudé void helper_sdl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2, 129a2b0a27dSPhilippe Mathieu-Daudé int mem_idx) 130a2b0a27dSPhilippe Mathieu-Daudé { 131*23a04dcdSPhilippe Mathieu-Daudé target_ulong lmask = get_lmask(env, arg2, 64); 1325b3cc34cSPhilippe Mathieu-Daudé int dir = cpu_is_bigendian(env) ? 1 : -1; 1335b3cc34cSPhilippe Mathieu-Daudé 134a2b0a27dSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2, (uint8_t)(arg1 >> 56), mem_idx, GETPC()); 135a2b0a27dSPhilippe Mathieu-Daudé 136*23a04dcdSPhilippe Mathieu-Daudé if (lmask <= 6) { 1375b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 + 1 * dir, (uint8_t)(arg1 >> 48), 138a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 139a2b0a27dSPhilippe Mathieu-Daudé } 140a2b0a27dSPhilippe Mathieu-Daudé 141*23a04dcdSPhilippe Mathieu-Daudé if (lmask <= 5) { 1425b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 + 2 * dir, (uint8_t)(arg1 >> 40), 143a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 144a2b0a27dSPhilippe Mathieu-Daudé } 145a2b0a27dSPhilippe Mathieu-Daudé 146*23a04dcdSPhilippe Mathieu-Daudé if (lmask <= 4) { 1475b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 + 3 * dir, (uint8_t)(arg1 >> 32), 148a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 149a2b0a27dSPhilippe Mathieu-Daudé } 150a2b0a27dSPhilippe Mathieu-Daudé 151*23a04dcdSPhilippe Mathieu-Daudé if (lmask <= 3) { 1525b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 + 4 * dir, (uint8_t)(arg1 >> 24), 153a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 154a2b0a27dSPhilippe Mathieu-Daudé } 155a2b0a27dSPhilippe Mathieu-Daudé 156*23a04dcdSPhilippe Mathieu-Daudé if (lmask <= 2) { 1575b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 + 5 * dir, (uint8_t)(arg1 >> 16), 158a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 159a2b0a27dSPhilippe Mathieu-Daudé } 160a2b0a27dSPhilippe Mathieu-Daudé 161*23a04dcdSPhilippe Mathieu-Daudé if (lmask <= 1) { 1625b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 + 6 * dir, (uint8_t)(arg1 >> 8), 163a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 164a2b0a27dSPhilippe Mathieu-Daudé } 165a2b0a27dSPhilippe Mathieu-Daudé 166*23a04dcdSPhilippe Mathieu-Daudé if (lmask <= 0) { 1675b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 + 7 * dir, (uint8_t)arg1, 168a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 169a2b0a27dSPhilippe Mathieu-Daudé } 170a2b0a27dSPhilippe Mathieu-Daudé } 171a2b0a27dSPhilippe Mathieu-Daudé 172a2b0a27dSPhilippe Mathieu-Daudé void helper_sdr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2, 173a2b0a27dSPhilippe Mathieu-Daudé int mem_idx) 174a2b0a27dSPhilippe Mathieu-Daudé { 175*23a04dcdSPhilippe Mathieu-Daudé target_ulong lmask = get_lmask(env, arg2, 64); 1765b3cc34cSPhilippe Mathieu-Daudé int dir = cpu_is_bigendian(env) ? 1 : -1; 1775b3cc34cSPhilippe Mathieu-Daudé 178a2b0a27dSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2, (uint8_t)arg1, mem_idx, GETPC()); 179a2b0a27dSPhilippe Mathieu-Daudé 180*23a04dcdSPhilippe Mathieu-Daudé if (lmask >= 1) { 1815b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 - 1 * dir, (uint8_t)(arg1 >> 8), 182a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 183a2b0a27dSPhilippe Mathieu-Daudé } 184a2b0a27dSPhilippe Mathieu-Daudé 185*23a04dcdSPhilippe Mathieu-Daudé if (lmask >= 2) { 1865b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 - 2 * dir, (uint8_t)(arg1 >> 16), 187a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 188a2b0a27dSPhilippe Mathieu-Daudé } 189a2b0a27dSPhilippe Mathieu-Daudé 190*23a04dcdSPhilippe Mathieu-Daudé if (lmask >= 3) { 1915b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 - 3 * dir, (uint8_t)(arg1 >> 24), 192a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 193a2b0a27dSPhilippe Mathieu-Daudé } 194a2b0a27dSPhilippe Mathieu-Daudé 195*23a04dcdSPhilippe Mathieu-Daudé if (lmask >= 4) { 1965b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 - 4 * dir, (uint8_t)(arg1 >> 32), 197a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 198a2b0a27dSPhilippe Mathieu-Daudé } 199a2b0a27dSPhilippe Mathieu-Daudé 200*23a04dcdSPhilippe Mathieu-Daudé if (lmask >= 5) { 2015b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 - 5 * dir, (uint8_t)(arg1 >> 40), 202a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 203a2b0a27dSPhilippe Mathieu-Daudé } 204a2b0a27dSPhilippe Mathieu-Daudé 205*23a04dcdSPhilippe Mathieu-Daudé if (lmask >= 6) { 2065b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 - 6 * dir, (uint8_t)(arg1 >> 48), 207a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 208a2b0a27dSPhilippe Mathieu-Daudé } 209a2b0a27dSPhilippe Mathieu-Daudé 210*23a04dcdSPhilippe Mathieu-Daudé if (lmask == 7) { 2115b3cc34cSPhilippe Mathieu-Daudé cpu_stb_mmuidx_ra(env, arg2 - 7 * dir, (uint8_t)(arg1 >> 56), 212a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 213a2b0a27dSPhilippe Mathieu-Daudé } 214a2b0a27dSPhilippe Mathieu-Daudé } 215a2b0a27dSPhilippe Mathieu-Daudé #endif /* TARGET_MIPS64 */ 216a2b0a27dSPhilippe Mathieu-Daudé 217a2b0a27dSPhilippe Mathieu-Daudé static const int multiple_regs[] = { 16, 17, 18, 19, 20, 21, 22, 23, 30 }; 218a2b0a27dSPhilippe Mathieu-Daudé 219a2b0a27dSPhilippe Mathieu-Daudé void helper_lwm(CPUMIPSState *env, target_ulong addr, target_ulong reglist, 220a2b0a27dSPhilippe Mathieu-Daudé uint32_t mem_idx) 221a2b0a27dSPhilippe Mathieu-Daudé { 222a2b0a27dSPhilippe Mathieu-Daudé target_ulong base_reglist = reglist & 0xf; 223a2b0a27dSPhilippe Mathieu-Daudé target_ulong do_r31 = reglist & 0x10; 224a2b0a27dSPhilippe Mathieu-Daudé 225a2b0a27dSPhilippe Mathieu-Daudé if (base_reglist > 0 && base_reglist <= ARRAY_SIZE(multiple_regs)) { 226a2b0a27dSPhilippe Mathieu-Daudé target_ulong i; 227a2b0a27dSPhilippe Mathieu-Daudé 228a2b0a27dSPhilippe Mathieu-Daudé for (i = 0; i < base_reglist; i++) { 229a2b0a27dSPhilippe Mathieu-Daudé env->active_tc.gpr[multiple_regs[i]] = 230a2b0a27dSPhilippe Mathieu-Daudé (target_long)cpu_ldl_mmuidx_ra(env, addr, mem_idx, GETPC()); 231a2b0a27dSPhilippe Mathieu-Daudé addr += 4; 232a2b0a27dSPhilippe Mathieu-Daudé } 233a2b0a27dSPhilippe Mathieu-Daudé } 234a2b0a27dSPhilippe Mathieu-Daudé 235a2b0a27dSPhilippe Mathieu-Daudé if (do_r31) { 236a2b0a27dSPhilippe Mathieu-Daudé env->active_tc.gpr[31] = 237a2b0a27dSPhilippe Mathieu-Daudé (target_long)cpu_ldl_mmuidx_ra(env, addr, mem_idx, GETPC()); 238a2b0a27dSPhilippe Mathieu-Daudé } 239a2b0a27dSPhilippe Mathieu-Daudé } 240a2b0a27dSPhilippe Mathieu-Daudé 241a2b0a27dSPhilippe Mathieu-Daudé void helper_swm(CPUMIPSState *env, target_ulong addr, target_ulong reglist, 242a2b0a27dSPhilippe Mathieu-Daudé uint32_t mem_idx) 243a2b0a27dSPhilippe Mathieu-Daudé { 244a2b0a27dSPhilippe Mathieu-Daudé target_ulong base_reglist = reglist & 0xf; 245a2b0a27dSPhilippe Mathieu-Daudé target_ulong do_r31 = reglist & 0x10; 246a2b0a27dSPhilippe Mathieu-Daudé 247a2b0a27dSPhilippe Mathieu-Daudé if (base_reglist > 0 && base_reglist <= ARRAY_SIZE(multiple_regs)) { 248a2b0a27dSPhilippe Mathieu-Daudé target_ulong i; 249a2b0a27dSPhilippe Mathieu-Daudé 250a2b0a27dSPhilippe Mathieu-Daudé for (i = 0; i < base_reglist; i++) { 251a2b0a27dSPhilippe Mathieu-Daudé cpu_stw_mmuidx_ra(env, addr, env->active_tc.gpr[multiple_regs[i]], 252a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 253a2b0a27dSPhilippe Mathieu-Daudé addr += 4; 254a2b0a27dSPhilippe Mathieu-Daudé } 255a2b0a27dSPhilippe Mathieu-Daudé } 256a2b0a27dSPhilippe Mathieu-Daudé 257a2b0a27dSPhilippe Mathieu-Daudé if (do_r31) { 258a2b0a27dSPhilippe Mathieu-Daudé cpu_stw_mmuidx_ra(env, addr, env->active_tc.gpr[31], mem_idx, GETPC()); 259a2b0a27dSPhilippe Mathieu-Daudé } 260a2b0a27dSPhilippe Mathieu-Daudé } 261a2b0a27dSPhilippe Mathieu-Daudé 262a2b0a27dSPhilippe Mathieu-Daudé #if defined(TARGET_MIPS64) 263a2b0a27dSPhilippe Mathieu-Daudé void helper_ldm(CPUMIPSState *env, target_ulong addr, target_ulong reglist, 264a2b0a27dSPhilippe Mathieu-Daudé uint32_t mem_idx) 265a2b0a27dSPhilippe Mathieu-Daudé { 266a2b0a27dSPhilippe Mathieu-Daudé target_ulong base_reglist = reglist & 0xf; 267a2b0a27dSPhilippe Mathieu-Daudé target_ulong do_r31 = reglist & 0x10; 268a2b0a27dSPhilippe Mathieu-Daudé 269a2b0a27dSPhilippe Mathieu-Daudé if (base_reglist > 0 && base_reglist <= ARRAY_SIZE(multiple_regs)) { 270a2b0a27dSPhilippe Mathieu-Daudé target_ulong i; 271a2b0a27dSPhilippe Mathieu-Daudé 272a2b0a27dSPhilippe Mathieu-Daudé for (i = 0; i < base_reglist; i++) { 273a2b0a27dSPhilippe Mathieu-Daudé env->active_tc.gpr[multiple_regs[i]] = 274a2b0a27dSPhilippe Mathieu-Daudé cpu_ldq_mmuidx_ra(env, addr, mem_idx, GETPC()); 275a2b0a27dSPhilippe Mathieu-Daudé addr += 8; 276a2b0a27dSPhilippe Mathieu-Daudé } 277a2b0a27dSPhilippe Mathieu-Daudé } 278a2b0a27dSPhilippe Mathieu-Daudé 279a2b0a27dSPhilippe Mathieu-Daudé if (do_r31) { 280a2b0a27dSPhilippe Mathieu-Daudé env->active_tc.gpr[31] = 281a2b0a27dSPhilippe Mathieu-Daudé cpu_ldq_mmuidx_ra(env, addr, mem_idx, GETPC()); 282a2b0a27dSPhilippe Mathieu-Daudé } 283a2b0a27dSPhilippe Mathieu-Daudé } 284a2b0a27dSPhilippe Mathieu-Daudé 285a2b0a27dSPhilippe Mathieu-Daudé void helper_sdm(CPUMIPSState *env, target_ulong addr, target_ulong reglist, 286a2b0a27dSPhilippe Mathieu-Daudé uint32_t mem_idx) 287a2b0a27dSPhilippe Mathieu-Daudé { 288a2b0a27dSPhilippe Mathieu-Daudé target_ulong base_reglist = reglist & 0xf; 289a2b0a27dSPhilippe Mathieu-Daudé target_ulong do_r31 = reglist & 0x10; 290a2b0a27dSPhilippe Mathieu-Daudé 291a2b0a27dSPhilippe Mathieu-Daudé if (base_reglist > 0 && base_reglist <= ARRAY_SIZE(multiple_regs)) { 292a2b0a27dSPhilippe Mathieu-Daudé target_ulong i; 293a2b0a27dSPhilippe Mathieu-Daudé 294a2b0a27dSPhilippe Mathieu-Daudé for (i = 0; i < base_reglist; i++) { 295a2b0a27dSPhilippe Mathieu-Daudé cpu_stq_mmuidx_ra(env, addr, env->active_tc.gpr[multiple_regs[i]], 296a2b0a27dSPhilippe Mathieu-Daudé mem_idx, GETPC()); 297a2b0a27dSPhilippe Mathieu-Daudé addr += 8; 298a2b0a27dSPhilippe Mathieu-Daudé } 299a2b0a27dSPhilippe Mathieu-Daudé } 300a2b0a27dSPhilippe Mathieu-Daudé 301a2b0a27dSPhilippe Mathieu-Daudé if (do_r31) { 302a2b0a27dSPhilippe Mathieu-Daudé cpu_stq_mmuidx_ra(env, addr, env->active_tc.gpr[31], mem_idx, GETPC()); 303a2b0a27dSPhilippe Mathieu-Daudé } 304a2b0a27dSPhilippe Mathieu-Daudé } 305a2b0a27dSPhilippe Mathieu-Daudé 306a2b0a27dSPhilippe Mathieu-Daudé #endif /* TARGET_MIPS64 */ 307