Added new op.genarray for dynamic arrays

Fixed up opcode table for new opcodes

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40125
This commit is contained in:
David Anderson 2006-10-16 04:10:01 +00:00
parent a19823e4c6
commit 209dd31751
6 changed files with 75 additions and 37 deletions

View File

@ -960,15 +960,55 @@ inline void WriteOp_Fill(JitWriter *jit)
IA32_Pop_Reg(jit, REG_EDI);
}
inline void WriteOp_Heap_Pri(JitWriter *jit)
inline void WriteOp_Heap_I(JitWriter *jit)
{
//mov edx, [esi+hea]
//add [esi+hea], eax
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_ALT, AMX_REG_INFO, AMX_INFO_HEAP);
IA32_Add_Rm_Reg_Disp8(jit, AMX_REG_INFO, AMX_REG_PRI, AMX_INFO_HEAP);
//sub [esi+hea], 4
//mov ecx, [esi+hea]
//mov ecx, [ebp+ecx]
//sub [esi+hea], ecx
IA32_Sub_Rm_Imm8_Disp8(jit, AMX_REG_INFO, 4, AMX_INFO_HEAP);
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_HEAP);
IA32_Mov_Reg_RmEBP_Disp_Reg(jit, AMX_REG_TMP, AMX_REG_DAT, AMX_REG_TMP, NOSCALE);
IA32_Add_Rm_Reg_Disp8(jit, AMX_REG_INFO, AMX_REG_TMP, AMX_INFO_HEAP);
/* :TODO: should we do a full bounds check here? */
Write_CheckHeap_Min(jit);
Write_CheckHeap_Low(jit);
}
inline void WriteOp_GenArray(JitWriter *jit)
{
cell_t val = jit->read_cell();
if (val == 1)
{
/* flat array. we can generate this without indirection tables. */
/* Note that we can overwrite ALT because technically STACK should be destroying ALT */
//mov edx, [esi+info.heap]
//mov ecx, [edi]
//mov [edi], edx ;store base of array into stack
//lea edx, [edx+ecx*4+4] ;get the final new heap pointer
//mov [esi+info.heap], edx ;store heap pointer back
//add edx, ebp ;relocate
//cmp edx, edi ;compare against stack pointer
//jae :error ;error out if not enough space
//shl ecx, 2
//mov [edx-4], ecx ;store # of cells allocated
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_ALT, AMX_REG_INFO, AMX_INFO_HEAP);
IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_STK, MOD_MEM_REG);
IA32_Mov_Rm_Reg(jit, AMX_REG_STK, AMX_REG_ALT, MOD_MEM_REG);
IA32_Lea_Reg_DispRegMultImm8(jit, AMX_REG_ALT, AMX_REG_ALT, AMX_REG_TMP, SCALE4, 4);
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_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);
} else {
//mov ecx, num_dims
//call [genarray]
IA32_Mov_Reg_Imm32(jit, AMX_REG_TMP, val);
jitoffs_t call = IA32_Call_Imm32(jit, 0);
IA32_Write_Jump32(jit, call, ((CompData *)jit->data)->jit_genarray);
}
}
inline void WriteOp_Push_Heap_C(JitWriter *jit)
@ -984,18 +1024,6 @@ inline void WriteOp_Push_Heap_C(JitWriter *jit)
Write_CheckHeap_Low(jit);
}
inline void WriteOp_Pop_Heap_Pri(JitWriter *jit)
{
//sub [esi+hea], 4
//mov ecx, [esi+hea]
//mov eax, [ebp+ecx]
IA32_Sub_Rm_Imm8_Disp8(jit, AMX_REG_INFO, 4, AMX_INFO_HEAP);
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_HEAP);
IA32_Mov_Reg_RmEBP_Disp_Reg(jit, AMX_REG_PRI, AMX_REG_DAT, AMX_REG_TMP, NOSCALE);
Write_CheckHeap_Min(jit);
}
inline void WriteOp_Load_Both(JitWriter *jit)
{
WriteOp_Load_Pri(jit);

View File

@ -27,6 +27,7 @@ public:
jitoffs_t jit_verify_addr_edx;
jitoffs_t jit_break; /* call to op.break */
jitoffs_t jit_sysreq_n; /* call version of op.sysreq.n */
jitoffs_t jit_genarray; /* call to genarray intrinsic */
jitoffs_t jit_error_bounds;
jitoffs_t jit_error_divzero;
jitoffs_t jit_error_stacklow;

View File

@ -451,6 +451,10 @@ void WriteOp_Sysreq_C_Function(JitWriter *jit)
IA32_Return(jit);
}
void WriteIntrinsic_GenArray(JitWriter *jit)
{
}
void WriteOp_Sysreq_N_Function(JitWriter *jit)
{
/* The big daddy of opcodes.

View File

@ -16,6 +16,11 @@ jitoffs_t Write_Execute_Function(JitWriter *jit);
void WriteOp_Sysreq_N_Function(JitWriter *jit);
void WriteOp_Sysreq_C_Function(JitWriter *jit);
/**
* Write the GENARRAY intrinsic function.
*/
void WriteIntrinsic_GenArray(JitWriter *jit);
/**
* Generates code to set an error state in the VM and return.
* This is used for generating the error set points in the VM.
@ -240,9 +245,9 @@ typedef enum
OP_SYSREQ_D, // !GEN UNSUPPORT
OP_SYSREQ_ND, // !GEN UNSUPPORT
/* ----- */
OP_HEAP_PRI, //DONE
OP_HEAP_I, //
OP_PUSH_HEAP_C, //DONE
OP_POP_HEAP_PRI, //DONE
OP_GENARRAY, //
/* ----- */
OP_NUM_OPCODES
} OPCODE;

