1 #pragma once
2 
3 #include "Types.h"
4 #include "Stream.h"
5 #include "MemStream.h"
6 #include "Literal128.h"
7 #include <map>
8 #include <vector>
9 
10 class CX86Assembler
11 {
12 public:
13 	enum REGISTER
14 	{
15 		rAX = 0,
16 		rCX,
17 		rDX,
18 		rBX,
19 		rSP,
20 		rBP,
21 		rSI,
22 		rDI,
23 		r8,
24 		r9,
25 		r10,
26 		r11,
27 		r12,
28 		r13,
29 		r14,
30 		r15,
31 	};
32 
33 	enum BYTEREGISTER
34 	{
35 		bAL = 0,
36 		bCL,
37 		bDL,
38 		bBL,
39 		bAH,
40 		bCH,
41 		bDH,
42 		bBH
43 	};
44 
45 	enum XMMREGISTER
46 	{
47 		xMM0 = 0,
48 		xMM1,
49 		xMM2,
50 		xMM3,
51 		xMM4,
52 		xMM5,
53 		xMM6,
54 		xMM7,
55 		xMM8,
56 		xMM9,
57 		xMM10,
58 		xMM11,
59 		xMM12,
60 		xMM13,
61 		xMM14,
62 		xMM15,
63 	};
64 
65 	typedef unsigned int LABEL;
66 	typedef unsigned int LITERAL128ID;
67 
68 	class CAddress
69 	{
70 	public:
71 						CAddress();
72 
73 		bool			nIsExtendedModRM;
74 		bool			nIsExtendedSib;
75 		bool			usesLegacyByteRegister;
76 
77 		union MODRMBYTE
78 		{
79 			struct
80 			{
81 				unsigned int nRM : 3;
82 				unsigned int nFnReg : 3;
83 				unsigned int nMod : 2;
84 			};
85 			uint8 nByte;
86 		};
87 
88 		union SIB
89 		{
90 			struct
91 			{
92 				unsigned int base : 3;
93 				unsigned int index : 3;
94 				unsigned int scale : 2;
95 			};
96 			uint8 byteValue;
97 		};
98 
99 		MODRMBYTE		ModRm;
100 		SIB				sib;
101 		uint32			nOffset;
102 		LITERAL128ID	literal128Id = 0;
103 
104 		bool			HasSib() const;
105 		bool			NeedsExtendedByteAddress() const;
106 		void			Write(Framework::CStream*);
107 	};
108 
109 	virtual									~CX86Assembler() = default;
110 
111 	void									Begin();
112 	void									End();
113 
114 	void									SetStream(Framework::CStream*);
115 
116 	static CAddress							MakeRegisterAddress(REGISTER);
117 	static CAddress							MakeXmmRegisterAddress(XMMREGISTER);
118 	static CAddress							MakeByteRegisterAddress(BYTEREGISTER);
119 	static CAddress							MakeIndRegAddress(REGISTER);
120 	static CAddress							MakeIndRegOffAddress(REGISTER, uint32);
121 	static CAddress							MakeBaseIndexScaleAddress(REGISTER, REGISTER, uint8);
122 	static CAddress							MakeLiteral128Address(LITERAL128ID);
123 	static CAddress							MakeBaseOffIndexScaleAddress(REGISTER, uint32, REGISTER, uint8);
124 
125 	static bool								HasByteRegister(REGISTER);
126 	static BYTEREGISTER						GetByteRegister(REGISTER);
127 
128 	static unsigned int						GetMinimumConstantSize(uint32);
129 	static unsigned int						GetMinimumConstantSize64(uint64);
130 
131 	LABEL									CreateLabel();
132 	void									MarkLabel(LABEL, int32 = 0);
133 	uint32									GetLabelOffset(LABEL) const;
134 
135 	LITERAL128ID							CreateLiteral128(const LITERAL128&);
136 	void									ResolveLiteralReferences();
137 
138 	void									AdcEd(REGISTER, const CAddress&);
139 	void									AdcId(const CAddress&, uint32);
140 	void									AddEd(REGISTER, const CAddress&);
141 	void									AddEq(REGISTER, const CAddress&);
142 	void									AddId(const CAddress&, uint32);
143 	void									AddIq(const CAddress&, uint64);
144 	void									AndEd(REGISTER, const CAddress&);
145 	void									AndEq(REGISTER, const CAddress&);
146 	void									AndIb(const CAddress&, uint8);
147 	void									AndId(const CAddress&, uint32);
148 	void									AndIq(const CAddress&, uint64);
149 	void									BsrEd(REGISTER, const CAddress&);
150 	void									CallEd(const CAddress&);
151 	void									CmovsEd(REGISTER, const CAddress&);
152 	void									CmovnsEd(REGISTER, const CAddress&);
153 	void									CmpEd(REGISTER, const CAddress&);
154 	void									CmpEq(REGISTER, const CAddress&);
155 	void									CmpIb(const CAddress&, uint8);
156 	void									CmpId(const CAddress&, uint32);
157 	void									CmpIq(const CAddress&, uint64);
158 	void									Cdq();
159 	void									DivEd(const CAddress&);
160 	void									IdivEd(const CAddress&);
161 	void									ImulEw(const CAddress&);
162 	void									ImulEd(const CAddress&);
163 	void									Int3();
164 	void									JbJx(LABEL);
165 	void									JbeJx(LABEL);
166 	void									JnbJx(LABEL);
167 	void									JzJx(LABEL);
168 	void									JnlJx(LABEL);
169 	void									JnleJx(LABEL);
170 	void									JlJx(LABEL);
171 	void									JleJx(LABEL);
172 	void									JmpEd(const CAddress&);
173 	void									JmpJx(LABEL);
174 	void									JnzJx(LABEL);
175 	void									JnbeJx(LABEL);
176 	void									JnoJx(LABEL);
177 	void									JnsJx(LABEL);
178 	void									LeaGd(REGISTER, const CAddress&);
179 	void									LeaGq(REGISTER, const CAddress&);
180 	void									MovEw(REGISTER, const CAddress&);
181 	void									MovEd(REGISTER, const CAddress&);
182 	void									MovEq(REGISTER, const CAddress&);
183 	void									MovGb(const CAddress&, BYTEREGISTER);
184 	void									MovGb(const CAddress&, REGISTER);
185 	void									MovGw(const CAddress&, REGISTER);
186 	void									MovGd(const CAddress&, REGISTER);
187 	void									MovGq(const CAddress&, REGISTER);
188 	void									MovId(REGISTER, uint32);
189 	void									MovIq(REGISTER, uint64);
190 	void									MovIb(const CAddress&, uint8);
191 	void									MovIw(const CAddress&, uint16);
192 	void									MovId(const CAddress&, uint32);
193 	void									MovsxEb(REGISTER, const CAddress&);
194 	void									MovsxEw(REGISTER, const CAddress&);
195 	void									MovzxEb(REGISTER, const CAddress&);
196 	void									MovzxEw(REGISTER, const CAddress&);
197 	void									MulEd(const CAddress&);
198 	void									NegEd(const CAddress&);
199 	void									Nop();
200 	void									NotEd(const CAddress&);
201 	void									OrEd(REGISTER, const CAddress&);
202 	void									OrId(const CAddress&, uint32);
203 	void									Pop(REGISTER);
204 	void									Push(REGISTER);
205 	void									PushEd(const CAddress&);
206 	void									PushId(uint32);
207 	void									RclEd(const CAddress&, uint8);
208 	void									RepMovsb();
209 	void									Ret();
210 	void									SarEd(const CAddress&);
211 	void									SarEd(const CAddress&, uint8);
212 	void									SarEq(const CAddress&);
213 	void									SarEq(const CAddress&, uint8);
214 	void									SbbEd(REGISTER, const CAddress&);
215 	void									SbbId(const CAddress&, uint32);
216 	void									SetaEb(const CAddress&);
217 	void									SetaeEb(const CAddress&);
218 	void									SetbEb(const CAddress&);
219 	void									SetbeEb(const CAddress&);
220 	void									SeteEb(const CAddress&);
221 	void									SetneEb(const CAddress&);
222 	void									SetlEb(const CAddress&);
223 	void									SetleEb(const CAddress&);
224 	void									SetgEb(const CAddress&);
225 	void									ShrEd(const CAddress&);
226 	void									ShrEd(const CAddress&, uint8);
227 	void									ShrEq(const CAddress&);
228 	void									ShrEq(const CAddress&, uint8);
229 	void									ShrdEd(const CAddress&, REGISTER);
230 	void									ShrdEd(const CAddress&, REGISTER, uint8);
231 	void									ShlEd(const CAddress&);
232 	void									ShlEd(const CAddress&, uint8);
233 	void									ShlEq(const CAddress&);
234 	void									ShlEq(const CAddress&, uint8);
235 	void									ShldEd(const CAddress&, REGISTER);
236 	void									ShldEd(const CAddress&, REGISTER, uint8);
237 	void									SubEd(REGISTER, const CAddress&);
238 	void									SubEq(REGISTER, const CAddress&);
239 	void									SubId(const CAddress&, uint32);
240 	void									SubIq(const CAddress&, uint64);
241 	void									TestEb(BYTEREGISTER, const CAddress&);
242 	void									TestEd(REGISTER, const CAddress&);
243 	void									TestEq(REGISTER, const CAddress&);
244 	void									XorEd(REGISTER, const CAddress&);
245 	void									XorId(const CAddress&, uint32);
246 	void									XorGd(const CAddress&, REGISTER);
247 	void									XorGq(const CAddress&, REGISTER);
248 
249 	//FPU
250 	void									FldEd(const CAddress&);
251 	void									FildEd(const CAddress&);
252 	void									FstpEd(const CAddress&);
253 	void									FistpEd(const CAddress&);
254 	void									FisttpEd(const CAddress&);
255 	void									FaddpSt(uint8);
256 	void									FsubpSt(uint8);
257 	void									FmulpSt(uint8);
258 	void									FdivpSt(uint8);
259 	void									Fwait();
260 	void									Fsin();
261 	void									FnstcwEw(const CAddress&);
262 	void									FldcwEw(const CAddress&);
263 
264 	//SSE
265 
266 	enum SSE_CMP_TYPE
267 	{
268 		SSE_CMP_EQ = 0,
269 		SSE_CMP_LT = 1,
270 		SSE_CMP_LE = 2,
271 		SSE_CMP_UNORD = 3,
272 		SSE_CMP_NEQ = 4,
273 		SSE_CMP_NLT = 5,
274 		SSE_CMP_NLE = 6,
275 		SSE_CMP_ORD = 7,
276 	};
277 
278 	void									MovdVo(XMMREGISTER, const CAddress&);
279 	void									MovdVo(const CAddress&, XMMREGISTER);
280 	void									MovqVo(XMMREGISTER, const CAddress&);
281 	void									MovdqaVo(XMMREGISTER, const CAddress&);
282 	void									MovdqaVo(const CAddress&, XMMREGISTER);
283 	void									MovdquVo(XMMREGISTER, const CAddress&);
284 	void									MovdquVo(const CAddress&, XMMREGISTER);
285 	void									MovapsVo(const CAddress&, XMMREGISTER);
286 	void									MovapsVo(XMMREGISTER, const CAddress&);
287 	void									PackssdwVo(XMMREGISTER, const CAddress&);
288 	void									PackuswbVo(XMMREGISTER, const CAddress&);
289 
290 	void									PaddbVo(XMMREGISTER, const CAddress&);
291 	void									PaddsbVo(XMMREGISTER, const CAddress&);
292 	void									PaddusbVo(XMMREGISTER, const CAddress&);
293 	void									PaddwVo(XMMREGISTER, const CAddress&);
294 	void									PaddswVo(XMMREGISTER, const CAddress&);
295 	void									PadduswVo(XMMREGISTER, const CAddress&);
296 	void									PadddVo(XMMREGISTER, const CAddress&);
297 
298 	void									PandVo(XMMREGISTER, const CAddress&);
299 	void									PandnVo(XMMREGISTER, const CAddress&);
300 	void									PcmpeqbVo(XMMREGISTER, const CAddress&);
301 	void									PcmpeqwVo(XMMREGISTER, const CAddress&);
302 	void									PcmpeqdVo(XMMREGISTER, const CAddress&);
303 	void									PcmpgtbVo(XMMREGISTER, const CAddress&);
304 	void									PcmpgtwVo(XMMREGISTER, const CAddress&);
305 	void									PcmpgtdVo(XMMREGISTER, const CAddress&);
306 	void									PmaxswVo(XMMREGISTER, const CAddress&);
307 	void									PmaxsdVo(XMMREGISTER, const CAddress&);
308 	void									PminswVo(XMMREGISTER, const CAddress&);
309 	void									PminsdVo(XMMREGISTER, const CAddress&);
310 	void									PmovmskbVo(REGISTER, XMMREGISTER);
311 	void									PorVo(XMMREGISTER, const CAddress&);
312 	void									PshufbVo(XMMREGISTER, const CAddress&);
313 	void									PshufdVo(XMMREGISTER, const CAddress&, uint8);
314 	void									PsllwVo(XMMREGISTER, uint8);
315 	void									PslldVo(XMMREGISTER, uint8);
316 	void									PsrawVo(XMMREGISTER, uint8);
317 	void									PsradVo(XMMREGISTER, uint8);
318 	void									PsrlwVo(XMMREGISTER, uint8);
319 	void									PsrldVo(XMMREGISTER, uint8);
320 
321 	void									PsubbVo(XMMREGISTER, const CAddress&);
322 	void									PsubusbVo(XMMREGISTER, const CAddress&);
323 	void									PsubwVo(XMMREGISTER, const CAddress&);
324 	void									PsubswVo(XMMREGISTER, const CAddress&);
325 	void									PsubuswVo(XMMREGISTER, const CAddress&);
326 	void									PsubdVo(XMMREGISTER, const CAddress&);
327 
328 	void									PunpcklbwVo(XMMREGISTER, const CAddress&);
329 	void									PunpcklwdVo(XMMREGISTER, const CAddress&);
330 	void									PunpckldqVo(XMMREGISTER, const CAddress&);
331 	void									PunpckhbwVo(XMMREGISTER, const CAddress&);
332 	void									PunpckhwdVo(XMMREGISTER, const CAddress&);
333 	void									PunpckhdqVo(XMMREGISTER, const CAddress&);
334 	void									PxorVo(XMMREGISTER, const CAddress&);
335 
336 	void									MovssEd(const CAddress&, XMMREGISTER);
337 	void									MovssEd(XMMREGISTER, const CAddress&);
338 	void									AddssEd(XMMREGISTER, const CAddress&);
339 	void									SubssEd(XMMREGISTER, const CAddress&);
340 	void									MaxssEd(XMMREGISTER, const CAddress&);
341 	void									MinssEd(XMMREGISTER, const CAddress&);
342 	void									MulssEd(XMMREGISTER, const CAddress&);
343 	void									DivssEd(XMMREGISTER, const CAddress&);
344 	void									RcpssEd(XMMREGISTER, const CAddress&);
345 	void									RsqrtssEd(XMMREGISTER, const CAddress&);
346 	void									SqrtssEd(XMMREGISTER, const CAddress&);
347 	void									CmpssEd(XMMREGISTER, const CAddress&, SSE_CMP_TYPE);
348 	void									CmppsVo(XMMREGISTER, const CAddress&, SSE_CMP_TYPE);
349 	void									CmpltpsVo(XMMREGISTER, const CAddress&);
350 	void									CmpgtpsVo(XMMREGISTER, const CAddress&);
351 	void									Cvtsi2ssEd(XMMREGISTER, const CAddress&);
352 	void									Cvttss2siEd(REGISTER, const CAddress&);
353 	void									Cvtdq2psVo(XMMREGISTER, const CAddress&);
354 	void									Cvttps2dqVo(XMMREGISTER, const CAddress&);
355 
356 	void									AddpsVo(XMMREGISTER, const CAddress&);
357 	void									BlendpsVo(XMMREGISTER, const CAddress&, uint8);
358 	void									DivpsVo(XMMREGISTER, const CAddress&);
359 	void									MaxpsVo(XMMREGISTER, const CAddress&);
360 	void									MinpsVo(XMMREGISTER, const CAddress&);
361 	void									MulpsVo(XMMREGISTER, const CAddress&);
362 	void									SubpsVo(XMMREGISTER, const CAddress&);
363 	void									ShufpsVo(XMMREGISTER, const CAddress&, uint8);
364 
365 	//AVX
366 	void									VmovdVo(XMMREGISTER, const CAddress&);
367 	void									VmovdVo(const CAddress&, XMMREGISTER);
368 
369 	void									VmovssEd(XMMREGISTER, const CAddress&);
370 	void									VmovssEd(const CAddress&, XMMREGISTER);
371 
372 	void									VaddssEd(XMMREGISTER, XMMREGISTER, const CAddress&);
373 	void									VsubssEd(XMMREGISTER, XMMREGISTER, const CAddress&);
374 	void									VmulssEd(XMMREGISTER, XMMREGISTER, const CAddress&);
375 	void									VdivssEd(XMMREGISTER, XMMREGISTER, const CAddress&);
376 	void									VmaxssEd(XMMREGISTER, XMMREGISTER, const CAddress&);
377 	void									VminssEd(XMMREGISTER, XMMREGISTER, const CAddress&);
378 
379 	void									VcmpssEd(XMMREGISTER, XMMREGISTER, const CAddress&, SSE_CMP_TYPE);
380 
381 	void									VsqrtssEd(XMMREGISTER, XMMREGISTER, const CAddress&);
382 
383 	void									Vcvtsi2ssEd(XMMREGISTER, const CAddress&);
384 	void									Vcvttss2siEd(REGISTER, const CAddress&);
385 
386 	void									VmovdqaVo(XMMREGISTER, const CAddress&);
387 	void									VmovdqaVo(const CAddress&, XMMREGISTER);
388 	void									VmovdquVo(XMMREGISTER, const CAddress&);
389 	void									VmovapsVo(XMMREGISTER, const CAddress&);
390 	void									VmovapsVo(const CAddress&, XMMREGISTER);
391 
392 	void									VpaddbVo(XMMREGISTER, XMMREGISTER, const CAddress&);
393 	void									VpaddwVo(XMMREGISTER, XMMREGISTER, const CAddress&);
394 	void									VpadddVo(XMMREGISTER, XMMREGISTER, const CAddress&);
395 
396 	void									VpaddsbVo(XMMREGISTER, XMMREGISTER, const CAddress&);
397 	void									VpaddswVo(XMMREGISTER, XMMREGISTER, const CAddress&);
398 
399 	void									VpaddusbVo(XMMREGISTER, XMMREGISTER, const CAddress&);
400 	void									VpadduswVo(XMMREGISTER, XMMREGISTER, const CAddress&);
401 
402 	void									VpsubbVo(XMMREGISTER, XMMREGISTER, const CAddress&);
403 	void									VpsubwVo(XMMREGISTER, XMMREGISTER, const CAddress&);
404 	void									VpsubdVo(XMMREGISTER, XMMREGISTER, const CAddress&);
405 
406 	void									VpsubswVo(XMMREGISTER, XMMREGISTER, const CAddress&);
407 
408 	void									VpsubusbVo(XMMREGISTER, XMMREGISTER, const CAddress&);
409 	void									VpsubuswVo(XMMREGISTER, XMMREGISTER, const CAddress&);
410 
411 	void									VpandVo(XMMREGISTER, XMMREGISTER, const CAddress&);
412 	void									VporVo(XMMREGISTER, XMMREGISTER, const CAddress&);
413 	void									VpxorVo(XMMREGISTER, XMMREGISTER, const CAddress&);
414 
415 	void									VpsllwVo(XMMREGISTER, XMMREGISTER, uint8);
416 	void									VpsrlwVo(XMMREGISTER, XMMREGISTER, uint8);
417 	void									VpsrawVo(XMMREGISTER, XMMREGISTER, uint8);
418 
419 	void									VpslldVo(XMMREGISTER, XMMREGISTER, uint8);
420 	void									VpsrldVo(XMMREGISTER, XMMREGISTER, uint8);
421 	void									VpsradVo(XMMREGISTER, XMMREGISTER, uint8);
422 
423 	void									VpcmpeqbVo(XMMREGISTER, XMMREGISTER, const CAddress&);
424 	void									VpcmpeqwVo(XMMREGISTER, XMMREGISTER, const CAddress&);
425 	void									VpcmpeqdVo(XMMREGISTER, XMMREGISTER, const CAddress&);
426 
427 	void									VpcmpgtbVo(XMMREGISTER, XMMREGISTER, const CAddress&);
428 	void									VpcmpgtwVo(XMMREGISTER, XMMREGISTER, const CAddress&);
429 	void									VpcmpgtdVo(XMMREGISTER, XMMREGISTER, const CAddress&);
430 
431 	void									VpmaxswVo(XMMREGISTER, XMMREGISTER, const CAddress&);
432 	void									VpmaxsdVo(XMMREGISTER, XMMREGISTER, const CAddress&);
433 	void									VpminswVo(XMMREGISTER, XMMREGISTER, const CAddress&);
434 	void									VpminsdVo(XMMREGISTER, XMMREGISTER, const CAddress&);
435 
436 	void									VpackssdwVo(XMMREGISTER, XMMREGISTER, const CAddress&);
437 	void									VpackuswbVo(XMMREGISTER, XMMREGISTER, const CAddress&);
438 
439 	void									VpunpcklbwVo(XMMREGISTER, XMMREGISTER, const CAddress&);
440 	void									VpunpcklwdVo(XMMREGISTER, XMMREGISTER, const CAddress&);
441 	void									VpunpckldqVo(XMMREGISTER, XMMREGISTER, const CAddress&);
442 	void									VpunpckhbwVo(XMMREGISTER, XMMREGISTER, const CAddress&);
443 	void									VpunpckhwdVo(XMMREGISTER, XMMREGISTER, const CAddress&);
444 	void									VpunpckhdqVo(XMMREGISTER, XMMREGISTER, const CAddress&);
445 
446 	void									VpshufbVo(XMMREGISTER, XMMREGISTER, const CAddress&);
447 	void									VpmovmskbVo(REGISTER, XMMREGISTER);
448 
449 	void									VaddpsVo(XMMREGISTER, XMMREGISTER, const CAddress&);
450 	void									VsubpsVo(XMMREGISTER, XMMREGISTER, const CAddress&);
451 	void									VmulpsVo(XMMREGISTER, XMMREGISTER, const CAddress&);
452 	void									VdivpsVo(XMMREGISTER, XMMREGISTER, const CAddress&);
453 
454 	void									VcmpltpsVo(XMMREGISTER, XMMREGISTER, const CAddress&);
455 	void									VcmpgtpsVo(XMMREGISTER, XMMREGISTER, const CAddress&);
456 
457 	void									VminpsVo(XMMREGISTER, XMMREGISTER, const CAddress&);
458 	void									VmaxpsVo(XMMREGISTER, XMMREGISTER, const CAddress&);
459 
460 	void									Vcvtdq2psVo(XMMREGISTER, const CAddress&);
461 	void									Vcvttps2dqVo(XMMREGISTER, const CAddress&);
462 
463 	void									VcmppsVo(XMMREGISTER, XMMREGISTER, const CAddress&, SSE_CMP_TYPE);
464 
465 	void									VblendpsVo(XMMREGISTER, XMMREGISTER, const CAddress&, uint8);
466 	void									VshufpsVo(XMMREGISTER, XMMREGISTER, const CAddress&, uint8);
467 
468 private:
469 	enum JMP_TYPE
470 	{
471 		JMP_O	= 0,
472 		JMP_NO	= 1,
473 		JMP_B	= 2,
474 		JMP_NB	= 3,
475 		JMP_Z	= 4,
476 		JMP_NZ	= 5,
477 		JMP_BE	= 6,
478 		JMP_NBE	= 7,
479 
480 		JMP_S	= 8,
481 		JMP_NS	= 9,
482 		JMP_P	= 10,
483 		JMP_NP	= 11,
484 		JMP_L	= 12,
485 		JMP_NL	= 13,
486 		JMP_LE	= 14,
487 		JMP_NLE	= 15,
488 
489 		JMP_ALWAYS,
490 	};
491 
492 	enum JMP_LENGTH
493 	{
494 		JMP_NOTSET,
495 		JMP_NEAR,
496 		JMP_FAR
497 	};
498 
499 	enum VEX_OPCODE_MAP : uint8
500 	{
501 		VEX_OPCODE_MAP_NONE = 0x01,
502 		VEX_OPCODE_MAP_66 = 0x11,
503 		VEX_OPCODE_MAP_66_38 = 0x12,
504 		VEX_OPCODE_MAP_66_3A = 0x13,
505 		VEX_OPCODE_MAP_F3 = 0x21,
506 		VEX_OPCODE_MAP_F2 = 0x31
507 	};
508 
509 	struct LABELREF
510 	{
LABELREFLABELREF511 		LABELREF()
512 			: label(0)
513 			, offset(0)
514 			, type(JMP_ALWAYS)
515 			, length(JMP_NOTSET)
516 		{
517 
518 		}
519 
520 		LABEL		label;
521 		uint32		offset;
522 		JMP_TYPE	type;
523 		JMP_LENGTH	length;
524 	};
525 
526 	typedef std::vector<LABELREF> LabelRefArray;
527 
528 	struct LITERAL128REF
529 	{
530 		uint32 offset = 0;
531 		LITERAL128 value = LITERAL128(0, 0);
532 	};
533 	typedef std::map<LITERAL128ID, LITERAL128REF> Literal128Refs;
534 
535 	struct LABELINFO
536 	{
LABELINFOLABELINFO537 		LABELINFO()
538 			: start(0)
539 			, size(0)
540 			, projectedStart(0)
541 		{
542 
543 		}
544 
545 		uint32			start;
546 		uint32			size;
547 		uint32			projectedStart;
548 		LabelRefArray	labelRefs;
549 		Literal128Refs	literal128Refs;
550 	};
551 
552 	typedef std::map<LABEL, LABELINFO> LabelMap;
553 	typedef std::vector<LABEL> LabelArray;
554 	typedef std::vector<uint8> ByteArray;
555 
556 	void									WriteRexByte(bool, const CAddress&);
557 	void									WriteRexByte(bool, const CAddress&, REGISTER&, bool = false);
558 	void									WriteVex(VEX_OPCODE_MAP, XMMREGISTER&, XMMREGISTER, const CAddress&);
559 	void									WriteEbOp_0F(uint8, uint8, const CAddress&);
560 	void									WriteEbGbOp(uint8, bool, const CAddress&, REGISTER);
561 	void									WriteEbGbOp(uint8, bool, const CAddress&, BYTEREGISTER);
562 	void									WriteEbGvOp0F(uint8, bool, const CAddress&, REGISTER);
563 	void									WriteEvOp(uint8, uint8, bool, const CAddress&);
564 	void									WriteEvGvOp(uint8, bool, const CAddress&, REGISTER);
565 	void									WriteEvGvOp0F(uint8, bool, const CAddress&, REGISTER);
566 	void									WriteEvIb(uint8, const CAddress&, uint8);
567 	void									WriteEvId(uint8, const CAddress&, uint32);
568 	void									WriteEvIq(uint8, const CAddress&, uint64);
569 	void									WriteEdVdOp(uint8, const CAddress&, XMMREGISTER);
570 	void									WriteEdVdOp_0F(uint8, const CAddress&, XMMREGISTER);
571 	void									WriteEdVdOp_66_0F(uint8, const CAddress&, XMMREGISTER);
572 	void									WriteEdVdOp_66_0F_64b(uint8, const CAddress&, XMMREGISTER);
573 	void									WriteEdVdOp_66_0F_38(uint8, const CAddress&, XMMREGISTER);
574 	void									WriteEdVdOp_66_0F_3A(uint8, const CAddress&, XMMREGISTER);
575 	void									WriteEdVdOp_F3_0F(uint8, const CAddress&, XMMREGISTER);
576 	void									WriteVrOp_66_0F(uint8, uint8, XMMREGISTER);
577 	void									WriteVexVoOp(VEX_OPCODE_MAP, uint8, XMMREGISTER, XMMREGISTER, const CAddress&);
578 	void									WriteVexShiftVoOp(uint8, uint8, XMMREGISTER, XMMREGISTER, uint8);
579 	void									WriteStOp(uint8, uint8, uint8);
580 
581 	void									CreateLabelReference(LABEL, JMP_TYPE);
582 
583 	void									IncrementJumpOffsetsLocal(LABELINFO&, LabelRefArray::iterator, unsigned int);
584 	void									IncrementJumpOffsets(LabelArray::const_iterator, unsigned int);
585 
586 	static unsigned int						GetJumpSize(JMP_TYPE, JMP_LENGTH);
587 	static void								WriteJump(Framework::CStream*, JMP_TYPE, JMP_LENGTH, uint32);
588 
589 	void									WriteByte(uint8);
590 	void									WriteWord(uint16);
591 	void									WriteDWord(uint32);
592 
593 	LabelMap								m_labels;
594 	LabelArray								m_labelOrder;
595 	LABEL									m_nextLabelId = 1;
596 	LITERAL128ID							m_nextLiteral128Id = 1;
597 	LABELINFO*								m_currentLabel = nullptr;
598 	Framework::CStream*						m_outputStream = nullptr;
599 	Framework::CMemStream					m_tmpStream;
600 	ByteArray								m_copyBuffer;
601 };
602