git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3195 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
blueswir1 2007-09-20 14:54:22 +00:00
parent 2e03286b9a
commit 0f8a249a0b
6 changed files with 2184 additions and 2184 deletions

View File

@ -22,9 +22,9 @@
#define TARGET_HAS_ICE 1
#if !defined(TARGET_SPARC64)
#define ELF_MACHINE EM_SPARC
#define ELF_MACHINE EM_SPARC
#else
#define ELF_MACHINE EM_SPARCV9
#define ELF_MACHINE EM_SPARCV9
#endif
/*#define EXCP_INTERRUPT 0x100*/
@ -143,8 +143,8 @@
#define FSR_FCC0 (1<<10)
/* MMU */
#define MMU_E (1<<0)
#define MMU_NF (1<<1)
#define MMU_E (1<<0)
#define MMU_NF (1<<1)
#define PTE_ENTRYTYPE_MASK 3
#define PTE_ACCESS_MASK 0x1c
@ -152,8 +152,8 @@
#define PTE_PPN_SHIFT 7
#define PTE_ADDR_MASK 0xffffff00
#define PG_ACCESSED_BIT 5
#define PG_MODIFIED_BIT 6
#define PG_ACCESSED_BIT 5
#define PG_MODIFIED_BIT 6
#define PG_CACHE_BIT 7
#define PG_ACCESSED_MASK (1 << PG_ACCESSED_BIT)
@ -221,7 +221,7 @@ typedef struct CPUSPARCState {
uint64_t tnpc[MAXTL];
uint64_t tstate[MAXTL];
uint32_t tt[MAXTL];
uint32_t xcc; /* Extended integer condition codes */
uint32_t xcc; /* Extended integer condition codes */
uint32_t asi;
uint32_t pstate;
uint32_t tl;
@ -245,12 +245,12 @@ typedef struct CPUSPARCState {
} CPUSPARCState;
#if defined(TARGET_SPARC64)
#define GET_FSR32(env) (env->fsr & 0xcfc1ffff)
#define PUT_FSR32(env, val) do { uint32_t _tmp = val; \
env->fsr = (_tmp & 0xcfc1c3ff) | (env->fsr & 0x3f00000000ULL); \
#define PUT_FSR32(env, val) do { uint32_t _tmp = val; \
env->fsr = (_tmp & 0xcfc1c3ff) | (env->fsr & 0x3f00000000ULL); \
} while (0)
#define GET_FSR64(env) (env->fsr & 0x3fcfc1ffffULL)
#define PUT_FSR64(env, val) do { uint64_t _tmp = val; \
env->fsr = _tmp & 0x3fcfc1c3ffULL; \
#define PUT_FSR64(env, val) do { uint64_t _tmp = val; \
env->fsr = _tmp & 0x3fcfc1c3ffULL; \
} while (0)
#else
#define GET_FSR32(env) (env->fsr)
@ -268,31 +268,31 @@ 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);
#define GET_PSR(env) (env->version | (env->psr & PSR_ICC) | \
(env->psref? PSR_EF : 0) | \
(env->psrpil << 8) | \
(env->psrs? PSR_S : 0) | \
(env->psrps? PSR_PS : 0) | \
(env->psret? PSR_ET : 0) | env->cwp)
(env->psref? PSR_EF : 0) | \
(env->psrpil << 8) | \
(env->psrs? PSR_S : 0) | \
(env->psrps? PSR_PS : 0) | \
(env->psret? PSR_ET : 0) | env->cwp)
#ifndef NO_CPU_IO_DEFS
void cpu_set_cwp(CPUSPARCState *env1, int new_cwp);
#endif
#define PUT_PSR(env, val) do { int _tmp = val; \
env->psr = _tmp & PSR_ICC; \
env->psref = (_tmp & PSR_EF)? 1 : 0; \
env->psrpil = (_tmp & PSR_PIL) >> 8; \
env->psrs = (_tmp & PSR_S)? 1 : 0; \
env->psrps = (_tmp & PSR_PS)? 1 : 0; \
env->psret = (_tmp & PSR_ET)? 1 : 0; \
#define PUT_PSR(env, val) do { int _tmp = val; \
env->psr = _tmp & PSR_ICC; \
env->psref = (_tmp & PSR_EF)? 1 : 0; \
env->psrpil = (_tmp & PSR_PIL) >> 8; \
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); \
} while (0)
#ifdef TARGET_SPARC64
#define GET_CCR(env) (((env->xcc >> 20) << 4) | ((env->psr & PSR_ICC) >> 20))
#define PUT_CCR(env, val) do { int _tmp = val; \
env->xcc = (_tmp >> 4) << 20; \
env->psr = (_tmp & 0xf) << 20; \
#define PUT_CCR(env, val) do { int _tmp = val; \
env->xcc = (_tmp >> 4) << 20; \
env->psr = (_tmp & 0xf) << 20; \
} while (0)
#define GET_CWP64(env) (NWINDOWS - 1 - (env)->cwp)
#define PUT_CWP64(env, val) \

View File

