Implemented data misalignment penalties on 486 and later CPUs.

This commit is contained in:
SarahW 2017-06-04 16:41:33 +01:00
commit 3b4392bcf8
7 changed files with 361 additions and 327 deletions

View file

@ -5,13 +5,13 @@ extern uint16_t ea_rseg;
#define readmemb(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF)?readmemb386l(s,a): *(uint8_t *)(readlookup2[(uint32_t)((s)+(a))>>12] + (uint32_t)((s) + (a))) ) #define readmemb(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF)?readmemb386l(s,a): *(uint8_t *)(readlookup2[(uint32_t)((s)+(a))>>12] + (uint32_t)((s) + (a))) )
#define readmemq(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFF8)?readmemql(s,a):*(uint64_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) #define readmemq(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a)) & 7))?readmemql(s,a):*(uint64_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a))))
#define writememb(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF) writememb386l(s,a,v); else *(uint8_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v #define writememb(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF) writememb386l(s,a,v); else *(uint8_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v
#define writememw(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFFE) writememwl(s,a,v); else *(uint16_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v #define writememw(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) writememwl(s,a,v); else *(uint16_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v
#define writememl(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFFC) writememll(s,a,v); else *(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v #define writememl(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) writememll(s,a,v); else *(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v
#define writememq(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFF8) writememql(s,a,v); else *(uint64_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v #define writememq(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a)) & 7)) writememql(s,a,v); else *(uint64_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v
int checkio(int port); int checkio(int port);
@ -88,8 +88,8 @@ static inline uint16_t fastreadw(uint32_t a)
uint16_t val; uint16_t val;
if ((a&0xFFF)>0xFFE) if ((a&0xFFF)>0xFFE)
{ {
val = readmemb(0, a); val = fastreadb(a);
val |= (readmemb(0, a + 1) << 8); val |= (fastreadb(a + 1) << 8);
return val; return val;
} }
if ((a>>12)==pccache) return *((uint16_t *)&pccache2[a]); if ((a>>12)==pccache) return *((uint16_t *)&pccache2[a]);
@ -119,10 +119,8 @@ static inline uint32_t fastreadl(uint32_t a)
} }
return *((uint32_t *)&pccache2[a]); return *((uint32_t *)&pccache2[a]);
} }
val =readmemb(0,a); val = fastreadw(a);
val |=(readmemb(0,a+1)<<8); val |= (fastreadw(a + 2) << 16);
val |=(readmemb(0,a+2)<<16);
val |=(readmemb(0,a+3)<<24);
return val; return val;
} }

View file

