From 0ece7914b77c9171788b845b33613c8eb3c656d8 Mon Sep 17 00:00:00 2001 From: Borja Ferrer Date: Sat, 4 Nov 2006 18:30:20 +0000 Subject: [PATCH] added tracker push helper dyn arrays are working now --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40139 --- sourcepawn/vm/jit/x86/jit_x86.cpp | 18 +++--- sourcepawn/vm/jit/x86/opcode_helpers.cpp | 78 +++++++++++++++++++++--- sourcepawn/vm/jit/x86/opcode_helpers.h | 9 ++- 3 files changed, 88 insertions(+), 17 deletions(-) diff --git a/sourcepawn/vm/jit/x86/jit_x86.cpp b/sourcepawn/vm/jit/x86/jit_x86.cpp index 2991e402..ca066953 100644 --- a/sourcepawn/vm/jit/x86/jit_x86.cpp +++ b/sourcepawn/vm/jit/x86/jit_x86.cpp @@ -1003,11 +1003,11 @@ inline void WriteOp_GenArray(JitWriter *jit, bool autozero) IA32_Mov_Rm_Reg(jit, AMX_REG_STK, AMX_REG_ALT, MOD_MEM_REG); IA32_Lea_Reg_DispRegMult(jit, AMX_REG_ALT, AMX_REG_ALT, AMX_REG_TMP, SCALE4); IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, AMX_REG_ALT, AMX_INFO_HEAP); - IA32_Add_Rm_Reg(jit, AMX_REG_ALT, AMX_REG_DAT, MOD_REG); - IA32_Cmp_Rm_Reg(jit, AMX_REG_ALT, AMX_REG_STK, MOD_REG); + IA32_Add_Reg_Rm(jit, AMX_REG_ALT, AMX_REG_DAT, MOD_REG); + IA32_Cmp_Reg_Rm(jit, AMX_REG_ALT, AMX_REG_STK, MOD_REG); IA32_Jump_Cond_Imm32_Abs(jit, CC_AE, ((CompData *)jit->data)->jit_error_heaplow); - /* :TODO: PUSH ECX ONTO TRACKER */ + WriteOp_Tracker_Push_Reg(jit, REG_ECX); if (autozero) { @@ -1024,8 +1024,8 @@ inline void WriteOp_GenArray(JitWriter *jit, bool autozero) 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_Mov_Reg_Rm(jit, REG_EDI, REG_EDI, MOD_MEM_REG); + IA32_Add_Reg_Rm(jit, REG_EDI, REG_EBP, MOD_REG); IA32_Cld(jit); IA32_Rep(jit); IA32_Stosd(jit); @@ -1624,11 +1624,11 @@ inline void WriteOp_Tracker_Push_C(JitWriter *jit) /* Push the value into the stack and increment pCur */ //mov edx, [eax+vm[]] //mov ecx, [edx+pcur] - //mov [ecx], + //mov [ecx], *4 ; we want the count in bytes not in cells //add [edx+pcur], 4 IA32_Mov_Reg_Rm_Disp8(jit, REG_EDX, REG_EAX, offsetof(sp_context_t, vm[JITVARS_TRACKER])); IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, REG_EDX, offsetof(tracker_t, pCur)); - IA32_Mov_Rm_Imm32(jit, AMX_REG_TMP, val, MOD_MEM_REG); + IA32_Mov_Rm_Imm32(jit, AMX_REG_TMP, val*4, MOD_MEM_REG); IA32_Add_Rm_Imm8_Disp8(jit, REG_EDX, 4, offsetof(tracker_t, pCur)); /* Restore PRI & ALT */ @@ -1677,6 +1677,8 @@ inline void WriteOp_Tracker_Pop_SetHeap(JitWriter *jit) IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_TMP, MOD_MEM_REG); IA32_Sub_Rm_Reg_Disp8(jit, AMX_REG_INFO, AMX_REG_TMP, AMX_INFO_HEAP); + Write_CheckHeap_Min(jit); + /* Restore PRI & ALT */ //pop edx //pop eax @@ -2038,7 +2040,7 @@ jit_rewind: ctx->vm[JITVARS_TRACKER] = trk; trk->pBase = (ucell_t *)malloc(1024); trk->pCur = trk->pBase; - trk->size = 1024; + trk->size = 1024 / sizeof(cell_t); /* clean up relocation+compilation memory */ AbortCompilation(co); diff --git a/sourcepawn/vm/jit/x86/opcode_helpers.cpp b/sourcepawn/vm/jit/x86/opcode_helpers.cpp index 35203f2a..555b3605 100644 --- a/sourcepawn/vm/jit/x86/opcode_helpers.cpp +++ b/sourcepawn/vm/jit/x86/opcode_helpers.cpp @@ -107,7 +107,7 @@ jitoffs_t Write_Execute_Function(JitWriter *jit) IA32_Sub_Reg_Rm(jit, REG_EDI, REG_EBP, MOD_REG); IA32_Mov_Reg_Rm_Disp8(jit, REG_EDX, REG_ESI, AMX_INFO_HEAP); IA32_Mov_Rm_Reg_Disp8(jit, REG_ECX, REG_EDI, offsetof(sp_context_t, sp)); - IA32_Mov_Rm_Reg(jit, REG_ECX, REG_EDX, MOD_REG); + IA32_Mov_Rm_Reg_Disp8(jit, REG_ECX, REG_EDX, offsetof(sp_context_t, hp)); //add esp, 4*NUM_INFO_PARAMS //pop ebx @@ -521,7 +521,7 @@ void WriteIntrinsic_GenArray(JitWriter *jit) //mov ecx, [edi+eax*4] ;get dimension size //imul edx, ecx ;multiply by size //add edx, ecx ;add size (indirection vector) - //inc eax ;increment + //add eax, 1 ;increment //jmp :loop ;jump back //:done IA32_Mov_Reg_Rm(jit, REG_EDX, AMX_REG_STK, MOD_MEM_REG); @@ -531,8 +531,8 @@ void WriteIntrinsic_GenArray(JitWriter *jit) jitoffs_t done1 = IA32_Jump_Cond_Imm8(jit, CC_AE, 0); IA32_Mov_Reg_Rm_Disp_Reg(jit, REG_ECX, AMX_REG_STK, REG_EAX, SCALE4); IA32_IMul_Reg_Rm(jit, REG_EDX, REG_ECX, MOD_REG); - IA32_Add_Rm_Reg(jit, REG_EDX, REG_ECX, MOD_REG); - IA32_Inc_Reg(jit, REG_EAX); + IA32_Add_Reg_Rm(jit, REG_EDX, REG_ECX, MOD_REG); + IA32_Add_Rm_Imm8(jit, REG_EAX, 1, MOD_REG); IA32_Write_Jump8(jit, IA32_Jump_Imm8(jit, loop1), loop1); IA32_Send_Jump8_Here(jit, done1); @@ -548,7 +548,7 @@ void WriteIntrinsic_GenArray(JitWriter *jit) IA32_Lea_Reg_DispRegMult(jit, REG_EAX, REG_EAX, REG_EDX, SCALE4); IA32_Cmp_Rm_Imm32(jit, MOD_REG, REG_EAX, ((CompData *)jit->data)->plugin->data_size); IA32_Jump_Cond_Imm32_Abs(jit, CC_BE, ((CompData *)jit->data)->jit_error_array_too_big); - IA32_Add_Rm_Reg(jit, REG_EAX, AMX_REG_DAT, MOD_REG); + IA32_Add_Reg_Rm(jit, REG_EAX, AMX_REG_DAT, MOD_REG); IA32_Cmp_Reg_Rm(jit, REG_EAX, AMX_REG_STK, MOD_REG); IA32_Jump_Cond_Imm32_Abs(jit, CC_AE, ((CompData *)jit->data)->jit_error_array_too_big); @@ -562,7 +562,7 @@ void WriteIntrinsic_GenArray(JitWriter *jit) IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, REG_EBX, AMX_INFO_HEAP); IA32_Push_Reg(jit, REG_EAX); - /* :TODO: Push EDX into tracker */ + WriteOp_Tracker_Push_Reg(jit, REG_EDX); /* This part is too messy to do in straight assembly. * I'm letting the compiler handle it and thus it's in C. @@ -686,6 +686,70 @@ void WriteOp_Sysreq_N_Function(JitWriter *jit) IA32_Return(jit); } +void WriteOp_Tracker_Push_Reg(JitWriter *jit, uint8_t reg) +{ + CompData *data = (CompData *)jit->data; + + //:TODO: optimize reg usage, i dont like it. + + /* Save registers that may be damaged by the call */ + //push eax + //push edx + //push ecx + //push + IA32_Push_Reg(jit, AMX_REG_PRI); + IA32_Push_Reg(jit, AMX_REG_ALT); + IA32_Push_Reg(jit, AMX_REG_TMP); + if (reg != REG_ECX) + { + IA32_Push_Reg(jit, reg); + } + + /* Get the context ptr, push it and call the check */ + //mov eax, [esi+context] + //push eax + //call JIT_VerifyOrAllocateTracker + IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, AMX_REG_INFO, AMX_INFO_CONTEXT); + IA32_Push_Reg(jit, REG_EAX); + jitoffs_t call = IA32_Call_Imm32(jit, 0); + IA32_Write_Jump32_Abs(jit, call, JIT_VerifyOrAllocateTracker); + + /* Check for errors */ + //pop eax + //cmp [eax+err], 0 + //jnz :error + IA32_Pop_Reg(jit, REG_EAX); + IA32_Cmp_Rm_Disp8_Imm8(jit, REG_EAX, offsetof(sp_context_t, err), 0); + IA32_Jump_Cond_Imm32_Abs(jit, CC_NZ, data->jit_error_tracker_bounds); + + /* Push the register into the stack and increment pCur */ + //pop ecx + //mov edx, [eax+vm[]] + //mov eax, [edx+pcur] + //lea ecx, [ecx*4] ; we want the count in bytes not in cells + //mov [eax], ecx + //add [edx+pcur], 4 + IA32_Pop_Reg(jit, REG_ECX); + IA32_Mov_Reg_Rm_Disp8(jit, REG_EDX, REG_EAX, offsetof(sp_context_t, vm[JITVARS_TRACKER])); + IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, REG_EDX, offsetof(tracker_t, pCur)); + IA32_Lea_Reg_RegMultImm32(jit, REG_ECX, REG_ECX, SCALE4, 0); + IA32_Mov_Rm_Reg(jit, REG_EAX, REG_ECX, MOD_MEM_REG); + IA32_Add_Rm_Imm8_Disp8(jit, REG_EDX, 4, offsetof(tracker_t, pCur)); + + /* Restore PRI, ALT and STK */ + //pop ecx + //pop edx + //pop eax + if (reg != REG_ECX) + { + IA32_Pop_Reg(jit, AMX_REG_ALT); + } else { + IA32_Shr_Rm_Imm8(jit, REG_ECX, 2, MOD_REG); + } + IA32_Pop_Reg(jit, AMX_REG_TMP); + IA32_Pop_Reg(jit, AMX_REG_PRI); +} + void JIT_VerifyOrAllocateTracker(sp_context_t *ctx) { tracker_t *trk = (tracker_t *)(ctx->vm[JITVARS_TRACKER]); @@ -700,7 +764,7 @@ void JIT_VerifyOrAllocateTracker(sp_context_t *ctx) { size_t disp = trk->size - 1; trk->size *= 2; - trk->pBase = (ucell_t *)realloc(trk->pBase, trk->size); + trk->pBase = (ucell_t *)realloc(trk->pBase, trk->size * sizeof(cell_t)); if (!trk->pBase) { diff --git a/sourcepawn/vm/jit/x86/opcode_helpers.h b/sourcepawn/vm/jit/x86/opcode_helpers.h index f47e85bc..5cddf40f 100644 --- a/sourcepawn/vm/jit/x86/opcode_helpers.h +++ b/sourcepawn/vm/jit/x86/opcode_helpers.h @@ -72,6 +72,11 @@ void Macro_PushN(JitWriter *jit, int i); void JIT_VerifyLowBoundTracker(sp_context_t *ctx); void JIT_VerifyOrAllocateTracker(sp_context_t *ctx); +/** +* Writes the push into tracker function. +*/ +void WriteOp_Tracker_Push_Reg(JitWriter *jit, uint8_t reg); + /** * Legend for Statuses: * ****** *** ******** @@ -252,7 +257,7 @@ typedef enum OP_SYSREQ_ND, // !GEN UNSUPPORT /* ----- */ OP_TRACKER_PUSH_C, //DONE - OP_TRACKER_POP_SETHEAP, //DONE + OP_TRACKER_POP_SETHEAP, //VERIFIED OP_GENARRAY, //VERIFIED OP_GENARRAY_Z, //-VERIFIED (not tested for 1D arrays) /* ----- */ @@ -262,8 +267,8 @@ typedef enum /* * :TODO: List of ASM Opts * from jit_x86.cpp -* TODO: all new array opcodes (4 ATM) * 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)