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