Initial commit of dynamic recompiler.

Various CPU changes to support dynamic recompiler.
This commit is contained in:
TomW 2014-11-05 21:24:16 +00:00
commit 4676daade4
52 changed files with 3740 additions and 1139 deletions

205
src/386.c
View file

@ -1,3 +1,4 @@
#ifndef DYNAREC
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
@ -9,6 +10,9 @@
#include "fdc.h"
#include "timer.h"
#include "386_common.h"
#define CPU_BLOCK_END()
x86seg *ea_seg;
@ -19,48 +23,6 @@ uint32_t oldpc2;
int trap;
#define check_io_perm(port) if (!IOPLp || (eflags&VM_FLAG)) \
{ \
int tempi = checkio(port); \
if (abrt) return 0; \
if (tempi) \
{ \
x86gpf(NULL,0); \
return 0; \
} \
}
#define checkio_perm(port) if (!IOPLp || (eflags&VM_FLAG)) \
{ \
tempi = checkio(port); \
if (abrt) break; \
if (tempi) \
{ \
x86gpf(NULL,0); \
break; \
} \
}
#define CHECK_READ(seg, low, high) \
if ((low < (seg)->limit_low) || (high > (seg)->limit_high)) \
{ \
x86gpf("Limit check", 0); \
return 0; \
}
#define CHECK_WRITE(seg, low, high) \
if ((low < (seg)->limit_low) || (high > (seg)->limit_high)) \
{ \
x86gpf("Limit check", 0); \
return 0; \
}
#define CHECK_WRITE_REP(seg, low, high) \
if ((low < (seg)->limit_low) || (high > (seg)->limit_high)) \
{ \
x86gpf("Limit check", 0); \
break; \
}
int cpl_override=0;
@ -74,16 +36,6 @@ uint16_t ea_rseg;
int is486;
int cgate32;
#undef readmemb
#undef writememb
#define readmemb(s,a) ((readlookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF)?readmemb386l(s,a): *(uint8_t *)(readlookup2[((s)+(a))>>12] + (s) + (a)) )
#define writememb(s,a,v) if (writelookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF) writememb386l(s,a,v); else *(uint8_t *)(writelookup2[((s) + (a)) >> 12] + (s) + (a)) = v
#define writememw(s,a,v) if (writelookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFFE) writememwl(s,a,v); else *(uint16_t *)(writelookup2[((s) + (a)) >> 12] + (s) + (a)) = v
#define writememl(s,a,v) if (writelookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFFC) writememll(s,a,v); else *(uint32_t *)(writelookup2[((s) + (a)) >> 12] + (s) + (a)) = v
uint8_t romext[32768];
@ -102,126 +54,8 @@ uint32_t oldcs2;
uint32_t oldecx;
uint32_t op32;
static inline uint8_t fastreadb(uint32_t a)
{
if ((a >> 12) == pccache)
return *((uint8_t *)&pccache2[a]);
pccache2 = getpccache(a);
if (abrt)
return;
pccache = a >> 12;
return *((uint8_t *)&pccache2[a]);
}
static inline uint16_t fastreadw(uint32_t a)
{
uint32_t t;
if ((a&0xFFF)>0xFFE)
{
t=readmemb(0,a);
t|=(readmemb(0,a+1)<<8);
return t;
}
if ((a>>12)==pccache) return *((uint16_t *)&pccache2[a]);
pccache2=getpccache(a);
if (abrt)
return;
pccache=a>>12;
return *((uint16_t *)&pccache2[a]);
}
static inline uint32_t fastreadl(uint32_t a)
{
uint8_t *t;
uint32_t val;
if ((a&0xFFF)<0xFFD)
{
if ((a>>12)!=pccache)
{
t = getpccache(a);
if (abrt) return 0;
pccache2 = t;
pccache=a>>12;
//return *((uint32_t *)&pccache2[a]);
}
return *((uint32_t *)&pccache2[a]);
}
val =readmemb(0,a);
val |=(readmemb(0,a+1)<<8);
val |=(readmemb(0,a+2)<<16);
val |=(readmemb(0,a+3)<<24);
return val;
}
static inline uint8_t getbyte()
{
pc++;
return fastreadb(cs + (pc - 1));
}
static inline uint16_t getword()
{
pc+=2;
return fastreadw(cs+(pc-2));
}
static inline uint32_t getlong()
{
pc+=4;
return fastreadl(cs+(pc-4));
}
uint32_t *eal_r, *eal_w;
static inline uint8_t geteab()
{
if (mod==3)
return (rm&4)?regs[rm&3].b.h:regs[rm&3].b.l;
if (eal_r) return *(uint8_t *)eal_r;
return readmemb(easeg,eaaddr);
}
static inline uint16_t geteaw()
{
if (mod==3)
return regs[rm].w;
// cycles-=3;
if (eal_r) return *(uint16_t *)eal_r;
return readmemw(easeg,eaaddr);
}
static inline uint32_t geteal()
{
if (mod==3)
return regs[rm].l;
// cycles-=3;
if (eal_r) return *eal_r;
return readmeml(easeg,eaaddr);
}
static inline uint8_t geteab_mem()
{
if (eal_r) return *(uint8_t *)eal_r;
return readmemb(easeg,eaaddr);
}
static inline uint16_t geteaw_mem()
{
if (eal_r) return *(uint16_t *)eal_r;
return readmemw(easeg,eaaddr);
}
static inline uint32_t geteal_mem()
{
if (eal_r) return *eal_r;
return readmeml(easeg,eaaddr);
}
#define seteab(v) if (mod!=3) { if (eal_w) *(uint8_t *)eal_w=v; else writememb386l(easeg,eaaddr,v); } else if (rm&4) regs[rm&3].b.h=v; else regs[rm].b.l=v
#define seteaw(v) if (mod!=3) { if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg,eaaddr,v); } else regs[rm].w=v
#define seteal(v) if (mod!=3) { if (eal_w) *eal_w=v; else writememll(easeg,eaaddr,v); } else regs[rm].l=v
#define seteab_mem(v) if (eal_w) *(uint8_t *)eal_w=v; else writememb386l(easeg,eaaddr,v);
#define seteaw_mem(v) if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg,eaaddr,v);
#define seteal_mem(v) if (eal_w) *eal_w=v; else writememll(easeg,eaaddr,v);
uint16_t *mod1add[2][8];
uint32_t *mod1seg[8];
@ -379,6 +213,7 @@ void x86_int(int num)
loadcs(readmemw(0,addr+2));
}
cycles-=70;
CPU_BLOCK_END();
}
void x86_int_sw(int num)
@ -416,6 +251,7 @@ void x86_int_sw(int num)
}
cycles-=70;
trap = 0;
CPU_BLOCK_END();
}
void x86illegal()
@ -431,13 +267,7 @@ void x86illegal()
}
#define NOTRM if (!(msw & 1) || (eflags & VM_FLAG))\
{ \
x86_int(6); \
break; \
}
void rep386(int fv)
int rep386(int fv)
{
uint8_t temp;
uint32_t c;//=CX;
@ -1150,6 +980,7 @@ void rep386(int fv)
if (rep32&0x200) ECX=c;
else CX=c;
// if (output) pclog("%03X %03X\n",rep32,use32);
return 1;
}
int checkio(int port)
@ -1183,12 +1014,12 @@ int xout=0;
x86_int(0); \
}
void divl(uint32_t val)
int divl(uint32_t val)
{
if (val==0)
{
divexcp();
return;
return 1;
}
uint64_t num=(((uint64_t)EDX)<<32)|EAX;
uint64_t quo=num/val;
@ -1197,17 +1028,18 @@ void divl(uint32_t val)
if (quo!=(uint64_t)quo32)
{
divexcp();
return;
return 1;
}
EDX=rem;
EAX=quo32;
return 0;
}
void idivl(int32_t val)
int idivl(int32_t val)
{
if (val==0)
{
divexcp();
return;
return 1;
}
int64_t num=(((uint64_t)EDX)<<32)|EAX;
int64_t quo=num/val;
@ -1216,10 +1048,11 @@ void idivl(int32_t val)
if (quo!=(int64_t)quo32)
{
divexcp();
return;
return 1;
}
EDX=rem;
EAX=quo32;
return 0;
}
@ -1244,6 +1077,8 @@ int dontprint=0;
return 0; \
}
#define OP_TABLE(name) ops_ ## name
#include "386_ops.h"
#undef NOTRM
@ -1302,8 +1137,7 @@ opcodestart:
pclog("%04X(%06X):%04X : %08X %08X %08X %08X %04X %04X %04X(%08X) %04X %04X %04X(%08X) %08X %08X %08X SP=%04X:%08X %02X %04X %i %08X %08X %i %i %02X %02X %02X %02X %02X %f %02X%02X %02X%02X %02X%02X %02X\n",CS,cs,pc,EAX,EBX,ECX,EDX,CS,DS,ES,es,FS,GS,SS,ss,EDI,ESI,EBP,SS,ESP,opcode,flags,ins,0, ldt.base, CPL, stack32, pic.pend, pic.mask, pic.mask2, pic2.pend, pic2.mask, pit.c[0], ram[0xB270+0x3F5], ram[0xB270+0x3F4], ram[0xB270+0x3F7], ram[0xB270+0x3F6], ram[0xB270+0x3F9], ram[0xB270+0x3F8], ram[0x4430+0x0D49]);
}
pc++;
if (x86_opcodes[(opcode | op32) & 0x3ff](fetchdat))
goto opcodestart;
x86_opcodes[(opcode | op32) & 0x3ff](fetchdat);
}
if (!use32) pc &= 0xffff;
@ -1420,3 +1254,4 @@ opcodestart:
timer_end_period(cycles);
}
}
#endif