| 93 |
#define RES_TYPE int |
#define RES_TYPE int |
| 94 |
#endif |
#endif |
| 95 |
|
|
| 96 |
|
#if ACCESS_TYPE == 3 |
| 97 |
|
#define ADDR_READ addr_code |
| 98 |
|
#else |
| 99 |
|
#define ADDR_READ addr_read |
| 100 |
|
#endif |
| 101 |
|
|
| 102 |
DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr, |
DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr, |
| 103 |
int is_user); |
int is_user); |
| 106 |
#if (DATA_SIZE <= 4) && (TARGET_LONG_BITS == 32) && defined(__i386__) && \ |
#if (DATA_SIZE <= 4) && (TARGET_LONG_BITS == 32) && defined(__i386__) && \ |
| 107 |
(ACCESS_TYPE <= 1) && defined(ASM_SOFTMMU) |
(ACCESS_TYPE <= 1) && defined(ASM_SOFTMMU) |
| 108 |
|
|
| 109 |
|
#define CPU_TLB_ENTRY_BITS 4 |
| 110 |
|
|
| 111 |
static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr) |
static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr) |
| 112 |
{ |
{ |
| 113 |
int res; |
int res; |
| 127 |
"movl %%eax, %0\n" |
"movl %%eax, %0\n" |
| 128 |
"jmp 2f\n" |
"jmp 2f\n" |
| 129 |
"1:\n" |
"1:\n" |
| 130 |
"addl 4(%%edx), %%eax\n" |
"addl 12(%%edx), %%eax\n" |
| 131 |
#if DATA_SIZE == 1 |
#if DATA_SIZE == 1 |
| 132 |
"movzbl (%%eax), %0\n" |
"movzbl (%%eax), %0\n" |
| 133 |
#elif DATA_SIZE == 2 |
#elif DATA_SIZE == 2 |
| 140 |
"2:\n" |
"2:\n" |
| 141 |
: "=r" (res) |
: "=r" (res) |
| 142 |
: "r" (ptr), |
: "r" (ptr), |
| 143 |
"i" ((CPU_TLB_SIZE - 1) << 3), |
"i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS), |
| 144 |
"i" (TARGET_PAGE_BITS - 3), |
"i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS), |
| 145 |
"i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)), |
"i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)), |
| 146 |
"m" (*(uint32_t *)offsetof(CPUState, tlb_read[CPU_MEM_INDEX][0].address)), |
"m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_read)), |
| 147 |
"i" (CPU_MEM_INDEX), |
"i" (CPU_MEM_INDEX), |
| 148 |
"m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX)) |
"m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX)) |
| 149 |
: "%eax", "%ecx", "%edx", "memory", "cc"); |
: "%eax", "%ecx", "%edx", "memory", "cc"); |
| 176 |
#endif |
#endif |
| 177 |
"jmp 2f\n" |
"jmp 2f\n" |
| 178 |
"1:\n" |
"1:\n" |
| 179 |
"addl 4(%%edx), %%eax\n" |
"addl 12(%%edx), %%eax\n" |
| 180 |
#if DATA_SIZE == 1 |
#if DATA_SIZE == 1 |
| 181 |
"movsbl (%%eax), %0\n" |
"movsbl (%%eax), %0\n" |
| 182 |
#elif DATA_SIZE == 2 |
#elif DATA_SIZE == 2 |
| 187 |
"2:\n" |
"2:\n" |
| 188 |
: "=r" (res) |
: "=r" (res) |
| 189 |
: "r" (ptr), |
: "r" (ptr), |
| 190 |
"i" ((CPU_TLB_SIZE - 1) << 3), |
"i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS), |
| 191 |
"i" (TARGET_PAGE_BITS - 3), |
"i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS), |
| 192 |
"i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)), |
"i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)), |
| 193 |
"m" (*(uint32_t *)offsetof(CPUState, tlb_read[CPU_MEM_INDEX][0].address)), |
"m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_read)), |
| 194 |
"i" (CPU_MEM_INDEX), |
"i" (CPU_MEM_INDEX), |
| 195 |
"m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX)) |
"m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX)) |
| 196 |
: "%eax", "%ecx", "%edx", "memory", "cc"); |
: "%eax", "%ecx", "%edx", "memory", "cc"); |
| 223 |
"popl %%eax\n" |
"popl %%eax\n" |
| 224 |
"jmp 2f\n" |
"jmp 2f\n" |
| 225 |
"1:\n" |
"1:\n" |
| 226 |
"addl 4(%%edx), %%eax\n" |
"addl 8(%%edx), %%eax\n" |
| 227 |
#if DATA_SIZE == 1 |
#if DATA_SIZE == 1 |
| 228 |
"movb %b1, (%%eax)\n" |
"movb %b1, (%%eax)\n" |
| 229 |
#elif DATA_SIZE == 2 |
#elif DATA_SIZE == 2 |
| 239 |
/* NOTE: 'q' would be needed as constraint, but we could not use it |
/* NOTE: 'q' would be needed as constraint, but we could not use it |
| 240 |
with T1 ! */ |
with T1 ! */ |
| 241 |
"r" (v), |
"r" (v), |
| 242 |
"i" ((CPU_TLB_SIZE - 1) << 3), |
"i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS), |
| 243 |
"i" (TARGET_PAGE_BITS - 3), |
"i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS), |
| 244 |
"i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)), |
"i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)), |
| 245 |
"m" (*(uint32_t *)offsetof(CPUState, tlb_write[CPU_MEM_INDEX][0].address)), |
"m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_write)), |
| 246 |
"i" (CPU_MEM_INDEX), |
"i" (CPU_MEM_INDEX), |
| 247 |
"m" (*(uint8_t *)&glue(glue(__st, SUFFIX), MMUSUFFIX)) |
"m" (*(uint8_t *)&glue(glue(__st, SUFFIX), MMUSUFFIX)) |
| 248 |
: "%eax", "%ecx", "%edx", "memory", "cc"); |
: "%eax", "%ecx", "%edx", "memory", "cc"); |
| 263 |
addr = ptr; |
addr = ptr; |
| 264 |
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); |
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); |
| 265 |
is_user = CPU_MEM_INDEX; |
is_user = CPU_MEM_INDEX; |
| 266 |
if (__builtin_expect(env->tlb_read[is_user][index].address != |
if (__builtin_expect(env->tlb_table[is_user][index].ADDR_READ != |
| 267 |
(addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) { |
(addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) { |
| 268 |
res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user); |
res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user); |
| 269 |
} else { |
} else { |
| 270 |
physaddr = addr + env->tlb_read[is_user][index].addend; |
physaddr = addr + env->tlb_table[is_user][index].addend; |
| 271 |
res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr); |
res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr); |
| 272 |
} |
} |
| 273 |
return res; |
return res; |
| 284 |
addr = ptr; |
addr = ptr; |
| 285 |
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); |
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); |
| 286 |
is_user = CPU_MEM_INDEX; |
is_user = CPU_MEM_INDEX; |
| 287 |
if (__builtin_expect(env->tlb_read[is_user][index].address != |
if (__builtin_expect(env->tlb_table[is_user][index].ADDR_READ != |
| 288 |
(addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) { |
(addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) { |
| 289 |
res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user); |
res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user); |
| 290 |
} else { |
} else { |
| 291 |
physaddr = addr + env->tlb_read[is_user][index].addend; |
physaddr = addr + env->tlb_table[is_user][index].addend; |
| 292 |
res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)physaddr); |
res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)physaddr); |
| 293 |
} |
} |
| 294 |
return res; |
return res; |
| 295 |
} |
} |
| 296 |
#endif |
#endif |
| 297 |
|
|
| 298 |
|
#if ACCESS_TYPE != 3 |
| 299 |
|
|
| 300 |
/* generic store macro */ |
/* generic store macro */ |
| 301 |
|
|
| 302 |
static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE v) |
static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE v) |
| 309 |
addr = ptr; |
addr = ptr; |
| 310 |
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); |
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); |
| 311 |
is_user = CPU_MEM_INDEX; |
is_user = CPU_MEM_INDEX; |
| 312 |
if (__builtin_expect(env->tlb_write[is_user][index].address != |
if (__builtin_expect(env->tlb_table[is_user][index].addr_write != |
| 313 |
(addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) { |
(addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) { |
| 314 |
glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, is_user); |
glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, is_user); |
| 315 |
} else { |
} else { |
| 316 |
physaddr = addr + env->tlb_write[is_user][index].addend; |
physaddr = addr + env->tlb_table[is_user][index].addend; |
| 317 |
glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, v); |
glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, v); |
| 318 |
} |
} |
| 319 |
} |
} |
| 320 |
|
|
| 321 |
#endif |
#endif /* ACCESS_TYPE != 3 */ |
| 322 |
|
|
| 323 |
|
#endif /* !asm */ |
| 324 |
|
|
| 325 |
|
#if ACCESS_TYPE != 3 |
| 326 |
|
|
| 327 |
#if DATA_SIZE == 8 |
#if DATA_SIZE == 8 |
| 328 |
static inline float64 glue(ldfq, MEMSUFFIX)(target_ulong ptr) |
static inline float64 glue(ldfq, MEMSUFFIX)(target_ulong ptr) |
| 368 |
} |
} |
| 369 |
#endif /* DATA_SIZE == 4 */ |
#endif /* DATA_SIZE == 4 */ |
| 370 |
|
|
| 371 |
|
#endif /* ACCESS_TYPE != 3 */ |
| 372 |
|
|
| 373 |
#undef RES_TYPE |
#undef RES_TYPE |
| 374 |
#undef DATA_TYPE |
#undef DATA_TYPE |
| 375 |
#undef DATA_STYPE |
#undef DATA_STYPE |
| 378 |
#undef DATA_SIZE |
#undef DATA_SIZE |
| 379 |
#undef CPU_MEM_INDEX |
#undef CPU_MEM_INDEX |
| 380 |
#undef MMUSUFFIX |
#undef MMUSUFFIX |
| 381 |
|
#undef ADDR_READ |