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