Pairing and other asm optimizations

made ungen_opcodes.h Compile

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40130
This commit is contained in:
Borja Ferrer 2006-10-20 23:03:16 +00:00
parent 0c67ad1e7d
commit 2f9a5a224e
6 changed files with 112 additions and 65 deletions

View File

@ -253,13 +253,14 @@ inline void WriteOp_Proc(JitWriter *jit)
IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_STK, AMX_REG_TMP, -4);
IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 8, MOD_REG);
//save frame:
//:TODO: move to a temp reg, subtract and then move to mem, faster??
//mov [esi+frm], edi - get new frame
//mov ecx, edi - get new frame
//mov ebx, edi - store frame back
//sub [esi+frm], ebp - relocate local frame
IA32_Mov_Rm_Reg(jit, AMX_REG_INFO, AMX_REG_STK, MOD_MEM_REG);
//sub ecx, ebp - relocate local frame
//mov [esi+frm], ecx
IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_STK, MOD_REG);
IA32_Mov_Reg_Rm(jit, AMX_REG_FRM, AMX_REG_STK, MOD_REG);
IA32_Sub_Rm_Reg(jit, AMX_REG_INFO, AMX_REG_DAT, MOD_MEM_REG);
IA32_Sub_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_DAT, MOD_REG);
IA32_Mov_Rm_Reg(jit, AMX_REG_INFO, AMX_REG_TMP, MOD_MEM_REG);
}
inline void WriteOp_Lidx_B(JitWriter *jit)
@ -888,17 +889,19 @@ inline void WriteOp_Swap_Alt(JitWriter *jit)
inline void WriteOp_PushAddr(JitWriter *jit)
{
//mov ecx, [esi+frm] ;get address (offset from frame)
//add ecx, <val>
//mov [edi-4], ecx
//sub edi, 4
//add ecx, <val>
//mov [edi], ecx
cell_t val = jit->read_cell();
IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_INFO, MOD_MEM_REG);
if (val < SCHAR_MAX && val > SCHAR_MIN)
IA32_Add_Rm_Imm8(jit, AMX_REG_TMP, (jit_int8_t)val, MOD_REG);
else
IA32_Add_Rm_Imm32(jit, AMX_REG_TMP, val, MOD_REG);
IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_STK, AMX_REG_TMP, -4);
IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG);
if (val < SCHAR_MAX && val > SCHAR_MIN)
{
IA32_Add_Rm_Imm8(jit, AMX_REG_TMP, (jit_int8_t)val, MOD_REG);
} else {
IA32_Add_Rm_Imm32(jit, AMX_REG_TMP, val, MOD_REG);
}
IA32_Mov_Rm_Reg(jit, AMX_REG_STK, AMX_REG_TMP, MOD_MEM_REG);
}
inline void WriteOp_Movs(JitWriter *jit)
@ -1217,7 +1220,12 @@ inline void WriteOp_Bounds(JitWriter *jit)
//cmp eax, <val>
//ja :error
IA32_Cmp_Rm_Imm32(jit, MOD_REG, AMX_REG_PRI, val);
if (val < SCHAR_MAX && val > SCHAR_MIN)
{
IA32_Cmp_Rm_Imm8(jit, MOD_REG, AMX_REG_PRI, (jit_int8_t)val);
} else {
IA32_Cmp_Eax_Imm32(jit, val);
}
IA32_Jump_Cond_Imm32_Abs(jit, CC_A, ((CompData *)jit->data)->jit_error_bounds);
}
@ -1405,9 +1413,9 @@ inline void WriteOp_Switch(JitWriter *jit)
* ECX still has the correctly bound offset in it, luckily!
* thus, we simply need to relocate ECX and store the cases.
*/
//shl ecx, 2
//lea ecx, [ecx*4]
//add ecx, <case table start>
IA32_Shl_Rm_Imm8(jit, AMX_REG_TMP, 2, MOD_REG);
IA32_Lea_Reg_RegMultImm32(jit, AMX_REG_TMP, AMX_REG_TMP, SCALE4, 0);
jitoffs_t tbl_offs = IA32_Add_Rm_Imm32_Later(jit, AMX_REG_TMP, MOD_REG);
IA32_Jump_Rm(jit, AMX_REG_TMP, MOD_MEM_REG);
/* The case table starts here. Go back and write the output pointer. */
@ -1472,7 +1480,7 @@ inline void WriteOp_Sysreq_C(JitWriter *jit)
}
//mov ecx, <native_index>
IA32_Mov_Rm_Imm32(jit, REG_ECX, native_index, MOD_REG);
IA32_Mov_Reg_Imm32(jit, REG_ECX, native_index);
jitoffs_t call = IA32_Call_Imm32(jit, 0);
IA32_Write_Jump32(jit, call, ((CompData *)jit->data)->jit_sysreq_c);
@ -1494,8 +1502,8 @@ inline void WriteOp_Sysreq_N_NoInline(JitWriter *jit)
//mov eax, <num_params>
//mov ecx, <native_index>
IA32_Mov_Rm_Imm32(jit, REG_EAX, num_params, MOD_REG);
IA32_Mov_Rm_Imm32(jit, REG_ECX, native_index, MOD_REG);
IA32_Mov_Reg_Imm32(jit, REG_EAX, num_params);
IA32_Mov_Reg_Imm32(jit, REG_ECX, native_index);
jitoffs_t call = IA32_Call_Imm32(jit, 0);
IA32_Write_Jump32(jit, call, ((CompData *)jit->data)->jit_sysreq_n);
@ -1528,27 +1536,31 @@ inline void WriteOp_Sysreq_N(JitWriter *jit)
//push edi ; stack
//push <native> ; native index
IA32_Push_Reg(jit, AMX_REG_STK);
if (native_index < SCHAR_MAX && native_index > SCHAR_MIN)
{
IA32_Push_Imm8(jit, (jit_int8_t)native_index);
} else {
IA32_Push_Imm32(jit, native_index);
}
/* Relocate stack, heap, frm information, then store back */
//sub edi, ebp
//mov ecx, [esi+hea]
//mov eax, [esi+context]
//mov ecx, [esi+hea]
//sub edi, ebp
//mov [eax+hp], ecx
//mov ecx, [esi]
//mov [eax+sp], edi
//mov ecx, [esi+frm]
//mov [eax+frm], ecx
IA32_Sub_Rm_Reg(jit, AMX_REG_STK, AMX_REG_DAT, MOD_REG);
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_HEAP);
IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, AMX_REG_INFO, AMX_INFO_CONTEXT);
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_HEAP);
IA32_Sub_Reg_Rm(jit, AMX_REG_STK, AMX_REG_DAT, MOD_REG);
IA32_Mov_Rm_Reg_Disp8(jit, REG_EAX, AMX_REG_TMP, offsetof(sp_context_t, hp));
IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_INFO_FRM, MOD_MEM_REG);
IA32_Mov_Rm_Reg_Disp8(jit, REG_EAX, AMX_REG_STK, offsetof(sp_context_t, sp));
IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_INFO_FRM, MOD_REG);
IA32_Mov_Rm_Reg_Disp8(jit, REG_EAX, AMX_REG_TMP, offsetof(sp_context_t, frm));
/* finally, push the last parameter and make the call */
//push eax ; context
//mov eax, [eax+context]
//call NativeCallback
IA32_Push_Reg(jit, REG_EAX);
jitoffs_t call = IA32_Call_Imm32(jit, 0);
@ -1564,7 +1576,7 @@ inline void WriteOp_Sysreq_N(JitWriter *jit)
//cmp [ecx+err], 0
//jnz :error
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_CONTEXT);
IA32_Cmp_Rm_Imm32_Disp8(jit, AMX_REG_TMP, offsetof(sp_context_t, err), 0);
IA32_Cmp_Rm_Disp8_Imm8(jit, AMX_REG_TMP, offsetof(sp_context_t, err), 0);
IA32_Jump_Cond_Imm32_Abs(jit, CC_NZ, data->jit_extern_error);
/* restore what we damaged */
@ -1572,7 +1584,7 @@ inline void WriteOp_Sysreq_N(JitWriter *jit)
//add edi, ebp
//pop edx
IA32_Add_Rm_Imm8(jit, REG_ESP, 4*3, MOD_REG);
IA32_Add_Rm_Reg(jit, AMX_REG_STK, AMX_REG_DAT, MOD_REG);
IA32_Add_Reg_Rm(jit, AMX_REG_STK, AMX_REG_DAT, MOD_REG);
IA32_Pop_Reg(jit, AMX_REG_ALT);
/* pop the stack. do not check the margins.

View File

@ -74,7 +74,6 @@ jitoffs_t RelocLookup(JitWriter *jit, cell_t pcode_offs, bool relative=false);
#define AMX_INFO_RETVAL 8 //physical
#define AMX_INFO_CONTEXT 12 //physical
#define AMX_INFO_STACKTOP 16 //relocated
#define AMX_INFO_STACKTOP_U 20 //not relocated
extern ISourcePawnEngine *engine;

View File

@ -4,7 +4,7 @@
#include "opcode_helpers.h"
#include "x86_macros.h"
#define NUM_INFO_PARAMS 6
#define NUM_INFO_PARAMS 5
jitoffs_t Write_Execute_Function(JitWriter *jit)
{
@ -63,11 +63,9 @@ jitoffs_t Write_Execute_Function(JitWriter *jit)
/* Info memory setup */
//mov ecx, [eax+<offs>] - copy memsize to temp var
//mov [esi+x], ecx - store unrelocated
//add ecx, ebp - relocate
//mov [esi+x], ecx - store relocated
IA32_Mov_Reg_Rm_Disp8(jit, REG_ECX, REG_EAX, offsetof(sp_context_t, memory));
IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, REG_ECX, AMX_INFO_STACKTOP_U);
IA32_Add_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_DAT, MOD_REG);
IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, REG_ECX, AMX_INFO_STACKTOP);
@ -277,9 +275,9 @@ void Write_Check_VerifyAddr(JitWriter *jit, jit_uint8_t reg)
*/
/* Part 1: Check if we're in the memory bounds */
//cmp <reg>, [esi+info.stpu]
//cmp <reg>, <stpu>
//jae :error
IA32_Cmp_Reg_Rm_Disp8(jit, reg, AMX_REG_INFO, AMX_INFO_STACKTOP_U);
IA32_Cmp_Rm_Imm32(jit, MOD_REG, reg, ((CompData *)jit->data)->plugin->memory);
IA32_Jump_Cond_Imm32_Abs(jit, CC_AE, ((CompData *)jit->data)->jit_error_memaccess);
/* Part 2: Check if we're in the invalid region between HP and SP */
@ -404,19 +402,19 @@ void WriteOp_Sysreq_C_Function(JitWriter *jit)
IA32_Push_Reg(jit, REG_ECX);
/* Relocate stack, heap, frm information, then store back */
//sub edi, ebp
//mov ecx, [esi+hea]
//mov eax, [esi+context]
//mov ecx, [esi+hea]
//sub edi, ebp
//mov [eax+hp], ecx
//mov ecx, [esi]
//mov [eax+sp], edi
//mov ecx, [esi+frm]
//mov [eax+frm], ecx
IA32_Sub_Rm_Reg(jit, AMX_REG_STK, AMX_REG_DAT, MOD_REG);
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_HEAP);
IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, AMX_REG_INFO, AMX_INFO_CONTEXT);
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_HEAP);
IA32_Sub_Reg_Rm(jit, AMX_REG_STK, AMX_REG_DAT, MOD_REG);
IA32_Mov_Rm_Reg_Disp8(jit, REG_EAX, AMX_REG_TMP, offsetof(sp_context_t, hp));
IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_INFO_FRM, MOD_MEM_REG);
IA32_Mov_Rm_Reg_Disp8(jit, REG_EAX, AMX_REG_STK, offsetof(sp_context_t, sp));
IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_INFO_FRM, MOD_REG);
IA32_Mov_Rm_Reg_Disp8(jit, REG_EAX, AMX_REG_TMP, offsetof(sp_context_t, frm));
/* finally, push the last parameter and make the call */
@ -436,7 +434,7 @@ void WriteOp_Sysreq_C_Function(JitWriter *jit)
//cmp [ecx+err], 0
//jnz :error
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_CONTEXT);
IA32_Cmp_Rm_Imm32_Disp8(jit, AMX_REG_TMP, offsetof(sp_context_t, err), 0);
IA32_Cmp_Rm_Disp8_Imm8(jit, AMX_REG_TMP, offsetof(sp_context_t, err), 0);
IA32_Jump_Cond_Imm32_Abs(jit, CC_NZ, data->jit_extern_error);
/* restore what we damaged */
@ -444,7 +442,7 @@ void WriteOp_Sysreq_C_Function(JitWriter *jit)
//add edi, ebp
//pop edx
IA32_Add_Rm_Imm8(jit, REG_ESP, 4*3, MOD_REG);
IA32_Add_Rm_Reg(jit, AMX_REG_STK, AMX_REG_DAT, MOD_REG);
IA32_Add_Reg_Rm(jit, AMX_REG_STK, AMX_REG_DAT, MOD_REG);
IA32_Pop_Reg(jit, AMX_REG_ALT);
//ret
@ -633,19 +631,19 @@ void WriteOp_Sysreq_N_Function(JitWriter *jit)
IA32_Push_Reg(jit, REG_ECX);
/* Relocate stack, heap, frm information, then store back */
//sub edi, ebp
//mov ecx, [esi+hea]
//mov eax, [esi+context]
//mov ecx, [esi+hea]
//sub edi, ebp
//mov [eax+hp], ecx
//mov ecx, [esi]
//mov [eax+sp], edi
//mov ecx, [esi+frm]
//mov [eax+frm], ecx
IA32_Sub_Rm_Reg(jit, AMX_REG_STK, AMX_REG_DAT, MOD_REG);
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_HEAP);
IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, AMX_REG_INFO, AMX_INFO_CONTEXT);
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_HEAP);
IA32_Sub_Reg_Rm(jit, AMX_REG_STK, AMX_REG_DAT, MOD_REG);
IA32_Mov_Rm_Reg_Disp8(jit, REG_EAX, AMX_REG_TMP, offsetof(sp_context_t, hp));
IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_INFO_FRM, MOD_MEM_REG);
IA32_Mov_Rm_Reg_Disp8(jit, REG_EAX, AMX_REG_STK, offsetof(sp_context_t, sp));
IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_INFO_FRM, MOD_REG);
IA32_Mov_Rm_Reg_Disp8(jit, REG_EAX, AMX_REG_TMP, offsetof(sp_context_t, frm));
/* finally, push the last parameter and make the call */
@ -665,7 +663,7 @@ void WriteOp_Sysreq_N_Function(JitWriter *jit)
//cmp [ecx+err], 0
//jnz :error
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_CONTEXT);
IA32_Cmp_Rm_Imm32_Disp8(jit, AMX_REG_TMP, offsetof(sp_context_t, err), 0);
IA32_Cmp_Rm_Disp8_Imm8(jit, AMX_REG_TMP, offsetof(sp_context_t, err), 0);
IA32_Jump_Cond_Imm32_Abs(jit, CC_NZ, data->jit_extern_error);
/* restore what we damaged */
@ -674,7 +672,7 @@ void WriteOp_Sysreq_N_Function(JitWriter *jit)
//pop edx
//pop ecx ; num_params
IA32_Add_Rm_Imm8(jit, REG_ESP, 4*3, MOD_REG);
IA32_Add_Rm_Reg(jit, AMX_REG_STK, AMX_REG_DAT, MOD_REG);
IA32_Add_Reg_Rm(jit, AMX_REG_STK, AMX_REG_DAT, MOD_REG);
IA32_Pop_Reg(jit, AMX_REG_ALT);
IA32_Pop_Reg(jit, REG_ECX);

View File

@ -253,4 +253,22 @@ typedef enum
OP_NUM_OPCODES
} OPCODE;
/*
* :TODO: List of ASM Opts
* from jit_x86.cpp
* TODO: all new array opcodes (4 ATM)
* DONE: Rest of opcodes including the SYSREQ.N inlined version (rev2)
* DONE: ALL ungen opcodes (rev1)
* from opcode_helpers.cpp
* DONE: SYSREQ.N .C (rev2)
* MACRO OPCODES (rev2)
* ERROR CHECKS\{VERIFY ADDR} (rev2)
* TODO: BrkDebug
* ARRAY STUFF
* EXEC FUNCTION
* VERIFY ADDR
*
* Oh and ALIGN all stuff that is called via CALL like what's done with PROC.
*/
#endif //_INCLUDE_SOURCEPAWN_JIT_X86_OPCODE_INFO_H_

View File

@ -113,7 +113,7 @@ inline void WriteOp_Cmps(JitWriter *jit)
inline void WriteOp_Lodb_I(JitWriter *jit)
{
Write_Check_VerifyAddr(jit, AMX_REG_PRI, false);
Write_Check_VerifyAddr(jit, AMX_REG_PRI);
//mov eax, [ebp+eax]
IA32_Mov_Reg_RmEBP_Disp_Reg(jit, AMX_REG_PRI, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
@ -137,7 +137,7 @@ inline void WriteOp_Lodb_I(JitWriter *jit)
inline void WriteOp_Strb_I(JitWriter *jit)
{
Write_Check_VerifyAddr(jit, AMX_REG_ALT, false);
Write_Check_VerifyAddr(jit, AMX_REG_ALT);
//mov [ebp+edx], eax
cell_t val = jit->read_cell();
switch (val)
@ -211,10 +211,10 @@ inline void WriteOp_Lctrl(JitWriter *jit)
{
//mov eax, [cip]
jitoffs_t imm32 = IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
jitoffs_t save = jit->jit_curpos();
jit->setpos(imm32);
jitoffs_t save = jit->get_outputpos();
jit->set_outputpos(imm32);
jit->write_int32((uint32_t)(jit->outbase + save));
jit->setpos(save);
jit->set_outputpos(save);
break;
}
}

View File

@ -23,6 +23,7 @@
#define REG_ESP 4
#define REG_SIB 4
#define REG_NOIDX 4
#define REG_IMM_BASE 5
#define REG_EBP 5
#define REG_ESI 6
#define REG_EDI 7
@ -122,6 +123,7 @@
#define IA32_PUSH_REG 0x50 // encoding is +r
#define IA32_PUSH_RM 0xFF // encoding is /6
#define IA32_PUSH_IMM32 0x68 // encoding is <imm32>
#define IA32_PUSH_IMM8 0x6A // encoding is <imm8>
#define IA32_REP 0xF3 // no extra encoding
#define IA32_MOVSD 0xA5 // no extra encoding
#define IA32_MOVSB 0xA4 // no extra encoding
@ -592,6 +594,18 @@ inline void IA32_Lea_Reg_DispRegMultImm8(JitWriter *jit,
jit->write_byte(val);
}
inline void IA32_Lea_Reg_RegMultImm32(JitWriter *jit,
jit_uint8_t dest,
jit_uint8_t src_index,
jit_uint8_t scale,
jit_int32_t val)
{
jit->write_ubyte(IA32_LEA_REG_MEM);
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest, REG_SIB));
jit->write_ubyte(ia32_sib(scale, src_index, REG_IMM_BASE));
jit->write_int32(val);
}
inline void IA32_Lea_DispRegImm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src_base, jit_int8_t val)
{
jit->write_ubyte(IA32_LEA_REG_MEM);
@ -620,6 +634,12 @@ inline void IA32_Push_Reg(JitWriter *jit, jit_uint8_t reg)
jit->write_ubyte(IA32_PUSH_REG+reg);
}
inline void IA32_Push_Imm8(JitWriter *jit, jit_int8_t val)
{
jit->write_ubyte(IA32_PUSH_IMM8);
jit->write_byte(val);
}
inline void IA32_Push_Imm32(JitWriter *jit, jit_int32_t val)
{
jit->write_ubyte(IA32_PUSH_IMM32);