@ -1069,16 +1069,14 @@ static inline void MEM_LOAD_ADDR_EA_W(x86seg *seg)
addbyte(0x8d); addbyte(0x8d);
addbyte(0x34); addbyte(0x34);
addbyte(0x08); addbyte(0x08);
addbyte(0x67); /*LEA EDI, 1[ESI]*/ addbyte(0x89); /*MOV EDI, ESI*/
addbyte(0x8d); addbyte(0xf7);
addbyte(0x7e);
addbyte(0x01);
addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xc1); /*SHR ESI, 12*/
addbyte(0xe8 | REG_ESI); addbyte(0xe8 | REG_ESI);
addbyte(12); addbyte(12);
addbyte(0xf7); /*TEST EDI, 0xfff*/ addbyte(0xf7); /*TEST EDI, 1*/
addbyte(0xc7); addbyte(0xc7);
addlong(0xfff); addlong(1);
if (IS_32_ADDR(readlookup2)) if (IS_32_ADDR(readlookup2))
{ {
addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/
@ -1098,18 +1096,17 @@ static inline void MEM_LOAD_ADDR_EA_W(x86seg *seg)
addbyte(0x34); addbyte(0x34);
addbyte(0xf2); addbyte(0xf2);
} }
addbyte(0x74); /*JE slowpath*/ addbyte(0x75); /*JNE slowpath*/
addbyte(3+2+5+2); addbyte(3+2+4+2);
addbyte(0x83); /*CMP ESI, -1*/ addbyte(0x83); /*CMP ESI, -1*/
addbyte(0xf8 | REG_ESI); addbyte(0xf8 | REG_ESI);
addbyte(-1); addbyte(-1);
addbyte(0x74); /*JE slowpath*/ addbyte(0x74); /*JE slowpath*/
addbyte(5+2); addbyte(4+2);
addbyte(0x66); /*MOV AX,-1[RDI+RSI]*/ addbyte(0x66); /*MOV AX,[RDI+RSI]*/
addbyte(0x8b); addbyte(0x8b);
addbyte(0x44); addbyte(0x04);
addbyte(REG_EDI | (REG_ESI << 3)); addbyte(REG_EDI | (REG_ESI << 3));
addbyte(-1);
addbyte(0xeb); /*JMP done*/ addbyte(0xeb); /*JMP done*/
addbyte(2+2+12+4+6); addbyte(2+2+12+4+6);
/*slowpath:*/ /*slowpath:*/
@ -1158,16 +1155,14 @@ static inline void MEM_LOAD_ADDR_EA_L(x86seg *seg)
addbyte(0x8d); addbyte(0x8d);
addbyte(0x34); addbyte(0x34);
addbyte(0x08); addbyte(0x08);
addbyte(0x67); /*LEA EDI, 3[ESI]*/ addbyte(0x89); /*MOV EDI, ESI*/
addbyte(0x8d); addbyte(0xf7);
addbyte(0x7e);
addbyte(0x03);
addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xc1); /*SHR ESI, 12*/
addbyte(0xe8 | REG_ESI); addbyte(0xe8 | REG_ESI);
addbyte(12); addbyte(12);
addbyte(0xf7); /*TEST EDI, 0xffc*/ addbyte(0xf7); /*TEST EDI, 3*/
addbyte(0xc7); addbyte(0xc7);
addlong(0xffc); addlong(3);
if (IS_32_ADDR(readlookup2)) if (IS_32_ADDR(readlookup2))
{ {
addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/
@ -1187,17 +1182,16 @@ static inline void MEM_LOAD_ADDR_EA_L(x86seg *seg)
addbyte(0x34); addbyte(0x34);
addbyte(0xf2); addbyte(0xf2);
} }
addbyte(0x74); /*JE slowpath*/ addbyte(0x75); /*JNE slowpath*/
addbyte(3+2+4+2); addbyte(3+2+3+2);
addbyte(0x83); /*CMP ESI, -1*/ addbyte(0x83); /*CMP ESI, -1*/
addbyte(0xf8 | REG_ESI); addbyte(0xf8 | REG_ESI);
addbyte(-1); addbyte(-1);
addbyte(0x74); /*JE slowpath*/ addbyte(0x74); /*JE slowpath*/
addbyte(4+2); addbyte(3+2);
addbyte(0x8b); /*MOV EAX,-3[RDI+RSI]*/ addbyte(0x8b); /*MOV EAX,[RDI+RSI]*/
addbyte(0x44); addbyte(0x04);
addbyte(REG_EDI | (REG_ESI << 3)); addbyte(REG_EDI | (REG_ESI << 3));
addbyte(-3);
addbyte(0xeb); /*JMP done*/ addbyte(0xeb); /*JMP done*/
addbyte(2+2+12+4+6); addbyte(2+2+12+4+6);
/*slowpath:*/ /*slowpath:*/
@ -1239,16 +1233,14 @@ static inline void MEM_LOAD_ADDR_EA_Q(x86seg *seg)
addbyte(0x8d); addbyte(0x8d);
addbyte(0x34); addbyte(0x34);
addbyte(0x08); addbyte(0x08);
addbyte(0x67); /*LEA EDI, 7[ESI]*/ addbyte(0x89); /*MOV EDI, ESI*/
addbyte(0x8d); addbyte(0xf7);
addbyte(0x7e);
addbyte(0x07);
addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xc1); /*SHR ESI, 12*/
addbyte(0xe8 | REG_ESI); addbyte(0xe8 | REG_ESI);
addbyte(12); addbyte(12);
addbyte(0xf7); /*TEST EDI, 0xff8*/ addbyte(0xf7); /*TEST EDI, 7*/
addbyte(0xc7); addbyte(0xc7);
addlong(0xff8); addlong(7);
if (IS_32_ADDR(readlookup2)) if (IS_32_ADDR(readlookup2))
{ {
addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/
@ -1268,18 +1260,17 @@ static inline void MEM_LOAD_ADDR_EA_Q(x86seg *seg)
addbyte(0x34); addbyte(0x34);
addbyte(0xf2); addbyte(0xf2);
} }
addbyte(0x74); /*JE slowpath*/ addbyte(0x75); /*JNE slowpath*/
addbyte(3+2+5+2); addbyte(3+2+4+2);
addbyte(0x83); /*CMP ESI, -1*/ addbyte(0x83); /*CMP ESI, -1*/
addbyte(0xf8 | REG_ESI); addbyte(0xf8 | REG_ESI);
addbyte(-1); addbyte(-1);
addbyte(0x74); /*JE slowpath*/ addbyte(0x74); /*JE slowpath*/
addbyte(5+2); addbyte(4+2);
addbyte(0x48); /*MOV RAX,-7[RDI+RSI]*/ addbyte(0x48); /*MOV RAX,[RDI+RSI]*/
addbyte(0x8b); addbyte(0x8b);
addbyte(0x44); addbyte(0x04);
addbyte(REG_EDI | (REG_ESI << 3)); addbyte(REG_EDI | (REG_ESI << 3));
addbyte(-7);
addbyte(0xeb); /*JMP done*/ addbyte(0xeb); /*JMP done*/
addbyte(2+2+12+4+6); addbyte(2+2+12+4+6);
/*slowpath:*/ /*slowpath:*/
@ -1447,16 +1438,14 @@ static inline void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg)
addbyte(0x8d); addbyte(0x8d);
addbyte(0x34); addbyte(0x34);
addbyte(0x08); addbyte(0x08);
addbyte(0x67); /*LEA EDI, 1[ESI]*/ addbyte(0x89); /*MOV EDI, ESI*/
addbyte(0x8d); addbyte(0xf7);
addbyte(0x7e);
addbyte(0x01);
addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xc1); /*SHR ESI, 12*/
addbyte(0xe8 | REG_ESI); addbyte(0xe8 | REG_ESI);
addbyte(12); addbyte(12);
addbyte(0xf7); /*TEST EDI, 0xfff*/ addbyte(0xf7); /*TEST EDI, 1*/
addbyte(0xc7); addbyte(0xc7);
addlong(0xfff); addlong(1);
if (IS_32_ADDR(writelookup2)) if (IS_32_ADDR(writelookup2))
{ {
addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/
@ -1476,29 +1465,27 @@ static inline void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg)
addbyte(0x34); addbyte(0x34);
addbyte(0xf2); addbyte(0xf2);
} }
addbyte(0x74); /*JE slowpath*/ addbyte(0x75); /*JNE slowpath*/
addbyte(3+2+((host_reg & 8) ? 6:5)+2); addbyte(3+2+((host_reg & 8) ? 5:4)+2);
addbyte(0x83); /*CMP ESI, -1*/ addbyte(0x83); /*CMP ESI, -1*/
addbyte(0xf8 | REG_ESI); addbyte(0xf8 | REG_ESI);
addbyte(-1); addbyte(-1);
addbyte(0x74); /*JE slowpath*/ addbyte(0x74); /*JE slowpath*/
addbyte(((host_reg & 8) ? 6:5)+2); addbyte(((host_reg & 8) ? 5:4)+2);
if (host_reg & 8) if (host_reg & 8)
{ {
addbyte(0x66); /*MOV -1[RDI+RSI],host_reg*/ addbyte(0x66); /*MOV [RDI+RSI],host_reg*/
addbyte(0x44); addbyte(0x44);
addbyte(0x89); addbyte(0x89);
addbyte(0x44 | ((host_reg & 7) << 3)); addbyte(0x04 | ((host_reg & 7) << 3));
addbyte(REG_EDI | (REG_ESI << 3)); addbyte(REG_EDI | (REG_ESI << 3));
addbyte(-1);
} }
else else
{ {
addbyte(0x66); /*MOV -1[RDI+RSI],host_reg*/ addbyte(0x66); /*MOV [RDI+RSI],host_reg*/
addbyte(0x89); addbyte(0x89);
addbyte(0x44 | (host_reg << 3)); addbyte(0x04 | (host_reg << 3));
addbyte(REG_EDI | (REG_ESI << 3)); addbyte(REG_EDI | (REG_ESI << 3));
addbyte(-1);
} }
addbyte(0xeb); /*JMP done*/ addbyte(0xeb); /*JMP done*/
addbyte(2+2+3+12+4+6); addbyte(2+2+3+12+4+6);
@ -1542,16 +1529,14 @@ static inline void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg)
addbyte(0x8d); addbyte(0x8d);
addbyte(0x34); addbyte(0x34);
addbyte(0x08); addbyte(0x08);
addbyte(0x67); /*LEA EDI, 3[ESI]*/ addbyte(0x89); /*MOV EDI, ESI*/
addbyte(0x8d); addbyte(0xf7);
addbyte(0x7e);
addbyte(0x03);
addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xc1); /*SHR ESI, 12*/
addbyte(0xe8 | REG_ESI); addbyte(0xe8 | REG_ESI);
addbyte(12); addbyte(12);
addbyte(0xf7); /*TEST EDI, 0xffc*/ addbyte(0xf7); /*TEST EDI, 3*/
addbyte(0xc7); addbyte(0xc7);
addlong(0xffc); addlong(3);
if (IS_32_ADDR(writelookup2)) if (IS_32_ADDR(writelookup2))
{ {
addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/
@ -1571,27 +1556,25 @@ static inline void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg)
addbyte(0x34); addbyte(0x34);
addbyte(0xf2); addbyte(0xf2);
} }
addbyte(0x74); /*JE slowpath*/ addbyte(0x75); /*JNE slowpath*/
addbyte(3+2+((host_reg & 8) ? 5:4)+2); addbyte(3+2+((host_reg & 8) ? 4:3)+2);
addbyte(0x83); /*CMP ESI, -1*/ addbyte(0x83); /*CMP ESI, -1*/
addbyte(0xf8 | REG_ESI); addbyte(0xf8 | REG_ESI);
addbyte(-1); addbyte(-1);
addbyte(0x74); /*JE slowpath*/ addbyte(0x74); /*JE slowpath*/
addbyte(((host_reg & 8) ? 5:4)+2); addbyte(((host_reg & 8) ? 4:3)+2);
if (host_reg & 8) if (host_reg & 8)
{ {
addbyte(0x44); /*MOV -3[RDI+RSI],host_reg*/ addbyte(0x44); /*MOV -3[RDI+RSI],host_reg*/
addbyte(0x89); addbyte(0x89);
addbyte(0x44 | ((host_reg & 7) << 3)); addbyte(0x04 | ((host_reg & 7) << 3));
addbyte(REG_EDI | (REG_ESI << 3)); addbyte(REG_EDI | (REG_ESI << 3));
addbyte(-3);
} }
else else
{ {
addbyte(0x89); /*MOV -3[RDI+RSI],host_reg*/ addbyte(0x89); /*MOV -3[RDI+RSI],host_reg*/
addbyte(0x44 | (host_reg << 3)); addbyte(0x04 | (host_reg << 3));
addbyte(REG_EDI | (REG_ESI << 3)); addbyte(REG_EDI | (REG_ESI << 3));
addbyte(-3);
} }
addbyte(0xeb); /*JMP done*/ addbyte(0xeb); /*JMP done*/
addbyte(2+2+3+12+4+6); addbyte(2+2+3+12+4+6);
@ -1635,16 +1618,14 @@ static inline void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2)
addbyte(0x8d); addbyte(0x8d);
addbyte(0x34); addbyte(0x34);
addbyte(0x08); addbyte(0x08);
addbyte(0x67); /*LEA EDI, 7[ESI]*/ addbyte(0x89); /*MOV EDI, ESI*/
addbyte(0x8d); addbyte(0xf7);
addbyte(0x7e);
addbyte(0x07);
addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xc1); /*SHR ESI, 12*/
addbyte(0xe8 | REG_ESI); addbyte(0xe8 | REG_ESI);
addbyte(12); addbyte(12);
addbyte(0xf7); /*TEST EDI, 0xff8*/ addbyte(0xf7); /*TEST EDI, 7*/
addbyte(0xc7); addbyte(0xc7);
addlong(0xff8); addlong(7);
if (IS_32_ADDR(writelookup2)) if (IS_32_ADDR(writelookup2))
{ {
addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/
@ -1664,28 +1645,26 @@ static inline void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2)
addbyte(0x34); addbyte(0x34);
addbyte(0xf2); addbyte(0xf2);
} }
addbyte(0x74); /*JE slowpath*/ addbyte(0x75); /*JNE slowpath*/
addbyte(3+2+5+2); addbyte(3+2+4+2);
addbyte(0x83); /*CMP ESI, -1*/ addbyte(0x83); /*CMP ESI, -1*/
addbyte(0xf8 | REG_ESI); addbyte(0xf8 | REG_ESI);
addbyte(-1); addbyte(-1);
addbyte(0x74); /*JE slowpath*/ addbyte(0x74); /*JE slowpath*/
addbyte(5+2); addbyte(4+2);
if (host_reg & 8) if (host_reg & 8)
{ {
addbyte(0x4c); /*MOV -7[RDI+RSI],host_reg*/ addbyte(0x4c); /*MOV [RDI+RSI],host_reg*/
addbyte(0x89); addbyte(0x89);
addbyte(0x44 | ((host_reg & 7) << 3)); addbyte(0x04 | ((host_reg & 7) << 3));
addbyte(REG_EDI | (REG_ESI << 3)); addbyte(REG_EDI | (REG_ESI << 3));
addbyte(-7);
} }
else else
{ {
addbyte(0x48); /*MOV -3[RDI+RSI],host_reg*/ addbyte(0x48); /*MOV [RDI+RSI],host_reg*/
addbyte(0x89); addbyte(0x89);
addbyte(0x44 | (host_reg << 3)); addbyte(0x04 | (host_reg << 3));
addbyte(REG_EDI | (REG_ESI << 3)); addbyte(REG_EDI | (REG_ESI << 3));
addbyte(-7);
} }
addbyte(0xeb); /*JMP done*/ addbyte(0xeb); /*JMP done*/
addbyte(2+2+3+12+4+6); addbyte(2+2+3+12+4+6);
@ -5823,16 +5802,14 @@ static inline int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg)
addbyte(0x8d); addbyte(0x8d);
addbyte(0x34); addbyte(0x34);
addbyte(0x08); addbyte(0x08);
addbyte(0x67); /*LEA EDI, 1[ESI]*/ addbyte(0x89); /*MOV EDI, ESI*/
addbyte(0x8d); addbyte(0xf7);
addbyte(0x7e);
addbyte(0x01);
addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xc1); /*SHR ESI, 12*/
addbyte(0xe8 | REG_ESI); addbyte(0xe8 | REG_ESI);
addbyte(12); addbyte(12);
addbyte(0xf7); /*TEST EDI, 0xfff*/ addbyte(0xf7); /*TEST EDI, 1*/
addbyte(0xc7); addbyte(0xc7);
addlong(0xfff); addlong(1);
if (IS_32_ADDR(readlookup2)) if (IS_32_ADDR(readlookup2))
{ {
addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/
@ -5852,18 +5829,17 @@ static inline int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg)
addbyte(0x34); addbyte(0x34);
addbyte(0xf2); addbyte(0xf2);
} }
addbyte(0x74); /*JE slowpath*/ addbyte(0x75); /*JNE slowpath*/
addbyte(3+2+5+2); addbyte(3+2+4+2);
addbyte(0x83); /*CMP ESI, -1*/ addbyte(0x83); /*CMP ESI, -1*/
addbyte(0xf8 | REG_ESI); addbyte(0xf8 | REG_ESI);
addbyte(-1); addbyte(-1);
addbyte(0x74); /*JE slowpath*/ addbyte(0x74); /*JE slowpath*/
addbyte(5+2); addbyte(4+2);
addbyte(0x66); /*MOV AX,-1[RDI+RSI]*/ addbyte(0x66); /*MOV AX,[RDI+RSI]*/
addbyte(0x8b); addbyte(0x8b);
addbyte(0x44); addbyte(0x04);
addbyte(REG_EDI | (REG_ESI << 3)); addbyte(REG_EDI | (REG_ESI << 3));
addbyte(-1);
addbyte(0xeb); /*JMP done*/ addbyte(0xeb); /*JMP done*/
addbyte(2+2+12); addbyte(2+2+12);
/*slowpath:*/ /*slowpath:*/
@ -5904,16 +5880,14 @@ static inline int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg)
addbyte(0x8d); addbyte(0x8d);
addbyte(0x34); addbyte(0x34);
addbyte(0x08); addbyte(0x08);
addbyte(0x67); /*LEA EDI, 3[ESI]*/ addbyte(0x89); /*MOV EDI, ESI*/
addbyte(0x8d); addbyte(0xf7);
addbyte(0x7e);
addbyte(0x03);
addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xc1); /*SHR ESI, 12*/
addbyte(0xe8 | REG_ESI); addbyte(0xe8 | REG_ESI);
addbyte(12); addbyte(12);
addbyte(0xf7); /*TEST EDI, 0xffc*/ addbyte(0xf7); /*TEST EDI, 1*/
addbyte(0xc7); addbyte(0xc7);
addlong(0xffc); addlong(1);
if (IS_32_ADDR(readlookup2)) if (IS_32_ADDR(readlookup2))
{ {
addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/
@ -5933,17 +5907,16 @@ static inline int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg)
addbyte(0x34); addbyte(0x34);
addbyte(0xf2); addbyte(0xf2);
} }
addbyte(0x74); /*JE slowpath*/ addbyte(0x75); /*JNE slowpath*/
addbyte(3+2+4+2); addbyte(3+2+3+2);
addbyte(0x83); /*CMP ESI, -1*/ addbyte(0x83); /*CMP ESI, -1*/
addbyte(0xf8 | REG_ESI); addbyte(0xf8 | REG_ESI);
addbyte(-1); addbyte(-1);
addbyte(0x74); /*JE slowpath*/ addbyte(0x74); /*JE slowpath*/
addbyte(4+2); addbyte(3+2);
addbyte(0x8b); /*MOV EAX,-3[RDI+RSI]*/ addbyte(0x8b); /*MOV EAX,[RDI+RSI]*/
addbyte(0x44); addbyte(0x04);
addbyte(REG_EDI | (REG_ESI << 3)); addbyte(REG_EDI | (REG_ESI << 3));
addbyte(-3);
addbyte(0xeb); /*JMP done*/ addbyte(0xeb); /*JMP done*/
addbyte(2+2+12); addbyte(2+2+12);
/*slowpath:*/ /*slowpath:*/
@ -6084,16 +6057,14 @@ static inline void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg)
addbyte(0x8d); addbyte(0x8d);
addbyte(0x34); addbyte(0x34);
addbyte(0x18); addbyte(0x18);
addbyte(0x67); /*LEA EDI, 1[ESI]*/ addbyte(0x89); /*MOV EDI, ESI*/
addbyte(0x8d); addbyte(0xf7);
addbyte(0x7e);
addbyte(0x01);
addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xc1); /*SHR ESI, 12*/
addbyte(0xe8 | REG_ESI); addbyte(0xe8 | REG_ESI);
addbyte(12); addbyte(12);
addbyte(0xf7); /*TEST EDI, 0xfff*/ addbyte(0xf7); /*TEST EDI, 1*/
addbyte(0xc7); addbyte(0xc7);
addlong(0xfff); addlong(1);
if (IS_32_ADDR(writelookup2)) if (IS_32_ADDR(writelookup2))
{ {
addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/
@ -6113,29 +6084,27 @@ static inline void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg)
addbyte(0x34); addbyte(0x34);
addbyte(0xf2); addbyte(0xf2);
} }
addbyte(0x74); /*JE slowpath*/ addbyte(0x75); /*JNE slowpath*/
addbyte(3+2+((host_reg & 8) ? 6:5)+2); addbyte(3+2+((host_reg & 8) ? 5:4)+2);
addbyte(0x83); /*CMP ESI, -1*/ addbyte(0x83); /*CMP ESI, -1*/
addbyte(0xf8 | REG_ESI); addbyte(0xf8 | REG_ESI);
addbyte(-1); addbyte(-1);
addbyte(0x74); /*JE slowpath*/ addbyte(0x74); /*JE slowpath*/
addbyte(((host_reg & 8) ? 6:5)+2); addbyte(((host_reg & 8) ? 5:4)+2);
if (host_reg & 8) if (host_reg & 8)
{ {
addbyte(0x66); /*MOV -1[RDI+RSI],host_reg*/ addbyte(0x66); /*MOV [RDI+RSI],host_reg*/
addbyte(0x44); addbyte(0x44);
addbyte(0x89); addbyte(0x89);
addbyte(0x44 | ((host_reg & 7) << 3)); addbyte(0x04 | ((host_reg & 7) << 3));
addbyte(REG_EDI | (REG_ESI << 3)); addbyte(REG_EDI | (REG_ESI << 3));
addbyte(-1);
} }
else else
{ {
addbyte(0x66); /*MOV -1[RDI+RSI],host_reg*/ addbyte(0x66); /*MOV [RDI+RSI],host_reg*/
addbyte(0x89); addbyte(0x89);
addbyte(0x44 | (host_reg << 3)); addbyte(0x04 | (host_reg << 3));
addbyte(REG_EDI | (REG_ESI << 3)); addbyte(REG_EDI | (REG_ESI << 3));
addbyte(-1);
} }
addbyte(0xeb); /*JMP done*/ addbyte(0xeb); /*JMP done*/
addbyte(2+2+3+12); addbyte(2+2+3+12);
@ -6172,16 +6141,14 @@ static inline void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg)
addbyte(0x8d); addbyte(0x8d);
addbyte(0x34); addbyte(0x34);
addbyte(0x18); addbyte(0x18);
addbyte(0x67); /*LEA EDI, 3[ESI]*/ addbyte(0x89); /*MOV EDI, ESI*/
addbyte(0x8d); addbyte(0xf7);
addbyte(0x7e);
addbyte(0x03);
addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xc1); /*SHR ESI, 12*/
addbyte(0xe8 | REG_ESI); addbyte(0xe8 | REG_ESI);
addbyte(12); addbyte(12);
addbyte(0xf7); /*TEST EDI, 0xffc*/ addbyte(0xf7); /*TEST EDI, 3*/
addbyte(0xc7); addbyte(0xc7);
addlong(0xffc); addlong(3);
if (IS_32_ADDR(writelookup2)) if (IS_32_ADDR(writelookup2))
{ {
addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/
@ -6201,27 +6168,25 @@ static inline void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg)
addbyte(0x34); addbyte(0x34);
addbyte(0xf2); addbyte(0xf2);
} }
addbyte(0x74); /*JE slowpath*/ addbyte(0x75); /*JNE slowpath*/
addbyte(3+2+((host_reg & 8) ? 5:4)+2); addbyte(3+2+((host_reg & 8) ? 4:3)+2);
addbyte(0x83); /*CMP ESI, -1*/ addbyte(0x83); /*CMP ESI, -1*/
addbyte(0xf8 | REG_ESI); addbyte(0xf8 | REG_ESI);
addbyte(-1); addbyte(-1);
addbyte(0x74); /*JE slowpath*/ addbyte(0x74); /*JE slowpath*/
addbyte(((host_reg & 8) ? 5:4)+2); addbyte(((host_reg & 8) ? 4:3)+2);
if (host_reg & 8) if (host_reg & 8)
{ {
addbyte(0x44); /*MOV -3[RDI+RSI],host_reg*/ addbyte(0x44); /*MOV [RDI+RSI],host_reg*/
addbyte(0x89); addbyte(0x89);
addbyte(0x44 | ((host_reg & 7) << 3)); addbyte(0x04 | ((host_reg & 7) << 3));
addbyte(REG_EDI | (REG_ESI << 3)); addbyte(REG_EDI | (REG_ESI << 3));
addbyte(-3);
} }
else else
{ {
addbyte(0x89); /*MOV -3[RDI+RSI],host_reg*/ addbyte(0x89); /*MOV [RDI+RSI],host_reg*/
addbyte(0x44 | (host_reg << 3)); addbyte(0x04 | (host_reg << 3));
addbyte(REG_EDI | (REG_ESI << 3)); addbyte(REG_EDI | (REG_ESI << 3));
addbyte(-3);
} }
addbyte(0xeb); /*JMP done*/ addbyte(0xeb); /*JMP done*/
addbyte(2+2+3+12); addbyte(2+2+3+12);

