softmmu_header.h revision 4af48bf7c72ef1e201c64bd475377b5af9d8e8a1
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Software MMU support
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Copyright (c) 2003 Fabrice Bellard
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * This library is free software; you can redistribute it and/or
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * modify it under the terms of the GNU Lesser General Public
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * License as published by the Free Software Foundation; either
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * version 2 of the License, or (at your option) any later version.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * This library is distributed in the hope that it will be useful,
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * but WITHOUT ANY WARRANTY; without even the implied warranty of
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Lesser General Public License for more details.
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * You should have received a copy of the GNU Lesser General Public
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * License along with this library; if not, write to the Free Software
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * a choice of LGPL license versions is made available with the language indicating
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * that LGPLv2 or any later version may be used, or where a choice of which version
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * of the LGPL is applied is otherwise unspecified.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#if (DATA_SIZE <= 4) && (TARGET_LONG_BITS == 32) && defined(__i386__) && \
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync (ACCESS_TYPE < NB_MMU_MODES) && defined(ASM_SOFTMMU) && !defined(VBOX)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
10eaaac806009b8336cc5d746fe5072f6c9f58c0vboxsync asm volatile ("movl %1, %%edx\n"
10eaaac806009b8336cc5d746fe5072f6c9f58c0vboxsync "movl %1, %%eax\n"
c50100d1513854735d4e3593b3b385c007f6d8b6vboxsync "shrl %3, %%edx\n"
2a08e12d5dcc1bb5057a9620e87ad361d41a1c1fvboxsync "andl %4, %%eax\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "andl %2, %%edx\n"
6c83eb6b98d1dd1b1d9795c16801ee2f53d2cc31vboxsync "leal %5(%%edx, %%ebp), %%edx\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "cmpl (%%edx), %%eax\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "movl %1, %%eax\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "movl %6, %%edx\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "call %7\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "movl %%eax, %0\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "addl 12(%%edx), %%eax\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "movzbl (%%eax), %0\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "movzwl (%%eax), %0\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "movl (%%eax), %0\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_read)),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync asm volatile ("movl %1, %%edx\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "movl %1, %%eax\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "shrl %3, %%edx\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "andl %4, %%eax\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "andl %2, %%edx\n"
5eca6b757429b1f1d768e16fba65c485af34319dvboxsync "leal %5(%%edx, %%ebp), %%edx\n"
5eca6b757429b1f1d768e16fba65c485af34319dvboxsync "cmpl (%%edx), %%eax\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "movl %1, %%eax\n"
48d60b042893290a747d3abeda71a3085d9133fdvboxsync "movl %6, %%edx\n"
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync "call %7\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "movsbl %%al, %0\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "movswl %%ax, %0\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "addl 12(%%edx), %%eax\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "movsbl (%%eax), %0\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "movswl (%%eax), %0\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_read)),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE v)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync asm volatile ("movl %0, %%edx\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "movl %0, %%eax\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "shrl %3, %%edx\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "andl %4, %%eax\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "andl %2, %%edx\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "leal %5(%%edx, %%ebp), %%edx\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "cmpl (%%edx), %%eax\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "movl %0, %%eax\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "movzbl %b1, %%edx\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "movzwl %w1, %%edx\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "movl %1, %%edx\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "movl %6, %%ecx\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "call %7\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "addl 8(%%edx), %%eax\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "movb %b1, (%%eax)\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "movw %w1, (%%eax)\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "movl %1, (%%eax)\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_write)),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "m" (*(uint8_t *)&glue(glue(__st, SUFFIX), MMUSUFFIX))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* generic load/store macros */
38b70b2dcb1783801f7580cba797a0c8af4b5326vboxsyncstatic inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync unsigned long physaddr;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync physaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync unsigned long physaddr;
b1c3cdef473df2fbc621d5da81acc82dbfb8a11avboxsync page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
fa92c704624def98d3c4aca86d65182effb98e04vboxsync res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx);
17c6e5e8177d068d1bc6af875d1610718efcfdb4vboxsync physaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
17c6e5e8177d068d1bc6af875d1610718efcfdb4vboxsync res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)physaddr);
b1c3cdef473df2fbc621d5da81acc82dbfb8a11avboxsync/* generic store macro */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE v)
17c6e5e8177d068d1bc6af875d1610718efcfdb4vboxsync unsigned long physaddr;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (unlikely(env->tlb_table[mmu_idx][page_index].addr_write !=
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, mmu_idx);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync physaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, v);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif /* !asm */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic inline float64 glue(ldfq, MEMSUFFIX)(target_ulong ptr)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return u.d;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic inline void glue(stfq, MEMSUFFIX)(target_ulong ptr, float64 v)
5eca6b757429b1f1d768e16fba65c485af34319dvboxsync#endif /* DATA_SIZE == 8 */
940dbfa4936f2e3966e9e874c4886709f0c75b44vboxsyncstatic inline float32 glue(ldfl, MEMSUFFIX)(target_ulong ptr)
5eca6b757429b1f1d768e16fba65c485af34319dvboxsync return u.f;
5eca6b757429b1f1d768e16fba65c485af34319dvboxsyncstatic inline void glue(stfl, MEMSUFFIX)(target_ulong ptr, float32 v)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif /* DATA_SIZE == 4 */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */