2013-12-19 17:10:14 +00:00
|
|
|
|
|
|
|
//included on x86_emitter.cpp
|
|
|
|
|
|
|
|
/*
|
|
|
|
enum x86_op_params
|
|
|
|
{
|
|
|
|
param_none,
|
|
|
|
param_reg,
|
|
|
|
param_mem,
|
|
|
|
param_imm,
|
|
|
|
|
|
|
|
param_reg_reg,
|
|
|
|
param_reg_mem,
|
|
|
|
param_reg_imm,
|
|
|
|
|
|
|
|
param_mem_reg,
|
|
|
|
param_mem_imm,
|
|
|
|
};
|
|
|
|
*/
|
|
|
|
|
|
|
|
encoded_type pg_none = {pg_NONE};
|
|
|
|
|
2015-05-08 16:59:20 +00:00
|
|
|
encoded_type param_type(x86_Label* lbl)
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
|
|
|
encoded_type rv;
|
|
|
|
//Return pg_MEM_Rel32/pg_MEM_Rel16/pg_MEM_Rel8
|
|
|
|
//we do need some more info on this :P
|
|
|
|
if (lbl->patch_sz==8)
|
|
|
|
rv.type=pg_MEM_Rel8;
|
|
|
|
else
|
|
|
|
rv.type=pg_MEM_Rel32;
|
|
|
|
rv.ptr=lbl;
|
|
|
|
rv.ptr_type=1;
|
|
|
|
return rv;
|
|
|
|
}
|
2015-05-08 16:59:20 +00:00
|
|
|
encoded_type param_type(x86_ptr_imm ptr)
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
|
|
|
encoded_type rv;
|
|
|
|
//Return pg_MEM_Rel32.Due to relocation we cant optimise to 16/8 in one pass ...
|
|
|
|
//we do need some more info on this :P
|
|
|
|
rv.type=pg_MEM_Rel32;
|
|
|
|
rv.ptr=ptr.ptr;
|
|
|
|
rv.ptr_type=0;
|
|
|
|
return rv;
|
|
|
|
}
|
2015-05-08 16:59:20 +00:00
|
|
|
encoded_type param_type(x86_mrm_t& modrm)
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
|
|
|
encoded_type rv;
|
|
|
|
rv.modrm=modrm;
|
|
|
|
//Return reg , mem cmplx , mem direct
|
|
|
|
rv.type=pg_ModRM;
|
|
|
|
return rv;
|
|
|
|
}
|
2015-05-08 16:59:20 +00:00
|
|
|
encoded_type param_type(x86_reg reg)
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
|
|
|
encoded_type rv;
|
|
|
|
rv.reg=REG_ID(reg);
|
|
|
|
//later : detect R0 :)
|
|
|
|
if (reg==EAX ||reg==AX ||reg==AL)
|
|
|
|
rv.type=pg_R0;
|
|
|
|
else if (reg==CL || reg==ECX)
|
|
|
|
rv.type=pg_CL;
|
|
|
|
else
|
|
|
|
rv.type=pg_REG;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2015-05-08 16:59:20 +00:00
|
|
|
encoded_type param_type(u32 imm)
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
|
|
|
encoded_type rv;
|
|
|
|
rv.imm=imm;
|
|
|
|
//later : detect u8/s8/s16/s32 encodings :)
|
|
|
|
|
|
|
|
if (IsS8(imm))
|
|
|
|
rv.type=pg_IMM_S8;
|
|
|
|
else if ((imm & (~0xFF))==0)
|
|
|
|
rv.type=pg_IMM_U8;
|
|
|
|
else if ((imm & (~0xFFFF))==0)
|
|
|
|
rv.type=pg_IMM_U16;
|
|
|
|
else
|
|
|
|
rv.type=pg_IMM_U32;
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
2015-05-08 16:59:20 +00:00
|
|
|
void Match_opcode(x86_block* block,const x86_opcode* ops,encoded_type pg1,encoded_type pg2,encoded_type pg3)
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
|
|
|
block->opcode_count++;
|
|
|
|
const x86_opcode* match=0;
|
|
|
|
for (u32 i=0;ops[i].encode!=0;i++)
|
|
|
|
{
|
|
|
|
if (ENC_PARAM_CONTAINS(ops[i].pg_1,pg1.type) &&
|
|
|
|
ENC_PARAM_CONTAINS(ops[i].pg_2,pg2.type) &&
|
|
|
|
ENC_PARAM_CONTAINS(ops[i].pg_3,pg3.type)
|
|
|
|
)
|
|
|
|
{
|
|
|
|
match= &ops[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (match==0)
|
|
|
|
{
|
|
|
|
char temp[512];
|
|
|
|
sprintf(temp,"Unable to match opcode %s",DissasmClass(ops->opcode));
|
|
|
|
die(temp);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// printf("Matched opcode %s to %s\n",DissasmClass(ops->opcode),DissasmClass(match->opcode));
|
|
|
|
match->encode(block,match,&pg1,&pg2,pg3.imm);
|
|
|
|
}
|
|
|
|
|
|
|
|
#define ME_op_0(opcl) Match_opcode(this,x86_opcode_list[opcl], pg_none, pg_none, pg_none)
|
|
|
|
|
|
|
|
#define ME_op_1_nrm(opcl, pg1) Match_opcode(this,x86_opcode_list[opcl], param_type(pg1), pg_none, pg_none)
|
|
|
|
#define ME_op_1_imm(opcl, pg1) Match_opcode(this,x86_opcode_list[opcl], pg_none, pg_none, param_type(pg1))
|
|
|
|
|
|
|
|
#define ME_op_2_nrm(opcl, pg1, pg2) Match_opcode(this,x86_opcode_list[opcl], param_type(pg1), param_type(pg2), pg_none)
|
|
|
|
#define ME_op_2_imm(opcl, pg1, pg2) Match_opcode(this,x86_opcode_list[opcl], param_type(pg1), pg_none,param_type(pg2))
|
|
|
|
|
|
|
|
#define ME_op_3_nrm(opcl, pg1, pg2, pg3) Match_opcode(this,x86_opcode_list[opcl], param_type(pg1), param_type(pg2), param_type(pg3))
|
|
|
|
#define ME_op_3_imm(opcl, pg1, pg2, pg3) Match_opcode(this,x86_opcode_list[opcl], param_type(pg1), param_type(pg2), param_type(pg3))
|