finished dynamic array generation

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40126
This commit is contained in:
David Anderson 2006-10-16 22:25:18 +00:00
parent 209dd31751
commit eb341f9a1d
4 changed files with 178 additions and 8 deletions

View File

@ -1087,21 +1087,14 @@ inline void WriteOp_Lidx(JitWriter *jit)
inline void WriteOp_Stack(JitWriter *jit)
{
/* :TODO: Find an instance in the compiler where
* the ALT value from STACK is actually used!
*/
//mov edx, edi
//add edi, <val>
//sub edx, ebp
cell_t val = jit->read_cell();
IA32_Mov_Reg_Rm(jit, AMX_REG_ALT, AMX_REG_STK, MOD_REG);
if (val < SCHAR_MAX && val > SCHAR_MIN)
{
IA32_Add_Rm_Imm8(jit, AMX_REG_STK, (jit_int8_t)val, MOD_REG);
} else {
IA32_Add_Rm_Imm32(jit, AMX_REG_STK, val, MOD_REG);
}
IA32_Sub_Reg_Rm(jit, AMX_REG_ALT, AMX_REG_DAT, MOD_REG);
if (val > 0)
{
@ -1674,6 +1667,9 @@ void WriteErrorRoutines(CompData *data, JitWriter *jit)
data->jit_error_heapmin = jit->get_outputpos();
Write_SetError(jit, SP_ERROR_HEAPMIN);
data->jit_error_array_too_big = jit->get_outputpos();
Write_SetError(jit, SP_ERROR_ARRAY_TOO_BIG);
data->jit_extern_error = jit->get_outputpos();
Write_GetError(jit);
}
@ -1728,6 +1724,9 @@ jit_rewind:
data->jit_sysreq_c = jit->get_outputpos();
WriteOp_Sysreq_C_Function(jit);
data->jit_genarray = jit->get_outputpos();
WriteIntrinsic_GenArray(jit);
/* Write error checking routines that are called to */
if (!(data->inline_level & JIT_INLINE_ERRORCHECKS))
{

View File

@ -35,6 +35,7 @@ public:
jitoffs_t jit_error_memaccess;
jitoffs_t jit_error_heaplow;
jitoffs_t jit_error_heapmin;
jitoffs_t jit_error_array_too_big;
jitoffs_t jit_extern_error; /* returning generic error */
jitoffs_t jit_sysreq_c; /* old version! */
uint32_t codesize; /* total codesize */

View File

@ -451,8 +451,141 @@ void WriteOp_Sysreq_C_Function(JitWriter *jit)
IA32_Return(jit);
}
void GenerateArrayIndirectionVectors(cell_t *arraybase, cell_t dims[], ucell_t dimcount)
{
cell_t vectors = 1; /* we need one vector to start off with */
cell_t cur_offs = 0;
cell_t cur_write = 0;
/* Initialize rotation */
cur_write = dims[dimcount-1];
while (--dimcount >= 1)
{
cell_t cur_dim = dims[dimcount];
cell_t sub_dim = dims[dimcount-1];
for (cell_t i=0; i<vectors; i++)
{
for (cell_t j=0; j<cur_dim; j++)
{
arraybase[cur_offs] = (cur_write - cur_offs)*sizeof(cell_t);
cur_offs++;
cur_write += sub_dim;
}
}
vectors = cur_dim;
}
return;
}
/**
* A few notes about this function.
* I was more concerned about efficient use of registers here, rather than
* fine-tuned optimization. The reason is that the code is already complicated,
* and it is very easy to mess up.
*/
void WriteIntrinsic_GenArray(JitWriter *jit)
{
/**
* save important values
*/
//push ebx
//push eax
//push ecx ;value is referenced on stack
IA32_Push_Reg(jit, REG_EBX);
IA32_Push_Reg(jit, REG_EAX);
IA32_Push_Reg(jit, REG_ECX);
/**
* Calculate how many cells will be needed.
*/
//mov edx, [edi] ;get last dimension's count
//mov eax, 1 ;position at second to last dimension
//:loop
//cmp eax, [esp] ;compare to # of params
//jae :done ;end loop if done
//mov ecx, [edi+eax*4] ;get dimension size
//imul edx, ecx ;multiply by size
//add edx, ecx ;add size (indirection vector)
//inc eax ;increment
//jmp :loop ;jump back
//:done
IA32_Mov_Reg_Rm(jit, REG_EDX, AMX_REG_STK, MOD_MEM_REG);
IA32_Mov_Reg_Imm32(jit, REG_EAX, 1);
jitoffs_t loop1 = jit->get_outputpos();
IA32_Cmp_Reg_Rm_ESP(jit, REG_EAX);
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_Write_Jump8(jit, IA32_Jump_Imm8(jit, loop1), loop1);
IA32_Send_Jump8_Here(jit, done1);
/* Test if we have heap space for this */
//mov eax, [esi+info.heap] ;get heap pointer
//lea eax, [eax+edx*4+4] ;new heap pointer
//cmp eax, <hlw> ;compare to heap low
//jbe :error ;die if we hit this (it should always be >)
//add eax, ebp ;relocate to stack
//cmp eax, edi ;die if above the stack pointer
//jae :error
IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, AMX_REG_INFO, AMX_INFO_HEAP);
IA32_Lea_Reg_DispRegMultImm8(jit, REG_EAX, REG_EAX, REG_EDX, SCALE4, 4);
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_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);
/* Prepare for indirection iteration */
//mov eax, [esi+info.heap] ;get heap pointer
//lea ebx, [eax+edx*4+4] ;new heap pointer
//mov [esi+info.heap], ebx ;store back
//lea ebx, [ebp+ebx-4] ;relocate
//mov [ebx], edx ;store back total size
//push eax ;save heap pointer - we need it
IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, AMX_REG_INFO, AMX_INFO_HEAP);
IA32_Lea_Reg_DispRegMultImm8(jit, REG_EBX, REG_EAX, REG_EDX, SCALE4, 4);
IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, REG_EBX, AMX_INFO_HEAP);
IA32_Lea_Reg_DispRegMultImm8(jit, REG_EBX, AMX_REG_DAT, REG_EBX, NOSCALE, -4);
IA32_Mov_Rm_Reg(jit, REG_EBX, REG_EDX, MOD_MEM_REG);
IA32_Push_Reg(jit, REG_EAX);
/* This part is too messy to do in straight assembly.
* 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 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_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);
/* Store the heap pointer back into the stack */
//pop eax ;restore heap pointer
//pop ecx ;restore param count
//lea edi, [edi+ecx*4-4] ;pop params-4 off the stack
//mov [edi], eax ;store back the heap pointer
IA32_Pop_Reg(jit, REG_EAX);
IA32_Pop_Reg(jit, REG_ECX);
IA32_Lea_Reg_DispRegMultImm8(jit, AMX_REG_STK, AMX_REG_STK, REG_ECX, SCALE4, -4);
IA32_Mov_Rm_Reg(jit, AMX_REG_STK, REG_EAX, MOD_MEM_REG);
/* Return to caller */
//pop eax
//pop ebx
//ret
IA32_Pop_Reg(jit, REG_EAX);
IA32_Pop_Reg(jit, REG_EBX);
IA32_Return(jit);
}
void WriteOp_Sysreq_N_Function(JitWriter *jit)

