mirror of
https://git.proxmox.com/git/qemu
synced 2025-08-09 02:56:42 +00:00
Detabify
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3195 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
2e03286b9a
commit
0f8a249a0b
@ -22,9 +22,9 @@
|
|||||||
#define TARGET_HAS_ICE 1
|
#define TARGET_HAS_ICE 1
|
||||||
|
|
||||||
#if !defined(TARGET_SPARC64)
|
#if !defined(TARGET_SPARC64)
|
||||||
#define ELF_MACHINE EM_SPARC
|
#define ELF_MACHINE EM_SPARC
|
||||||
#else
|
#else
|
||||||
#define ELF_MACHINE EM_SPARCV9
|
#define ELF_MACHINE EM_SPARCV9
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*#define EXCP_INTERRUPT 0x100*/
|
/*#define EXCP_INTERRUPT 0x100*/
|
||||||
@ -143,8 +143,8 @@
|
|||||||
#define FSR_FCC0 (1<<10)
|
#define FSR_FCC0 (1<<10)
|
||||||
|
|
||||||
/* MMU */
|
/* MMU */
|
||||||
#define MMU_E (1<<0)
|
#define MMU_E (1<<0)
|
||||||
#define MMU_NF (1<<1)
|
#define MMU_NF (1<<1)
|
||||||
|
|
||||||
#define PTE_ENTRYTYPE_MASK 3
|
#define PTE_ENTRYTYPE_MASK 3
|
||||||
#define PTE_ACCESS_MASK 0x1c
|
#define PTE_ACCESS_MASK 0x1c
|
||||||
@ -152,8 +152,8 @@
|
|||||||
#define PTE_PPN_SHIFT 7
|
#define PTE_PPN_SHIFT 7
|
||||||
#define PTE_ADDR_MASK 0xffffff00
|
#define PTE_ADDR_MASK 0xffffff00
|
||||||
|
|
||||||
#define PG_ACCESSED_BIT 5
|
#define PG_ACCESSED_BIT 5
|
||||||
#define PG_MODIFIED_BIT 6
|
#define PG_MODIFIED_BIT 6
|
||||||
#define PG_CACHE_BIT 7
|
#define PG_CACHE_BIT 7
|
||||||
|
|
||||||
#define PG_ACCESSED_MASK (1 << PG_ACCESSED_BIT)
|
#define PG_ACCESSED_MASK (1 << PG_ACCESSED_BIT)
|
||||||
@ -221,7 +221,7 @@ typedef struct CPUSPARCState {
|
|||||||
uint64_t tnpc[MAXTL];
|
uint64_t tnpc[MAXTL];
|
||||||
uint64_t tstate[MAXTL];
|
uint64_t tstate[MAXTL];
|
||||||
uint32_t tt[MAXTL];
|
uint32_t tt[MAXTL];
|
||||||
uint32_t xcc; /* Extended integer condition codes */
|
uint32_t xcc; /* Extended integer condition codes */
|
||||||
uint32_t asi;
|
uint32_t asi;
|
||||||
uint32_t pstate;
|
uint32_t pstate;
|
||||||
uint32_t tl;
|
uint32_t tl;
|
||||||
@ -245,12 +245,12 @@ typedef struct CPUSPARCState {
|
|||||||
} CPUSPARCState;
|
} CPUSPARCState;
|
||||||
#if defined(TARGET_SPARC64)
|
#if defined(TARGET_SPARC64)
|
||||||
#define GET_FSR32(env) (env->fsr & 0xcfc1ffff)
|
#define GET_FSR32(env) (env->fsr & 0xcfc1ffff)
|
||||||
#define PUT_FSR32(env, val) do { uint32_t _tmp = val; \
|
#define PUT_FSR32(env, val) do { uint32_t _tmp = val; \
|
||||||
env->fsr = (_tmp & 0xcfc1c3ff) | (env->fsr & 0x3f00000000ULL); \
|
env->fsr = (_tmp & 0xcfc1c3ff) | (env->fsr & 0x3f00000000ULL); \
|
||||||
} while (0)
|
} while (0)
|
||||||
#define GET_FSR64(env) (env->fsr & 0x3fcfc1ffffULL)
|
#define GET_FSR64(env) (env->fsr & 0x3fcfc1ffffULL)
|
||||||
#define PUT_FSR64(env, val) do { uint64_t _tmp = val; \
|
#define PUT_FSR64(env, val) do { uint64_t _tmp = val; \
|
||||||
env->fsr = _tmp & 0x3fcfc1c3ffULL; \
|
env->fsr = _tmp & 0x3fcfc1c3ffULL; \
|
||||||
} while (0)
|
} while (0)
|
||||||
#else
|
#else
|
||||||
#define GET_FSR32(env) (env->fsr)
|
#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);
|
int cpu_sparc_register (CPUSPARCState *env, const sparc_def_t *def);
|
||||||
|
|
||||||
#define GET_PSR(env) (env->version | (env->psr & PSR_ICC) | \
|
#define GET_PSR(env) (env->version | (env->psr & PSR_ICC) | \
|
||||||
(env->psref? PSR_EF : 0) | \
|
(env->psref? PSR_EF : 0) | \
|
||||||
(env->psrpil << 8) | \
|
(env->psrpil << 8) | \
|
||||||
(env->psrs? PSR_S : 0) | \
|
(env->psrs? PSR_S : 0) | \
|
||||||
(env->psrps? PSR_PS : 0) | \
|
(env->psrps? PSR_PS : 0) | \
|
||||||
(env->psret? PSR_ET : 0) | env->cwp)
|
(env->psret? PSR_ET : 0) | env->cwp)
|
||||||
|
|
||||||
#ifndef NO_CPU_IO_DEFS
|
#ifndef NO_CPU_IO_DEFS
|
||||||
void cpu_set_cwp(CPUSPARCState *env1, int new_cwp);
|
void cpu_set_cwp(CPUSPARCState *env1, int new_cwp);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PUT_PSR(env, val) do { int _tmp = val; \
|
#define PUT_PSR(env, val) do { int _tmp = val; \
|
||||||
env->psr = _tmp & PSR_ICC; \
|
env->psr = _tmp & PSR_ICC; \
|
||||||
env->psref = (_tmp & PSR_EF)? 1 : 0; \
|
env->psref = (_tmp & PSR_EF)? 1 : 0; \
|
||||||
env->psrpil = (_tmp & PSR_PIL) >> 8; \
|
env->psrpil = (_tmp & PSR_PIL) >> 8; \
|
||||||
env->psrs = (_tmp & PSR_S)? 1 : 0; \
|
env->psrs = (_tmp & PSR_S)? 1 : 0; \
|
||||||
env->psrps = (_tmp & PSR_PS)? 1 : 0; \
|
env->psrps = (_tmp & PSR_PS)? 1 : 0; \
|
||||||
env->psret = (_tmp & PSR_ET)? 1 : 0; \
|
env->psret = (_tmp & PSR_ET)? 1 : 0; \
|
||||||
cpu_set_cwp(env, _tmp & PSR_CWP); \
|
cpu_set_cwp(env, _tmp & PSR_CWP); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#ifdef TARGET_SPARC64
|
#ifdef TARGET_SPARC64
|
||||||
#define GET_CCR(env) (((env->xcc >> 20) << 4) | ((env->psr & PSR_ICC) >> 20))
|
#define GET_CCR(env) (((env->xcc >> 20) << 4) | ((env->psr & PSR_ICC) >> 20))
|
||||||
#define PUT_CCR(env, val) do { int _tmp = val; \
|
#define PUT_CCR(env, val) do { int _tmp = val; \
|
||||||
env->xcc = (_tmp >> 4) << 20; \
|
env->xcc = (_tmp >> 4) << 20; \
|
||||||
env->psr = (_tmp & 0xf) << 20; \
|
env->psr = (_tmp & 0xf) << 20; \
|
||||||
} while (0)
|
} while (0)
|
||||||
#define GET_CWP64(env) (NWINDOWS - 1 - (env)->cwp)
|
#define GET_CWP64(env) (NWINDOWS - 1 - (env)->cwp)
|
||||||
#define PUT_CWP64(env, val) \
|
#define PUT_CWP64(env, val) \
|
||||||
|
@ -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 get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
|
||||||
int *access_index, target_ulong address, int rw,
|
int *access_index, target_ulong address, int rw,
|
||||||
int is_user)
|
int is_user)
|
||||||
{
|
{
|
||||||
int access_perms = 0;
|
int access_perms = 0;
|
||||||
target_phys_addr_t pde_ptr;
|
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;
|
virt_addr = address & TARGET_PAGE_MASK;
|
||||||
if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */
|
if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */
|
||||||
*physical = address;
|
*physical = address;
|
||||||
*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
|
*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -128,70 +128,70 @@ int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot
|
|||||||
switch (pde & PTE_ENTRYTYPE_MASK) {
|
switch (pde & PTE_ENTRYTYPE_MASK) {
|
||||||
default:
|
default:
|
||||||
case 0: /* Invalid */
|
case 0: /* Invalid */
|
||||||
return 1 << 2;
|
return 1 << 2;
|
||||||
case 2: /* L0 PTE, maybe should not happen? */
|
case 2: /* L0 PTE, maybe should not happen? */
|
||||||
case 3: /* Reserved */
|
case 3: /* Reserved */
|
||||||
return 4 << 2;
|
return 4 << 2;
|
||||||
case 1: /* L0 PDE */
|
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);
|
pde = ldl_phys(pde_ptr);
|
||||||
|
|
||||||
switch (pde & PTE_ENTRYTYPE_MASK) {
|
switch (pde & PTE_ENTRYTYPE_MASK) {
|
||||||
default:
|
default:
|
||||||
case 0: /* Invalid */
|
case 0: /* Invalid */
|
||||||
return (1 << 8) | (1 << 2);
|
return (1 << 8) | (1 << 2);
|
||||||
case 3: /* Reserved */
|
case 3: /* Reserved */
|
||||||
return (1 << 8) | (4 << 2);
|
return (1 << 8) | (4 << 2);
|
||||||
case 1: /* L1 PDE */
|
case 1: /* L1 PDE */
|
||||||
pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
|
pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
|
||||||
pde = ldl_phys(pde_ptr);
|
pde = ldl_phys(pde_ptr);
|
||||||
|
|
||||||
switch (pde & PTE_ENTRYTYPE_MASK) {
|
switch (pde & PTE_ENTRYTYPE_MASK) {
|
||||||
default:
|
default:
|
||||||
case 0: /* Invalid */
|
case 0: /* Invalid */
|
||||||
return (2 << 8) | (1 << 2);
|
return (2 << 8) | (1 << 2);
|
||||||
case 3: /* Reserved */
|
case 3: /* Reserved */
|
||||||
return (2 << 8) | (4 << 2);
|
return (2 << 8) | (4 << 2);
|
||||||
case 1: /* L2 PDE */
|
case 1: /* L2 PDE */
|
||||||
pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
|
pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
|
||||||
pde = ldl_phys(pde_ptr);
|
pde = ldl_phys(pde_ptr);
|
||||||
|
|
||||||
switch (pde & PTE_ENTRYTYPE_MASK) {
|
switch (pde & PTE_ENTRYTYPE_MASK) {
|
||||||
default:
|
default:
|
||||||
case 0: /* Invalid */
|
case 0: /* Invalid */
|
||||||
return (3 << 8) | (1 << 2);
|
return (3 << 8) | (1 << 2);
|
||||||
case 1: /* PDE, should not happen */
|
case 1: /* PDE, should not happen */
|
||||||
case 3: /* Reserved */
|
case 3: /* Reserved */
|
||||||
return (3 << 8) | (4 << 2);
|
return (3 << 8) | (4 << 2);
|
||||||
case 2: /* L3 PTE */
|
case 2: /* L3 PTE */
|
||||||
virt_addr = address & TARGET_PAGE_MASK;
|
virt_addr = address & TARGET_PAGE_MASK;
|
||||||
page_offset = (address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1);
|
page_offset = (address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2: /* L2 PTE */
|
case 2: /* L2 PTE */
|
||||||
virt_addr = address & ~0x3ffff;
|
virt_addr = address & ~0x3ffff;
|
||||||
page_offset = address & 0x3ffff;
|
page_offset = address & 0x3ffff;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2: /* L1 PTE */
|
case 2: /* L1 PTE */
|
||||||
virt_addr = address & ~0xffffff;
|
virt_addr = address & ~0xffffff;
|
||||||
page_offset = address & 0xffffff;
|
page_offset = address & 0xffffff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* update page modified and dirty bits */
|
/* update page modified and dirty bits */
|
||||||
is_dirty = (rw & 1) && !(pde & PG_MODIFIED_MASK);
|
is_dirty = (rw & 1) && !(pde & PG_MODIFIED_MASK);
|
||||||
if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
|
if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
|
||||||
pde |= PG_ACCESSED_MASK;
|
pde |= PG_ACCESSED_MASK;
|
||||||
if (is_dirty)
|
if (is_dirty)
|
||||||
pde |= PG_MODIFIED_MASK;
|
pde |= PG_MODIFIED_MASK;
|
||||||
stl_phys_notdirty(pde_ptr, pde);
|
stl_phys_notdirty(pde_ptr, pde);
|
||||||
}
|
}
|
||||||
/* check access */
|
/* check access */
|
||||||
access_perms = (pde & PTE_ACCESS_MASK) >> PTE_ACCESS_SHIFT;
|
access_perms = (pde & PTE_ACCESS_MASK) >> PTE_ACCESS_SHIFT;
|
||||||
error_code = access_table[*access_index][access_perms];
|
error_code = access_table[*access_index][access_perms];
|
||||||
if (error_code && !((env->mmuregs[0] & MMU_NF) && is_user))
|
if (error_code && !((env->mmuregs[0] & MMU_NF) && is_user))
|
||||||
return error_code;
|
return error_code;
|
||||||
|
|
||||||
/* the page can be put in the TLB */
|
/* the page can be put in the TLB */
|
||||||
*prot = perm_table[is_user][access_perms];
|
*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);
|
error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, is_user);
|
||||||
if (error_code == 0) {
|
if (error_code == 0) {
|
||||||
vaddr = address & TARGET_PAGE_MASK;
|
vaddr = address & TARGET_PAGE_MASK;
|
||||||
paddr &= TARGET_PAGE_MASK;
|
paddr &= TARGET_PAGE_MASK;
|
||||||
#ifdef DEBUG_MMU
|
#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);
|
TARGET_FMT_lx "\n", address, paddr, vaddr);
|
||||||
#endif
|
#endif
|
||||||
ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
|
ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (env->mmuregs[3]) /* Fault status register */
|
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[3] |= (access_index << 5) | error_code | 2;
|
||||||
env->mmuregs[4] = address; /* Fault address register */
|
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
|
// permissions. If no mapping is available, redirect accesses to
|
||||||
// neverland. Fake/overridden mappings will be flushed when
|
// neverland. Fake/overridden mappings will be flushed when
|
||||||
// switching to normal mode.
|
// switching to normal mode.
|
||||||
vaddr = address & TARGET_PAGE_MASK;
|
vaddr = address & TARGET_PAGE_MASK;
|
||||||
prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
|
prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
|
||||||
ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
|
ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
|
||||||
return ret;
|
return ret;
|
||||||
} else {
|
} else {
|
||||||
if (rw & 2)
|
if (rw & 2)
|
||||||
env->exception_index = TT_TFAULT;
|
env->exception_index = TT_TFAULT;
|
||||||
@ -265,50 +265,50 @@ target_ulong mmu_probe(CPUState *env, target_ulong address, int mmulev)
|
|||||||
case 0: /* Invalid */
|
case 0: /* Invalid */
|
||||||
case 2: /* PTE, maybe should not happen? */
|
case 2: /* PTE, maybe should not happen? */
|
||||||
case 3: /* Reserved */
|
case 3: /* Reserved */
|
||||||
return 0;
|
return 0;
|
||||||
case 1: /* L1 PDE */
|
case 1: /* L1 PDE */
|
||||||
if (mmulev == 3)
|
if (mmulev == 3)
|
||||||
return pde;
|
return pde;
|
||||||
pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
|
pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
|
||||||
pde = ldl_phys(pde_ptr);
|
pde = ldl_phys(pde_ptr);
|
||||||
|
|
||||||
switch (pde & PTE_ENTRYTYPE_MASK) {
|
switch (pde & PTE_ENTRYTYPE_MASK) {
|
||||||
default:
|
default:
|
||||||
case 0: /* Invalid */
|
case 0: /* Invalid */
|
||||||
case 3: /* Reserved */
|
case 3: /* Reserved */
|
||||||
return 0;
|
return 0;
|
||||||
case 2: /* L1 PTE */
|
case 2: /* L1 PTE */
|
||||||
return pde;
|
return pde;
|
||||||
case 1: /* L2 PDE */
|
case 1: /* L2 PDE */
|
||||||
if (mmulev == 2)
|
if (mmulev == 2)
|
||||||
return pde;
|
return pde;
|
||||||
pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
|
pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
|
||||||
pde = ldl_phys(pde_ptr);
|
pde = ldl_phys(pde_ptr);
|
||||||
|
|
||||||
switch (pde & PTE_ENTRYTYPE_MASK) {
|
switch (pde & PTE_ENTRYTYPE_MASK) {
|
||||||
default:
|
default:
|
||||||
case 0: /* Invalid */
|
case 0: /* Invalid */
|
||||||
case 3: /* Reserved */
|
case 3: /* Reserved */
|
||||||
return 0;
|
return 0;
|
||||||
case 2: /* L2 PTE */
|
case 2: /* L2 PTE */
|
||||||
return pde;
|
return pde;
|
||||||
case 1: /* L3 PDE */
|
case 1: /* L3 PDE */
|
||||||
if (mmulev == 1)
|
if (mmulev == 1)
|
||||||
return pde;
|
return pde;
|
||||||
pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
|
pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
|
||||||
pde = ldl_phys(pde_ptr);
|
pde = ldl_phys(pde_ptr);
|
||||||
|
|
||||||
switch (pde & PTE_ENTRYTYPE_MASK) {
|
switch (pde & PTE_ENTRYTYPE_MASK) {
|
||||||
default:
|
default:
|
||||||
case 0: /* Invalid */
|
case 0: /* Invalid */
|
||||||
case 1: /* PDE, should not happen */
|
case 1: /* PDE, should not happen */
|
||||||
case 3: /* Reserved */
|
case 3: /* Reserved */
|
||||||
return 0;
|
return 0;
|
||||||
case 2: /* L3 PTE */
|
case 2: /* L3 PTE */
|
||||||
return pde;
|
return pde;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -327,29 +327,29 @@ void dump_mmu(CPUState *env)
|
|||||||
printf("Root ptr: " TARGET_FMT_plx ", ctx: %d\n",
|
printf("Root ptr: " TARGET_FMT_plx ", ctx: %d\n",
|
||||||
(target_phys_addr_t)env->mmuregs[1] << 4, env->mmuregs[2]);
|
(target_phys_addr_t)env->mmuregs[1] << 4, env->mmuregs[2]);
|
||||||
for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) {
|
for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) {
|
||||||
pde = mmu_probe(env, va, 2);
|
pde = mmu_probe(env, va, 2);
|
||||||
if (pde) {
|
if (pde) {
|
||||||
pa = cpu_get_phys_page_debug(env, va);
|
pa = cpu_get_phys_page_debug(env, va);
|
||||||
printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx
|
printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx
|
||||||
" PDE: " TARGET_FMT_lx "\n", va, pa, pde);
|
" PDE: " TARGET_FMT_lx "\n", va, pa, pde);
|
||||||
for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) {
|
for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) {
|
||||||
pde = mmu_probe(env, va1, 1);
|
pde = mmu_probe(env, va1, 1);
|
||||||
if (pde) {
|
if (pde) {
|
||||||
pa = cpu_get_phys_page_debug(env, va1);
|
pa = cpu_get_phys_page_debug(env, va1);
|
||||||
printf(" VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx
|
printf(" VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx
|
||||||
" PDE: " TARGET_FMT_lx "\n", va1, pa, pde);
|
" PDE: " TARGET_FMT_lx "\n", va1, pa, pde);
|
||||||
for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) {
|
for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) {
|
||||||
pde = mmu_probe(env, va2, 0);
|
pde = mmu_probe(env, va2, 0);
|
||||||
if (pde) {
|
if (pde) {
|
||||||
pa = cpu_get_phys_page_debug(env, va2);
|
pa = cpu_get_phys_page_debug(env, va2);
|
||||||
printf(" VA: " TARGET_FMT_lx ", PA: "
|
printf(" VA: " TARGET_FMT_lx ", PA: "
|
||||||
TARGET_FMT_plx " PTE: " TARGET_FMT_lx "\n",
|
TARGET_FMT_plx " PTE: " TARGET_FMT_lx "\n",
|
||||||
va2, pa, pde);
|
va2, pa, pde);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("MMU dump ends\n");
|
printf("MMU dump ends\n");
|
||||||
}
|
}
|
||||||
@ -360,57 +360,57 @@ void dump_mmu(CPUState *env)
|
|||||||
* UltraSparc IIi I/DMMUs
|
* UltraSparc IIi I/DMMUs
|
||||||
*/
|
*/
|
||||||
static int get_physical_address_data(CPUState *env, target_phys_addr_t *physical, int *prot,
|
static int get_physical_address_data(CPUState *env, target_phys_addr_t *physical, int *prot,
|
||||||
int *access_index, target_ulong address, int rw,
|
int *access_index, target_ulong address, int rw,
|
||||||
int is_user)
|
int is_user)
|
||||||
{
|
{
|
||||||
target_ulong mask;
|
target_ulong mask;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
if ((env->lsu & DMMU_E) == 0) { /* DMMU disabled */
|
if ((env->lsu & DMMU_E) == 0) { /* DMMU disabled */
|
||||||
*physical = address;
|
*physical = address;
|
||||||
*prot = PAGE_READ | PAGE_WRITE;
|
*prot = PAGE_READ | PAGE_WRITE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < 64; i++) {
|
for (i = 0; i < 64; i++) {
|
||||||
switch ((env->dtlb_tte[i] >> 61) & 3) {
|
switch ((env->dtlb_tte[i] >> 61) & 3) {
|
||||||
default:
|
default:
|
||||||
case 0x0: // 8k
|
case 0x0: // 8k
|
||||||
mask = 0xffffffffffffe000ULL;
|
mask = 0xffffffffffffe000ULL;
|
||||||
break;
|
break;
|
||||||
case 0x1: // 64k
|
case 0x1: // 64k
|
||||||
mask = 0xffffffffffff0000ULL;
|
mask = 0xffffffffffff0000ULL;
|
||||||
break;
|
break;
|
||||||
case 0x2: // 512k
|
case 0x2: // 512k
|
||||||
mask = 0xfffffffffff80000ULL;
|
mask = 0xfffffffffff80000ULL;
|
||||||
break;
|
break;
|
||||||
case 0x3: // 4M
|
case 0x3: // 4M
|
||||||
mask = 0xffffffffffc00000ULL;
|
mask = 0xffffffffffc00000ULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// ctx match, vaddr match?
|
// ctx match, vaddr match?
|
||||||
if (env->dmmuregs[1] == (env->dtlb_tag[i] & 0x1fff) &&
|
if (env->dmmuregs[1] == (env->dtlb_tag[i] & 0x1fff) &&
|
||||||
(address & mask) == (env->dtlb_tag[i] & ~0x1fffULL)) {
|
(address & mask) == (env->dtlb_tag[i] & ~0x1fffULL)) {
|
||||||
// valid, access ok?
|
// valid, access ok?
|
||||||
if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0 ||
|
if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0 ||
|
||||||
((env->dtlb_tte[i] & 0x4) && is_user) ||
|
((env->dtlb_tte[i] & 0x4) && is_user) ||
|
||||||
(!(env->dtlb_tte[i] & 0x2) && (rw == 1))) {
|
(!(env->dtlb_tte[i] & 0x2) && (rw == 1))) {
|
||||||
if (env->dmmuregs[3]) /* Fault status register */
|
if (env->dmmuregs[3]) /* Fault status register */
|
||||||
env->dmmuregs[3] = 2; /* overflow (not read before another fault) */
|
env->dmmuregs[3] = 2; /* overflow (not read before another fault) */
|
||||||
env->dmmuregs[3] |= (is_user << 3) | ((rw == 1) << 2) | 1;
|
env->dmmuregs[3] |= (is_user << 3) | ((rw == 1) << 2) | 1;
|
||||||
env->dmmuregs[4] = address; /* Fault address register */
|
env->dmmuregs[4] = address; /* Fault address register */
|
||||||
env->exception_index = TT_DFAULT;
|
env->exception_index = TT_DFAULT;
|
||||||
#ifdef DEBUG_MMU
|
#ifdef DEBUG_MMU
|
||||||
printf("DFAULT at 0x%" PRIx64 "\n", address);
|
printf("DFAULT at 0x%" PRIx64 "\n", address);
|
||||||
#endif
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
*physical = (env->dtlb_tte[i] & mask & 0x1fffffff000ULL) + (address & ~mask & 0x1fffffff000ULL);
|
*physical = (env->dtlb_tte[i] & mask & 0x1fffffff000ULL) + (address & ~mask & 0x1fffffff000ULL);
|
||||||
*prot = PAGE_READ;
|
*prot = PAGE_READ;
|
||||||
if (env->dtlb_tte[i] & 0x2)
|
if (env->dtlb_tte[i] & 0x2)
|
||||||
*prot |= PAGE_WRITE;
|
*prot |= PAGE_WRITE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_MMU
|
#ifdef DEBUG_MMU
|
||||||
printf("DMISS at 0x%" PRIx64 "\n", address);
|
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,
|
static int get_physical_address_code(CPUState *env, target_phys_addr_t *physical, int *prot,
|
||||||
int *access_index, target_ulong address, int rw,
|
int *access_index, target_ulong address, int rw,
|
||||||
int is_user)
|
int is_user)
|
||||||
{
|
{
|
||||||
target_ulong mask;
|
target_ulong mask;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
if ((env->lsu & IMMU_E) == 0) { /* IMMU disabled */
|
if ((env->lsu & IMMU_E) == 0) { /* IMMU disabled */
|
||||||
*physical = address;
|
*physical = address;
|
||||||
*prot = PAGE_EXEC;
|
*prot = PAGE_EXEC;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < 64; i++) {
|
for (i = 0; i < 64; i++) {
|
||||||
switch ((env->itlb_tte[i] >> 61) & 3) {
|
switch ((env->itlb_tte[i] >> 61) & 3) {
|
||||||
default:
|
default:
|
||||||
case 0x0: // 8k
|
case 0x0: // 8k
|
||||||
mask = 0xffffffffffffe000ULL;
|
mask = 0xffffffffffffe000ULL;
|
||||||
break;
|
break;
|
||||||
case 0x1: // 64k
|
case 0x1: // 64k
|
||||||
mask = 0xffffffffffff0000ULL;
|
mask = 0xffffffffffff0000ULL;
|
||||||
break;
|
break;
|
||||||
case 0x2: // 512k
|
case 0x2: // 512k
|
||||||
mask = 0xfffffffffff80000ULL;
|
mask = 0xfffffffffff80000ULL;
|
||||||
break;
|
break;
|
||||||
case 0x3: // 4M
|
case 0x3: // 4M
|
||||||
mask = 0xffffffffffc00000ULL;
|
mask = 0xffffffffffc00000ULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// ctx match, vaddr match?
|
// ctx match, vaddr match?
|
||||||
if (env->dmmuregs[1] == (env->itlb_tag[i] & 0x1fff) &&
|
if (env->dmmuregs[1] == (env->itlb_tag[i] & 0x1fff) &&
|
||||||
(address & mask) == (env->itlb_tag[i] & ~0x1fffULL)) {
|
(address & mask) == (env->itlb_tag[i] & ~0x1fffULL)) {
|
||||||
// valid, access ok?
|
// valid, access ok?
|
||||||
if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0 ||
|
if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0 ||
|
||||||
((env->itlb_tte[i] & 0x4) && is_user)) {
|
((env->itlb_tte[i] & 0x4) && is_user)) {
|
||||||
if (env->immuregs[3]) /* Fault status register */
|
if (env->immuregs[3]) /* Fault status register */
|
||||||
env->immuregs[3] = 2; /* overflow (not read before another fault) */
|
env->immuregs[3] = 2; /* overflow (not read before another fault) */
|
||||||
env->immuregs[3] |= (is_user << 3) | 1;
|
env->immuregs[3] |= (is_user << 3) | 1;
|
||||||
env->exception_index = TT_TFAULT;
|
env->exception_index = TT_TFAULT;
|
||||||
#ifdef DEBUG_MMU
|
#ifdef DEBUG_MMU
|
||||||
printf("TFAULT at 0x%" PRIx64 "\n", address);
|
printf("TFAULT at 0x%" PRIx64 "\n", address);
|
||||||
#endif
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
*physical = (env->itlb_tte[i] & mask & 0x1fffffff000ULL) + (address & ~mask & 0x1fffffff000ULL);
|
*physical = (env->itlb_tte[i] & mask & 0x1fffffff000ULL) + (address & ~mask & 0x1fffffff000ULL);
|
||||||
*prot = PAGE_EXEC;
|
*prot = PAGE_EXEC;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_MMU
|
#ifdef DEBUG_MMU
|
||||||
printf("TMISS at 0x%" PRIx64 "\n", address);
|
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 get_physical_address(CPUState *env, target_phys_addr_t *physical, int *prot,
|
||||||
int *access_index, target_ulong address, int rw,
|
int *access_index, target_ulong address, int rw,
|
||||||
int is_user)
|
int is_user)
|
||||||
{
|
{
|
||||||
if (rw == 2)
|
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
|
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 */
|
/* 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);
|
error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, is_user);
|
||||||
if (error_code == 0) {
|
if (error_code == 0) {
|
||||||
virt_addr = address & TARGET_PAGE_MASK;
|
virt_addr = address & TARGET_PAGE_MASK;
|
||||||
vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1));
|
vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1));
|
||||||
#ifdef DEBUG_MMU
|
#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
|
#endif
|
||||||
ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
|
ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
// XXX
|
// XXX
|
||||||
return 1;
|
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]);
|
printf("MMU contexts: Primary: %" PRId64 ", Secondary: %" PRId64 "\n", env->dmmuregs[1], env->dmmuregs[2]);
|
||||||
if ((env->lsu & DMMU_E) == 0) {
|
if ((env->lsu & DMMU_E) == 0) {
|
||||||
printf("DMMU disabled\n");
|
printf("DMMU disabled\n");
|
||||||
} else {
|
} else {
|
||||||
printf("DMMU dump:\n");
|
printf("DMMU dump:\n");
|
||||||
for (i = 0; i < 64; i++) {
|
for (i = 0; i < 64; i++) {
|
||||||
switch ((env->dtlb_tte[i] >> 61) & 3) {
|
switch ((env->dtlb_tte[i] >> 61) & 3) {
|
||||||
default:
|
default:
|
||||||
case 0x0:
|
case 0x0:
|
||||||
mask = " 8k";
|
mask = " 8k";
|
||||||
break;
|
break;
|
||||||
case 0x1:
|
case 0x1:
|
||||||
mask = " 64k";
|
mask = " 64k";
|
||||||
break;
|
break;
|
||||||
case 0x2:
|
case 0x2:
|
||||||
mask = "512k";
|
mask = "512k";
|
||||||
break;
|
break;
|
||||||
case 0x3:
|
case 0x3:
|
||||||
mask = " 4M";
|
mask = " 4M";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0) {
|
if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0) {
|
||||||
printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx ", %s, %s, %s, %s, ctx %" PRId64 "\n",
|
printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx ", %s, %s, %s, %s, ctx %" PRId64 "\n",
|
||||||
env->dtlb_tag[i] & ~0x1fffULL,
|
env->dtlb_tag[i] & ~0x1fffULL,
|
||||||
env->dtlb_tte[i] & 0x1ffffffe000ULL,
|
env->dtlb_tte[i] & 0x1ffffffe000ULL,
|
||||||
mask,
|
mask,
|
||||||
env->dtlb_tte[i] & 0x4? "priv": "user",
|
env->dtlb_tte[i] & 0x4? "priv": "user",
|
||||||
env->dtlb_tte[i] & 0x2? "RW": "RO",
|
env->dtlb_tte[i] & 0x2? "RW": "RO",
|
||||||
env->dtlb_tte[i] & 0x40? "locked": "unlocked",
|
env->dtlb_tte[i] & 0x40? "locked": "unlocked",
|
||||||
env->dtlb_tag[i] & 0x1fffULL);
|
env->dtlb_tag[i] & 0x1fffULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((env->lsu & IMMU_E) == 0) {
|
if ((env->lsu & IMMU_E) == 0) {
|
||||||
printf("IMMU disabled\n");
|
printf("IMMU disabled\n");
|
||||||
} else {
|
} else {
|
||||||
printf("IMMU dump:\n");
|
printf("IMMU dump:\n");
|
||||||
for (i = 0; i < 64; i++) {
|
for (i = 0; i < 64; i++) {
|
||||||
switch ((env->itlb_tte[i] >> 61) & 3) {
|
switch ((env->itlb_tte[i] >> 61) & 3) {
|
||||||
default:
|
default:
|
||||||
case 0x0:
|
case 0x0:
|
||||||
mask = " 8k";
|
mask = " 8k";
|
||||||
break;
|
break;
|
||||||
case 0x1:
|
case 0x1:
|
||||||
mask = " 64k";
|
mask = " 64k";
|
||||||
break;
|
break;
|
||||||
case 0x2:
|
case 0x2:
|
||||||
mask = "512k";
|
mask = "512k";
|
||||||
break;
|
break;
|
||||||
case 0x3:
|
case 0x3:
|
||||||
mask = " 4M";
|
mask = " 4M";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0) {
|
if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0) {
|
||||||
printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx ", %s, %s, %s, ctx %" PRId64 "\n",
|
printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx ", %s, %s, %s, ctx %" PRId64 "\n",
|
||||||
env->itlb_tag[i] & ~0x1fffULL,
|
env->itlb_tag[i] & ~0x1fffULL,
|
||||||
env->itlb_tte[i] & 0x1ffffffe000ULL,
|
env->itlb_tte[i] & 0x1ffffffe000ULL,
|
||||||
mask,
|
mask,
|
||||||
env->itlb_tte[i] & 0x4? "priv": "user",
|
env->itlb_tte[i] & 0x4? "priv": "user",
|
||||||
env->itlb_tte[i] & 0x40? "locked": "unlocked",
|
env->itlb_tte[i] & 0x40? "locked": "unlocked",
|
||||||
env->itlb_tag[i] & 0x1fffULL);
|
env->itlb_tag[i] & 0x1fffULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* DEBUG_MMU */
|
#endif /* DEBUG_MMU */
|
||||||
|
@ -376,33 +376,33 @@ void OPPROTO op_add_T1_T0_cc(void)
|
|||||||
env->psr = 0;
|
env->psr = 0;
|
||||||
#ifdef TARGET_SPARC64
|
#ifdef TARGET_SPARC64
|
||||||
if (!(T0 & 0xffffffff))
|
if (!(T0 & 0xffffffff))
|
||||||
env->psr |= PSR_ZERO;
|
env->psr |= PSR_ZERO;
|
||||||
if ((int32_t) T0 < 0)
|
if ((int32_t) T0 < 0)
|
||||||
env->psr |= PSR_NEG;
|
env->psr |= PSR_NEG;
|
||||||
if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
|
if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
|
||||||
env->psr |= PSR_CARRY;
|
env->psr |= PSR_CARRY;
|
||||||
if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
|
if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
|
||||||
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
|
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
|
||||||
env->psr |= PSR_OVF;
|
env->psr |= PSR_OVF;
|
||||||
|
|
||||||
env->xcc = 0;
|
env->xcc = 0;
|
||||||
if (!T0)
|
if (!T0)
|
||||||
env->xcc |= PSR_ZERO;
|
env->xcc |= PSR_ZERO;
|
||||||
if ((int64_t) T0 < 0)
|
if ((int64_t) T0 < 0)
|
||||||
env->xcc |= PSR_NEG;
|
env->xcc |= PSR_NEG;
|
||||||
if (T0 < src1)
|
if (T0 < src1)
|
||||||
env->xcc |= PSR_CARRY;
|
env->xcc |= PSR_CARRY;
|
||||||
if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
|
if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
|
||||||
env->xcc |= PSR_OVF;
|
env->xcc |= PSR_OVF;
|
||||||
#else
|
#else
|
||||||
if (!T0)
|
if (!T0)
|
||||||
env->psr |= PSR_ZERO;
|
env->psr |= PSR_ZERO;
|
||||||
if ((int32_t) T0 < 0)
|
if ((int32_t) T0 < 0)
|
||||||
env->psr |= PSR_NEG;
|
env->psr |= PSR_NEG;
|
||||||
if (T0 < src1)
|
if (T0 < src1)
|
||||||
env->psr |= PSR_CARRY;
|
env->psr |= PSR_CARRY;
|
||||||
if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
|
if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
|
||||||
env->psr |= PSR_OVF;
|
env->psr |= PSR_OVF;
|
||||||
#endif
|
#endif
|
||||||
FORCE_RET();
|
FORCE_RET();
|
||||||
}
|
}
|
||||||
@ -448,26 +448,26 @@ void OPPROTO op_addx_T1_T0_cc(void)
|
|||||||
}
|
}
|
||||||
#ifdef TARGET_SPARC64
|
#ifdef TARGET_SPARC64
|
||||||
if (!(T0 & 0xffffffff))
|
if (!(T0 & 0xffffffff))
|
||||||
env->psr |= PSR_ZERO;
|
env->psr |= PSR_ZERO;
|
||||||
if ((int32_t) T0 < 0)
|
if ((int32_t) T0 < 0)
|
||||||
env->psr |= PSR_NEG;
|
env->psr |= PSR_NEG;
|
||||||
if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
|
if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
|
||||||
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
|
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
|
||||||
env->psr |= PSR_OVF;
|
env->psr |= PSR_OVF;
|
||||||
|
|
||||||
if (!T0)
|
if (!T0)
|
||||||
env->xcc |= PSR_ZERO;
|
env->xcc |= PSR_ZERO;
|
||||||
if ((int64_t) T0 < 0)
|
if ((int64_t) T0 < 0)
|
||||||
env->xcc |= PSR_NEG;
|
env->xcc |= PSR_NEG;
|
||||||
if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
|
if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
|
||||||
env->xcc |= PSR_OVF;
|
env->xcc |= PSR_OVF;
|
||||||
#else
|
#else
|
||||||
if (!T0)
|
if (!T0)
|
||||||
env->psr |= PSR_ZERO;
|
env->psr |= PSR_ZERO;
|
||||||
if ((int32_t) T0 < 0)
|
if ((int32_t) T0 < 0)
|
||||||
env->psr |= PSR_NEG;
|
env->psr |= PSR_NEG;
|
||||||
if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
|
if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
|
||||||
env->psr |= PSR_OVF;
|
env->psr |= PSR_OVF;
|
||||||
#endif
|
#endif
|
||||||
FORCE_RET();
|
FORCE_RET();
|
||||||
}
|
}
|
||||||
@ -481,37 +481,37 @@ void OPPROTO op_tadd_T1_T0_cc(void)
|
|||||||
env->psr = 0;
|
env->psr = 0;
|
||||||
#ifdef TARGET_SPARC64
|
#ifdef TARGET_SPARC64
|
||||||
if (!(T0 & 0xffffffff))
|
if (!(T0 & 0xffffffff))
|
||||||
env->psr |= PSR_ZERO;
|
env->psr |= PSR_ZERO;
|
||||||
if ((int32_t) T0 < 0)
|
if ((int32_t) T0 < 0)
|
||||||
env->psr |= PSR_NEG;
|
env->psr |= PSR_NEG;
|
||||||
if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
|
if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
|
||||||
env->psr |= PSR_CARRY;
|
env->psr |= PSR_CARRY;
|
||||||
if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
|
if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
|
||||||
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
|
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
|
||||||
env->psr |= PSR_OVF;
|
env->psr |= PSR_OVF;
|
||||||
if ((src1 & 0x03) || (T1 & 0x03))
|
if ((src1 & 0x03) || (T1 & 0x03))
|
||||||
env->psr |= PSR_OVF;
|
env->psr |= PSR_OVF;
|
||||||
|
|
||||||
env->xcc = 0;
|
env->xcc = 0;
|
||||||
if (!T0)
|
if (!T0)
|
||||||
env->xcc |= PSR_ZERO;
|
env->xcc |= PSR_ZERO;
|
||||||
if ((int64_t) T0 < 0)
|
if ((int64_t) T0 < 0)
|
||||||
env->xcc |= PSR_NEG;
|
env->xcc |= PSR_NEG;
|
||||||
if (T0 < src1)
|
if (T0 < src1)
|
||||||
env->xcc |= PSR_CARRY;
|
env->xcc |= PSR_CARRY;
|
||||||
if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
|
if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
|
||||||
env->xcc |= PSR_OVF;
|
env->xcc |= PSR_OVF;
|
||||||
#else
|
#else
|
||||||
if (!T0)
|
if (!T0)
|
||||||
env->psr |= PSR_ZERO;
|
env->psr |= PSR_ZERO;
|
||||||
if ((int32_t) T0 < 0)
|
if ((int32_t) T0 < 0)
|
||||||
env->psr |= PSR_NEG;
|
env->psr |= PSR_NEG;
|
||||||
if (T0 < src1)
|
if (T0 < src1)
|
||||||
env->psr |= PSR_CARRY;
|
env->psr |= PSR_CARRY;
|
||||||
if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
|
if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
|
||||||
env->psr |= PSR_OVF;
|
env->psr |= PSR_OVF;
|
||||||
if ((src1 & 0x03) || (T1 & 0x03))
|
if ((src1 & 0x03) || (T1 & 0x03))
|
||||||
env->psr |= PSR_OVF;
|
env->psr |= PSR_OVF;
|
||||||
#endif
|
#endif
|
||||||
FORCE_RET();
|
FORCE_RET();
|
||||||
}
|
}
|
||||||
@ -528,7 +528,7 @@ void OPPROTO op_tadd_T1_T0_ccTV(void)
|
|||||||
|
|
||||||
#ifdef TARGET_SPARC64
|
#ifdef TARGET_SPARC64
|
||||||
if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
|
if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
|
||||||
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
|
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
|
||||||
raise_exception(TT_TOVF);
|
raise_exception(TT_TOVF);
|
||||||
#else
|
#else
|
||||||
if ((src1 & 0x03) || (T1 & 0x03))
|
if ((src1 & 0x03) || (T1 & 0x03))
|
||||||
@ -538,26 +538,26 @@ void OPPROTO op_tadd_T1_T0_ccTV(void)
|
|||||||
env->psr = 0;
|
env->psr = 0;
|
||||||
#ifdef TARGET_SPARC64
|
#ifdef TARGET_SPARC64
|
||||||
if (!(T0 & 0xffffffff))
|
if (!(T0 & 0xffffffff))
|
||||||
env->psr |= PSR_ZERO;
|
env->psr |= PSR_ZERO;
|
||||||
if ((int32_t) T0 < 0)
|
if ((int32_t) T0 < 0)
|
||||||
env->psr |= PSR_NEG;
|
env->psr |= PSR_NEG;
|
||||||
if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
|
if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
|
||||||
env->psr |= PSR_CARRY;
|
env->psr |= PSR_CARRY;
|
||||||
|
|
||||||
env->xcc = 0;
|
env->xcc = 0;
|
||||||
if (!T0)
|
if (!T0)
|
||||||
env->xcc |= PSR_ZERO;
|
env->xcc |= PSR_ZERO;
|
||||||
if ((int64_t) T0 < 0)
|
if ((int64_t) T0 < 0)
|
||||||
env->xcc |= PSR_NEG;
|
env->xcc |= PSR_NEG;
|
||||||
if (T0 < src1)
|
if (T0 < src1)
|
||||||
env->xcc |= PSR_CARRY;
|
env->xcc |= PSR_CARRY;
|
||||||
#else
|
#else
|
||||||
if (!T0)
|
if (!T0)
|
||||||
env->psr |= PSR_ZERO;
|
env->psr |= PSR_ZERO;
|
||||||
if ((int32_t) T0 < 0)
|
if ((int32_t) T0 < 0)
|
||||||
env->psr |= PSR_NEG;
|
env->psr |= PSR_NEG;
|
||||||
if (T0 < src1)
|
if (T0 < src1)
|
||||||
env->psr |= PSR_CARRY;
|
env->psr |= PSR_CARRY;
|
||||||
#endif
|
#endif
|
||||||
FORCE_RET();
|
FORCE_RET();
|
||||||
}
|
}
|
||||||
@ -576,33 +576,33 @@ void OPPROTO op_sub_T1_T0_cc(void)
|
|||||||
env->psr = 0;
|
env->psr = 0;
|
||||||
#ifdef TARGET_SPARC64
|
#ifdef TARGET_SPARC64
|
||||||
if (!(T0 & 0xffffffff))
|
if (!(T0 & 0xffffffff))
|
||||||
env->psr |= PSR_ZERO;
|
env->psr |= PSR_ZERO;
|
||||||
if ((int32_t) T0 < 0)
|
if ((int32_t) T0 < 0)
|
||||||
env->psr |= PSR_NEG;
|
env->psr |= PSR_NEG;
|
||||||
if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
|
if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
|
||||||
env->psr |= PSR_CARRY;
|
env->psr |= PSR_CARRY;
|
||||||
if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
|
if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
|
||||||
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
|
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
|
||||||
env->psr |= PSR_OVF;
|
env->psr |= PSR_OVF;
|
||||||
|
|
||||||
env->xcc = 0;
|
env->xcc = 0;
|
||||||
if (!T0)
|
if (!T0)
|
||||||
env->xcc |= PSR_ZERO;
|
env->xcc |= PSR_ZERO;
|
||||||
if ((int64_t) T0 < 0)
|
if ((int64_t) T0 < 0)
|
||||||
env->xcc |= PSR_NEG;
|
env->xcc |= PSR_NEG;
|
||||||
if (src1 < T1)
|
if (src1 < T1)
|
||||||
env->xcc |= PSR_CARRY;
|
env->xcc |= PSR_CARRY;
|
||||||
if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
|
if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
|
||||||
env->xcc |= PSR_OVF;
|
env->xcc |= PSR_OVF;
|
||||||
#else
|
#else
|
||||||
if (!T0)
|
if (!T0)
|
||||||
env->psr |= PSR_ZERO;
|
env->psr |= PSR_ZERO;
|
||||||
if ((int32_t) T0 < 0)
|
if ((int32_t) T0 < 0)
|
||||||
env->psr |= PSR_NEG;
|
env->psr |= PSR_NEG;
|
||||||
if (src1 < T1)
|
if (src1 < T1)
|
||||||
env->psr |= PSR_CARRY;
|
env->psr |= PSR_CARRY;
|
||||||
if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
|
if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
|
||||||
env->psr |= PSR_OVF;
|
env->psr |= PSR_OVF;
|
||||||
#endif
|
#endif
|
||||||
FORCE_RET();
|
FORCE_RET();
|
||||||
}
|
}
|
||||||
@ -648,26 +648,26 @@ void OPPROTO op_subx_T1_T0_cc(void)
|
|||||||
}
|
}
|
||||||
#ifdef TARGET_SPARC64
|
#ifdef TARGET_SPARC64
|
||||||
if (!(T0 & 0xffffffff))
|
if (!(T0 & 0xffffffff))
|
||||||
env->psr |= PSR_ZERO;
|
env->psr |= PSR_ZERO;
|
||||||
if ((int32_t) T0 < 0)
|
if ((int32_t) T0 < 0)
|
||||||
env->psr |= PSR_NEG;
|
env->psr |= PSR_NEG;
|
||||||
if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
|
if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
|
||||||
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
|
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
|
||||||
env->psr |= PSR_OVF;
|
env->psr |= PSR_OVF;
|
||||||
|
|
||||||
if (!T0)
|
if (!T0)
|
||||||
env->xcc |= PSR_ZERO;
|
env->xcc |= PSR_ZERO;
|
||||||
if ((int64_t) T0 < 0)
|
if ((int64_t) T0 < 0)
|
||||||
env->xcc |= PSR_NEG;
|
env->xcc |= PSR_NEG;
|
||||||
if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
|
if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
|
||||||
env->xcc |= PSR_OVF;
|
env->xcc |= PSR_OVF;
|
||||||
#else
|
#else
|
||||||
if (!T0)
|
if (!T0)
|
||||||
env->psr |= PSR_ZERO;
|
env->psr |= PSR_ZERO;
|
||||||
if ((int32_t) T0 < 0)
|
if ((int32_t) T0 < 0)
|
||||||
env->psr |= PSR_NEG;
|
env->psr |= PSR_NEG;
|
||||||
if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
|
if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
|
||||||
env->psr |= PSR_OVF;
|
env->psr |= PSR_OVF;
|
||||||
#endif
|
#endif
|
||||||
FORCE_RET();
|
FORCE_RET();
|
||||||
}
|
}
|
||||||
@ -681,37 +681,37 @@ void OPPROTO op_tsub_T1_T0_cc(void)
|
|||||||
env->psr = 0;
|
env->psr = 0;
|
||||||
#ifdef TARGET_SPARC64
|
#ifdef TARGET_SPARC64
|
||||||
if (!(T0 & 0xffffffff))
|
if (!(T0 & 0xffffffff))
|
||||||
env->psr |= PSR_ZERO;
|
env->psr |= PSR_ZERO;
|
||||||
if ((int32_t) T0 < 0)
|
if ((int32_t) T0 < 0)
|
||||||
env->psr |= PSR_NEG;
|
env->psr |= PSR_NEG;
|
||||||
if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
|
if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
|
||||||
env->psr |= PSR_CARRY;
|
env->psr |= PSR_CARRY;
|
||||||
if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
|
if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
|
||||||
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
|
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
|
||||||
env->psr |= PSR_OVF;
|
env->psr |= PSR_OVF;
|
||||||
if ((src1 & 0x03) || (T1 & 0x03))
|
if ((src1 & 0x03) || (T1 & 0x03))
|
||||||
env->psr |= PSR_OVF;
|
env->psr |= PSR_OVF;
|
||||||
|
|
||||||
env->xcc = 0;
|
env->xcc = 0;
|
||||||
if (!T0)
|
if (!T0)
|
||||||
env->xcc |= PSR_ZERO;
|
env->xcc |= PSR_ZERO;
|
||||||
if ((int64_t) T0 < 0)
|
if ((int64_t) T0 < 0)
|
||||||
env->xcc |= PSR_NEG;
|
env->xcc |= PSR_NEG;
|
||||||
if (src1 < T1)
|
if (src1 < T1)
|
||||||
env->xcc |= PSR_CARRY;
|
env->xcc |= PSR_CARRY;
|
||||||
if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
|
if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
|
||||||
env->xcc |= PSR_OVF;
|
env->xcc |= PSR_OVF;
|
||||||
#else
|
#else
|
||||||
if (!T0)
|
if (!T0)
|
||||||
env->psr |= PSR_ZERO;
|
env->psr |= PSR_ZERO;
|
||||||
if ((int32_t) T0 < 0)
|
if ((int32_t) T0 < 0)
|
||||||
env->psr |= PSR_NEG;
|
env->psr |= PSR_NEG;
|
||||||
if (src1 < T1)
|
if (src1 < T1)
|
||||||
env->psr |= PSR_CARRY;
|
env->psr |= PSR_CARRY;
|
||||||
if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
|
if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
|
||||||
env->psr |= PSR_OVF;
|
env->psr |= PSR_OVF;
|
||||||
if ((src1 & 0x03) || (T1 & 0x03))
|
if ((src1 & 0x03) || (T1 & 0x03))
|
||||||
env->psr |= PSR_OVF;
|
env->psr |= PSR_OVF;
|
||||||
#endif
|
#endif
|
||||||
FORCE_RET();
|
FORCE_RET();
|
||||||
}
|
}
|
||||||
@ -728,7 +728,7 @@ void OPPROTO op_tsub_T1_T0_ccTV(void)
|
|||||||
|
|
||||||
#ifdef TARGET_SPARC64
|
#ifdef TARGET_SPARC64
|
||||||
if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
|
if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
|
||||||
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
|
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
|
||||||
raise_exception(TT_TOVF);
|
raise_exception(TT_TOVF);
|
||||||
#else
|
#else
|
||||||
if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
|
if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
|
||||||
@ -738,26 +738,26 @@ void OPPROTO op_tsub_T1_T0_ccTV(void)
|
|||||||
env->psr = 0;
|
env->psr = 0;
|
||||||
#ifdef TARGET_SPARC64
|
#ifdef TARGET_SPARC64
|
||||||
if (!(T0 & 0xffffffff))
|
if (!(T0 & 0xffffffff))
|
||||||
env->psr |= PSR_ZERO;
|
env->psr |= PSR_ZERO;
|
||||||
if ((int32_t) T0 < 0)
|
if ((int32_t) T0 < 0)
|
||||||
env->psr |= PSR_NEG;
|
env->psr |= PSR_NEG;
|
||||||
if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
|
if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
|
||||||
env->psr |= PSR_CARRY;
|
env->psr |= PSR_CARRY;
|
||||||
|
|
||||||
env->xcc = 0;
|
env->xcc = 0;
|
||||||
if (!T0)
|
if (!T0)
|
||||||
env->xcc |= PSR_ZERO;
|
env->xcc |= PSR_ZERO;
|
||||||
if ((int64_t) T0 < 0)
|
if ((int64_t) T0 < 0)
|
||||||
env->xcc |= PSR_NEG;
|
env->xcc |= PSR_NEG;
|
||||||
if (src1 < T1)
|
if (src1 < T1)
|
||||||
env->xcc |= PSR_CARRY;
|
env->xcc |= PSR_CARRY;
|
||||||
#else
|
#else
|
||||||
if (!T0)
|
if (!T0)
|
||||||
env->psr |= PSR_ZERO;
|
env->psr |= PSR_ZERO;
|
||||||
if ((int32_t) T0 < 0)
|
if ((int32_t) T0 < 0)
|
||||||
env->psr |= PSR_NEG;
|
env->psr |= PSR_NEG;
|
||||||
if (src1 < T1)
|
if (src1 < T1)
|
||||||
env->psr |= PSR_CARRY;
|
env->psr |= PSR_CARRY;
|
||||||
#endif
|
#endif
|
||||||
FORCE_RET();
|
FORCE_RET();
|
||||||
}
|
}
|
||||||
@ -833,13 +833,13 @@ void OPPROTO op_mulscc_T1_T0(void)
|
|||||||
T0 += T1;
|
T0 += T1;
|
||||||
env->psr = 0;
|
env->psr = 0;
|
||||||
if (!T0)
|
if (!T0)
|
||||||
env->psr |= PSR_ZERO;
|
env->psr |= PSR_ZERO;
|
||||||
if ((int32_t) T0 < 0)
|
if ((int32_t) T0 < 0)
|
||||||
env->psr |= PSR_NEG;
|
env->psr |= PSR_NEG;
|
||||||
if (T0 < src1)
|
if (T0 < src1)
|
||||||
env->psr |= PSR_CARRY;
|
env->psr |= PSR_CARRY;
|
||||||
if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
|
if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
|
||||||
env->psr |= PSR_OVF;
|
env->psr |= PSR_OVF;
|
||||||
env->y = (b2 << 31) | (env->y >> 1);
|
env->y = (b2 << 31) | (env->y >> 1);
|
||||||
FORCE_RET();
|
FORCE_RET();
|
||||||
}
|
}
|
||||||
@ -858,11 +858,11 @@ void OPPROTO op_udiv_T1_T0(void)
|
|||||||
|
|
||||||
x0 = x0 / x1;
|
x0 = x0 / x1;
|
||||||
if (x0 > 0xffffffff) {
|
if (x0 > 0xffffffff) {
|
||||||
T0 = 0xffffffff;
|
T0 = 0xffffffff;
|
||||||
T1 = 1;
|
T1 = 1;
|
||||||
} else {
|
} else {
|
||||||
T0 = x0;
|
T0 = x0;
|
||||||
T1 = 0;
|
T1 = 0;
|
||||||
}
|
}
|
||||||
FORCE_RET();
|
FORCE_RET();
|
||||||
}
|
}
|
||||||
@ -881,11 +881,11 @@ void OPPROTO op_sdiv_T1_T0(void)
|
|||||||
|
|
||||||
x0 = x0 / x1;
|
x0 = x0 / x1;
|
||||||
if ((int32_t) x0 != x0) {
|
if ((int32_t) x0 != x0) {
|
||||||
T0 = x0 < 0? 0x80000000: 0x7fffffff;
|
T0 = x0 < 0? 0x80000000: 0x7fffffff;
|
||||||
T1 = 1;
|
T1 = 1;
|
||||||
} else {
|
} else {
|
||||||
T0 = x0;
|
T0 = x0;
|
||||||
T1 = 0;
|
T1 = 0;
|
||||||
}
|
}
|
||||||
FORCE_RET();
|
FORCE_RET();
|
||||||
}
|
}
|
||||||
@ -895,24 +895,24 @@ void OPPROTO op_div_cc(void)
|
|||||||
env->psr = 0;
|
env->psr = 0;
|
||||||
#ifdef TARGET_SPARC64
|
#ifdef TARGET_SPARC64
|
||||||
if (!T0)
|
if (!T0)
|
||||||
env->psr |= PSR_ZERO;
|
env->psr |= PSR_ZERO;
|
||||||
if ((int32_t) T0 < 0)
|
if ((int32_t) T0 < 0)
|
||||||
env->psr |= PSR_NEG;
|
env->psr |= PSR_NEG;
|
||||||
if (T1)
|
if (T1)
|
||||||
env->psr |= PSR_OVF;
|
env->psr |= PSR_OVF;
|
||||||
|
|
||||||
env->xcc = 0;
|
env->xcc = 0;
|
||||||
if (!T0)
|
if (!T0)
|
||||||
env->xcc |= PSR_ZERO;
|
env->xcc |= PSR_ZERO;
|
||||||
if ((int64_t) T0 < 0)
|
if ((int64_t) T0 < 0)
|
||||||
env->xcc |= PSR_NEG;
|
env->xcc |= PSR_NEG;
|
||||||
#else
|
#else
|
||||||
if (!T0)
|
if (!T0)
|
||||||
env->psr |= PSR_ZERO;
|
env->psr |= PSR_ZERO;
|
||||||
if ((int32_t) T0 < 0)
|
if ((int32_t) T0 < 0)
|
||||||
env->psr |= PSR_NEG;
|
env->psr |= PSR_NEG;
|
||||||
if (T1)
|
if (T1)
|
||||||
env->psr |= PSR_OVF;
|
env->psr |= PSR_OVF;
|
||||||
#endif
|
#endif
|
||||||
FORCE_RET();
|
FORCE_RET();
|
||||||
}
|
}
|
||||||
@ -939,9 +939,9 @@ void OPPROTO op_sdivx_T1_T0(void)
|
|||||||
raise_exception(TT_DIV_ZERO);
|
raise_exception(TT_DIV_ZERO);
|
||||||
}
|
}
|
||||||
if (T0 == INT64_MIN && T1 == -1)
|
if (T0 == INT64_MIN && T1 == -1)
|
||||||
T0 = INT64_MIN;
|
T0 = INT64_MIN;
|
||||||
else
|
else
|
||||||
T0 /= (target_long) T1;
|
T0 /= (target_long) T1;
|
||||||
FORCE_RET();
|
FORCE_RET();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -951,20 +951,20 @@ void OPPROTO op_logic_T0_cc(void)
|
|||||||
env->psr = 0;
|
env->psr = 0;
|
||||||
#ifdef TARGET_SPARC64
|
#ifdef TARGET_SPARC64
|
||||||
if (!(T0 & 0xffffffff))
|
if (!(T0 & 0xffffffff))
|
||||||
env->psr |= PSR_ZERO;
|
env->psr |= PSR_ZERO;
|
||||||
if ((int32_t) T0 < 0)
|
if ((int32_t) T0 < 0)
|
||||||
env->psr |= PSR_NEG;
|
env->psr |= PSR_NEG;
|
||||||
|
|
||||||
env->xcc = 0;
|
env->xcc = 0;
|
||||||
if (!T0)
|
if (!T0)
|
||||||
env->xcc |= PSR_ZERO;
|
env->xcc |= PSR_ZERO;
|
||||||
if ((int64_t) T0 < 0)
|
if ((int64_t) T0 < 0)
|
||||||
env->xcc |= PSR_NEG;
|
env->xcc |= PSR_NEG;
|
||||||
#else
|
#else
|
||||||
if (!T0)
|
if (!T0)
|
||||||
env->psr |= PSR_ZERO;
|
env->psr |= PSR_ZERO;
|
||||||
if ((int32_t) T0 < 0)
|
if ((int32_t) T0 < 0)
|
||||||
env->psr |= PSR_NEG;
|
env->psr |= PSR_NEG;
|
||||||
#endif
|
#endif
|
||||||
FORCE_RET();
|
FORCE_RET();
|
||||||
}
|
}
|
||||||
@ -1200,17 +1200,17 @@ void OPPROTO op_save(void)
|
|||||||
cwp = (env->cwp - 1) & (NWINDOWS - 1);
|
cwp = (env->cwp - 1) & (NWINDOWS - 1);
|
||||||
if (env->cansave == 0) {
|
if (env->cansave == 0) {
|
||||||
raise_exception(TT_SPILL | (env->otherwin != 0 ?
|
raise_exception(TT_SPILL | (env->otherwin != 0 ?
|
||||||
(TT_WOTHER | ((env->wstate & 0x38) >> 1)):
|
(TT_WOTHER | ((env->wstate & 0x38) >> 1)):
|
||||||
((env->wstate & 0x7) << 2)));
|
((env->wstate & 0x7) << 2)));
|
||||||
} else {
|
} else {
|
||||||
if (env->cleanwin - env->canrestore == 0) {
|
if (env->cleanwin - env->canrestore == 0) {
|
||||||
// XXX Clean windows without trap
|
// XXX Clean windows without trap
|
||||||
raise_exception(TT_CLRWIN);
|
raise_exception(TT_CLRWIN);
|
||||||
} else {
|
} else {
|
||||||
env->cansave--;
|
env->cansave--;
|
||||||
env->canrestore++;
|
env->canrestore++;
|
||||||
set_cwp(cwp);
|
set_cwp(cwp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FORCE_RET();
|
FORCE_RET();
|
||||||
}
|
}
|
||||||
@ -1221,12 +1221,12 @@ void OPPROTO op_restore(void)
|
|||||||
cwp = (env->cwp + 1) & (NWINDOWS - 1);
|
cwp = (env->cwp + 1) & (NWINDOWS - 1);
|
||||||
if (env->canrestore == 0) {
|
if (env->canrestore == 0) {
|
||||||
raise_exception(TT_FILL | (env->otherwin != 0 ?
|
raise_exception(TT_FILL | (env->otherwin != 0 ?
|
||||||
(TT_WOTHER | ((env->wstate & 0x38) >> 1)):
|
(TT_WOTHER | ((env->wstate & 0x38) >> 1)):
|
||||||
((env->wstate & 0x7) << 2)));
|
((env->wstate & 0x7) << 2)));
|
||||||
} else {
|
} else {
|
||||||
env->cansave++;
|
env->cansave++;
|
||||||
env->canrestore--;
|
env->canrestore--;
|
||||||
set_cwp(cwp);
|
set_cwp(cwp);
|
||||||
}
|
}
|
||||||
FORCE_RET();
|
FORCE_RET();
|
||||||
}
|
}
|
||||||
@ -1576,15 +1576,15 @@ void OPPROTO op_clear_ieee_excp_and_FTT(void)
|
|||||||
#define F_BINOP(name) \
|
#define F_BINOP(name) \
|
||||||
F_OP(name, s) \
|
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); \
|
FT0 = float32_ ## name (FT0, FT1, &env->fp_status); \
|
||||||
check_ieee_exceptions(); \
|
check_ieee_exceptions(); \
|
||||||
} \
|
} \
|
||||||
F_OP(name, d) \
|
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); \
|
DT0 = float64_ ## name (DT0, DT1, &env->fp_status); \
|
||||||
check_ieee_exceptions(); \
|
check_ieee_exceptions(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
F_BINOP(add);
|
F_BINOP(add);
|
||||||
@ -1784,27 +1784,27 @@ void OPPROTO op_fdtox(void)
|
|||||||
void OPPROTO op_fmovs_cc(void)
|
void OPPROTO op_fmovs_cc(void)
|
||||||
{
|
{
|
||||||
if (T2)
|
if (T2)
|
||||||
FT0 = FT1;
|
FT0 = FT1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OPPROTO op_fmovd_cc(void)
|
void OPPROTO op_fmovd_cc(void)
|
||||||
{
|
{
|
||||||
if (T2)
|
if (T2)
|
||||||
DT0 = DT1;
|
DT0 = DT1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OPPROTO op_mov_cc(void)
|
void OPPROTO op_mov_cc(void)
|
||||||
{
|
{
|
||||||
if (T2)
|
if (T2)
|
||||||
T0 = T1;
|
T0 = T1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OPPROTO op_flushw(void)
|
void OPPROTO op_flushw(void)
|
||||||
{
|
{
|
||||||
if (env->cansave != NWINDOWS - 2) {
|
if (env->cansave != NWINDOWS - 2) {
|
||||||
raise_exception(TT_SPILL | (env->otherwin != 0 ?
|
raise_exception(TT_SPILL | (env->otherwin != 0 ?
|
||||||
(TT_WOTHER | ((env->wstate & 0x38) >> 1)):
|
(TT_WOTHER | ((env->wstate & 0x38) >> 1)):
|
||||||
((env->wstate & 0x7) << 2)));
|
((env->wstate & 0x7) << 2)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1812,9 +1812,9 @@ void OPPROTO op_saved(void)
|
|||||||
{
|
{
|
||||||
env->cansave++;
|
env->cansave++;
|
||||||
if (env->otherwin == 0)
|
if (env->otherwin == 0)
|
||||||
env->canrestore--;
|
env->canrestore--;
|
||||||
else
|
else
|
||||||
env->otherwin--;
|
env->otherwin--;
|
||||||
FORCE_RET();
|
FORCE_RET();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1822,11 +1822,11 @@ void OPPROTO op_restored(void)
|
|||||||
{
|
{
|
||||||
env->canrestore++;
|
env->canrestore++;
|
||||||
if (env->cleanwin < NWINDOWS - 1)
|
if (env->cleanwin < NWINDOWS - 1)
|
||||||
env->cleanwin++;
|
env->cleanwin++;
|
||||||
if (env->otherwin == 0)
|
if (env->otherwin == 0)
|
||||||
env->cansave--;
|
env->cansave--;
|
||||||
else
|
else
|
||||||
env->otherwin--;
|
env->otherwin--;
|
||||||
FORCE_RET();
|
FORCE_RET();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,29 +16,29 @@ void check_ieee_exceptions()
|
|||||||
T0 = get_float_exception_flags(&env->fp_status);
|
T0 = get_float_exception_flags(&env->fp_status);
|
||||||
if (T0)
|
if (T0)
|
||||||
{
|
{
|
||||||
/* Copy IEEE 754 flags into FSR */
|
/* Copy IEEE 754 flags into FSR */
|
||||||
if (T0 & float_flag_invalid)
|
if (T0 & float_flag_invalid)
|
||||||
env->fsr |= FSR_NVC;
|
env->fsr |= FSR_NVC;
|
||||||
if (T0 & float_flag_overflow)
|
if (T0 & float_flag_overflow)
|
||||||
env->fsr |= FSR_OFC;
|
env->fsr |= FSR_OFC;
|
||||||
if (T0 & float_flag_underflow)
|
if (T0 & float_flag_underflow)
|
||||||
env->fsr |= FSR_UFC;
|
env->fsr |= FSR_UFC;
|
||||||
if (T0 & float_flag_divbyzero)
|
if (T0 & float_flag_divbyzero)
|
||||||
env->fsr |= FSR_DZC;
|
env->fsr |= FSR_DZC;
|
||||||
if (T0 & float_flag_inexact)
|
if (T0 & float_flag_inexact)
|
||||||
env->fsr |= FSR_NXC;
|
env->fsr |= FSR_NXC;
|
||||||
|
|
||||||
if ((env->fsr & FSR_CEXC_MASK) & ((env->fsr & FSR_TEM_MASK) >> 23))
|
if ((env->fsr & FSR_CEXC_MASK) & ((env->fsr & FSR_TEM_MASK) >> 23))
|
||||||
{
|
{
|
||||||
/* Unmasked exception, generate a trap */
|
/* Unmasked exception, generate a trap */
|
||||||
env->fsr |= FSR_FTT_IEEE_EXCP;
|
env->fsr |= FSR_FTT_IEEE_EXCP;
|
||||||
raise_exception(TT_FP_EXCP);
|
raise_exception(TT_FP_EXCP);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Accumulate exceptions */
|
/* Accumulate exceptions */
|
||||||
env->fsr |= (env->fsr & FSR_CEXC_MASK) << 5;
|
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 */
|
case 2: /* SuperSparc MXCC registers */
|
||||||
break;
|
break;
|
||||||
case 3: /* MMU probe */
|
case 3: /* MMU probe */
|
||||||
{
|
{
|
||||||
int mmulev;
|
int mmulev;
|
||||||
|
|
||||||
mmulev = (T0 >> 8) & 15;
|
mmulev = (T0 >> 8) & 15;
|
||||||
if (mmulev > 4)
|
if (mmulev > 4)
|
||||||
ret = 0;
|
ret = 0;
|
||||||
else {
|
else {
|
||||||
ret = mmu_probe(env, T0, mmulev);
|
ret = mmu_probe(env, T0, mmulev);
|
||||||
//bswap32s(&ret);
|
//bswap32s(&ret);
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_MMU
|
#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
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 4: /* read MMU regs */
|
case 4: /* read MMU regs */
|
||||||
{
|
{
|
||||||
int reg = (T0 >> 8) & 0xf;
|
int reg = (T0 >> 8) & 0xf;
|
||||||
|
|
||||||
ret = env->mmuregs[reg];
|
ret = env->mmuregs[reg];
|
||||||
if (reg == 3) /* Fault status cleared on read */
|
if (reg == 3) /* Fault status cleared on read */
|
||||||
env->mmuregs[reg] = 0;
|
env->mmuregs[reg] = 0;
|
||||||
#ifdef DEBUG_MMU
|
#ifdef DEBUG_MMU
|
||||||
printf("mmu_read: reg[%d] = 0x%08x\n", reg, ret);
|
printf("mmu_read: reg[%d] = 0x%08x\n", reg, ret);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 9: /* Supervisor code access */
|
case 9: /* Supervisor code access */
|
||||||
switch(size) {
|
switch(size) {
|
||||||
case 1:
|
case 1:
|
||||||
@ -218,11 +218,11 @@ void helper_ld_asi(int asi, int size, int sign)
|
|||||||
ret = ldl_phys(T0 & ~3);
|
ret = ldl_phys(T0 & ~3);
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
ret = ldl_phys(T0 & ~3);
|
ret = ldl_phys(T0 & ~3);
|
||||||
T0 = ldl_phys((T0 + 4) & ~3);
|
T0 = ldl_phys((T0 + 4) & ~3);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x2e: /* MMU passthrough, 0xexxxxxxxx */
|
case 0x2e: /* MMU passthrough, 0xexxxxxxxx */
|
||||||
case 0x2f: /* MMU passthrough, 0xfxxxxxxxx */
|
case 0x2f: /* MMU passthrough, 0xfxxxxxxxx */
|
||||||
switch(size) {
|
switch(size) {
|
||||||
@ -244,14 +244,14 @@ void helper_ld_asi(int asi, int size, int sign)
|
|||||||
| ((target_phys_addr_t)(asi & 0xf) << 32));
|
| ((target_phys_addr_t)(asi & 0xf) << 32));
|
||||||
T0 = ldl_phys((target_phys_addr_t)((T0 + 4) & ~3)
|
T0 = ldl_phys((target_phys_addr_t)((T0 + 4) & ~3)
|
||||||
| ((target_phys_addr_t)(asi & 0xf) << 32));
|
| ((target_phys_addr_t)(asi & 0xf) << 32));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x21 ... 0x2d: /* MMU passthrough, unassigned */
|
case 0x21 ... 0x2d: /* MMU passthrough, unassigned */
|
||||||
default:
|
default:
|
||||||
do_unassigned_access(T0, 0, 0, 1);
|
do_unassigned_access(T0, 0, 0, 1);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
T1 = ret;
|
T1 = ret;
|
||||||
}
|
}
|
||||||
@ -262,48 +262,48 @@ void helper_st_asi(int asi, int size, int sign)
|
|||||||
case 2: /* SuperSparc MXCC registers */
|
case 2: /* SuperSparc MXCC registers */
|
||||||
break;
|
break;
|
||||||
case 3: /* MMU flush */
|
case 3: /* MMU flush */
|
||||||
{
|
{
|
||||||
int mmulev;
|
int mmulev;
|
||||||
|
|
||||||
mmulev = (T0 >> 8) & 15;
|
mmulev = (T0 >> 8) & 15;
|
||||||
#ifdef DEBUG_MMU
|
#ifdef DEBUG_MMU
|
||||||
printf("mmu flush level %d\n", mmulev);
|
printf("mmu flush level %d\n", mmulev);
|
||||||
#endif
|
#endif
|
||||||
switch (mmulev) {
|
switch (mmulev) {
|
||||||
case 0: // flush page
|
case 0: // flush page
|
||||||
tlb_flush_page(env, T0 & 0xfffff000);
|
tlb_flush_page(env, T0 & 0xfffff000);
|
||||||
break;
|
break;
|
||||||
case 1: // flush segment (256k)
|
case 1: // flush segment (256k)
|
||||||
case 2: // flush region (16M)
|
case 2: // flush region (16M)
|
||||||
case 3: // flush context (4G)
|
case 3: // flush context (4G)
|
||||||
case 4: // flush entire
|
case 4: // flush entire
|
||||||
tlb_flush(env, 1);
|
tlb_flush(env, 1);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_MMU
|
#ifdef DEBUG_MMU
|
||||||
dump_mmu(env);
|
dump_mmu(env);
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case 4: /* write MMU regs */
|
case 4: /* write MMU regs */
|
||||||
{
|
{
|
||||||
int reg = (T0 >> 8) & 0xf;
|
int reg = (T0 >> 8) & 0xf;
|
||||||
uint32_t oldreg;
|
uint32_t oldreg;
|
||||||
|
|
||||||
oldreg = env->mmuregs[reg];
|
oldreg = env->mmuregs[reg];
|
||||||
switch(reg) {
|
switch(reg) {
|
||||||
case 0:
|
case 0:
|
||||||
env->mmuregs[reg] &= ~(MMU_E | MMU_NF);
|
env->mmuregs[reg] &= ~(MMU_E | MMU_NF);
|
||||||
env->mmuregs[reg] |= T1 & (MMU_E | MMU_NF);
|
env->mmuregs[reg] |= T1 & (MMU_E | MMU_NF);
|
||||||
// Mappings generated during no-fault mode or MMU
|
// Mappings generated during no-fault mode or MMU
|
||||||
// disabled mode are invalid in normal mode
|
// disabled mode are invalid in normal mode
|
||||||
if (oldreg != env->mmuregs[reg])
|
if (oldreg != env->mmuregs[reg])
|
||||||
tlb_flush(env, 1);
|
tlb_flush(env, 1);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
env->mmuregs[reg] = T1;
|
env->mmuregs[reg] = T1;
|
||||||
if (oldreg != env->mmuregs[reg]) {
|
if (oldreg != env->mmuregs[reg]) {
|
||||||
/* we flush when the MMU context changes because
|
/* we flush when the MMU context changes because
|
||||||
QEMU has no MMU context support */
|
QEMU has no MMU context support */
|
||||||
@ -314,17 +314,17 @@ void helper_st_asi(int asi, int size, int sign)
|
|||||||
case 4:
|
case 4:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
env->mmuregs[reg] = T1;
|
env->mmuregs[reg] = T1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_MMU
|
#ifdef DEBUG_MMU
|
||||||
if (oldreg != env->mmuregs[reg]) {
|
if (oldreg != env->mmuregs[reg]) {
|
||||||
printf("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, 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
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case 0xc: /* I-cache tag */
|
case 0xc: /* I-cache tag */
|
||||||
case 0xd: /* I-cache data */
|
case 0xd: /* I-cache data */
|
||||||
case 0xe: /* D-cache tag */
|
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 */
|
case 0x14: /* I/D-cache flush user */
|
||||||
break;
|
break;
|
||||||
case 0x17: /* Block copy, sta access */
|
case 0x17: /* Block copy, sta access */
|
||||||
{
|
{
|
||||||
// value (T1) = src
|
// value (T1) = src
|
||||||
// address (T0) = dst
|
// address (T0) = dst
|
||||||
// copy 32 bytes
|
// copy 32 bytes
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
uint32_t src = T1 & ~3, dst = T0 & ~3, temp;
|
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);
|
temp = ldl_kernel(src);
|
||||||
stl_kernel(dst, temp);
|
stl_kernel(dst, temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case 0x1f: /* Block fill, stda access */
|
case 0x1f: /* Block fill, stda access */
|
||||||
{
|
{
|
||||||
// value (T1, T2)
|
// value (T1, T2)
|
||||||
// address (T0) = dst
|
// address (T0) = dst
|
||||||
// fill 32 bytes
|
// fill 32 bytes
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
uint32_t dst = T0 & 7;
|
uint32_t dst = T0 & 7;
|
||||||
uint64_t val;
|
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)
|
for (i = 0; i < 32; i += 8, dst += 8)
|
||||||
stq_kernel(dst, val);
|
stq_kernel(dst, val);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case 0x20: /* MMU passthrough */
|
case 0x20: /* MMU passthrough */
|
||||||
{
|
{
|
||||||
switch(size) {
|
switch(size) {
|
||||||
case 1:
|
case 1:
|
||||||
stb_phys(T0, T1);
|
stb_phys(T0, T1);
|
||||||
@ -382,11 +382,11 @@ void helper_st_asi(int asi, int size, int sign)
|
|||||||
stl_phys((T0 + 4) & ~3, T2);
|
stl_phys((T0 + 4) & ~3, T2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case 0x2e: /* MMU passthrough, 0xexxxxxxxx */
|
case 0x2e: /* MMU passthrough, 0xexxxxxxxx */
|
||||||
case 0x2f: /* MMU passthrough, 0xfxxxxxxxx */
|
case 0x2f: /* MMU passthrough, 0xfxxxxxxxx */
|
||||||
{
|
{
|
||||||
switch(size) {
|
switch(size) {
|
||||||
case 1:
|
case 1:
|
||||||
stb_phys((target_phys_addr_t)T0
|
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);
|
| ((target_phys_addr_t)(asi & 0xf) << 32), T1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case 0x31: /* Ross RT620 I-cache flush */
|
case 0x31: /* Ross RT620 I-cache flush */
|
||||||
case 0x36: /* I-cache flash clear */
|
case 0x36: /* I-cache flash clear */
|
||||||
case 0x37: /* D-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 */
|
case 0x21 ... 0x2d: /* MMU passthrough, unassigned */
|
||||||
default:
|
default:
|
||||||
do_unassigned_access(T0, 1, 0, 1);
|
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;
|
uint64_t ret = 0;
|
||||||
|
|
||||||
if (asi < 0x80 && (env->pstate & PS_PRIV) == 0)
|
if (asi < 0x80 && (env->pstate & PS_PRIV) == 0)
|
||||||
raise_exception(TT_PRIV_ACT);
|
raise_exception(TT_PRIV_ACT);
|
||||||
|
|
||||||
switch (asi) {
|
switch (asi) {
|
||||||
case 0x14: // Bypass
|
case 0x14: // Bypass
|
||||||
case 0x15: // Bypass, non-cacheable
|
case 0x15: // Bypass, non-cacheable
|
||||||
{
|
{
|
||||||
switch(size) {
|
switch(size) {
|
||||||
case 1:
|
case 1:
|
||||||
ret = ldub_phys(T0);
|
ret = ldub_phys(T0);
|
||||||
@ -450,8 +450,8 @@ void helper_ld_asi(int asi, int size, int sign)
|
|||||||
ret = ldq_phys(T0 & ~7);
|
ret = ldq_phys(T0 & ~7);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x04: // Nucleus
|
case 0x04: // Nucleus
|
||||||
case 0x0c: // Nucleus Little Endian (LE)
|
case 0x0c: // Nucleus Little Endian (LE)
|
||||||
case 0x10: // As if user primary
|
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 0x89: // Secondary LE
|
||||||
case 0x8a: // Primary no-fault LE
|
case 0x8a: // Primary no-fault LE
|
||||||
case 0x8b: // Secondary no-fault LE
|
case 0x8b: // Secondary no-fault LE
|
||||||
// XXX
|
// XXX
|
||||||
break;
|
break;
|
||||||
case 0x45: // LSU
|
case 0x45: // LSU
|
||||||
ret = env->lsu;
|
ret = env->lsu;
|
||||||
break;
|
break;
|
||||||
case 0x50: // I-MMU regs
|
case 0x50: // I-MMU regs
|
||||||
{
|
{
|
||||||
int reg = (T0 >> 3) & 0xf;
|
int reg = (T0 >> 3) & 0xf;
|
||||||
|
|
||||||
ret = env->immuregs[reg];
|
ret = env->immuregs[reg];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x51: // I-MMU 8k TSB pointer
|
case 0x51: // I-MMU 8k TSB pointer
|
||||||
case 0x52: // I-MMU 64k TSB pointer
|
case 0x52: // I-MMU 64k TSB pointer
|
||||||
case 0x55: // I-MMU data access
|
case 0x55: // I-MMU data access
|
||||||
// XXX
|
// XXX
|
||||||
break;
|
break;
|
||||||
case 0x56: // I-MMU tag read
|
case 0x56: // I-MMU tag read
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
for (i = 0; i < 64; i++) {
|
for (i = 0; i < 64; i++) {
|
||||||
// Valid, ctx match, vaddr match
|
// Valid, ctx match, vaddr match
|
||||||
if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0 &&
|
if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0 &&
|
||||||
env->itlb_tag[i] == T0) {
|
env->itlb_tag[i] == T0) {
|
||||||
ret = env->itlb_tag[i];
|
ret = env->itlb_tag[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x58: // D-MMU regs
|
case 0x58: // D-MMU regs
|
||||||
{
|
{
|
||||||
int reg = (T0 >> 3) & 0xf;
|
int reg = (T0 >> 3) & 0xf;
|
||||||
|
|
||||||
ret = env->dmmuregs[reg];
|
ret = env->dmmuregs[reg];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x5e: // D-MMU tag read
|
case 0x5e: // D-MMU tag read
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
for (i = 0; i < 64; i++) {
|
for (i = 0; i < 64; i++) {
|
||||||
// Valid, ctx match, vaddr match
|
// Valid, ctx match, vaddr match
|
||||||
if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0 &&
|
if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0 &&
|
||||||
env->dtlb_tag[i] == T0) {
|
env->dtlb_tag[i] == T0) {
|
||||||
ret = env->dtlb_tag[i];
|
ret = env->dtlb_tag[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x59: // D-MMU 8k TSB pointer
|
case 0x59: // D-MMU 8k TSB pointer
|
||||||
case 0x5a: // D-MMU 64k TSB pointer
|
case 0x5a: // D-MMU 64k TSB pointer
|
||||||
case 0x5b: // D-MMU data 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 0x48: // Interrupt dispatch, RO
|
||||||
case 0x49: // Interrupt data receive
|
case 0x49: // Interrupt data receive
|
||||||
case 0x7f: // Incoming interrupt vector, RO
|
case 0x7f: // Incoming interrupt vector, RO
|
||||||
// XXX
|
// XXX
|
||||||
break;
|
break;
|
||||||
case 0x54: // I-MMU data in, WO
|
case 0x54: // I-MMU data in, WO
|
||||||
case 0x57: // I-MMU demap, WO
|
case 0x57: // I-MMU demap, WO
|
||||||
case 0x5c: // D-MMU data in, 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
|
case 0x77: // Interrupt vector, WO
|
||||||
default:
|
default:
|
||||||
do_unassigned_access(T0, 0, 0, 1);
|
do_unassigned_access(T0, 0, 0, 1);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
T1 = ret;
|
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)
|
void helper_st_asi(int asi, int size, int sign)
|
||||||
{
|
{
|
||||||
if (asi < 0x80 && (env->pstate & PS_PRIV) == 0)
|
if (asi < 0x80 && (env->pstate & PS_PRIV) == 0)
|
||||||
raise_exception(TT_PRIV_ACT);
|
raise_exception(TT_PRIV_ACT);
|
||||||
|
|
||||||
switch(asi) {
|
switch(asi) {
|
||||||
case 0x14: // Bypass
|
case 0x14: // Bypass
|
||||||
case 0x15: // Bypass, non-cacheable
|
case 0x15: // Bypass, non-cacheable
|
||||||
{
|
{
|
||||||
switch(size) {
|
switch(size) {
|
||||||
case 1:
|
case 1:
|
||||||
stb_phys(T0, T1);
|
stb_phys(T0, T1);
|
||||||
@ -567,8 +567,8 @@ void helper_st_asi(int asi, int size, int sign)
|
|||||||
stq_phys(T0 & ~7, T1);
|
stq_phys(T0 & ~7, T1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case 0x04: // Nucleus
|
case 0x04: // Nucleus
|
||||||
case 0x0c: // Nucleus Little Endian (LE)
|
case 0x0c: // Nucleus Little Endian (LE)
|
||||||
case 0x10: // As if user primary
|
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 0x4a: // UPA config
|
||||||
case 0x88: // Primary LE
|
case 0x88: // Primary LE
|
||||||
case 0x89: // Secondary LE
|
case 0x89: // Secondary LE
|
||||||
// XXX
|
// XXX
|
||||||
return;
|
return;
|
||||||
case 0x45: // LSU
|
case 0x45: // LSU
|
||||||
{
|
{
|
||||||
uint64_t oldreg;
|
uint64_t oldreg;
|
||||||
|
|
||||||
oldreg = env->lsu;
|
oldreg = env->lsu;
|
||||||
env->lsu = T1 & (DMMU_E | IMMU_E);
|
env->lsu = T1 & (DMMU_E | IMMU_E);
|
||||||
// Mappings generated during D/I MMU disabled mode are
|
// Mappings generated during D/I MMU disabled mode are
|
||||||
// invalid in normal mode
|
// invalid in normal mode
|
||||||
if (oldreg != env->lsu) {
|
if (oldreg != env->lsu) {
|
||||||
#ifdef DEBUG_MMU
|
#ifdef DEBUG_MMU
|
||||||
printf("LSU change: 0x%" PRIx64 " -> 0x%" PRIx64 "\n", oldreg, env->lsu);
|
printf("LSU change: 0x%" PRIx64 " -> 0x%" PRIx64 "\n", oldreg, env->lsu);
|
||||||
dump_mmu(env);
|
dump_mmu(env);
|
||||||
#endif
|
#endif
|
||||||
tlb_flush(env, 1);
|
tlb_flush(env, 1);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case 0x50: // I-MMU regs
|
case 0x50: // I-MMU regs
|
||||||
{
|
{
|
||||||
int reg = (T0 >> 3) & 0xf;
|
int reg = (T0 >> 3) & 0xf;
|
||||||
uint64_t oldreg;
|
uint64_t oldreg;
|
||||||
|
|
||||||
oldreg = env->immuregs[reg];
|
oldreg = env->immuregs[reg];
|
||||||
switch(reg) {
|
switch(reg) {
|
||||||
case 0: // RO
|
case 0: // RO
|
||||||
case 4:
|
case 4:
|
||||||
@ -617,73 +617,73 @@ void helper_st_asi(int asi, int size, int sign)
|
|||||||
case 8:
|
case 8:
|
||||||
return;
|
return;
|
||||||
case 3: // SFSR
|
case 3: // SFSR
|
||||||
if ((T1 & 1) == 0)
|
if ((T1 & 1) == 0)
|
||||||
T1 = 0; // Clear SFSR
|
T1 = 0; // Clear SFSR
|
||||||
break;
|
break;
|
||||||
case 5: // TSB access
|
case 5: // TSB access
|
||||||
case 6: // Tag access
|
case 6: // Tag access
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
env->immuregs[reg] = T1;
|
env->immuregs[reg] = T1;
|
||||||
#ifdef DEBUG_MMU
|
#ifdef DEBUG_MMU
|
||||||
if (oldreg != env->immuregs[reg]) {
|
if (oldreg != env->immuregs[reg]) {
|
||||||
printf("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, 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
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case 0x54: // I-MMU data in
|
case 0x54: // I-MMU data in
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
// Try finding an invalid entry
|
// Try finding an invalid entry
|
||||||
for (i = 0; i < 64; i++) {
|
for (i = 0; i < 64; i++) {
|
||||||
if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0) {
|
if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0) {
|
||||||
env->itlb_tag[i] = env->immuregs[6];
|
env->itlb_tag[i] = env->immuregs[6];
|
||||||
env->itlb_tte[i] = T1;
|
env->itlb_tte[i] = T1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Try finding an unlocked entry
|
// Try finding an unlocked entry
|
||||||
for (i = 0; i < 64; i++) {
|
for (i = 0; i < 64; i++) {
|
||||||
if ((env->itlb_tte[i] & 0x40) == 0) {
|
if ((env->itlb_tte[i] & 0x40) == 0) {
|
||||||
env->itlb_tag[i] = env->immuregs[6];
|
env->itlb_tag[i] = env->immuregs[6];
|
||||||
env->itlb_tte[i] = T1;
|
env->itlb_tte[i] = T1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// error state?
|
// error state?
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case 0x55: // I-MMU data access
|
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_tag[i] = env->immuregs[6];
|
||||||
env->itlb_tte[i] = T1;
|
env->itlb_tte[i] = T1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case 0x57: // I-MMU demap
|
case 0x57: // I-MMU demap
|
||||||
// XXX
|
// XXX
|
||||||
return;
|
return;
|
||||||
case 0x58: // D-MMU regs
|
case 0x58: // D-MMU regs
|
||||||
{
|
{
|
||||||
int reg = (T0 >> 3) & 0xf;
|
int reg = (T0 >> 3) & 0xf;
|
||||||
uint64_t oldreg;
|
uint64_t oldreg;
|
||||||
|
|
||||||
oldreg = env->dmmuregs[reg];
|
oldreg = env->dmmuregs[reg];
|
||||||
switch(reg) {
|
switch(reg) {
|
||||||
case 0: // RO
|
case 0: // RO
|
||||||
case 4:
|
case 4:
|
||||||
return;
|
return;
|
||||||
case 3: // SFSR
|
case 3: // SFSR
|
||||||
if ((T1 & 1) == 0) {
|
if ((T1 & 1) == 0) {
|
||||||
T1 = 0; // Clear SFSR, Fault address
|
T1 = 0; // Clear SFSR, Fault address
|
||||||
env->dmmuregs[4] = 0;
|
env->dmmuregs[4] = 0;
|
||||||
}
|
}
|
||||||
env->dmmuregs[reg] = T1;
|
env->dmmuregs[reg] = T1;
|
||||||
break;
|
break;
|
||||||
case 1: // Primary context
|
case 1: // Primary context
|
||||||
case 2: // Secondary context
|
case 2: // Secondary context
|
||||||
@ -694,50 +694,50 @@ void helper_st_asi(int asi, int size, int sign)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
env->dmmuregs[reg] = T1;
|
env->dmmuregs[reg] = T1;
|
||||||
#ifdef DEBUG_MMU
|
#ifdef DEBUG_MMU
|
||||||
if (oldreg != env->dmmuregs[reg]) {
|
if (oldreg != env->dmmuregs[reg]) {
|
||||||
printf("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, 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
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case 0x5c: // D-MMU data in
|
case 0x5c: // D-MMU data in
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
// Try finding an invalid entry
|
// Try finding an invalid entry
|
||||||
for (i = 0; i < 64; i++) {
|
for (i = 0; i < 64; i++) {
|
||||||
if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0) {
|
if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0) {
|
||||||
env->dtlb_tag[i] = env->dmmuregs[6];
|
env->dtlb_tag[i] = env->dmmuregs[6];
|
||||||
env->dtlb_tte[i] = T1;
|
env->dtlb_tte[i] = T1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Try finding an unlocked entry
|
// Try finding an unlocked entry
|
||||||
for (i = 0; i < 64; i++) {
|
for (i = 0; i < 64; i++) {
|
||||||
if ((env->dtlb_tte[i] & 0x40) == 0) {
|
if ((env->dtlb_tte[i] & 0x40) == 0) {
|
||||||
env->dtlb_tag[i] = env->dmmuregs[6];
|
env->dtlb_tag[i] = env->dmmuregs[6];
|
||||||
env->dtlb_tte[i] = T1;
|
env->dtlb_tte[i] = T1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// error state?
|
// error state?
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case 0x5d: // D-MMU data access
|
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_tag[i] = env->dmmuregs[6];
|
||||||
env->dtlb_tte[i] = T1;
|
env->dtlb_tte[i] = T1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case 0x5f: // D-MMU demap
|
case 0x5f: // D-MMU demap
|
||||||
case 0x49: // Interrupt data receive
|
case 0x49: // Interrupt data receive
|
||||||
// XXX
|
// XXX
|
||||||
return;
|
return;
|
||||||
case 0x51: // I-MMU 8k TSB pointer, RO
|
case 0x51: // I-MMU 8k TSB pointer, RO
|
||||||
case 0x52: // I-MMU 64k TSB pointer, RO
|
case 0x52: // I-MMU 64k TSB pointer, RO
|
||||||
case 0x56: // I-MMU tag read, 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
|
case 0x8b: // Secondary no-fault LE, RO
|
||||||
default:
|
default:
|
||||||
do_unassigned_access(T0, 1, 0, 1);
|
do_unassigned_access(T0, 1, 0, 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -783,17 +783,17 @@ void helper_ldfsr(void)
|
|||||||
switch (env->fsr & FSR_RD_MASK) {
|
switch (env->fsr & FSR_RD_MASK) {
|
||||||
case FSR_RD_NEAREST:
|
case FSR_RD_NEAREST:
|
||||||
rnd_mode = float_round_nearest_even;
|
rnd_mode = float_round_nearest_even;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
case FSR_RD_ZERO:
|
case FSR_RD_ZERO:
|
||||||
rnd_mode = float_round_to_zero;
|
rnd_mode = float_round_to_zero;
|
||||||
break;
|
break;
|
||||||
case FSR_RD_POS:
|
case FSR_RD_POS:
|
||||||
rnd_mode = float_round_up;
|
rnd_mode = float_round_up;
|
||||||
break;
|
break;
|
||||||
case FSR_RD_NEG:
|
case FSR_RD_NEG:
|
||||||
rnd_mode = float_round_down;
|
rnd_mode = float_round_down;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
set_float_rounding_mode(rnd_mode, &env->fp_status);
|
set_float_rounding_mode(rnd_mode, &env->fp_status);
|
||||||
}
|
}
|
||||||
@ -835,13 +835,13 @@ static inline uint64_t *get_gregset(uint64_t pstate)
|
|||||||
switch (pstate) {
|
switch (pstate) {
|
||||||
default:
|
default:
|
||||||
case 0:
|
case 0:
|
||||||
return env->bgregs;
|
return env->bgregs;
|
||||||
case PS_AG:
|
case PS_AG:
|
||||||
return env->agregs;
|
return env->agregs;
|
||||||
case PS_MG:
|
case PS_MG:
|
||||||
return env->mgregs;
|
return env->mgregs;
|
||||||
case PS_IG:
|
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;
|
pstate_regs = env->pstate & 0xc01;
|
||||||
new_pstate_regs = new_pstate & 0xc01;
|
new_pstate_regs = new_pstate & 0xc01;
|
||||||
if (new_pstate_regs != pstate_regs) {
|
if (new_pstate_regs != pstate_regs) {
|
||||||
// Switch global register bank
|
// Switch global register bank
|
||||||
src = get_gregset(new_pstate_regs);
|
src = get_gregset(new_pstate_regs);
|
||||||
dst = get_gregset(pstate_regs);
|
dst = get_gregset(pstate_regs);
|
||||||
memcpy32(dst, env->gregs);
|
memcpy32(dst, env->gregs);
|
||||||
memcpy32(env->gregs, src);
|
memcpy32(env->gregs, src);
|
||||||
}
|
}
|
||||||
env->pstate = new_pstate;
|
env->pstate = new_pstate;
|
||||||
}
|
}
|
||||||
@ -927,36 +927,36 @@ void do_interrupt(int intno)
|
|||||||
{
|
{
|
||||||
#ifdef DEBUG_PCALL
|
#ifdef DEBUG_PCALL
|
||||||
if (loglevel & CPU_LOG_INT) {
|
if (loglevel & CPU_LOG_INT) {
|
||||||
static int count;
|
static int count;
|
||||||
fprintf(logfile, "%6d: v=%04x pc=%016" PRIx64 " npc=%016" PRIx64 " SP=%016" PRIx64 "\n",
|
fprintf(logfile, "%6d: v=%04x pc=%016" PRIx64 " npc=%016" PRIx64 " SP=%016" PRIx64 "\n",
|
||||||
count, intno,
|
count, intno,
|
||||||
env->pc,
|
env->pc,
|
||||||
env->npc, env->regwptr[6]);
|
env->npc, env->regwptr[6]);
|
||||||
cpu_dump_state(env, logfile, fprintf, 0);
|
cpu_dump_state(env, logfile, fprintf, 0);
|
||||||
#if 0
|
#if 0
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
uint8_t *ptr;
|
uint8_t *ptr;
|
||||||
|
|
||||||
fprintf(logfile, " code=");
|
fprintf(logfile, " code=");
|
||||||
ptr = (uint8_t *)env->pc;
|
ptr = (uint8_t *)env->pc;
|
||||||
for(i = 0; i < 16; i++) {
|
for(i = 0; i < 16; i++) {
|
||||||
fprintf(logfile, " %02x", ldub(ptr + i));
|
fprintf(logfile, " %02x", ldub(ptr + i));
|
||||||
}
|
}
|
||||||
fprintf(logfile, "\n");
|
fprintf(logfile, "\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
if (env->tl == MAXTL) {
|
if (env->tl == MAXTL) {
|
||||||
cpu_abort(env, "Trap 0x%04x while trap level is MAXTL, Error state", env->exception_index);
|
cpu_abort(env, "Trap 0x%04x while trap level is MAXTL, Error state", env->exception_index);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
env->tstate[env->tl] = ((uint64_t)GET_CCR(env) << 32) | ((env->asi & 0xff) << 24) |
|
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->tpc[env->tl] = env->pc;
|
||||||
env->tnpc[env->tl] = env->npc;
|
env->tnpc[env->tl] = env->npc;
|
||||||
env->tt[env->tl] = intno;
|
env->tt[env->tl] = intno;
|
||||||
@ -971,11 +971,11 @@ void do_interrupt(int intno)
|
|||||||
env->tbr &= ~0x7fffULL;
|
env->tbr &= ~0x7fffULL;
|
||||||
env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
|
env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
|
||||||
if (env->tl < MAXTL - 1) {
|
if (env->tl < MAXTL - 1) {
|
||||||
env->tl++;
|
env->tl++;
|
||||||
} else {
|
} else {
|
||||||
env->pstate |= PS_RED;
|
env->pstate |= PS_RED;
|
||||||
if (env->tl != MAXTL)
|
if (env->tl != MAXTL)
|
||||||
env->tl++;
|
env->tl++;
|
||||||
}
|
}
|
||||||
env->pc = env->tbr;
|
env->pc = env->tbr;
|
||||||
env->npc = env->pc + 4;
|
env->npc = env->pc + 4;
|
||||||
@ -988,32 +988,32 @@ void do_interrupt(int intno)
|
|||||||
|
|
||||||
#ifdef DEBUG_PCALL
|
#ifdef DEBUG_PCALL
|
||||||
if (loglevel & CPU_LOG_INT) {
|
if (loglevel & CPU_LOG_INT) {
|
||||||
static int count;
|
static int count;
|
||||||
fprintf(logfile, "%6d: v=%02x pc=%08x npc=%08x SP=%08x\n",
|
fprintf(logfile, "%6d: v=%02x pc=%08x npc=%08x SP=%08x\n",
|
||||||
count, intno,
|
count, intno,
|
||||||
env->pc,
|
env->pc,
|
||||||
env->npc, env->regwptr[6]);
|
env->npc, env->regwptr[6]);
|
||||||
cpu_dump_state(env, logfile, fprintf, 0);
|
cpu_dump_state(env, logfile, fprintf, 0);
|
||||||
#if 0
|
#if 0
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
uint8_t *ptr;
|
uint8_t *ptr;
|
||||||
|
|
||||||
fprintf(logfile, " code=");
|
fprintf(logfile, " code=");
|
||||||
ptr = (uint8_t *)env->pc;
|
ptr = (uint8_t *)env->pc;
|
||||||
for(i = 0; i < 16; i++) {
|
for(i = 0; i < 16; i++) {
|
||||||
fprintf(logfile, " %02x", ldub(ptr + i));
|
fprintf(logfile, " %02x", ldub(ptr + i));
|
||||||
}
|
}
|
||||||
fprintf(logfile, "\n");
|
fprintf(logfile, "\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
if (env->psret == 0) {
|
if (env->psret == 0) {
|
||||||
cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state", env->exception_index);
|
cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state", env->exception_index);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
env->psret = 0;
|
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;
|
saved_env = env;
|
||||||
env = cpu_single_env;
|
env = cpu_single_env;
|
||||||
if (env->mmuregs[3]) /* Fault status register */
|
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)
|
if (is_asi)
|
||||||
env->mmuregs[3] |= 1 << 16;
|
env->mmuregs[3] |= 1 << 16;
|
||||||
if (env->psrs)
|
if (env->psrs)
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
#define SPARC_LD_OP(name, qp) \
|
#define SPARC_LD_OP(name, qp) \
|
||||||
void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \
|
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) \
|
#define SPARC_LD_OP_S(name, qp) \
|
||||||
void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \
|
void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \
|
||||||
{ \
|
{ \
|
||||||
T1 = (target_long)glue(qp, MEMSUFFIX)(T0); \
|
T1 = (target_long)glue(qp, MEMSUFFIX)(T0); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SPARC_ST_OP(name, op) \
|
#define SPARC_ST_OP(name, op) \
|
||||||
@ -85,7 +85,7 @@ void OPPROTO glue(op_cas, MEMSUFFIX)(void)
|
|||||||
tmp = glue(ldl, MEMSUFFIX)(T0);
|
tmp = glue(ldl, MEMSUFFIX)(T0);
|
||||||
T2 &= 0xffffffffULL;
|
T2 &= 0xffffffffULL;
|
||||||
if (tmp == (T1 & 0xffffffffULL)) {
|
if (tmp == (T1 & 0xffffffffULL)) {
|
||||||
glue(stl, MEMSUFFIX)(T0, T2);
|
glue(stl, MEMSUFFIX)(T0, T2);
|
||||||
}
|
}
|
||||||
T2 = tmp;
|
T2 = tmp;
|
||||||
}
|
}
|
||||||
@ -98,7 +98,7 @@ void OPPROTO glue(op_casx, MEMSUFFIX)(void)
|
|||||||
tmp = (uint64_t)glue(ldl, MEMSUFFIX)(T0) << 32;
|
tmp = (uint64_t)glue(ldl, MEMSUFFIX)(T0) << 32;
|
||||||
tmp |= glue(ldl, MEMSUFFIX)(T0);
|
tmp |= glue(ldl, MEMSUFFIX)(T0);
|
||||||
if (tmp == T1) {
|
if (tmp == T1) {
|
||||||
glue(stq, MEMSUFFIX)(T0, T2);
|
glue(stq, MEMSUFFIX)(T0, T2);
|
||||||
}
|
}
|
||||||
T2 = tmp;
|
T2 = tmp;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user