View File

@ -458,21 +458,6 @@
WriteOp_Fill(jit);
break;
}
case OP_HEAP_PRI:
{
WriteOp_Heap_Pri(jit);
break;
}
case OP_PUSH_HEAP_C:
{
WriteOp_Push_Heap_C(jit);
break;
}
case OP_POP_HEAP_PRI:
{
WriteOp_Pop_Heap_Pri(jit);
break;
}
case OP_PUSH_C:
{
WriteOp_Push_C(jit);
@ -658,6 +643,21 @@
}
break;
}
case OP_PUSH_HEAP_C:
{
WriteOp_Push_Heap_C(jit);
break;
}
case OP_HEAP_I:
{
WriteOp_Heap_I(jit);
break;
}
case OP_GENARRAY:
{
WriteOp_GenArray(jit);
break;
}
#if defined USE_UNGEN_OPCODES
#include "ungen_opcode_switch.inc"
#endif

View File

@ -82,6 +82,8 @@
#define IA32_CMP_RM_IMM8 0x83 // encoding is /7 <imm8>
#define IA32_CMP_AL_IMM32 0x3C // no extra encoding
#define IA32_CMP_EAX_IMM32 0x3D // no extra encoding
#define IA32_CMP_RM_REG 0x39 // encoding is /r
#define IA32_CMP_REG_RM 0x3B // encoding is /r
#define IA32_CMPSB 0xA6 // no extra encoding
#define IA32_TEST_RM_REG 0x85 // encoding is /r
#define IA32_JCC_IMM 0x70 // encoding is +cc <imm8>
@ -110,8 +112,6 @@
#define IA32_SHR_RM_CL 0xD3 // encoding is /5
#define IA32_SHL_RM_CL 0xD3 // encoding is /4
#define IA32_SAR_RM_IMM8 0xC1 // encoding is /7 <ib>
#define IA32_CMP_RM_REG 0x39 // encoding is /r
#define IA32_CMP_REG_RM 0x3B // encoding is /r
#define IA32_SETCC_RM8_1 0x0F // opcode part 1
#define IA32_SETCC_RM8_2 0x90 // encoding is +cc /0 (8bits)
#define IA32_XCHG_EAX_REG 0x90 // encoding is +r