diff --git a/plugins/testsuite/goto_test.sp b/plugins/testsuite/goto_test.sp new file mode 100644 index 00000000..2c6721c8 --- /dev/null +++ b/plugins/testsuite/goto_test.sp @@ -0,0 +1,28 @@ +#include + +public OnPluginStart() +{ + RegServerCmd("test_goto", Test_Goto); +} + +public Action:Test_Goto(args) +{ + new bool:hello = false; + new String:crab[] = "space crab"; + +sample_label: + + new String:yam[] = "yams"; + + PrintToServer("%s %s", crab, yam); + + if (!hello) + { + new bool:what = true; + hello = what + goto sample_label; + } + + return Plugin_Handled; +} + diff --git a/sourcepawn/compiler/sc4.c b/sourcepawn/compiler/sc4.c index 91887f5c..1eb19208 100644 --- a/sourcepawn/compiler/sc4.c +++ b/sourcepawn/compiler/sc4.c @@ -854,19 +854,10 @@ SC_FUNC void modstk(int delta) /* set the stack to a hard offset from the frame */ SC_FUNC void setstk(cell value) { - stgwrite("\tlctrl 5\n"); /* get FRM in PRI */ + stgwrite("\tstackadjust "); assert(value<=0); /* STK should always become <= FRM */ - if (value<0) { - stgwrite("\tadd.c "); - outval(value, TRUE); /* add (negative) offset */ - code_idx+=opcodes(1)+opargs(1); - // ??? write zeros in the space between STK and the value in PRI (the new stk) - // get value of STK in ALT - // zero PRI - // need new FILL opcode that takes a variable size - } /* if */ - stgwrite("\tsctrl 4\n"); /* store in STK */ - code_idx+=opcodes(2)+opargs(2); + outval(value, TRUE); /* add (negative) offset */ + code_idx+=opcodes(1)+opargs(1); } SC_FUNC void modheap(int delta) diff --git a/sourcepawn/compiler/sc6.c b/sourcepawn/compiler/sc6.c index a19b62cd..6a431eac 100644 --- a/sourcepawn/compiler/sc6.c +++ b/sourcepawn/compiler/sc6.c @@ -596,6 +596,7 @@ static OPCODEC opcodelist[] = { { 21, "sref.s.pri", sIN_CSEG, parm1 }, { 67, "sshr", sIN_CSEG, parm0 }, { 44, "stack", sIN_CSEG, parm1 }, + {165, "stackadjust",sIN_CSEG, parm1 }, { 0, "stksize", 0, noop }, { 16, "stor.alt", sIN_CSEG, parm1 }, { 23, "stor.i", sIN_CSEG, parm0 }, diff --git a/sourcepawn/jit/x86/jit_x86.cpp b/sourcepawn/jit/x86/jit_x86.cpp index 6103f3da..26e6eb76 100644 --- a/sourcepawn/jit/x86/jit_x86.cpp +++ b/sourcepawn/jit/x86/jit_x86.cpp @@ -1209,6 +1209,28 @@ inline void WriteOp_Stack(JitWriter *jit) } } +inline void WriteOp_StackAdjust(JitWriter *jit) +{ + cell_t val = jit->read_cell(); + + assert(val <= 0); + + //lea edi, [ebx-val] + + if (val < SCHAR_MAX && val > SCHAR_MIN) + { + IA32_Lea_DispRegImm8(jit, AMX_REG_STK, AMX_REG_FRM, val); + } + else + { + IA32_Lea_DispRegImm32(jit, AMX_REG_STK, AMX_REG_FRM, val); + } + + /* We assume the compiler has generated good code -- + * That is, we do not bother validating this amount! + */ +} + inline void WriteOp_Heap(JitWriter *jit) { //mov edx, [esi+hea] @@ -3009,7 +3031,7 @@ unsigned int JITX86::FunctionCount(const sp_context_t *ctx) const char *JITX86::GetVersionString() { - return SVN_FULL_VERSION; + return SVN_FULL_VERSION "-goto"; } const char *JITX86::GetCPUOptimizations() diff --git a/sourcepawn/jit/x86/opcode_helpers.h b/sourcepawn/jit/x86/opcode_helpers.h index eb74eb30..c7bb2c75 100644 --- a/sourcepawn/jit/x86/opcode_helpers.h +++ b/sourcepawn/jit/x86/opcode_helpers.h @@ -124,8 +124,8 @@ typedef enum OP_LOAD_ALT, //~!VERIFIED (load.pri) OP_LOAD_S_PRI, //VERIFIED OP_LOAD_S_ALT, //VERIFIED - OP_LREF_PRI, // !GEN :TODO: we will need this for dynarrays - OP_LREF_ALT, // !GEN :TODO: we will need this for dynarrays + OP_LREF_PRI, //VERIFIED + OP_LREF_ALT, //~VERIFIED OP_LREF_S_PRI, //VERIFIED OP_LREF_S_ALT, //~VERIFIED (lref.s.pri) OP_LOAD_I, //VERIFIED @@ -138,8 +138,8 @@ typedef enum OP_STOR_ALT, //~VERIFIED (stor.pri) OP_STOR_S_PRI, //VERIFIED OP_STOR_S_ALT, //~VERIFIED (stor.s.pri) - OP_SREF_PRI, // !GEN :TODO: we will need this for dynarrays - OP_SREF_ALT, // !GEN :TODO: we will need this for dynarrays + OP_SREF_PRI, //VERIFIED + OP_SREF_ALT, //~VERIFIED OP_SREF_S_PRI, //VERIFIED OP_SREF_S_ALT, //~VERIFIED (stor.s.alt) OP_STOR_I, //VERIFIED @@ -286,6 +286,7 @@ typedef enum OP_GENARRAY, //VERIFIED OP_GENARRAY_Z, //-VERIFIED (not tested for 1D arrays) OP_STRADJUST_PRI, //VERIFIED + OP_STACKADJUST, //:TODO: VERIFY OP_FABS, //VERIFIED OP_FLOAT, //VERIFIED OP_FLOATADD, //VERIFIED @@ -301,22 +302,4 @@ typedef enum OP_NUM_OPCODES } OPCODE; -/* -* :TODO: List of ASM Opts -* from jit_x86.cpp -* DONE: Rest of opcodes including the SYSREQ.N inlined version (rev2) -* Including genarray and the 2 tracker ones -* DONE: ALL ungen opcodes (rev1) -* from opcode_helpers.cpp -* DONE: SYSREQ.N .C (rev2) -* MACRO OPCODES (rev2) -* ERROR CHECKS\{VERIFY ADDR} (rev2) -* ARRAY STUFF -* TODO: BrkDebug -* EXEC FUNCTION -* VERIFY ADDR -* -* Oh and ALIGN to 16BYTES all stuff that is called via CALL and frequently used jump labels like what's done with PROC. -*/ - #endif //_INCLUDE_SOURCEPAWN_JIT_X86_OPCODE_INFO_H_ diff --git a/sourcepawn/jit/x86/opcode_switch.inc b/sourcepawn/jit/x86/opcode_switch.inc index 2ac2d2f0..e62c5791 100644 --- a/sourcepawn/jit/x86/opcode_switch.inc +++ b/sourcepawn/jit/x86/opcode_switch.inc @@ -748,6 +748,11 @@ WriteOp_FloatCompare(jit); break; } + case OP_STACKADJUST: + { + WriteOp_StackAdjust(jit); + break; + } #if defined USE_UNGEN_OPCODES #include "ungen_opcode_switch.inc" #endif