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); Write_CheckHeap_Low(jit);
} }
inline void WriteOp_GenArray(JitWriter *jit) inline void WriteOp_GenArray(JitWriter *jit, bool autozero)
{ {
cell_t val = jit->read_cell(); cell_t val = jit->read_cell();
if (val == 1) 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_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_Shl_Rm_Imm8(jit, AMX_REG_TMP, 4, MOD_REG);
IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_ALT, AMX_REG_TMP, -4); 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 { } else {
//mov ecx, num_dims //mov ecx, num_dims
//mov edx, 0/1
//call [genarray] //call [genarray]
IA32_Mov_Reg_Imm32(jit, AMX_REG_TMP, val); 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); jitoffs_t call = IA32_Call_Imm32(jit, 0);
IA32_Write_Jump32(jit, call, ((CompData *)jit->data)->jit_genarray); 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); 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 vectors = 1; /* we need one vector to start off with */
cell_t cur_offs = 0; cell_t cur_offs = 0;
cell_t cur_write = 0; cell_t cur_write = 0;
cell_t dimcount = _dimcount;
/* Initialize rotation */ /* Initialize rotation */
cur_write = dims[dimcount-1]; cur_write = dims[dimcount-1];
@ -476,6 +477,17 @@ void GenerateArrayIndirectionVectors(cell_t *arraybase, cell_t dims[], ucell_t d
vectors = cur_dim; 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; return;
} }
@ -492,9 +504,11 @@ void WriteIntrinsic_GenArray(JitWriter *jit)
*/ */
//push ebx //push ebx
//push eax //push eax
//push edx
//push ecx ;value is referenced on stack //push ecx ;value is referenced on stack
IA32_Push_Reg(jit, REG_EBX); IA32_Push_Reg(jit, REG_EBX);
IA32_Push_Reg(jit, REG_EAX); IA32_Push_Reg(jit, REG_EAX);
IA32_Push_Reg(jit, REG_EDX);
IA32_Push_Reg(jit, REG_ECX); 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. * I'm letting the compiler handle it and thus it's in C.
*/ */
//lea ebx, [ebp+eax] ;get base pointer //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 edi ;push dim array
//push ebx //push ebx
//call GenerateArrayIndirectionVectors //call GenerateArrayIndirectionVectors
//add esp, 4*3 //add esp, 4*3
IA32_Lea_Reg_DispRegMult(jit, REG_EBX, REG_EAX, REG_EBP, NOSCALE); 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_EDI);
IA32_Push_Reg(jit, REG_EBX); IA32_Push_Reg(jit, REG_EBX);
IA32_Write_Jump32_Abs(jit, IA32_Call_Imm32(jit, 0), (void *)&GenerateArrayIndirectionVectors); 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 */ /* Store the heap pointer back into the stack */
//pop eax ;restore heap pointer //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); IA32_Mov_Rm_Reg(jit, AMX_REG_STK, REG_EAX, MOD_MEM_REG);
/* Return to caller */ /* Return to caller */
//pop edx
//pop eax //pop eax
//pop ebx //pop ebx
//ret //ret
IA32_Pop_Reg(jit, REG_ECX);
IA32_Pop_Reg(jit, REG_EAX); IA32_Pop_Reg(jit, REG_EAX);
IA32_Pop_Reg(jit, REG_EBX); IA32_Pop_Reg(jit, REG_EBX);
IA32_Return(jit); IA32_Return(jit);

View File

@ -245,9 +245,10 @@ typedef enum
OP_SYSREQ_D, // !GEN UNSUPPORT OP_SYSREQ_D, // !GEN UNSUPPORT
OP_SYSREQ_ND, // !GEN UNSUPPORT OP_SYSREQ_ND, // !GEN UNSUPPORT
/* ----- */ /* ----- */
OP_HEAP_I, // OP_HEAP_I, //VERIFIED
OP_PUSH_HEAP_C, //DONE OP_PUSH_HEAP_C, //VERIFIED
OP_GENARRAY, // OP_GENARRAY, //VERIFIED
OP_GENARRAY_Z, //-VERIFIED (not tested for 1D arrays)
/* ----- */ /* ----- */
OP_NUM_OPCODES OP_NUM_OPCODES
} OPCODE; } OPCODE;

View File

@ -655,7 +655,12 @@
} }
case OP_GENARRAY: case OP_GENARRAY:
{ {
WriteOp_GenArray(jit); WriteOp_GenArray(jit, false);
break;
}
case OP_GENARRAY_Z:
{
WriteOp_GenArray(jit, true);
break; break;
} }
#if defined USE_UNGEN_OPCODES #if defined USE_UNGEN_OPCODES