@ -99,8 +99,8 @@ static const int perm_table[2][8] = {
};
int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
int *access_index, target_ulong address, int rw,
int is_user)
int *access_index, target_ulong address, int rw,
int is_user)
{
int access_perms = 0;
target_phys_addr_t pde_ptr;
@ -111,7 +111,7 @@ int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot
virt_addr = address & TARGET_PAGE_MASK;
if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */
*physical = address;
*physical = address;
*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
return 0;
}
@ -128,70 +128,70 @@ int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot
switch (pde & PTE_ENTRYTYPE_MASK) {
default:
case 0: /* Invalid */
return 1 << 2;
return 1 << 2;
case 2: /* L0 PTE, maybe should not happen? */
case 3: /* Reserved */
return 4 << 2;
case 1: /* L0 PDE */
pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
pde = ldl_phys(pde_ptr);
switch (pde & PTE_ENTRYTYPE_MASK) {
default:
case 0: /* Invalid */
return (1 << 8) | (1 << 2);
case 3: /* Reserved */
return (1 << 8) | (4 << 2);
case 1: /* L1 PDE */
pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
switch (pde & PTE_ENTRYTYPE_MASK) {
default:
case 0: /* Invalid */
return (1 << 8) | (1 << 2);
case 3: /* Reserved */
return (1 << 8) | (4 << 2);
case 1: /* L1 PDE */
pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
pde = ldl_phys(pde_ptr);
switch (pde & PTE_ENTRYTYPE_MASK) {
default:
case 0: /* Invalid */
return (2 << 8) | (1 << 2);
case 3: /* Reserved */
return (2 << 8) | (4 << 2);
case 1: /* L2 PDE */
pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
switch (pde & PTE_ENTRYTYPE_MASK) {
default:
case 0: /* Invalid */
return (2 << 8) | (1 << 2);
case 3: /* Reserved */
return (2 << 8) | (4 << 2);
case 1: /* L2 PDE */
pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
pde = ldl_phys(pde_ptr);
switch (pde & PTE_ENTRYTYPE_MASK) {
default:
case 0: /* Invalid */
return (3 << 8) | (1 << 2);
case 1: /* PDE, should not happen */
case 3: /* Reserved */
return (3 << 8) | (4 << 2);
case 2: /* L3 PTE */
virt_addr = address & TARGET_PAGE_MASK;
page_offset = (address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1);
}
break;
case 2: /* L2 PTE */
virt_addr = address & ~0x3ffff;
page_offset = address & 0x3ffff;
}
break;
case 2: /* L1 PTE */
virt_addr = address & ~0xffffff;
page_offset = address & 0xffffff;
}
switch (pde & PTE_ENTRYTYPE_MASK) {
default:
case 0: /* Invalid */
return (3 << 8) | (1 << 2);
case 1: /* PDE, should not happen */
case 3: /* Reserved */
return (3 << 8) | (4 << 2);
case 2: /* L3 PTE */
virt_addr = address & TARGET_PAGE_MASK;
page_offset = (address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1);
}
break;
case 2: /* L2 PTE */
virt_addr = address & ~0x3ffff;
page_offset = address & 0x3ffff;
}
break;
case 2: /* L1 PTE */
virt_addr = address & ~0xffffff;
page_offset = address & 0xffffff;
}
}
/* update page modified and dirty bits */
is_dirty = (rw & 1) && !(pde & PG_MODIFIED_MASK);
if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
pde |= PG_ACCESSED_MASK;
if (is_dirty)
pde |= PG_MODIFIED_MASK;
pde |= PG_ACCESSED_MASK;
if (is_dirty)
pde |= PG_MODIFIED_MASK;
stl_phys_notdirty(pde_ptr, pde);
}
/* check access */
access_perms = (pde & PTE_ACCESS_MASK) >> PTE_ACCESS_SHIFT;
error_code = access_table[*access_index][access_perms];
if (error_code && !((env->mmuregs[0] & MMU_NF) && is_user))
return error_code;
return error_code;
/* the page can be put in the TLB */
*prot = perm_table[is_user][access_perms];
@ -217,18 +217,18 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, is_user);
if (error_code == 0) {
vaddr = address & TARGET_PAGE_MASK;
paddr &= TARGET_PAGE_MASK;
vaddr = address & TARGET_PAGE_MASK;
paddr &= TARGET_PAGE_MASK;
#ifdef DEBUG_MMU
printf("Translate at " TARGET_FMT_lx " -> " TARGET_FMT_plx ", 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;
ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
return ret;
}
if (env->mmuregs[3]) /* Fault status register */
env->mmuregs[3] = 1; /* overflow (not read before another fault) */
env->mmuregs[3] = 1; /* overflow (not read before another fault) */
env->mmuregs[3] |= (access_index << 5) | error_code | 2;
env->mmuregs[4] = address; /* Fault address register */
@ -237,10 +237,10 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
// permissions. If no mapping is available, redirect accesses to
// neverland. Fake/overridden mappings will be flushed when
// switching to normal mode.
vaddr = address & TARGET_PAGE_MASK;
vaddr = address & TARGET_PAGE_MASK;
prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
return ret;
return ret;
} else {
if (rw & 2)
env->exception_index = TT_TFAULT;
@ -265,50 +265,50 @@ target_ulong mmu_probe(CPUState *env, target_ulong address, int mmulev)
case 0: /* Invalid */
case 2: /* PTE, maybe should not happen? */
case 3: /* Reserved */
return 0;
return 0;
case 1: /* L1 PDE */
if (mmulev == 3)
return pde;
pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
if (mmulev == 3)
return pde;
pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
pde = ldl_phys(pde_ptr);
switch (pde & PTE_ENTRYTYPE_MASK) {
default:
case 0: /* Invalid */
case 3: /* Reserved */
return 0;
case 2: /* L1 PTE */
return pde;
case 1: /* L2 PDE */
if (mmulev == 2)
return pde;
pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
switch (pde & PTE_ENTRYTYPE_MASK) {
default:
case 0: /* Invalid */
case 3: /* Reserved */
return 0;
case 2: /* L1 PTE */
return pde;
case 1: /* L2 PDE */
if (mmulev == 2)
return pde;
pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
pde = ldl_phys(pde_ptr);
switch (pde & PTE_ENTRYTYPE_MASK) {
default:
case 0: /* Invalid */
case 3: /* Reserved */
return 0;
case 2: /* L2 PTE */
return pde;
case 1: /* L3 PDE */
if (mmulev == 1)
return pde;
pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
switch (pde & PTE_ENTRYTYPE_MASK) {
default:
case 0: /* Invalid */
case 3: /* Reserved */
return 0;
case 2: /* L2 PTE */
return pde;
case 1: /* L3 PDE */
if (mmulev == 1)
return pde;
pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
pde = ldl_phys(pde_ptr);
switch (pde & PTE_ENTRYTYPE_MASK) {
default:
case 0: /* Invalid */
case 1: /* PDE, should not happen */
case 3: /* Reserved */
return 0;
case 2: /* L3 PTE */
return pde;
}
}
}
switch (pde & PTE_ENTRYTYPE_MASK) {
default:
case 0: /* Invalid */
case 1: /* PDE, should not happen */
case 3: /* Reserved */
return 0;
case 2: /* L3 PTE */
return pde;
}
}
}
}
return 0;
}
@ -327,29 +327,29 @@ void dump_mmu(CPUState *env)
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 = mmu_probe(env, va, 2);
if (pde) {
pa = cpu_get_phys_page_debug(env, va);
printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx
pde = mmu_probe(env, va, 2);
if (pde) {
pa = cpu_get_phys_page_debug(env, va);
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 = mmu_probe(env, va1, 1);
if (pde) {
pa = cpu_get_phys_page_debug(env, va1);
printf(" VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx
for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) {
pde = mmu_probe(env, va1, 1);
if (pde) {
pa = cpu_get_phys_page_debug(env, va1);
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 = mmu_probe(env, va2, 0);
if (pde) {
pa = cpu_get_phys_page_debug(env, va2);
printf(" VA: " TARGET_FMT_lx ", PA: "
for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) {
pde = mmu_probe(env, va2, 0);
if (pde) {
pa = cpu_get_phys_page_debug(env, va2);
printf(" VA: " TARGET_FMT_lx ", PA: "
TARGET_FMT_plx " PTE: " TARGET_FMT_lx "\n",
va2, pa, pde);
}
}
}
}
}
}
}
}
}
}
}
printf("MMU dump ends\n");
}
@ -360,57 +360,57 @@ void dump_mmu(CPUState *env)
* UltraSparc IIi I/DMMUs
*/
static int get_physical_address_data(CPUState *env, target_phys_addr_t *physical, int *prot,
int *access_index, target_ulong address, int rw,
int is_user)
int *access_index, target_ulong address, int rw,
int is_user)
{
target_ulong mask;
unsigned int i;
if ((env->lsu & DMMU_E) == 0) { /* DMMU disabled */
*physical = address;
*prot = PAGE_READ | PAGE_WRITE;
*physical = address;
*prot = PAGE_READ | PAGE_WRITE;
return 0;
}
for (i = 0; i < 64; i++) {
switch ((env->dtlb_tte[i] >> 61) & 3) {
default:
case 0x0: // 8k
mask = 0xffffffffffffe000ULL;
break;
case 0x1: // 64k
mask = 0xffffffffffff0000ULL;
break;
case 0x2: // 512k
mask = 0xfffffffffff80000ULL;
break;
case 0x3: // 4M
mask = 0xffffffffffc00000ULL;
break;
}
// ctx match, vaddr match?
if (env->dmmuregs[1] == (env->dtlb_tag[i] & 0x1fff) &&
(address & mask) == (env->dtlb_tag[i] & ~0x1fffULL)) {
// valid, access ok?
if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0 ||
((env->dtlb_tte[i] & 0x4) && is_user) ||
(!(env->dtlb_tte[i] & 0x2) && (rw == 1))) {
if (env->dmmuregs[3]) /* Fault status register */
env->dmmuregs[3] = 2; /* overflow (not read before another fault) */
env->dmmuregs[3] |= (is_user << 3) | ((rw == 1) << 2) | 1;
env->dmmuregs[4] = address; /* Fault address register */
env->exception_index = TT_DFAULT;
switch ((env->dtlb_tte[i] >> 61) & 3) {
default:
case 0x0: // 8k
mask = 0xffffffffffffe000ULL;
break;
case 0x1: // 64k
mask = 0xffffffffffff0000ULL;
break;
case 0x2: // 512k
mask = 0xfffffffffff80000ULL;
break;
case 0x3: // 4M
mask = 0xffffffffffc00000ULL;
break;
}
// ctx match, vaddr match?
if (env->dmmuregs[1] == (env->dtlb_tag[i] & 0x1fff) &&
(address & mask) == (env->dtlb_tag[i] & ~0x1fffULL)) {
// valid, access ok?
if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0 ||
((env->dtlb_tte[i] & 0x4) && is_user) ||
(!(env->dtlb_tte[i] & 0x2) && (rw == 1))) {
if (env->dmmuregs[3]) /* Fault status register */
env->dmmuregs[3] = 2; /* overflow (not read before another fault) */
env->dmmuregs[3] |= (is_user << 3) | ((rw == 1) << 2) | 1;
env->dmmuregs[4] = address; /* Fault address register */
env->exception_index = TT_DFAULT;
#ifdef DEBUG_MMU
printf("DFAULT at 0x%" PRIx64 "\n", address);
printf("DFAULT at 0x%" PRIx64 "\n", address);
#endif
return 1;
}
*physical = (env->dtlb_tte[i] & mask & 0x1fffffff000ULL) + (address & ~mask & 0x1fffffff000ULL);
*prot = PAGE_READ;
if (env->dtlb_tte[i] & 0x2)
*prot |= PAGE_WRITE;
return 0;
}
return 1;
}
*physical = (env->dtlb_tte[i] & mask & 0x1fffffff000ULL) + (address & ~mask & 0x1fffffff000ULL);
*prot = PAGE_READ;
if (env->dtlb_tte[i] & 0x2)
*prot |= PAGE_WRITE;
return 0;
}
}
#ifdef DEBUG_MMU
printf("DMISS at 0x%" PRIx64 "\n", address);
@ -420,53 +420,53 @@ static int get_physical_address_data(CPUState *env, target_phys_addr_t *physical
}
static int get_physical_address_code(CPUState *env, target_phys_addr_t *physical, int *prot,
int *access_index, target_ulong address, int rw,
int is_user)
int *access_index, target_ulong address, int rw,
int is_user)
{
target_ulong mask;
unsigned int i;
if ((env->lsu & IMMU_E) == 0) { /* IMMU disabled */
*physical = address;
*prot = PAGE_EXEC;
*physical = address;
*prot = PAGE_EXEC;
return 0;
}
for (i = 0; i < 64; i++) {
switch ((env->itlb_tte[i] >> 61) & 3) {
default:
case 0x0: // 8k
mask = 0xffffffffffffe000ULL;
break;
case 0x1: // 64k
mask = 0xffffffffffff0000ULL;
break;
case 0x2: // 512k
mask = 0xfffffffffff80000ULL;
break;
case 0x3: // 4M
mask = 0xffffffffffc00000ULL;
break;
}
// ctx match, vaddr match?
if (env->dmmuregs[1] == (env->itlb_tag[i] & 0x1fff) &&
(address & mask) == (env->itlb_tag[i] & ~0x1fffULL)) {
// valid, access ok?
if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0 ||
((env->itlb_tte[i] & 0x4) && is_user)) {
if (env->immuregs[3]) /* Fault status register */
env->immuregs[3] = 2; /* overflow (not read before another fault) */
env->immuregs[3] |= (is_user << 3) | 1;
env->exception_index = TT_TFAULT;
switch ((env->itlb_tte[i] >> 61) & 3) {
default:
case 0x0: // 8k
mask = 0xffffffffffffe000ULL;
break;
case 0x1: // 64k
mask = 0xffffffffffff0000ULL;
break;
case 0x2: // 512k
mask = 0xfffffffffff80000ULL;
break;
case 0x3: // 4M
mask = 0xffffffffffc00000ULL;
break;
}
// ctx match, vaddr match?
if (env->dmmuregs[1] == (env->itlb_tag[i] & 0x1fff) &&
(address & mask) == (env->itlb_tag[i] & ~0x1fffULL)) {
// valid, access ok?
if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0 ||
((env->itlb_tte[i] & 0x4) && is_user)) {
if (env->immuregs[3]) /* Fault status register */
env->immuregs[3] = 2; /* overflow (not read before another fault) */
env->immuregs[3] |= (is_user << 3) | 1;
env->exception_index = TT_TFAULT;
#ifdef DEBUG_MMU
printf("TFAULT at 0x%" PRIx64 "\n", address);
printf("TFAULT at 0x%" PRIx64 "\n", address);
#endif
return 1;
}
*physical = (env->itlb_tte[i] & mask & 0x1fffffff000ULL) + (address & ~mask & 0x1fffffff000ULL);
*prot = PAGE_EXEC;
return 0;
}
return 1;
}
*physical = (env->itlb_tte[i] & mask & 0x1fffffff000ULL) + (address & ~mask & 0x1fffffff000ULL);
*prot = PAGE_EXEC;
return 0;
}
}
#ifdef DEBUG_MMU
printf("TMISS at 0x%" PRIx64 "\n", address);
@ -476,13 +476,13 @@ static int get_physical_address_code(CPUState *env, target_phys_addr_t *physical
}
int get_physical_address(CPUState *env, target_phys_addr_t *physical, int *prot,
int *access_index, target_ulong address, int rw,
int is_user)
int *access_index, target_ulong address, int rw,
int is_user)
{
if (rw == 2)
return get_physical_address_code(env, physical, prot, access_index, address, rw, is_user);
return get_physical_address_code(env, physical, prot, access_index, address, rw, is_user);
else
return get_physical_address_data(env, physical, prot, access_index, address, rw, is_user);
return get_physical_address_data(env, physical, prot, access_index, address, rw, is_user);
}
/* Perform address translation */
@ -495,13 +495,13 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, is_user);
if (error_code == 0) {
virt_addr = address & TARGET_PAGE_MASK;
vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1));
virt_addr = address & TARGET_PAGE_MASK;
vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1));
#ifdef DEBUG_MMU
printf("Translate at 0x%" PRIx64 " -> 0x%" PRIx64 ", vaddr 0x%" PRIx64 "\n", address, paddr, vaddr);
printf("Translate at 0x%" PRIx64 " -> 0x%" PRIx64 ", vaddr 0x%" PRIx64 "\n", address, paddr, vaddr);
#endif
ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
return ret;
ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
return ret;
}
// XXX
return 1;
@ -515,67 +515,67 @@ void dump_mmu(CPUState *env)
printf("MMU contexts: Primary: %" PRId64 ", Secondary: %" PRId64 "\n", env->dmmuregs[1], env->dmmuregs[2]);
if ((env->lsu & DMMU_E) == 0) {
printf("DMMU disabled\n");
printf("DMMU disabled\n");
} else {
printf("DMMU dump:\n");
for (i = 0; i < 64; i++) {
switch ((env->dtlb_tte[i] >> 61) & 3) {
default:
case 0x0:
mask = " 8k";
break;
case 0x1:
mask = " 64k";
break;
case 0x2:
mask = "512k";
break;
case 0x3:
mask = " 4M";
break;
}
if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0) {
printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx ", %s, %s, %s, %s, ctx %" PRId64 "\n",
env->dtlb_tag[i] & ~0x1fffULL,
env->dtlb_tte[i] & 0x1ffffffe000ULL,
mask,
env->dtlb_tte[i] & 0x4? "priv": "user",
env->dtlb_tte[i] & 0x2? "RW": "RO",
env->dtlb_tte[i] & 0x40? "locked": "unlocked",
env->dtlb_tag[i] & 0x1fffULL);
}
}
printf("DMMU dump:\n");
for (i = 0; i < 64; i++) {
switch ((env->dtlb_tte[i] >> 61) & 3) {
default:
case 0x0:
mask = " 8k";
break;
case 0x1:
mask = " 64k";
break;
case 0x2:
mask = "512k";
break;
case 0x3:
mask = " 4M";
break;
}
if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0) {
printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx ", %s, %s, %s, %s, ctx %" PRId64 "\n",
env->dtlb_tag[i] & ~0x1fffULL,
env->dtlb_tte[i] & 0x1ffffffe000ULL,
mask,
env->dtlb_tte[i] & 0x4? "priv": "user",
env->dtlb_tte[i] & 0x2? "RW": "RO",
env->dtlb_tte[i] & 0x40? "locked": "unlocked",
env->dtlb_tag[i] & 0x1fffULL);
}
}
}
if ((env->lsu & IMMU_E) == 0) {
printf("IMMU disabled\n");
printf("IMMU disabled\n");
} else {
printf("IMMU dump:\n");
for (i = 0; i < 64; i++) {
switch ((env->itlb_tte[i] >> 61) & 3) {
default:
case 0x0:
mask = " 8k";
break;
case 0x1:
mask = " 64k";
break;
case 0x2:
mask = "512k";
break;
case 0x3:
mask = " 4M";
break;
}
if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0) {
printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx ", %s, %s, %s, ctx %" PRId64 "\n",
env->itlb_tag[i] & ~0x1fffULL,
env->itlb_tte[i] & 0x1ffffffe000ULL,
mask,
env->itlb_tte[i] & 0x4? "priv": "user",
env->itlb_tte[i] & 0x40? "locked": "unlocked",
env->itlb_tag[i] & 0x1fffULL);
}
}
printf("IMMU dump:\n");
for (i = 0; i < 64; i++) {
switch ((env->itlb_tte[i] >> 61) & 3) {
default:
case 0x0:
mask = " 8k";
break;
case 0x1:
mask = " 64k";
break;
case 0x2:
mask = "512k";
break;
case 0x3:
mask = " 4M";
break;
}
if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0) {
printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx ", %s, %s, %s, ctx %" PRId64 "\n",
env->itlb_tag[i] & ~0x1fffULL,
env->itlb_tte[i] & 0x1ffffffe000ULL,
mask,
env->itlb_tte[i] & 0x4? "priv": "user",
env->itlb_tte[i] & 0x40? "locked": "unlocked",
env->itlb_tag[i] & 0x1fffULL);
}
}
}
}
#endif /* DEBUG_MMU */

