From dcaf3066bf67b22fbe65a988651db7c8bde5c810 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Fri, 10 Feb 2006 15:43:27 +0000 Subject: [PATCH] experimental optimizer for float ops --- amxmodx/CPlugin.cpp | 2 +- amxmodx/JIT/amxexecn.obj | Bin 11858 -> 12282 bytes amxmodx/JIT/amxjitsn.obj | Bin 38226 -> 42614 bytes amxmodx/amx.cpp | 178 ++++++++++++++++++++++++--------- amxmodx/amx.h | 6 +- amxmodx/amxdbg.cpp | 22 ++++ amxmodx/amxexecn.asm | 88 +++++++++++++++- amxmodx/amxjitsn.asm | 92 ++++++++++++++++- amxmodx/debugger.cpp | 2 +- amxmodx/modules.cpp | 7 ++ amxmodx/msvc/amxmodx_mm.def | 6 -- amxmodx/msvc/amxmodx_mm.vcproj | 6 ++ amxmodx/optimizer.cpp | 100 ++++++++++++++++++ amxmodx/optimizer.h | 24 +++++ 14 files changed, 474 insertions(+), 59 deletions(-) delete mode 100755 amxmodx/msvc/amxmodx_mm.def create mode 100644 amxmodx/optimizer.cpp create mode 100644 amxmodx/optimizer.h diff --git a/amxmodx/CPlugin.cpp b/amxmodx/CPlugin.cpp index de8752fe..495cb9fd 100755 --- a/amxmodx/CPlugin.cpp +++ b/amxmodx/CPlugin.cpp @@ -288,7 +288,7 @@ static cell AMX_NATIVE_CALL invalid_native(AMX *amx, cell *params) } char name[sNAMEMAX + 1]; - int native = amx->usertags[UT_NATIVE]; + int native = reinterpret_cast(amx->usertags[UT_NATIVE]); int err = amx_GetNative(amx, native, name); if (err != AMX_ERR_NONE) diff --git a/amxmodx/JIT/amxexecn.obj b/amxmodx/JIT/amxexecn.obj index 4a366eeee0732381c62d01c83cecac9766f6c458..ec565eb52fbc93395ec6f2c6d794cd8f8c035b02 100755 GIT binary patch delta 1457 zcmcZ<^DCa$hmncl)TTGiW+Ds>LKAt#xo&VXFr+XrFxc=+)Dx2g@fa8w7y_6W7~FUm z7^d-ocnk~^CdSt5yyjwHuy#>lDdMm^!QXV3i-Dn=h5f&pwTlV|fAcvM$pe!)7}w|s zgTz9>8cy*yv2rmmbh3#5SF;WQY52y;z+erRd@=a}W4dJnNDOX65hv7!z-~X5%MY55 zaWGzpgxD62qR^9ba|4qnqs=9D1_o;%6%PLXd+ZDh&Br+Yt99qGbcd+0fb{05u=Hjg zu*^|m;qPC;&cM)}qax6qD+3njc|VzzMMNL(;zIUJslvEknE`d$-+&_ zVrF2_Jj!?#;)WO$IX~vf)f`4zQXoNigz_*mF!;jM|7SvW)yK)#IimUBGBGf8=Ye9z z@&$kU+{uodu}qCjlNWGCi>ZL5LR1vGWmLL-R8$y$|5tmNz&Kfu%Z^EbadIG+aeebK zmYXj8EH`}kIkFgT%BV#ASAz+aU<$cl3Z<~91L>{p-FjR9fFhE571LB>6TphhZeuIcGfb9Rs&cJX6t_Wm5BL@Qm z8#hcFNQ9q*fq@?`l3G+0pPZPJqY4)RsgdGfV6a9JQQ=@<2t*MvBQd*S9upcgxlb@0lpO^=6>K$QRh delta 1012 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 IYD5zQ0Oc$h!~g&Q diff --git a/amxmodx/amx.cpp b/amxmodx/amx.cpp index 359388f3..1ab05032 100755 --- a/amxmodx/amx.cpp +++ b/amxmodx/amx.cpp @@ -46,6 +46,7 @@ #include #include #include +#include #include "osdefs.h" #if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__ #include @@ -265,6 +266,12 @@ typedef enum { OP_SYSREQ_D, OP_SYMTAG, /* obsolete */ OP_BREAK, + OP_FLOAT_MUL, + OP_FLOAT_DIV, + OP_FLOAT_ADD, + OP_FLOAT_SUB, + OP_FLOAT_TO, + OP_FLOAT_ROUND, /* ----- */ OP_NUM_OPCODES } OPCODE; @@ -444,7 +451,7 @@ int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params) /* As of AMX Mod X 1.56, we don't patch sysreq.c to sysreq.d anymore. * Otherwise, we'd have no way of knowing the last native to be used. */ - amx->usertags[UT_NATIVE] = (long)index; + amx->usertags[UT_NATIVE] = (void *)index; /* Note: * params[0] == number of bytes for the additional parameters passed to the native function @@ -487,6 +494,7 @@ static int amx_BrowseRelocate(AMX *amx) cell cip; long codesize; OPCODE op; + BROWSEHOOK hook = NULL; #if defined __GNUC__ || defined ASM32 || defined JIT cell *opcode_list; #endif @@ -502,6 +510,7 @@ static int amx_BrowseRelocate(AMX *amx) code=amx->base+(int)hdr->cod; codesize=hdr->dat - hdr->cod; amx->flags|=AMX_FLAG_BROWSE; + hook = (BROWSEHOOK)amx->usertags[UT_BROWSEHOOK]; /* sanity checks */ assert(OP_PUSH_PRI==36); @@ -607,11 +616,22 @@ static int amx_BrowseRelocate(AMX *amx) case OP_FILL: case OP_HALT: case OP_BOUNDS: - case OP_SYSREQ_C: case OP_PUSHADDR: case OP_SYSREQ_D: cip+=sizeof(cell); break; + case OP_SYSREQ_C: + { + if (hook) +#if defined __GNUC__ || defined ASM32 || defined JIT + hook(amx, opcode_list, &cip); +#else + hook(amx, NULL, &cip); +#endif + else + cip+=sizeof(cell); + break; + } case OP_LOAD_I: /* instructions without parameters */ case OP_STOR_I: @@ -672,6 +692,12 @@ static int amx_BrowseRelocate(AMX *amx) case OP_SWAP_ALT: case OP_NOP: case OP_BREAK: + case OP_FLOAT_MUL: + case OP_FLOAT_DIV: + case OP_FLOAT_ADD: + case OP_FLOAT_SUB: + case OP_FLOAT_TO: + case OP_FLOAT_ROUND: break; case OP_CALL: /* opcodes that need relocation */ @@ -796,9 +822,10 @@ static void expand(unsigned char *code, long codesize, long memsize) } #endif /* defined AMX_INIT */ -int AMXAPI amx_Init(AMX *amx,void *program) +int AMXAPI amx_Init(AMX *amx, void *program) { AMX_HEADER *hdr; + BROWSEHOOK hook = NULL; #if (defined _Windows || defined LINUX || defined __FreeBSD__ || defined __OpenBSD__) && !defined AMX_NODYNALOAD char libname[sNAMEMAX+8]; /* +1 for '\0', +3 for 'amx' prefix, +4 for extension */ #if defined _Windows @@ -946,6 +973,9 @@ int AMXAPI amx_Init(AMX *amx,void *program) #endif /* relocate call and jump instructions */ + hook = (BROWSEHOOK)amx->usertags[UT_BROWSEHOOK]; + if (hook) + hook(amx, NULL, NULL); amx_BrowseRelocate(amx); /* load any extension modules that the AMX refers to */ @@ -1259,27 +1289,22 @@ int AMXAPI amx_GetNative(AMX *amx, int index, char *funcname) int AMXAPI amx_FindNative(AMX *amx, const char *name, int *index) { - int first,last,mid,result; + int first,last,mid; char pname[sNAMEMAX+1]; amx_NumNatives(amx, &last); last--; /* last valid index is 1 less than the number of functions */ first=0; - /* binary search */ - while (first<=last) { - mid=(first+last)/2; + /* normal search */ + for (mid=0; mid<=last; mid++) + { amx_GetNative(amx, mid, pname); - result=strcmp(pname,name); - if (result>0) { - last=mid-1; - } else if (result<0) { - first=mid+1; - } else { - *index=mid; + if (strcmp(pname, name)==0) + { + *index = mid; return AMX_ERR_NONE; - } /* if */ - } /* while */ - /* not found, set to an invalid index, so amx_Exec() will fail */ + } /* if */ + } /* for */ *index=INT_MAX; return AMX_ERR_NOTFOUND; } @@ -1492,37 +1517,11 @@ int AMXAPI amx_FindTagId(AMX *amx, cell tag_id, char *tagname) #if defined AMX_XXXUSERDATA int AMXAPI amx_GetUserData(AMX *amx, long tag, void **ptr) { - int index; - - assert(amx!=NULL); - assert(tag!=0); - for (index=0; indexusertags[index]!=tag; index++) - /* nothing */; - if (index>=AMX_USERNUM) - return AMX_ERR_USERDATA; - *ptr=amx->userdata[index]; return AMX_ERR_NONE; } int AMXAPI amx_SetUserData(AMX *amx, long tag, void *ptr) { - int index; - - assert(amx!=NULL); - assert(tag!=0); - /* try to find existing tag */ - for (index=0; indexusertags[index]!=tag; index++) - /* nothing */; - /* if not found, try to find empty tag */ - if (index>=AMX_USERNUM) - for (index=0; indexusertags[index]!=0; index++) - /* nothing */; - /* if still not found, quit with error */ - if (index>=AMX_USERNUM) - return AMX_ERR_INDEX; - /* set the tag and the value */ - amx->usertags[index]=tag; - amx->userdata[index]=ptr; return AMX_ERR_NONE; } #endif /* AMX_XXXUSERDATA */ @@ -1764,13 +1763,15 @@ static const void * const amx_opcodelist[] = { &&op_file, &&op_line, &&op_symbol, &&op_srange, &&op_jump_pri, &&op_switch, &&op_casetbl, &&op_swap_pri, &&op_swap_alt, &&op_pushaddr, &&op_nop, &&op_sysreq_d, - &&op_symtag, &&op_break }; + &&op_symtag, &&op_break, &&op_float_mul, &&op_float_div, + &&op_float_add, &&op_float_sub, &&op_float_to, &&op_float_round}; AMX_HEADER *hdr; AMX_FUNCSTUB *func; unsigned char *code, *data; cell pri,alt,stk,frm,hea; cell reset_stk, reset_hea, *cip; - cell offs; + cell offs, offs2; + REAL fnum; ucell codesize; int num,i; @@ -2616,7 +2617,48 @@ static const void * const amx_opcodelist[] = { NEXT(cip); op_nop: NEXT(cip); - op_break: + op_float_mul: + offs = *(cell *)(data + (int)stk + sizeof(cell)*1); + offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2); + fnum = amx_ctof(offs) * amx_ctof(offs2); + pri = amx_ftoc(fnum); + NEXT(cip); + op_float_add: + offs = *(cell *)(data + (int)stk + sizeof(cell)*1); + offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2); + fnum = amx_ctof(offs) + amx_ctof(offs2); + pri = amx_ftoc(fnum); + NEXT(cip); + op_float_sub: + offs = *(cell *)(data + (int)stk + sizeof(cell)*1); + offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2); + fnum = amx_ctof(offs) - amx_ctof(offs2); + pri = amx_ftoc(fnum); + NEXT(cip); + op_float_div: + offs = *(cell *)(data + (int)stk + sizeof(cell)*1); + offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2); + fnum = amx_ctof(offs) / amx_ctof(offs2); + pri = amx_ftoc(fnum); + NEXT(cip); + op_float_to: + offs = *(cell *)(data + (int)stk + sizeof(cell)*1); + fnum = (REAL)offs; + pri = amx_ftoc(fnum); + NEXT(cip); + op_float_round: + offs = *(cell *)(data + (int)stk + sizeof(cell)*1); + offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2); + fnum = amx_ctof(offs); + if (!offs2) + fnum = floor(fnum + 0.5); + else if (offs2 == 1) + fnum = floor(fnum); + else + fnum = ceil(fnum); + pri = (cell)fnum; + NEXT(cip); +op_break: if (amx->debug!=NULL) { /* store status */ amx->frm=frm; @@ -2700,7 +2742,8 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index) cell parms[9]; /* registers and parameters for assembler AMX */ #else OPCODE op; - cell offs; + cell offs, offs2; + REAL fnum; int num; #endif assert(amx!=NULL); @@ -3590,6 +3633,47 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index) PUSH(frm+offs); break; case OP_NOP: + break; + case OP_FLOAT_MUL: + offs = *(cell *)(data + (int)stk + sizeof(cell)*1); + offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2); + fnum = amx_ctof(offs) * amx_ctof(offs2); + pri = amx_ftoc(fnum); + break; + case OP_FLOAT_ADD: + offs = *(cell *)(data + (int)stk + sizeof(cell)*1); + offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2); + fnum = amx_ctof(offs) + amx_ctof(offs2); + pri = amx_ftoc(fnum); + break; + case OP_FLOAT_SUB: + offs = *(cell *)(data + (int)stk + sizeof(cell)*1); + offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2); + fnum = amx_ctof(offs) - amx_ctof(offs2); + pri = amx_ftoc(fnum); + break; + case OP_FLOAT_DIV: + offs = *(cell *)(data + (int)stk + sizeof(cell)*1); + offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2); + fnum = amx_ctof(offs) / amx_ctof(offs2); + pri = amx_ftoc(fnum); + break; + case OP_FLOAT_TO: + offs = *(cell *)(data + (int)stk + sizeof(cell)*1); + fnum = (float)offs; + pri = amx_ftoc(fnum); + break; + case OP_FLOAT_ROUND: + offs = *(cell *)(data + (int)stk + sizeof(cell)*1); + offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2); + fnum = amx_ctof(offs); + if (!offs2) + fnum = (REAL)floor(fnum + 0.5); + else if (offs2 == 1) + fnum = floor(fnum); + else + fnum = ceil(fnum); + pri = (cell)fnum; break; case OP_BREAK: assert((amx->flags & AMX_FLAG_BROWSE)==0); diff --git a/amxmodx/amx.h b/amxmodx/amx.h index 8fbddce9..89d8151e 100755 --- a/amxmodx/amx.h +++ b/amxmodx/amx.h @@ -231,7 +231,7 @@ typedef struct tagAMX { cell stp PACKED; /* top of the stack: relative to base + amxhdr->dat */ int flags PACKED; /* current status, see amx_Flags() */ /* user data */ - long usertags[AMX_USERNUM] PACKED; + void _FAR *usertags[AMX_USERNUM] PACKED; //okay userdata[3] in AMX Mod X is for the CPlugin * pointer //we're also gonna set userdata[2] to a special debug structure //lastly, userdata[1] is for opcode_list from amx_BrowseRelocate @@ -334,6 +334,10 @@ enum { #define UD_OPCODELIST 1 #define UD_HANDLER 0 #define UT_NATIVE 3 +#define UT_OPTIMIZER 2 +#define UT_BROWSEHOOK 1 + +typedef void (*BROWSEHOOK)(AMX *amx, cell *oplist, cell *cip); /* for native functions that use floating point parameters, the following * two macros are convenient for casting a "cell" into a "float" type _without_ diff --git a/amxmodx/amxdbg.cpp b/amxmodx/amxdbg.cpp index 7f05afb7..ebb06fd9 100755 --- a/amxmodx/amxdbg.cpp +++ b/amxmodx/amxdbg.cpp @@ -267,6 +267,28 @@ int AMXAPI dbg_LookupLine(AMX_DBG *amxdbg, ucell address, long *line) return AMX_ERR_NONE; } +void AMXAPI dbg_DumpFuncs(AMX_DBG *amxdbg, const char *file) +{ + int index; + FILE *fp = fopen(file, "at"); + + if (!fp) + return; + + for (index=0; indexhdr->symbols; index++) + { + if (amxdbg->symboltbl[index]->ident == iFUNCTN) + { + fprintf(fp, "[%s] --> (%d-%d)", + amxdbg->symboltbl[index]->name, + amxdbg->symboltbl[index]->codestart, + amxdbg->symboltbl[index]->codeend); + } + } + + fclose(fp); +} + int AMXAPI dbg_LookupFunction(AMX_DBG *amxdbg, ucell address, const char **funcname) { /* dbg_LookupFunction() finds the function a code address is in. It can be diff --git a/amxmodx/amxexecn.asm b/amxmodx/amxexecn.asm index 89d26d0a..7b56fe04 100755 --- a/amxmodx/amxexecn.asm +++ b/amxmodx/amxexecn.asm @@ -56,6 +56,8 @@ ; ;History (list of changes) ;------------------------- +; 10 february 2006 by David Anderson +; Addition of float opcodes ; 17 february 2005 by Thiadmer Riemersms ; Addition of the BREAK opcode, removal of the older debugging opcode table. ; 6 march 2004 by Thiadmer Riemersma @@ -1405,7 +1407,84 @@ OP_PUSHADDR: OP_NOP: add esi,4 GO_ON - + +OP_FLOAT_MUL: + add esi,4 + fld dword [edi+ecx+4] + fmul dword [edi+ecx+8] + push dword 0 + fstp dword [esp] + pop eax + GO_ON + +OP_FLOAT_DIV: + add esi,4 + fld dword [edi+ecx+4] + fdiv dword [edi+ecx+8] + push dword 0 + fstp dword [esp] + pop eax + GO_ON + +OP_FLOAT_ADD: + add esi,4 + fld dword [edi+ecx+4] + fadd dword [edi+ecx+8] + push dword 0 + fstp dword [esp] + pop eax + GO_ON + +OP_FLOAT_SUB: + add esi,4 + fld dword [edi+ecx+4] + fsub dword [edi+ecx+8] + push dword 0 + fstp dword [esp] + pop eax + GO_ON + +OP_FLOAT_TO: + add esi,4 + fild dword [edi+ecx+4] + push 0 + fstp dword [esp] + pop eax + GO_ON + +OP_FLOAT_ROUND: + add esi,4 + ;get the float control word + push 0 + mov ebp,esp + fstcw [ebp] + mov eax,[ebp] + push eax + ;clear the top bits + xor ah,ah + ;get the control method + push edx + mov edx,[edi+ecx+8] + and edx,3 ;sanity check + shl edx,2 ;shift it to right position + ;set the bits + or ah,dl ;set bits 15,14 of FCW to rounding method + or ah,3 ;set precision to 64bit + mov [ebp], eax + fldcw [ebp] + ;calculate + push 0 + fld dword [edi+ecx+4] + frndint + fistp dword [esp] + pop eax + pop edx + ;restore bits + pop ebp + mov [esp], ebp + fldcw [esp] + pop ebp + GO_ON OP_BREAK: mov ebp,amx ; get amx into ebp @@ -1642,4 +1721,9 @@ _amx_opcodelist DD OP_INVALID DD OP_SYSREQ_D DD OP_SYMTAG DD OP_BREAK - + DD OP_FLOAT_MUL + DD OP_FLOAT_DIV + DD OP_FLOAT_ADD + DD OP_FLOAT_SUB + DD OP_FLOAT_TO + DD OP_FLOAT_ROUND diff --git a/amxmodx/amxjitsn.asm b/amxmodx/amxjitsn.asm index 47e3b46e..f2ac86c8 100755 --- a/amxmodx/amxjitsn.asm +++ b/amxmodx/amxjitsn.asm @@ -1882,7 +1882,7 @@ OP_BREAK: jae code_gen_done jmp DWORD [ebx] ; go on with the next opcode %else - GO_ON j_break, OP_INVALID + GO_ON j_break, OP_FLOAT_MUL j_break: mov ebp,amx cmp DWORD [ebp+_debug], 0 @@ -1891,6 +1891,90 @@ OP_BREAK: CHECKCODESIZE j_break %endif +OP_FLOAT_MUL: + GO_ON j_float_mul, OP_FLOAT_DIV + j_float_mul: + fld dword [esi+4] + fmul dword [esi+8] + push dword 0 + fstp dword [esp] + pop eax + CHECKCODESIZE j_float_mul + +OP_FLOAT_DIV: + GO_ON j_float_div, OP_FLOAT_ADD + j_float_div: + fld dword [esi+4] + fdiv dword [esi+8] + push dword 0 + fstp dword [esp] + pop eax + CHECKCODESIZE j_float_div + +OP_FLOAT_ADD: + GO_ON j_float_add, OP_FLOAT_SUB + j_float_add: + fld dword [esi+4] + fadd dword [esi+8] + push dword 0 + fstp dword [esp] + pop eax + CHECKCODESIZE j_float_add + +OP_FLOAT_SUB: + GO_ON j_float_sub, OP_FLOAT_TO + j_float_sub: + fld dword [esi+4] + fsub dword [esi+8] + push dword 0 + fstp dword [esp] + pop eax + CHECKCODESIZE j_float_sub + +OP_FLOAT_TO: + GO_ON j_float_to, OP_FLOAT_ROUND + j_float_to: + fild dword [esi+4] + push 0 + fstp dword [esp] + pop eax + CHECKCODESIZE j_float_to + +OP_FLOAT_ROUND: + GO_ON j_float_round, OP_INVALID + j_float_round: + ;get the float control word + push 0 + mov ebp,esp + fstcw [ebp] + mov eax,[ebp] + push eax + ;clear the top bits + xor ah,ah + ;get the control method + push edx + mov edx,[esi+8] + and edx,3 ;sanity check + shl edx,2 ;shift it to right position + ;set the bits + or ah,dl ;set bits 15,14 of FCW to rounding method + or ah,3 ;set precision to 64bit + mov [ebp], eax + fldcw [ebp] + ;calculate + push 0 + fld dword [esi+4] + frndint + fistp dword [esp] + pop eax + pop edx + ;restore bits + pop ebp + mov [esp], ebp + fldcw [esp] + pop ebp + CHECKCODESIZE j_float_round + OP_INVALID: ; break from the compiler with an error code mov eax,AMX_ERR_INVINSTR pop esi @@ -2461,5 +2545,11 @@ _amx_opcodelist_jit: DD OP_SYSREQ_D ; TR DD OP_SYMTAG ; TR DD OP_BREAK ; TR + DD OP_FLOAT_MUL ; DA + DD OP_FLOAT_DIV ; DA + DD OP_FLOAT_ADD ; DA + DD OP_FLOAT_SUB ; DA + DD OP_FLOAT_TO ; DA + DD OP_FLOAT_ROUND ; DA END diff --git a/amxmodx/debugger.cpp b/amxmodx/debugger.cpp index 95c2355f..4bf32c55 100755 --- a/amxmodx/debugger.cpp +++ b/amxmodx/debugger.cpp @@ -442,7 +442,7 @@ int Debugger::FormatError(char *buffer, size_t maxLength) num = (int)*p_cip; }*/ //New code only requires this... - num = m_pAmx->usertags[UT_NATIVE]; + num = (int)m_pAmx->usertags[UT_NATIVE]; amx_err = amx_GetNative(m_pAmx, num, native_name); /*if (num) amx_err = amx_GetNative(m_pAmx, (int)*p_cip, native_name); diff --git a/amxmodx/modules.cpp b/amxmodx/modules.cpp index 0291e457..2c264211 100755 --- a/amxmodx/modules.cpp +++ b/amxmodx/modules.cpp @@ -44,6 +44,7 @@ #include "newmenus.h" #include "natives.h" #include "debugger.h" +#include "optimizer.h" CList g_modules; CList g_loadedscripts; @@ -100,6 +101,8 @@ void free_amxmemory(void **ptr) *ptr = 0; } +void AMXAPI dbg_DumpFuncs(AMX_DBG *amxdbg, const char *file); + int load_amxscript(AMX *amx, void **program, const char *filename, char error[64], int debug) { *error = 0; @@ -197,6 +200,8 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64 return (amx->error = AMX_ERR_INIT); } + dbg_DumpFuncs(pDbg, "c:\\test.txt"); + amx->flags |= AMX_FLAG_DEBUG; } else { sprintf(error, "Plugin not compiled with debug option"); @@ -209,6 +214,8 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64 #endif } + SetupOptimizer(amx); + if ((err = amx_Init(amx, *program)) != AMX_ERR_NONE) { if (pDbg) diff --git a/amxmodx/msvc/amxmodx_mm.def b/amxmodx/msvc/amxmodx_mm.def deleted file mode 100755 index 05c55dc7..00000000 --- a/amxmodx/msvc/amxmodx_mm.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY amxx_mm -EXPORTS - GiveFnptrsToDll @1 - -SECTIONS - .data READ WRITE diff --git a/amxmodx/msvc/amxmodx_mm.vcproj b/amxmodx/msvc/amxmodx_mm.vcproj index ca770cc0..a1d9f6e9 100755 --- a/amxmodx/msvc/amxmodx_mm.vcproj +++ b/amxmodx/msvc/amxmodx_mm.vcproj @@ -686,6 +686,9 @@ + + @@ -835,6 +838,9 @@ + + diff --git a/amxmodx/optimizer.cpp b/amxmodx/optimizer.cpp new file mode 100644 index 00000000..6bd95e46 --- /dev/null +++ b/amxmodx/optimizer.cpp @@ -0,0 +1,100 @@ +#include +#include "optimizer.h" + +#define OP_SYSREQ_C 123 +#define OP_NOP 134 +#define OP_FLOAT_MUL 138 +#define OP_FLOAT_DIV 139 +#define OP_FLOAT_ADD 140 +#define OP_FLOAT_SUB 141 +#define OP_FLOAT_TO 142 +#define OP_FLOAT_ROUND 143 + +cell op_trans_table[N_Total_FloatOps] = +{ + OP_FLOAT_MUL, + OP_FLOAT_DIV, + OP_FLOAT_ADD, + OP_FLOAT_SUB, + OP_FLOAT_TO, + OP_FLOAT_ROUND +}; + +void OnBrowseRelocate(AMX *amx, cell *oplist, cell *cip) +{ + char *codeptr = (char *)amx->base + (long)(((AMX_HEADER *)amx->base)->cod); + + //jump to the parameter; + codeptr += *cip; + + int native = -1; + cell n_offs = *(cell *)codeptr; + optimizer_s *opt = (optimizer_s *)amx->usertags[UT_OPTIMIZER]; + for (int i=0; inatives[i] == n_offs) + { + native = i; + break; + } + } + + if (native != -1) + { + //we're patching this: + // 0x7B 0x?? SYSREQ.C float??? + //with: + // 0x8A FLOAT.MUL + // 0x86 NOP + cell new_opcodes[2]; + new_opcodes[0] = op_trans_table[native]; + new_opcodes[1] = OP_NOP; + codeptr -= sizeof(cell); +#if defined __GNUC__ || defined ASM32 || defined JIT + *(cell *)codeptr = oplist[new_opcodes[0]]; + *(cell *)(codeptr + sizeof(cell)) = oplist[new_opcodes[1]]; +#else + *(cell *)codeptr = new_opcodes[0]; + *(cell *)(codeptr + sizeof(cell)) = new_opcodes[1]; +#endif + } + + *cip += sizeof(cell); + + return; +} + +#define FIND_NATIVE(name, bind) \ + if (amx_FindNative(amx, name, &index) != AMX_ERR_NOTFOUND) \ + opt->natives[bind] = index; + +void _Setup_Optimizer_Stage2(AMX *amx, cell *oplist, cell *cip) +{ + int index; + + amx->usertags[UT_BROWSEHOOK] = (void *)OnBrowseRelocate; + + optimizer_s *opt = new optimizer_s; + + for (int i=0; inatives[i] = -1; + + amx->usertags[UT_OPTIMIZER] = (void *)opt; + + FIND_NATIVE("floatmul", N_Float_Mul); + FIND_NATIVE("floatdiv", N_Float_Div); + FIND_NATIVE("floatadd", N_Float_Add); + FIND_NATIVE("floatsub", N_Float_Sub); + FIND_NATIVE("float", N_Float_To); + FIND_NATIVE("floatround", N_Float_Round); + //we don't do these yet because of radix stuff >:\ + //FIND_NATIVE("floatsin", N_Float_Sin); + //FIND_NATIVE("floatcos", N_Float_Cos); + //FIND_NATIVE("floattan", N_Float_Tan); +} + +void SetupOptimizer(AMX *amx) +{ + amx->usertags[UT_BROWSEHOOK] = (void *)_Setup_Optimizer_Stage2; +} + diff --git a/amxmodx/optimizer.h b/amxmodx/optimizer.h new file mode 100644 index 00000000..7e482e3e --- /dev/null +++ b/amxmodx/optimizer.h @@ -0,0 +1,24 @@ +#ifndef _INCLUDE_AMXMODX_OPTIMIZER_H +#define _INCLUDE_AMXMODX_OPTIMIZER_H + +#include "amx.h" + +enum +{ + N_Float_Mul=0, + N_Float_Div, + N_Float_Add, + N_Float_Sub, + N_Float_To, + N_Float_Round, + N_Total_FloatOps +}; + +struct optimizer_s +{ + int natives[N_Total_FloatOps]; +}; + +void SetupOptimizer(AMX *amx); + +#endif //_INCLUDE_AMXMODX_OPTIMIZER_H