flycast/core/emitter/x86_matcher.h

120 lines
2.9 KiB
C
Raw Normal View History

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))