View File

@ -376,33 +376,33 @@ void OPPROTO op_add_T1_T0_cc(void)
env->psr = 0;
#ifdef TARGET_SPARC64
if (!(T0 & 0xffffffff))
env->psr |= PSR_ZERO;
env->psr |= PSR_ZERO;
if ((int32_t) T0 < 0)
env->psr |= PSR_NEG;
env->psr |= PSR_NEG;
if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
env->psr |= PSR_CARRY;
env->psr |= PSR_CARRY;
if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
env->psr |= PSR_OVF;
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
env->psr |= PSR_OVF;
env->xcc = 0;
if (!T0)
env->xcc |= PSR_ZERO;
env->xcc |= PSR_ZERO;
if ((int64_t) T0 < 0)
env->xcc |= PSR_NEG;
env->xcc |= PSR_NEG;
if (T0 < src1)
env->xcc |= PSR_CARRY;
env->xcc |= PSR_CARRY;
if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
env->xcc |= PSR_OVF;
env->xcc |= PSR_OVF;
#else
if (!T0)
env->psr |= PSR_ZERO;
env->psr |= PSR_ZERO;
if ((int32_t) T0 < 0)
env->psr |= PSR_NEG;
env->psr |= PSR_NEG;
if (T0 < src1)
env->psr |= PSR_CARRY;
env->psr |= PSR_CARRY;
if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
env->psr |= PSR_OVF;
env->psr |= PSR_OVF;
#endif
FORCE_RET();
}
@ -448,26 +448,26 @@ void OPPROTO op_addx_T1_T0_cc(void)
}
#ifdef TARGET_SPARC64
if (!(T0 & 0xffffffff))
env->psr |= PSR_ZERO;
env->psr |= PSR_ZERO;
if ((int32_t) T0 < 0)
env->psr |= PSR_NEG;
env->psr |= PSR_NEG;
if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
env->psr |= PSR_OVF;
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
env->psr |= PSR_OVF;
if (!T0)
env->xcc |= PSR_ZERO;
env->xcc |= PSR_ZERO;
if ((int64_t) T0 < 0)
env->xcc |= PSR_NEG;
env->xcc |= PSR_NEG;
if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
env->xcc |= PSR_OVF;
env->xcc |= PSR_OVF;
#else
if (!T0)
env->psr |= PSR_ZERO;
env->psr |= PSR_ZERO;
if ((int32_t) T0 < 0)
env->psr |= PSR_NEG;
env->psr |= PSR_NEG;
if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
env->psr |= PSR_OVF;
env->psr |= PSR_OVF;
#endif
FORCE_RET();
}
@ -481,37 +481,37 @@ void OPPROTO op_tadd_T1_T0_cc(void)
env->psr = 0;
#ifdef TARGET_SPARC64
if (!(T0 & 0xffffffff))
env->psr |= PSR_ZERO;
env->psr |= PSR_ZERO;
if ((int32_t) T0 < 0)
env->psr |= PSR_NEG;
env->psr |= PSR_NEG;
if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
env->psr |= PSR_CARRY;
env->psr |= PSR_CARRY;
if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
env->psr |= PSR_OVF;
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
env->psr |= PSR_OVF;
if ((src1 & 0x03) || (T1 & 0x03))
env->psr |= PSR_OVF;
env->psr |= PSR_OVF;
env->xcc = 0;
if (!T0)
env->xcc |= PSR_ZERO;
env->xcc |= PSR_ZERO;
if ((int64_t) T0 < 0)
env->xcc |= PSR_NEG;
env->xcc |= PSR_NEG;
if (T0 < src1)
env->xcc |= PSR_CARRY;
env->xcc |= PSR_CARRY;
if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
env->xcc |= PSR_OVF;
env->xcc |= PSR_OVF;
#else
if (!T0)
env->psr |= PSR_ZERO;
env->psr |= PSR_ZERO;
if ((int32_t) T0 < 0)
env->psr |= PSR_NEG;
env->psr |= PSR_NEG;
if (T0 < src1)
env->psr |= PSR_CARRY;
env->psr |= PSR_CARRY;
if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
env->psr |= PSR_OVF;
env->psr |= PSR_OVF;
if ((src1 & 0x03) || (T1 & 0x03))
env->psr |= PSR_OVF;
env->psr |= PSR_OVF;
#endif
FORCE_RET();
}
@ -528,7 +528,7 @@ void OPPROTO op_tadd_T1_T0_ccTV(void)
#ifdef TARGET_SPARC64
if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
raise_exception(TT_TOVF);
#else
if ((src1 & 0x03) || (T1 & 0x03))
@ -538,26 +538,26 @@ void OPPROTO op_tadd_T1_T0_ccTV(void)
env->psr = 0;
#ifdef TARGET_SPARC64
if (!(T0 & 0xffffffff))
env->psr |= PSR_ZERO;
env->psr |= PSR_ZERO;
if ((int32_t) T0 < 0)
env->psr |= PSR_NEG;
env->psr |= PSR_NEG;
if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
env->psr |= PSR_CARRY;
env->psr |= PSR_CARRY;
env->xcc = 0;
if (!T0)
env->xcc |= PSR_ZERO;
env->xcc |= PSR_ZERO;
if ((int64_t) T0 < 0)
env->xcc |= PSR_NEG;
env->xcc |= PSR_NEG;
if (T0 < src1)
env->xcc |= PSR_CARRY;
env->xcc |= PSR_CARRY;
#else
if (!T0)
env->psr |= PSR_ZERO;
env->psr |= PSR_ZERO;
if ((int32_t) T0 < 0)
env->psr |= PSR_NEG;
env->psr |= PSR_NEG;
if (T0 < src1)
env->psr |= PSR_CARRY;
env->psr |= PSR_CARRY;
#endif
FORCE_RET();
}
@ -576,33 +576,33 @@ void OPPROTO op_sub_T1_T0_cc(void)
env->psr = 0;
#ifdef TARGET_SPARC64
if (!(T0 & 0xffffffff))
env->psr |= PSR_ZERO;
env->psr |= PSR_ZERO;
if ((int32_t) T0 < 0)
env->psr |= PSR_NEG;
env->psr |= PSR_NEG;
if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
env->psr |= PSR_CARRY;
env->psr |= PSR_CARRY;
if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
env->psr |= PSR_OVF;
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
env->psr |= PSR_OVF;
env->xcc = 0;
if (!T0)
env->xcc |= PSR_ZERO;
env->xcc |= PSR_ZERO;
if ((int64_t) T0 < 0)
env->xcc |= PSR_NEG;
env->xcc |= PSR_NEG;
if (src1 < T1)
env->xcc |= PSR_CARRY;
env->xcc |= PSR_CARRY;
if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
env->xcc |= PSR_OVF;
env->xcc |= PSR_OVF;
#else
if (!T0)
env->psr |= PSR_ZERO;
env->psr |= PSR_ZERO;
if ((int32_t) T0 < 0)
env->psr |= PSR_NEG;
env->psr |= PSR_NEG;
if (src1 < T1)
env->psr |= PSR_CARRY;
env->psr |= PSR_CARRY;
if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
env->psr |= PSR_OVF;
env->psr |= PSR_OVF;
#endif
FORCE_RET();
}
@ -648,26 +648,26 @@ void OPPROTO op_subx_T1_T0_cc(void)
}
#ifdef TARGET_SPARC64
if (!(T0 & 0xffffffff))
env->psr |= PSR_ZERO;
env->psr |= PSR_ZERO;
if ((int32_t) T0 < 0)
env->psr |= PSR_NEG;
env->psr |= PSR_NEG;
if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
env->psr |= PSR_OVF;
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
env->psr |= PSR_OVF;
if (!T0)
env->xcc |= PSR_ZERO;
env->xcc |= PSR_ZERO;
if ((int64_t) T0 < 0)
env->xcc |= PSR_NEG;
env->xcc |= PSR_NEG;
if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
env->xcc |= PSR_OVF;
env->xcc |= PSR_OVF;
#else
if (!T0)
env->psr |= PSR_ZERO;
env->psr |= PSR_ZERO;
if ((int32_t) T0 < 0)
env->psr |= PSR_NEG;
env->psr |= PSR_NEG;
if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
env->psr |= PSR_OVF;
env->psr |= PSR_OVF;
#endif
FORCE_RET();
}
@ -681,37 +681,37 @@ void OPPROTO op_tsub_T1_T0_cc(void)
env->psr = 0;
#ifdef TARGET_SPARC64
if (!(T0 & 0xffffffff))
env->psr |= PSR_ZERO;
env->psr |= PSR_ZERO;
if ((int32_t) T0 < 0)
env->psr |= PSR_NEG;
env->psr |= PSR_NEG;
if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
env->psr |= PSR_CARRY;
env->psr |= PSR_CARRY;
if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
env->psr |= PSR_OVF;
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
env->psr |= PSR_OVF;
if ((src1 & 0x03) || (T1 & 0x03))
env->psr |= PSR_OVF;
env->psr |= PSR_OVF;
env->xcc = 0;
if (!T0)
env->xcc |= PSR_ZERO;
env->xcc |= PSR_ZERO;
if ((int64_t) T0 < 0)
env->xcc |= PSR_NEG;
env->xcc |= PSR_NEG;
if (src1 < T1)
env->xcc |= PSR_CARRY;
env->xcc |= PSR_CARRY;
if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
env->xcc |= PSR_OVF;
env->xcc |= PSR_OVF;
#else
if (!T0)
env->psr |= PSR_ZERO;
env->psr |= PSR_ZERO;
if ((int32_t) T0 < 0)
env->psr |= PSR_NEG;
env->psr |= PSR_NEG;
if (src1 < T1)
env->psr |= PSR_CARRY;
env->psr |= PSR_CARRY;
if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
env->psr |= PSR_OVF;
env->psr |= PSR_OVF;
if ((src1 & 0x03) || (T1 & 0x03))
env->psr |= PSR_OVF;
env->psr |= PSR_OVF;
#endif
FORCE_RET();
}
@ -728,7 +728,7 @@ void OPPROTO op_tsub_T1_T0_ccTV(void)
#ifdef TARGET_SPARC64
if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
raise_exception(TT_TOVF);
#else
if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
@ -738,26 +738,26 @@ void OPPROTO op_tsub_T1_T0_ccTV(void)
env->psr = 0;
#ifdef TARGET_SPARC64
if (!(T0 & 0xffffffff))
env->psr |= PSR_ZERO;
env->psr |= PSR_ZERO;
if ((int32_t) T0 < 0)
env->psr |= PSR_NEG;
env->psr |= PSR_NEG;
if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
env->psr |= PSR_CARRY;
env->psr |= PSR_CARRY;
env->xcc = 0;
if (!T0)
env->xcc |= PSR_ZERO;
env->xcc |= PSR_ZERO;
if ((int64_t) T0 < 0)
env->xcc |= PSR_NEG;
env->xcc |= PSR_NEG;
if (src1 < T1)
env->xcc |= PSR_CARRY;
env->xcc |= PSR_CARRY;
#else
if (!T0)
env->psr |= PSR_ZERO;
env->psr |= PSR_ZERO;
if ((int32_t) T0 < 0)
env->psr |= PSR_NEG;
env->psr |= PSR_NEG;
if (src1 < T1)
env->psr |= PSR_CARRY;
env->psr |= PSR_CARRY;
#endif
FORCE_RET();
}
@ -833,13 +833,13 @@ void OPPROTO op_mulscc_T1_T0(void)
T0 += T1;
env->psr = 0;
if (!T0)
env->psr |= PSR_ZERO;
env->psr |= PSR_ZERO;
if ((int32_t) T0 < 0)
env->psr |= PSR_NEG;
env->psr |= PSR_NEG;
if (T0 < src1)
env->psr |= PSR_CARRY;
env->psr |= PSR_CARRY;
if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
env->psr |= PSR_OVF;
env->psr |= PSR_OVF;
env->y = (b2 << 31) | (env->y >> 1);
FORCE_RET();
}
@ -858,11 +858,11 @@ void OPPROTO op_udiv_T1_T0(void)
x0 = x0 / x1;
if (x0 > 0xffffffff) {
T0 = 0xffffffff;
T1 = 1;
T0 = 0xffffffff;
T1 = 1;
} else {
T0 = x0;
T1 = 0;
T0 = x0;
T1 = 0;
}
FORCE_RET();
}
@ -881,11 +881,11 @@ void OPPROTO op_sdiv_T1_T0(void)
x0 = x0 / x1;
if ((int32_t) x0 != x0) {
T0 = x0 < 0? 0x80000000: 0x7fffffff;
T1 = 1;
T0 = x0 < 0? 0x80000000: 0x7fffffff;
T1 = 1;
} else {
T0 = x0;
T1 = 0;
T0 = x0;
T1 = 0;
}
FORCE_RET();
}
@ -895,24 +895,24 @@ void OPPROTO op_div_cc(void)
env->psr = 0;
#ifdef TARGET_SPARC64
if (!T0)
env->psr |= PSR_ZERO;
env->psr |= PSR_ZERO;
if ((int32_t) T0 < 0)
env->psr |= PSR_NEG;
env->psr |= PSR_NEG;
if (T1)
env->psr |= PSR_OVF;
env->psr |= PSR_OVF;
env->xcc = 0;
if (!T0)
env->xcc |= PSR_ZERO;
env->xcc |= PSR_ZERO;
if ((int64_t) T0 < 0)
env->xcc |= PSR_NEG;
env->xcc |= PSR_NEG;
#else
if (!T0)
env->psr |= PSR_ZERO;
env->psr |= PSR_ZERO;
if ((int32_t) T0 < 0)
env->psr |= PSR_NEG;
env->psr |= PSR_NEG;
if (T1)
env->psr |= PSR_OVF;
env->psr |= PSR_OVF;
#endif
FORCE_RET();
}
@ -939,9 +939,9 @@ void OPPROTO op_sdivx_T1_T0(void)
raise_exception(TT_DIV_ZERO);
}
if (T0 == INT64_MIN && T1 == -1)
T0 = INT64_MIN;
T0 = INT64_MIN;
else
T0 /= (target_long) T1;
T0 /= (target_long) T1;
FORCE_RET();
}
#endif
@ -951,20 +951,20 @@ void OPPROTO op_logic_T0_cc(void)
env->psr = 0;
#ifdef TARGET_SPARC64
if (!(T0 & 0xffffffff))
env->psr |= PSR_ZERO;
env->psr |= PSR_ZERO;
if ((int32_t) T0 < 0)
env->psr |= PSR_NEG;
env->psr |= PSR_NEG;
env->xcc = 0;
if (!T0)
env->xcc |= PSR_ZERO;
env->xcc |= PSR_ZERO;
if ((int64_t) T0 < 0)
env->xcc |= PSR_NEG;
env->xcc |= PSR_NEG;
#else
if (!T0)
env->psr |= PSR_ZERO;
env->psr |= PSR_ZERO;
if ((int32_t) T0 < 0)
env->psr |= PSR_NEG;
env->psr |= PSR_NEG;
#endif
FORCE_RET();
}
@ -1200,17 +1200,17 @@ void OPPROTO op_save(void)
cwp = (env->cwp - 1) & (NWINDOWS - 1);
if (env->cansave == 0) {
raise_exception(TT_SPILL | (env->otherwin != 0 ?
(TT_WOTHER | ((env->wstate & 0x38) >> 1)):
((env->wstate & 0x7) << 2)));
(TT_WOTHER | ((env->wstate & 0x38) >> 1)):
((env->wstate & 0x7) << 2)));
} else {
if (env->cleanwin - env->canrestore == 0) {
// XXX Clean windows without trap
raise_exception(TT_CLRWIN);
} else {
env->cansave--;
env->canrestore++;
set_cwp(cwp);
}
if (env->cleanwin - env->canrestore == 0) {
// XXX Clean windows without trap
raise_exception(TT_CLRWIN);
} else {
env->cansave--;
env->canrestore++;
set_cwp(cwp);
}
}
FORCE_RET();
}
@ -1221,12 +1221,12 @@ void OPPROTO op_restore(void)
cwp = (env->cwp + 1) & (NWINDOWS - 1);
if (env->canrestore == 0) {
raise_exception(TT_FILL | (env->otherwin != 0 ?
(TT_WOTHER | ((env->wstate & 0x38) >> 1)):
((env->wstate & 0x7) << 2)));
(TT_WOTHER | ((env->wstate & 0x38) >> 1)):
((env->wstate & 0x7) << 2)));
} else {
env->cansave++;
env->canrestore--;
set_cwp(cwp);
env->cansave++;
env->canrestore--;
set_cwp(cwp);
}
FORCE_RET();
}
@ -1576,15 +1576,15 @@ void OPPROTO op_clear_ieee_excp_and_FTT(void)
#define F_BINOP(name) \
F_OP(name, s) \
{ \
set_float_exception_flags(0, &env->fp_status); \
set_float_exception_flags(0, &env->fp_status); \
FT0 = float32_ ## name (FT0, FT1, &env->fp_status); \
check_ieee_exceptions(); \
check_ieee_exceptions(); \
} \
F_OP(name, d) \
{ \
set_float_exception_flags(0, &env->fp_status); \
set_float_exception_flags(0, &env->fp_status); \
DT0 = float64_ ## name (DT0, DT1, &env->fp_status); \
check_ieee_exceptions(); \
check_ieee_exceptions(); \
}
F_BINOP(add);
@ -1784,27 +1784,27 @@ void OPPROTO op_fdtox(void)
void OPPROTO op_fmovs_cc(void)
{
if (T2)
FT0 = FT1;
FT0 = FT1;
}
void OPPROTO op_fmovd_cc(void)
{
if (T2)
DT0 = DT1;
DT0 = DT1;
}
void OPPROTO op_mov_cc(void)
{
if (T2)
T0 = T1;
T0 = T1;
}
void OPPROTO op_flushw(void)
{
if (env->cansave != NWINDOWS - 2) {
raise_exception(TT_SPILL | (env->otherwin != 0 ?
(TT_WOTHER | ((env->wstate & 0x38) >> 1)):
((env->wstate & 0x7) << 2)));
(TT_WOTHER | ((env->wstate & 0x38) >> 1)):
((env->wstate & 0x7) << 2)));
}
}
@ -1812,9 +1812,9 @@ void OPPROTO op_saved(void)
{
env->cansave++;
if (env->otherwin == 0)
env->canrestore--;
env->canrestore--;
else
env->otherwin--;
env->otherwin--;
FORCE_RET();
}
@ -1822,11 +1822,11 @@ void OPPROTO op_restored(void)
{
env->canrestore++;
if (env->cleanwin < NWINDOWS - 1)
env->cleanwin++;
env->cleanwin++;
if (env->otherwin == 0)
env->cansave--;
env->cansave--;
else
env->otherwin--;
env->otherwin--;
FORCE_RET();
}