View file

@ -137,31 +137,29 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_W()
addbyte(0xd6); addbyte(0xd6);
addbyte(0x01); /*ADDL EDX, EAX*/ addbyte(0x01); /*ADDL EDX, EAX*/
addbyte(0xc2); addbyte(0xc2);
addbyte(0x8d); /*LEA EDI, 1[EDX]*/ addbyte(0x89); /*MOV EDI, EDX*/
addbyte(0x7a); addbyte(0xd7);
addbyte(0x01);
addbyte(0xc1); /*SHR EDX, 12*/ addbyte(0xc1); /*SHR EDX, 12*/
addbyte(0xea); addbyte(0xea);
addbyte(12); addbyte(12);
addbyte(0xf7); /*TEST EDI, 0xfff*/ addbyte(0xf7); /*TEST EDI, 1*/
addbyte(0xc7); addbyte(0xc7);
addlong(0xfff); addlong(1);
addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/
addbyte(0x14); addbyte(0x14);
addbyte(0x95); addbyte(0x95);
addlong((uint32_t)readlookup2); addlong((uint32_t)readlookup2);
addbyte(0x74); /*JE slowpath*/ addbyte(0x75); /*JNE slowpath*/
addbyte(3+2+5+1); addbyte(3+2+4+1);
addbyte(0x83); /*CMP EDX, -1*/ addbyte(0x83); /*CMP EDX, -1*/
addbyte(0xfa); addbyte(0xfa);
addbyte(-1); addbyte(-1);
addbyte(0x74); /*JE slowpath*/ addbyte(0x74); /*JE slowpath*/
addbyte(5+1); addbyte(4+1);
addbyte(0x0f); /*MOVZX EAX, -1[EDX+EDI]W*/ addbyte(0x0f); /*MOVZX EAX, [EDX+EDI]W*/
addbyte(0xb7); addbyte(0xb7);
addbyte(0x44); addbyte(0x04);
addbyte(0x3a); addbyte(0x3a);
addbyte(-1);
addbyte(0xc3); /*RET*/ addbyte(0xc3); /*RET*/
addbyte(0x50); /*slowpath: PUSH EAX*/ addbyte(0x50); /*slowpath: PUSH EAX*/
@ -194,30 +192,28 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_L()
addbyte(0xd6); addbyte(0xd6);
addbyte(0x01); /*ADDL EDX, EAX*/ addbyte(0x01); /*ADDL EDX, EAX*/
addbyte(0xc2); addbyte(0xc2);
addbyte(0x8d); /*LEA EDI, 3[EDX]*/ addbyte(0x89); /*MOV EDI, EDX*/
addbyte(0x7a); addbyte(0xd7);
addbyte(0x03);
addbyte(0xc1); /*SHR EDX, 12*/ addbyte(0xc1); /*SHR EDX, 12*/
addbyte(0xea); addbyte(0xea);
addbyte(12); addbyte(12);
addbyte(0xf7); /*TEST EDI, 0xffc*/ addbyte(0xf7); /*TEST EDI, 3*/
addbyte(0xc7); addbyte(0xc7);
addlong(0xffc); addlong(3);
addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/
addbyte(0x14); addbyte(0x14);
addbyte(0x95); addbyte(0x95);
addlong((uint32_t)readlookup2); addlong((uint32_t)readlookup2);
addbyte(0x74); /*JE slowpath*/ addbyte(0x75); /*JNE slowpath*/
addbyte(3+2+4+1); addbyte(3+2+3+1);
addbyte(0x83); /*CMP EDX, -1*/ addbyte(0x83); /*CMP EDX, -1*/
addbyte(0xfa); addbyte(0xfa);
addbyte(-1); addbyte(-1);
addbyte(0x74); /*JE slowpath*/ addbyte(0x74); /*JE slowpath*/
addbyte(4+1); addbyte(3+1);
addbyte(0x8b); /*MOV EAX, -3[EDX+EDI]*/ addbyte(0x8b); /*MOV EAX, [EDX+EDI]*/
addbyte(0x44); addbyte(0x04);
addbyte(0x3a); addbyte(0x3a);
addbyte(-3);
addbyte(0xc3); /*RET*/ addbyte(0xc3); /*RET*/
addbyte(0x50); /*slowpath: PUSH EAX*/ addbyte(0x50); /*slowpath: PUSH EAX*/
@ -247,34 +243,32 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_Q()
addbyte(0xd6); addbyte(0xd6);
addbyte(0x01); /*ADDL EDX, EAX*/ addbyte(0x01); /*ADDL EDX, EAX*/
addbyte(0xc2); addbyte(0xc2);
addbyte(0x8d); /*LEA EDI, 7[EDX]*/ addbyte(0x89); /*MOV EDI, EDX*/
addbyte(0x7a); addbyte(0xd7);
addbyte(0x07);
addbyte(0xc1); /*SHR EDX, 12*/ addbyte(0xc1); /*SHR EDX, 12*/
addbyte(0xea); addbyte(0xea);
addbyte(12); addbyte(12);
addbyte(0xf7); /*TEST EDI, 0xff8*/ addbyte(0xf7); /*TEST EDI, 7*/
addbyte(0xc7); addbyte(0xc7);
addlong(0xff8); addlong(7);
addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/
addbyte(0x14); addbyte(0x14);
addbyte(0x95); addbyte(0x95);
addlong((uint32_t)readlookup2); addlong((uint32_t)readlookup2);
addbyte(0x74); /*JE slowpath*/ addbyte(0x75); /*JNE slowpath*/
addbyte(3+2+4+4+1); addbyte(3+2+3+4+1);
addbyte(0x83); /*CMP EDX, -1*/ addbyte(0x83); /*CMP EDX, -1*/
addbyte(0xfa); addbyte(0xfa);
addbyte(-1); addbyte(-1);
addbyte(0x74); /*JE slowpath*/ addbyte(0x74); /*JE slowpath*/
addbyte(4+4+1); addbyte(3+4+1);
addbyte(0x8b); /*MOV EAX, [EDX+EDI]*/ addbyte(0x8b); /*MOV EAX, [EDX+EDI]*/
addbyte(0x44); addbyte(0x04);
addbyte(0x3a); addbyte(0x3a);
addbyte(-7);
addbyte(0x8b); /*MOV EDX, [EDX+EDI+4]*/ addbyte(0x8b); /*MOV EDX, [EDX+EDI+4]*/
addbyte(0x54); addbyte(0x54);
addbyte(0x3a); addbyte(0x3a);
addbyte(-7+4); addbyte(4);
addbyte(0xc3); /*RET*/ addbyte(0xc3); /*RET*/
addbyte(0x50); /*slowpath: PUSH EAX*/ addbyte(0x50); /*slowpath: PUSH EAX*/
@ -353,31 +347,29 @@ static uint32_t gen_MEM_STORE_ADDR_EA_W()
addbyte(0xf3); addbyte(0xf3);
addbyte(0x01); /*ADDL ESI, EAX*/ addbyte(0x01); /*ADDL ESI, EAX*/
addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); addbyte(0xc0 | (REG_EAX << 3) | REG_ESI);
addbyte(0x8d); /*LEA EDI, 1[ESI]*/ addbyte(0x89); /*MOV EDI, ESI*/
addbyte(0x7e); addbyte(0xf7);
addbyte(0x01);
addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xc1); /*SHR ESI, 12*/
addbyte(0xe8 | REG_ESI); addbyte(0xe8 | REG_ESI);
addbyte(12); addbyte(12);
addbyte(0xf7); /*TEST EDI, 0xfff*/ addbyte(0xf7); /*TEST EDI, 1*/
addbyte(0xc7); addbyte(0xc7);
addlong(0xfff); addlong(1);
addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/
addbyte(0x04 | (REG_ESI << 3)); addbyte(0x04 | (REG_ESI << 3));
addbyte(0x85 | (REG_ESI << 3)); addbyte(0x85 | (REG_ESI << 3));
addlong((uint32_t)writelookup2); addlong((uint32_t)writelookup2);
addbyte(0x74); /*JE slowpath*/ addbyte(0x75); /*JNE slowpath*/
addbyte(3+2+5+1); addbyte(3+2+4+1);
addbyte(0x83); /*CMP ESI, -1*/ addbyte(0x83); /*CMP ESI, -1*/
addbyte(0xf8 | REG_ESI); addbyte(0xf8 | REG_ESI);
addbyte(-1); addbyte(-1);
addbyte(0x74); /*JE slowpath*/ addbyte(0x74); /*JE slowpath*/
addbyte(5+1); addbyte(4+1);
addbyte(0x66); /*MOV -1[EDI+ESI],CX*/ addbyte(0x66); /*MOV [EDI+ESI],CX*/
addbyte(0x89); addbyte(0x89);
addbyte(0x44 | (REG_CX << 3)); addbyte(0x04 | (REG_CX << 3));
addbyte(REG_EDI | (REG_ESI << 3)); addbyte(REG_EDI | (REG_ESI << 3));
addbyte(-1);
addbyte(0xc3); /*RET*/ addbyte(0xc3); /*RET*/
addbyte(0x51); /*slowpath: PUSH ECX*/ addbyte(0x51); /*slowpath: PUSH ECX*/
@ -409,30 +401,28 @@ static uint32_t gen_MEM_STORE_ADDR_EA_L()
addbyte(0xf3); addbyte(0xf3);
addbyte(0x01); /*ADDL ESI, EAX*/ addbyte(0x01); /*ADDL ESI, EAX*/
addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); addbyte(0xc0 | (REG_EAX << 3) | REG_ESI);
addbyte(0x8d); /*LEA EDI, 3[ESI]*/ addbyte(0x89); /*MOV EDI, ESI*/
addbyte(0x7e); addbyte(0xf7);
addbyte(0x03);
addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xc1); /*SHR ESI, 12*/
addbyte(0xe8 | REG_ESI); addbyte(0xe8 | REG_ESI);
addbyte(12); addbyte(12);
addbyte(0xf7); /*TEST EDI, 0xffc*/ addbyte(0xf7); /*TEST EDI, 3*/
addbyte(0xc7); addbyte(0xc7);
addlong(0xffc); addlong(3);
addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/
addbyte(0x04 | (REG_ESI << 3)); addbyte(0x04 | (REG_ESI << 3));
addbyte(0x85 | (REG_ESI << 3)); addbyte(0x85 | (REG_ESI << 3));
addlong((uint32_t)writelookup2); addlong((uint32_t)writelookup2);
addbyte(0x74); /*JE slowpath*/ addbyte(0x75); /*JNE slowpath*/
addbyte(3+2+4+1); addbyte(3+2+3+1);
addbyte(0x83); /*CMP ESI, -1*/ addbyte(0x83); /*CMP ESI, -1*/
addbyte(0xf8 | REG_ESI); addbyte(0xf8 | REG_ESI);
addbyte(-1); addbyte(-1);
addbyte(0x74); /*JE slowpath*/ addbyte(0x74); /*JE slowpath*/
addbyte(4+1); addbyte(3+1);
addbyte(0x89); /*MOV -3[EDI+ESI],ECX*/ addbyte(0x89); /*MOV [EDI+ESI],ECX*/
addbyte(0x44 | (REG_ECX << 3)); addbyte(0x04 | (REG_ECX << 3));
addbyte(REG_EDI | (REG_ESI << 3)); addbyte(REG_EDI | (REG_ESI << 3));
addbyte(-3);
addbyte(0xc3); /*RET*/ addbyte(0xc3); /*RET*/
addbyte(0x51); /*slowpath: PUSH ECX*/ addbyte(0x51); /*slowpath: PUSH ECX*/
@ -464,34 +454,32 @@ static uint32_t gen_MEM_STORE_ADDR_EA_Q()
addbyte(0xf2); addbyte(0xf2);
addbyte(0x01); /*ADDL ESI, EAX*/ addbyte(0x01); /*ADDL ESI, EAX*/
addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); addbyte(0xc0 | (REG_EAX << 3) | REG_ESI);
addbyte(0x8d); /*LEA EDI, 7[ESI]*/ addbyte(0x89); /*MOV EDI, ESI*/
addbyte(0x7e); addbyte(0xf7);
addbyte(0x07);
addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xc1); /*SHR ESI, 12*/
addbyte(0xe8 | REG_ESI); addbyte(0xe8 | REG_ESI);
addbyte(12); addbyte(12);
addbyte(0xf7); /*TEST EDI, 0xff8*/ addbyte(0xf7); /*TEST EDI, 7*/
addbyte(0xc7); addbyte(0xc7);
addlong(0xff8); addlong(7);
addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/
addbyte(0x04 | (REG_ESI << 3)); addbyte(0x04 | (REG_ESI << 3));
addbyte(0x85 | (REG_ESI << 3)); addbyte(0x85 | (REG_ESI << 3));
addlong((uint32_t)writelookup2); addlong((uint32_t)writelookup2);
addbyte(0x74); /*JE slowpath*/ addbyte(0x75); /*JNE slowpath*/
addbyte(3+2+4+4+1); addbyte(3+2+3+4+1);
addbyte(0x83); /*CMP ESI, -1*/ addbyte(0x83); /*CMP ESI, -1*/
addbyte(0xf8 | REG_ESI); addbyte(0xf8 | REG_ESI);
addbyte(-1); addbyte(-1);
addbyte(0x74); /*JE slowpath*/ addbyte(0x74); /*JE slowpath*/
addbyte(4+4+1); addbyte(3+4+1);
addbyte(0x89); /*MOV -7[EDI+ESI],EBX*/ addbyte(0x89); /*MOV [EDI+ESI],EBX*/
addbyte(0x44 | (REG_EBX << 3)); addbyte(0x04 | (REG_EBX << 3));
addbyte(REG_EDI | (REG_ESI << 3)); addbyte(REG_EDI | (REG_ESI << 3));
addbyte(-7); addbyte(0x89); /*MOV 4[EDI+ESI],EBX*/
addbyte(0x89); /*MOV -7[EDI+ESI],EBX*/
addbyte(0x44 | (REG_ECX << 3)); addbyte(0x44 | (REG_ECX << 3));
addbyte(REG_EDI | (REG_ESI << 3)); addbyte(REG_EDI | (REG_ESI << 3));
addbyte(-7+4); addbyte(4);
addbyte(0xc3); /*RET*/ addbyte(0xc3); /*RET*/
addbyte(0x51); /*slowpath: PUSH ECX*/ addbyte(0x51); /*slowpath: PUSH ECX*/
@ -515,7 +503,9 @@ static uint32_t gen_MEM_STORE_ADDR_EA_Q()
return addr; return addr;
} }
#ifndef RELEASE_BUILD
static char gen_MEM_LOAD_ADDR_EA_B_NO_ABRT_err[] = "gen_MEM_LOAD_ADDR_EA_B_NO_ABRT aborted\n"; static char gen_MEM_LOAD_ADDR_EA_B_NO_ABRT_err[] = "gen_MEM_LOAD_ADDR_EA_B_NO_ABRT aborted\n";
#endif
static uint32_t gen_MEM_LOAD_ADDR_EA_B_NO_ABRT() static uint32_t gen_MEM_LOAD_ADDR_EA_B_NO_ABRT()
{ {
uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos];
@ -577,7 +567,9 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_B_NO_ABRT()
return addr; return addr;
} }
#ifndef RELEASE_BUILD
static char gen_MEM_LOAD_ADDR_EA_W_NO_ABRT_err[] = "gen_MEM_LOAD_ADDR_EA_W_NO_ABRT aborted\n"; static char gen_MEM_LOAD_ADDR_EA_W_NO_ABRT_err[] = "gen_MEM_LOAD_ADDR_EA_W_NO_ABRT aborted\n";
#endif
static uint32_t gen_MEM_LOAD_ADDR_EA_W_NO_ABRT() static uint32_t gen_MEM_LOAD_ADDR_EA_W_NO_ABRT()
{ {
uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos];
@ -586,31 +578,29 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_W_NO_ABRT()
addbyte(0xd6); addbyte(0xd6);
addbyte(0x01); /*ADDL EDX, EAX*/ addbyte(0x01); /*ADDL EDX, EAX*/
addbyte(0xc2); addbyte(0xc2);
addbyte(0x8d); /*LEA EDI, 1[EDX]*/ addbyte(0x89); /*MOV EDI, EDX*/
addbyte(0x7a); addbyte(0xd7);
addbyte(0x01);
addbyte(0xc1); /*SHR EDX, 12*/ addbyte(0xc1); /*SHR EDX, 12*/
addbyte(0xea); addbyte(0xea);
addbyte(12); addbyte(12);
addbyte(0xf7); /*TEST EDI, 0xfff*/ addbyte(0xf7); /*TEST EDI, 1*/
addbyte(0xc7); addbyte(0xc7);
addlong(0xfff); addlong(1);
addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/
addbyte(0x14); addbyte(0x14);
addbyte(0x95); addbyte(0x95);
addlong((uint32_t)readlookup2); addlong((uint32_t)readlookup2);
addbyte(0x74); /*JE slowpath*/ addbyte(0x75); /*JNE slowpath*/
addbyte(3+2+5+1); addbyte(3+2+4+1);
addbyte(0x83); /*CMP EDX, -1*/ addbyte(0x83); /*CMP EDX, -1*/
addbyte(0xfa); addbyte(0xfa);
addbyte(-1); addbyte(-1);
addbyte(0x74); /*JE slowpath*/ addbyte(0x74); /*JE slowpath*/
addbyte(5+1); addbyte(4+1);
addbyte(0x0f); /*MOVZX EEX, -1[EDX+EDI]W*/ addbyte(0x0f); /*MOVZX ECX, [EDX+EDI]W*/
addbyte(0xb7); addbyte(0xb7);
addbyte(0x4c); addbyte(0x0c);
addbyte(0x3a); addbyte(0x3a);
addbyte(-1);
addbyte(0xc3); /*RET*/ addbyte(0xc3); /*RET*/
addbyte(0x50); /*slowpath: PUSH EAX*/ addbyte(0x50); /*slowpath: PUSH EAX*/
@ -646,7 +636,9 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_W_NO_ABRT()
return addr; return addr;
} }
#ifndef RELEASE_BUILD
static char gen_MEM_LOAD_ADDR_EA_L_NO_ABRT_err[] = "gen_MEM_LOAD_ADDR_EA_L_NO_ABRT aborted\n"; static char gen_MEM_LOAD_ADDR_EA_L_NO_ABRT_err[] = "gen_MEM_LOAD_ADDR_EA_L_NO_ABRT aborted\n";
#endif
static uint32_t gen_MEM_LOAD_ADDR_EA_L_NO_ABRT() static uint32_t gen_MEM_LOAD_ADDR_EA_L_NO_ABRT()
{ {
uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos];
@ -655,30 +647,28 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_L_NO_ABRT()
addbyte(0xd6); addbyte(0xd6);
addbyte(0x01); /*ADDL EDX, EAX*/ addbyte(0x01); /*ADDL EDX, EAX*/
addbyte(0xc2); addbyte(0xc2);
addbyte(0x8d); /*LEA EDI, 3[EDX]*/ addbyte(0x89); /*MOV EDI, EDX*/
addbyte(0x7a); addbyte(0xd7);
addbyte(0x03);
addbyte(0xc1); /*SHR EDX, 12*/ addbyte(0xc1); /*SHR EDX, 12*/
addbyte(0xea); addbyte(0xea);
addbyte(12); addbyte(12);
addbyte(0xf7); /*TEST EDI, 0xffc*/ addbyte(0xf7); /*TEST EDI, 3*/
addbyte(0xc7); addbyte(0xc7);
addlong(0xffc); addlong(3);
addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/
addbyte(0x14); addbyte(0x14);
addbyte(0x95); addbyte(0x95);
addlong((uint32_t)readlookup2); addlong((uint32_t)readlookup2);
addbyte(0x74); /*JE slowpath*/ addbyte(0x75); /*JE slowpath*/
addbyte(3+2+4+1); addbyte(3+2+3+1);
addbyte(0x83); /*CMP EDX, -1*/ addbyte(0x83); /*CMP EDX, -1*/
addbyte(0xfa); addbyte(0xfa);
addbyte(-1); addbyte(-1);
addbyte(0x74); /*JE slowpath*/ addbyte(0x74); /*JE slowpath*/
addbyte(4+1); addbyte(3+1);
addbyte(0x8b); /*MOV ECX, -3[EDX+EDI]*/ addbyte(0x8b); /*MOV ECX, [EDX+EDI]*/
addbyte(0x4c); addbyte(0x0c);
addbyte(0x3a); addbyte(0x3a);
addbyte(-3);
addbyte(0xc3); /*RET*/ addbyte(0xc3); /*RET*/
addbyte(0x50); /*slowpath: PUSH EAX*/ addbyte(0x50); /*slowpath: PUSH EAX*/
@ -714,7 +704,9 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_L_NO_ABRT()
return addr; return addr;
} }
#ifndef RELEASE_BUILD
static char gen_MEM_STORE_ADDR_EA_B_NO_ABRT_err[] = "gen_MEM_STORE_ADDR_EA_B_NO_ABRT aborted\n"; static char gen_MEM_STORE_ADDR_EA_B_NO_ABRT_err[] = "gen_MEM_STORE_ADDR_EA_B_NO_ABRT aborted\n";
#endif
static uint32_t gen_MEM_STORE_ADDR_EA_B_NO_ABRT() static uint32_t gen_MEM_STORE_ADDR_EA_B_NO_ABRT()
{ {
uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos];
@ -772,7 +764,9 @@ static uint32_t gen_MEM_STORE_ADDR_EA_B_NO_ABRT()
return addr; return addr;
} }
#ifndef RELEASE_BUILD
static char gen_MEM_STORE_ADDR_EA_W_NO_ABRT_err[] = "gen_MEM_STORE_ADDR_EA_W_NO_ABRT aborted\n"; static char gen_MEM_STORE_ADDR_EA_W_NO_ABRT_err[] = "gen_MEM_STORE_ADDR_EA_W_NO_ABRT aborted\n";
#endif
static uint32_t gen_MEM_STORE_ADDR_EA_W_NO_ABRT() static uint32_t gen_MEM_STORE_ADDR_EA_W_NO_ABRT()
{ {
uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos];
@ -782,31 +776,29 @@ static uint32_t gen_MEM_STORE_ADDR_EA_W_NO_ABRT()
addbyte(0xf3); addbyte(0xf3);
addbyte(0x01); /*ADDL ESI, EAX*/ addbyte(0x01); /*ADDL ESI, EAX*/
addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); addbyte(0xc0 | (REG_EAX << 3) | REG_ESI);
addbyte(0x8d); /*LEA EDI, 1[ESI]*/ addbyte(0x89); /*MOV EDI, ESI*/
addbyte(0x7e); addbyte(0xf7);
addbyte(0x01);
addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xc1); /*SHR ESI, 12*/
addbyte(0xe8 | REG_ESI); addbyte(0xe8 | REG_ESI);
addbyte(12); addbyte(12);
addbyte(0xf7); /*TEST EDI, 0xfff*/ addbyte(0xf7); /*TEST EDI, 1*/
addbyte(0xc7); addbyte(0xc7);
addlong(0xfff); addlong(1);
addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/
addbyte(0x04 | (REG_ESI << 3)); addbyte(0x04 | (REG_ESI << 3));
addbyte(0x85 | (REG_ESI << 3)); addbyte(0x85 | (REG_ESI << 3));
addlong((uint32_t)writelookup2); addlong((uint32_t)writelookup2);
addbyte(0x74); /*JE slowpath*/ addbyte(0x75); /*JNE slowpath*/
addbyte(3+2+5+1); addbyte(3+2+4+1);
addbyte(0x83); /*CMP ESI, -1*/ addbyte(0x83); /*CMP ESI, -1*/
addbyte(0xf8 | REG_ESI); addbyte(0xf8 | REG_ESI);
addbyte(-1); addbyte(-1);
addbyte(0x74); /*JE slowpath*/ addbyte(0x74); /*JE slowpath*/
addbyte(5+1); addbyte(4+1);
addbyte(0x66); /*MOV -1[EDI+ESI],CX*/ addbyte(0x66); /*MOV [EDI+ESI],CX*/
addbyte(0x89); addbyte(0x89);
addbyte(0x44 | (REG_CX << 3)); addbyte(0x04 | (REG_CX << 3));
addbyte(REG_EDI | (REG_ESI << 3)); addbyte(REG_EDI | (REG_ESI << 3));
addbyte(-1);
addbyte(0xc3); /*RET*/ addbyte(0xc3); /*RET*/
addbyte(0x51); /*slowpath: PUSH ECX*/ addbyte(0x51); /*slowpath: PUSH ECX*/
@ -838,7 +830,9 @@ static uint32_t gen_MEM_STORE_ADDR_EA_W_NO_ABRT()
return addr; return addr;
} }
#ifndef RELEASE_BUILD
static char gen_MEM_STORE_ADDR_EA_L_NO_ABRT_err[] = "gen_MEM_STORE_ADDR_EA_L_NO_ABRT aborted\n"; static char gen_MEM_STORE_ADDR_EA_L_NO_ABRT_err[] = "gen_MEM_STORE_ADDR_EA_L_NO_ABRT aborted\n";
#endif
static uint32_t gen_MEM_STORE_ADDR_EA_L_NO_ABRT() static uint32_t gen_MEM_STORE_ADDR_EA_L_NO_ABRT()
{ {
uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos];
@ -848,30 +842,28 @@ static uint32_t gen_MEM_STORE_ADDR_EA_L_NO_ABRT()
addbyte(0xf3); addbyte(0xf3);
addbyte(0x01); /*ADDL ESI, EAX*/ addbyte(0x01); /*ADDL ESI, EAX*/
addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); addbyte(0xc0 | (REG_EAX << 3) | REG_ESI);
addbyte(0x8d); /*LEA EDI, 3[ESI]*/ addbyte(0x89); /*MOV EDI, ESI*/
addbyte(0x7e); addbyte(0xf7);
addbyte(0x03);
addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xc1); /*SHR ESI, 12*/
addbyte(0xe8 | REG_ESI); addbyte(0xe8 | REG_ESI);
addbyte(12); addbyte(12);
addbyte(0xf7); /*TEST EDI, 0xffc*/ addbyte(0xf7); /*TEST EDI, 3*/
addbyte(0xc7); addbyte(0xc7);
addlong(0xffc); addlong(3);
addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/
addbyte(0x04 | (REG_ESI << 3)); addbyte(0x04 | (REG_ESI << 3));
addbyte(0x85 | (REG_ESI << 3)); addbyte(0x85 | (REG_ESI << 3));
addlong((uint32_t)writelookup2); addlong((uint32_t)writelookup2);
addbyte(0x74); /*JE slowpath*/ addbyte(0x75); /*JNE slowpath*/
addbyte(3+2+4+1); addbyte(3+2+3+1);
addbyte(0x83); /*CMP ESI, -1*/ addbyte(0x83); /*CMP ESI, -1*/
addbyte(0xf8 | REG_ESI); addbyte(0xf8 | REG_ESI);
addbyte(-1); addbyte(-1);
addbyte(0x74); /*JE slowpath*/ addbyte(0x74); /*JE slowpath*/
addbyte(4+1); addbyte(3+1);
addbyte(0x89); /*MOV -3[EDI+ESI],ECX*/ addbyte(0x89); /*MOV [EDI+ESI],ECX*/
addbyte(0x44 | (REG_ECX << 3)); addbyte(0x04 | (REG_ECX << 3));
addbyte(REG_EDI | (REG_ESI << 3)); addbyte(REG_EDI | (REG_ESI << 3));
addbyte(-3);
addbyte(0xc3); /*RET*/ addbyte(0xc3); /*RET*/
addbyte(0x51); /*slowpath: PUSH ECX*/ addbyte(0x51); /*slowpath: PUSH ECX*/

