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;