Added code generation for memory versions of MOV, and memory source versions of ADD, SUB, AND, OR, XOR and CMP.
This commit is contained in:
parent
7a7f586cd3
commit
ba715706b6
11 changed files with 997 additions and 85 deletions
|
|
@ -1,7 +1,14 @@
|
|||
/*Register allocation :
|
||||
EBX, ECX, EDX - emulated registers
|
||||
EAX - work register, EA storage
|
||||
ESI, EDI - work registers
|
||||
*/
|
||||
#define HOST_REG_START 1
|
||||
#define HOST_REG_END 4
|
||||
static inline int find_host_reg()
|
||||
{
|
||||
int c;
|
||||
for (c = 0; c < NR_HOST_REGS; c++)
|
||||
for (c = HOST_REG_START; c < HOST_REG_END; c++)
|
||||
{
|
||||
if (host_reg_mapping[c] == -1)
|
||||
break;
|
||||
|
|
@ -100,6 +107,18 @@ static int LOAD_REG_L(int reg)
|
|||
return host_reg;
|
||||
}
|
||||
|
||||
static int LOAD_REG_IMM(uint32_t imm)
|
||||
{
|
||||
int host_reg = find_host_reg();
|
||||
host_reg_mapping[host_reg] = reg;
|
||||
|
||||
addbyte(0xc7); /*MOVL host_reg, imm*/
|
||||
addbyte(0xc0 | host_reg);
|
||||
addlong(imm);
|
||||
|
||||
return host_reg;
|
||||
}
|
||||
|
||||
static void STORE_REG_B_RELEASE(int host_reg)
|
||||
{
|
||||
addbyte(0x88); /*MOVB [reg],host_reg*/
|
||||
|
|
@ -284,3 +303,615 @@ static void CALL_FUNC(void *dest)
|
|||
addbyte(0xE8); /*CALL*/
|
||||
addlong(((uint8_t *)dest - (uint8_t *)(&codeblock[block_current].data[block_pos + 4])));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void CHECK_SEG_READ(x86seg *seg)
|
||||
{
|
||||
addbyte(0x83); /*CMP seg->base, -1*/
|
||||
addbyte(0x05|0x38);
|
||||
addlong((uint32_t)&seg->base);
|
||||
addbyte(-1);
|
||||
addbyte(0x0f);
|
||||
addbyte(0x84); /*JE end*/
|
||||
addlong(BLOCK_EXIT_OFFSET - (block_pos + 4));
|
||||
}
|
||||
static void CHECK_SEG_WRITE(x86seg *seg)
|
||||
{
|
||||
addbyte(0x83); /*CMP seg->base, -1*/
|
||||
addbyte(0x05|0x38);
|
||||
addlong((uint32_t)&seg->base);
|
||||
addbyte(-1);
|
||||
addbyte(0x0f);
|
||||
addbyte(0x84); /*JE end*/
|
||||
addlong(BLOCK_EXIT_OFFSET - (block_pos + 4));
|
||||
}
|
||||
static void CHECK_SEG_LIMITS(x86seg *seg, int end_offset)
|
||||
{
|
||||
addbyte(0x3b); /*CMP EAX, seg->limit_low*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t)&seg->limit_low);
|
||||
addbyte(0x0f); /*JB BLOCK_GPF_OFFSET*/
|
||||
addbyte(0x82);
|
||||
addlong(BLOCK_GPF_OFFSET - (block_pos + 4));
|
||||
if (end_offset)
|
||||
{
|
||||
addbyte(0x83); /*ADD EAX, end_offset*/
|
||||
addbyte(0xc0);
|
||||
addbyte(end_offset);
|
||||
addbyte(0x3b); /*CMP EAX, seg->limit_high*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t)&seg->limit_high);
|
||||
addbyte(0x0f); /*JNBE BLOCK_GPF_OFFSET*/
|
||||
addbyte(0x87);
|
||||
addlong(BLOCK_GPF_OFFSET - (block_pos + 4));
|
||||
addbyte(0x83); /*SUB EAX, end_offset*/
|
||||
addbyte(0xe8);
|
||||
addbyte(end_offset);
|
||||
}
|
||||
}
|
||||
|
||||
static void MEM_LOAD_ADDR_EA_B(x86seg *seg)
|
||||
{
|
||||
addbyte(0x8b); /*MOVL EDX, seg->base*/
|
||||
addbyte(0x05 | (REG_EDX << 3));
|
||||
addlong((uint32_t)&seg->base);
|
||||
addbyte(0x89); /*MOV ESI, EDX*/
|
||||
addbyte(0xd6);
|
||||
addbyte(0x01); /*ADDL EDX, EAX*/
|
||||
addbyte(0xc2);
|
||||
addbyte(0x89); /*MOV EDI, EDX*/
|
||||
addbyte(0xd7);
|
||||
addbyte(0xc1); /*SHR EDX, 12*/
|
||||
addbyte(0xea);
|
||||
addbyte(12);
|
||||
addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/
|
||||
addbyte(0x14);
|
||||
addbyte(0x95);
|
||||
addlong((uint32_t)readlookup2);
|
||||
addbyte(0x83); /*CMP EDX, -1*/
|
||||
addbyte(0xfa);
|
||||
addbyte(-1);
|
||||
addbyte(0x74); /*JE slowpath*/
|
||||
addbyte(3+2);
|
||||
addbyte(0x8a); /*MOV AL, [EDX+EDI]*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x3a);
|
||||
addbyte(0xeb); /*JMP done*/
|
||||
addbyte(4+3+5+7+6);
|
||||
addbyte(0x89); /*slowpath: MOV [ESP+4], EAX*/
|
||||
addbyte(0x44);
|
||||
addbyte(0x24);
|
||||
addbyte(0x04);
|
||||
addbyte(0x89); /*MOV [ESP], ESI*/
|
||||
addbyte(0x34);
|
||||
addbyte(0x24);
|
||||
addbyte(0xe8); /*CALL readmemb386l*/
|
||||
addlong((uint32_t)readmemb386l - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
|
||||
addbyte(0x83); /*CMP abrt, 0*/
|
||||
addbyte(0x3d);
|
||||
addlong((uint32_t)&abrt);
|
||||
addbyte(0);
|
||||
addbyte(0x0f); /*JNE end*/
|
||||
addbyte(0x85);
|
||||
addlong(BLOCK_EXIT_OFFSET - (block_pos + 4));
|
||||
/*done:*/
|
||||
addbyte(0x0f); /*MOVZX EAX, AL*/
|
||||
addbyte(0xb6);
|
||||
addbyte(0xc0);
|
||||
host_reg_mapping[0] = 8;
|
||||
}
|
||||
static void MEM_LOAD_ADDR_EA_W(x86seg *seg)
|
||||
{
|
||||
addbyte(0x8b); /*MOVL EDX, seg->base*/
|
||||
addbyte(0x05 | (REG_EDX << 3));
|
||||
addlong((uint32_t)&seg->base);
|
||||
addbyte(0x89); /*MOV ESI, EDX*/
|
||||
addbyte(0xd6);
|
||||
addbyte(0x01); /*ADDL EDX, EAX*/
|
||||
addbyte(0xc2);
|
||||
addbyte(0x89); /*MOV EDI, EDX*/
|
||||
addbyte(0xd7);
|
||||
addbyte(0x83); /*XOR EDI, -1*/
|
||||
addbyte(0xf7);
|
||||
addbyte(-1);
|
||||
addbyte(0xc1); /*SHR EDX, 12*/
|
||||
addbyte(0xea);
|
||||
addbyte(12);
|
||||
addbyte(0xf7); /*TEST EDI, 0xfff*/
|
||||
addbyte(0xc7);
|
||||
addlong(0xfff);
|
||||
addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/
|
||||
addbyte(0x14);
|
||||
addbyte(0x95);
|
||||
addlong((uint32_t)readlookup2);
|
||||
addbyte(0x74); /*JE slowpath*/
|
||||
addbyte(3+3+2+4+2);
|
||||
addbyte(0x83); /*XOR EDI, -1*/
|
||||
addbyte(0xf7);
|
||||
addbyte(-1);
|
||||
addbyte(0x83); /*CMP EDX, -1*/
|
||||
addbyte(0xfa);
|
||||
addbyte(-1);
|
||||
addbyte(0x74); /*JE slowpath*/
|
||||
addbyte(4+2);
|
||||
addbyte(0x66); /*MOV AX, [EDX+EDI]*/
|
||||
addbyte(0x8b);
|
||||
addbyte(0x04);
|
||||
addbyte(0x3a);
|
||||
addbyte(0xeb); /*JMP done*/
|
||||
addbyte(4+3+5+7+6);
|
||||
addbyte(0x89); /*slowpath: MOV [ESP+4], EAX*/
|
||||
addbyte(0x44);
|
||||
addbyte(0x24);
|
||||
addbyte(0x04);
|
||||
addbyte(0x89); /*MOV [ESP], ESI*/
|
||||
addbyte(0x34);
|
||||
addbyte(0x24);
|
||||
addbyte(0xe8); /*CALL readmemwl*/
|
||||
addlong((uint32_t)readmemwl - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
|
||||
addbyte(0x83); /*CMP abrt, 0*/
|
||||
addbyte(0x3d);
|
||||
addlong((uint32_t)&abrt);
|
||||
addbyte(0);
|
||||
addbyte(0x0f);
|
||||
addbyte(0x85); /*JNE end*/
|
||||
addlong(BLOCK_EXIT_OFFSET - (block_pos + 4));
|
||||
/*done:*/
|
||||
addbyte(0x0f); /*MOVZX EAX, AX*/
|
||||
addbyte(0xb7);
|
||||
addbyte(0xc0);
|
||||
host_reg_mapping[0] = 8;
|
||||
}
|
||||
static void MEM_LOAD_ADDR_EA_L(x86seg *seg)
|
||||
{
|
||||
addbyte(0x8b); /*MOVL EDX, seg->base*/
|
||||
addbyte(0x05 | (REG_EDX << 3));
|
||||
addlong((uint32_t)&seg->base);
|
||||
addbyte(0x89); /*MOV ESI, EDX*/
|
||||
addbyte(0xd6);
|
||||
addbyte(0x01); /*ADDL EDX, EAX*/
|
||||
addbyte(0xc2);
|
||||
addbyte(0x89); /*MOV EDI, EDX*/
|
||||
addbyte(0xd7);
|
||||
addbyte(0x83); /*XOR EDI, -1*/
|
||||
addbyte(0xf7);
|
||||
addbyte(-1);
|
||||
addbyte(0xc1); /*SHR EDX, 12*/
|
||||
addbyte(0xea);
|
||||
addbyte(12);
|
||||
addbyte(0xf7); /*TEST EDI, 0xffc*/
|
||||
addbyte(0xc7);
|
||||
addlong(0xffc);
|
||||
addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/
|
||||
addbyte(0x14);
|
||||
addbyte(0x95);
|
||||
addlong((uint32_t)readlookup2);
|
||||
addbyte(0x74); /*JE slowpath*/
|
||||
addbyte(3+3+2+3+2);
|
||||
addbyte(0x83); /*XOR EDI, -1*/
|
||||
addbyte(0xf7);
|
||||
addbyte(-1);
|
||||
addbyte(0x83); /*CMP EDX, -1*/
|
||||
addbyte(0xfa);
|
||||
addbyte(-1);
|
||||
addbyte(0x74); /*JE slowpath*/
|
||||
addbyte(3+2);
|
||||
addbyte(0x8b); /*MOV EAX, [EDX+EDI]*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x3a);
|
||||
addbyte(0xeb); /*JMP done*/
|
||||
addbyte(4+3+5+7+6);
|
||||
addbyte(0x89); /*slowpath: MOV [ESP+4], EAX*/
|
||||
addbyte(0x44);
|
||||
addbyte(0x24);
|
||||
addbyte(0x04);
|
||||
addbyte(0x89); /*MOV [ESP], ESI*/
|
||||
addbyte(0x34);
|
||||
addbyte(0x24);
|
||||
addbyte(0xe8); /*CALL readmemll*/
|
||||
addlong((uint32_t)readmemll - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
|
||||
addbyte(0x83); /*CMP abrt, 0*/
|
||||
addbyte(0x3d);
|
||||
addlong((uint32_t)&abrt);
|
||||
addbyte(0);
|
||||
addbyte(0x0f);
|
||||
addbyte(0x85); /*JNE end*/
|
||||
addlong(BLOCK_EXIT_OFFSET - (block_pos + 4));
|
||||
/*done:*/
|
||||
host_reg_mapping[0] = 8;
|
||||
}
|
||||
|
||||
static void MEM_LOAD_ADDR_IMM_B(x86seg *seg, uint32_t addr)
|
||||
{
|
||||
addbyte(0xb8); /*MOV EAX, addr*/
|
||||
addlong(addr);
|
||||
MEM_LOAD_ADDR_EA_B(seg);
|
||||
}
|
||||
static void MEM_LOAD_ADDR_IMM_W(x86seg *seg, uint32_t addr)
|
||||
{
|
||||
addbyte(0xb8); /*MOV EAX, addr*/
|
||||
addlong(addr);
|
||||
MEM_LOAD_ADDR_EA_W(seg);
|
||||
}
|
||||
static void MEM_LOAD_ADDR_IMM_L(x86seg *seg, uint32_t addr)
|
||||
{
|
||||
addbyte(0xb8); /*MOV EAX, addr*/
|
||||
addlong(addr);
|
||||
MEM_LOAD_ADDR_EA_L(seg);
|
||||
}
|
||||
|
||||
static void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg)
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ESI, seg->base*/
|
||||
addbyte(0x05 | (REG_ESI << 3));
|
||||
addlong((uint32_t)&seg->base);
|
||||
addbyte(0x01); /*ADDL ESI, EAX*/
|
||||
addbyte(0xc0 | (REG_EAX << 3) | REG_ESI);
|
||||
addbyte(0x89); /*MOV EDI, ESI*/
|
||||
addbyte(0xc0 | (REG_ESI << 3) | REG_EDI);
|
||||
addbyte(0xc1); /*SHR ESI, 12*/
|
||||
addbyte(0xe8 | REG_ESI);
|
||||
addbyte(12);
|
||||
addbyte(0xf7); /*TEST EDI, 0xfff*/
|
||||
addbyte(0xc7);
|
||||
addlong(0xfff);
|
||||
addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/
|
||||
addbyte(0x04 | (REG_ESI << 3));
|
||||
addbyte(0x85 | (REG_ESI << 3));
|
||||
addlong((uint32_t)writelookup2);
|
||||
addbyte(0x83); /*CMP ESI, -1*/
|
||||
addbyte(0xf8 | REG_ESI);
|
||||
addbyte(-1);
|
||||
addbyte(0x74); /*JE slowpath*/
|
||||
addbyte(3+2);
|
||||
addbyte(0x88); /*MOV [EDI+ESI],host_reg*/
|
||||
addbyte(0x04 | (host_reg << 3));
|
||||
addbyte(REG_EDI | (REG_ESI << 3));
|
||||
addbyte(0xeb); /*JMP done*/
|
||||
addbyte(4+5+4+3+5+7+6);
|
||||
addbyte(0x89); /*slowpath: MOV [ESP+4], EAX*/
|
||||
addbyte(0x44);
|
||||
addbyte(0x24);
|
||||
addbyte(0x04);
|
||||
addbyte(0xa1); /*MOV EAX, seg->base*/
|
||||
addlong((uint32_t)&seg->base);
|
||||
addbyte(0x89); /*MOV [ESP+8], host_reg*/
|
||||
addbyte(0x44 | (host_reg << 3));
|
||||
addbyte(0x24);
|
||||
addbyte(0x08);
|
||||
addbyte(0x89); /*MOV [ESP], EAX*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x24);
|
||||
addbyte(0xe8); /*CALL writememb386l*/
|
||||
addlong((uint32_t)writememb386l - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
|
||||
addbyte(0x83); /*CMP abrt, 0*/
|
||||
addbyte(0x3d);
|
||||
addlong((uint32_t)&abrt);
|
||||
addbyte(0);
|
||||
addbyte(0x0f); /*JNE end*/
|
||||
addbyte(0x85);
|
||||
addlong(BLOCK_EXIT_OFFSET - (block_pos + 4));
|
||||
/*done:*/
|
||||
}
|
||||
static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg)
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ESI, seg->base*/
|
||||
addbyte(0x05 | (REG_ESI << 3));
|
||||
addlong((uint32_t)&seg->base);
|
||||
addbyte(0x01); /*ADDL ESI, EAX*/
|
||||
addbyte(0xc0 | (REG_EAX << 3) | REG_ESI);
|
||||
addbyte(0x89); /*MOV EDI, ESI*/
|
||||
addbyte(0xc0 | (REG_ESI << 3) | REG_EDI);
|
||||
addbyte(0x83); /*XOR EDI, -1*/
|
||||
addbyte(0xf7);
|
||||
addbyte(-1);
|
||||
addbyte(0xc1); /*SHR ESI, 12*/
|
||||
addbyte(0xe8 | REG_ESI);
|
||||
addbyte(12);
|
||||
addbyte(0xf7); /*TEST EDI, 0xfff*/
|
||||
addbyte(0xc7);
|
||||
addlong(0xfff);
|
||||
addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/
|
||||
addbyte(0x04 | (REG_ESI << 3));
|
||||
addbyte(0x85 | (REG_ESI << 3));
|
||||
addlong((uint32_t)writelookup2);
|
||||
addbyte(0x74); /*JE slowpath*/
|
||||
addbyte(3+3+2+4+2);
|
||||
addbyte(0x83); /*XOR EDI, -1*/
|
||||
addbyte(0xf7);
|
||||
addbyte(-1);
|
||||
addbyte(0x83); /*CMP ESI, -1*/
|
||||
addbyte(0xf8 | REG_ESI);
|
||||
addbyte(-1);
|
||||
addbyte(0x74); /*JE slowpath*/
|
||||
addbyte(4+2);
|
||||
addbyte(0x66); /*MOV [EDI+ESI],host_reg*/
|
||||
addbyte(0x89);
|
||||
addbyte(0x04 | (host_reg << 3));
|
||||
addbyte(REG_EDI | (REG_ESI << 3));
|
||||
addbyte(0xeb); /*JMP done*/
|
||||
addbyte(4+5+4+3+5+7+6);
|
||||
addbyte(0x89); /*slowpath: MOV [ESP+4], EAX*/
|
||||
addbyte(0x44);
|
||||
addbyte(0x24);
|
||||
addbyte(0x04);
|
||||
addbyte(0xa1); /*MOV EAX, seg->base*/
|
||||
addlong((uint32_t)&seg->base);
|
||||
addbyte(0x89); /*MOV [ESP+8], host_reg*/
|
||||
addbyte(0x44 | (host_reg << 3));
|
||||
addbyte(0x24);
|
||||
addbyte(0x08);
|
||||
addbyte(0x89); /*MOV [ESP], EAX*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x24);
|
||||
addbyte(0xe8); /*CALL writememwl*/
|
||||
addlong((uint32_t)writememwl - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
|
||||
addbyte(0x83); /*CMP abrt, 0*/
|
||||
addbyte(0x3d);
|
||||
addlong((uint32_t)&abrt);
|
||||
addbyte(0);
|
||||
addbyte(0x0f); /*JNE end*/
|
||||
addbyte(0x85);
|
||||
addlong(BLOCK_EXIT_OFFSET - (block_pos + 4));
|
||||
/*done:*/
|
||||
}
|
||||
static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg)
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ESI, seg->base*/
|
||||
addbyte(0x05 | (REG_ESI << 3));
|
||||
addlong((uint32_t)&seg->base);
|
||||
addbyte(0x01); /*ADDL ESI, EAX*/
|
||||
addbyte(0xc0 | (REG_EAX << 3) | REG_ESI);
|
||||
addbyte(0x89); /*MOV EDI, ESI*/
|
||||
addbyte(0xc0 | (REG_ESI << 3) | REG_EDI);
|
||||
addbyte(0x83); /*XOR EDI, -1*/
|
||||
addbyte(0xf7);
|
||||
addbyte(-1);
|
||||
addbyte(0xc1); /*SHR ESI, 12*/
|
||||
addbyte(0xe8 | REG_ESI);
|
||||
addbyte(12);
|
||||
addbyte(0xf7); /*TEST EDI, 0xffc*/
|
||||
addbyte(0xc7);
|
||||
addlong(0xffc);
|
||||
addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/
|
||||
addbyte(0x04 | (REG_ESI << 3));
|
||||
addbyte(0x85 | (REG_ESI << 3));
|
||||
addlong((uint32_t)writelookup2);
|
||||
addbyte(0x74); /*JE slowpath*/
|
||||
addbyte(3+3+2+3+2);
|
||||
addbyte(0x83); /*XOR EDI, -1*/
|
||||
addbyte(0xf7);
|
||||
addbyte(-1);
|
||||
addbyte(0x83); /*CMP ESI, -1*/
|
||||
addbyte(0xf8 | REG_ESI);
|
||||
addbyte(-1);
|
||||
addbyte(0x74); /*JE slowpath*/
|
||||
addbyte(3+2);
|
||||
addbyte(0x89); /*MOV [EDI+ESI],host_reg*/
|
||||
addbyte(0x04 | (host_reg << 3));
|
||||
addbyte(REG_EDI | (REG_ESI << 3));
|
||||
addbyte(0xeb); /*JMP done*/
|
||||
addbyte(4+5+4+3+5+7+6);
|
||||
addbyte(0x89); /*slowpath: MOV [ESP+4], EAX*/
|
||||
addbyte(0x44);
|
||||
addbyte(0x24);
|
||||
addbyte(0x04);
|
||||
addbyte(0xa1); /*MOV EAX, seg->base*/
|
||||
addlong((uint32_t)&seg->base);
|
||||
addbyte(0x89); /*MOV [ESP+8], host_reg*/
|
||||
addbyte(0x44 | (host_reg << 3));
|
||||
addbyte(0x24);
|
||||
addbyte(0x08);
|
||||
addbyte(0x89); /*MOV [ESP], EAX*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x24);
|
||||
addbyte(0xe8); /*CALL writememll*/
|
||||
addlong((uint32_t)writememll - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
|
||||
addbyte(0x83); /*CMP abrt, 0*/
|
||||
addbyte(0x3d);
|
||||
addlong((uint32_t)&abrt);
|
||||
addbyte(0);
|
||||
addbyte(0x0f); /*JNE end*/
|
||||
addbyte(0x85);
|
||||
addlong(BLOCK_EXIT_OFFSET - (block_pos + 4));
|
||||
/*done:*/
|
||||
}
|
||||
|
||||
static void MEM_STORE_ADDR_IMM_B(x86seg *seg, uint32_t addr, int host_reg)
|
||||
{
|
||||
addbyte(0xb8); /*MOV EAX, addr*/
|
||||
addlong(addr);
|
||||
MEM_STORE_ADDR_EA_B(seg, host_reg);
|
||||
}
|
||||
static void MEM_STORE_ADDR_IMM_L(x86seg *seg, uint32_t addr, int host_reg)
|
||||
{
|
||||
addbyte(0xb8); /*MOV EAX, addr*/
|
||||
addlong(addr);
|
||||
MEM_STORE_ADDR_EA_L(seg, host_reg);
|
||||
}
|
||||
static void MEM_STORE_ADDR_IMM_W(x86seg *seg, uint32_t addr, int host_reg)
|
||||
{
|
||||
addbyte(0xb8); /*MOV EAX, addr*/
|
||||
addlong(addr);
|
||||
MEM_STORE_ADDR_EA_W(seg, host_reg);
|
||||
}
|
||||
|
||||
|
||||
static x86seg *FETCH_EA_16(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc)
|
||||
{
|
||||
int mod = (fetchdat >> 6) & 3;
|
||||
int reg = (fetchdat >> 3) & 7;
|
||||
int rm = fetchdat & 7;
|
||||
if (!mod && rm == 6)
|
||||
{
|
||||
addbyte(0xb8); /*MOVL EAX, imm16*/
|
||||
addlong((fetchdat >> 8) & 0xffff);
|
||||
(*op_pc) += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (mod)
|
||||
{
|
||||
case 0:
|
||||
addbyte(0xa1); /*MOVL EAX, *mod1add[0][rm]*/
|
||||
addlong((uint32_t)mod1add[0][rm]);
|
||||
addbyte(0x03); /*ADDL EAX, *mod1add[1][rm]*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t)mod1add[1][rm]);
|
||||
break;
|
||||
case 1:
|
||||
addbyte(0xb8); /*MOVL EAX, imm8*/
|
||||
addlong((uint32_t)(int8_t)(rmdat >> 8));// pc++;
|
||||
addbyte(0x03); /*ADDL EAX, *mod1add[0][rm]*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t)mod1add[0][rm]);
|
||||
addbyte(0x03); /*ADDL EAX, *mod1add[1][rm]*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t)mod1add[1][rm]);
|
||||
(*op_pc)++;
|
||||
break;
|
||||
case 2:
|
||||
addbyte(0xb8); /*MOVL EAX, imm16*/
|
||||
addlong((fetchdat >> 8) & 0xffff);// pc++;
|
||||
addbyte(0x03); /*EAX, ADDL *mod1add[0][rm]*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t)mod1add[0][rm]);
|
||||
addbyte(0x03); /*EAX, ADDL *mod1add[1][rm]*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t)mod1add[1][rm]);
|
||||
(*op_pc) += 2;
|
||||
break;
|
||||
}
|
||||
addbyte(0x25); /*ANDL EAX, 0xffff*/
|
||||
addlong(0xffff);
|
||||
|
||||
if (mod1seg[rm] == &ss && !op_ssegs)
|
||||
op_ea_seg = &_ss;
|
||||
}
|
||||
return op_ea_seg;
|
||||
}
|
||||
|
||||
static x86seg *FETCH_EA_32(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset)
|
||||
{
|
||||
uint32_t new_eaaddr;
|
||||
int mod = (fetchdat >> 6) & 3;
|
||||
int reg = (fetchdat >> 3) & 7;
|
||||
int rm = fetchdat & 7;
|
||||
|
||||
if (rm == 4)
|
||||
{
|
||||
uint8_t sib = fetchdat >> 8;
|
||||
(*op_pc)++;
|
||||
|
||||
switch (mod)
|
||||
{
|
||||
case 0:
|
||||
if ((sib & 7) == 5)
|
||||
{
|
||||
new_eaaddr = fastreadl(cs + (*op_pc) + 1);
|
||||
addbyte(0xb8); /*MOVL EAX, imm32*/
|
||||
addlong(new_eaaddr);// pc++;
|
||||
(*op_pc) += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0xa1); /*MOVL EAX, regs[sib&7].l*/
|
||||
addlong((uint32_t)®s[sib & 7].l);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
new_eaaddr = (uint32_t)(int8_t)((fetchdat >> 16) & 0xff);
|
||||
addbyte(0xb8); /*MOVL EAX, imm8*/
|
||||
addlong(new_eaaddr);
|
||||
addbyte(0x03); /*ADDL EAX, regs[sib&7].l*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t)®s[sib & 7].l);
|
||||
(*op_pc)++;
|
||||
break;
|
||||
case 2:
|
||||
new_eaaddr = fastreadl(cs + (*op_pc) + 1);
|
||||
addbyte(0xb8); /*MOVL EAX, new_eaaddr*/
|
||||
addlong(new_eaaddr);
|
||||
addbyte(0x03); /*ADDL EAX, regs[sib&7].l*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t)®s[sib & 7].l);
|
||||
(*op_pc) += 4;
|
||||
break;
|
||||
}
|
||||
if (stack_offset && (sib & 7) == 4 && (mod || (sib & 7) != 5)) /*ESP*/
|
||||
{
|
||||
addbyte(0x05); /*ADDL EAX, stack_offset*/
|
||||
addlong(stack_offset);
|
||||
}
|
||||
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 EAX, regs[sib&7].l*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t)®s[(sib >> 3) & 7].l);
|
||||
break;
|
||||
case 1:
|
||||
addbyte(0x8B); addbyte(0x05 | (REG_EDI << 3)); addlong((uint32_t)®s[(sib >> 3) & 7].l); /*MOVL EDI, reg*/
|
||||
addbyte(0x01); addbyte(0xc0 | REG_EAX | (REG_EDI << 3)); /*ADDL EAX, EDI*/
|
||||
addbyte(0x01); addbyte(0xc0 | REG_EAX | (REG_EDI << 3)); /*ADDL EAX, EDI*/
|
||||
break;
|
||||
case 2:
|
||||
addbyte(0x8B); addbyte(0x05 | (REG_EDI << 3)); addlong((uint32_t)®s[(sib >> 3) & 7].l); /*MOVL EDI, reg*/
|
||||
addbyte(0xC1); addbyte(0xE0 | REG_EDI); addbyte(2); /*SHL EDI, 2*/
|
||||
addbyte(0x01); addbyte(0xc0 | REG_EAX | (REG_EDI << 3)); /*ADDL EAX, EDI*/
|
||||
break;
|
||||
case 3:
|
||||
addbyte(0x8B); addbyte(0x05 | (REG_EDI << 3)); addlong((uint32_t)®s[(sib >> 3) & 7].l); /*MOVL EDI reg*/
|
||||
addbyte(0xC1); addbyte(0xE0 | REG_EDI); addbyte(3); /*SHL EDI, 3*/
|
||||
addbyte(0x01); addbyte(0xc0 | REG_EAX | (REG_EDI << 3)); /*ADDL EAX, EDI*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!mod && rm == 5)
|
||||
{
|
||||
new_eaaddr = fastreadl(cs + (*op_pc) + 1);
|
||||
addbyte(0xb8); /*MOVL EAX, imm32*/
|
||||
addlong(new_eaaddr);
|
||||
(*op_pc) += 4;
|
||||
return op_ea_seg;
|
||||
}
|
||||
addbyte(0xa1); /*MOVL EAX, regs[rm].l*/
|
||||
addlong((uint32_t)®s[rm].l);
|
||||
eaaddr = regs[rm].l;
|
||||
if (mod)
|
||||
{
|
||||
if (rm == 5 && !op_ssegs)
|
||||
op_ea_seg = &_ss;
|
||||
if (mod == 1)
|
||||
{
|
||||
addbyte(0x05); /*ADD EAX, imm8*/
|
||||
addlong((uint32_t)(int8_t)(fetchdat >> 8));
|
||||
(*op_pc)++;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_eaaddr = fastreadl(cs + (*op_pc) + 1);
|
||||
addbyte(0x05); /*ADD EAX, imm32*/
|
||||
addlong(new_eaaddr);
|
||||
(*op_pc) += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
return op_ea_seg;
|
||||
}
|
||||
|
||||
static x86seg *FETCH_EA(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32)
|
||||
{
|
||||
if (op_32 & 0x200)
|
||||
return FETCH_EA_32(op_ea_seg, fetchdat, op_ssegs, op_pc, 0);
|
||||
return FETCH_EA_16(op_ea_seg, fetchdat, op_ssegs, op_pc);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue