Effective address calculations now implemented by recompiled code in x86-64 recompiler.
This commit is contained in:
parent
406b16fa28
commit
04a0859f79
2 changed files with 288 additions and 224 deletions
|
|
@ -16,72 +16,11 @@
|
|||
extern uint16_t *mod1add[2][8];
|
||||
extern uint32_t *mod1seg[8];
|
||||
|
||||
/*Copy-and-pasted from 386_dynarec.c, is not in a header file because it will
|
||||
eventually be different for the dynarec ops*/
|
||||
#ifdef __amd64__
|
||||
static inline void fetch_ea_32_long(uint32_t rmdat)
|
||||
{
|
||||
eal_r = eal_w = NULL;
|
||||
easeg = ea_seg->base;
|
||||
ea_rseg = ea_seg->seg;
|
||||
if (rm == 4)
|
||||
{
|
||||
uint8_t sib = rmdat >> 8;
|
||||
|
||||
switch (mod)
|
||||
{
|
||||
case 0:
|
||||
eaaddr = regs[sib & 7].l;
|
||||
pc++;
|
||||
break;
|
||||
case 1:
|
||||
pc++;
|
||||
eaaddr = ((uint32_t)(int8_t)getbyte()) + regs[sib & 7].l;
|
||||
// pc++;
|
||||
break;
|
||||
case 2:
|
||||
eaaddr = (fastreadl(cs + pc + 1)) + regs[sib & 7].l;
|
||||
pc += 5;
|
||||
break;
|
||||
}
|
||||
/*SIB byte present*/
|
||||
if ((sib & 7) == 5 && !mod)
|
||||
eaaddr = getlong();
|
||||
else if ((sib & 6) == 4 && !ssegs)
|
||||
{
|
||||
easeg = ss;
|
||||
ea_rseg = SS;
|
||||
ea_seg = &_ss;
|
||||
}
|
||||
if (((sib >> 3) & 7) != 4)
|
||||
eaaddr += regs[(sib >> 3) & 7].l << (sib >> 6);
|
||||
}
|
||||
else
|
||||
{
|
||||
eaaddr = regs[rm].l;
|
||||
if (mod)
|
||||
{
|
||||
if (rm == 5 && !ssegs)
|
||||
{
|
||||
easeg = ss;
|
||||
ea_rseg = SS;
|
||||
ea_seg = &_ss;
|
||||
}
|
||||
if (mod == 1)
|
||||
{
|
||||
eaaddr += ((uint32_t)(int8_t)(rmdat >> 8));
|
||||
pc++;
|
||||
}
|
||||
else
|
||||
{
|
||||
eaaddr += getlong();
|
||||
}
|
||||
}
|
||||
else if (rm == 5)
|
||||
{
|
||||
eaaddr = getlong();
|
||||
}
|
||||
}
|
||||
if (easeg != 0xFFFFFFFF && ((easeg + eaaddr) & 0xFFF) <= 0xFFC)
|
||||
{
|
||||
uint32_t addr = easeg + eaaddr;
|
||||
|
|
@ -97,33 +36,6 @@ static inline void fetch_ea_16_long(uint32_t rmdat)
|
|||
eal_r = eal_w = NULL;
|
||||
easeg = ea_seg->base;
|
||||
ea_rseg = ea_seg->seg;
|
||||
if (!mod && rm == 6)
|
||||
{
|
||||
eaaddr = getword();
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (mod)
|
||||
{
|
||||
case 0:
|
||||
eaaddr = 0;
|
||||
break;
|
||||
case 1:
|
||||
eaaddr = (uint16_t)(int8_t)(rmdat >> 8); pc++;
|
||||
break;
|
||||
case 2:
|
||||
eaaddr = getword();
|
||||
break;
|
||||
}
|
||||
eaaddr += (*mod1add[0][rm]) + (*mod1add[1][rm]);
|
||||
if (mod1seg[rm] == &ss && !ssegs)
|
||||
{
|
||||
easeg = ss;
|
||||
ea_rseg = SS;
|
||||
ea_seg = &_ss;
|
||||
}
|
||||
eaaddr &= 0xFFFF;
|
||||
}
|
||||
if (easeg != 0xFFFFFFFF && ((easeg + eaaddr) & 0xFFF) <= 0xFFC)
|
||||
{
|
||||
uint32_t addr = easeg + eaaddr;
|
||||
|
|
@ -134,44 +46,9 @@ static inline void fetch_ea_16_long(uint32_t rmdat)
|
|||
}
|
||||
}
|
||||
|
||||
#define fetch_ea_16(rmdat) pc++; mod=(rmdat >> 6) & 3; reg=(rmdat >> 3) & 7; rm = rmdat & 7; if (mod != 3) { fetch_ea_16_long(rmdat); if (abrt) return 1; }
|
||||
#define fetch_ea_32(rmdat) pc++; mod=(rmdat >> 6) & 3; reg=(rmdat >> 3) & 7; rm = rmdat & 7; if (mod != 3) { fetch_ea_32_long(rmdat); } if (abrt) return 1
|
||||
|
||||
#else /*__amd64__*/
|
||||
|
||||
static inline void fetch_ea_32_long(uint32_t rmdat)
|
||||
{
|
||||
eal_r = eal_w = NULL;
|
||||
easeg = ea_seg->base;
|
||||
ea_rseg = ea_seg->seg;
|
||||
if (easeg != 0xFFFFFFFF && ((easeg + eaaddr) & 0xFFF) <= 0xFFC)
|
||||
{
|
||||
if ( readlookup2[(easeg + eaaddr) >> 12] != -1)
|
||||
eal_r = (uint32_t *)(readlookup2[(easeg + eaaddr) >> 12] + easeg + eaaddr);
|
||||
if (writelookup2[(easeg + eaaddr) >> 12] != -1)
|
||||
eal_w = (uint32_t *)(writelookup2[(easeg + eaaddr) >> 12] + easeg + eaaddr);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void fetch_ea_16_long(uint32_t rmdat)
|
||||
{
|
||||
eal_r = eal_w = NULL;
|
||||
easeg = ea_seg->base;
|
||||
ea_rseg = ea_seg->seg;
|
||||
if (easeg != 0xFFFFFFFF && ((easeg + eaaddr) & 0xFFF) <= 0xFFC)
|
||||
{
|
||||
if ( readlookup2[(easeg + eaaddr) >> 12] != -1)
|
||||
eal_r = (uint32_t *)(readlookup2[(easeg + eaaddr) >> 12] + easeg + eaaddr);
|
||||
if (writelookup2[(easeg + eaaddr) >> 12] != -1)
|
||||
eal_w = (uint32_t *)(writelookup2[(easeg + eaaddr) >> 12] + easeg + eaaddr);
|
||||
}
|
||||
}
|
||||
|
||||
#define fetch_ea_16(rmdat) pc++; if (mod != 3) fetch_ea_16_long(rmdat);
|
||||
#define fetch_ea_32(rmdat) pc++; if (mod != 3) fetch_ea_32_long(rmdat);
|
||||
|
||||
#endif /*__amd64__*/
|
||||
|
||||
|
||||
|
||||
#define OP_TABLE(name) dynarec_ops_ ## name
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#include "codegen.h"
|
||||
#include "codegen_ops.h"
|
||||
//#include "codegen_ops_x86.h"
|
||||
#include "codegen_ops_x86-64.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#include <sys/mman.h>
|
||||
|
|
@ -297,16 +297,34 @@ void codegen_block_init(uint32_t phys_addr)
|
|||
addbyte(0xf6);
|
||||
#endif
|
||||
call(block, (uintptr_t)x86gpf);
|
||||
while (block_pos < BLOCK_EXIT_OFFSET)
|
||||
addbyte(0x90); /*NOP*/
|
||||
block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/
|
||||
addbyte(0x48); /*ADDL $32,%rsp*/
|
||||
addbyte(0x83);
|
||||
addbyte(0xC4);
|
||||
addbyte(0x20);
|
||||
addbyte(0x41); /*POP R15*/
|
||||
addbyte(0x5f);
|
||||
addbyte(0x41); /*POP R14*/
|
||||
addbyte(0x5e);
|
||||
addbyte(0x41); /*POP R13*/
|
||||
addbyte(0x5d);
|
||||
addbyte(0x41); /*POP R12*/
|
||||
addbyte(0x5c);
|
||||
addbyte(0x5d); /*POP RBP*/
|
||||
addbyte(0xC3); /*RET*/
|
||||
cpu_block_end = 0;
|
||||
block_pos = 0; /*Entry code*/
|
||||
addbyte(0x55); /*PUSH RBP*/
|
||||
addbyte(0x41); /*PUSH R12*/
|
||||
addbyte(0x54);
|
||||
addbyte(0x41); /*PUSH R13*/
|
||||
addbyte(0x55);
|
||||
addbyte(0x41); /*PUSH R14*/
|
||||
addbyte(0x56);
|
||||
addbyte(0x41); /*PUSH R15*/
|
||||
addbyte(0x57);
|
||||
addbyte(0x48); /*SUBL $32,%rsp*/
|
||||
addbyte(0x83);
|
||||
addbyte(0xEC);
|
||||
|
|
@ -482,6 +500,14 @@ void codegen_block_end()
|
|||
addbyte(0x83);
|
||||
addbyte(0xC4);
|
||||
addbyte(0x20);
|
||||
addbyte(0x41); /*POP R15*/
|
||||
addbyte(0x5f);
|
||||
addbyte(0x41); /*POP R14*/
|
||||
addbyte(0x5e);
|
||||
addbyte(0x41); /*POP R13*/
|
||||
addbyte(0x5d);
|
||||
addbyte(0x41); /*POP R12*/
|
||||
addbyte(0x5c);
|
||||
addbyte(0x5d); /*POP RBP*/
|
||||
addbyte(0xC3); /*RET*/
|
||||
|
||||
|
|
@ -595,54 +621,125 @@ void codegen_debug()
|
|||
pclog("At %04x(%08x):%04x %04x(%08x):%04x es=%08x EAX=%08x BX=%04x ECX=%08x BP=%04x EDX=%08x EDI=%08x\n", CS, cs, pc, SS, ss, ESP, es,EAX, BX,ECX,BP, EDX,EDI);
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
|
||||
static x86seg *codegen_generate_ea_16_long(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc)
|
||||
{
|
||||
if (!mod && rm == 6)
|
||||
{
|
||||
addbyte(0xC7); /*MOVL $0,(ssegs)*/
|
||||
addbyte(0x05);
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)&eaaddr);
|
||||
addlong((fetchdat >> 8) & 0xffff);
|
||||
(*op_pc) += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
int base_reg, index_reg;
|
||||
|
||||
switch (rm)
|
||||
{
|
||||
case 0: case 1: case 7:
|
||||
base_reg = LOAD_REG_W(REG_BX);
|
||||
break;
|
||||
case 2: case 3: case 6:
|
||||
base_reg = LOAD_REG_W(REG_BP);
|
||||
break;
|
||||
case 4:
|
||||
base_reg = LOAD_REG_W(REG_SI);
|
||||
break;
|
||||
case 5:
|
||||
base_reg = LOAD_REG_W(REG_DI);
|
||||
break;
|
||||
}
|
||||
if (!(rm & 4))
|
||||
{
|
||||
if (rm & 1)
|
||||
index_reg = LOAD_REG_W(REG_DI);
|
||||
else
|
||||
index_reg = LOAD_REG_W(REG_SI);
|
||||
}
|
||||
base_reg &= 7;
|
||||
index_reg &= 7;
|
||||
|
||||
switch (mod)
|
||||
{
|
||||
case 0:
|
||||
addbyte(0xa1); /*MOVL *mod1add[0][rm], %eax*/
|
||||
addlong((uint32_t)mod1add[0][rm]);
|
||||
addbyte(0x03); /*ADDL *mod1add[1][rm], %eax*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t)mod1add[1][rm]);
|
||||
if (rm & 4)
|
||||
{
|
||||
addbyte(0x41); /*MOVZX EAX, base_reg*/
|
||||
addbyte(0x0f);
|
||||
addbyte(0xb7);
|
||||
addbyte(0xc0 | base_reg);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x67); /*LEA EAX, base_reg+index_reg*/
|
||||
addbyte(0x43);
|
||||
addbyte(0x8d);
|
||||
if (base_reg == 5)
|
||||
{
|
||||
addbyte(0x44);
|
||||
addbyte(base_reg | (index_reg << 3));
|
||||
addbyte(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x04);
|
||||
addbyte(base_reg | (index_reg << 3));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
addbyte(0xb8); /*MOVL ,%eax*/
|
||||
addlong((uint32_t)(int8_t)(rmdat >> 8));// pc++;
|
||||
addbyte(0x03); /*ADDL *mod1add[0][rm], %eax*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t)mod1add[0][rm]);
|
||||
addbyte(0x03); /*ADDL *mod1add[1][rm], %eax*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t)mod1add[1][rm]);
|
||||
if (rm & 4)
|
||||
{
|
||||
addbyte(0x67); /*LEA EAX, base_reg+imm8*/
|
||||
addbyte(0x41);
|
||||
addbyte(0x8d);
|
||||
addbyte(0x40 | base_reg);
|
||||
addbyte((fetchdat >> 8) & 0xff);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x67); /*LEA EAX, base_reg+index_reg+imm8*/
|
||||
addbyte(0x43);
|
||||
addbyte(0x8d);
|
||||
addbyte(0x44);
|
||||
addbyte(base_reg | (index_reg << 3));
|
||||
addbyte((fetchdat >> 8) & 0xff);
|
||||
}
|
||||
(*op_pc)++;
|
||||
break;
|
||||
case 2:
|
||||
addbyte(0xb8); /*MOVL ,%eax*/
|
||||
addlong((fetchdat >> 8) & 0xffff);// pc++;
|
||||
addbyte(0x03); /*ADDL *mod1add[0][rm], %eax*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t)mod1add[0][rm]);
|
||||
addbyte(0x03); /*ADDL *mod1add[1][rm], %eax*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t)mod1add[1][rm]);
|
||||
if (rm & 4)
|
||||
{
|
||||
addbyte(0x67); /*LEA EAX, base_reg+imm8*/
|
||||
addbyte(0x41);
|
||||
addbyte(0x8d);
|
||||
addbyte(0x80 | base_reg);
|
||||
addlong((fetchdat >> 8) & 0xffff);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x67); /*LEA EAX, base_reg+index_reg+imm16*/
|
||||
addbyte(0x43);
|
||||
addbyte(0x8d);
|
||||
addbyte(0x84);
|
||||
addbyte(base_reg | (index_reg << 3));
|
||||
addlong((fetchdat >> 8) & 0xffff);
|
||||
}
|
||||
(*op_pc) += 2;
|
||||
break;
|
||||
|
||||
}
|
||||
addbyte(0x25); /*ANDL $0xffff, %eax*/
|
||||
addlong(0xffff);
|
||||
addbyte(0xa3);
|
||||
if (mod || !(rm & 4))
|
||||
{
|
||||
addbyte(0x25); /*ANDL $0xffff, %eax*/
|
||||
addlong(0xffff);
|
||||
}
|
||||
addbyte(0x89); /*MOV eaaddr, EAX*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)&eaaddr);
|
||||
|
||||
if (mod1seg[rm] == &ss && !op_ssegs)
|
||||
|
|
@ -650,7 +747,7 @@ static x86seg *codegen_generate_ea_16_long(x86seg *op_ea_seg, uint32_t fetchdat,
|
|||
}
|
||||
return op_ea_seg;
|
||||
}
|
||||
|
||||
//#if 0
|
||||
static x86seg *codegen_generate_ea_32_long(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset)
|
||||
{
|
||||
uint32_t new_eaaddr;
|
||||
|
|
@ -658,42 +755,135 @@ static x86seg *codegen_generate_ea_32_long(x86seg *op_ea_seg, uint32_t fetchdat,
|
|||
if (rm == 4)
|
||||
{
|
||||
uint8_t sib = fetchdat >> 8;
|
||||
int base_reg = -1, index_reg = -1;
|
||||
|
||||
(*op_pc)++;
|
||||
|
||||
switch (mod)
|
||||
|
||||
if (mod || (sib & 7) != 5)
|
||||
base_reg = LOAD_REG_L(sib & 7) & 7;
|
||||
|
||||
if (((sib >> 3) & 7) != 4)
|
||||
index_reg = LOAD_REG_L((sib >> 3) & 7) & 7;
|
||||
|
||||
if (index_reg == -1)
|
||||
{
|
||||
case 0:
|
||||
if ((sib & 7) == 5)
|
||||
switch (mod)
|
||||
{
|
||||
case 0:
|
||||
if ((sib & 7) == 5)
|
||||
{
|
||||
new_eaaddr = fastreadl(cs + (*op_pc) + 1);
|
||||
addbyte(0xb8); /*MOV EAX, imm32*/
|
||||
addlong(new_eaaddr);
|
||||
(*op_pc) += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x44); /*MOV EAX, base_reg*/
|
||||
addbyte(0x89);
|
||||
addbyte(0xc0 | (base_reg << 3));
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
addbyte(0x67); /*LEA EAX, imm8+base_reg*/
|
||||
addbyte(0x41);
|
||||
addbyte(0x8d);
|
||||
if (base_reg == 4)
|
||||
{
|
||||
addbyte(0x44);
|
||||
addbyte(0x24);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x40 | base_reg);
|
||||
}
|
||||
addbyte((fetchdat >> 16) & 0xff);
|
||||
(*op_pc)++;
|
||||
break;
|
||||
case 2:
|
||||
new_eaaddr = fastreadl(cs + (*op_pc) + 1);
|
||||
addbyte(0xb8); /*MOVL ,%eax*/
|
||||
addlong(new_eaaddr);// pc++;
|
||||
addbyte(0x67); /*LEA EAX, imm32+base_reg*/
|
||||
addbyte(0x41);
|
||||
addbyte(0x8d);
|
||||
if (base_reg == 4)
|
||||
{
|
||||
addbyte(0x84);
|
||||
addbyte(0x24);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x80 | base_reg);
|
||||
}
|
||||
addlong(new_eaaddr);
|
||||
(*op_pc) += 4;
|
||||
break;
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (mod)
|
||||
{
|
||||
addbyte(0xa1); /*MOVL regs[sib&7].l, %eax*/
|
||||
addlong((uint32_t)®s[sib & 7].l);
|
||||
case 0:
|
||||
if ((sib & 7) == 5)
|
||||
{
|
||||
new_eaaddr = fastreadl(cs + (*op_pc) + 1);
|
||||
if (sib >> 6)
|
||||
{
|
||||
addbyte(0x67); /*LEA EAX, imm32+index_reg*scale*/
|
||||
addbyte(0x42);
|
||||
addbyte(0x8d);
|
||||
addbyte(0x04);
|
||||
addbyte(0x05 | (sib & 0xc0) | (index_reg << 3));
|
||||
addlong(new_eaaddr);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x67); /*LEA EAX, imm32+index_reg*/
|
||||
addbyte(0x41);
|
||||
addbyte(0x8d);
|
||||
addbyte(0x80 | index_reg);
|
||||
addlong(new_eaaddr);
|
||||
}
|
||||
(*op_pc) += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x67); /*LEA EAX, base_reg+index_reg*scale*/
|
||||
addbyte(0x43);
|
||||
addbyte(0x8d);
|
||||
if (base_reg == 5)
|
||||
{
|
||||
addbyte(0x44);
|
||||
addbyte(base_reg | (index_reg << 3) | (sib & 0xc0));
|
||||
addbyte(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x04);
|
||||
addbyte(base_reg | (index_reg << 3) | (sib & 0xc0));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
addbyte(0x67); /*LEA EAX, imm8+base_reg+index_reg*scale*/
|
||||
addbyte(0x43);
|
||||
addbyte(0x8d);
|
||||
addbyte(0x44);
|
||||
addbyte(base_reg | (index_reg << 3) | (sib & 0xc0));
|
||||
addbyte((fetchdat >> 16) & 0xff);
|
||||
(*op_pc)++;
|
||||
break;
|
||||
case 2:
|
||||
new_eaaddr = fastreadl(cs + (*op_pc) + 1);
|
||||
addbyte(0x67); /*LEA EAX, imm32+base_reg+index_reg*scale*/
|
||||
addbyte(0x43);
|
||||
addbyte(0x8d);
|
||||
addbyte(0x84);
|
||||
addbyte(base_reg | (index_reg << 3) | (sib & 0xc0));
|
||||
addlong(new_eaaddr);
|
||||
(*op_pc) += 4;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
new_eaaddr = (uint32_t)(int8_t)((fetchdat >> 16) & 0xff);
|
||||
addbyte(0xb8); /*MOVL new_eaaddr, %eax*/
|
||||
addlong(new_eaaddr);
|
||||
addbyte(0x03); /*ADDL regs[sib&7].l, %eax*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t)®s[sib & 7].l);
|
||||
(*op_pc)++;
|
||||
break;
|
||||
case 2:
|
||||
new_eaaddr = fastreadl(cs + (*op_pc) + 1);
|
||||
addbyte(0xb8); /*MOVL new_eaaddr, %eax*/
|
||||
addlong(new_eaaddr);
|
||||
addbyte(0x03); /*ADDL regs[sib&7].l, %eax*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t)®s[sib & 7].l);
|
||||
(*op_pc) += 4;
|
||||
break;
|
||||
}
|
||||
if (stack_offset && (sib & 7) == 4 && (mod || (sib & 7) != 5)) /*ESP*/
|
||||
{
|
||||
|
|
@ -702,74 +892,68 @@ static x86seg *codegen_generate_ea_32_long(x86seg *op_ea_seg, uint32_t fetchdat,
|
|||
}
|
||||
if (((sib & 7) == 4 || (mod && (sib & 7) == 5)) && !op_ssegs)
|
||||
op_ea_seg = &_ss;
|
||||
if (((sib >> 3) & 7) != 4)
|
||||
{
|
||||
switch (sib >> 6)
|
||||
{
|
||||
case 0:
|
||||
addbyte(0x03); /*ADDL regs[sib&7].l, %eax*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t)®s[(sib >> 3) & 7].l);
|
||||
break;
|
||||
case 1:
|
||||
addbyte(0x8B); addbyte(0x1D); addlong((uint32_t)®s[(sib >> 3) & 7].l); /*MOVL armregs[RD],%ebx*/
|
||||
addbyte(0x01); addbyte(0xD8); /*ADDL %ebx,%eax*/
|
||||
addbyte(0x01); addbyte(0xD8); /*ADDL %ebx,%eax*/
|
||||
break;
|
||||
case 2:
|
||||
addbyte(0x8B); addbyte(0x1D); addlong((uint32_t)®s[(sib >> 3) & 7].l); /*MOVL armregs[RD],%ebx*/
|
||||
addbyte(0xC1); addbyte(0xE3); addbyte(2); /*SHL $2,%ebx*/
|
||||
addbyte(0x01); addbyte(0xD8); /*ADDL %ebx,%eax*/
|
||||
break;
|
||||
case 3:
|
||||
addbyte(0x8B); addbyte(0x1D); addlong((uint32_t)®s[(sib >> 3) & 7].l); /*MOVL armregs[RD],%ebx*/
|
||||
addbyte(0xC1); addbyte(0xE3); addbyte(3); /*SHL $2,%ebx*/
|
||||
addbyte(0x01); addbyte(0xD8); /*ADDL %ebx,%eax*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
addbyte(0xa3);
|
||||
|
||||
addbyte(0x89); /*MOV eaaddr, EAX*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)&eaaddr);
|
||||
}
|
||||
else
|
||||
{
|
||||
int base_reg;
|
||||
|
||||
if (!mod && rm == 5)
|
||||
{
|
||||
new_eaaddr = fastreadl(cs + (*op_pc) + 1);
|
||||
addbyte(0xC7); /*MOVL $new_eaaddr,(eaaddr)*/
|
||||
addbyte(0x05);
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)&eaaddr);
|
||||
addlong(new_eaaddr);
|
||||
(*op_pc) += 4;
|
||||
return op_ea_seg;
|
||||
}
|
||||
addbyte(0xa1); /*MOVL regs[rm].l, %eax*/
|
||||
addlong((uint32_t)®s[rm].l);
|
||||
eaaddr = regs[rm].l;
|
||||
base_reg = LOAD_REG_L(rm) & 7;
|
||||
if (mod)
|
||||
{
|
||||
if (rm == 5 && !op_ssegs)
|
||||
op_ea_seg = &_ss;
|
||||
if (mod == 1)
|
||||
{
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t)(int8_t)(fetchdat >> 8));
|
||||
addbyte(0x67); /*LEA EAX, base_reg+imm8*/
|
||||
addbyte(0x41);
|
||||
addbyte(0x8d);
|
||||
addbyte(0x40 | base_reg);
|
||||
addbyte((fetchdat >> 8) & 0xff);
|
||||
(*op_pc)++;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_eaaddr = fastreadl(cs + (*op_pc) + 1);
|
||||
addbyte(0x05);
|
||||
addlong(new_eaaddr);
|
||||
addbyte(0x67); /*LEA EAX, base_reg+imm32*/
|
||||
addbyte(0x41);
|
||||
addbyte(0x8d);
|
||||
addbyte(0x80 | base_reg);
|
||||
addlong(new_eaaddr);
|
||||
(*op_pc) += 4;
|
||||
}
|
||||
addbyte(0x89); /*MOV eaaddr, EAX*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)&eaaddr);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x44); /*MOV eaaddr, base_reg*/
|
||||
addbyte(0x89);
|
||||
addbyte(4 | (base_reg << 3));
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)&eaaddr);
|
||||
}
|
||||
addbyte(0xa3);
|
||||
addlong((uint32_t)&eaaddr);
|
||||
}
|
||||
return op_ea_seg;
|
||||
}
|
||||
#endif
|
||||
//#endif
|
||||
void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc)
|
||||
{
|
||||
codeblock_t *block = &codeblock[block_current];
|
||||
|
|
@ -1002,10 +1186,10 @@ generate_call:
|
|||
addlong((uint32_t)&ssegs);
|
||||
addlong(op_ssegs);
|
||||
}
|
||||
#if 0
|
||||
if (!test_modrm ||
|
||||
//#if 0
|
||||
if ((!test_modrm ||
|
||||
(op_table == x86_dynarec_opcodes && opcode_modrm[opcode]) ||
|
||||
(op_table == x86_dynarec_opcodes_0f && opcode_0f_modrm[opcode]))
|
||||
(op_table == x86_dynarec_opcodes_0f && opcode_0f_modrm[opcode]))/* && !(op_32 & 0x200)*/)
|
||||
{
|
||||
int stack_offset = 0;
|
||||
|
||||
|
|
@ -1017,15 +1201,18 @@ generate_call:
|
|||
rm = fetchdat & 7;
|
||||
|
||||
addbyte(0xC7); /*MOVL $mod,(mod)*/
|
||||
addbyte(0x05);
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)&mod);
|
||||
addlong(mod);
|
||||
addbyte(0xC7); /*MOVL $reg,(reg)*/
|
||||
addbyte(0x05);
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)®);
|
||||
addlong(reg);
|
||||
addbyte(0xC7); /*MOVL $rm,(rm)*/
|
||||
addbyte(0x05);
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)&rm);
|
||||
addlong(rm);
|
||||
|
||||
|
|
@ -1036,7 +1223,7 @@ generate_call:
|
|||
op_ea_seg = codegen_generate_ea_32_long(op_ea_seg, fetchdat, op_ssegs, &op_pc, stack_offset);
|
||||
op_pc -= pc_off;
|
||||
}
|
||||
#endif
|
||||
//#endif
|
||||
// if (op_ea_seg != last_ea_seg)
|
||||
// {
|
||||
// last_ea_seg = op_ea_seg;
|
||||
|
|
|
|||
Loading…
Reference in a new issue