View File

@ -16,29 +16,29 @@ 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;
/* 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;
}
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;
}
}
}
@ -155,33 +155,33 @@ void helper_ld_asi(int asi, int size, int sign)
case 2: /* SuperSparc MXCC registers */
break;
case 3: /* MMU probe */
{
int mmulev;
{
int mmulev;
mmulev = (T0 >> 8) & 15;
if (mmulev > 4)
ret = 0;
else {
ret = mmu_probe(env, T0, mmulev);
//bswap32s(&ret);
}
mmulev = (T0 >> 8) & 15;
if (mmulev > 4)
ret = 0;
else {
ret = mmu_probe(env, T0, mmulev);
//bswap32s(&ret);
}
#ifdef DEBUG_MMU
printf("mmu_probe: 0x%08x (lev %d) -> 0x%08x\n", T0, mmulev, ret);
printf("mmu_probe: 0x%08x (lev %d) -> 0x%08x\n", T0, mmulev, ret);
#endif
}
break;
}
break;
case 4: /* read MMU regs */
{
int reg = (T0 >> 8) & 0xf;
{
int reg = (T0 >> 8) & 0xf;
ret = env->mmuregs[reg];
if (reg == 3) /* Fault status cleared on read */
env->mmuregs[reg] = 0;
ret = env->mmuregs[reg];
if (reg == 3) /* Fault status cleared on read */
env->mmuregs[reg] = 0;
#ifdef DEBUG_MMU
printf("mmu_read: reg[%d] = 0x%08x\n", reg, ret);
printf("mmu_read: reg[%d] = 0x%08x\n", reg, ret);
#endif
}
break;
}
break;
case 9: /* Supervisor code access */
switch(size) {
case 1:
@ -218,11 +218,11 @@ void helper_ld_asi(int asi, int size, int sign)
ret = ldl_phys(T0 & ~3);
break;
case 8:
ret = ldl_phys(T0 & ~3);
T0 = ldl_phys((T0 + 4) & ~3);
break;
ret = ldl_phys(T0 & ~3);
T0 = ldl_phys((T0 + 4) & ~3);
break;
}
break;
break;
case 0x2e: /* MMU passthrough, 0xexxxxxxxx */
case 0x2f: /* MMU passthrough, 0xfxxxxxxxx */
switch(size) {
@ -244,14 +244,14 @@ void helper_ld_asi(int asi, int size, int sign)
| ((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;
}
break;
break;
case 0x21 ... 0x2d: /* MMU passthrough, unassigned */
default:
do_unassigned_access(T0, 0, 0, 1);
ret = 0;
break;
ret = 0;
break;
}
T1 = ret;
}
@ -262,48 +262,48 @@ void helper_st_asi(int asi, int size, int sign)
case 2: /* SuperSparc MXCC registers */
break;
case 3: /* MMU flush */
{
int mmulev;
{
int mmulev;
mmulev = (T0 >> 8) & 15;
mmulev = (T0 >> 8) & 15;
#ifdef DEBUG_MMU
printf("mmu flush level %d\n", mmulev);
printf("mmu flush level %d\n", mmulev);
#endif
switch (mmulev) {
case 0: // flush page
tlb_flush_page(env, T0 & 0xfffff000);
break;
case 1: // flush segment (256k)
case 2: // flush region (16M)
case 3: // flush context (4G)
case 4: // flush entire
tlb_flush(env, 1);
break;
default:
break;
}
switch (mmulev) {
case 0: // flush page
tlb_flush_page(env, T0 & 0xfffff000);
break;
case 1: // flush segment (256k)
case 2: // flush region (16M)
case 3: // flush context (4G)
case 4: // flush entire
tlb_flush(env, 1);
break;
default:
break;
}
#ifdef DEBUG_MMU
dump_mmu(env);
dump_mmu(env);
#endif
return;
}
return;
}
case 4: /* write MMU regs */
{
int reg = (T0 >> 8) & 0xf;
uint32_t oldreg;
{
int reg = (T0 >> 8) & 0xf;
uint32_t oldreg;
oldreg = env->mmuregs[reg];
oldreg = env->mmuregs[reg];
switch(reg) {
case 0:
env->mmuregs[reg] &= ~(MMU_E | MMU_NF);
env->mmuregs[reg] |= T1 & (MMU_E | MMU_NF);
// Mappings generated during no-fault mode or MMU
// disabled mode are invalid in normal mode
env->mmuregs[reg] &= ~(MMU_E | MMU_NF);
env->mmuregs[reg] |= T1 & (MMU_E | MMU_NF);
// Mappings generated during no-fault mode or MMU
// disabled mode are invalid in normal mode
if (oldreg != env->mmuregs[reg])
tlb_flush(env, 1);
break;
case 2:
env->mmuregs[reg] = T1;
env->mmuregs[reg] = T1;
if (oldreg != env->mmuregs[reg]) {
/* we flush when the MMU context changes because
QEMU has no MMU context support */
@ -314,17 +314,17 @@ void helper_st_asi(int asi, int size, int sign)
case 4:
break;
default:
env->mmuregs[reg] = T1;
env->mmuregs[reg] = T1;
break;
}
#ifdef DEBUG_MMU
if (oldreg != env->mmuregs[reg]) {
printf("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, oldreg, env->mmuregs[reg]);
}
dump_mmu(env);
dump_mmu(env);
#endif
return;
}
return;
}
case 0xc: /* I-cache tag */
case 0xd: /* I-cache data */
case 0xe: /* D-cache tag */
@ -336,10 +336,10 @@ void helper_st_asi(int asi, int size, int sign)
case 0x14: /* I/D-cache flush user */
break;
case 0x17: /* Block copy, sta access */
{
// value (T1) = src
// address (T0) = dst
// copy 32 bytes
{
// value (T1) = src
// address (T0) = dst
// copy 32 bytes
unsigned int i;
uint32_t src = T1 & ~3, dst = T0 & ~3, temp;
@ -347,13 +347,13 @@ void helper_st_asi(int asi, int size, int sign)
temp = ldl_kernel(src);
stl_kernel(dst, temp);
}
}
return;
}
return;
case 0x1f: /* Block fill, stda access */
{
// value (T1, T2)
// address (T0) = dst
// fill 32 bytes
{
// value (T1, T2)
// address (T0) = dst
// fill 32 bytes
unsigned int i;
uint32_t dst = T0 & 7;
uint64_t val;
@ -362,10 +362,10 @@ void helper_st_asi(int asi, int size, int sign)
for (i = 0; i < 32; i += 8, dst += 8)
stq_kernel(dst, val);
}
return;
}
return;
case 0x20: /* MMU passthrough */
{
{
switch(size) {
case 1:
stb_phys(T0, T1);
@ -382,11 +382,11 @@ void helper_st_asi(int asi, int size, int sign)
stl_phys((T0 + 4) & ~3, T2);
break;
}
}
return;
}
return;
case 0x2e: /* MMU passthrough, 0xexxxxxxxx */
case 0x2f: /* MMU passthrough, 0xfxxxxxxxx */
{
{
switch(size) {
case 1:
stb_phys((target_phys_addr_t)T0
@ -408,8 +408,8 @@ void helper_st_asi(int asi, int size, int sign)
| ((target_phys_addr_t)(asi & 0xf) << 32), T1);
break;
}
}
return;
}
return;
case 0x31: /* Ross RT620 I-cache flush */
case 0x36: /* I-cache flash clear */
case 0x37: /* D-cache flash clear */
@ -418,7 +418,7 @@ void helper_st_asi(int asi, int size, int sign)
case 0x21 ... 0x2d: /* MMU passthrough, unassigned */
default:
do_unassigned_access(T0, 1, 0, 1);
return;
return;
}
}
@ -429,12 +429,12 @@ void helper_ld_asi(int asi, int size, int sign)
uint64_t ret = 0;
if (asi < 0x80 && (env->pstate & PS_PRIV) == 0)
raise_exception(TT_PRIV_ACT);
raise_exception(TT_PRIV_ACT);
switch (asi) {
case 0x14: // Bypass
case 0x15: // Bypass, non-cacheable
{
{
switch(size) {
case 1:
ret = ldub_phys(T0);
@ -450,8 +450,8 @@ void helper_ld_asi(int asi, int size, int sign)
ret = ldq_phys(T0 & ~7);
break;
}
break;
}
break;
}
case 0x04: // Nucleus
case 0x0c: // Nucleus Little Endian (LE)
case 0x10: // As if user primary
@ -469,58 +469,58 @@ void helper_ld_asi(int asi, int size, int sign)
case 0x89: // Secondary LE
case 0x8a: // Primary no-fault LE
case 0x8b: // Secondary no-fault LE
// XXX
break;
// XXX
break;
case 0x45: // LSU
ret = env->lsu;
break;
ret = env->lsu;
break;
case 0x50: // I-MMU regs
{
int reg = (T0 >> 3) & 0xf;
{
int reg = (T0 >> 3) & 0xf;
ret = env->immuregs[reg];
break;
}
ret = env->immuregs[reg];
break;
}
case 0x51: // I-MMU 8k TSB pointer
case 0x52: // I-MMU 64k TSB pointer
case 0x55: // I-MMU data access
// XXX
break;
// XXX
break;
case 0x56: // I-MMU tag read
{
unsigned int i;
{
unsigned int i;
for (i = 0; i < 64; i++) {
// Valid, ctx match, vaddr match
if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0 &&
env->itlb_tag[i] == T0) {
ret = env->itlb_tag[i];
break;
}
}
break;
}
for (i = 0; i < 64; i++) {
// Valid, ctx match, vaddr match
if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0 &&
env->itlb_tag[i] == T0) {
ret = env->itlb_tag[i];
break;
}
}
break;
}
case 0x58: // D-MMU regs
{
int reg = (T0 >> 3) & 0xf;
{
int reg = (T0 >> 3) & 0xf;
ret = env->dmmuregs[reg];
break;
}
ret = env->dmmuregs[reg];
break;
}
case 0x5e: // D-MMU tag read
{
unsigned int i;
{
unsigned int i;
for (i = 0; i < 64; i++) {
// Valid, ctx match, vaddr match
if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0 &&
env->dtlb_tag[i] == T0) {
ret = env->dtlb_tag[i];
break;
}
}
break;
}
for (i = 0; i < 64; i++) {
// Valid, ctx match, vaddr match
if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0 &&
env->dtlb_tag[i] == T0) {
ret = env->dtlb_tag[i];
break;
}
}
break;
}
case 0x59: // D-MMU 8k TSB pointer
case 0x5a: // D-MMU 64k TSB pointer
case 0x5b: // D-MMU data pointer
@ -528,8 +528,8 @@ void helper_ld_asi(int asi, int size, int sign)
case 0x48: // Interrupt dispatch, RO
case 0x49: // Interrupt data receive
case 0x7f: // Incoming interrupt vector, RO
// XXX
break;
// XXX
break;
case 0x54: // I-MMU data in, WO
case 0x57: // I-MMU demap, WO
case 0x5c: // D-MMU data in, WO
@ -537,8 +537,8 @@ void helper_ld_asi(int asi, int size, int sign)
case 0x77: // Interrupt vector, WO
default:
do_unassigned_access(T0, 0, 0, 1);
ret = 0;
break;
ret = 0;
break;
}
T1 = ret;
}
@ -546,12 +546,12 @@ void helper_ld_asi(int asi, int size, int sign)
void helper_st_asi(int asi, int size, int sign)
{
if (asi < 0x80 && (env->pstate & PS_PRIV) == 0)
raise_exception(TT_PRIV_ACT);
raise_exception(TT_PRIV_ACT);
switch(asi) {
case 0x14: // Bypass
case 0x15: // Bypass, non-cacheable
{
{
switch(size) {
case 1:
stb_phys(T0, T1);
@ -567,8 +567,8 @@ void helper_st_asi(int asi, int size, int sign)
stq_phys(T0 & ~7, T1);
break;
}
}
return;
}
return;
case 0x04: // Nucleus
case 0x0c: // Nucleus Little Endian (LE)
case 0x10: // As if user primary
@ -582,31 +582,31 @@ void helper_st_asi(int asi, int size, int sign)
case 0x4a: // UPA config
case 0x88: // Primary LE
case 0x89: // Secondary LE
// XXX
return;
// XXX
return;
case 0x45: // LSU
{
uint64_t oldreg;
{
uint64_t oldreg;
oldreg = env->lsu;
env->lsu = T1 & (DMMU_E | IMMU_E);
// Mappings generated during D/I MMU disabled mode are
// invalid in normal mode
if (oldreg != env->lsu) {
oldreg = env->lsu;
env->lsu = T1 & (DMMU_E | IMMU_E);
// Mappings generated during D/I MMU disabled mode are
// invalid in normal mode
if (oldreg != env->lsu) {
#ifdef DEBUG_MMU
printf("LSU change: 0x%" PRIx64 " -> 0x%" PRIx64 "\n", oldreg, env->lsu);
dump_mmu(env);
dump_mmu(env);
#endif
tlb_flush(env, 1);
}
return;
}
tlb_flush(env, 1);
}
return;
}
case 0x50: // I-MMU regs
{
int reg = (T0 >> 3) & 0xf;
uint64_t oldreg;
{
int reg = (T0 >> 3) & 0xf;
uint64_t oldreg;
oldreg = env->immuregs[reg];
oldreg = env->immuregs[reg];
switch(reg) {
case 0: // RO
case 4:
@ -617,73 +617,73 @@ void helper_st_asi(int asi, int size, int sign)
case 8:
return;
case 3: // SFSR
if ((T1 & 1) == 0)
T1 = 0; // Clear SFSR
if ((T1 & 1) == 0)
T1 = 0; // Clear SFSR
break;
case 5: // TSB access
case 6: // Tag access
default:
break;
}
env->immuregs[reg] = T1;
env->immuregs[reg] = T1;
#ifdef DEBUG_MMU
if (oldreg != env->immuregs[reg]) {
printf("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->immuregs[reg]);
}
dump_mmu(env);
dump_mmu(env);
#endif
return;
}
return;
}
case 0x54: // I-MMU data in
{
unsigned int i;
{
unsigned int i;
// Try finding an invalid entry
for (i = 0; i < 64; i++) {
if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0) {
env->itlb_tag[i] = env->immuregs[6];
env->itlb_tte[i] = T1;
return;
}
}
// Try finding an unlocked entry
for (i = 0; i < 64; i++) {
if ((env->itlb_tte[i] & 0x40) == 0) {
env->itlb_tag[i] = env->immuregs[6];
env->itlb_tte[i] = T1;
return;
}
}
// error state?
return;
}
// Try finding an invalid entry
for (i = 0; i < 64; i++) {
if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0) {
env->itlb_tag[i] = env->immuregs[6];
env->itlb_tte[i] = T1;
return;
}
}
// Try finding an unlocked entry
for (i = 0; i < 64; i++) {
if ((env->itlb_tte[i] & 0x40) == 0) {
env->itlb_tag[i] = env->immuregs[6];
env->itlb_tte[i] = T1;
return;
}
}
// error state?
return;
}
case 0x55: // I-MMU data access
{
unsigned int i = (T0 >> 3) & 0x3f;
{
unsigned int i = (T0 >> 3) & 0x3f;
env->itlb_tag[i] = env->immuregs[6];
env->itlb_tte[i] = T1;
return;
}
env->itlb_tag[i] = env->immuregs[6];
env->itlb_tte[i] = T1;
return;
}
case 0x57: // I-MMU demap
// XXX
return;
// XXX
return;
case 0x58: // D-MMU regs
{
int reg = (T0 >> 3) & 0xf;
uint64_t oldreg;
{
int reg = (T0 >> 3) & 0xf;
uint64_t oldreg;
oldreg = env->dmmuregs[reg];
oldreg = env->dmmuregs[reg];
switch(reg) {
case 0: // RO
case 4:
return;
case 3: // SFSR
if ((T1 & 1) == 0) {
T1 = 0; // Clear SFSR, Fault address
env->dmmuregs[4] = 0;
}
env->dmmuregs[reg] = T1;
if ((T1 & 1) == 0) {
T1 = 0; // Clear SFSR, Fault address
env->dmmuregs[4] = 0;
}
env->dmmuregs[reg] = T1;
break;
case 1: // Primary context
case 2: // Secondary context
@ -694,50 +694,50 @@ void helper_st_asi(int asi, int size, int sign)
default:
break;
}
env->dmmuregs[reg] = T1;
env->dmmuregs[reg] = T1;
#ifdef DEBUG_MMU
if (oldreg != env->dmmuregs[reg]) {
printf("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->dmmuregs[reg]);
}
dump_mmu(env);
dump_mmu(env);
#endif
return;
}
return;
}
case 0x5c: // D-MMU data in
{
unsigned int i;
{
unsigned int i;
// Try finding an invalid entry
for (i = 0; i < 64; i++) {
if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0) {
env->dtlb_tag[i] = env->dmmuregs[6];
env->dtlb_tte[i] = T1;
return;
}
}
// Try finding an unlocked entry
for (i = 0; i < 64; i++) {
if ((env->dtlb_tte[i] & 0x40) == 0) {
env->dtlb_tag[i] = env->dmmuregs[6];
env->dtlb_tte[i] = T1;
return;
}
}
// error state?
return;
}
// Try finding an invalid entry
for (i = 0; i < 64; i++) {
if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0) {
env->dtlb_tag[i] = env->dmmuregs[6];
env->dtlb_tte[i] = T1;
return;
}
}
// Try finding an unlocked entry
for (i = 0; i < 64; i++) {
if ((env->dtlb_tte[i] & 0x40) == 0) {
env->dtlb_tag[i] = env->dmmuregs[6];
env->dtlb_tte[i] = T1;
return;
}
}
// error state?
return;
}
case 0x5d: // D-MMU data access
{
unsigned int i = (T0 >> 3) & 0x3f;
{
unsigned int i = (T0 >> 3) & 0x3f;
env->dtlb_tag[i] = env->dmmuregs[6];
env->dtlb_tte[i] = T1;
return;
}
env->dtlb_tag[i] = env->dmmuregs[6];
env->dtlb_tte[i] = T1;
return;
}
case 0x5f: // D-MMU demap
case 0x49: // Interrupt data receive
// XXX
return;
// XXX
return;
case 0x51: // I-MMU 8k TSB pointer, RO
case 0x52: // I-MMU 64k TSB pointer, RO
case 0x56: // I-MMU tag read, RO
@ -753,7 +753,7 @@ void helper_st_asi(int asi, int size, int sign)
case 0x8b: // Secondary no-fault LE, RO
default:
do_unassigned_access(T0, 1, 0, 1);
return;
return;
}
}
#endif
@ -783,17 +783,17 @@ void helper_ldfsr(void)
switch (env->fsr & FSR_RD_MASK) {
case FSR_RD_NEAREST:
rnd_mode = float_round_nearest_even;
break;
break;
default:
case FSR_RD_ZERO:
rnd_mode = float_round_to_zero;
break;
break;
case FSR_RD_POS:
rnd_mode = float_round_up;
break;
break;
case FSR_RD_NEG:
rnd_mode = float_round_down;
break;
break;
}
set_float_rounding_mode(rnd_mode, &env->fp_status);
}
@ -835,13 +835,13 @@ static inline uint64_t *get_gregset(uint64_t pstate)
switch (pstate) {
default:
case 0:
return env->bgregs;
return env->bgregs;
case PS_AG:
return env->agregs;
return env->agregs;
case PS_MG:
return env->mgregs;
return env->mgregs;
case PS_IG:
return env->igregs;
return env->igregs;
}
}
@ -853,11 +853,11 @@ static inline void change_pstate(uint64_t new_pstate)
pstate_regs = env->pstate & 0xc01;
new_pstate_regs = new_pstate & 0xc01;
if (new_pstate_regs != pstate_regs) {
// Switch global register bank
src = get_gregset(new_pstate_regs);
dst = get_gregset(pstate_regs);
memcpy32(dst, env->gregs);
memcpy32(env->gregs, src);
// Switch global register bank
src = get_gregset(new_pstate_regs);
dst = get_gregset(pstate_regs);
memcpy32(dst, env->gregs);
memcpy32(env->gregs, src);
}
env->pstate = new_pstate;
}
@ -927,36 +927,36 @@ void do_interrupt(int intno)
{
#ifdef DEBUG_PCALL
if (loglevel & CPU_LOG_INT) {
static int count;
fprintf(logfile, "%6d: v=%04x pc=%016" PRIx64 " npc=%016" PRIx64 " SP=%016" PRIx64 "\n",
static int count;
fprintf(logfile, "%6d: v=%04x pc=%016" PRIx64 " npc=%016" PRIx64 " SP=%016" PRIx64 "\n",
count, intno,
env->pc,
env->npc, env->regwptr[6]);
cpu_dump_state(env, logfile, fprintf, 0);
cpu_dump_state(env, logfile, fprintf, 0);
#if 0
{
int i;
uint8_t *ptr;
{
int i;
uint8_t *ptr;
fprintf(logfile, " code=");
ptr = (uint8_t *)env->pc;
for(i = 0; i < 16; i++) {
fprintf(logfile, " %02x", ldub(ptr + i));
}
fprintf(logfile, "\n");
}
fprintf(logfile, " code=");
ptr = (uint8_t *)env->pc;
for(i = 0; i < 16; i++) {
fprintf(logfile, " %02x", ldub(ptr + i));
}
fprintf(logfile, "\n");
}
#endif
count++;
count++;
}
#endif
#if !defined(CONFIG_USER_ONLY)
if (env->tl == MAXTL) {
cpu_abort(env, "Trap 0x%04x while trap level is MAXTL, Error state", env->exception_index);
return;
return;
}
#endif
env->tstate[env->tl] = ((uint64_t)GET_CCR(env) << 32) | ((env->asi & 0xff) << 24) |
((env->pstate & 0xf3f) << 8) | GET_CWP64(env);
((env->pstate & 0xf3f) << 8) | GET_CWP64(env);
env->tpc[env->tl] = env->pc;
env->tnpc[env->tl] = env->npc;
env->tt[env->tl] = intno;
@ -971,11 +971,11 @@ void do_interrupt(int intno)
env->tbr &= ~0x7fffULL;
env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
if (env->tl < MAXTL - 1) {
env->tl++;
env->tl++;
} else {
env->pstate |= PS_RED;
if (env->tl != MAXTL)
env->tl++;
env->pstate |= PS_RED;
if (env->tl != MAXTL)
env->tl++;
}
env->pc = env->tbr;
env->npc = env->pc + 4;
@ -988,32 +988,32 @@ void do_interrupt(int intno)
#ifdef DEBUG_PCALL
if (loglevel & CPU_LOG_INT) {
static int count;
fprintf(logfile, "%6d: v=%02x pc=%08x npc=%08x SP=%08x\n",
static int count;
fprintf(logfile, "%6d: v=%02x pc=%08x npc=%08x SP=%08x\n",
count, intno,
env->pc,
env->npc, env->regwptr[6]);
cpu_dump_state(env, logfile, fprintf, 0);
cpu_dump_state(env, logfile, fprintf, 0);
#if 0
{
int i;
uint8_t *ptr;
{
int i;
uint8_t *ptr;
fprintf(logfile, " code=");
ptr = (uint8_t *)env->pc;
for(i = 0; i < 16; i++) {
fprintf(logfile, " %02x", ldub(ptr + i));
}
fprintf(logfile, "\n");
}
fprintf(logfile, " code=");
ptr = (uint8_t *)env->pc;
for(i = 0; i < 16; i++) {
fprintf(logfile, " %02x", ldub(ptr + i));
}
fprintf(logfile, "\n");
}
#endif
count++;
count++;
}
#endif
#if !defined(CONFIG_USER_ONLY)
if (env->psret == 0) {
cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state", env->exception_index);
return;
return;
}
#endif
env->psret = 0;
@ -1106,7 +1106,7 @@ void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
saved_env = env;
env = cpu_single_env;
if (env->mmuregs[3]) /* Fault status register */
env->mmuregs[3] = 1; /* overflow (not read before another fault) */
env->mmuregs[3] = 1; /* overflow (not read before another fault) */
if (is_asi)
env->mmuregs[3] |= 1 << 16;
if (env->psrs)

View File

@ -2,13 +2,13 @@
#define SPARC_LD_OP(name, qp) \
void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \
{ \
T1 = (target_ulong)glue(qp, MEMSUFFIX)(T0); \
T1 = (target_ulong)glue(qp, MEMSUFFIX)(T0); \
}
#define SPARC_LD_OP_S(name, qp) \
void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \
{ \
T1 = (target_long)glue(qp, MEMSUFFIX)(T0); \
#define SPARC_LD_OP_S(name, qp) \
void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \
{ \
T1 = (target_long)glue(qp, MEMSUFFIX)(T0); \
}
#define SPARC_ST_OP(name, op) \
@ -85,7 +85,7 @@ void OPPROTO glue(op_cas, MEMSUFFIX)(void)
tmp = glue(ldl, MEMSUFFIX)(T0);
T2 &= 0xffffffffULL;
if (tmp == (T1 & 0xffffffffULL)) {
glue(stl, MEMSUFFIX)(T0, T2);
glue(stl, MEMSUFFIX)(T0, T2);
}
T2 = tmp;
}
@ -98,7 +98,7 @@ void OPPROTO glue(op_casx, MEMSUFFIX)(void)
tmp = (uint64_t)glue(ldl, MEMSUFFIX)(T0) << 32;
tmp |= glue(ldl, MEMSUFFIX)(T0);
if (tmp == T1) {
glue(stq, MEMSUFFIX)(T0, T2);
glue(stq, MEMSUFFIX)(T0, T2);
}
T2 = tmp;
}

File diff suppressed because it is too large Load Diff