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 4a366eee..ec565eb5 100755 Binary files a/amxmodx/JIT/amxexecn.obj and b/amxmodx/JIT/amxexecn.obj differ diff --git a/amxmodx/JIT/amxjitsn.obj b/amxmodx/JIT/amxjitsn.obj index 293bad6e..1c868ed9 100755 Binary files a/amxmodx/JIT/amxjitsn.obj and b/amxmodx/JIT/amxjitsn.obj differ 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