extern uae_u32 needed_flags;
-extern cacheline cache_tags[];
extern uae_u8* comp_pc_p;
extern void* pushall_call_handler;
n_smallstatus nat[N_REGS];
} smallstate;
-extern bigstate live;
extern int touchcnt;
DECLARE(cmov_b_rr(RW1 d, R1 s, IMM cc));
DECLARE(cmov_w_rr(RW2 d, R2 s, IMM cc));
DECLARE(cmov_l_rr(RW4 d, R4 s, IMM cc));
+DECLARE(setzflg_l(RW4 r));
DECLARE(cmov_l_rm(RW4 d, IMM s, IMM cc));
DECLARE(bsf_l_rr(W4 d, R4 s));
DECLARE(pop_m(IMM d));
void comp_fsave_opp (uae_u32 opcode);
void comp_frestore_opp (uae_u32 opcode);
void comp_fpp_opp (uae_u32 opcode, uae_u16 extra);
+
+#ifdef _WIN32
+LONG WINAPI EvalException(LPEXCEPTION_POINTERS info);
+#if defined(_MSC_VER) && !defined(NO_WIN32_EXCEPTION_HANDLER)
+#define USE_STRUCTURED_EXCEPTION_HANDLING
+#endif
+#endif
extern void comp_fscc_opp (uae_u32 opcode, uae_u16 extra);
extern uae_u32 needed_flags;
-extern cacheline cache_tags[];
extern uae_u8* comp_pc_p;
extern void* pushall_call_handler;
raw_add_l_ri(4,off);
}
+
/*************************************************************************
* Handling mistaken direct memory access *
*************************************************************************/
-
-#ifdef NATMEM_OFFSET
-#ifdef _WIN32 // %%% BRIAN KING WAS HERE %%%
-#include <winbase.h>
-#else
-#include <asm/sigcontext.h>
-#endif
-#include <signal.h>
-
-#define SIG_READ 1
-#define SIG_WRITE 2
-
-static int in_handler=0;
-static uae_u8 *veccode;
-
-#ifdef _WIN32
-
-#if defined(CPU_64_BIT)
-#define ctxPC (pContext->Rip)
-#else
-#define ctxPC (pContext->Eip)
-#endif
-
-int EvalException (LPEXCEPTION_POINTERS blah, int n_except)
-{
- PEXCEPTION_RECORD pExceptRecord = NULL;
- PCONTEXT pContext = NULL;
-
- uae_u8* i = NULL;
- uae_u32 addr = 0;
- int r=-1;
- int size=4;
- int dir=-1;
- int len=0;
-
- if (n_except != STATUS_ACCESS_VIOLATION || !canbang || currprefs.cachesize == 0)
- return EXCEPTION_CONTINUE_SEARCH;
-
- pExceptRecord = blah->ExceptionRecord;
- pContext = blah->ContextRecord;
-
- if (pContext)
- i = (uae_u8 *)ctxPC;
- if (pExceptRecord)
- addr = (uae_u32)(pExceptRecord->ExceptionInformation[1]);
-#ifdef JIT_DEBUG
- write_log (_T("JIT: fault address is 0x%x at 0x%x\n"),addr,i);
-#endif
- if (!canbang || !currprefs.cachesize)
- return EXCEPTION_CONTINUE_SEARCH;
-
- if (in_handler)
- write_log (_T("JIT: Argh --- Am already in a handler. Shouldn't happen!\n"));
-
- if (canbang && i>=compiled_code && i<=current_compile_p) {
- if (*i==0x66) {
- i++;
- size=2;
- len++;
- }
-
- switch(i[0]) {
- case 0x8a:
- if ((i[1]&0xc0)==0x80) {
- r=(i[1]>>3)&7;
- dir=SIG_READ;
- size=1;
- len+=6;
- break;
- }
- break;
- case 0x88:
- if ((i[1]&0xc0)==0x80) {
- r=(i[1]>>3)&7;
- dir=SIG_WRITE;
- size=1;
- len+=6;
- break;
- }
- break;
- case 0x8b:
- switch(i[1]&0xc0) {
- case 0x80:
- r=(i[1]>>3)&7;
- dir=SIG_READ;
- len+=6;
- break;
- case 0x40:
- r=(i[1]>>3)&7;
- dir=SIG_READ;
- len+=3;
- break;
- case 0x00:
- r=(i[1]>>3)&7;
- dir=SIG_READ;
- len+=2;
- break;
- default:
- break;
- }
- break;
- case 0x89:
- switch(i[1]&0xc0) {
- case 0x80:
- r=(i[1]>>3)&7;
- dir=SIG_WRITE;
- len+=6;
- break;
- case 0x40:
- r=(i[1]>>3)&7;
- dir=SIG_WRITE;
- len+=3;
- break;
- case 0x00:
- r=(i[1]>>3)&7;
- dir=SIG_WRITE;
- len+=2;
- break;
- }
- break;
- }
- }
-
- if (r!=-1) {
- void* pr=NULL;
-#ifdef JIT_DEBUG
- write_log (_T("JIT: register was %d, direction was %d, size was %d\n"),r,dir,size);
+#ifdef UAE
+#include "exception_handler.cpp"
#endif
- switch(r) {
-#if defined(CPU_64_BIT)
- case 0: pr=&(pContext->Rax); break;
- case 1: pr=&(pContext->Rcx); break;
- case 2: pr=&(pContext->Rdx); break;
- case 3: pr=&(pContext->Rbx); break;
- case 4: pr=(size>1)?NULL:(((uae_u8*)&(pContext->Rax))+1); break;
- case 5: pr=(size>1)?
- (void*)(&(pContext->Rbp)):
- (void*)(((uae_u8*)&(pContext->Rcx))+1); break;
- case 6: pr=(size>1)?
- (void*)(&(pContext->Rsi)):
- (void*)(((uae_u8*)&(pContext->Rdx))+1); break;
- case 7: pr=(size>1)?
- (void*)(&(pContext->Rdi)):
- (void*)(((uae_u8*)&(pContext->Rbx))+1); break;
-#else
- case 0: pr=&(pContext->Eax); break;
- case 1: pr=&(pContext->Ecx); break;
- case 2: pr=&(pContext->Edx); break;
- case 3: pr=&(pContext->Ebx); break;
- case 4: pr=(size>1)?NULL:(((uae_u8*)&(pContext->Eax))+1); break;
- case 5: pr=(size>1)?
- (void*)(&(pContext->Ebp)):
- (void*)(((uae_u8*)&(pContext->Ecx))+1); break;
- case 6: pr=(size>1)?
- (void*)(&(pContext->Esi)):
- (void*)(((uae_u8*)&(pContext->Edx))+1); break;
- case 7: pr=(size>1)?
- (void*)(&(pContext->Edi)):
- (void*)(((uae_u8*)&(pContext->Ebx))+1); break;
-#endif
- default: abort();
- }
- if (pr) {
- blockinfo* bi;
-
- if (currprefs.comp_oldsegv) {
- addr-=(uae_u32)NATMEM_OFFSET;
-
-#ifdef JIT_DEBUG
- if ((addr>=0x10000000 && addr<0x40000000) ||
- (addr>=0x50000000)) {
- write_log (_T("JIT: Suspicious address 0x%x in SEGV handler.\n"),addr);
- }
-#endif
- if (dir==SIG_READ) {
- switch (size) {
- case 1: *((uae_u8*)pr)=get_byte (addr); break;
- case 2: *((uae_u16*)pr)=swap16(get_word (addr)); break;
- case 4: *((uae_u32*)pr)=swap32(get_long (addr)); break;
- default: abort();
- }
- }
- else { /* write */
- switch (size) {
- case 1: put_byte (addr,*((uae_u8*)pr)); break;
- case 2: put_word (addr,swap16(*((uae_u16*)pr))); break;
- case 4: put_long (addr,swap32(*((uae_u32*)pr))); break;
- default: abort();
- }
- }
-#ifdef JIT_DEBUG
- write_log (_T("JIT: Handled one access!\n"));
-#endif
- fflush(stdout);
- segvcount++;
- ctxPC+=len;
- }
- else {
- void* tmp=target;
- int i;
- uae_u8 vecbuf[5];
-
- addr-=(uae_u32)NATMEM_OFFSET;
-
-#ifdef JIT_DEBUG
- if ((addr>=0x10000000 && addr<0x40000000) ||
- (addr>=0x50000000)) {
- write_log (_T("JIT: Suspicious address 0x%x in SEGV handler.\n"),addr);
- }
-#endif
-
- target=(uae_u8*)ctxPC;
- for (i=0;i<5;i++)
- vecbuf[i]=target[i];
- emit_byte(0xe9);
- emit_long((uae_u32)veccode-(uae_u32)target-4);
-#ifdef JIT_DEBUG
-
- write_log (_T("JIT: Create jump to %p\n"),veccode);
- write_log (_T("JIT: Handled one access!\n"));
-#endif
- segvcount++;
-
- target=veccode;
-
- if (dir==SIG_READ) {
- switch(size) {
- case 1: raw_mov_b_ri(r,get_byte (addr)); break;
- case 2: raw_mov_w_ri(r,swap16(get_word (addr))); break;
- case 4: raw_mov_l_ri(r,swap32(get_long (addr))); break;
- default: abort();
- }
- }
- else { /* write */
- switch(size) {
- case 1: put_byte (addr,*((uae_u8*)pr)); break;
- case 2: put_word (addr,swap16(*((uae_u16*)pr))); break;
- case 4: put_long (addr,swap32(*((uae_u32*)pr))); break;
- default: abort();
- }
- }
- for (i=0;i<5;i++)
- raw_mov_b_mi(ctxPC+i,vecbuf[i]);
- raw_mov_l_mi((uae_u32)&in_handler,0);
- emit_byte(0xe9);
- emit_long(ctxPC+len-(uae_u32)target-4);
- in_handler=1;
- target=(uae_u8*)tmp;
- }
- bi=active;
- while (bi) {
- if (bi->handler &&
- (uae_u8*)bi->direct_handler<=i &&
- (uae_u8*)bi->nexthandler>i) {
-#ifdef JIT_DEBUG
- write_log (_T("JIT: deleted trigger (%p<%p<%p) %p\n"),
- bi->handler,
- i,
- bi->nexthandler,
- bi->pc_p);
-#endif
- invalidate_block(bi);
- raise_in_cl_list(bi);
- set_special(0);
- return EXCEPTION_CONTINUE_EXECUTION;
- }
- bi=bi->next;
- }
- /* Not found in the active list. Might be a rom routine that
- is in the dormant list */
- bi=dormant;
- while (bi) {
- if (bi->handler &&
- (uae_u8*)bi->direct_handler<=i &&
- (uae_u8*)bi->nexthandler>i) {
-#ifdef JIT_DEBUG
- write_log (_T("JIT: deleted trigger (%p<%p<%p) %p\n"),
- bi->handler,
- i,
- bi->nexthandler,
- bi->pc_p);
-#endif
- invalidate_block(bi);
- raise_in_cl_list(bi);
- set_special(0);
- return EXCEPTION_CONTINUE_EXECUTION;
- }
- bi=bi->next;
- }
-#ifdef JIT_DEBUG
- write_log (_T("JIT: Huh? Could not find trigger!\n"));
-#endif
- return EXCEPTION_CONTINUE_EXECUTION;
- }
- }
- write_log (_T("JIT: Can't handle access %08X!\n"), i);
-#if 0
- if (i)
- {
- int j;
-
- for (j=0;j<10;j++) {
- write_log (_T("JIT: instruction byte %2d is 0x%02x\n"),j,i[j]);
- }
- }
- write_log (_T("Please send the above info (starting at \"fault address\") to\n")
- _T("bmeyer@csse.monash.edu.au\n")
- _T("This shouldn't happen ;-)\n"));
-#endif
- return EXCEPTION_CONTINUE_SEARCH;
-}
-#else
-static void vec(int x, struct sigcontext sc)
-{
- uae_u8* i=(uae_u8*)sc.eip;
- uae_u32 addr=sc.cr2;
- int r=-1;
- int size=4;
- int dir=-1;
- int len=0;
- int j;
-
- write_log (_T("JIT: fault address is %08x at %08x\n"),sc.cr2,sc.eip);
- if (!canbang)
- write_log (_T("JIT: Not happy! Canbang is 0 in SIGSEGV handler!\n"));
- if (in_handler)
- write_log (_T("JIT: Argh --- Am already in a handler. Shouldn't happen!\n"));
-
- if (canbang && i>=compiled_code && i<=current_compile_p) {
- if (*i==0x66) {
- i++;
- size=2;
- len++;
- }
-
- switch(i[0]) {
- case 0x8a:
- if ((i[1]&0xc0)==0x80) {
- r=(i[1]>>3)&7;
- dir=SIG_READ;
- size=1;
- len+=6;
- break;
- }
- break;
- case 0x88:
- if ((i[1]&0xc0)==0x80) {
- r=(i[1]>>3)&7;
- dir=SIG_WRITE;
- size=1;
- len+=6;
- break;
- }
- break;
-
- case 0x8b:
- switch(i[1]&0xc0) {
- case 0x80:
- r=(i[1]>>3)&7;
- dir=SIG_READ;
- len+=6;
- break;
- case 0x40:
- r=(i[1]>>3)&7;
- dir=SIG_READ;
- len+=3;
- break;
- case 0x00:
- r=(i[1]>>3)&7;
- dir=SIG_READ;
- len+=2;
- break;
- default:
- break;
- }
- break;
-
- case 0x89:
- switch(i[1]&0xc0) {
- case 0x80:
- r=(i[1]>>3)&7;
- dir=SIG_WRITE;
- len+=6;
- break;
- case 0x40:
- r=(i[1]>>3)&7;
- dir=SIG_WRITE;
- len+=3;
- break;
- case 0x00:
- r=(i[1]>>3)&7;
- dir=SIG_WRITE;
- len+=2;
- break;
- }
- break;
- }
- }
-
- if (r!=-1) {
- void* pr=NULL;
- write_log (_T("JIT: register was %d, direction was %d, size was %d\n"),r,dir,size);
-
- switch(r) {
- case 0: pr=&(sc.eax); break;
- case 1: pr=&(sc.ecx); break;
- case 2: pr=&(sc.edx); break;
- case 3: pr=&(sc.ebx); break;
- case 4: pr=(size>1)?NULL:(((uae_u8*)&(sc.eax))+1); break;
- case 5: pr=(size>1)?
- (void*)(&(sc.ebp)):
- (void*)(((uae_u8*)&(sc.ecx))+1); break;
- case 6: pr=(size>1)?
- (void*)(&(sc.esi)):
- (void*)(((uae_u8*)&(sc.edx))+1); break;
- case 7: pr=(size>1)?
- (void*)(&(sc.edi)):
- (void*)(((uae_u8*)&(sc.ebx))+1); break;
- default: abort();
- }
- if (pr) {
- blockinfo* bi;
-
- if (currprefs.comp_oldsegv) {
- addr-=NATMEM_OFFSET;
-
- if ((addr>=0x10000000 && addr<0x40000000) ||
- (addr>=0x50000000)) {
- write_log (_T("JIT: Suspicious address in %x SEGV handler.\n"),addr);
- }
- if (dir==SIG_READ) {
- switch(size) {
- case 1: *((uae_u8*)pr)=get_byte (addr); break;
- case 2: *((uae_u16*)pr)=get_word (addr); break;
- case 4: *((uae_u32*)pr)=get_long (addr); break;
- default: abort();
- }
- }
- else { /* write */
- switch(size) {
- case 1: put_byte (addr,*((uae_u8*)pr)); break;
- case 2: put_word (addr,*((uae_u16*)pr)); break;
- case 4: put_long (addr,*((uae_u32*)pr)); break;
- default: abort();
- }
- }
- write_log (_T("JIT: Handled one access!\n"));
- fflush(stdout);
- segvcount++;
- sc.eip+=len;
- }
- else {
- void* tmp=target;
- int i;
- uae_u8 vecbuf[5];
-
- addr-=NATMEM_OFFSET;
-
- if ((addr>=0x10000000 && addr<0x40000000) ||
- (addr>=0x50000000)) {
- write_log (_T("JIT: Suspicious address 0x%x in SEGV handler.\n"),addr);
- }
-
- target=(uae_u8*)sc.eip;
- for (i=0;i<5;i++)
- vecbuf[i]=target[i];
- emit_byte(0xe9);
- emit_long((uae_u32)veccode-(uae_u32)target-4);
- write_log (_T("JIT: Create jump to %p\n"),veccode);
-
- write_log (_T("JIT: Handled one access!\n"));
- segvcount++;
-
- target=veccode;
-
- if (dir==SIG_READ) {
- switch(size) {
- case 1: raw_mov_b_ri(r,get_byte (addr)); break;
- case 2: raw_mov_w_ri(r,get_word (addr)); break;
- case 4: raw_mov_l_ri(r,get_long (addr)); break;
- default: abort();
- }
- }
- else { /* write */
- switch(size) {
- case 1: put_byte (addr,*((uae_u8*)pr)); break;
- case 2: put_word (addr,*((uae_u16*)pr)); break;
- case 4: put_long (addr,*((uae_u32*)pr)); break;
- default: abort();
- }
- }
- for (i=0;i<5;i++)
- raw_mov_b_mi(sc.eip+i,vecbuf[i]);
- raw_mov_l_mi((uae_u32)&in_handler,0);
- emit_byte(0xe9);
- emit_long(sc.eip+len-(uae_u32)target-4);
- in_handler=1;
- target=tmp;
- }
- bi=active;
- while (bi) {
- if (bi->handler &&
- (uae_u8*)bi->direct_handler<=i &&
- (uae_u8*)bi->nexthandler>i) {
- write_log (_T("JIT: deleted trigger (%p<%p<%p) %p\n"),
- bi->handler,
- i,
- bi->nexthandler,
- bi->pc_p);
- invalidate_block(bi);
- raise_in_cl_list(bi);
- set_special(0);
- return;
- }
- bi=bi->next;
- }
- /* Not found in the active list. Might be a rom routine that
- is in the dormant list */
- bi=dormant;
- while (bi) {
- if (bi->handler &&
- (uae_u8*)bi->direct_handler<=i &&
- (uae_u8*)bi->nexthandler>i) {
- write_log (_T("JIT: deleted trigger (%p<%p<%p) %p\n"),
- bi->handler,
- i,
- bi->nexthandler,
- bi->pc_p);
- invalidate_block(bi);
- raise_in_cl_list(bi);
- set_special(0);
- return;
- }
- bi=bi->next;
- }
- write_log (_T("JIT: Huh? Could not find trigger!\n"));
- return;
- }
- }
- write_log (_T("JIT: Can't handle access!\n"));
- for (j=0;j<10;j++) {
- write_log (_T("JIT: instruction byte %2d is %02x\n"),j,i[j]);
- }
-#if 0
- write_log (_T("Please send the above info (starting at \"fault address\") to\n")
- "bmeyer@csse.monash.edu.au\n"
- "This shouldn't happen ;-)\n");
- fflush(stdout);
-#endif
- signal(SIGSEGV,SIG_DFL); /* returning here will cause a "real" SEGV */
-}
-#endif
-#endif
/*************************************************************************
* Checking for CPU features *
{
const int CPUID_SPACE = 4096;
uae_u8* cpuid_space = (uae_u8*)cache_alloc(CPUID_SPACE);
+ if (cpuid_space == 0)
+ abort ();
static uae_u32 s_op, s_eax, s_ebx, s_ecx, s_edx;
uae_u8* tmp=get_target();
#include "options.h"
#include "events.h"
-#include "include/memory.h"
+#include "memory.h"
#include "custom.h"
#include "newcpu.h"
#include "comptbl.h"
// %%% BRIAN KING WAS HERE %%%
extern bool canbang;
-#include <sys/mman.h>
+//#include <sys/mman.h>
extern void jit_abort(const TCHAR*,...);
compop_func *compfunctbl[65536];
compop_func *nfcompfunctbl[65536];
void writebyte(int address, int source, int tmp)
{
int distrust = currprefs.comptrustbyte;
-#if 0
- switch (currprefs.comptrustbyte) {
- case 0: distrust=0; break;
- case 1: distrust=1; break;
- case 2: distrust=((start_pc&0xF80000)==0xF80000); break;
- case 3: distrust=!have_done_picasso; break;
- default: abort();
- }
-#endif
if ((special_mem&S_WRITE) || distrust)
writemem_special(address,source,20,1,tmp);
else
int clobber)
{
int distrust = currprefs.comptrustword;
-#if 0
- switch (currprefs.comptrustword) {
- case 0: distrust=0; break;
- case 1: distrust=1; break;
- case 2: distrust=((start_pc&0xF80000)==0xF80000); break;
- case 3: distrust=!have_done_picasso; break;
- default: abort();
- }
-#endif
if ((special_mem&S_WRITE) || distrust)
writemem_special(address,source,16,2,tmp);
else
int clobber)
{
int distrust = currprefs.comptrustlong;
-#if 0
- switch (currprefs.comptrustlong) {
- case 0: distrust=0; break;
- case 1: distrust=1; break;
- case 2: distrust=((start_pc&0xF80000)==0xF80000); break;
- case 3: distrust=!have_done_picasso; break;
- default: abort();
- }
-#endif
if ((special_mem&S_WRITE) || distrust)
writemem_special(address,source,12,4,tmp);
else
void readbyte(int address, int dest, int tmp)
{
int distrust = currprefs.comptrustbyte;
-#if 0
- switch (currprefs.comptrustbyte) {
- case 0: distrust=0; break;
- case 1: distrust=1; break;
- case 2: distrust=((start_pc&0xF80000)==0xF80000); break;
- case 3: distrust=!have_done_picasso; break;
- default: abort();
- }
-#endif
if ((special_mem&S_READ) || distrust)
readmem_special(address,dest,8,1,tmp);
else
void readword(int address, int dest, int tmp)
{
int distrust = currprefs.comptrustword;
-#if 0
- switch (currprefs.comptrustword) {
- case 0: distrust=0; break;
- case 1: distrust=1; break;
- case 2: distrust=((start_pc&0xF80000)==0xF80000); break;
- case 3: distrust=!have_done_picasso; break;
- default: abort();
- }
-#endif
if ((special_mem&S_READ) || distrust)
readmem_special(address,dest,4,2,tmp);
else
void readlong(int address, int dest, int tmp)
{
int distrust = currprefs.comptrustlong;
-#if 0
- switch (currprefs.comptrustlong) {
- case 0: distrust=0; break;
- case 1: distrust=1; break;
- case 2: distrust=((start_pc&0xF80000)==0xF80000); break;
- case 3: distrust=!have_done_picasso; break;
- default: abort();
- }
-#endif
if ((special_mem&S_READ) || distrust)
readmem_special(address,dest,0,4,tmp);
else
void get_n_addr(int address, int dest, int tmp)
{
int distrust = currprefs.comptrustnaddr;
-#if 0
- switch (currprefs.comptrustnaddr) {
- case 0: distrust=0; break;
- case 1: distrust=1; break;
- case 2: distrust=((start_pc&0xF80000)==0xF80000); break;
- case 3: distrust=!have_done_picasso; break;
- default: abort();
- }
-#endif
if (special_mem || distrust)
get_n_addr_old(address,dest,tmp);
else
#endif
raw_init_cpu();
#ifdef NATMEM_OFFSET
- write_log (_T("JIT: Setting signal handler\n"));
-#ifndef _WIN32
- signal(SIGSEGV,vec);
-#endif
+ install_exception_handler();
#endif
write_log (_T("JIT: Building Compiler function table\n"));
for (opcode = 0; opcode < 65536; opcode++) {
--- /dev/null
+/*************************************************************************
+* Handling mistaken direct memory access *
+*************************************************************************/
+
+#ifdef NATMEM_OFFSET
+#ifdef _WIN32 // %%% BRIAN KING WAS HERE %%%
+#include <winbase.h>
+#else
+#ifndef __USE_GNU
+#define __USE_GNU
+#endif
+#include <sys/ucontext.h>
+#endif
+#include <signal.h>
+
+#define SIG_READ 1
+#define SIG_WRITE 2
+
+static int in_handler=0;
+static uae_u8 *veccode;
+
+#ifdef _WIN32
+
+typedef LPEXCEPTION_POINTERS CONTEXT_T;
+#define HAVE_CONTEXT_T 1
+
+#define CONTEXT_EIP(context) (context->ContextRecord->Eip)
+#define CONTEXT_EAX(context) (context->ContextRecord->Eax)
+#define CONTEXT_ECX(context) (context->ContextRecord->Ecx)
+#define CONTEXT_EDX(context) (context->ContextRecord->Edx)
+#define CONTEXT_EBX(context) (context->ContextRecord->Ebx)
+#define CONTEXT_ESP(context) (context->ContextRecord->Esp)
+#define CONTEXT_EBP(context) (context->ContextRecord->Ebp)
+#define CONTEXT_ESI(context) (context->ContextRecord->Esi)
+#define CONTEXT_EDI(context) (context->ContextRecord->Edi)
+
+#define CONTEXT_RIP(context) (context->ContextRecord->Rip)
+#define CONTEXT_RAX(context) (context->ContextRecord->Rax)
+#define CONTEXT_RCX(context) (context->ContextRecord->Rcx)
+#define CONTEXT_RDX(context) (context->ContextRecord->Rdx)
+#define CONTEXT_RBX(context) (context->ContextRecord->Rbx)
+#define CONTEXT_RSP(context) (context->ContextRecord->Rsp)
+#define CONTEXT_RBP(context) (context->ContextRecord->Rbp)
+#define CONTEXT_RSI(context) (context->ContextRecord->Rsi)
+#define CONTEXT_RDI(context) (context->ContextRecord->Rdi)
+
+#define CONTEXT_CR2(context) ((uae_u32)(context->ExceptionRecord->ExceptionInformation[1]))
+
+#elif HAVE_STRUCT_UCONTEXT_UC_MCONTEXT_GREGS
+
+typedef void *CONTEXT_T;
+#define HAVE_CONTEXT_T 1
+
+#define CONTEXT_EIP(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_EIP])
+#define CONTEXT_EAX(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_EAX])
+#define CONTEXT_ECX(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_ECX])
+#define CONTEXT_EDX(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_EDX])
+#define CONTEXT_EBX(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_EBX])
+#define CONTEXT_ESP(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_ESP])
+#define CONTEXT_EBP(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_EBP])
+#define CONTEXT_ESI(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_ESI])
+#define CONTEXT_EDI(context) (((struct ucontext *) context)->uc_mcontext.gregs[REG_EDI])
+
+#define CONTEXT_CR2(context) (((struct ucontext *) context)->uc_mcontext.cr2)
+
+#endif
+
+#if defined(CPU_64_BIT)
+#ifdef CONTEXT_RIP
+#define CONTEXT_PC(context) CONTEXT_RIP(context)
+#endif
+#else
+#ifdef CONTEXT_EIP
+#define CONTEXT_PC(context) CONTEXT_EIP(context)
+#endif
+#endif
+
+#ifdef HAVE_CONTEXT_T
+/*
+ * Try to handle faulted memory access in compiled code
+ *
+ * Returns 1 if handled, 0 otherwise
+ */
+static int handle_access(CONTEXT_T context)
+{
+ uae_u8 *i = (uae_u8 *) CONTEXT_EIP(context);
+ uae_u32 addr = CONTEXT_CR2(context);
+
+ int r=-1;
+ int size=4;
+ int dir=-1;
+ int len=0;
+
+#ifdef JIT_DEBUG
+ write_log (_T("JIT: fault address is 0x%x at 0x%x\n"),addr,i);
+#endif
+ if (!canbang || !currprefs.cachesize)
+ return 0;
+
+ if (in_handler)
+ write_log (_T("JIT: Argh --- Am already in a handler. Shouldn't happen!\n"));
+
+ if (canbang && i>=compiled_code && i<=current_compile_p) {
+ if (*i==0x66) {
+ i++;
+ size=2;
+ len++;
+ }
+
+ switch(i[0]) {
+ case 0x8a:
+ if ((i[1]&0xc0)==0x80) {
+ r=(i[1]>>3)&7;
+ dir=SIG_READ;
+ size=1;
+ len+=6;
+ break;
+ }
+ break;
+ case 0x88:
+ if ((i[1]&0xc0)==0x80) {
+ r=(i[1]>>3)&7;
+ dir=SIG_WRITE;
+ size=1;
+ len+=6;
+ break;
+ }
+ break;
+ case 0x8b:
+ switch(i[1]&0xc0) {
+ case 0x80:
+ r=(i[1]>>3)&7;
+ dir=SIG_READ;
+ len+=6;
+ break;
+ case 0x40:
+ r=(i[1]>>3)&7;
+ dir=SIG_READ;
+ len+=3;
+ break;
+ case 0x00:
+ r=(i[1]>>3)&7;
+ dir=SIG_READ;
+ len+=2;
+ break;
+ default:
+ break;
+ }
+ break;
+ case 0x89:
+ switch(i[1]&0xc0) {
+ case 0x80:
+ r=(i[1]>>3)&7;
+ dir=SIG_WRITE;
+ len+=6;
+ break;
+ case 0x40:
+ r=(i[1]>>3)&7;
+ dir=SIG_WRITE;
+ len+=3;
+ break;
+ case 0x00:
+ r=(i[1]>>3)&7;
+ dir=SIG_WRITE;
+ len+=2;
+ break;
+ }
+ break;
+ }
+ }
+
+ if (r!=-1) {
+ void* pr=NULL;
+#ifdef JIT_DEBUG
+ write_log (_T("JIT: register was %d, direction was %d, size was %d\n"),r,dir,size);
+#endif
+
+ switch(r) {
+#if defined(CPU_64_BIT)
+ case 0: pr = &(CONTEXT_RAX(context)); break;
+ case 1: pr = &(CONTEXT_RCX(context)); break;
+ case 2: pr = &(CONTEXT_RDX(context)); break;
+ case 3: pr = &(CONTEXT_RBX(context)); break;
+ case 4: pr = (size > 1) ? NULL
+ : (((uae_u8*)&(CONTEXT_RAX(context)))+1);
+ break;
+ case 5: pr = (size > 1) ? (void*) (&(CONTEXT_RBP(context)))
+ : (void*)(((uae_u8*)&(CONTEXT_RCX(context))) + 1);
+ break;
+ case 6: pr = (size > 1) ? (void*) (&(CONTEXT_RSI(context)))
+ : (void*)(((uae_u8*)&(CONTEXT_RDX(context))) + 1);
+ break;
+ case 7: pr = (size > 1) ? (void*) (&(CONTEXT_RDI(context)))
+ : (void*)(((uae_u8*)&(CONTEXT_RBX(context))) + 1);
+ break;
+#else
+ case 0: pr = &(CONTEXT_EAX(context)); break;
+ case 1: pr = &(CONTEXT_ECX(context)); break;
+ case 2: pr = &(CONTEXT_EDX(context)); break;
+ case 3: pr = &(CONTEXT_EBX(context)); break;
+ case 4: pr = (size > 1) ? NULL
+ : (((uae_u8*)&(CONTEXT_EAX(context)))+1);
+ break;
+ case 5: pr = (size > 1) ? (void*) (&(CONTEXT_EBP(context)))
+ : (void*)(((uae_u8*)&(CONTEXT_ECX(context))) + 1);
+ break;
+ case 6: pr = (size > 1) ? (void*) (&(CONTEXT_ESI(context)))
+ : (void*)(((uae_u8*)&(CONTEXT_EDX(context))) + 1);
+ break;
+ case 7: pr = (size > 1) ? (void*) (&(CONTEXT_EDI(context)))
+ : (void*)(((uae_u8*)&(CONTEXT_EBX(context))) + 1);
+ break;
+#endif
+ default:
+ abort ();
+ }
+ if (pr) {
+ blockinfo* bi;
+
+ if (currprefs.comp_oldsegv) {
+ addr-=(uae_u32)NATMEM_OFFSET;
+
+#ifdef JIT_DEBUG
+ if ((addr>=0x10000000 && addr<0x40000000) ||
+ (addr>=0x50000000)) {
+ write_log (_T("JIT: Suspicious address 0x%x in SEGV handler.\n"),addr);
+ }
+#endif
+ if (dir==SIG_READ) {
+ switch (size) {
+ case 1: *((uae_u8*)pr)=get_byte (addr); break;
+ case 2: *((uae_u16*)pr)=swap16(get_word (addr)); break;
+ case 4: *((uae_u32*)pr)=swap32(get_long (addr)); break;
+ default: abort();
+ }
+ }
+ else { /* write */
+ switch (size) {
+ case 1: put_byte (addr,*((uae_u8*)pr)); break;
+ case 2: put_word (addr,swap16(*((uae_u16*)pr))); break;
+ case 4: put_long (addr,swap32(*((uae_u32*)pr))); break;
+ default: abort();
+ }
+ }
+#ifdef JIT_DEBUG
+ write_log (_T("JIT: Handled one access!\n"));
+#endif
+ fflush(stdout);
+ segvcount++;
+ CONTEXT_PC(context) += len;
+ }
+ else {
+ void* tmp=target;
+ int i;
+ uae_u8 vecbuf[5];
+
+ addr-=(uae_u32)NATMEM_OFFSET;
+
+#ifdef JIT_DEBUG
+ if ((addr>=0x10000000 && addr<0x40000000) ||
+ (addr>=0x50000000)) {
+ write_log (_T("JIT: Suspicious address 0x%x in SEGV handler.\n"),addr);
+ }
+#endif
+
+ target = (uae_u8*) CONTEXT_PC(context);
+ for (i=0;i<5;i++)
+ vecbuf[i]=target[i];
+ emit_byte(0xe9);
+ emit_long((uae_u32)veccode-(uae_u32)target-4);
+#ifdef JIT_DEBUG
+
+ write_log (_T("JIT: Create jump to %p\n"),veccode);
+ write_log (_T("JIT: Handled one access!\n"));
+#endif
+ segvcount++;
+
+ target=veccode;
+
+ if (dir==SIG_READ) {
+ switch(size) {
+ case 1: raw_mov_b_ri(r,get_byte (addr)); break;
+ case 2: raw_mov_w_ri(r,swap16(get_word (addr))); break;
+ case 4: raw_mov_l_ri(r,swap32(get_long (addr))); break;
+ default: abort();
+ }
+ }
+ else { /* write */
+ switch(size) {
+ case 1: put_byte (addr,*((uae_u8*)pr)); break;
+ case 2: put_word (addr,swap16(*((uae_u16*)pr))); break;
+ case 4: put_long (addr,swap32(*((uae_u32*)pr))); break;
+ default: abort();
+ }
+ }
+ for (i=0;i<5;i++)
+ raw_mov_b_mi(CONTEXT_PC(context) + i, vecbuf[i]);
+ raw_mov_l_mi((uae_u32)&in_handler,0);
+ emit_byte(0xe9);
+ emit_long(CONTEXT_PC(context) + len - (uae_u32)target - 4);
+ in_handler=1;
+ target=(uae_u8*)tmp;
+ }
+ bi=active;
+ while (bi) {
+ if (bi->handler &&
+ (uae_u8*)bi->direct_handler<=i &&
+ (uae_u8*)bi->nexthandler>i) {
+#ifdef JIT_DEBUG
+ write_log (_T("JIT: deleted trigger (%p<%p<%p) %p\n"),
+ bi->handler,
+ i,
+ bi->nexthandler,
+ bi->pc_p);
+#endif
+ invalidate_block(bi);
+ raise_in_cl_list(bi);
+ set_special(0);
+ return 1;
+ }
+ bi=bi->next;
+ }
+ /* Not found in the active list. Might be a rom routine that
+ is in the dormant list */
+ bi=dormant;
+ while (bi) {
+ if (bi->handler &&
+ (uae_u8*)bi->direct_handler<=i &&
+ (uae_u8*)bi->nexthandler>i) {
+#ifdef JIT_DEBUG
+ write_log (_T("JIT: deleted trigger (%p<%p<%p) %p\n"),
+ bi->handler,
+ i,
+ bi->nexthandler,
+ bi->pc_p);
+#endif
+ invalidate_block(bi);
+ raise_in_cl_list(bi);
+ set_special(0);
+ return 1;
+ }
+ bi=bi->next;
+ }
+#ifdef JIT_DEBUG
+ write_log (_T("JIT: Huh? Could not find trigger!\n"));
+#endif
+ return 1;
+ }
+ }
+ write_log (_T("JIT: Can't handle access %08X!\n"), i);
+#if 0
+ if (i)
+ {
+ int j;
+
+ for (j=0;j<10;j++) {
+ write_log (_T("JIT: instruction byte %2d is 0x%02x\n"),j,i[j]);
+ }
+ }
+ write_log (_T("Please send the above info (starting at \"fault address\") to\n"));
+ write_log (_T("bmeyer@csse.monash.edu.au\n"));
+ write_log (_T("This shouldn't happen ;-)\n"));
+#endif
+ return 0;
+}
+#endif /* CONTEXT_T */
+
+#ifdef _WIN32
+
+LONG WINAPI EvalException(LPEXCEPTION_POINTERS info)
+{
+ DWORD code = info->ExceptionRecord->ExceptionCode;
+ if (code != STATUS_ACCESS_VIOLATION || !canbang || currprefs.cachesize == 0)
+ return EXCEPTION_CONTINUE_SEARCH;
+
+ if (handle_access(info)) {
+ return EXCEPTION_CONTINUE_EXECUTION;
+ }
+ return EXCEPTION_CONTINUE_SEARCH;
+}
+
+#elif defined(HAVE_CONTEXT_T)
+
+static void sigsegv_handler(int signum, struct siginfo *info, void *context)
+{
+ uae_u8 *i = (uae_u8 *) CONTEXT_EIP(context);
+ uae_u32 addr = CONTEXT_CR2(context);
+
+ if (i >= compiled_code) {
+ if (handle_access (context))
+ return;
+ else {
+ int j;
+ write_log ("JIT: can't handle access!\n");
+ for (j = 0 ; j < 10; j++)
+ write_log ("JIT: instruction byte %2d is %02x\n", i, j[i]);
+ }
+ } else {
+ write_log ("Caught illegal access to %08x at eip=%08x\n", addr, i);
+ }
+
+ exit (EXIT_FAILURE);
+}
+
+#endif
+
+static void install_exception_handler(void)
+{
+#ifdef USE_STRUCTURED_EXCEPTION_HANDLING
+ /* Structured exception handler is installed in main.cpp */
+#elif defined(_WIN32)
+ write_log (_T("JIT: Installing unhandled exception filter\n"));
+ SetUnhandledExceptionFilter(EvalException);
+#elif defined(HAVE_CONTEXT_T)
+ write_log (_T("JIT: Installing segfault handler\n"));
+ struct sigaction act;
+ act.sa_sigaction = (void (*)(int, siginfo_t*, void*)) sigsegv_handler;
+ sigemptyset (&act.sa_mask);
+ act.sa_flags = SA_SIGINFO;
+ sigaction(SIGSEGV, &act, NULL);
+#else
+ write_log (_T("JIT: No segfault handler installed\n"));
+#endif
+}
+
+#endif /* NATMEM_OFFSET */
#include "cpuboard.h"
#include "uae/ppc.h"
#include "devices.h"
+#include "jit/compemu.h"
#ifdef RETROPLATFORM
#include "rp.h"
#endif
#endif
}
#endif
- if (p->maprom && !p->address_space_24)
+ if (p->maprom && !p->address_space_24) {
p->maprom = 0x0f000000;
+ }
if (((p->maprom & 0xff000000) && p->address_space_24) || (p->maprom && p->mbresmem_high_size >= 0x08000000)) {
p->maprom = 0x00e00000;
}
#ifdef WITH_LUA
uae_lua_loadall ();
#endif
-#if (defined (_WIN32) || defined (_WIN64)) && !defined (NO_WIN32_EXCEPTION_HANDLER)
- extern int EvalException (LPEXCEPTION_POINTERS blah, int n_except);
+#ifdef USE_STRUCTURED_EXCEPTION_HANDLING
__try
#endif
{
m68k_go (1);
}
-#if (defined (_WIN32) || defined (_WIN64)) && !defined (NO_WIN32_EXCEPTION_HANDLER)
+#ifdef USE_STRUCTURED_EXCEPTION_HANDLING
#ifdef JIT
- __except (EvalException (GetExceptionInformation (), GetExceptionCode ()))
+ __except (EvalException(GetExceptionInformation()))
#else
__except (DummyException (GetExceptionInformation (), GetExceptionCode ()))
#endif