| 
									
										
										
										
											2003-08-08 23:58:05 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  *  Software MMU support | 
					
						
							| 
									
										
										
										
											2007-09-16 21:08:06 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2003-08-08 23:58:05 +00:00
										 |  |  |  *  Copyright (c) 2003 Fabrice Bellard | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This library is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU Lesser General Public | 
					
						
							|  |  |  |  * License as published by the Free Software Foundation; either | 
					
						
							|  |  |  |  * version 2 of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This library is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
					
						
							|  |  |  |  * Lesser General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU Lesser General Public | 
					
						
							|  |  |  |  * License along with this library; if not, write to the Free Software | 
					
						
							| 
									
										
										
										
											2009-01-04 22:05:52 +00:00
										 |  |  |  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA | 
					
						
							| 
									
										
										
										
											2003-08-08 23:58:05 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | #if DATA_SIZE == 8
 | 
					
						
							|  |  |  | #define SUFFIX q
 | 
					
						
							| 
									
										
										
										
											2003-10-27 21:22:23 +00:00
										 |  |  | #define USUFFIX q
 | 
					
						
							| 
									
										
										
										
											2003-08-08 23:58:05 +00:00
										 |  |  | #define DATA_TYPE uint64_t
 | 
					
						
							|  |  |  | #elif DATA_SIZE == 4
 | 
					
						
							|  |  |  | #define SUFFIX l
 | 
					
						
							| 
									
										
										
										
											2003-10-27 21:22:23 +00:00
										 |  |  | #define USUFFIX l
 | 
					
						
							| 
									
										
										
										
											2003-08-08 23:58:05 +00:00
										 |  |  | #define DATA_TYPE uint32_t
 | 
					
						
							|  |  |  | #elif DATA_SIZE == 2
 | 
					
						
							|  |  |  | #define SUFFIX w
 | 
					
						
							| 
									
										
										
										
											2003-10-27 21:22:23 +00:00
										 |  |  | #define USUFFIX uw
 | 
					
						
							| 
									
										
										
										
											2003-08-08 23:58:05 +00:00
										 |  |  | #define DATA_TYPE uint16_t
 | 
					
						
							|  |  |  | #define DATA_STYPE int16_t
 | 
					
						
							|  |  |  | #elif DATA_SIZE == 1
 | 
					
						
							|  |  |  | #define SUFFIX b
 | 
					
						
							| 
									
										
										
										
											2003-10-27 21:22:23 +00:00
										 |  |  | #define USUFFIX ub
 | 
					
						
							| 
									
										
										
										
											2003-08-08 23:58:05 +00:00
										 |  |  | #define DATA_TYPE uint8_t
 | 
					
						
							|  |  |  | #define DATA_STYPE int8_t
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #error unsupported data size
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-14 07:07:08 +00:00
										 |  |  | #if ACCESS_TYPE < (NB_MMU_MODES)
 | 
					
						
							| 
									
										
										
										
											2003-10-27 21:22:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-14 07:07:08 +00:00
										 |  |  | #define CPU_MMU_INDEX ACCESS_TYPE
 | 
					
						
							| 
									
										
										
										
											2003-10-27 21:22:23 +00:00
										 |  |  | #define MMUSUFFIX _mmu
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-14 07:07:08 +00:00
										 |  |  | #elif ACCESS_TYPE == (NB_MMU_MODES)
 | 
					
						
							| 
									
										
										
										
											2003-10-27 21:22:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-14 07:07:08 +00:00
										 |  |  | #define CPU_MMU_INDEX (cpu_mmu_index(env))
 | 
					
						
							| 
									
										
										
										
											2003-10-27 21:22:23 +00:00
										 |  |  | #define MMUSUFFIX _mmu
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-14 07:07:08 +00:00
										 |  |  | #elif ACCESS_TYPE == (NB_MMU_MODES + 1)
 | 
					
						
							| 
									
										
										
										
											2003-10-27 21:22:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-14 07:07:08 +00:00
										 |  |  | #define CPU_MMU_INDEX (cpu_mmu_index(env))
 | 
					
						
							| 
									
										
										
										
											2003-10-27 21:22:23 +00:00
										 |  |  | #define MMUSUFFIX _cmmu
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-08 23:58:05 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2003-10-27 21:22:23 +00:00
										 |  |  | #error invalid ACCESS_TYPE
 | 
					
						
							| 
									
										
										
										
											2003-08-08 23:58:05 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if DATA_SIZE == 8
 | 
					
						
							|  |  |  | #define RES_TYPE uint64_t
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #define RES_TYPE int
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-14 07:07:08 +00:00
										 |  |  | #if ACCESS_TYPE == (NB_MMU_MODES + 1)
 | 
					
						
							| 
									
										
										
										
											2005-11-28 21:19:04 +00:00
										 |  |  | #define ADDR_READ addr_code
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #define ADDR_READ addr_read
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2003-08-08 23:58:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-01-03 23:35:10 +00:00
										 |  |  | #if (DATA_SIZE <= 4) && (TARGET_LONG_BITS == 32) && defined(__i386__) && \
 | 
					
						
							| 
									
										
										
										
											2007-10-14 07:07:08 +00:00
										 |  |  |     (ACCESS_TYPE < NB_MMU_MODES) && defined(ASM_SOFTMMU) | 
					
						
							| 
									
										
										
										
											2004-01-04 18:15:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-01-03 23:35:10 +00:00
										 |  |  | static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr) | 
					
						
							| 
									
										
										
										
											2004-01-04 18:15:29 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     int res; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     asm volatile ("movl %1, %%edx\n" | 
					
						
							|  |  |  |                   "movl %1, %%eax\n" | 
					
						
							|  |  |  |                   "shrl %3, %%edx\n" | 
					
						
							|  |  |  |                   "andl %4, %%eax\n" | 
					
						
							|  |  |  |                   "andl %2, %%edx\n" | 
					
						
							|  |  |  |                   "leal %5(%%edx, %%ebp), %%edx\n" | 
					
						
							|  |  |  |                   "cmpl (%%edx), %%eax\n" | 
					
						
							|  |  |  |                   "movl %1, %%eax\n" | 
					
						
							|  |  |  |                   "je 1f\n" | 
					
						
							| 
									
										
										
										
											2008-01-31 09:22:27 +00:00
										 |  |  |                   "movl %6, %%edx\n" | 
					
						
							| 
									
										
										
										
											2004-01-04 18:15:29 +00:00
										 |  |  |                   "call %7\n" | 
					
						
							|  |  |  |                   "movl %%eax, %0\n" | 
					
						
							|  |  |  |                   "jmp 2f\n" | 
					
						
							|  |  |  |                   "1:\n" | 
					
						
							| 
									
										
										
										
											2005-11-28 21:19:04 +00:00
										 |  |  |                   "addl 12(%%edx), %%eax\n" | 
					
						
							| 
									
										
										
										
											2004-01-04 18:15:29 +00:00
										 |  |  | #if DATA_SIZE == 1
 | 
					
						
							|  |  |  |                   "movzbl (%%eax), %0\n" | 
					
						
							|  |  |  | #elif DATA_SIZE == 2
 | 
					
						
							|  |  |  |                   "movzwl (%%eax), %0\n" | 
					
						
							|  |  |  | #elif DATA_SIZE == 4
 | 
					
						
							|  |  |  |                   "movl (%%eax), %0\n" | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #error unsupported size
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |                   "2:\n" | 
					
						
							|  |  |  |                   : "=r" (res) | 
					
						
							| 
									
										
										
										
											2007-09-16 21:08:06 +00:00
										 |  |  |                   : "r" (ptr), | 
					
						
							|  |  |  |                   "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS), | 
					
						
							|  |  |  |                   "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS), | 
					
						
							| 
									
										
										
										
											2004-01-04 18:15:29 +00:00
										 |  |  |                   "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)), | 
					
						
							| 
									
										
										
										
											2007-10-14 07:07:08 +00:00
										 |  |  |                   "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_read)), | 
					
						
							|  |  |  |                   "i" (CPU_MMU_INDEX), | 
					
						
							| 
									
										
										
										
											2004-01-04 18:15:29 +00:00
										 |  |  |                   "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX)) | 
					
						
							|  |  |  |                   : "%eax", "%ecx", "%edx", "memory", "cc"); | 
					
						
							|  |  |  |     return res; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if DATA_SIZE <= 2
 | 
					
						
							| 
									
										
										
										
											2005-01-03 23:35:10 +00:00
										 |  |  | static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr) | 
					
						
							| 
									
										
										
										
											2004-01-04 18:15:29 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     int res; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     asm volatile ("movl %1, %%edx\n" | 
					
						
							|  |  |  |                   "movl %1, %%eax\n" | 
					
						
							|  |  |  |                   "shrl %3, %%edx\n" | 
					
						
							|  |  |  |                   "andl %4, %%eax\n" | 
					
						
							|  |  |  |                   "andl %2, %%edx\n" | 
					
						
							|  |  |  |                   "leal %5(%%edx, %%ebp), %%edx\n" | 
					
						
							|  |  |  |                   "cmpl (%%edx), %%eax\n" | 
					
						
							|  |  |  |                   "movl %1, %%eax\n" | 
					
						
							|  |  |  |                   "je 1f\n" | 
					
						
							| 
									
										
										
										
											2008-01-31 09:22:27 +00:00
										 |  |  |                   "movl %6, %%edx\n" | 
					
						
							| 
									
										
										
										
											2004-01-04 18:15:29 +00:00
										 |  |  |                   "call %7\n" | 
					
						
							|  |  |  | #if DATA_SIZE == 1
 | 
					
						
							|  |  |  |                   "movsbl %%al, %0\n" | 
					
						
							|  |  |  | #elif DATA_SIZE == 2
 | 
					
						
							|  |  |  |                   "movswl %%ax, %0\n" | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #error unsupported size
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |                   "jmp 2f\n" | 
					
						
							|  |  |  |                   "1:\n" | 
					
						
							| 
									
										
										
										
											2005-11-28 21:19:04 +00:00
										 |  |  |                   "addl 12(%%edx), %%eax\n" | 
					
						
							| 
									
										
										
										
											2004-01-04 18:15:29 +00:00
										 |  |  | #if DATA_SIZE == 1
 | 
					
						
							|  |  |  |                   "movsbl (%%eax), %0\n" | 
					
						
							|  |  |  | #elif DATA_SIZE == 2
 | 
					
						
							|  |  |  |                   "movswl (%%eax), %0\n" | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #error unsupported size
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |                   "2:\n" | 
					
						
							|  |  |  |                   : "=r" (res) | 
					
						
							| 
									
										
										
										
											2007-09-16 21:08:06 +00:00
										 |  |  |                   : "r" (ptr), | 
					
						
							|  |  |  |                   "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS), | 
					
						
							|  |  |  |                   "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS), | 
					
						
							| 
									
										
										
										
											2004-01-04 18:15:29 +00:00
										 |  |  |                   "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)), | 
					
						
							| 
									
										
										
										
											2007-10-14 07:07:08 +00:00
										 |  |  |                   "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_read)), | 
					
						
							|  |  |  |                   "i" (CPU_MMU_INDEX), | 
					
						
							| 
									
										
										
										
											2004-01-04 18:15:29 +00:00
										 |  |  |                   "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX)) | 
					
						
							|  |  |  |                   : "%eax", "%ecx", "%edx", "memory", "cc"); | 
					
						
							|  |  |  |     return res; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-01-03 23:35:10 +00:00
										 |  |  | static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE v) | 
					
						
							| 
									
										
										
										
											2004-01-04 18:15:29 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     asm volatile ("movl %0, %%edx\n" | 
					
						
							|  |  |  |                   "movl %0, %%eax\n" | 
					
						
							|  |  |  |                   "shrl %3, %%edx\n" | 
					
						
							|  |  |  |                   "andl %4, %%eax\n" | 
					
						
							|  |  |  |                   "andl %2, %%edx\n" | 
					
						
							|  |  |  |                   "leal %5(%%edx, %%ebp), %%edx\n" | 
					
						
							|  |  |  |                   "cmpl (%%edx), %%eax\n" | 
					
						
							|  |  |  |                   "movl %0, %%eax\n" | 
					
						
							|  |  |  |                   "je 1f\n" | 
					
						
							|  |  |  | #if DATA_SIZE == 1
 | 
					
						
							|  |  |  |                   "movzbl %b1, %%edx\n" | 
					
						
							|  |  |  | #elif DATA_SIZE == 2
 | 
					
						
							|  |  |  |                   "movzwl %w1, %%edx\n" | 
					
						
							|  |  |  | #elif DATA_SIZE == 4
 | 
					
						
							|  |  |  |                   "movl %1, %%edx\n" | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #error unsupported size
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2008-01-31 09:22:27 +00:00
										 |  |  |                   "movl %6, %%ecx\n" | 
					
						
							| 
									
										
										
										
											2004-01-04 18:15:29 +00:00
										 |  |  |                   "call %7\n" | 
					
						
							|  |  |  |                   "jmp 2f\n" | 
					
						
							|  |  |  |                   "1:\n" | 
					
						
							| 
									
										
										
										
											2005-11-28 21:19:04 +00:00
										 |  |  |                   "addl 8(%%edx), %%eax\n" | 
					
						
							| 
									
										
										
										
											2004-01-04 18:15:29 +00:00
										 |  |  | #if DATA_SIZE == 1
 | 
					
						
							|  |  |  |                   "movb %b1, (%%eax)\n" | 
					
						
							|  |  |  | #elif DATA_SIZE == 2
 | 
					
						
							|  |  |  |                   "movw %w1, (%%eax)\n" | 
					
						
							|  |  |  | #elif DATA_SIZE == 4
 | 
					
						
							|  |  |  |                   "movl %1, (%%eax)\n" | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #error unsupported size
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |                   "2:\n" | 
					
						
							| 
									
										
										
										
											2007-09-16 21:08:06 +00:00
										 |  |  |                   : | 
					
						
							|  |  |  |                   : "r" (ptr), | 
					
						
							| 
									
										
										
										
											2008-01-21 15:07:18 +00:00
										 |  |  | #if DATA_SIZE == 1
 | 
					
						
							|  |  |  |                   "q" (v), | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2007-09-16 21:08:06 +00:00
										 |  |  |                   "r" (v), | 
					
						
							| 
									
										
										
										
											2008-01-21 15:07:18 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2007-09-16 21:08:06 +00:00
										 |  |  |                   "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS), | 
					
						
							|  |  |  |                   "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS), | 
					
						
							| 
									
										
										
										
											2004-01-04 18:15:29 +00:00
										 |  |  |                   "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)), | 
					
						
							| 
									
										
										
										
											2007-10-14 07:07:08 +00:00
										 |  |  |                   "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_write)), | 
					
						
							|  |  |  |                   "i" (CPU_MMU_INDEX), | 
					
						
							| 
									
										
										
										
											2004-01-04 18:15:29 +00:00
										 |  |  |                   "m" (*(uint8_t *)&glue(glue(__st, SUFFIX), MMUSUFFIX)) | 
					
						
							|  |  |  |                   : "%eax", "%ecx", "%edx", "memory", "cc"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* generic load/store macros */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-01-03 23:35:10 +00:00
										 |  |  | static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr) | 
					
						
							| 
									
										
										
										
											2003-08-08 23:58:05 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-05-10 10:14:22 +00:00
										 |  |  |     int page_index; | 
					
						
							| 
									
										
										
										
											2003-08-08 23:58:05 +00:00
										 |  |  |     RES_TYPE res; | 
					
						
							| 
									
										
										
										
											2005-01-03 23:35:10 +00:00
										 |  |  |     target_ulong addr; | 
					
						
							|  |  |  |     unsigned long physaddr; | 
					
						
							| 
									
										
										
										
											2007-10-14 07:07:08 +00:00
										 |  |  |     int mmu_idx; | 
					
						
							| 
									
										
										
										
											2003-10-27 21:22:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-01-03 23:35:10 +00:00
										 |  |  |     addr = ptr; | 
					
						
							| 
									
										
										
										
											2008-05-10 10:14:22 +00:00
										 |  |  |     page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); | 
					
						
							| 
									
										
										
										
											2007-10-14 07:07:08 +00:00
										 |  |  |     mmu_idx = CPU_MMU_INDEX; | 
					
						
							| 
									
										
										
										
											2008-07-03 17:57:36 +00:00
										 |  |  |     if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ != | 
					
						
							|  |  |  |                  (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) { | 
					
						
							| 
									
										
										
										
											2007-10-14 07:07:08 +00:00
										 |  |  |         res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx); | 
					
						
							| 
									
										
										
										
											2003-08-08 23:58:05 +00:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2008-05-10 10:14:22 +00:00
										 |  |  |         physaddr = addr + env->tlb_table[mmu_idx][page_index].addend; | 
					
						
							| 
									
										
										
										
											2003-10-27 21:22:23 +00:00
										 |  |  |         res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr); | 
					
						
							| 
									
										
										
										
											2003-08-08 23:58:05 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     return res; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if DATA_SIZE <= 2
 | 
					
						
							| 
									
										
										
										
											2005-01-03 23:35:10 +00:00
										 |  |  | static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr) | 
					
						
							| 
									
										
										
										
											2003-08-08 23:58:05 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-05-10 10:14:22 +00:00
										 |  |  |     int res, page_index; | 
					
						
							| 
									
										
										
										
											2005-01-03 23:35:10 +00:00
										 |  |  |     target_ulong addr; | 
					
						
							|  |  |  |     unsigned long physaddr; | 
					
						
							| 
									
										
										
										
											2007-10-14 07:07:08 +00:00
										 |  |  |     int mmu_idx; | 
					
						
							| 
									
										
										
										
											2003-10-27 21:22:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-01-03 23:35:10 +00:00
										 |  |  |     addr = ptr; | 
					
						
							| 
									
										
										
										
											2008-05-10 10:14:22 +00:00
										 |  |  |     page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); | 
					
						
							| 
									
										
										
										
											2007-10-14 07:07:08 +00:00
										 |  |  |     mmu_idx = CPU_MMU_INDEX; | 
					
						
							| 
									
										
										
										
											2008-07-03 17:57:36 +00:00
										 |  |  |     if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ != | 
					
						
							|  |  |  |                  (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) { | 
					
						
							| 
									
										
										
										
											2007-10-14 07:07:08 +00:00
										 |  |  |         res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx); | 
					
						
							| 
									
										
										
										
											2003-08-08 23:58:05 +00:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2008-05-10 10:14:22 +00:00
										 |  |  |         physaddr = addr + env->tlb_table[mmu_idx][page_index].addend; | 
					
						
							| 
									
										
										
										
											2003-08-08 23:58:05 +00:00
										 |  |  |         res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)physaddr); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return res; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-14 07:07:08 +00:00
										 |  |  | #if ACCESS_TYPE != (NB_MMU_MODES + 1)
 | 
					
						
							| 
									
										
										
										
											2005-11-28 21:19:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-04 18:15:29 +00:00
										 |  |  | /* generic store macro */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-01-03 23:35:10 +00:00
										 |  |  | static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE v) | 
					
						
							| 
									
										
										
										
											2003-08-08 23:58:05 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-05-10 10:14:22 +00:00
										 |  |  |     int page_index; | 
					
						
							| 
									
										
										
										
											2005-01-03 23:35:10 +00:00
										 |  |  |     target_ulong addr; | 
					
						
							|  |  |  |     unsigned long physaddr; | 
					
						
							| 
									
										
										
										
											2007-10-14 07:07:08 +00:00
										 |  |  |     int mmu_idx; | 
					
						
							| 
									
										
										
										
											2003-10-27 21:22:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-01-03 23:35:10 +00:00
										 |  |  |     addr = ptr; | 
					
						
							| 
									
										
										
										
											2008-05-10 10:14:22 +00:00
										 |  |  |     page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); | 
					
						
							| 
									
										
										
										
											2007-10-14 07:07:08 +00:00
										 |  |  |     mmu_idx = CPU_MMU_INDEX; | 
					
						
							| 
									
										
										
										
											2008-07-03 17:57:36 +00:00
										 |  |  |     if (unlikely(env->tlb_table[mmu_idx][page_index].addr_write != | 
					
						
							|  |  |  |                  (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) { | 
					
						
							| 
									
										
										
										
											2007-10-14 07:07:08 +00:00
										 |  |  |         glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, mmu_idx); | 
					
						
							| 
									
										
										
										
											2003-08-08 23:58:05 +00:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2008-05-10 10:14:22 +00:00
										 |  |  |         physaddr = addr + env->tlb_table[mmu_idx][page_index].addend; | 
					
						
							| 
									
										
										
										
											2003-08-08 23:58:05 +00:00
										 |  |  |         glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, v); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-14 07:07:08 +00:00
										 |  |  | #endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
 | 
					
						
							| 
									
										
										
										
											2005-11-28 21:19:04 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #endif /* !asm */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-14 07:07:08 +00:00
										 |  |  | #if ACCESS_TYPE != (NB_MMU_MODES + 1)
 | 
					
						
							| 
									
										
										
										
											2004-01-04 18:15:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-04 23:56:24 +00:00
										 |  |  | #if DATA_SIZE == 8
 | 
					
						
							| 
									
										
										
										
											2005-11-06 19:56:23 +00:00
										 |  |  | static inline float64 glue(ldfq, MEMSUFFIX)(target_ulong ptr) | 
					
						
							| 
									
										
										
										
											2004-01-04 23:56:24 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     union { | 
					
						
							| 
									
										
										
										
											2005-11-06 19:56:23 +00:00
										 |  |  |         float64 d; | 
					
						
							| 
									
										
										
										
											2004-01-04 23:56:24 +00:00
										 |  |  |         uint64_t i; | 
					
						
							|  |  |  |     } u; | 
					
						
							|  |  |  |     u.i = glue(ldq, MEMSUFFIX)(ptr); | 
					
						
							|  |  |  |     return u.d; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-06 19:56:23 +00:00
										 |  |  | static inline void glue(stfq, MEMSUFFIX)(target_ulong ptr, float64 v) | 
					
						
							| 
									
										
										
										
											2004-01-04 23:56:24 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     union { | 
					
						
							| 
									
										
										
										
											2005-11-06 19:56:23 +00:00
										 |  |  |         float64 d; | 
					
						
							| 
									
										
										
										
											2004-01-04 23:56:24 +00:00
										 |  |  |         uint64_t i; | 
					
						
							|  |  |  |     } u; | 
					
						
							|  |  |  |     u.d = v; | 
					
						
							|  |  |  |     glue(stq, MEMSUFFIX)(ptr, u.i); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif /* DATA_SIZE == 8 */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if DATA_SIZE == 4
 | 
					
						
							| 
									
										
										
										
											2005-11-06 19:56:23 +00:00
										 |  |  | static inline float32 glue(ldfl, MEMSUFFIX)(target_ulong ptr) | 
					
						
							| 
									
										
										
										
											2004-01-04 23:56:24 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     union { | 
					
						
							| 
									
										
										
										
											2005-11-06 19:56:23 +00:00
										 |  |  |         float32 f; | 
					
						
							| 
									
										
										
										
											2004-01-04 23:56:24 +00:00
										 |  |  |         uint32_t i; | 
					
						
							|  |  |  |     } u; | 
					
						
							|  |  |  |     u.i = glue(ldl, MEMSUFFIX)(ptr); | 
					
						
							|  |  |  |     return u.f; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-06 19:56:23 +00:00
										 |  |  | static inline void glue(stfl, MEMSUFFIX)(target_ulong ptr, float32 v) | 
					
						
							| 
									
										
										
										
											2004-01-04 23:56:24 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     union { | 
					
						
							| 
									
										
										
										
											2005-11-06 19:56:23 +00:00
										 |  |  |         float32 f; | 
					
						
							| 
									
										
										
										
											2004-01-04 23:56:24 +00:00
										 |  |  |         uint32_t i; | 
					
						
							|  |  |  |     } u; | 
					
						
							|  |  |  |     u.f = v; | 
					
						
							|  |  |  |     glue(stl, MEMSUFFIX)(ptr, u.i); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif /* DATA_SIZE == 4 */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-14 07:07:08 +00:00
										 |  |  | #endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
 | 
					
						
							| 
									
										
										
										
											2005-11-28 21:19:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-08 23:58:05 +00:00
										 |  |  | #undef RES_TYPE
 | 
					
						
							|  |  |  | #undef DATA_TYPE
 | 
					
						
							|  |  |  | #undef DATA_STYPE
 | 
					
						
							|  |  |  | #undef SUFFIX
 | 
					
						
							| 
									
										
										
										
											2003-10-27 21:22:23 +00:00
										 |  |  | #undef USUFFIX
 | 
					
						
							| 
									
										
										
										
											2003-08-08 23:58:05 +00:00
										 |  |  | #undef DATA_SIZE
 | 
					
						
							| 
									
										
										
										
											2007-10-14 07:07:08 +00:00
										 |  |  | #undef CPU_MMU_INDEX
 | 
					
						
							| 
									
										
										
										
											2003-10-27 21:22:23 +00:00
										 |  |  | #undef MMUSUFFIX
 | 
					
						
							| 
									
										
										
										
											2005-11-28 21:19:04 +00:00
										 |  |  | #undef ADDR_READ
 |