sourcepawn/vm/jit/x86/opcode_helpers.cpp
changeset 74 935d64738275
parent 73 9d08f3f63830
child 75 55682fa202ea
     1.1 --- a/sourcepawn/vm/jit/x86/opcode_helpers.cpp	Wed Sep 20 04:52:13 2006 +0000
     1.2 +++ b/sourcepawn/vm/jit/x86/opcode_helpers.cpp	Wed Sep 20 07:07:49 2006 +0000
     1.3 @@ -6,26 +6,129 @@
     1.4  
     1.5  int OpAdvTable[OP_NUM_OPCODES];
     1.6  
     1.7 -void Write_Prologue(JitWriter *jit)
     1.8 +jitoffs_t Write_Execute_Function(JitWriter *jit, bool never_inline)
     1.9  {
    1.10  	/** 
    1.11  	 * The state expected by our plugin is:
    1.12 -	 * #define AMX_REG_PRI		REG_EAX
    1.13 -	   #define AMX_REG_ALT		REG_EDX
    1.14 -	   #define AMX_REG_STK		REG_EBP
    1.15 -	   #define AMX_REG_DAT		REG_EDI
    1.16 -	   #define AMX_REG_TMP		REG_ECX
    1.17 -	   #define AMX_REG_INFO		REG_ESI
    1.18 -	   #define AMX_REG_FRM		REG_EBX
    1.19 -	   #define AMX_INFO_FRM		AMX_REG_INFO
    1.20 -	   #define AMX_INFO_HEAP	4
    1.21 -	   #define AMX_INFO_RETVAL	12
    1.22 +	 * #define AMX_REG_PRI		REG_EAX		(done)
    1.23 +	   #define AMX_REG_ALT		REG_EDX		(done)
    1.24 +	   #define AMX_REG_STK		REG_EBP		(done)
    1.25 +	   #define AMX_REG_DAT		REG_EDI		(done)
    1.26 +	   #define AMX_REG_TMP		REG_ECX		(nothing)
    1.27 +	   #define AMX_REG_INFO		REG_ESI		(done)
    1.28 +	   #define AMX_REG_FRM		REG_EBX		(done)
    1.29 +	   #define AMX_INFO_FRM		AMX_REG_INFO	(done)
    1.30 +	   #define AMX_INFO_HEAP	4			(done)
    1.31 +	   #define AMX_INFO_RETVAL	8			(done)
    1.32 +	   #define AMX_INFO_CONTEXT	12			(done)
    1.33  	 *
    1.34  	 * The variables we're passed in:
    1.35  	 *  sp_context_t *ctx, uint32_t code_idx, cell_t *result
    1.36  	 */
    1.37  
    1.38 +	/**
    1.39 +	 * !NOTE!
    1.40 +	 * Currently, we do not accept ctx->frm as the new frame pointer.
    1.41 +	 * Instead, we copy the frame from the stack pointer.
    1.42 +	 * This is because we do not support resuming or sleeping!
    1.43 +	 */
    1.44  
    1.45 +	//push ebp
    1.46 +	//mov ebp, esp
    1.47 +	IA32_Push_Reg(jit, REG_EBP);
    1.48 +	IA32_Mov_Reg_Rm(jit, REG_EBP, REG_ESP, MOD_REG);
    1.49 +
    1.50 +	//push esi
    1.51 +	//push edi
    1.52 +	//push ebx
    1.53 +	IA32_Push_Reg(jit, REG_ESI);
    1.54 +	IA32_Push_Reg(jit, REG_EDI);
    1.55 +	IA32_Push_Reg(jit, REG_EBX);
    1.56 +
    1.57 +	//sub esp, 4*4	- allocate info array
    1.58 +	//mov esi, esp	- save info pointer
    1.59 +	IA32_Sub_Rm_Imm8(jit, REG_ESP, 4*4, MOD_REG);
    1.60 +	IA32_Mov_Reg_Rm(jit, AMX_REG_INFO, REG_ESP, MOD_REG);
    1.61 +
    1.62 +	//mov eax, [ebp+16]	- get result pointer
    1.63 +	//mov [esi+8], eax	- store into info pointer
    1.64 +	IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, REG_EBP, 16);
    1.65 +	IA32_Mov_Rm_Reg_Disp8(jit, REG_ESI, REG_EAX, AMX_INFO_RETVAL);
    1.66 +
    1.67 +	//mov eax, [ebp+8]		- get context
    1.68 +	//mov [esi+12], eax		- store context into info pointer
    1.69 +	//mov ecx, [eax+<offs>]	- get heap pointer
    1.70 +	//mov [esi+4], ecx		- store heap into info pointer
    1.71 +	//mov edi, [eax+<offs>]	- get data pointer
    1.72 +	IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, REG_EBP, 8);
    1.73 +	IA32_Mov_Rm_Reg_Disp8(jit, REG_ESI, REG_EAX, AMX_INFO_CONTEXT);
    1.74 +	IA32_Mov_Reg_Rm_Disp8(jit, REG_ECX, REG_EAX, offsetof(sp_context_t, hp));
    1.75 +	IA32_Mov_Rm_Reg_Disp8(jit, REG_ESI, REG_ECX, AMX_INFO_HEAP);
    1.76 +	IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_DAT, REG_EAX, offsetof(sp_context_t, data));
    1.77 +
    1.78 +	//mov ebp, [eax+<offs>]	- get stack pointer
    1.79 +	//add ebp, edi			- relocate to data section
    1.80 +	//mov ebx, ebp			- copy sp to frm
    1.81 +	//mov ecx, [ebp+12]		- get code index
    1.82 +	//add ecx, [eax+<offs>] - add code base to index
    1.83 +	//mov edx, [eax+<offs>]	- get alt
    1.84 +	//mov eax, [eax+<offs>] - get pri
    1.85 +	IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_STK, REG_EAX, offsetof(sp_context_t, sp));
    1.86 +	IA32_Add_Rm_Reg(jit, REG_EBP, AMX_REG_STK, AMX_REG_DAT);
    1.87 +	IA32_Mov_Reg_Rm(jit, AMX_REG_FRM, AMX_REG_STK, MOD_REG);
    1.88 +	IA32_Mov_Reg_Rm_Disp8(jit, REG_ECX, REG_EBP, 12);
    1.89 +	IA32_Add_Reg_Rm_Disp8(jit, REG_ECX, REG_EAX, offsetof(sp_context_t, base));
    1.90 +	IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_ALT, REG_EAX, offsetof(sp_context_t, alt));
    1.91 +	IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_PRI, REG_EAX, offsetof(sp_context_t, pri));
    1.92 +
    1.93 +	/* by now, everything is set up, so we can call into the plugin */
    1.94 +
    1.95 +	//call ecx
    1.96 +	IA32_Call_Rm(jit, REG_ECX);
    1.97 +
    1.98 +	/* if the code flow gets to here, there was a normal return */
    1.99 +	//mov ebp, [esi+8]		- get retval pointer
   1.100 +	//mov [ebp], eax		- store retval from PRI
   1.101 +	//mov eax, SP_ERR_NONE	- set no error
   1.102 +	IA32_Mov_Reg_Rm_Disp8(jit, REG_EBP, AMX_REG_INFO, AMX_INFO_RETVAL);
   1.103 +	IA32_Mov_Rm_Reg(jit, REG_EBP, AMX_REG_PRI, MOD_MEM_REG);
   1.104 +	IA32_Mov_Reg_Imm32(jit, REG_EAX, SP_ERR_NONE);
   1.105 +
   1.106 +	/* where error checking/return functions should go to */
   1.107 +	jitoffs_t offs_return;
   1.108 +	if (never_inline)
   1.109 +	{
   1.110 +		/* We have to write code assume we're breaking out of a call */
   1.111 +		//jmp [past the next instruction]
   1.112 +		//add esp, 4
   1.113 +		jitoffs_t offs = IA32_Jump_Imm8(jit, 0);
   1.114 +		offs_return = jit->jit_curpos();
   1.115 +		IA32_Sub_Rm_Imm8(jit, REG_ESP, 4, MOD_REG);
   1.116 +		IA32_Send_Jump8_Here(jit, offs);
   1.117 +	} else {
   1.118 +		offs_return = jit->jit_curpos();
   1.119 +	}
   1.120 +
   1.121 +	/* _FOR NOW_ ... 
   1.122 +	 * We are _not_ going to restore anything that was on the stack.
   1.123 +	 * This is a tiny, useless optimization based on the fact that 
   1.124 +	 * BaseContext::Execute() automatically restores our values anyway.
   1.125 +	 */
   1.126 +
   1.127 +	//add esp, 4*4
   1.128 +	//pop ebx
   1.129 +	//pop edi
   1.130 +	//pop esi
   1.131 +	//pop ebp
   1.132 +	//ret
   1.133 +	IA32_Add_Rm_Imm8(jit, REG_ESP, 4*4, MOD_REG);
   1.134 +	IA32_Pop_Reg(jit, REG_EBX);
   1.135 +	IA32_Pop_Reg(jit, REG_EDI);
   1.136 +	IA32_Pop_Reg(jit, REG_ESI);
   1.137 +	IA32_Pop_Reg(jit, REG_EBP);
   1.138 +	IA32_Return(jit);
   1.139 +
   1.140 +	return offs_return;
   1.141  }
   1.142  
   1.143  void Macro_PushN_Addr(JitWriter *jit, int i)
   1.144 @@ -142,6 +245,7 @@
   1.145  	OpAdvTable[OP_LOAD_S_BOTH] = sizeof(cell_t)*2;
   1.146  	OpAdvTable[OP_CONST] = sizeof(cell_t)*2;
   1.147  	OpAdvTable[OP_CONST_S] = sizeof(cell_t)*2;
   1.148 +	OpAdvTable[OP_SYSREQ_N] = sizeof(cell_t)*2;
   1.149  
   1.150  	/* instructions with 1 parameter */
   1.151  	OpAdvTable[OP_LOAD_PRI] = sizeof(cell_t);
   1.152 @@ -199,6 +303,7 @@
   1.153  	OpAdvTable[OP_BOUNDS] = sizeof(cell_t);
   1.154  	OpAdvTable[OP_PUSH_ADR] = sizeof(cell_t);
   1.155  	OpAdvTable[OP_PUSH_HEAP_C] = sizeof(cell_t);
   1.156 +	OpAdvTable[OP_SYSREQ_C] = sizeof(cell_t);
   1.157  
   1.158  	/* instructions with 0 parameters */
   1.159  	OpAdvTable[OP_LOAD_I] = 0;
   1.160 @@ -261,6 +366,7 @@
   1.161  	OpAdvTable[OP_BREAK] = 0;
   1.162  	OpAdvTable[OP_HEAP_PRI] = 0;
   1.163  	OpAdvTable[OP_POP_HEAP_PRI] = 0;
   1.164 +	OpAdvTable[OP_SYSREQ_PRI] = 0;
   1.165  
   1.166  	/* opcodes that need relocation */
   1.167  	OpAdvTable[OP_CALL] = -2;