|
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_OPCODE_INFO_H_ |
|
dvander@157
|
16 |
#define _INCLUDE_SOURCEPAWN_JIT_X86_OPCODE_INFO_H_ |
|
dvander@157
|
17 |
|
|
dvander@350
|
18 |
#include "../jit_helpers.h" |
|
dvander@157
|
19 |
|
|
dvander@157
|
20 |
/** |
|
dvander@157
|
21 |
* This outputs the execution function for a plugin. |
|
dvander@157
|
22 |
* It also returns the 'return' offset, which is used for |
|
dvander@157
|
23 |
* breaking out of the JIT during runtime. |
|
dvander@157
|
24 |
*/ |
|
dvander@157
|
25 |
jitoffs_t Write_Execute_Function(JitWriter *jit); |
|
dvander@157
|
26 |
|
|
dvander@157
|
27 |
/** |
|
dvander@157
|
28 |
* Writes the Sysreq.* opcodes as a function call. |
|
dvander@157
|
29 |
*/ |
|
dvander@157
|
30 |
void WriteOp_Sysreq_N_Function(JitWriter *jit); |
|
dvander@157
|
31 |
void WriteOp_Sysreq_C_Function(JitWriter *jit); |
|
dvander@157
|
32 |
|
|
dvander@157
|
33 |
/** |
|
dvander@157
|
34 |
* Write the GENARRAY intrinsic function. |
|
dvander@157
|
35 |
*/ |
|
dvander@157
|
36 |
void WriteIntrinsic_GenArray(JitWriter *jit); |
|
dvander@157
|
37 |
|
|
dvander@157
|
38 |
/** |
|
dvander@157
|
39 |
* Generates code to set an error state in the VM and return. |
|
dvander@157
|
40 |
* This is used for generating the error set points in the VM. |
|
dvander@157
|
41 |
* GetError writes the error from the context. SetError hardcodes. |
|
dvander@157
|
42 |
*/ |
|
dvander@157
|
43 |
void Write_GetError(JitWriter *jit); |
|
dvander@157
|
44 |
void Write_SetError(JitWriter *jit, int error); |
|
dvander@157
|
45 |
|
|
dvander@157
|
46 |
/** |
|
dvander@157
|
47 |
* Checks the stacks for min and low errors. |
|
dvander@157
|
48 |
* :TODO: Should a variation of this go in the pushN opcodes? |
|
dvander@157
|
49 |
*/ |
|
dvander@157
|
50 |
void Write_CheckStack_Min(JitWriter *jit); |
|
dvander@157
|
51 |
void Write_CheckStack_Low(JitWriter *jit); |
|
dvander@157
|
52 |
|
|
dvander@157
|
53 |
/** |
|
dvander@157
|
54 |
* Checks the heap for min and low errors. |
|
dvander@157
|
55 |
*/ |
|
dvander@157
|
56 |
void Write_CheckHeap_Min(JitWriter *jit); |
|
dvander@157
|
57 |
void Write_CheckHeap_Low(JitWriter *jit); |
|
dvander@157
|
58 |
|
|
dvander@157
|
59 |
/** |
|
dvander@157
|
60 |
* Verifies an address by register. The address must reside |
|
dvander@157
|
61 |
* between DAT and HP and SP and STP. |
|
dvander@157
|
62 |
*/ |
|
dvander@157
|
63 |
void Write_Check_VerifyAddr(JitWriter *jit, jit_uint8_t reg); |
|
dvander@157
|
64 |
|
|
dvander@157
|
65 |
/** |
|
dvander@157
|
66 |
* Checks for division by zero. |
|
dvander@157
|
67 |
*/ |
|
dvander@157
|
68 |
void Write_Check_DivZero(JitWriter *jit, jit_uint8_t reg); |
|
dvander@157
|
69 |
|
|
dvander@157
|
70 |
/** |
|
dvander@157
|
71 |
* Writes the break debug function. |
|
dvander@157
|
72 |
*/ |
|
dvander@157
|
73 |
void Write_BreakDebug(JitWriter *jit); |
|
dvander@157
|
74 |
|
|
dvander@157
|
75 |
/** |
|
dvander@157
|
76 |
* These are for writing the PushN opcodes. |
|
dvander@157
|
77 |
*/ |
|
dvander@157
|
78 |
void Macro_PushN_Addr(JitWriter *jit, int i); |
|
dvander@157
|
79 |
void Macro_PushN_S(JitWriter *jit, int i); |
|
dvander@157
|
80 |
void Macro_PushN_C(JitWriter *jit, int i); |
|
dvander@157
|
81 |
void Macro_PushN(JitWriter *jit, int i); |
|
dvander@157
|
82 |
|
|
dvander@157
|
83 |
/** |
|
dvander@157
|
84 |
* Bound checking for the tracker stack, |
|
dvander@157
|
85 |
*/ |
|
dvander@237
|
86 |
int JIT_VerifyLowBoundTracker(sp_context_t *ctx); |
|
dvander@237
|
87 |
int JIT_VerifyOrAllocateTracker(sp_context_t *ctx); |
|
dvander@157
|
88 |
|
|
dvander@157
|
89 |
/** |
|
dvander@157
|
90 |
* Writes the push into tracker function. |
|
dvander@157
|
91 |
*/ |
|
dvander@157
|
92 |
void WriteOp_Tracker_Push_Reg(JitWriter *jit, uint8_t reg); |
|
dvander@157
|
93 |
|
|
faluco@831
|
94 |
/** |
|
faluco@831
|
95 |
* Writes the rounding table for the float compare opcode. |
|
faluco@831
|
96 |
*/ |
|
faluco@831
|
97 |
void Write_RoundingTable(JitWriter *jit); |
|
faluco@831
|
98 |
|
|
faluco@853
|
99 |
/** |
|
faluco@853
|
100 |
* Aligns the current code position to 16 bytes. |
|
faluco@853
|
101 |
*/ |
|
faluco@853
|
102 |
void AlignMe(JitWriter *jit); |
|
faluco@853
|
103 |
|
|
dvander@157
|
104 |
/** |
|
dvander@157
|
105 |
* Legend for Statuses: |
|
dvander@157
|
106 |
* ****** *** ******** |
|
dvander@157
|
107 |
* DONE -> code generation is done |
|
dvander@157
|
108 |
* !GEN -> code generation is deliberate skipped because: |
|
dvander@157
|
109 |
* (default): compiler does not generate |
|
dvander@157
|
110 |
* DEPRECATED: this feature no longer exists/supported |
|
dvander@157
|
111 |
* UNSUPPORTED: this opcode is not supported |
|
dvander@157
|
112 |
* TODO: done in case needed |
|
dvander@157
|
113 |
* VERIFIED -> code generation is checked as run-time working. prefixes: |
|
dvander@157
|
114 |
* ! errors are not checked yet. |
|
dvander@157
|
115 |
* - non-inline errors are not checked yet. |
|
dvander@157
|
116 |
* ~ assumed checked because of related variation, but not actually checked |
|
dvander@157
|
117 |
*/ |
|
dvander@157
|
118 |
|
|
dvander@157
|
119 |
typedef enum |
|
dvander@157
|
120 |
{ |
|
dvander@157
|
121 |
OP_NONE, /* invalid opcode */ |
|
dvander@157
|
122 |
OP_LOAD_PRI, //!VERIFIED |
|
dvander@157
|
123 |
OP_LOAD_ALT, //~!VERIFIED (load.pri) |
|
dvander@157
|
124 |
OP_LOAD_S_PRI, //VERIFIED |
|
dvander@157
|
125 |
OP_LOAD_S_ALT, //VERIFIED |
|
dvander@157
|
126 |
OP_LREF_PRI, // !GEN :TODO: we will need this for dynarrays |
|
dvander@157
|
127 |
OP_LREF_ALT, // !GEN :TODO: we will need this for dynarrays |
|
dvander@157
|
128 |
OP_LREF_S_PRI, //VERIFIED |
|
dvander@157
|
129 |
OP_LREF_S_ALT, //~VERIFIED (lref.s.pri) |
|
dvander@157
|
130 |
OP_LOAD_I, //VERIFIED |
|
dvander@157
|
131 |
OP_LODB_I, //VERIFIED |
|
dvander@157
|
132 |
OP_CONST_PRI, //VERIFIED |
|
dvander@157
|
133 |
OP_CONST_ALT, //~VERIFIED (const.pri) |
|
dvander@157
|
134 |
OP_ADDR_PRI, //VERIFIED |
|
dvander@157
|
135 |
OP_ADDR_ALT, //VERIFIED |
|
dvander@157
|
136 |
OP_STOR_PRI, //VERIFIED |
|
dvander@157
|
137 |
OP_STOR_ALT, //~VERIFIED (stor.pri) |
|
dvander@157
|
138 |
OP_STOR_S_PRI, //VERIFIED |
|
dvander@157
|
139 |
OP_STOR_S_ALT, //~VERIFIED (stor.s.pri) |
|
dvander@157
|
140 |
OP_SREF_PRI, // !GEN :TODO: we will need this for dynarrays |
|
dvander@157
|
141 |
OP_SREF_ALT, // !GEN :TODO: we will need this for dynarrays |
|
dvander@157
|
142 |
OP_SREF_S_PRI, //VERIFIED |
|
dvander@157
|
143 |
OP_SREF_S_ALT, //~VERIFIED (stor.s.alt) |
|
dvander@157
|
144 |
OP_STOR_I, //VERIFIED |
|
dvander@157
|
145 |
OP_STRB_I, //VERIFIED |
|
dvander@157
|
146 |
OP_LIDX, //VERIFIED |
|
dvander@157
|
147 |
OP_LIDX_B, //DONE |
|
dvander@157
|
148 |
OP_IDXADDR, //VERIFIED |
|
dvander@157
|
149 |
OP_IDXADDR_B, //DONE |
|
dvander@157
|
150 |
OP_ALIGN_PRI, // !GEN :TODO: - only used for pack access, drop support in compiler first |
|
dvander@157
|
151 |
OP_ALIGN_ALT, // !GEN :TODO: - only used for pack access, drop support in compiler first |
|
dvander@157
|
152 |
OP_LCTRL, // !GEN |
|
dvander@157
|
153 |
OP_SCTRL, // !GEN |
|
dvander@157
|
154 |
OP_MOVE_PRI, //~VERIFIED (move.alt) |
|
dvander@157
|
155 |
OP_MOVE_ALT, //VERIFIED |
|
dvander@157
|
156 |
OP_XCHG, //DONE |
|
dvander@157
|
157 |
OP_PUSH_PRI, //DONE |
|
dvander@157
|
158 |
OP_PUSH_ALT, //DONE |
|
dvander@157
|
159 |
OP_PUSH_R, // !GEN DEPRECATED |
|
dvander@157
|
160 |
OP_PUSH_C, //VERIFIED |
|
dvander@157
|
161 |
OP_PUSH, //DONE |
|
dvander@157
|
162 |
OP_PUSH_S, //VERIFIED |
|
dvander@157
|
163 |
OP_POP_PRI, //VERIFIED |
|
dvander@157
|
164 |
OP_POP_ALT, //VERIFIED |
|
dvander@157
|
165 |
OP_STACK, //VERIFIED |
|
dvander@157
|
166 |
OP_HEAP, //VERIFIED |
|
dvander@157
|
167 |
OP_PROC, //VERIFIED |
|
dvander@157
|
168 |
OP_RET, // !GEN |
|
dvander@157
|
169 |
OP_RETN, //VERIFIED |
|
dvander@157
|
170 |
OP_CALL, //VERIFIED |
|
dvander@157
|
171 |
OP_CALL_PRI, // !GEN |
|
dvander@157
|
172 |
OP_JUMP, //VERIFIED |
|
dvander@157
|
173 |
OP_JREL, // !GEN |
|
dvander@157
|
174 |
OP_JZER, //VERIFIED |
|
dvander@157
|
175 |
OP_JNZ, //DONE |
|
dvander@157
|
176 |
OP_JEQ, //VERIFIED |
|
dvander@157
|
177 |
OP_JNEQ, //VERIFIED |
|
dvander@157
|
178 |
OP_JLESS, // !GEN |
|
dvander@157
|
179 |
OP_JLEQ, // !GEN |
|
dvander@157
|
180 |
OP_JGRTR, // !GEN |
|
dvander@157
|
181 |
OP_JGEQ, // !GEN |
|
dvander@157
|
182 |
OP_JSLESS, //VERIFIED |
|
dvander@157
|
183 |
OP_JSLEQ, //VERIFIED |
|
dvander@157
|
184 |
OP_JSGRTR, //VERIFIED |
|
dvander@157
|
185 |
OP_JSGEQ, //VERIFIED |
|
dvander@157
|
186 |
OP_SHL, //VERIFIED |
|
dvander@157
|
187 |
OP_SHR, //VERIFIED (Note: operator >>>) |
|
dvander@157
|
188 |
OP_SSHR, //VERIFIED (Note: operator >>) |
|
dvander@157
|
189 |
OP_SHL_C_PRI, //DONE |
|
dvander@157
|
190 |
OP_SHL_C_ALT, //DONE |
|
dvander@157
|
191 |
OP_SHR_C_PRI, //DONE |
|
dvander@157
|
192 |
OP_SHR_C_ALT, //DONE |
|
dvander@157
|
193 |
OP_SMUL, //VERIFIED |
|
dvander@157
|
194 |
OP_SDIV, //DONE |
|
dvander@157
|
195 |
OP_SDIV_ALT, //VERIFIED |
|
dvander@157
|
196 |
OP_UMUL, // !GEN |
|
dvander@157
|
197 |
OP_UDIV, // !GEN |
|
dvander@157
|
198 |
OP_UDIV_ALT, // !GEN |
|
dvander@157
|
199 |
OP_ADD, //VERIFIED |
|
dvander@157
|
200 |
OP_SUB, //DONE |
|
dvander@157
|
201 |
OP_SUB_ALT, //VERIFIED |
|
dvander@157
|
202 |
OP_AND, //VERIFIED |
|
dvander@157
|
203 |
OP_OR, //VERIFIED |
|
dvander@157
|
204 |
OP_XOR, //VERIFIED |
|
dvander@157
|
205 |
OP_NOT, //VERIFIED |
|
dvander@157
|
206 |
OP_NEG, //VERIFIED |
|
dvander@157
|
207 |
OP_INVERT, //VERIFIED |
|
dvander@157
|
208 |
OP_ADD_C, //VERIFIED |
|
dvander@157
|
209 |
OP_SMUL_C, //VERIFIED |
|
dvander@157
|
210 |
OP_ZERO_PRI, //VERIFIED |
|
dvander@157
|
211 |
OP_ZERO_ALT, //~VERIFIED |
|
dvander@157
|
212 |
OP_ZERO, //VERIFIED |
|
dvander@157
|
213 |
OP_ZERO_S, //VERIFIED |
|
dvander@157
|
214 |
OP_SIGN_PRI, //DONE |
|
dvander@157
|
215 |
OP_SIGN_ALT, //DONE |
|
dvander@157
|
216 |
OP_EQ, //VERIFIED |
|
dvander@157
|
217 |
OP_NEQ, //VERIFIED |
|
dvander@157
|
218 |
OP_LESS, // !GEN |
|
dvander@157
|
219 |
OP_LEQ, // !GEN |
|
dvander@157
|
220 |
OP_GRTR, // !GEN |
|
dvander@157
|
221 |
OP_GEQ, // !GEN |
|
dvander@157
|
222 |
OP_SLESS, //VERIFIED |
|
dvander@157
|
223 |
OP_SLEQ, //VERIFIED |
|
dvander@157
|
224 |
OP_SGRTR, //VERIFIED |
|
dvander@157
|
225 |
OP_SGEQ, //VERIFIED |
|
dvander@157
|
226 |
OP_EQ_C_PRI, //DONE |
|
dvander@157
|
227 |
OP_EQ_C_ALT, //DONE |
|
dvander@157
|
228 |
OP_INC_PRI, //VERIFIED |
|
dvander@157
|
229 |
OP_INC_ALT, //~VERIFIED (inc.pri) |
|
dvander@157
|
230 |
OP_INC, //VERIFIED |
|
dvander@157
|
231 |
OP_INC_S, //VERIFIED |
|
dvander@157
|
232 |
OP_INC_I, //VERIFIED |
|
dvander@157
|
233 |
OP_DEC_PRI, //VERIFIED |
|
dvander@157
|
234 |
OP_DEC_ALT, //~VERIFIED (dec.pri) |
|
dvander@157
|
235 |
OP_DEC, //VERIFIED |
|
dvander@157
|
236 |
OP_DEC_S, //VERIFIED |
|
dvander@157
|
237 |
OP_DEC_I, //VERIFIED |
|
dvander@157
|
238 |
OP_MOVS, //VERIFIED |
|
dvander@157
|
239 |
OP_CMPS, // !GEN |
|
dvander@157
|
240 |
OP_FILL, //VERIFIED |
|
dvander@157
|
241 |
OP_HALT, //DONE |
|
dvander@157
|
242 |
OP_BOUNDS, //VERIFIED |
|
dvander@157
|
243 |
OP_SYSREQ_PRI, // !GEN |
|
dvander@157
|
244 |
OP_SYSREQ_C, //VERIFIED |
|
dvander@157
|
245 |
OP_FILE, // !GEN DEPRECATED |
|
dvander@157
|
246 |
OP_LINE, // !GEN DEPRECATED |
|
dvander@157
|
247 |
OP_SYMBOL, // !GEN DEPRECATED |
|
dvander@157
|
248 |
OP_SRANGE, // !GEN DEPRECATED |
|
dvander@157
|
249 |
OP_JUMP_PRI, // !GEN |
|
dvander@157
|
250 |
OP_SWITCH, //VERIFIED |
|
dvander@157
|
251 |
OP_CASETBL, //VERIFIED |
|
dvander@157
|
252 |
OP_SWAP_PRI, //VERIFIED |
|
dvander@157
|
253 |
OP_SWAP_ALT, //~VERIFIED (swap.alt) |
|
dvander@157
|
254 |
OP_PUSH_ADR, //VERIFIED |
|
dvander@157
|
255 |
OP_NOP, //VERIFIED (lol) |
|
dvander@157
|
256 |
OP_SYSREQ_N, //VERIFIED |
|
dvander@157
|
257 |
OP_SYMTAG, // !GEN DEPRECATED |
|
dvander@157
|
258 |
OP_BREAK, //DONE |
|
dvander@157
|
259 |
OP_PUSH2_C, //~VERIFIED (push3.c) |
|
dvander@157
|
260 |
OP_PUSH2, //VERIFIED |
|
dvander@157
|
261 |
OP_PUSH2_S, //VERIFIED |
|
dvander@157
|
262 |
OP_PUSH2_ADR, //VERIFIED |
|
dvander@157
|
263 |
OP_PUSH3_C, //VERIFIED |
|
dvander@157
|
264 |
OP_PUSH3, //~VERIFIED (push2) |
|
dvander@157
|
265 |
OP_PUSH3_S, //~VERIFIED (push2.s) |
|
dvander@157
|
266 |
OP_PUSH3_ADR, //~VERIFIED (push2.adr) |
|
dvander@157
|
267 |
OP_PUSH4_C, //~VERIFIED (push3.c) |
|
dvander@157
|
268 |
OP_PUSH4, //~VERIFIED (push2) |
|
dvander@157
|
269 |
OP_PUSH4_S, //~VERIFIED (push2.s) |
|
dvander@157
|
270 |
OP_PUSH4_ADR, //~VERIFIED (push2.adr) |
|
dvander@157
|
271 |
OP_PUSH5_C, //~VERIFIED (push3.c) |
|
dvander@157
|
272 |
OP_PUSH5, //~VERIFIED (push2) |
|
dvander@157
|
273 |
OP_PUSH5_S, //~VERIFIED (push2.s) |
|
dvander@157
|
274 |
OP_PUSH5_ADR, //~VERIFIED (push2.adr) |
|
dvander@157
|
275 |
OP_LOAD_BOTH, //VERIFIED |
|
dvander@157
|
276 |
OP_LOAD_S_BOTH, //VERIFIED |
|
dvander@157
|
277 |
OP_CONST, //VERIFIED |
|
dvander@157
|
278 |
OP_CONST_S, //DONE |
|
dvander@157
|
279 |
/* ----- */ |
|
dvander@157
|
280 |
OP_SYSREQ_D, // !GEN UNSUPPORT |
|
dvander@157
|
281 |
OP_SYSREQ_ND, // !GEN UNSUPPORT |
|
dvander@157
|
282 |
/* ----- */ |
|
dvander@157
|
283 |
OP_TRACKER_PUSH_C, //DONE |
|
dvander@157
|
284 |
OP_TRACKER_POP_SETHEAP, //VERIFIED |
|
dvander@157
|
285 |
OP_GENARRAY, //VERIFIED |
|
dvander@157
|
286 |
OP_GENARRAY_Z, //-VERIFIED (not tested for 1D arrays) |
|
faluco@201
|
287 |
OP_STRADJUST_PRI, //VERIFIED |
|
faluco@831
|
288 |
OP_FABS, //VERIFIED |
|
faluco@831
|
289 |
OP_FLOAT, //VERIFIED |
|
faluco@831
|
290 |
OP_FLOATADD, //VERIFIED |
|
faluco@831
|
291 |
OP_FLOATSUB, //VERIFIED |
|
faluco@831
|
292 |
OP_FLOATMUL, //VERIFIED |
|
faluco@831
|
293 |
OP_FLOATDIV, //VERIFIED |
|
faluco@831
|
294 |
OP_RND_TO_NEAREST, //VERIFIED |
|
faluco@831
|
295 |
OP_RND_TO_FLOOR, //VERIFIED |
|
faluco@831
|
296 |
OP_RND_TO_CEIL, //VERIFIED |
|
faluco@831
|
297 |
OP_RND_TO_ZERO, //VERIFIED |
|
faluco@831
|
298 |
OP_FLOATCMP, //VERIFIED |
|
dvander@157
|
299 |
/* ----- */ |
|
dvander@157
|
300 |
OP_NUM_OPCODES |
|
dvander@157
|
301 |
} OPCODE; |
|
dvander@157
|
302 |
|
|
dvander@157
|
303 |
/* |
|
dvander@157
|
304 |
* :TODO: List of ASM Opts |
|
dvander@157
|
305 |
* from jit_x86.cpp |
|
dvander@157
|
306 |
* DONE: Rest of opcodes including the SYSREQ.N inlined version (rev2) |
|
dvander@157
|
307 |
* Including genarray and the 2 tracker ones |
|
dvander@157
|
308 |
* DONE: ALL ungen opcodes (rev1) |
|
dvander@157
|
309 |
* from opcode_helpers.cpp |
|
dvander@157
|
310 |
* DONE: SYSREQ.N .C (rev2) |
|
dvander@157
|
311 |
* MACRO OPCODES (rev2) |
|
dvander@157
|
312 |
* ERROR CHECKS\{VERIFY ADDR} (rev2) |
|
dvander@157
|
313 |
* ARRAY STUFF |
|
dvander@157
|
314 |
* TODO: BrkDebug |
|
dvander@157
|
315 |
* EXEC FUNCTION |
|
dvander@157
|
316 |
* VERIFY ADDR |
|
dvander@157
|
317 |
* |
|
faluco@831
|
318 |
* Oh and ALIGN to 16BYTES all stuff that is called via CALL and frequently used jump labels like what's done with PROC. |
|
dvander@157
|
319 |
*/ |
|
dvander@157
|
320 |
|
|
dvander@157
|
321 |
#endif //_INCLUDE_SOURCEPAWN_JIT_X86_OPCODE_INFO_H_ |