added support for op.genarray.z opcode

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40129
This commit is contained in:
David Anderson 2006-10-17 05:50:59 +00:00
parent 53be062c6b
commit 0c67ad1e7d
4 changed files with 63 additions and 9 deletions

View File

@ -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);
}

View File

@ -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);

View File

@ -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;

View File

@ -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