X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=softmmu_header.h;h=0798cf5721233cc83760d3c19abe80f1cf3e19de;hb=0289b2c1df2a6e8347541bde30533898ac1d5553;hp=26b4f2cddb116f659af1e9f53196968003539661;hpb=61382a500a9e54ef96ca28e0f221151f569cbb6e;p=qemu diff --git a/softmmu_header.h b/softmmu_header.h index 26b4f2c..0798cf5 100644 --- a/softmmu_header.h +++ b/softmmu_header.h @@ -51,12 +51,28 @@ #elif ACCESS_TYPE == 2 +#ifdef TARGET_I386 #define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3) +#elif defined (TARGET_PPC) +#define CPU_MEM_INDEX (msr_pr) +#elif defined (TARGET_MIPS) +#define CPU_MEM_INDEX ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM) +#elif defined (TARGET_SPARC) +#define CPU_MEM_INDEX ((env->psrs) == 0) +#endif #define MMUSUFFIX _mmu #elif ACCESS_TYPE == 3 +#ifdef TARGET_I386 #define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3) +#elif defined (TARGET_PPC) +#define CPU_MEM_INDEX (msr_pr) +#elif defined (TARGET_MIPS) +#define CPU_MEM_INDEX ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM) +#elif defined (TARGET_SPARC) +#define CPU_MEM_INDEX ((env->psrs) == 0) +#endif #define MMUSUFFIX _cmmu #else @@ -70,18 +86,166 @@ #endif -DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(unsigned long addr, +DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr, int is_user); -void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(unsigned long addr, DATA_TYPE v, int is_user); +void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, DATA_TYPE v, int is_user); + +#if (DATA_SIZE <= 4) && (TARGET_LONG_BITS == 32) && defined(__i386__) && \ + (ACCESS_TYPE <= 1) && defined(ASM_SOFTMMU) + +static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr) +{ + 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" + "pushl %6\n" + "call %7\n" + "popl %%edx\n" + "movl %%eax, %0\n" + "jmp 2f\n" + "1:\n" + "addl 4(%%edx), %%eax\n" +#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) + : "r" (ptr), + "i" ((CPU_TLB_SIZE - 1) << 3), + "i" (TARGET_PAGE_BITS - 3), + "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)), + "m" (*(uint32_t *)offsetof(CPUState, tlb_read[CPU_MEM_INDEX][0].address)), + "i" (CPU_MEM_INDEX), + "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX)) + : "%eax", "%ecx", "%edx", "memory", "cc"); + return res; +} + +#if DATA_SIZE <= 2 +static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr) +{ + 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" + "pushl %6\n" + "call %7\n" + "popl %%edx\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" + "addl 4(%%edx), %%eax\n" +#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) + : "r" (ptr), + "i" ((CPU_TLB_SIZE - 1) << 3), + "i" (TARGET_PAGE_BITS - 3), + "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)), + "m" (*(uint32_t *)offsetof(CPUState, tlb_read[CPU_MEM_INDEX][0].address)), + "i" (CPU_MEM_INDEX), + "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX)) + : "%eax", "%ecx", "%edx", "memory", "cc"); + return res; +} +#endif -static inline int glue(glue(ld, USUFFIX), MEMSUFFIX)(void *ptr) +static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE v) +{ + 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 + "pushl %6\n" + "call %7\n" + "popl %%eax\n" + "jmp 2f\n" + "1:\n" + "addl 4(%%edx), %%eax\n" +#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" + : + : "r" (ptr), +/* NOTE: 'q' would be needed as constraint, but we could not use it + with T1 ! */ + "r" (v), + "i" ((CPU_TLB_SIZE - 1) << 3), + "i" (TARGET_PAGE_BITS - 3), + "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)), + "m" (*(uint32_t *)offsetof(CPUState, tlb_write[CPU_MEM_INDEX][0].address)), + "i" (CPU_MEM_INDEX), + "m" (*(uint8_t *)&glue(glue(__st, SUFFIX), MMUSUFFIX)) + : "%eax", "%ecx", "%edx", "memory", "cc"); +} + +#else + +/* generic load/store macros */ + +static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr) { int index; RES_TYPE res; - unsigned long addr, physaddr; + target_ulong addr; + unsigned long physaddr; int is_user; - addr = (unsigned long)ptr; + addr = ptr; index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); is_user = CPU_MEM_INDEX; if (__builtin_expect(env->tlb_read[is_user][index].address != @@ -95,13 +259,14 @@ static inline int glue(glue(ld, USUFFIX), MEMSUFFIX)(void *ptr) } #if DATA_SIZE <= 2 -static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(void *ptr) +static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr) { int res, index; - unsigned long addr, physaddr; + target_ulong addr; + unsigned long physaddr; int is_user; - addr = (unsigned long)ptr; + addr = ptr; index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); is_user = CPU_MEM_INDEX; if (__builtin_expect(env->tlb_read[is_user][index].address != @@ -115,13 +280,16 @@ static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(void *ptr) } #endif -static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(void *ptr, RES_TYPE v) +/* generic store macro */ + +static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE v) { int index; - unsigned long addr, physaddr; + target_ulong addr; + unsigned long physaddr; int is_user; - addr = (unsigned long)ptr; + addr = ptr; index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); is_user = CPU_MEM_INDEX; if (__builtin_expect(env->tlb_write[is_user][index].address != @@ -133,6 +301,52 @@ static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(void *ptr, RES_TYPE v) } } +#endif + +#if DATA_SIZE == 8 +static inline double glue(ldfq, MEMSUFFIX)(target_ulong ptr) +{ + union { + double d; + uint64_t i; + } u; + u.i = glue(ldq, MEMSUFFIX)(ptr); + return u.d; +} + +static inline void glue(stfq, MEMSUFFIX)(target_ulong ptr, double v) +{ + union { + double d; + uint64_t i; + } u; + u.d = v; + glue(stq, MEMSUFFIX)(ptr, u.i); +} +#endif /* DATA_SIZE == 8 */ + +#if DATA_SIZE == 4 +static inline float glue(ldfl, MEMSUFFIX)(target_ulong ptr) +{ + union { + float f; + uint32_t i; + } u; + u.i = glue(ldl, MEMSUFFIX)(ptr); + return u.f; +} + +static inline void glue(stfl, MEMSUFFIX)(target_ulong ptr, float v) +{ + union { + float f; + uint32_t i; + } u; + u.f = v; + glue(stl, MEMSUFFIX)(ptr, u.i); +} +#endif /* DATA_SIZE == 4 */ + #undef RES_TYPE #undef DATA_TYPE #undef DATA_STYPE