From 0c67ad1e7d3a8078d96c995077583c2dcee8f4df Mon Sep 17 00:00:00 2001 From: David Anderson Date: Tue, 17 Oct 2006 05:50:59 +0000 Subject: [PATCH] added support for op.genarray.z opcode --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40129 --- sourcepawn/vm/jit/x86/jit_x86.cpp | 32 +++++++++++++++++++++++- sourcepawn/vm/jit/x86/opcode_helpers.cpp | 26 ++++++++++++++++--- sourcepawn/vm/jit/x86/opcode_helpers.h | 7 +++--- sourcepawn/vm/jit/x86/opcode_switch.inc | 7 +++++- 4 files changed, 63 insertions(+), 9 deletions(-) diff --git a/sourcepawn/vm/jit/x86/jit_x86.cpp b/sourcepawn/vm/jit/x86/jit_x86.cpp index 7eea2026..450362d9 100644 --- a/sourcepawn/vm/jit/x86/jit_x86.cpp +++ b/sourcepawn/vm/jit/x86/jit_x86.cpp @@ -975,7 +975,7 @@ inline void WriteOp_Heap_I(JitWriter *jit) Write_CheckHeap_Low(jit); } -inline void WriteOp_GenArray(JitWriter *jit) +inline void WriteOp_GenArray(JitWriter *jit, bool autozero) { cell_t val = jit->read_cell(); if (val == 1) @@ -1002,10 +1002,40 @@ inline void WriteOp_GenArray(JitWriter *jit) IA32_Jump_Cond_Imm32_Abs(jit, CC_AE, ((CompData *)jit->data)->jit_error_heaplow); IA32_Shl_Rm_Imm8(jit, AMX_REG_TMP, 4, MOD_REG); IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_ALT, AMX_REG_TMP, -4); + if (autozero) + { + /* Zero out the array - inline a quick fill */ + //push eax ;save pri + //push edi ;save stk + //xor eax, eax ;zero source + //mov edi, [edi] ;get heap ptr out of the stack + //add edi, ebp ;relocate + //cld ;clear direction flag + //rep stosd ;copy (note: ECX is sane from above) + //pop edi ;pop stk + //pop eax ;pop pri + IA32_Push_Reg(jit, REG_EAX); + IA32_Push_Reg(jit, REG_EDI); + IA32_Xor_Reg_Rm(jit, REG_EAX, REG_EAX, MOD_REG); + IA32_Mov_Reg_Rm(jit, REG_EDI, REG_EDI, MOD_REG); + IA32_Add_Rm_Reg(jit, REG_EDI, REG_EBP, MOD_REG); + IA32_Cld(jit); + IA32_Rep(jit); + IA32_Stosd(jit); + IA32_Pop_Reg(jit, REG_EDI); + IA32_Pop_Reg(jit, REG_EAX); + } } else { //mov ecx, num_dims + //mov edx, 0/1 //call [genarray] IA32_Mov_Reg_Imm32(jit, AMX_REG_TMP, val); + if (autozero) + { + IA32_Mov_Reg_Imm32(jit, REG_EDX, 1); + } else { + IA32_Mov_Reg_Imm32(jit, REG_EDX, 0); + } jitoffs_t call = IA32_Call_Imm32(jit, 0); IA32_Write_Jump32(jit, call, ((CompData *)jit->data)->jit_genarray); } diff --git a/sourcepawn/vm/jit/x86/opcode_helpers.cpp b/sourcepawn/vm/jit/x86/opcode_helpers.cpp index 8e1e3c7f..d6b6b54e 100644 --- a/sourcepawn/vm/jit/x86/opcode_helpers.cpp +++ b/sourcepawn/vm/jit/x86/opcode_helpers.cpp @@ -451,11 +451,12 @@ void WriteOp_Sysreq_C_Function(JitWriter *jit) IA32_Return(jit); } -void GenerateArrayIndirectionVectors(cell_t *arraybase, cell_t dims[], ucell_t dimcount) +void GenerateArrayIndirectionVectors(cell_t *arraybase, cell_t dims[], ucell_t _dimcount, bool autozero) { cell_t vectors = 1; /* we need one vector to start off with */ cell_t cur_offs = 0; cell_t cur_write = 0; + cell_t dimcount = _dimcount; /* Initialize rotation */ cur_write = dims[dimcount-1]; @@ -476,6 +477,17 @@ void GenerateArrayIndirectionVectors(cell_t *arraybase, cell_t dims[], ucell_t d vectors = cur_dim; } + /* everything after cur_offs can be zeroed */ + if (autozero) + { + size_t size = 1; + for (ucell_t i=0; i<_dimcount; i++) + { + size *= dims[i]; + } + memset(&arraybase[cur_offs], 0, size*sizeof(cell_t)); + } + return; } @@ -492,9 +504,11 @@ void WriteIntrinsic_GenArray(JitWriter *jit) */ //push ebx //push eax + //push edx //push ecx ;value is referenced on stack IA32_Push_Reg(jit, REG_EBX); IA32_Push_Reg(jit, REG_EAX); + IA32_Push_Reg(jit, REG_EDX); IA32_Push_Reg(jit, REG_ECX); /** @@ -557,17 +571,19 @@ void WriteIntrinsic_GenArray(JitWriter *jit) * I'm letting the compiler handle it and thus it's in C. */ //lea ebx, [ebp+eax] ;get base pointer - //push dword [esp-4] ;push dimension count + //push dword [esp-8] ;push autozero + //push dword [esp-8] ;push dimension count //push edi ;push dim array //push ebx //call GenerateArrayIndirectionVectors //add esp, 4*3 IA32_Lea_Reg_DispRegMult(jit, REG_EBX, REG_EAX, REG_EBP, NOSCALE); - IA32_Push_Rm_Disp8_ESP(jit, 4); + IA32_Push_Rm_Disp8_ESP(jit, 8); + IA32_Push_Rm_Disp8_ESP(jit, 8); IA32_Push_Reg(jit, REG_EDI); IA32_Push_Reg(jit, REG_EBX); IA32_Write_Jump32_Abs(jit, IA32_Call_Imm32(jit, 0), (void *)&GenerateArrayIndirectionVectors); - IA32_Add_Rm_Imm8(jit, REG_ESP, 4*3, MOD_REG); + IA32_Add_Rm_Imm8(jit, REG_ESP, 4*4, MOD_REG); /* Store the heap pointer back into the stack */ //pop eax ;restore heap pointer @@ -580,9 +596,11 @@ void WriteIntrinsic_GenArray(JitWriter *jit) IA32_Mov_Rm_Reg(jit, AMX_REG_STK, REG_EAX, MOD_MEM_REG); /* Return to caller */ + //pop edx //pop eax //pop ebx //ret + IA32_Pop_Reg(jit, REG_ECX); IA32_Pop_Reg(jit, REG_EAX); IA32_Pop_Reg(jit, REG_EBX); IA32_Return(jit); diff --git a/sourcepawn/vm/jit/x86/opcode_helpers.h b/sourcepawn/vm/jit/x86/opcode_helpers.h index 3cf1942a..0afe8498 100644 --- a/sourcepawn/vm/jit/x86/opcode_helpers.h +++ b/sourcepawn/vm/jit/x86/opcode_helpers.h @@ -245,9 +245,10 @@ typedef enum OP_SYSREQ_D, // !GEN UNSUPPORT OP_SYSREQ_ND, // !GEN UNSUPPORT /* ----- */ - OP_HEAP_I, // - OP_PUSH_HEAP_C, //DONE - OP_GENARRAY, // + OP_HEAP_I, //VERIFIED + OP_PUSH_HEAP_C, //VERIFIED + OP_GENARRAY, //VERIFIED + OP_GENARRAY_Z, //-VERIFIED (not tested for 1D arrays) /* ----- */ OP_NUM_OPCODES } OPCODE; diff --git a/sourcepawn/vm/jit/x86/opcode_switch.inc b/sourcepawn/vm/jit/x86/opcode_switch.inc index 6b2e3946..d5786fec 100644 --- a/sourcepawn/vm/jit/x86/opcode_switch.inc +++ b/sourcepawn/vm/jit/x86/opcode_switch.inc @@ -655,7 +655,12 @@ } case OP_GENARRAY: { - WriteOp_GenArray(jit); + WriteOp_GenArray(jit, false); + break; + } + case OP_GENARRAY_Z: + { + WriteOp_GenArray(jit, true); break; } #if defined USE_UNGEN_OPCODES