View file

@ -68,6 +68,7 @@ int cpu_hasrdtsc;
int cpu_hasMMX, cpu_hasMSR; int cpu_hasMMX, cpu_hasMSR;
int cpu_hasCR4; int cpu_hasCR4;
int cpu_use_dynarec; int cpu_use_dynarec;
int cpu_cyrix_alignment;
uint64_t cpu_CR4_mask; uint64_t cpu_CR4_mask;
@ -90,6 +91,7 @@ int timing_iret_rm, timing_iret_v86, timing_iret_pm, timing_iret_pm_outer;
int timing_call_rm, timing_call_pm, timing_call_pm_gate, timing_call_pm_gate_inner; int timing_call_rm, timing_call_pm, timing_call_pm_gate, timing_call_pm_gate_inner;
int timing_retf_rm, timing_retf_pm, timing_retf_pm_outer; int timing_retf_rm, timing_retf_pm, timing_retf_pm_outer;
int timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate; int timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate;
int timing_misaligned;
static struct static struct
{ {
@ -581,6 +583,9 @@ void cpu_set()
} }
memset(&msr, 0, sizeof(msr)); memset(&msr, 0, sizeof(msr));
timing_misaligned = 0;
cpu_cyrix_alignment = 0;
switch (cpu_s->cpu_type) switch (cpu_s->cpu_type)
{ {
@ -712,6 +717,7 @@ void cpu_set()
timing_jmp_rm = 9; timing_jmp_rm = 9;
timing_jmp_pm = 26; timing_jmp_pm = 26;
timing_jmp_pm_gate = 37; timing_jmp_pm_gate = 37;
timing_misaligned = 3;
break; break;
case CPU_486DLC: case CPU_486DLC:
@ -744,6 +750,7 @@ void cpu_set()
timing_jmp_rm = 9; timing_jmp_rm = 9;
timing_jmp_pm = 26; timing_jmp_pm = 26;
timing_jmp_pm_gate = 37; timing_jmp_pm_gate = 37;
timing_misaligned = 3;
break; break;
case CPU_i486SX: case CPU_i486SX:
@ -776,6 +783,7 @@ void cpu_set()
timing_jmp_rm = 17; timing_jmp_rm = 17;
timing_jmp_pm = 19; timing_jmp_pm = 19;
timing_jmp_pm_gate = 32; timing_jmp_pm_gate = 32;
timing_misaligned = 3;
break; break;
case CPU_Am486SX: case CPU_Am486SX:
@ -809,6 +817,7 @@ void cpu_set()
timing_jmp_rm = 17; timing_jmp_rm = 17;
timing_jmp_pm = 19; timing_jmp_pm = 19;
timing_jmp_pm_gate = 32; timing_jmp_pm_gate = 32;
timing_misaligned = 3;
break; break;
case CPU_Cx486S: case CPU_Cx486S:
@ -841,6 +850,7 @@ void cpu_set()
timing_jmp_rm = 9; timing_jmp_rm = 9;
timing_jmp_pm = 26; timing_jmp_pm = 26;
timing_jmp_pm_gate = 37; timing_jmp_pm_gate = 37;
timing_misaligned = 3;
break; break;
case CPU_Cx5x86: case CPU_Cx5x86:
@ -872,6 +882,8 @@ void cpu_set()
timing_jmp_rm = 5; timing_jmp_rm = 5;
timing_jmp_pm = 7; timing_jmp_pm = 7;
timing_jmp_pm_gate = 17; timing_jmp_pm_gate = 17;
timing_misaligned = 2;
cpu_cyrix_alignment = 1;
break; break;
case CPU_WINCHIP: case CPU_WINCHIP:
@ -909,6 +921,8 @@ void cpu_set()
timing_jmp_rm = 5; timing_jmp_rm = 5;
timing_jmp_pm = 7; timing_jmp_pm = 7;
timing_jmp_pm_gate = 17; timing_jmp_pm_gate = 17;
timing_misaligned = 2;
cpu_cyrix_alignment = 1;
codegen_timing_set(&codegen_timing_winchip); codegen_timing_set(&codegen_timing_winchip);
break; break;
@ -942,6 +956,7 @@ void cpu_set()
timing_jmp_rm = 3; timing_jmp_rm = 3;
timing_jmp_pm = 3; timing_jmp_pm = 3;
timing_jmp_pm_gate = 18; timing_jmp_pm_gate = 18;
timing_misaligned = 3;
cpu_hasrdtsc = 1; cpu_hasrdtsc = 1;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_hasMMX = 0; cpu_hasMMX = 0;
@ -981,6 +996,7 @@ void cpu_set()
timing_jmp_rm = 3; timing_jmp_rm = 3;
timing_jmp_pm = 3; timing_jmp_pm = 3;
timing_jmp_pm_gate = 18; timing_jmp_pm_gate = 18;
timing_misaligned = 3;
cpu_hasrdtsc = 1; cpu_hasrdtsc = 1;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_hasMMX = 1; cpu_hasMMX = 1;
@ -1019,6 +1035,8 @@ void cpu_set()
timing_jmp_rm = 1; timing_jmp_rm = 1;
timing_jmp_pm = 4; timing_jmp_pm = 4;
timing_jmp_pm_gate = 14; timing_jmp_pm_gate = 14;
timing_misaligned = 2;
cpu_cyrix_alignment = 1;
cpu_hasrdtsc = 1; cpu_hasrdtsc = 1;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_hasMMX = 0; cpu_hasMMX = 0;
@ -1057,6 +1075,8 @@ void cpu_set()
timing_jmp_rm = 1; timing_jmp_rm = 1;
timing_jmp_pm = 4; timing_jmp_pm = 4;
timing_jmp_pm_gate = 14; timing_jmp_pm_gate = 14;
timing_misaligned = 2;
cpu_cyrix_alignment = 1;
cpu_hasrdtsc = 1; cpu_hasrdtsc = 1;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_hasMMX = 0; cpu_hasMMX = 0;
@ -1129,6 +1149,8 @@ void cpu_set()
timing_jmp_rm = 1; timing_jmp_rm = 1;
timing_jmp_pm = 4; timing_jmp_pm = 4;
timing_jmp_pm_gate = 14; timing_jmp_pm_gate = 14;
timing_misaligned = 2;
cpu_cyrix_alignment = 1;
cpu_hasrdtsc = 1; cpu_hasrdtsc = 1;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_hasMMX = 1; cpu_hasMMX = 1;

View file

@ -51,6 +51,7 @@ extern int timing_call_rm, timing_call_pm, timing_call_pm_gate, timing_call_pm_g
extern int timing_retf_rm, timing_retf_pm, timing_retf_pm_outer; extern int timing_retf_rm, timing_retf_pm, timing_retf_pm_outer;
extern int timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate; extern int timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate;
extern int timing_misaligned;
typedef struct typedef struct
{ {
@ -97,6 +98,8 @@ extern int cpu_iscyrix;
extern int cpu_16bitbus; extern int cpu_16bitbus;
extern int cpu_busspeed; extern int cpu_busspeed;
extern int cpu_multi; extern int cpu_multi;
/*Cyrix 5x86/6x86 only has data misalignment penalties when crossing 8-byte boundaries*/
extern int cpu_cyrix_alignment;
extern int cpu_hasrdtsc; extern int cpu_hasrdtsc;
extern int cpu_hasMSR; extern int cpu_hasMSR;

View file

@ -24,8 +24,8 @@ int writelnext;
extern int mmu_perm; extern int mmu_perm;
#define readmemb(a) ((readlookup2[(a)>>12]==-1)?readmembl(a):*(uint8_t *)(readlookup2[(a) >> 12] + (a))) #define readmemb(a) ((readlookup2[(a)>>12]==-1)?readmembl(a):*(uint8_t *)(readlookup2[(a) >> 12] + (a)))
#define readmemw(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFFE)?readmemwl(s,a):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) #define readmemw(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a)) & 1))?readmemwl(s,a):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a))))
#define readmeml(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFFC)?readmemll(s,a):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) #define readmeml(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a)) & 3))?readmemll(s,a):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a))))
//#define writememb(a,v) if (writelookup2[(a)>>12]==0xFFFFFFFF) writemembl(a,v); else ram[writelookup2[(a)>>12]+((a)&0xFFF)]=v //#define writememb(a,v) if (writelookup2[(a)>>12]==0xFFFFFFFF) writemembl(a,v); else ram[writelookup2[(a)>>12]+((a)&0xFFF)]=v
//#define writememw(s,a,v) if (writelookup2[((s)+(a))>>12]==0xFFFFFFFF || (s)==0xFFFFFFFF) writememwl(s,a,v); else *((uint16_t *)(&ram[writelookup2[((s)+(a))>>12]+(((s)+(a))&0xFFF)]))=v //#define writememw(s,a,v) if (writelookup2[((s)+(a))>>12]==0xFFFFFFFF || (s)==0xFFFFFFFF) writememwl(s,a,v); else *((uint16_t *)(&ram[writelookup2[((s)+(a))>>12]+(((s)+(a))&0xFFF)]))=v

194
src/mem.c
View file

@ -1099,22 +1099,30 @@ void writememb386l(uint32_t seg, uint32_t addr, uint8_t val)
uint16_t readmemwl(uint32_t seg, uint32_t addr) uint16_t readmemwl(uint32_t seg, uint32_t addr)
{ {
uint32_t addr2 = mem_logical_addr = seg + addr; uint32_t addr2 = mem_logical_addr = seg + addr;
if ((addr2&0xFFF)>0xFFE)
{
if (cr0>>31)
{
if (mmutranslate_read(addr2) == 0xffffffff) return 0xffff;
if (mmutranslate_read(addr2+1) == 0xffffffff) return 0xffff;
}
if (is386) return readmemb386l(seg,addr)|(readmemb386l(seg,addr+1)<<8);
else return readmembl(seg+addr)|(readmembl(seg+addr+1)<<8);
}
if (seg==-1) if (seg==-1)
{ {
x86gpf("NULL segment", 0); x86gpf("NULL segment", 0);
printf("NULL segment! rw %04X(%08X):%08X %02X %08X\n",CS,cs,cpu_state.pc,opcode,addr); printf("NULL segment! rw %04X(%08X):%08X %02X %08X\n",CS,cs,cpu_state.pc,opcode,addr);
return -1; return -1;
} }
if (addr2 & 1)
{
if (!cpu_cyrix_alignment || (addr2 & 7) == 7)
cycles -= timing_misaligned;
if ((addr2 & 0xFFF) > 0xFFE)
{
if (cr0 >> 31)
{
if (mmutranslate_read(addr2) == 0xffffffff) return 0xffff;
if (mmutranslate_read(addr2+1) == 0xffffffff) return 0xffff;
}
if (is386) return readmemb386l(seg,addr)|(readmemb386l(seg,addr+1)<<8);
else return readmembl(seg+addr)|(readmembl(seg+addr+1)<<8);
}
else if (readlookup2[addr2 >> 12] != -1)
return *(uint16_t *)(readlookup2[addr2 >> 12] + addr2);
}
if (cr0>>31) if (cr0>>31)
{ {
addr2 = mmutranslate_read(addr2); addr2 = mmutranslate_read(addr2);
@ -1137,25 +1145,6 @@ uint16_t readmemwl(uint32_t seg, uint32_t addr)
void writememwl(uint32_t seg, uint32_t addr, uint16_t val) void writememwl(uint32_t seg, uint32_t addr, uint16_t val)
{ {
uint32_t addr2 = mem_logical_addr = seg + addr; uint32_t addr2 = mem_logical_addr = seg + addr;
if ((addr2&0xFFF)>0xFFE)
{
if (cr0>>31)
{
if (mmutranslate_write(addr2) == 0xffffffff) return;
if (mmutranslate_write(addr2+1) == 0xffffffff) return;
}
if (is386)
{
writememb386l(seg,addr,val);
writememb386l(seg,addr+1,val>>8);
}
else
{
writemembl(seg+addr,val);
writemembl(seg+addr+1,val>>8);
}
return;
}
if (seg==-1) if (seg==-1)
{ {
@ -1163,6 +1152,37 @@ void writememwl(uint32_t seg, uint32_t addr, uint16_t val)
printf("NULL segment! ww %04X(%08X):%08X %02X %08X\n",CS,cs,cpu_state.pc,opcode,addr); printf("NULL segment! ww %04X(%08X):%08X %02X %08X\n",CS,cs,cpu_state.pc,opcode,addr);
return; return;
} }
if (addr2 & 1)
{
if (!cpu_cyrix_alignment || (addr2 & 7) == 7)
cycles -= timing_misaligned;
if ((addr2 & 0xFFF) > 0xFFE)
{
if (cr0 >> 31)
{
if (mmutranslate_write(addr2) == 0xffffffff) return;
if (mmutranslate_write(addr2+1) == 0xffffffff) return;
}
if (is386)
{
writememb386l(seg,addr,val);
writememb386l(seg,addr+1,val>>8);
}
else
{
writemembl(seg+addr,val);
writemembl(seg+addr+1,val>>8);
}
return;
}
else if (writelookup2[addr2 >> 12] != -1)
{
*(uint16_t *)(writelookup2[addr2 >> 12] + addr2) = val;
return;
}
}
if (page_lookup[addr2>>12]) if (page_lookup[addr2>>12])
{ {
page_lookup[addr2>>12]->write_w(addr2, val, page_lookup[addr2>>12]); page_lookup[addr2>>12]->write_w(addr2, val, page_lookup[addr2>>12]);
@ -1197,15 +1217,6 @@ void writememwl(uint32_t seg, uint32_t addr, uint16_t val)
uint32_t readmemll(uint32_t seg, uint32_t addr) uint32_t readmemll(uint32_t seg, uint32_t addr)
{ {
uint32_t addr2 = mem_logical_addr = seg + addr; uint32_t addr2 = mem_logical_addr = seg + addr;
if ((addr2&0xFFF)>0xFFC)
{
if (cr0>>31)
{
if (mmutranslate_read(addr2) == 0xffffffff) return 0xffffffff;
if (mmutranslate_read(addr2+3) == 0xffffffff) return 0xffffffff;
}
return readmemwl(seg,addr)|(readmemwl(seg,addr+2)<<16);
}
if (seg==-1) if (seg==-1)
{ {
@ -1213,7 +1224,24 @@ uint32_t readmemll(uint32_t seg, uint32_t addr)
printf("NULL segment! rl %04X(%08X):%08X %02X %08X\n",CS,cs,cpu_state.pc,opcode,addr); printf("NULL segment! rl %04X(%08X):%08X %02X %08X\n",CS,cs,cpu_state.pc,opcode,addr);
return -1; return -1;
} }
if (addr2 & 3)
{
if (!cpu_cyrix_alignment || (addr2 & 7) > 4)
cycles -= timing_misaligned;
if ((addr2&0xFFF)>0xFFC)
{
if (cr0>>31)
{
if (mmutranslate_read(addr2) == 0xffffffff) return 0xffffffff;
if (mmutranslate_read(addr2+3) == 0xffffffff) return 0xffffffff;
}
return readmemwl(seg,addr)|(readmemwl(seg,addr+2)<<16);
}
else if (readlookup2[addr2 >> 12] != -1)
return *(uint32_t *)(readlookup2[addr2 >> 12] + addr2);
}
if (cr0>>31) if (cr0>>31)
{ {
addr2 = mmutranslate_read(addr2); addr2 = mmutranslate_read(addr2);
@ -1236,23 +1264,33 @@ void writememll(uint32_t seg, uint32_t addr, uint32_t val)
{ {
uint32_t addr2 = mem_logical_addr = seg + addr; uint32_t addr2 = mem_logical_addr = seg + addr;
if ((addr2&0xFFF)>0xFFC)
{
if (cr0>>31)
{
if (mmutranslate_write(addr2) == 0xffffffff) return;
if (mmutranslate_write(addr2+3) == 0xffffffff) return;
}
writememwl(seg,addr,val);
writememwl(seg,addr+2,val>>16);
return;
}
if (seg==-1) if (seg==-1)
{ {
x86gpf("NULL segment", 0); x86gpf("NULL segment", 0);
printf("NULL segment! wl %04X(%08X):%08X %02X %08X\n",CS,cs,cpu_state.pc,opcode,addr); printf("NULL segment! wl %04X(%08X):%08X %02X %08X\n",CS,cs,cpu_state.pc,opcode,addr);
return; return;
} }
if (addr2 & 3)
{
if (!cpu_cyrix_alignment || (addr2 & 7) > 4)
cycles -= timing_misaligned;
if ((addr2 & 0xFFF) > 0xFFC)
{
if (cr0>>31)
{
if (mmutranslate_write(addr2) == 0xffffffff) return;
if (mmutranslate_write(addr2+3) == 0xffffffff) return;
}
writememwl(seg,addr,val);
writememwl(seg,addr+2,val>>16);
return;
}
else if (writelookup2[addr2 >> 12] != -1)
{
*(uint32_t *)(writelookup2[addr2 >> 12] + addr2) = val;
return;
}
}
if (page_lookup[addr2>>12]) if (page_lookup[addr2>>12])
{ {
page_lookup[addr2>>12]->write_l(addr2, val, page_lookup[addr2>>12]); page_lookup[addr2>>12]->write_l(addr2, val, page_lookup[addr2>>12]);
@ -1294,15 +1332,6 @@ void writememll(uint32_t seg, uint32_t addr, uint32_t val)
uint64_t readmemql(uint32_t seg, uint32_t addr) uint64_t readmemql(uint32_t seg, uint32_t addr)
{ {
uint32_t addr2 = mem_logical_addr = seg + addr; uint32_t addr2 = mem_logical_addr = seg + addr;
if ((addr2&0xFFF)>0xFF8)
{
if (cr0>>31)
{
if (mmutranslate_read(addr2) == 0xffffffff) return 0xffffffff;
if (mmutranslate_read(addr2+7) == 0xffffffff) return 0xffffffff;
}
return readmemll(seg,addr)|((uint64_t)readmemll(seg,addr+4)<<32);
}
if (seg==-1) if (seg==-1)
{ {
@ -1310,6 +1339,22 @@ uint64_t readmemql(uint32_t seg, uint32_t addr)
printf("NULL segment! rl %04X(%08X):%08X %02X %08X\n",CS,cs,cpu_state.pc,opcode,addr); printf("NULL segment! rl %04X(%08X):%08X %02X %08X\n",CS,cs,cpu_state.pc,opcode,addr);
return -1; return -1;
} }
if (addr2 & 7)
{
cycles -= timing_misaligned;
if ((addr2 & 0xFFF) > 0xFF8)
{
if (cr0>>31)
{
if (mmutranslate_read(addr2) == 0xffffffff) return 0xffffffff;
if (mmutranslate_read(addr2+7) == 0xffffffff) return 0xffffffff;
}
return readmemll(seg,addr)|((uint64_t)readmemll(seg,addr+4)<<32);
}
else if (readlookup2[addr2 >> 12] != -1)
return *(uint64_t *)(readlookup2[addr2 >> 12] + addr2);
}
if (cr0>>31) if (cr0>>31)
{ {
@ -1330,23 +1375,32 @@ void writememql(uint32_t seg, uint32_t addr, uint64_t val)
{ {
uint32_t addr2 = mem_logical_addr = seg + addr; uint32_t addr2 = mem_logical_addr = seg + addr;
if ((addr2 & 0xFFF) > 0xFF8)
{
if (cr0>>31)
{
if (mmutranslate_write(addr2) == 0xffffffff) return;
if (mmutranslate_write(addr2+7) == 0xffffffff) return;
}
writememll(seg, addr, val);
writememll(seg, addr+4, val >> 32);
return;
}
if (seg==-1) if (seg==-1)
{ {
x86gpf("NULL segment", 0); x86gpf("NULL segment", 0);
printf("NULL segment! wl %04X(%08X):%08X %02X %08X\n",CS,cs,cpu_state.pc,opcode,addr); printf("NULL segment! wl %04X(%08X):%08X %02X %08X\n",CS,cs,cpu_state.pc,opcode,addr);
return; return;
} }
if (addr2 & 7)
{
cycles -= timing_misaligned;
if ((addr2 & 0xFFF) > 0xFF8)
{
if (cr0>>31)
{
if (mmutranslate_write(addr2) == 0xffffffff) return;
if (mmutranslate_write(addr2+7) == 0xffffffff) return;
}
writememll(seg, addr, val);
writememll(seg, addr+4, val >> 32);
return;
}
else if (writelookup2[addr2 >> 12] != -1)
{
*(uint64_t *)(writelookup2[addr2 >> 12] + addr2) = val;
return;
}
}
if (page_lookup[addr2>>12]) if (page_lookup[addr2>>12])
{ {
page_lookup[addr2>>12]->write_l(addr2, val, page_lookup[addr2>>12]); page_lookup[addr2>>12]->write_l(addr2, val, page_lookup[addr2>>12]);