View File

@ -102,10 +102,12 @@
#define IA32_NOT_RM 0xF7 // encoding is /2
#define IA32_DIV_RM 0xF7 // encoding is /6
#define IA32_MUL_RM 0xF7 // encoding is /4
#define IA32_IMUL_RM 0xF7 // encoding is /5
#define IA32_IDIV_RM 0xF7 // encoding is /7
#define IA32_IMUL_RM 0xF7 // encoding is /5
#define IA32_IMUL_REG_IMM32 0x69 // encoding is /r
#define IA32_IMUL_REG_IMM8 0x6B // encoding is /r
#define IA32_IMUL_REG_RM_1 0x0F // encoding is _2
#define IA32_IMUL_REG_RM_2 0xAF // encoding is /r
#define IA32_SHR_RM_IMM8 0xC1 // encoding is /5 <ib>
#define IA32_SHL_RM_IMM8 0xC1 // encoding is /4 <ib>
#define IA32_SAR_RM_CL 0xD3 // encoding is /7
@ -445,6 +447,13 @@ inline void IA32_IMul_Reg_Imm32(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mod
jit->write_int32(value);
}
inline void IA32_IMul_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
{
jit->write_ubyte(IA32_IMUL_REG_RM_1);
jit->write_ubyte(IA32_IMUL_REG_RM_2);
jit->write_ubyte(ia32_modrm(mode, dest, src));
}
inline void IA32_Add_Rm_Reg_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
{
jit->write_ubyte(IA32_ADD_RM_REG);
@ -634,6 +643,14 @@ inline void IA32_Push_Rm_Disp8(JitWriter *jit, jit_uint8_t reg, jit_int8_t disp8
jit->write_byte(disp8);
}
inline void IA32_Push_Rm_Disp8_ESP(JitWriter *jit, jit_int8_t disp8)
{
jit->write_ubyte(IA32_PUSH_RM);
jit->write_ubyte(ia32_modrm(MOD_DISP8, 6, REG_SIB));
jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP));
jit->write_byte(disp8);
}
/**
* Moving from REGISTER/MEMORY to REGISTER
*/
@ -677,6 +694,19 @@ inline void IA32_Mov_Reg_Rm_Disp_Reg(JitWriter *jit,
jit->write_ubyte(ia32_sib(src_scale, src_index, src_base));
}
inline void IA32_Mov_Reg_Rm_Disp_Reg_Disp8(JitWriter *jit,
jit_uint8_t dest,
jit_uint8_t src_base,
jit_uint8_t src_index,
jit_uint8_t src_scale,
jit_int8_t disp8)
{
jit->write_ubyte(IA32_MOV_REG_MEM);
jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, REG_SIB));
jit->write_ubyte(ia32_sib(src_scale, src_index, src_base));
jit->write_byte(disp8);
}
inline void IA32_Mov_Reg_RmEBP_Disp_Reg(JitWriter *jit,
jit_uint8_t dest,
jit_uint8_t src_base,
@ -968,6 +998,13 @@ inline void IA32_Cmp_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, j
jit->write_ubyte(ia32_modrm(mode, dest, src));
}
inline void IA32_Cmp_Reg_Rm_ESP(JitWriter *jit, jit_uint8_t cmpreg)
{
jit->write_ubyte(IA32_CMP_REG_RM);
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, cmpreg, REG_SIB));
jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP));
}
inline void IA32_Cmp_Reg_Rm_Disp8(JitWriter *jit, jit_uint8_t reg1, jit_uint8_t reg2, jit_int8_t disp8)
{
jit->write_ubyte(IA32_CMP_REG_RM);