finished dynamic array generation
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40126
This commit is contained in:
parent
209dd31751
commit
eb341f9a1d
@ -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))
|
||||
{
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user