From: Stuart B. <zu...@us...> - 2008-02-18 00:14:05
|
Update of /cvsroot/hppaqemu/hppaqemu/target-sparc In directory sc8-pr-cvs17.sourceforge.net:/tmp/cvs-serv24609/target-sparc Modified Files: cpu.h exec.h helper.c op.c op_helper.c translate.c Log Message: Update to QEMU CVS from 2007-06-01. Index: translate.c =================================================================== RCS file: /cvsroot/hppaqemu/hppaqemu/target-sparc/translate.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -d -r1.1.1.1 -r1.2 --- translate.c 23 Feb 2007 21:44:42 -0000 1.1.1.1 +++ translate.c 18 Feb 2008 00:14:00 -0000 1.2 @@ -25,9 +25,7 @@ Rest of V9 instructions, VIS instructions NPC/PC static optimisations (use JUMP_TB when possible) Optimize synthetic instructions - Optional alignment check 128-bit float - Tagged add/sub */ #include <stdarg.h> @@ -56,6 +54,13 @@ struct TranslationBlock *tb; [...1389 lines suppressed...] return addr; } @@ -2826,7 +3489,7 @@ int *access_index, target_ulong address, int rw, int is_user); -target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr) +target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) { target_phys_addr_t phys_addr; int prot, access_index; @@ -2834,6 +3497,8 @@ if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2, 0) != 0) if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 0, 0) != 0) return -1; + if (cpu_get_physical_page_desc(phys_addr) == IO_MEM_UNASSIGNED) + return -1; return phys_addr; } #endif Index: helper.c =================================================================== RCS file: /cvsroot/hppaqemu/hppaqemu/target-sparc/helper.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -d -r1.1.1.1 -r1.2 --- helper.c 23 Feb 2007 21:44:41 -0000 1.1.1.1 +++ helper.c 18 Feb 2008 00:14:00 -0000 1.2 @@ -117,7 +117,7 @@ } *access_index = ((rw & 1) << 2) | (rw & 2) | (is_user? 0 : 1); - *physical = 0xfffff000; + *physical = 0xffffffffffff0000ULL; /* SPARC reference MMU table walk: Context table->L1->L2->PTE */ /* Context base + context number */ @@ -203,7 +203,7 @@ /* Even if large ptes, we map only one 4KB page in the cache to avoid filling it too fast */ - *physical = ((pde & PTE_ADDR_MASK) << 4) + page_offset; + *physical = ((target_phys_addr_t)(pde & PTE_ADDR_MASK) << 4) + page_offset; return error_code; } @@ -212,7 +212,7 @@ int is_user, int is_softmmu) { target_phys_addr_t paddr; - unsigned long vaddr; + target_ulong vaddr; int error_code = 0, prot, ret = 0, access_index; error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, is_user); @@ -220,7 +220,8 @@ vaddr = address & TARGET_PAGE_MASK; paddr &= TARGET_PAGE_MASK; #ifdef DEBUG_MMU - printf("Translate at 0x%lx -> 0x%lx, vaddr 0x%lx\n", (long)address, (long)paddr, (long)vaddr); + printf("Translate at " TARGET_FMT_lx " -> " TARGET_FMT_plx ", vaddr " + TARGET_FMT_lx "\n", address, paddr, vaddr); #endif ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu); return ret; @@ -255,7 +256,8 @@ uint32_t pde; /* Context base + context number */ - pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2); + pde_ptr = (target_phys_addr_t)(env->mmuregs[1] << 4) + + (env->mmuregs[2] << 2); pde = ldl_phys(pde_ptr); switch (pde & PTE_ENTRYTYPE_MASK) { @@ -314,30 +316,35 @@ #ifdef DEBUG_MMU void dump_mmu(CPUState *env) { - target_ulong va, va1, va2; - unsigned int n, m, o; - target_phys_addr_t pde_ptr, pa; + target_ulong va, va1, va2; + unsigned int n, m, o; + target_phys_addr_t pde_ptr, pa; uint32_t pde; printf("MMU dump:\n"); pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2); pde = ldl_phys(pde_ptr); - printf("Root ptr: " TARGET_FMT_lx ", ctx: %d\n", env->mmuregs[1] << 4, env->mmuregs[2]); + printf("Root ptr: " TARGET_FMT_plx ", ctx: %d\n", + (target_phys_addr_t)env->mmuregs[1] << 4, env->mmuregs[2]); for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) { - pde_ptr = mmu_probe(env, va, 2); - if (pde_ptr) { + pde = mmu_probe(env, va, 2); + if (pde) { pa = cpu_get_phys_page_debug(env, va); - printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PDE: " TARGET_FMT_lx "\n", va, pa, pde_ptr); + printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx + " PDE: " TARGET_FMT_lx "\n", va, pa, pde); for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) { - pde_ptr = mmu_probe(env, va1, 1); - if (pde_ptr) { + pde = mmu_probe(env, va1, 1); + if (pde) { pa = cpu_get_phys_page_debug(env, va1); - printf(" VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PDE: " TARGET_FMT_lx "\n", va1, pa, pde_ptr); + printf(" VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx + " PDE: " TARGET_FMT_lx "\n", va1, pa, pde); for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) { - pde_ptr = mmu_probe(env, va2, 0); - if (pde_ptr) { + pde = mmu_probe(env, va2, 0); + if (pde) { pa = cpu_get_phys_page_debug(env, va2); - printf(" VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PTE: " TARGET_FMT_lx "\n", va2, pa, pde_ptr); + printf(" VA: " TARGET_FMT_lx ", PA: " + TARGET_FMT_plx " PTE: " TARGET_FMT_lx "\n", + va2, pa, pde); } } } Index: op_helper.c =================================================================== RCS file: /cvsroot/hppaqemu/hppaqemu/target-sparc/op_helper.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -d -r1.1.1.1 -r1.2 --- op_helper.c 23 Feb 2007 21:44:42 -0000 1.1.1.1 +++ op_helper.c 18 Feb 2008 00:14:00 -0000 1.2 @@ -2,6 +2,8 @@ //#define DEBUG_PCALL //#define DEBUG_MMU +//#define DEBUG_UNALIGNED +//#define DEBUG_UNASSIGNED void raise_exception(int tt) { @@ -9,10 +11,43 @@ cpu_loop_exit(); } +void check_ieee_exceptions() +{ + T0 = get_float_exception_flags(&env->fp_status); + if (T0) + { + /* Copy IEEE 754 flags into FSR */ + if (T0 & float_flag_invalid) + env->fsr |= FSR_NVC; + if (T0 & float_flag_overflow) + env->fsr |= FSR_OFC; + if (T0 & float_flag_underflow) + env->fsr |= FSR_UFC; + if (T0 & float_flag_divbyzero) + env->fsr |= FSR_DZC; + if (T0 & float_flag_inexact) + env->fsr |= FSR_NXC; + + if ((env->fsr & FSR_CEXC_MASK) & ((env->fsr & FSR_TEM_MASK) >> 23)) + { + /* Unmasked exception, generate a trap */ + env->fsr |= FSR_FTT_IEEE_EXCP; + raise_exception(TT_FP_EXCP); + } + else + { + /* Accumulate exceptions */ + env->fsr |= (env->fsr & FSR_CEXC_MASK) << 5; + } + } +} + #ifdef USE_INT_TO_FLOAT_HELPERS void do_fitos(void) { + set_float_exception_flags(0, &env->fp_status); FT0 = int32_to_float32(*((int32_t *)&FT1), &env->fp_status); + check_ieee_exceptions(); } void do_fitod(void) @@ -35,23 +70,29 @@ void do_fsqrts(void) { + set_float_exception_flags(0, &env->fp_status); FT0 = float32_sqrt(FT1, &env->fp_status); + check_ieee_exceptions(); } void do_fsqrtd(void) { + set_float_exception_flags(0, &env->fp_status); DT0 = float64_sqrt(DT1, &env->fp_status); + check_ieee_exceptions(); } -#define GEN_FCMP(name, size, reg1, reg2, FS) \ +#define GEN_FCMP(name, size, reg1, reg2, FS, TRAP) \ void glue(do_, name) (void) \ { \ env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \ switch (glue(size, _compare) (reg1, reg2, &env->fp_status)) { \ case float_relation_unordered: \ T0 = (FSR_FCC1 | FSR_FCC0) << FS; \ - if (env->fsr & FSR_NVM) { \ + if ((env->fsr & FSR_NVM) || TRAP) { \ env->fsr |= T0; \ + env->fsr |= FSR_NVC; \ + env->fsr |= FSR_FTT_IEEE_EXCP; \ raise_exception(TT_FP_EXCP); \ } else { \ env->fsr |= FSR_NVA; \ @@ -70,18 +111,30 @@ env->fsr |= T0; \ } -GEN_FCMP(fcmps, float32, FT0, FT1, 0); -GEN_FCMP(fcmpd, float64, DT0, DT1, 0); +GEN_FCMP(fcmps, float32, FT0, FT1, 0, 0); +GEN_FCMP(fcmpd, float64, DT0, DT1, 0, 0); + +GEN_FCMP(fcmpes, float32, FT0, FT1, 0, 1); +GEN_FCMP(fcmped, float64, DT0, DT1, 0, 1); #ifdef TARGET_SPARC64 -GEN_FCMP(fcmps_fcc1, float32, FT0, FT1, 22); -GEN_FCMP(fcmpd_fcc1, float64, DT0, DT1, 22); +GEN_FCMP(fcmps_fcc1, float32, FT0, FT1, 22, 0); +GEN_FCMP(fcmpd_fcc1, float64, DT0, DT1, 22, 0); -GEN_FCMP(fcmps_fcc2, float32, FT0, FT1, 24); -GEN_FCMP(fcmpd_fcc2, float64, DT0, DT1, 24); +GEN_FCMP(fcmps_fcc2, float32, FT0, FT1, 24, 0); +GEN_FCMP(fcmpd_fcc2, float64, DT0, DT1, 24, 0); -GEN_FCMP(fcmps_fcc3, float32, FT0, FT1, 26); -GEN_FCMP(fcmpd_fcc3, float64, DT0, DT1, 26); +GEN_FCMP(fcmps_fcc3, float32, FT0, FT1, 26, 0); +GEN_FCMP(fcmpd_fcc3, float64, DT0, DT1, 26, 0); + +GEN_FCMP(fcmpes_fcc1, float32, FT0, FT1, 22, 1); +GEN_FCMP(fcmped_fcc1, float64, DT0, DT1, 22, 1); + +GEN_FCMP(fcmpes_fcc2, float32, FT0, FT1, 24, 1); +GEN_FCMP(fcmped_fcc2, float64, DT0, DT1, 24, 1); + +GEN_FCMP(fcmpes_fcc3, float32, FT0, FT1, 26, 1); +GEN_FCMP(fcmped_fcc3, float64, DT0, DT1, 26, 1); #endif #if defined(CONFIG_USER_ONLY) @@ -99,6 +152,8 @@ uint32_t ret = 0; switch (asi) { + case 2: /* SuperSparc MXCC registers */ + break; case 3: /* MMU probe */ { int mmulev; @@ -127,7 +182,30 @@ #endif } break; - case 0x20 ... 0x2f: /* MMU passthrough */ + case 9: /* Supervisor code access */ + switch(size) { + case 1: + ret = ldub_code(T0); + break; + case 2: + ret = lduw_code(T0 & ~1); + break; + default: + case 4: + ret = ldl_code(T0 & ~3); + break; + case 8: + ret = ldl_code(T0 & ~3); + T0 = ldl_code((T0 + 4) & ~3); + break; + } + break; + case 0xc: /* I-cache tag */ + case 0xd: /* I-cache data */ + case 0xe: /* D-cache tag */ + case 0xf: /* D-cache data */ + break; + case 0x20: /* MMU passthrough */ switch(size) { case 1: ret = ldub_phys(T0); @@ -145,7 +223,33 @@ break; } break; + case 0x2e: /* MMU passthrough, 0xexxxxxxxx */ + case 0x2f: /* MMU passthrough, 0xfxxxxxxxx */ + switch(size) { + case 1: + ret = ldub_phys((target_phys_addr_t)T0 + | ((target_phys_addr_t)(asi & 0xf) << 32)); + break; + case 2: + ret = lduw_phys((target_phys_addr_t)(T0 & ~1) + | ((target_phys_addr_t)(asi & 0xf) << 32)); + break; + default: + case 4: + ret = ldl_phys((target_phys_addr_t)(T0 & ~3) + | ((target_phys_addr_t)(asi & 0xf) << 32)); + break; + case 8: + ret = ldl_phys((target_phys_addr_t)(T0 & ~3) + | ((target_phys_addr_t)(asi & 0xf) << 32)); + T0 = ldl_phys((target_phys_addr_t)((T0 + 4) & ~3) + | ((target_phys_addr_t)(asi & 0xf) << 32)); + break; + } + break; + case 0x21 ... 0x2d: /* MMU passthrough, unassigned */ default: + do_unassigned_access(T0, 0, 0, 1); ret = 0; break; } @@ -155,6 +259,8 @@ void helper_st_asi(int asi, int size, int sign) { switch(asi) { + case 2: /* SuperSparc MXCC registers */ + break; case 3: /* MMU flush */ { int mmulev; @@ -219,18 +325,28 @@ #endif return; } + case 0xc: /* I-cache tag */ + case 0xd: /* I-cache data */ + case 0xe: /* D-cache tag */ + case 0xf: /* D-cache data */ + case 0x10: /* I/D-cache flush page */ + case 0x11: /* I/D-cache flush segment */ + case 0x12: /* I/D-cache flush region */ + case 0x13: /* I/D-cache flush context */ + case 0x14: /* I/D-cache flush user */ + break; case 0x17: /* Block copy, sta access */ { // value (T1) = src // address (T0) = dst // copy 32 bytes - uint32_t src = T1, dst = T0; - uint8_t temp[32]; + unsigned int i; + uint32_t src = T1 & ~3, dst = T0 & ~3, temp; - tswap32s(&src); - - cpu_physical_memory_read(src, (void *) &temp, 32); - cpu_physical_memory_write(dst, (void *) &temp, 32); + for (i = 0; i < 32; i += 4, src += 4, dst += 4) { + temp = ldl_kernel(src); + stl_kernel(dst, temp); + } } return; case 0x1f: /* Block fill, stda access */ @@ -238,19 +354,17 @@ // value (T1, T2) // address (T0) = dst // fill 32 bytes - int i; - uint32_t dst = T0; - uint64_t val; - - val = (((uint64_t)T1) << 32) | T2; - tswap64s(&val); + unsigned int i; + uint32_t dst = T0 & 7; + uint64_t val; - for (i = 0; i < 32; i += 8, dst += 8) { - cpu_physical_memory_write(dst, (void *) &val, 8); - } + val = (((uint64_t)T1) << 32) | T2; + + for (i = 0; i < 32; i += 8, dst += 8) + stq_kernel(dst, val); } return; - case 0x20 ... 0x2f: /* MMU passthrough */ + case 0x20: /* MMU passthrough */ { switch(size) { case 1: @@ -270,7 +384,40 @@ } } return; + case 0x2e: /* MMU passthrough, 0xexxxxxxxx */ + case 0x2f: /* MMU passthrough, 0xfxxxxxxxx */ + { + switch(size) { + case 1: + stb_phys((target_phys_addr_t)T0 + | ((target_phys_addr_t)(asi & 0xf) << 32), T1); + break; + case 2: + stw_phys((target_phys_addr_t)(T0 & ~1) + | ((target_phys_addr_t)(asi & 0xf) << 32), T1); + break; + case 4: + default: + stl_phys((target_phys_addr_t)(T0 & ~3) + | ((target_phys_addr_t)(asi & 0xf) << 32), T1); + break; + case 8: + stl_phys((target_phys_addr_t)(T0 & ~3) + | ((target_phys_addr_t)(asi & 0xf) << 32), T1); + stl_phys((target_phys_addr_t)((T0 + 4) & ~3) + | ((target_phys_addr_t)(asi & 0xf) << 32), T1); + break; + } + } + return; + case 0x31: /* Ross RT620 I-cache flush */ + case 0x36: /* I-cache flash clear */ + case 0x37: /* D-cache flash clear */ + break; + case 9: /* Supervisor code access, XXX */ + case 0x21 ... 0x2d: /* MMU passthrough, unassigned */ default: + do_unassigned_access(T0, 1, 0, 1); return; } } @@ -389,6 +536,7 @@ case 0x5f: // D-MMU demap, WO case 0x77: // Interrupt vector, WO default: + do_unassigned_access(T0, 0, 0, 1); ret = 0; break; } @@ -604,6 +752,7 @@ case 0x8a: // Primary no-fault LE, RO case 0x8b: // Secondary no-fault LE, RO default: + do_unassigned_access(T0, 1, 0, 1); return; } } @@ -615,6 +764,9 @@ { unsigned int cwp; + if (env->psret == 1) + raise_exception(TT_ILL_INSN); + env->psret = 1; cwp = (env->cwp + 1) & (NWINDOWS - 1); if (env->wim & (1 << cwp)) { @@ -655,7 +807,10 @@ #ifndef TARGET_SPARC64 void do_wrpsr() { - PUT_PSR(env, T0); + if ((T0 & PSR_CWP) >= NWINDOWS) + raise_exception(TT_ILL_INSN); + else + PUT_PSR(env, T0); } void do_rdpsr() @@ -866,7 +1021,11 @@ #if !defined(CONFIG_USER_ONLY) +static void do_unaligned_access(target_ulong addr, int is_write, int is_user, + void *retaddr); + #define MMUSUFFIX _mmu +#define ALIGNED_ONLY #define GETPC() (__builtin_return_address(0)) #define SHIFT 0 @@ -881,6 +1040,14 @@ #define SHIFT 3 #include "softmmu_template.h" +static void do_unaligned_access(target_ulong addr, int is_write, int is_user, + void *retaddr) +{ +#ifdef DEBUG_UNALIGNED + printf("Unaligned access to 0x%x from 0x%x\n", addr, env->pc); +#endif + raise_exception(TT_UNALIGNED); +} /* try to fill the TLB and return an exception if error. If retaddr is NULL, it means that the function was called in C code (i.e. not @@ -916,3 +1083,76 @@ } #endif + +#ifndef TARGET_SPARC64 +void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec, + int is_asi) +{ + CPUState *saved_env; + + /* XXX: hack to restore env in all cases, even if not called from + generated code */ + saved_env = env; + env = cpu_single_env; + if (env->mmuregs[3]) /* Fault status register */ + env->mmuregs[3] = 1; /* overflow (not read before another fault) */ + if (is_asi) + env->mmuregs[3] |= 1 << 16; + if (env->psrs) + env->mmuregs[3] |= 1 << 5; + if (is_exec) + env->mmuregs[3] |= 1 << 6; + if (is_write) + env->mmuregs[3] |= 1 << 7; + env->mmuregs[3] |= (5 << 2) | 2; + env->mmuregs[4] = addr; /* Fault address register */ + if ((env->mmuregs[0] & MMU_E) && !(env->mmuregs[0] & MMU_NF)) { +#ifdef DEBUG_UNASSIGNED + printf("Unassigned mem access to " TARGET_FMT_plx " from " TARGET_FMT_lx + "\n", addr, env->pc); +#endif + if (is_exec) + raise_exception(TT_CODE_ACCESS); + else + raise_exception(TT_DATA_ACCESS); + } + env = saved_env; +} +#else +void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec, + int is_asi) +{ +#ifdef DEBUG_UNASSIGNED + CPUState *saved_env; + + /* XXX: hack to restore env in all cases, even if not called from + generated code */ + saved_env = env; + env = cpu_single_env; + printf("Unassigned mem access to " TARGET_FMT_plx " from " TARGET_FMT_lx "\n", + addr, env->pc); + env = saved_env; +#endif + if (is_exec) + raise_exception(TT_CODE_ACCESS); + else + raise_exception(TT_DATA_ACCESS); +} +#endif + +#ifdef TARGET_SPARC64 +void do_tick_set_count(void *opaque, uint64_t count) +{ + ptimer_set_count(opaque, -count); +} + +uint64_t do_tick_get_count(void *opaque) +{ + return -ptimer_get_count(opaque); +} + +void do_tick_set_limit(void *opaque, uint64_t limit) +{ + ptimer_set_limit(opaque, -limit, 0); +} +#endif Index: op.c =================================================================== RCS file: /cvsroot/hppaqemu/hppaqemu/target-sparc/op.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -d -r1.1.1.1 -r1.2 --- op.c 23 Feb 2007 21:44:41 -0000 1.1.1.1 +++ op.c 18 Feb 2008 00:14:00 -0000 1.2 @@ -472,6 +472,96 @@ FORCE_RET(); } +void OPPROTO op_tadd_T1_T0_cc(void) +{ + target_ulong src1; + + src1 = T0; + T0 += T1; + env->psr = 0; +#ifdef TARGET_SPARC64 [...973 lines suppressed...] + s.d = DT0; \ + d.d = DT1; \ + \ + d.VIS_L64(0) = F(d.VIS_L64(0), s.VIS_L64(0))? 1: 0; \ + d.VIS_L64(0) |= F(d.VIS_L64(1), s.VIS_L64(1))? 2: 0; \ + \ + DT0 = d.d; \ + } + +#define FCMPGT(a, b) ((a) > (b)) +#define FCMPEQ(a, b) ((a) == (b)) +#define FCMPLE(a, b) ((a) <= (b)) +#define FCMPNE(a, b) ((a) != (b)) + +VIS_CMPOP(op_fcmpgt, FCMPGT) +VIS_CMPOP(op_fcmpeq, FCMPEQ) +VIS_CMPOP(op_fcmple, FCMPLE) +VIS_CMPOP(op_fcmpne, FCMPNE) + #endif Index: cpu.h =================================================================== RCS file: /cvsroot/hppaqemu/hppaqemu/target-sparc/cpu.h,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -d -r1.1.1.1 -r1.2 --- cpu.h 23 Feb 2007 21:44:41 -0000 1.1.1.1 +++ cpu.h 18 Feb 2008 00:14:00 -0000 1.2 @@ -35,23 +35,32 @@ #define TT_NFPU_INSN 0x04 #define TT_WIN_OVF 0x05 #define TT_WIN_UNF 0x06 +#define TT_UNALIGNED 0x07 #define TT_FP_EXCP 0x08 #define TT_DFAULT 0x09 +#define TT_TOVF 0x0a #define TT_EXTINT 0x10 +#define TT_CODE_ACCESS 0x21 +#define TT_DATA_ACCESS 0x29 #define TT_DIV_ZERO 0x2a +#define TT_NCP_INSN 0x24 #define TT_TRAP 0x80 #else #define TT_TFAULT 0x08 #define TT_TMISS 0x09 +#define TT_CODE_ACCESS 0x0a #define TT_ILL_INSN 0x10 #define TT_PRIV_INSN 0x11 #define TT_NFPU_INSN 0x20 #define TT_FP_EXCP 0x21 +#define TT_TOVF 0x23 #define TT_CLRWIN 0x24 #define TT_DIV_ZERO 0x28 #define TT_DFAULT 0x30 #define TT_DMISS 0x31 -#define TT_DPROT 0x32 +#define TT_DATA_ACCESS 0x32 +#define TT_DPROT 0x33 +#define TT_UNALIGNED 0x34 #define TT_PRIV_ACT 0x37 #define TT_EXTINT 0x40 #define TT_SPILL 0x80 @@ -124,6 +133,7 @@ #define FSR_FTT_MASK (FSR_FTT2 | FSR_FTT1 | FSR_FTT0) #define FSR_FTT_IEEE_EXCP (1 << 14) #define FSR_FTT_UNIMPFPOP (3 << 14) +#define FSR_FTT_SEQ_ERROR (4 << 14) #define FSR_FTT_INVAL_FPR (6 << 14) #define FSR_FCC1 (1<<11) @@ -150,6 +160,8 @@ /* 2 <= NWINDOWS <= 32. In QEMU it must also be a power of two. */ #define NWINDOWS 8 +typedef struct sparc_def_t sparc_def_t; + typedef struct CPUSPARCState { target_ulong gregs[8]; /* general registers */ target_ulong *regwptr; /* pointer to current register window */ @@ -168,6 +180,7 @@ int psret; /* enable traps */ uint32_t psrpil; /* interrupt level */ int psref; /* enable fpu */ + target_ulong version; jmp_buf jmp_env; int user_mode_only; int exception_index; @@ -213,10 +226,14 @@ uint64_t bgregs[8]; /* backup for normal global registers */ uint64_t igregs[8]; /* interrupt general registers */ uint64_t mgregs[8]; /* mmu general registers */ - uint64_t version; uint64_t fprs; uint64_t tick_cmpr, stick_cmpr; + void *tick, *stick; uint64_t gsr; + uint32_t gl; // UA2005 + /* UA 2005 hyperprivileged registers */ + uint64_t hpstate, htstate[MAXTL], hintp, htba, hver, hstick_cmpr, ssr; + void *hstick; // UA 2005 #endif #if !defined(TARGET_SPARC64) && !defined(reg_T2) target_ulong t2; @@ -231,22 +248,22 @@ #define PUT_FSR64(env, val) do { uint64_t _tmp = val; \ env->fsr = _tmp & 0x3fcfc1c3ffULL; \ } while (0) -// Manuf 0x17, version 0x11, mask 0 (UltraSparc-II) -#define GET_VER(env) ((0x17ULL << 48) | (0x11ULL << 32) | \ - (0 << 24) | (MAXTL << 8) | (NWINDOWS - 1)) #else #define GET_FSR32(env) (env->fsr) -#define PUT_FSR32(env, val) do { uint32_t _tmp = val; \ - env->fsr = _tmp & 0xcfc1ffff; \ +#define PUT_FSR32(env, val) do { uint32_t _tmp = val; \ + env->fsr = (_tmp & 0xcfc1dfff) | (env->fsr & 0x000e0000); \ } while (0) #endif CPUSPARCState *cpu_sparc_init(void); int cpu_sparc_exec(CPUSPARCState *s); int cpu_sparc_close(CPUSPARCState *s); +int sparc_find_by_name (const unsigned char *name, const sparc_def_t **def); +void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, + ...)); +int cpu_sparc_register (CPUSPARCState *env, const sparc_def_t *def); -/* Fake impl 0, version 4 */ -#define GET_PSR(env) ((0 << 28) | (4 << 24) | (env->psr & PSR_ICC) | \ +#define GET_PSR(env) (env->version | (env->psr & PSR_ICC) | \ (env->psref? PSR_EF : 0) | \ (env->psrpil << 8) | \ (env->psrs? PSR_S : 0) | \ @@ -264,7 +281,7 @@ env->psrs = (_tmp & PSR_S)? 1 : 0; \ env->psrps = (_tmp & PSR_PS)? 1 : 0; \ env->psret = (_tmp & PSR_ET)? 1 : 0; \ - cpu_set_cwp(env, _tmp & PSR_CWP & (NWINDOWS - 1)); \ + cpu_set_cwp(env, _tmp & PSR_CWP); \ } while (0) #ifdef TARGET_SPARC64 @@ -276,6 +293,12 @@ #endif int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc); +void raise_exception(int tt); +void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec, + int is_asi); +void do_tick_set_count(void *opaque, uint64_t count); +uint64_t do_tick_get_count(void *opaque); +void do_tick_set_limit(void *opaque, uint64_t limit); #include "cpu-all.h" Index: exec.h =================================================================== RCS file: /cvsroot/hppaqemu/hppaqemu/target-sparc/exec.h,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -d -r1.1.1.1 -r1.2 --- exec.h 23 Feb 2007 21:44:41 -0000 1.1.1.1 +++ exec.h 18 Feb 2008 00:14:00 -0000 1.2 @@ -1,13 +1,9 @@ #ifndef EXEC_SPARC_H #define EXEC_SPARC_H 1 -#include "dyngen-exec.h" #include "config.h" +#include "dyngen-exec.h" -#if defined(__sparc__) -struct CPUSPARCState *env; -#else register struct CPUSPARCState *env asm(AREG0); -#endif #ifdef TARGET_SPARC64 #define T0 (env->t0) @@ -15,13 +11,8 @@ #define T2 (env->t2) #define REGWPTR env->regwptr #else -#if defined(__sparc__) -register uint32_t T0 asm(AREG3); -register uint32_t T1 asm(AREG2); -#else register uint32_t T0 asm(AREG1); register uint32_t T1 asm(AREG2); -#endif #undef REG_REGWPTR // Broken #ifdef REG_REGWPTR @@ -33,11 +24,7 @@ #define reg_REGWPTR #ifdef AREG4 -#if defined(__sparc__) -register uint32_t T2 asm(AREG0); -#else register uint32_t T2 asm(AREG4); -#endif #define reg_T2 #else #define T2 (env->t2) @@ -45,14 +32,10 @@ #else #define REGWPTR env->regwptr -#if defined(__sparc__) -register uint32_t T2 asm(AREG0); -#else register uint32_t T2 asm(AREG3); #endif #define reg_T2 #endif -#endif #define FT0 (env->ft0) #define FT1 (env->ft1) @@ -78,6 +61,8 @@ void do_fsqrtd(void); void do_fcmps(void); void do_fcmpd(void); +void do_fcmpes(void); +void do_fcmped(void); #ifdef TARGET_SPARC64 void do_fabsd(void); void do_fcmps_fcc1(void); @@ -86,6 +71,12 @@ void do_fcmpd_fcc2(void); void do_fcmps_fcc3(void); void do_fcmpd_fcc3(void); +void do_fcmpes_fcc1(void); +void do_fcmped_fcc1(void); +void do_fcmpes_fcc2(void); +void do_fcmped_fcc2(void); +void do_fcmpes_fcc3(void); +void do_fcmped_fcc3(void); void do_popc(); void do_wrpstate(); void do_done(); @@ -96,6 +87,7 @@ void do_ldd_raw(target_ulong addr); void do_interrupt(int intno); void raise_exception(int tt); +void check_ieee_exceptions(); void memcpy32(target_ulong *dst, const target_ulong *src); target_ulong mmu_probe(CPUState *env, target_ulong address, int mmulev); void dump_mmu(CPUState *env); |