mirror of
https://github.com/alliedmodders/amxmodx.git
synced 2024-12-26 06:45:37 +03:00
experimental optimizer for float ops
This commit is contained in:
parent
b527efde41
commit
dcaf3066bf
@ -288,7 +288,7 @@ static cell AMX_NATIVE_CALL invalid_native(AMX *amx, cell *params)
|
|||||||
}
|
}
|
||||||
|
|
||||||
char name[sNAMEMAX + 1];
|
char name[sNAMEMAX + 1];
|
||||||
int native = amx->usertags[UT_NATIVE];
|
int native = reinterpret_cast<int>(amx->usertags[UT_NATIVE]);
|
||||||
int err = amx_GetNative(amx, native, name);
|
int err = amx_GetNative(amx, native, name);
|
||||||
|
|
||||||
if (err != AMX_ERR_NONE)
|
if (err != AMX_ERR_NONE)
|
||||||
|
Binary file not shown.
Binary file not shown.
170
amxmodx/amx.cpp
170
amxmodx/amx.cpp
@ -46,6 +46,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
#include "osdefs.h"
|
#include "osdefs.h"
|
||||||
#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
|
#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
|
||||||
#include <sclinux.h>
|
#include <sclinux.h>
|
||||||
@ -265,6 +266,12 @@ typedef enum {
|
|||||||
OP_SYSREQ_D,
|
OP_SYSREQ_D,
|
||||||
OP_SYMTAG, /* obsolete */
|
OP_SYMTAG, /* obsolete */
|
||||||
OP_BREAK,
|
OP_BREAK,
|
||||||
|
OP_FLOAT_MUL,
|
||||||
|
OP_FLOAT_DIV,
|
||||||
|
OP_FLOAT_ADD,
|
||||||
|
OP_FLOAT_SUB,
|
||||||
|
OP_FLOAT_TO,
|
||||||
|
OP_FLOAT_ROUND,
|
||||||
/* ----- */
|
/* ----- */
|
||||||
OP_NUM_OPCODES
|
OP_NUM_OPCODES
|
||||||
} OPCODE;
|
} 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.
|
/* 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.
|
* 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:
|
/* Note:
|
||||||
* params[0] == number of bytes for the additional parameters passed to the native function
|
* 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;
|
cell cip;
|
||||||
long codesize;
|
long codesize;
|
||||||
OPCODE op;
|
OPCODE op;
|
||||||
|
BROWSEHOOK hook = NULL;
|
||||||
#if defined __GNUC__ || defined ASM32 || defined JIT
|
#if defined __GNUC__ || defined ASM32 || defined JIT
|
||||||
cell *opcode_list;
|
cell *opcode_list;
|
||||||
#endif
|
#endif
|
||||||
@ -502,6 +510,7 @@ static int amx_BrowseRelocate(AMX *amx)
|
|||||||
code=amx->base+(int)hdr->cod;
|
code=amx->base+(int)hdr->cod;
|
||||||
codesize=hdr->dat - hdr->cod;
|
codesize=hdr->dat - hdr->cod;
|
||||||
amx->flags|=AMX_FLAG_BROWSE;
|
amx->flags|=AMX_FLAG_BROWSE;
|
||||||
|
hook = (BROWSEHOOK)amx->usertags[UT_BROWSEHOOK];
|
||||||
|
|
||||||
/* sanity checks */
|
/* sanity checks */
|
||||||
assert(OP_PUSH_PRI==36);
|
assert(OP_PUSH_PRI==36);
|
||||||
@ -607,11 +616,22 @@ static int amx_BrowseRelocate(AMX *amx)
|
|||||||
case OP_FILL:
|
case OP_FILL:
|
||||||
case OP_HALT:
|
case OP_HALT:
|
||||||
case OP_BOUNDS:
|
case OP_BOUNDS:
|
||||||
case OP_SYSREQ_C:
|
|
||||||
case OP_PUSHADDR:
|
case OP_PUSHADDR:
|
||||||
case OP_SYSREQ_D:
|
case OP_SYSREQ_D:
|
||||||
cip+=sizeof(cell);
|
cip+=sizeof(cell);
|
||||||
break;
|
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_LOAD_I: /* instructions without parameters */
|
||||||
case OP_STOR_I:
|
case OP_STOR_I:
|
||||||
@ -672,6 +692,12 @@ static int amx_BrowseRelocate(AMX *amx)
|
|||||||
case OP_SWAP_ALT:
|
case OP_SWAP_ALT:
|
||||||
case OP_NOP:
|
case OP_NOP:
|
||||||
case OP_BREAK:
|
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;
|
break;
|
||||||
|
|
||||||
case OP_CALL: /* opcodes that need relocation */
|
case OP_CALL: /* opcodes that need relocation */
|
||||||
@ -799,6 +825,7 @@ static void expand(unsigned char *code, long codesize, long memsize)
|
|||||||
int AMXAPI amx_Init(AMX *amx, void *program)
|
int AMXAPI amx_Init(AMX *amx, void *program)
|
||||||
{
|
{
|
||||||
AMX_HEADER *hdr;
|
AMX_HEADER *hdr;
|
||||||
|
BROWSEHOOK hook = NULL;
|
||||||
#if (defined _Windows || defined LINUX || defined __FreeBSD__ || defined __OpenBSD__) && !defined AMX_NODYNALOAD
|
#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 */
|
char libname[sNAMEMAX+8]; /* +1 for '\0', +3 for 'amx' prefix, +4 for extension */
|
||||||
#if defined _Windows
|
#if defined _Windows
|
||||||
@ -946,6 +973,9 @@ int AMXAPI amx_Init(AMX *amx,void *program)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* relocate call and jump instructions */
|
/* relocate call and jump instructions */
|
||||||
|
hook = (BROWSEHOOK)amx->usertags[UT_BROWSEHOOK];
|
||||||
|
if (hook)
|
||||||
|
hook(amx, NULL, NULL);
|
||||||
amx_BrowseRelocate(amx);
|
amx_BrowseRelocate(amx);
|
||||||
|
|
||||||
/* load any extension modules that the AMX refers to */
|
/* 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 AMXAPI amx_FindNative(AMX *amx, const char *name, int *index)
|
||||||
{
|
{
|
||||||
int first,last,mid,result;
|
int first,last,mid;
|
||||||
char pname[sNAMEMAX+1];
|
char pname[sNAMEMAX+1];
|
||||||
|
|
||||||
amx_NumNatives(amx, &last);
|
amx_NumNatives(amx, &last);
|
||||||
last--; /* last valid index is 1 less than the number of functions */
|
last--; /* last valid index is 1 less than the number of functions */
|
||||||
first=0;
|
first=0;
|
||||||
/* binary search */
|
/* normal search */
|
||||||
while (first<=last) {
|
for (mid=0; mid<=last; mid++)
|
||||||
mid=(first+last)/2;
|
{
|
||||||
amx_GetNative(amx, mid, pname);
|
amx_GetNative(amx, mid, pname);
|
||||||
result=strcmp(pname,name);
|
if (strcmp(pname, name)==0)
|
||||||
if (result>0) {
|
{
|
||||||
last=mid-1;
|
|
||||||
} else if (result<0) {
|
|
||||||
first=mid+1;
|
|
||||||
} else {
|
|
||||||
*index = mid;
|
*index = mid;
|
||||||
return AMX_ERR_NONE;
|
return AMX_ERR_NONE;
|
||||||
} /* if */
|
} /* if */
|
||||||
} /* while */
|
} /* for */
|
||||||
/* not found, set to an invalid index, so amx_Exec() will fail */
|
|
||||||
*index=INT_MAX;
|
*index=INT_MAX;
|
||||||
return AMX_ERR_NOTFOUND;
|
return AMX_ERR_NOTFOUND;
|
||||||
}
|
}
|
||||||
@ -1492,37 +1517,11 @@ int AMXAPI amx_FindTagId(AMX *amx, cell tag_id, char *tagname)
|
|||||||
#if defined AMX_XXXUSERDATA
|
#if defined AMX_XXXUSERDATA
|
||||||
int AMXAPI amx_GetUserData(AMX *amx, long tag, void **ptr)
|
int AMXAPI amx_GetUserData(AMX *amx, long tag, void **ptr)
|
||||||
{
|
{
|
||||||
int index;
|
|
||||||
|
|
||||||
assert(amx!=NULL);
|
|
||||||
assert(tag!=0);
|
|
||||||
for (index=0; index<AMX_USERNUM && amx->usertags[index]!=tag; index++)
|
|
||||||
/* nothing */;
|
|
||||||
if (index>=AMX_USERNUM)
|
|
||||||
return AMX_ERR_USERDATA;
|
|
||||||
*ptr=amx->userdata[index];
|
|
||||||
return AMX_ERR_NONE;
|
return AMX_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AMXAPI amx_SetUserData(AMX *amx, long tag, void *ptr)
|
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; index<AMX_USERNUM && amx->usertags[index]!=tag; index++)
|
|
||||||
/* nothing */;
|
|
||||||
/* if not found, try to find empty tag */
|
|
||||||
if (index>=AMX_USERNUM)
|
|
||||||
for (index=0; index<AMX_USERNUM && amx->usertags[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;
|
return AMX_ERR_NONE;
|
||||||
}
|
}
|
||||||
#endif /* AMX_XXXUSERDATA */
|
#endif /* AMX_XXXUSERDATA */
|
||||||
@ -1764,13 +1763,15 @@ static const void * const amx_opcodelist[] = {
|
|||||||
&&op_file, &&op_line, &&op_symbol, &&op_srange,
|
&&op_file, &&op_line, &&op_symbol, &&op_srange,
|
||||||
&&op_jump_pri, &&op_switch, &&op_casetbl, &&op_swap_pri,
|
&&op_jump_pri, &&op_switch, &&op_casetbl, &&op_swap_pri,
|
||||||
&&op_swap_alt, &&op_pushaddr, &&op_nop, &&op_sysreq_d,
|
&&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_HEADER *hdr;
|
||||||
AMX_FUNCSTUB *func;
|
AMX_FUNCSTUB *func;
|
||||||
unsigned char *code, *data;
|
unsigned char *code, *data;
|
||||||
cell pri,alt,stk,frm,hea;
|
cell pri,alt,stk,frm,hea;
|
||||||
cell reset_stk, reset_hea, *cip;
|
cell reset_stk, reset_hea, *cip;
|
||||||
cell offs;
|
cell offs, offs2;
|
||||||
|
REAL fnum;
|
||||||
ucell codesize;
|
ucell codesize;
|
||||||
int num,i;
|
int num,i;
|
||||||
|
|
||||||
@ -2616,6 +2617,47 @@ static const void * const amx_opcodelist[] = {
|
|||||||
NEXT(cip);
|
NEXT(cip);
|
||||||
op_nop:
|
op_nop:
|
||||||
NEXT(cip);
|
NEXT(cip);
|
||||||
|
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:
|
op_break:
|
||||||
if (amx->debug!=NULL) {
|
if (amx->debug!=NULL) {
|
||||||
/* store status */
|
/* store status */
|
||||||
@ -2700,7 +2742,8 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index)
|
|||||||
cell parms[9]; /* registers and parameters for assembler AMX */
|
cell parms[9]; /* registers and parameters for assembler AMX */
|
||||||
#else
|
#else
|
||||||
OPCODE op;
|
OPCODE op;
|
||||||
cell offs;
|
cell offs, offs2;
|
||||||
|
REAL fnum;
|
||||||
int num;
|
int num;
|
||||||
#endif
|
#endif
|
||||||
assert(amx!=NULL);
|
assert(amx!=NULL);
|
||||||
@ -3590,6 +3633,47 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index)
|
|||||||
PUSH(frm+offs);
|
PUSH(frm+offs);
|
||||||
break;
|
break;
|
||||||
case OP_NOP:
|
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;
|
break;
|
||||||
case OP_BREAK:
|
case OP_BREAK:
|
||||||
assert((amx->flags & AMX_FLAG_BROWSE)==0);
|
assert((amx->flags & AMX_FLAG_BROWSE)==0);
|
||||||
|
@ -231,7 +231,7 @@ typedef struct tagAMX {
|
|||||||
cell stp PACKED; /* top of the stack: relative to base + amxhdr->dat */
|
cell stp PACKED; /* top of the stack: relative to base + amxhdr->dat */
|
||||||
int flags PACKED; /* current status, see amx_Flags() */
|
int flags PACKED; /* current status, see amx_Flags() */
|
||||||
/* user data */
|
/* 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
|
//okay userdata[3] in AMX Mod X is for the CPlugin * pointer
|
||||||
//we're also gonna set userdata[2] to a special debug structure
|
//we're also gonna set userdata[2] to a special debug structure
|
||||||
//lastly, userdata[1] is for opcode_list from amx_BrowseRelocate
|
//lastly, userdata[1] is for opcode_list from amx_BrowseRelocate
|
||||||
@ -334,6 +334,10 @@ enum {
|
|||||||
#define UD_OPCODELIST 1
|
#define UD_OPCODELIST 1
|
||||||
#define UD_HANDLER 0
|
#define UD_HANDLER 0
|
||||||
#define UT_NATIVE 3
|
#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
|
/* for native functions that use floating point parameters, the following
|
||||||
* two macros are convenient for casting a "cell" into a "float" type _without_
|
* two macros are convenient for casting a "cell" into a "float" type _without_
|
||||||
|
@ -267,6 +267,28 @@ int AMXAPI dbg_LookupLine(AMX_DBG *amxdbg, ucell address, long *line)
|
|||||||
return AMX_ERR_NONE;
|
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; index<amxdbg->hdr->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)
|
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
|
/* dbg_LookupFunction() finds the function a code address is in. It can be
|
||||||
|
@ -56,6 +56,8 @@
|
|||||||
;
|
;
|
||||||
;History (list of changes)
|
;History (list of changes)
|
||||||
;-------------------------
|
;-------------------------
|
||||||
|
; 10 february 2006 by David Anderson
|
||||||
|
; Addition of float opcodes
|
||||||
; 17 february 2005 by Thiadmer Riemersms
|
; 17 february 2005 by Thiadmer Riemersms
|
||||||
; Addition of the BREAK opcode, removal of the older debugging opcode table.
|
; Addition of the BREAK opcode, removal of the older debugging opcode table.
|
||||||
; 6 march 2004 by Thiadmer Riemersma
|
; 6 march 2004 by Thiadmer Riemersma
|
||||||
@ -1406,6 +1408,83 @@ OP_NOP:
|
|||||||
add esi,4
|
add esi,4
|
||||||
GO_ON
|
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:
|
OP_BREAK:
|
||||||
mov ebp,amx ; get amx into ebp
|
mov ebp,amx ; get amx into ebp
|
||||||
@ -1642,4 +1721,9 @@ _amx_opcodelist DD OP_INVALID
|
|||||||
DD OP_SYSREQ_D
|
DD OP_SYSREQ_D
|
||||||
DD OP_SYMTAG
|
DD OP_SYMTAG
|
||||||
DD OP_BREAK
|
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
|
||||||
|
@ -1882,7 +1882,7 @@ OP_BREAK:
|
|||||||
jae code_gen_done
|
jae code_gen_done
|
||||||
jmp DWORD [ebx] ; go on with the next opcode
|
jmp DWORD [ebx] ; go on with the next opcode
|
||||||
%else
|
%else
|
||||||
GO_ON j_break, OP_INVALID
|
GO_ON j_break, OP_FLOAT_MUL
|
||||||
j_break:
|
j_break:
|
||||||
mov ebp,amx
|
mov ebp,amx
|
||||||
cmp DWORD [ebp+_debug], 0
|
cmp DWORD [ebp+_debug], 0
|
||||||
@ -1891,6 +1891,90 @@ OP_BREAK:
|
|||||||
CHECKCODESIZE j_break
|
CHECKCODESIZE j_break
|
||||||
%endif
|
%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
|
OP_INVALID: ; break from the compiler with an error code
|
||||||
mov eax,AMX_ERR_INVINSTR
|
mov eax,AMX_ERR_INVINSTR
|
||||||
pop esi
|
pop esi
|
||||||
@ -2461,5 +2545,11 @@ _amx_opcodelist_jit:
|
|||||||
DD OP_SYSREQ_D ; TR
|
DD OP_SYSREQ_D ; TR
|
||||||
DD OP_SYMTAG ; TR
|
DD OP_SYMTAG ; TR
|
||||||
DD OP_BREAK ; 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
|
END
|
||||||
|
@ -442,7 +442,7 @@ int Debugger::FormatError(char *buffer, size_t maxLength)
|
|||||||
num = (int)*p_cip;
|
num = (int)*p_cip;
|
||||||
}*/
|
}*/
|
||||||
//New code only requires this...
|
//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);
|
amx_err = amx_GetNative(m_pAmx, num, native_name);
|
||||||
/*if (num)
|
/*if (num)
|
||||||
amx_err = amx_GetNative(m_pAmx, (int)*p_cip, native_name);
|
amx_err = amx_GetNative(m_pAmx, (int)*p_cip, native_name);
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
#include "newmenus.h"
|
#include "newmenus.h"
|
||||||
#include "natives.h"
|
#include "natives.h"
|
||||||
#include "debugger.h"
|
#include "debugger.h"
|
||||||
|
#include "optimizer.h"
|
||||||
|
|
||||||
CList<CModule, const char*> g_modules;
|
CList<CModule, const char*> g_modules;
|
||||||
CList<CScript, AMX*> g_loadedscripts;
|
CList<CScript, AMX*> g_loadedscripts;
|
||||||
@ -100,6 +101,8 @@ void free_amxmemory(void **ptr)
|
|||||||
*ptr = 0;
|
*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)
|
int load_amxscript(AMX *amx, void **program, const char *filename, char error[64], int debug)
|
||||||
{
|
{
|
||||||
*error = 0;
|
*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);
|
return (amx->error = AMX_ERR_INIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dbg_DumpFuncs(pDbg, "c:\\test.txt");
|
||||||
|
|
||||||
amx->flags |= AMX_FLAG_DEBUG;
|
amx->flags |= AMX_FLAG_DEBUG;
|
||||||
} else {
|
} else {
|
||||||
sprintf(error, "Plugin not compiled with debug option");
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SetupOptimizer(amx);
|
||||||
|
|
||||||
if ((err = amx_Init(amx, *program)) != AMX_ERR_NONE)
|
if ((err = amx_Init(amx, *program)) != AMX_ERR_NONE)
|
||||||
{
|
{
|
||||||
if (pDbg)
|
if (pDbg)
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
LIBRARY amxx_mm
|
|
||||||
EXPORTS
|
|
||||||
GiveFnptrsToDll @1
|
|
||||||
|
|
||||||
SECTIONS
|
|
||||||
.data READ WRITE
|
|
@ -686,6 +686,9 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\newmenus.cpp">
|
RelativePath="..\newmenus.cpp">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\optimizer.cpp">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\power.cpp">
|
RelativePath="..\power.cpp">
|
||||||
</File>
|
</File>
|
||||||
@ -835,6 +838,9 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\newmenus.h">
|
RelativePath="..\newmenus.h">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\optimizer.h">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\resource.h">
|
RelativePath="..\resource.h">
|
||||||
</File>
|
</File>
|
||||||
|
100
amxmodx/optimizer.cpp
Normal file
100
amxmodx/optimizer.cpp
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
#include <string.h>
|
||||||
|
#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; i<N_Total_FloatOps; i++)
|
||||||
|
{
|
||||||
|
if (opt->natives[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; i<N_Total_FloatOps; i++)
|
||||||
|
opt->natives[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;
|
||||||
|
}
|
||||||
|
|
24
amxmodx/optimizer.h
Normal file
24
amxmodx/optimizer.h
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user