sourcepawn/jit/x86/ungen_opcodes.h
author Scott Ehlert <ds@alliedmods.net>
Sun Jul 15 08:00:26 2007 +0000 (2007-07-15)
changeset 1116 40cc5e9f0f1b
parent 653 ef60870067ff
child 1330 ab94316bb52b
permissions -rw-r--r--
Removed strange debugging code
     1 /**
     2  * vim: set ts=4 :
     3  * ================================================================
     4  * SourcePawn (C)2004-2007 AlliedModders LLC.  All rights reserved.
     5  * ================================================================
     6  *
     7  * This file is not open source and may not be copied without explicit
     8  * written permission of AlliedModders LLC.  This file may not be redistributed 
     9  * in whole or significant part.
    10  * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
    11  *
    12  * Version: $Id$
    13  */
    14 
    15 #ifndef _INCLUDE_SOURCEPAWN_JIT_X86_UNGEN_OPCODES_H_
    16 #define _INCLUDE_SOURCEPAWN_JIT_X86_UNGEN_OPCODES_H_
    17 
    18 inline void WriteOp_UMul(JitWriter *jit)
    19 {
    20 	//mov ecx, edx
    21 	//mul edx
    22 	//mov edx, ecx
    23 	IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_ALT, MOD_REG);
    24 	IA32_Mul_Rm(jit, AMX_REG_ALT, MOD_REG);
    25 	IA32_Mov_Reg_Rm(jit, AMX_REG_ALT, AMX_REG_TMP, MOD_REG);
    26 }
    27 
    28 inline void WriteOp_Less(JitWriter *jit)
    29 {
    30 	//cmp eax, edx	; PRI < ALT ? (unsigned)
    31 	//mov eax, 0
    32 	//setb al
    33 	IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
    34 	IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
    35 	IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_B);
    36 }
    37 
    38 inline void WriteOp_Leq(JitWriter *jit)
    39 {
    40 	//cmp eax, edx	; PRI <= ALT ? (unsigned)
    41 	//mov eax, 0
    42 	//setbe al
    43 	IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
    44 	IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
    45 	IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_BE);
    46 }
    47 
    48 inline void WriteOp_Grtr(JitWriter *jit)
    49 {
    50 	//cmp eax, edx	; PRI > ALT ? (unsigned)
    51 	//mov eax, 0
    52 	//seta al
    53 	IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
    54 	IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
    55 	IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_A);
    56 }
    57 
    58 inline void WriteOp_Geq(JitWriter *jit)
    59 {
    60 	//cmp eax, edx	; PRI >= ALT ? (unsigned)
    61 	//mov eax, 0
    62 	//setae al
    63 	IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
    64 	IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
    65 	IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_AE);
    66 }
    67 
    68 inline void WriteOp_Align_Pri(JitWriter *jit)
    69 {
    70 	//xor eax, <cellsize - val>
    71 	cell_t val = sizeof(cell_t) - jit->read_cell();
    72 	if (val < SCHAR_MAX && val > SCHAR_MIN)
    73 	{
    74 		IA32_Xor_Rm_Imm8(jit, AMX_REG_PRI, MOD_REG, (jit_int8_t)val);
    75 	} else {
    76 		IA32_Xor_Eax_Imm32(jit, val);
    77 	}
    78 }
    79 
    80 inline void WriteOp_Align_Alt(JitWriter *jit)
    81 {
    82 	//xor edx, <cellsize - val>
    83 	cell_t val = sizeof(cell_t) - jit->read_cell();
    84 	if (val < SCHAR_MAX && val > SCHAR_MIN)
    85 	{
    86 		IA32_Xor_Rm_Imm8(jit, AMX_REG_ALT, MOD_REG, (jit_int8_t)val);
    87 	} else {
    88 		IA32_Xor_Rm_Imm32(jit, AMX_REG_ALT, MOD_REG, val);
    89 	}
    90 }
    91 
    92 inline void WriteOp_Cmps(JitWriter *jit)
    93 {
    94 	//push edi
    95 	//push esi
    96 	//lea esi, [ebp+edx]
    97 	//lea edi, [ebp+eax]
    98 	//mov ecx, <val>
    99 	unsigned int val = jit->read_cell();
   100 
   101 	IA32_Push_Reg(jit, REG_EDI);
   102 	IA32_Push_Reg(jit, REG_ESI);
   103 	IA32_Lea_Reg_DispEBPRegMult(jit, REG_ESI, AMX_REG_DAT, AMX_REG_ALT, NOSCALE);
   104 	IA32_Lea_Reg_DispEBPRegMult(jit, REG_EDI, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
   105 	IA32_Mov_Reg_Imm32(jit, REG_ECX, val);
   106 
   107 	//xor eax, eax
   108 	//repe cmpsb
   109 	//je :cmps1
   110 	IA32_Xor_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_PRI, MOD_REG);
   111 	IA32_Rep(jit);
   112 	IA32_Cmpsb(jit);
   113 	jitoffs_t jmp = IA32_Jump_Cond_Imm8(jit, CC_E, 0);
   114 
   115 	//sbb eax, eax
   116 	//sbb eax, -1
   117 	IA32_Sbb_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_PRI, MOD_REG);
   118 	IA32_Sbb_Rm_Imm8(jit, AMX_REG_PRI, -1, MOD_REG);
   119 
   120 	//:cmps1
   121 	//pop esi
   122 	//pop edi
   123 	IA32_Send_Jump8_Here(jit, jmp);
   124 	IA32_Pop_Reg(jit, REG_ESI);
   125 	IA32_Pop_Reg(jit, REG_EDI);
   126 }
   127 
   128 inline void WriteOp_Lctrl(JitWriter *jit)
   129 {
   130 	cell_t val = jit->read_cell();
   131 	switch (val)
   132 	{
   133 	case 0:
   134 		{
   135 			//mov ecx, [esi+ctx]
   136 			//mov eax, [ecx+ctx.codebase]
   137 			IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_CONTEXT);
   138 			IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_PRI, AMX_REG_TMP, offsetof(sp_context_t, codebase));
   139 			break;
   140 		}
   141 	case 1:
   142 		{
   143 			//mov eax, ebp
   144 			IA32_Mov_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_DAT, MOD_REG);
   145 			break;
   146 		}
   147 	case 2:
   148 		{
   149 			//mov eax, [esi+hea]
   150 			IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_PRI, AMX_REG_INFO, AMX_INFO_HEAP);
   151 			break;
   152 		}
   153 	case 3:
   154 		{
   155 			//mov ecx, [esi+ctx]
   156 			//mov eax, [ecx+ctx.memory]
   157 			IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_CONTEXT);
   158 			IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_PRI, AMX_REG_TMP, offsetof(sp_context_t, memory));
   159 			break;
   160 		}
   161 	case 4:
   162 		{
   163 			//mov eax, edi
   164 			//sub eax, ebp	- unrelocate
   165 			IA32_Mov_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_STK, MOD_REG);
   166 			IA32_Sub_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_DAT, MOD_REG);
   167 			break;
   168 		}
   169 	case 5:
   170 		{
   171 			//mov eax, [esi+frm]
   172 			IA32_Mov_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_INFO, MOD_MEM_REG);
   173 			break;
   174 		}
   175 	case 6:
   176 		{
   177 			//mov eax, [cip]
   178 			jitoffs_t imm32 = IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
   179 			jitoffs_t save = jit->get_outputpos();
   180 			jit->set_outputpos(imm32);
   181 			jit->write_int32((uint32_t)(jit->outbase + save));
   182 			jit->set_outputpos(save);
   183 			break;
   184 		}
   185 	}
   186 }
   187 
   188 inline void WriteOp_Sctrl(JitWriter *jit)
   189 {
   190 	cell_t val = jit->read_cell();
   191 	switch (val)
   192 	{
   193 	case 2:
   194 		{
   195 			//mov [esi+hea], eax
   196 			IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, AMX_REG_PRI, AMX_INFO_HEAP);
   197 			break;
   198 		}
   199 	case 4:
   200 		{
   201 			//lea edi, [ebp+eax]
   202 			IA32_Lea_Reg_DispEBPRegMult(jit, AMX_REG_STK, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
   203 			break;
   204 		}
   205 	case 5:
   206 		{
   207 			//lea ebx, [ebp+eax]	- overwrite frm
   208 			//mov [esi+frm], eax	- overwrite stacked frame
   209 			IA32_Lea_Reg_DispEBPRegMult(jit, AMX_REG_FRM, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
   210 			IA32_Mov_Rm_Reg(jit, AMX_REG_INFO, AMX_REG_PRI, MOD_MEM_REG);
   211 			break;
   212 		}
   213 	case 6:
   214 		{
   215 			IA32_Jump_Reg(jit, AMX_REG_PRI);
   216 			break;
   217 		}
   218 	}
   219 }
   220 
   221 inline void WriteOp_UDiv(JitWriter *jit)
   222 {
   223 	//mov ecx, edx
   224 	//xor edx, edx
   225 	//div ecx
   226 	IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_ALT, MOD_REG);
   227 	IA32_Xor_Reg_Rm(jit, AMX_REG_ALT, AMX_REG_ALT, MOD_REG);
   228 	Write_Check_DivZero(jit, AMX_REG_TMP);
   229 	IA32_Div_Rm(jit, AMX_REG_TMP, MOD_REG);
   230 }
   231 
   232 inline void WriteOp_UDiv_Alt(JitWriter *jit)
   233 {
   234 	//mov ecx, eax
   235 	//mov eax, edx
   236 	//xor edx, edx
   237 	//div ecx
   238 	IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_PRI, MOD_REG);
   239 	IA32_Mov_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
   240 	IA32_Xor_Reg_Rm(jit, AMX_REG_ALT, AMX_REG_ALT, MOD_REG);
   241 	Write_Check_DivZero(jit, AMX_REG_TMP);
   242 	IA32_Div_Rm(jit, AMX_REG_TMP, MOD_REG);
   243 }
   244 
   245 inline void WriteOp_Ret(JitWriter *jit)
   246 {
   247 	//mov ebx, [edi]		- get old FRM
   248 	//add edi, 4			- pop stack
   249 	//mov [esi+frm], ebx	- restore
   250 	//add ebx, ebp			- relocate
   251 	//ret
   252 	IA32_Mov_Reg_Rm(jit, AMX_REG_FRM, AMX_REG_STK, MOD_MEM_REG);
   253 	IA32_Add_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG);
   254 	IA32_Mov_Rm_Reg(jit, AMX_REG_INFO, AMX_REG_FRM, MOD_MEM_REG);
   255 	IA32_Add_Reg_Rm(jit, AMX_REG_FRM, AMX_REG_DAT, MOD_REG);
   256 	IA32_Return(jit);
   257 }
   258 
   259 inline void WriteOp_JRel(JitWriter *jit)
   260 {
   261 	//jmp <offs>	;relative jump
   262 	cell_t cip_offs = jit->read_cell();
   263 
   264 	/* Note that since code size calculation has to be done in the same
   265 	* phase as building relocation information, we cannot know the jump size
   266 	* beforehand.  Thus, we always write full 32bit jumps for safety.
   267 	*/
   268 	jitoffs_t jmp = IA32_Jump_Imm32(jit, 0);
   269 	IA32_Write_Jump32(jit, jmp, RelocLookup(jit, cip_offs));
   270 }
   271 
   272 inline void WriteOp_Jless(JitWriter *jit)
   273 {
   274 	//cmp eax, edx
   275 	//jb <target>
   276 	cell_t target = jit->read_cell();
   277 	IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
   278 	IA32_Jump_Cond_Imm32(jit, CC_B, RelocLookup(jit, target, false));
   279 }
   280 
   281 inline void WriteOp_Jleq(JitWriter *jit)
   282 {
   283 	//cmp eax, edx
   284 	//jbe <target>
   285 	cell_t target = jit->read_cell();
   286 	IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
   287 	IA32_Jump_Cond_Imm32(jit, CC_BE, RelocLookup(jit, target, false));
   288 }
   289 
   290 inline void WriteOp_Jgrtr(JitWriter *jit)
   291 {
   292 	//cmp eax, edx
   293 	//ja <target>
   294 	cell_t target = jit->read_cell();
   295 	IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
   296 	IA32_Jump_Cond_Imm32(jit, CC_A, RelocLookup(jit, target, false));
   297 }
   298 
   299 inline void WriteOp_Jgeq(JitWriter *jit)
   300 {
   301 	//cmp eax, edx
   302 	//jae <target>
   303 	cell_t target = jit->read_cell();
   304 	IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
   305 	IA32_Jump_Cond_Imm32(jit, CC_AE, RelocLookup(jit, target, false));
   306 }
   307 
   308 #endif //_INCLUDE_SOURCEPAWN_JIT_X86_UNGEN_OPCODES_H_