Commit | Line | Data |
---|---|---|
ef79bbde P |
1 | /*************************************************************************** |
2 | * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team * | |
3 | * * | |
4 | * This program is free software; you can redistribute it and/or modify * | |
5 | * it under the terms of the GNU General Public License as published by * | |
6 | * the Free Software Foundation; either version 2 of the License, or * | |
7 | * (at your option) any later version. * | |
8 | * * | |
9 | * This program is distributed in the hope that it will be useful, * | |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |
12 | * GNU General Public License for more details. * | |
13 | * * | |
14 | * You should have received a copy of the GNU General Public License * | |
15 | * along with this program; if not, write to the * | |
16 | * Free Software Foundation, Inc., * | |
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA. * | |
18 | ***************************************************************************/ | |
19 | ||
20 | /* | |
21 | * ix86 core v0.5.1 | |
22 | * Authors: linuzappz <linuzappz@pcsx.net> | |
23 | * alexey silinov | |
24 | */ | |
25 | ||
26 | #include "ix86.h" | |
27 | ||
28 | s8 *x86Ptr; | |
29 | u8 *j8Ptr[32]; | |
30 | u32 *j32Ptr[32]; | |
31 | ||
32 | void x86Init() { | |
33 | } | |
34 | ||
35 | void x86SetPtr(char *ptr) { | |
36 | x86Ptr = ptr; | |
37 | } | |
38 | ||
39 | void x86Shutdown() { | |
40 | } | |
41 | ||
42 | void x86SetJ8(u8 *j8) { | |
43 | u32 jump = (x86Ptr - (s8*)j8) - 1; | |
44 | ||
45 | if (jump > 0x7f) printf("j8 greater than 0x7f!!\n"); | |
46 | *j8 = (u8)jump; | |
47 | } | |
48 | ||
49 | void x86SetJ32(u32 *j32) { | |
50 | *j32 = (x86Ptr - (s8*)j32) - 4; | |
51 | } | |
52 | ||
53 | void x86Align(int bytes) { | |
54 | // fordward align | |
55 | x86Ptr = (s8*)(((u32)x86Ptr + bytes) & ~(bytes - 1)); | |
56 | } | |
57 | ||
58 | #define SIB 4 | |
59 | #define DISP32 5 | |
60 | ||
61 | /* macros helpers */ | |
62 | ||
63 | #define ModRM(mod, rm, reg) \ | |
64 | write8((mod << 6) | (rm << 3) | (reg)); | |
65 | ||
66 | #define SibSB(ss, rm, index) \ | |
67 | write8((ss << 6) | (rm << 3) | (index)); | |
68 | ||
69 | #define SET8R(cc, to) { \ | |
70 | write8(0x0F); write8(cc); \ | |
71 | write8((0xC0) | (to)); } | |
72 | ||
73 | #define J8Rel(cc, to) { \ | |
74 | write8(cc); write8(to); return x86Ptr - 1; } | |
75 | ||
76 | #define J32Rel(cc, to) { \ | |
77 | write8(0x0F); write8(cc); write32(to); return (u32*)(x86Ptr - 4); } | |
78 | ||
79 | #define CMOV32RtoR(cc, to, from) { \ | |
80 | write8(0x0F); write8(cc); \ | |
81 | ModRM(3, to, from); } | |
82 | ||
83 | #define CMOV32MtoR(cc, to, from) { \ | |
84 | write8(0x0F); write8(cc); \ | |
85 | ModRM(0, to, DISP32); \ | |
86 | write32(from); } | |
87 | ||
88 | /********************/ | |
89 | /* IX86 intructions */ | |
90 | /********************/ | |
91 | ||
92 | // mov instructions | |
93 | ||
94 | /* mov r32 to r32 */ | |
95 | void MOV32RtoR(int to, int from) { | |
96 | write8(0x89); | |
97 | ModRM(3, from, to); | |
98 | } | |
99 | ||
100 | /* mov r32 to m32 */ | |
101 | void MOV32RtoM(u32 to, int from) { | |
102 | write8(0x89); | |
103 | ModRM(0, from, DISP32); | |
104 | write32(to); | |
105 | } | |
106 | ||
107 | /* mov m32 to r32 */ | |
108 | void MOV32MtoR(int to, u32 from) { | |
109 | write8(0x8B); | |
110 | ModRM(0, to, DISP32); | |
111 | write32(from); | |
112 | } | |
113 | ||
114 | /* mov [r32] to r32 */ | |
115 | void MOV32RmtoR(int to, int from) { | |
116 | write8(0x8B); | |
117 | ModRM(0, to, from); | |
118 | } | |
119 | ||
120 | /* mov [r32][r32*scale] to r32 */ | |
121 | void MOV32RmStoR(int to, int from, int from2, int scale) { | |
122 | write8(0x8B); | |
123 | ModRM(0, to, 0x4); | |
124 | SibSB(scale, from2, from); | |
125 | } | |
126 | ||
127 | /* mov r32 to [r32] */ | |
128 | void MOV32RtoRm(int to, int from) { | |
129 | write8(0x89); | |
130 | ModRM(0, from, to); | |
131 | } | |
132 | ||
133 | /* mov r32 to [r32][r32*scale] */ | |
134 | void MOV32RtoRmS(int to, int to2, int scale, int from) { | |
135 | write8(0x89); | |
136 | ModRM(0, from, 0x4); | |
137 | SibSB(scale, to2, to); | |
138 | } | |
139 | ||
140 | /* mov imm32 to r32 */ | |
141 | void MOV32ItoR(int to, u32 from) { | |
142 | write8(0xB8 | to); | |
143 | write32(from); | |
144 | } | |
145 | ||
146 | /* mov imm32 to m32 */ | |
147 | void MOV32ItoM(u32 to, u32 from) { | |
148 | write8(0xC7); | |
149 | ModRM(0, 0, DISP32); | |
150 | write32(to); | |
151 | write32(from); | |
152 | } | |
153 | ||
154 | /* mov r16 to m16 */ | |
155 | void MOV16RtoM(u32 to, int from) { | |
156 | write8(0x66); | |
157 | write8(0x89); | |
158 | ModRM(0, from, DISP32); | |
159 | write32(to); | |
160 | } | |
161 | ||
162 | /* mov m16 to r16 */ | |
163 | void MOV16MtoR(int to, u32 from) { | |
164 | write8(0x66); | |
165 | write8(0x8B); | |
166 | ModRM(0, to, DISP32); | |
167 | write32(from); | |
168 | } | |
169 | ||
170 | /* mov imm16 to m16 */ | |
171 | void MOV16ItoM(u32 to, u16 from) { | |
172 | write8(0x66); | |
173 | write8(0xC7); | |
174 | ModRM(0, 0, DISP32); | |
175 | write32(to); | |
176 | write16(from); | |
177 | } | |
178 | ||
179 | /* mov r8 to m8 */ | |
180 | void MOV8RtoM(u32 to, int from) { | |
181 | write8(0x88); | |
182 | ModRM(0, from, DISP32); | |
183 | write32(to); | |
184 | } | |
185 | ||
186 | /* mov m8 to r8 */ | |
187 | void MOV8MtoR(int to, u32 from) { | |
188 | write8(0x8A); | |
189 | ModRM(0, to, DISP32); | |
190 | write32(from); | |
191 | } | |
192 | ||
193 | /* mov imm8 to m8 */ | |
194 | void MOV8ItoM(u32 to, u8 from) { | |
195 | write8(0xC6); | |
196 | ModRM(0, 0, DISP32); | |
197 | write32(to); | |
198 | write8(from); | |
199 | } | |
200 | ||
201 | /* movsx r8 to r32 */ | |
202 | void MOVSX32R8toR(int to, int from) { | |
203 | write16(0xBE0F); | |
204 | ModRM(3, to, from); | |
205 | } | |
206 | ||
207 | /* movsx m8 to r32 */ | |
208 | void MOVSX32M8toR(int to, u32 from) { | |
209 | write16(0xBE0F); | |
210 | ModRM(0, to, DISP32); | |
211 | write32(from); | |
212 | } | |
213 | ||
214 | /* movsx r16 to r32 */ | |
215 | void MOVSX32R16toR(int to, int from) { | |
216 | write16(0xBF0F); | |
217 | ModRM(3, to, from); | |
218 | } | |
219 | ||
220 | /* movsx m16 to r32 */ | |
221 | void MOVSX32M16toR(int to, u32 from) { | |
222 | write16(0xBF0F); | |
223 | ModRM(0, to, DISP32); | |
224 | write32(from); | |
225 | } | |
226 | ||
227 | /* movzx r8 to r32 */ | |
228 | void MOVZX32R8toR(int to, int from) { | |
229 | write16(0xB60F); | |
230 | ModRM(3, to, from); | |
231 | } | |
232 | ||
233 | /* movzx m8 to r32 */ | |
234 | void MOVZX32M8toR(int to, u32 from) { | |
235 | write16(0xB60F); | |
236 | ModRM(0, to, DISP32); | |
237 | write32(from); | |
238 | } | |
239 | ||
240 | /* movzx r16 to r32 */ | |
241 | void MOVZX32R16toR(int to, int from) { | |
242 | write16(0xB70F); | |
243 | ModRM(3, to, from); | |
244 | } | |
245 | ||
246 | /* movzx m16 to r32 */ | |
247 | void MOVZX32M16toR(int to, u32 from) { | |
248 | write16(0xB70F); | |
249 | ModRM(0, to, DISP32); | |
250 | write32(from); | |
251 | } | |
252 | ||
253 | /* cmovne r32 to r32 */ | |
254 | void CMOVNE32RtoR(int to, int from) { | |
255 | CMOV32RtoR(0x45, to, from); | |
256 | } | |
257 | ||
258 | /* cmovne m32 to r32*/ | |
259 | void CMOVNE32MtoR(int to, u32 from) { | |
260 | CMOV32MtoR(0x45, to, from); | |
261 | } | |
262 | ||
263 | /* cmove r32 to r32*/ | |
264 | void CMOVE32RtoR(int to, int from) { | |
265 | CMOV32RtoR(0x44, to, from); | |
266 | } | |
267 | ||
268 | /* cmove m32 to r32*/ | |
269 | void CMOVE32MtoR(int to, u32 from) { | |
270 | CMOV32MtoR(0x44, to, from); | |
271 | } | |
272 | ||
273 | /* cmovg r32 to r32*/ | |
274 | void CMOVG32RtoR(int to, int from) { | |
275 | CMOV32RtoR(0x4F, to, from); | |
276 | } | |
277 | ||
278 | /* cmovg m32 to r32*/ | |
279 | void CMOVG32MtoR(int to, u32 from) { | |
280 | CMOV32MtoR(0x4F, to, from); | |
281 | } | |
282 | ||
283 | /* cmovge r32 to r32*/ | |
284 | void CMOVGE32RtoR(int to, int from) { | |
285 | CMOV32RtoR(0x4D, to, from); | |
286 | } | |
287 | ||
288 | /* cmovge m32 to r32*/ | |
289 | void CMOVGE32MtoR(int to, u32 from) { | |
290 | CMOV32MtoR(0x4D, to, from); | |
291 | } | |
292 | ||
293 | /* cmovl r32 to r32*/ | |
294 | void CMOVL32RtoR(int to, int from) { | |
295 | CMOV32RtoR(0x4C, to, from); | |
296 | } | |
297 | ||
298 | /* cmovl m32 to r32*/ | |
299 | void CMOVL32MtoR(int to, u32 from) { | |
300 | CMOV32MtoR(0x4C, to, from); | |
301 | } | |
302 | ||
303 | /* cmovle r32 to r32*/ | |
304 | void CMOVLE32RtoR(int to, int from) { | |
305 | CMOV32RtoR(0x4E, to, from); | |
306 | } | |
307 | ||
308 | /* cmovle m32 to r32*/ | |
309 | void CMOVLE32MtoR(int to, u32 from) { | |
310 | CMOV32MtoR(0x4E, to, from); | |
311 | } | |
312 | ||
313 | // arithmic instructions | |
314 | ||
315 | /* add imm32 to r32 */ | |
316 | void ADD32ItoR(int to, u32 from) { | |
317 | if (to == EAX) { | |
318 | write8(0x05); | |
319 | } else { | |
320 | write8(0x81); | |
321 | ModRM(3, 0, to); | |
322 | } | |
323 | write32(from); | |
324 | } | |
325 | ||
326 | /* add imm32 to m32 */ | |
327 | void ADD32ItoM(u32 to, u32 from) { | |
328 | write8(0x81); | |
329 | ModRM(0, 0, DISP32); | |
330 | write32(to); | |
331 | write32(from); | |
332 | } | |
333 | ||
334 | /* add r32 to r32 */ | |
335 | void ADD32RtoR(int to, int from) { | |
336 | write8(0x01); | |
337 | ModRM(3, from, to); | |
338 | } | |
339 | ||
340 | /* add r32 to m32 */ | |
341 | void ADD32RtoM(u32 to, int from) { | |
342 | write8(0x01); | |
343 | ModRM(0, from, DISP32); | |
344 | write32(to); | |
345 | } | |
346 | ||
347 | /* add m32 to r32 */ | |
348 | void ADD32MtoR(int to, u32 from) { | |
349 | write8(0x03); | |
350 | ModRM(0, to, DISP32); | |
351 | write32(from); | |
352 | } | |
353 | ||
354 | /* adc imm32 to r32 */ | |
355 | void ADC32ItoR(int to, u32 from) { | |
356 | if (to == EAX) { | |
357 | write8(0x15); | |
358 | } else { | |
359 | write8(0x81); | |
360 | ModRM(3, 2, to); | |
361 | } | |
362 | write32(from); | |
363 | } | |
364 | ||
365 | /* adc r32 to r32 */ | |
366 | void ADC32RtoR(int to, int from) { | |
367 | write8(0x11); | |
368 | ModRM(3, from, to); | |
369 | } | |
370 | ||
371 | /* adc m32 to r32 */ | |
372 | void ADC32MtoR(int to, u32 from) { | |
373 | write8(0x13); | |
374 | ModRM(0, to, DISP32); | |
375 | write32(from); | |
376 | } | |
377 | ||
378 | /* inc r32 */ | |
379 | void INC32R(int to) { | |
380 | write8(0x40 + to); | |
381 | } | |
382 | ||
383 | /* inc m32 */ | |
384 | void INC32M(u32 to) { | |
385 | write8(0xFF); | |
386 | ModRM(0, 0, DISP32); | |
387 | write32(to); | |
388 | } | |
389 | ||
390 | /* sub imm32 to r32 */ | |
391 | void SUB32ItoR(int to, u32 from) { | |
392 | if (to == EAX) { | |
393 | write8(0x2D); | |
394 | } else { | |
395 | write8(0x81); | |
396 | ModRM(3, 5, to); | |
397 | } | |
398 | write32(from); | |
399 | } | |
400 | ||
401 | /* sub r32 to r32 */ | |
402 | void SUB32RtoR(int to, int from) { | |
403 | write8(0x29); | |
404 | ModRM(3, from, to); | |
405 | } | |
406 | ||
407 | /* sub m32 to r32 */ | |
408 | void SUB32MtoR(int to, u32 from) { | |
409 | write8(0x2B); | |
410 | ModRM(0, to, DISP32); | |
411 | write32(from); | |
412 | } | |
413 | ||
414 | /* sbb imm32 to r32 */ | |
415 | void SBB32ItoR(int to, u32 from) { | |
416 | if (to == EAX) { | |
417 | write8(0x1D); | |
418 | } else { | |
419 | write8(0x81); | |
420 | ModRM(3, 3, to); | |
421 | } | |
422 | write32(from); | |
423 | } | |
424 | ||
425 | /* sbb r32 to r32 */ | |
426 | void SBB32RtoR(int to, int from) { | |
427 | write8(0x19); | |
428 | ModRM(3, from, to); | |
429 | } | |
430 | ||
431 | /* sbb m32 to r32 */ | |
432 | void SBB32MtoR(int to, u32 from) { | |
433 | write8(0x1B); | |
434 | ModRM(0, to, DISP32); | |
435 | write32(from); | |
436 | } | |
437 | ||
438 | /* dec r32 */ | |
439 | void DEC32R(int to) { | |
440 | write8(0x48 + to); | |
441 | } | |
442 | ||
443 | /* dec m32 */ | |
444 | void DEC32M(u32 to) { | |
445 | write8(0xFF); | |
446 | ModRM(0, 1, DISP32); | |
447 | write32(to); | |
448 | } | |
449 | ||
450 | /* mul eax by r32 to edx:eax */ | |
451 | void MUL32R(int from) { | |
452 | write8(0xF7); | |
453 | ModRM(3, 4, from); | |
454 | } | |
455 | ||
456 | /* imul eax by r32 to edx:eax */ | |
457 | void IMUL32R(int from) { | |
458 | write8(0xF7); | |
459 | ModRM(3, 5, from); | |
460 | } | |
461 | ||
462 | /* mul eax by m32 to edx:eax */ | |
463 | void MUL32M(u32 from) { | |
464 | write8(0xF7); | |
465 | ModRM(0, 4, DISP32); | |
466 | write32(from); | |
467 | } | |
468 | ||
469 | /* imul eax by m32 to edx:eax */ | |
470 | void IMUL32M(u32 from) { | |
471 | write8(0xF7); | |
472 | ModRM(0, 5, DISP32); | |
473 | write32(from); | |
474 | } | |
475 | ||
476 | /* imul r32 by r32 to r32 */ | |
477 | void IMUL32RtoR(int to, int from) { | |
478 | write16(0xAF0F); | |
479 | ModRM(3, to, from); | |
480 | } | |
481 | ||
482 | /* div eax by r32 to edx:eax */ | |
483 | void DIV32R(int from) { | |
484 | write8(0xF7); | |
485 | ModRM(3, 6, from); | |
486 | } | |
487 | ||
488 | /* idiv eax by r32 to edx:eax */ | |
489 | void IDIV32R(int from) { | |
490 | write8(0xF7); | |
491 | ModRM(3, 7, from); | |
492 | } | |
493 | ||
494 | /* div eax by m32 to edx:eax */ | |
495 | void DIV32M(u32 from) { | |
496 | write8(0xF7); | |
497 | ModRM(0, 6, DISP32); | |
498 | write32(from); | |
499 | } | |
500 | ||
501 | /* idiv eax by m32 to edx:eax */ | |
502 | void IDIV32M(u32 from) { | |
503 | write8(0xF7); | |
504 | ModRM(0, 7, DISP32); | |
505 | write32(from); | |
506 | } | |
507 | ||
508 | // shifting instructions | |
509 | ||
510 | void RCR32ItoR(int to,int from) | |
511 | { | |
512 | if (from==1) | |
513 | { | |
514 | write8(0xd1); | |
515 | write8(0xd8 | to); | |
516 | } | |
517 | else | |
518 | { | |
519 | write8(0xc1); | |
520 | write8(0xd8 | to); | |
521 | write8(from); | |
522 | } | |
523 | } | |
524 | ||
525 | /* shl imm8 to r32 */ | |
526 | void SHL32ItoR(int to, u8 from) { | |
527 | if (from==1) | |
528 | { | |
529 | write8(0xd1); | |
530 | write8(0xe0 | to); | |
531 | return; | |
532 | } | |
533 | write8(0xC1); | |
534 | ModRM(3, 4, to); | |
535 | write8(from); | |
536 | } | |
537 | ||
538 | /* shl cl to r32 */ | |
539 | void SHL32CLtoR(int to) { | |
540 | write8(0xD3); | |
541 | ModRM(3, 4, to); | |
542 | } | |
543 | ||
544 | /* shr imm8 to r32 */ | |
545 | void SHR32ItoR(int to, u8 from) { | |
546 | if (from==1) | |
547 | { | |
548 | write8(0xd1); | |
549 | write8(0xe8 | to); | |
550 | return; | |
551 | } | |
552 | write8(0xC1); | |
553 | ModRM(3, 5, to); | |
554 | write8(from); | |
555 | } | |
556 | ||
557 | /* shr cl to r32 */ | |
558 | void SHR32CLtoR(int to) { | |
559 | write8(0xD3); | |
560 | ModRM(3, 5, to); | |
561 | } | |
562 | ||
563 | /* sar imm8 to r32 */ | |
564 | void SAR32ItoR(int to, u8 from) { | |
565 | write8(0xC1); | |
566 | ModRM(3, 7, to); | |
567 | write8(from); | |
568 | } | |
569 | ||
570 | /* sar cl to r32 */ | |
571 | void SAR32CLtoR(int to) { | |
572 | write8(0xD3); | |
573 | ModRM(3, 7, to); | |
574 | } | |
575 | ||
576 | ||
577 | // logical instructions | |
578 | ||
579 | /* or imm32 to r32 */ | |
580 | void OR32ItoR(int to, u32 from) { | |
581 | if (to == EAX) { | |
582 | write8(0x0D); | |
583 | } else { | |
584 | write8(0x81); | |
585 | ModRM(3, 1, to); | |
586 | } | |
587 | write32(from); | |
588 | } | |
589 | ||
590 | /* or imm32 to m32 */ | |
591 | void OR32ItoM(u32 to, u32 from) { | |
592 | write8(0x81); | |
593 | ModRM(0, 1, DISP32); | |
594 | write32(to); | |
595 | write32(from); | |
596 | } | |
597 | ||
598 | /* or r32 to r32 */ | |
599 | void OR32RtoR(int to, int from) { | |
600 | write8(0x09); | |
601 | ModRM(3, from, to); | |
602 | } | |
603 | ||
604 | /* or r32 to m32 */ | |
605 | void OR32RtoM(u32 to, int from) { | |
606 | write8(0x09); | |
607 | ModRM(0, from, DISP32); | |
608 | write32(to); | |
609 | } | |
610 | ||
611 | /* or m32 to r32 */ | |
612 | void OR32MtoR(int to, u32 from) { | |
613 | write8(0x0B); | |
614 | ModRM(0, to, DISP32); | |
615 | write32(from); | |
616 | } | |
617 | ||
618 | /* xor imm32 to r32 */ | |
619 | void XOR32ItoR(int to, u32 from) { | |
620 | if (to == EAX) { | |
621 | write8(0x35); | |
622 | } else { | |
623 | write8(0x81); | |
624 | ModRM(3, 6, to); | |
625 | } | |
626 | write32(from); | |
627 | } | |
628 | ||
629 | /* xor imm32 to m32 */ | |
630 | void XOR32ItoM(u32 to, u32 from) { | |
631 | write8(0x81); | |
632 | ModRM(0, 6, DISP32); | |
633 | write32(to); | |
634 | write32(from); | |
635 | } | |
636 | ||
637 | /* xor r32 to r32 */ | |
638 | void XOR32RtoR(int to, int from) { | |
639 | write8(0x31); | |
640 | ModRM(3, from, to); | |
641 | } | |
642 | ||
643 | /* xor r32 to m32 */ | |
644 | void XOR32RtoM(u32 to, int from) { | |
645 | write8(0x31); | |
646 | ModRM(0, from, DISP32); | |
647 | write32(to); | |
648 | } | |
649 | ||
650 | /* xor m32 to r32 */ | |
651 | void XOR32MtoR(int to, u32 from) { | |
652 | write8(0x33); | |
653 | ModRM(0, to, DISP32); | |
654 | write32(from); | |
655 | } | |
656 | ||
657 | /* and imm32 to r32 */ | |
658 | void AND32ItoR(int to, u32 from) { | |
659 | if (to == EAX) { | |
660 | write8(0x25); | |
661 | } else { | |
662 | write8(0x81); | |
663 | ModRM(3, 0x4, to); | |
664 | } | |
665 | write32(from); | |
666 | } | |
667 | ||
668 | /* and imm32 to m32 */ | |
669 | void AND32ItoM(u32 to, u32 from) { | |
670 | write8(0x81); | |
671 | ModRM(0, 0x4, DISP32); | |
672 | write32(to); | |
673 | write32(from); | |
674 | } | |
675 | ||
676 | /* and r32 to r32 */ | |
677 | void AND32RtoR(int to, int from) { | |
678 | write8(0x21); | |
679 | ModRM(3, from, to); | |
680 | } | |
681 | ||
682 | /* and r32 to m32 */ | |
683 | void AND32RtoM(u32 to, int from) { | |
684 | write8(0x21); | |
685 | ModRM(0, from, DISP32); | |
686 | write32(to); | |
687 | } | |
688 | ||
689 | /* and m32 to r32 */ | |
690 | void AND32MtoR(int to, u32 from) { | |
691 | write8(0x23); | |
692 | ModRM(0, to, DISP32); | |
693 | write32(from); | |
694 | } | |
695 | ||
696 | /* not r32 */ | |
697 | void NOT32R(int from) { | |
698 | write8(0xF7); | |
699 | ModRM(3, 2, from); | |
700 | } | |
701 | ||
702 | /* neg r32 */ | |
703 | void NEG32R(int from) { | |
704 | write8(0xF7); | |
705 | ModRM(3, 3, from); | |
706 | } | |
707 | ||
708 | // jump instructions | |
709 | ||
710 | /* jmp rel8 */ | |
711 | u8* JMP8(u8 to) { | |
712 | write8(0xEB); | |
713 | write8(to); | |
714 | return x86Ptr - 1; | |
715 | } | |
716 | ||
717 | /* jmp rel32 */ | |
718 | u32* JMP32(u32 to) { | |
719 | write8(0xE9); | |
720 | write32(to); | |
721 | return (u32*)(x86Ptr - 4); | |
722 | } | |
723 | ||
724 | /* jmp r32 */ | |
725 | void JMP32R(int to) { | |
726 | write8(0xFF); | |
727 | ModRM(3, 4, to); | |
728 | } | |
729 | ||
730 | /* je rel8 */ | |
731 | u8* JE8(u8 to) { | |
732 | J8Rel(0x74, to); | |
733 | } | |
734 | ||
735 | /* jz rel8 */ | |
736 | u8* JZ8(u8 to) { | |
737 | J8Rel(0x74, to); | |
738 | } | |
739 | ||
740 | /* jg rel8 */ | |
741 | u8* JG8(u8 to) { | |
742 | J8Rel(0x7F, to); | |
743 | } | |
744 | ||
745 | /* jge rel8 */ | |
746 | u8* JGE8(u8 to) { | |
747 | J8Rel(0x7D, to); | |
748 | } | |
749 | ||
750 | /* jl rel8 */ | |
751 | u8* JL8(u8 to) { | |
752 | J8Rel(0x7C, to); | |
753 | } | |
754 | ||
755 | /* jle rel8 */ | |
756 | u8* JLE8(u8 to) { | |
757 | J8Rel(0x7E, to); | |
758 | } | |
759 | ||
760 | /* jne rel8 */ | |
761 | u8* JNE8(u8 to) { | |
762 | J8Rel(0x75, to); | |
763 | } | |
764 | ||
765 | /* jnz rel8 */ | |
766 | u8* JNZ8(u8 to) { | |
767 | J8Rel(0x75, to); | |
768 | } | |
769 | ||
770 | /* jng rel8 */ | |
771 | u8* JNG8(u8 to) { | |
772 | J8Rel(0x7E, to); | |
773 | } | |
774 | ||
775 | /* jnge rel8 */ | |
776 | u8* JNGE8(u8 to) { | |
777 | J8Rel(0x7C, to); | |
778 | } | |
779 | ||
780 | /* jnl rel8 */ | |
781 | u8* JNL8(u8 to) { | |
782 | J8Rel(0x7D, to); | |
783 | } | |
784 | ||
785 | /* jnle rel8 */ | |
786 | u8* JNLE8(u8 to) { | |
787 | J8Rel(0x7F, to); | |
788 | } | |
789 | ||
790 | /* jo rel8 */ | |
791 | u8* JO8(u8 to) { | |
792 | J8Rel(0x70, to); | |
793 | } | |
794 | ||
795 | /* jno rel8 */ | |
796 | u8* JNO8(u8 to) { | |
797 | J8Rel(0x71, to); | |
798 | } | |
799 | ||
800 | /* je rel32 */ | |
801 | u32* JE32(u32 to) { | |
802 | J32Rel(0x84, to); | |
803 | } | |
804 | ||
805 | /* jz rel32 */ | |
806 | u32* JZ32(u32 to) { | |
807 | J32Rel(0x84, to); | |
808 | } | |
809 | ||
810 | /* jg rel32 */ | |
811 | u32* JG32(u32 to) { | |
812 | J32Rel(0x8F, to); | |
813 | } | |
814 | ||
815 | /* jge rel32 */ | |
816 | u32* JGE32(u32 to) { | |
817 | J32Rel(0x8D, to); | |
818 | } | |
819 | ||
820 | /* jl rel32 */ | |
821 | u32* JL32(u32 to) { | |
822 | J32Rel(0x8C, to); | |
823 | } | |
824 | ||
825 | /* jle rel32 */ | |
826 | u32* JLE32(u32 to) { | |
827 | J32Rel(0x8E, to); | |
828 | } | |
829 | ||
830 | /* jne rel32 */ | |
831 | u32* JNE32(u32 to) { | |
832 | J32Rel(0x85, to); | |
833 | } | |
834 | ||
835 | /* jnz rel32 */ | |
836 | u32* JNZ32(u32 to) { | |
837 | J32Rel(0x85, to); | |
838 | } | |
839 | ||
840 | /* jng rel32 */ | |
841 | u32* JNG32(u32 to) { | |
842 | J32Rel(0x8E, to); | |
843 | } | |
844 | ||
845 | /* jnge rel32 */ | |
846 | u32* JNGE32(u32 to) { | |
847 | J32Rel(0x8C, to); | |
848 | } | |
849 | ||
850 | /* jnl rel32 */ | |
851 | u32* JNL32(u32 to) { | |
852 | J32Rel(0x8D, to); | |
853 | } | |
854 | ||
855 | /* jnle rel32 */ | |
856 | u32* JNLE32(u32 to) { | |
857 | J32Rel(0x8F, to); | |
858 | } | |
859 | ||
860 | /* jo rel32 */ | |
861 | u32* JO32(u32 to) { | |
862 | J32Rel(0x80, to); | |
863 | } | |
864 | ||
865 | /* jno rel32 */ | |
866 | u32* JNO32(u32 to) { | |
867 | J32Rel(0x81, to); | |
868 | } | |
869 | ||
870 | /* call func */ | |
871 | void CALLFunc(u32 func) { | |
872 | CALL32(func - ((u32)x86Ptr + 5)); | |
873 | } | |
874 | ||
875 | /* call rel32 */ | |
876 | void CALL32(u32 to) { | |
877 | write8(0xE8); | |
878 | write32(to); | |
879 | } | |
880 | ||
881 | /* call r32 */ | |
882 | void CALL32R(int to) { | |
883 | write8(0xFF); | |
884 | ModRM(3, 2, to); | |
885 | } | |
886 | ||
887 | /* call m32 */ | |
888 | void CALL32M(u32 to) { | |
889 | write8(0xFF); | |
890 | ModRM(0, 2, DISP32); | |
891 | write32(to); | |
892 | } | |
893 | ||
894 | // misc instructions | |
895 | ||
896 | /* cmp imm32 to r32 */ | |
897 | void CMP32ItoR(int to, u32 from) { | |
898 | if (to == EAX) { | |
899 | write8(0x3D); | |
900 | } else { | |
901 | write8(0x81); | |
902 | ModRM(3, 7, to); | |
903 | } | |
904 | write32(from); | |
905 | } | |
906 | ||
907 | /* cmp imm32 to m32 */ | |
908 | void CMP32ItoM(u32 to, u32 from) { | |
909 | write8(0x81); | |
910 | ModRM(0, 7, DISP32); | |
911 | write32(to); | |
912 | write32(from); | |
913 | } | |
914 | ||
915 | /* cmp r32 to r32 */ | |
916 | void CMP32RtoR(int to, int from) { | |
917 | write8(0x39); | |
918 | ModRM(3, from, to); | |
919 | } | |
920 | ||
921 | /* cmp m32 to r32 */ | |
922 | void CMP32MtoR(int to, u32 from) { | |
923 | write8(0x3B); | |
924 | ModRM(0, to, DISP32); | |
925 | write32(from); | |
926 | } | |
927 | ||
928 | /* test imm32 to r32 */ | |
929 | void TEST32ItoR(int to, u32 from) { | |
930 | if (to == EAX) { | |
931 | write8(0xA9); | |
932 | } else { | |
933 | write8(0xF7); | |
934 | ModRM(3, 0, to); | |
935 | } | |
936 | write32(from); | |
937 | } | |
938 | ||
939 | /* test r32 to r32 */ | |
940 | void TEST32RtoR(int to, int from) { | |
941 | write8(0x85); | |
942 | ModRM(3, from, to); | |
943 | } | |
944 | ||
945 | void BT32ItoR(int to,int from) | |
946 | { | |
947 | write16(0xba0f); | |
948 | write8(0xe0 | to); | |
949 | write8(from); | |
950 | } | |
951 | ||
952 | /* sets r8 */ | |
953 | void SETS8R(int to) { | |
954 | SET8R(0x98, to); | |
955 | } | |
956 | /* setl r8 */ | |
957 | void SETL8R(int to) { | |
958 | SET8R(0x9C, to); | |
959 | } | |
960 | ||
961 | /* setb r8 */ | |
962 | void SETB8R(int to) { | |
963 | SET8R(0x92, to); | |
964 | } | |
965 | ||
966 | /* setnz r8 */ | |
967 | void SETNZ8R(int to) { | |
968 | SET8R(0x95,to); | |
969 | } | |
970 | ||
971 | /* cbw */ | |
972 | void CBW() { | |
973 | write16(0x9866); | |
974 | } | |
975 | ||
976 | /* cwd */ | |
977 | void CWD() { | |
978 | write8(0x98); | |
979 | } | |
980 | ||
981 | /* cdq */ | |
982 | void CDQ() { | |
983 | write8(0x99); | |
984 | } | |
985 | ||
986 | /* push r32 */ | |
987 | void PUSH32R(int from) { | |
988 | write8(0x50 | from); | |
989 | } | |
990 | ||
991 | /* push m32 */ | |
992 | void PUSH32M(u32 from) { | |
993 | write8(0xFF); | |
994 | ModRM(0, 6, DISP32); | |
995 | write32(from); | |
996 | } | |
997 | ||
998 | /* push imm32 */ | |
999 | void PUSH32I(u32 from) { | |
1000 | write8(0x68); write32(from); | |
1001 | } | |
1002 | ||
1003 | /* pop r32 */ | |
1004 | void POP32R(int from) { | |
1005 | write8(0x58 | from); | |
1006 | } | |
1007 | ||
1008 | /* pushad */ | |
1009 | void PUSHA32() { | |
1010 | write8(0x60); | |
1011 | } | |
1012 | ||
1013 | /* popad */ | |
1014 | void POPA32() { | |
1015 | write8(0x61); | |
1016 | } | |
1017 | ||
1018 | /* ret */ | |
1019 | void RET() { | |
1020 | write8(0xC3); | |
1021 | } | |
1022 | ||
1023 | /********************/ | |
1024 | /* FPU instructions */ | |
1025 | /********************/ | |
1026 | ||
1027 | //Added:basara 14.01.2003 | |
1028 | /* compare m32 to fpu reg stack */ | |
1029 | void FCOMP32(u32 from) { | |
1030 | write8(0xD8); | |
1031 | ModRM(0, 0x3, DISP32); | |
1032 | write32(from); | |
1033 | } | |
1034 | ||
1035 | void FNSTSWtoAX() { | |
1036 | write16(0xE0DF); | |
1037 | } | |
1038 | ||
1039 | /* fild m32 to fpu reg stack */ | |
1040 | void FILD32(u32 from) { | |
1041 | write8(0xDB); | |
1042 | ModRM(0, 0x0, DISP32); | |
1043 | write32(from); | |
1044 | } | |
1045 | ||
1046 | /* fistp m32 from fpu reg stack */ | |
1047 | void FISTP32(u32 from) { | |
1048 | write8(0xDB); | |
1049 | ModRM(0, 0x3, DISP32); | |
1050 | write32(from); | |
1051 | } | |
1052 | ||
1053 | /* fld m32 to fpu reg stack */ | |
1054 | void FLD32(u32 from) { | |
1055 | write8(0xD9); | |
1056 | ModRM(0, 0x0, DISP32); | |
1057 | write32(from); | |
1058 | } | |
1059 | ||
1060 | /* fstp m32 from fpu reg stack */ | |
1061 | void FSTP32(u32 to) { | |
1062 | write8(0xD9); | |
1063 | ModRM(0, 0x3, DISP32); | |
1064 | write32(to); | |
1065 | } | |
1066 | ||
1067 | // | |
1068 | ||
1069 | /* fldcw fpu control word from m16 */ | |
1070 | void FLDCW(u32 from) { | |
1071 | write8(0xD9); | |
1072 | ModRM(0, 0x5, DISP32); | |
1073 | write32(from); | |
1074 | } | |
1075 | ||
1076 | /* fnstcw fpu control word to m16 */ | |
1077 | void FNSTCW(u32 to) { | |
1078 | write8(0xD9); | |
1079 | ModRM(0, 0x7, DISP32); | |
1080 | write32(to); | |
1081 | } | |
1082 | ||
1083 | // | |
1084 | ||
1085 | /* fadd m32 to fpu reg stack */ | |
1086 | void FADD32(u32 from) { | |
1087 | write8(0xD8); | |
1088 | ModRM(0, 0x0, DISP32); | |
1089 | write32(from); | |
1090 | } | |
1091 | ||
1092 | /* fsub m32 to fpu reg stack */ | |
1093 | void FSUB32(u32 from) { | |
1094 | write8(0xD8); | |
1095 | ModRM(0, 0x4, DISP32); | |
1096 | write32(from); | |
1097 | } | |
1098 | ||
1099 | /* fmul m32 to fpu reg stack */ | |
1100 | void FMUL32(u32 from) { | |
1101 | write8(0xD8); | |
1102 | ModRM(0, 0x1, DISP32); | |
1103 | write32(from); | |
1104 | } | |
1105 | ||
1106 | /* fdiv m32 to fpu reg stack */ | |
1107 | void FDIV32(u32 from) { | |
1108 | write8(0xD8); | |
1109 | ModRM(0, 0x6, DISP32); | |
1110 | write32(from); | |
1111 | } | |
1112 | ||
1113 | /* fabs fpu reg stack */ | |
1114 | void FABS() { | |
1115 | write16(0xE1D9); | |
1116 | } | |
1117 | ||
1118 | /* fsqrt fpu reg stack */ | |
1119 | void FSQRT() { | |
1120 | write16(0xFAD9); | |
1121 | } | |
1122 | ||
1123 | /* fchs fpu reg stack */ | |
1124 | void FCHS() { | |
1125 | write16(0xE0D9); | |
1126 | } | |
1127 | ||
1128 | /********************/ | |
1129 | /* MMX instructions */ | |
1130 | /********************/ | |
1131 | ||
1132 | // r64 = mm | |
1133 | ||
1134 | /* movq m64 to r64 */ | |
1135 | void MOVQMtoR(int to, u32 from) { | |
1136 | write16(0x6F0F); | |
1137 | ModRM(0, to, DISP32); | |
1138 | write32(from); | |
1139 | } | |
1140 | ||
1141 | /* movq r64 to m64 */ | |
1142 | void MOVQRtoM(u32 to, int from) { | |
1143 | write16(0x7F0F); | |
1144 | ModRM(0, from, DISP32); | |
1145 | write32(to); | |
1146 | } | |
1147 | ||
1148 | /* pand r64 to r64 */ | |
1149 | void PANDRtoR(int to, int from) { | |
1150 | write16(0xDB0F); | |
1151 | ModRM(3, to, from); | |
1152 | } | |
1153 | ||
1154 | /* pand r64 to r64 */ | |
1155 | void PANDNRtoR(int to, int from) { | |
1156 | write16(0xDF0F); | |
1157 | ModRM(3, to, from); | |
1158 | } | |
1159 | ||
1160 | /* por r64 to r64 */ | |
1161 | void PORRtoR(int to, int from) { | |
1162 | write16(0xEB0F); | |
1163 | ModRM(3, to, from); | |
1164 | } | |
1165 | ||
1166 | /* pxor r64 to r64 */ | |
1167 | void PXORRtoR(int to, int from) { | |
1168 | write16(0xEF0F); | |
1169 | ModRM(3, to, from); | |
1170 | } | |
1171 | ||
1172 | /* psllq r64 to r64 */ | |
1173 | void PSLLQRtoR(int to, int from) { | |
1174 | write16(0xF30F); | |
1175 | ModRM(3, to, from); | |
1176 | } | |
1177 | ||
1178 | /* psllq m64 to r64 */ | |
1179 | void PSLLQMtoR(int to, u32 from) { | |
1180 | write16(0xF30F); | |
1181 | ModRM(0, to, DISP32); | |
1182 | write32(from); | |
1183 | } | |
1184 | ||
1185 | /* psllq imm8 to r64 */ | |
1186 | void PSLLQItoR(int to, u8 from) { | |
1187 | write16(0x730F); | |
1188 | ModRM(3, 6, to); | |
1189 | write8(from); | |
1190 | } | |
1191 | ||
1192 | /* psrlq r64 to r64 */ | |
1193 | void PSRLQRtoR(int to, int from) { | |
1194 | write16(0xD30F); | |
1195 | ModRM(3, to, from); | |
1196 | } | |
1197 | ||
1198 | /* psrlq m64 to r64 */ | |
1199 | void PSRLQMtoR(int to, u32 from) { | |
1200 | write16(0xD30F); | |
1201 | ModRM(0, to, DISP32); | |
1202 | write32(from); | |
1203 | } | |
1204 | ||
1205 | /* psrlq imm8 to r64 */ | |
1206 | void PSRLQItoR(int to, u8 from) { | |
1207 | write16(0x730F); | |
1208 | ModRM(3, 2, to); | |
1209 | write8(from); | |
1210 | } | |
1211 | ||
1212 | /* paddusb r64 to r64 */ | |
1213 | void PADDUSBRtoR(int to, int from) { | |
1214 | write16(0xDC0F); | |
1215 | ModRM(3, to, from); | |
1216 | } | |
1217 | ||
1218 | /* paddusb m64 to r64 */ | |
1219 | void PADDUSBMtoR(int to, u32 from) { | |
1220 | write16(0xDC0F); | |
1221 | ModRM(0, to, DISP32); | |
1222 | write32(from); | |
1223 | } | |
1224 | ||
1225 | /* paddusw r64 to r64 */ | |
1226 | void PADDUSWRtoR(int to, int from) { | |
1227 | write16(0xDD0F); | |
1228 | ModRM(3, to, from); | |
1229 | } | |
1230 | ||
1231 | /* paddusw m64 to r64 */ | |
1232 | void PADDUSWMtoR(int to, u32 from) { | |
1233 | write16(0xDD0F); | |
1234 | ModRM(0, to, DISP32); | |
1235 | write32(from); | |
1236 | } | |
1237 | ||
1238 | /* paddb r64 to r64 */ | |
1239 | void PADDBRtoR(int to, int from) { | |
1240 | write16(0xFC0F); | |
1241 | ModRM(3, to, from); | |
1242 | } | |
1243 | ||
1244 | /* paddb m64 to r64 */ | |
1245 | void PADDBMtoR(int to, u32 from) { | |
1246 | write16(0xFC0F); | |
1247 | ModRM(0, to, DISP32); | |
1248 | write32(from); | |
1249 | } | |
1250 | ||
1251 | /* paddw r64 to r64 */ | |
1252 | void PADDWRtoR(int to, int from) { | |
1253 | write16(0xFD0F); | |
1254 | ModRM(3, to, from); | |
1255 | } | |
1256 | ||
1257 | /* paddw m64 to r64 */ | |
1258 | void PADDWMtoR(int to, u32 from) { | |
1259 | write16(0xFD0F); | |
1260 | ModRM(0, to, DISP32); | |
1261 | write32(from); | |
1262 | } | |
1263 | ||
1264 | /* paddd r64 to r64 */ | |
1265 | void PADDDRtoR(int to, int from) { | |
1266 | write16(0xFE0F); | |
1267 | ModRM(3, to, from); | |
1268 | } | |
1269 | ||
1270 | /* paddd m64 to r64 */ | |
1271 | void PADDDMtoR(int to, u32 from) { | |
1272 | write16(0xFE0F); | |
1273 | ModRM(0, to, DISP32); | |
1274 | write32(from); | |
1275 | } | |
1276 | ||
1277 | /* emms */ | |
1278 | void EMMS() { | |
1279 | //use femms if we have 3dnow | |
1280 | write16(0x0e0f); | |
1281 | return; | |
1282 | } | |
1283 | ||
1284 | /* femms */ | |
1285 | void FEMMS() { | |
1286 | write16(0x770F); | |
1287 | return; | |
1288 | } | |
1289 | ||
1290 | //Basara:changed | |
1291 | void PADDSBRtoR(int to, int from) { | |
1292 | write16(0xEC0F); | |
1293 | ModRM(3, to, from); | |
1294 | } | |
1295 | ||
1296 | void PADDSWRtoR(int to, int from) { | |
1297 | write16(0xED0F); | |
1298 | ModRM(3, to, from); | |
1299 | } | |
1300 | ||
1301 | void PADDSDRtoR(int to, int from) { | |
1302 | write16(0xEE0F); | |
1303 | ModRM(3, to, from); | |
1304 | } | |
1305 | ||
1306 | void PSUBSBRtoR(int to, int from) { | |
1307 | write16(0xE80F); | |
1308 | ModRM(3, to, from); | |
1309 | } | |
1310 | ||
1311 | void PSUBSWRtoR(int to, int from) { | |
1312 | write16(0xE90F); | |
1313 | ModRM(3, to, from); | |
1314 | } | |
1315 | ||
1316 | void PSUBSDRtoR(int to, int from) { | |
1317 | write16(0xEA0F); | |
1318 | ModRM(3, to, from); | |
1319 | } | |
1320 | ||
1321 | void PSUBBRtoR(int to, int from) { | |
1322 | write16(0xF80F); | |
1323 | ModRM(3, to, from); | |
1324 | } | |
1325 | ||
1326 | void PSUBWRtoR(int to, int from) { | |
1327 | write16(0xF90F); | |
1328 | ModRM(3, to, from); | |
1329 | } | |
1330 | ||
1331 | void PSUBDRtoR(int to, int from) { | |
1332 | write16(0xFA0F); | |
1333 | ModRM(3, to, from); | |
1334 | } | |
1335 | ||
1336 | //changed:basara | |
1337 | //P.s.It's sux.Don't use it offten. | |
1338 | void MOVQ64ItoR(int reg,u64 i) | |
1339 | { | |
1340 | MOVQMtoR(reg,(u32)(x86Ptr)+2+7); | |
1341 | JMP8(8); | |
1342 | write64(i); | |
1343 | } | |
1344 | ||
1345 | void PSUBUSBRtoR(int to, int from) { | |
1346 | write16(0xD80F); | |
1347 | ModRM(3, to, from); | |
1348 | } | |
1349 | ||
1350 | void PSUBUSWRtoR(int to, int from) { | |
1351 | write16(0xD90F); | |
1352 | ModRM(3, to, from); | |
1353 | } | |
1354 | ||
1355 | void PMAXSWRtoR(int to,int from) | |
1356 | { | |
1357 | write16(0xEE0F); | |
1358 | ModRM(3, to, from); | |
1359 | } | |
1360 | ||
1361 | void PMINSWRtoR(int to,int from) | |
1362 | { | |
1363 | write16(0xEA0F); | |
1364 | ModRM(3, to, from); | |
1365 | } | |
1366 | ||
1367 | void PCMPEQBRtoR(int to,int from) | |
1368 | { | |
1369 | write16(0x740F); | |
1370 | ModRM(3, to, from); | |
1371 | } | |
1372 | ||
1373 | void PCMPEQWRtoR(int to,int from) | |
1374 | { | |
1375 | write16(0x750F); | |
1376 | ModRM(3, to, from); | |
1377 | } | |
1378 | ||
1379 | void PCMPEQDRtoR(int to,int from) | |
1380 | { | |
1381 | write16(0x760F); | |
1382 | ModRM(3, to, from); | |
1383 | } | |
1384 | ||
1385 | void PCMPGTBRtoR(int to,int from) | |
1386 | { | |
1387 | write16(0x640F); | |
1388 | ModRM(3, to, from); | |
1389 | } | |
1390 | ||
1391 | void PCMPGTWRtoR(int to,int from) | |
1392 | { | |
1393 | write16(0x650F); | |
1394 | ModRM(3, to, from); | |
1395 | } | |
1396 | ||
1397 | void PCMPGTDRtoR(int to,int from) | |
1398 | { | |
1399 | write16(0x660F); | |
1400 | ModRM(3, to, from); | |
1401 | } | |
1402 | ||
1403 | //Basara:Added 10.01.2003 | |
1404 | void PSRLWItoR(int to,int from) | |
1405 | { | |
1406 | write16(0x710f); | |
1407 | ModRM(2, 2 , to); | |
1408 | write8(from); | |
1409 | } | |
1410 | void PSRLDItoR(int to,int from) | |
1411 | { | |
1412 | write16(0x720f); | |
1413 | ModRM(2, 2 , to); | |
1414 | write8(from); | |
1415 | } | |
1416 | ||
1417 | void PSLLWItoR(int to,int from) | |
1418 | { | |
1419 | write16(0x710f); | |
1420 | ModRM(3, 6 , to); | |
1421 | write8(from); | |
1422 | } | |
1423 | ||
1424 | void PSLLDItoR(int to,int from) | |
1425 | { | |
1426 | write16(0x720f); | |
1427 | ModRM(3, 6 , to); | |
1428 | write8(from); | |
1429 | } | |
1430 | ||
1431 | void PSRAWItoR(int to,int from) | |
1432 | { | |
1433 | write16(0x710f); | |
1434 | ModRM(3, 4 , to); | |
1435 | write8(from); | |
1436 | } | |
1437 | ||
1438 | void PSRADItoR(int to,int from) | |
1439 | { | |
1440 | write16(0x720f); | |
1441 | ModRM(3, 4 , to); | |
1442 | write8(from); | |
1443 | } | |
1444 | ||
1445 | /* por m64 to r64 */ | |
1446 | void PORMtoR(int to, u32 from) { | |
1447 | write16(0xEB0F); | |
1448 | ModRM(0, to, DISP32); | |
1449 | write32(from); | |
1450 | } | |
1451 | ||
1452 | /* pxor m64 to r64 */ | |
1453 | void PXORMtoR(int to, u32 from) { | |
1454 | write16(0xEF0F); | |
1455 | ModRM(0, to, DISP32); | |
1456 | write32(from); | |
1457 | } | |
1458 | ||
1459 | /* pand m64 to r64 */ | |
1460 | void PANDMtoR(int to, u32 from) { | |
1461 | write16(0xDB0F); | |
1462 | ModRM(0, to, DISP32); | |
1463 | write32(from); | |
1464 | } | |
1465 | ||
1466 | /* pandn m64 to r64 */ | |
1467 | void PANDNMtoR(int to, u32 from) { | |
1468 | write16(0xDF0F); | |
1469 | ModRM(0, to, DISP32); | |
1470 | write32(from); | |
1471 | } | |
1472 | ||
1473 | /* movd m32 to r64 */ | |
1474 | void MOVDMtoR(int to, u32 from) { | |
1475 | write16(0x6E0F); | |
1476 | ModRM(0, to, DISP32); | |
1477 | write32(from); | |
1478 | } | |
1479 | ||
1480 | /* movq r64 to m32 */ | |
1481 | void MOVDRtoM(u32 to, int from) { | |
1482 | write16(0x7E0F); | |
1483 | ModRM(0, from, DISP32); | |
1484 | write32(to); | |
1485 | } | |
1486 | ||
1487 | /* movd r32 to r64 */ | |
1488 | void MOVD32RtoR(int to, int from) { | |
1489 | write16(0x6E0F); | |
1490 | ModRM(3, to,from); | |
1491 | } | |
1492 | ||
1493 | /* movq r64 to r32 */ | |
1494 | void MOVD64RtoR(int to, int from) { | |
1495 | write16(0x7E0F); | |
1496 | ModRM(3, from,to); | |
1497 | } | |
1498 | ||
1499 | void MOVQRtoR(int to, int from) { | |
1500 | write16(0x6F0F); | |
1501 | ModRM(3, to,from); | |
1502 | } | |
1503 | ||
1504 | void PUNPCKHDQRtoR(int to, int from) { | |
1505 | write16(0x6A0F); | |
1506 | ModRM(3, to,from); | |
1507 | } | |
1508 | ||
1509 | void PUNPCKLDQRtoR(int to, int from) { | |
1510 | write16(0x620F); | |
1511 | ModRM(3, to,from); | |
1512 | } | |
1513 | ||
1514 | ////////////////////////////////////////////////////////////////////////// | |
1515 | // SSE intructions | |
1516 | ////////////////////////////////////////////////////////////////////////// | |
1517 | ||
1518 | void MOVAPSMtoR(int to, int from) { | |
1519 | write16(0x280f); | |
1520 | ModRM(0, to, DISP32); | |
1521 | write32(from); | |
1522 | } | |
1523 | ||
1524 | void MOVAPSRtoM(int to, int from) { | |
1525 | write16(0x2b0f); | |
1526 | ModRM(0, from, DISP32); | |
1527 | write32(to); | |
1528 | } | |
1529 | ||
1530 | void MOVAPSRtoR(int to, int from) { | |
1531 | write16(0x290f); | |
1532 | ModRM(3, to,from); | |
1533 | } | |
1534 | ||
1535 | void ORPSMtoR(int to, int from) { | |
1536 | write16(0x560f); | |
1537 | ModRM(0, to, DISP32); | |
1538 | write32(from); | |
1539 | } | |
1540 | ||
1541 | void ORPSRtoR(int to, int from) { | |
1542 | write16(0x560f); | |
1543 | ModRM(3, to,from); | |
1544 | } | |
1545 | ||
1546 | void XORPSMtoR(int to, int from) { | |
1547 | write16(0x570f); | |
1548 | ModRM(0, to, DISP32); | |
1549 | write32(from); | |
1550 | } | |
1551 | ||
1552 | void XORPSRtoR(int to, int from) { | |
1553 | write16(0x570f); | |
1554 | ModRM(3, to,from); | |
1555 | } | |
1556 | ||
1557 | void ANDPSMtoR(int to, int from) { | |
1558 | write16(0x540f); | |
1559 | ModRM(0, to, DISP32); | |
1560 | write32(from); | |
1561 | } | |
1562 | ||
1563 | void ANDPSRtoR(int to, int from) { | |
1564 | write16(0x540f); | |
1565 | ModRM(3, to,from); | |
1566 | } | |
1567 | ||
1568 | /* | |
1569 | 3DNOW intructions | |
1570 | */ | |
1571 | ||
1572 | void PFCMPEQMtoR(int to, int from) { | |
1573 | write16(0x0f0f); | |
1574 | ModRM(0, to, DISP32); | |
1575 | write32(from); | |
1576 | write8(0xb0); | |
1577 | } | |
1578 | ||
1579 | void PFCMPGTMtoR(int to, int from) { | |
1580 | write16(0x0f0f); | |
1581 | ModRM(0, to, DISP32); | |
1582 | write32(from); | |
1583 | write8(0xa0); | |
1584 | } | |
1585 | ||
1586 | void PFCMPGEMtoR(int to, int from) { | |
1587 | write16(0x0f0f); | |
1588 | ModRM(0, to, DISP32); | |
1589 | write32(from); | |
1590 | write8(0x90); | |
1591 | } | |
1592 | ||
1593 | void PFADDMtoR(int to, int from) { | |
1594 | write16(0x0f0f); | |
1595 | ModRM(0, to, DISP32); | |
1596 | write32(from); | |
1597 | write8(0x9e); | |
1598 | } | |
1599 | ||
1600 | void PFADDRtoR(int to, int from) { | |
1601 | write16(0x0f0f); | |
1602 | ModRM(3, to, from); | |
1603 | write8(0x9e); | |
1604 | } | |
1605 | ||
1606 | void PFSUBMtoR(int to, int from) { | |
1607 | write16(0x0f0f); | |
1608 | ModRM(0, to, DISP32); | |
1609 | write32(from); | |
1610 | write8(0x9a); | |
1611 | } | |
1612 | ||
1613 | void PFSUBRtoR(int to, int from) { | |
1614 | write16(0x0f0f); | |
1615 | ModRM(3, to, from); | |
1616 | write8(0x9a); | |
1617 | } | |
1618 | ||
1619 | void PFMULMtoR(int to, int from) { | |
1620 | write16(0x0f0f); | |
1621 | ModRM(0, to, DISP32); | |
1622 | write32(from); | |
1623 | write8(0xb4); | |
1624 | } | |
1625 | ||
1626 | void PFMULRtoR(int to, int from) { | |
1627 | write16(0x0f0f); | |
1628 | ModRM(3, to,from); | |
1629 | write8(0xb4); | |
1630 | } | |
1631 | ||
1632 | void PFRCPMtoR(int to, int from) { | |
1633 | write16(0x0f0f); | |
1634 | ModRM(0, to, DISP32); | |
1635 | write32(from); | |
1636 | write8(0x96); | |
1637 | } | |
1638 | ||
1639 | void PFRCPRtoR(int to, int from) { | |
1640 | write16(0x0f0f); | |
1641 | ModRM(3, to,from); | |
1642 | write8(0x96); | |
1643 | } | |
1644 | ||
1645 | void PFRCPIT1RtoR(int to, int from) { | |
1646 | write16(0x0f0f); | |
1647 | ModRM(3, to,from); | |
1648 | write8(0xa6); | |
1649 | } | |
1650 | ||
1651 | void PFRCPIT2RtoR(int to, int from) { | |
1652 | write16(0x0f0f); | |
1653 | ModRM(3, to,from); | |
1654 | write8(0xb6); | |
1655 | } | |
1656 | ||
1657 | void PFRSQRTRtoR(int to, int from) { | |
1658 | write16(0x0f0f); | |
1659 | ModRM(3, to,from); | |
1660 | write8(0x97); | |
1661 | } | |
1662 | ||
1663 | void PFRSQIT1RtoR(int to, int from) { | |
1664 | write16(0x0f0f); | |
1665 | ModRM(3, to,from); | |
1666 | write8(0xa7); | |
1667 | } | |
1668 | ||
1669 | void PF2IDMtoR(int to, int from) { | |
1670 | write16(0x0f0f); | |
1671 | ModRM(0, to, DISP32); | |
1672 | write32(from); | |
1673 | write8(0x1d); | |
1674 | } | |
1675 | ||
1676 | void PF2IDRtoR(int to, int from) { | |
1677 | write16(0x0f0f); | |
1678 | ModRM(3, to, from); | |
1679 | write8(0x1d); | |
1680 | } | |
1681 | ||
1682 | void PI2FDMtoR(int to, int from) { | |
1683 | write16(0x0f0f); | |
1684 | ModRM(0, to, DISP32); | |
1685 | write32(from); | |
1686 | write8(0x0d); | |
1687 | } | |
1688 | ||
1689 | void PI2FDRtoR(int to, int from) { | |
1690 | write16(0x0f0f); | |
1691 | ModRM(3, to, from); | |
1692 | write8(0x0d); | |
1693 | } | |
1694 | ||
1695 | /* | |
1696 | 3DNOW Extension intructions | |
1697 | */ | |
1698 | ||
1699 | void PFMAXMtoR(int to, int from) { | |
1700 | write16(0x0f0f); | |
1701 | ModRM(0, to, DISP32); | |
1702 | write32(from); | |
1703 | write8(0xa4); | |
1704 | } | |
1705 | ||
1706 | void PFMAXRtoR(int to, int from) { | |
1707 | write16(0x0f0f); | |
1708 | ModRM(3, to, from); | |
1709 | write8(0xa4); | |
1710 | } | |
1711 | ||
1712 | void PFMINMtoR(int to, int from) { | |
1713 | write16(0x0f0f); | |
1714 | ModRM(0, to, DISP32); | |
1715 | write32(from); | |
1716 | write8(0x94); | |
1717 | } | |
1718 | ||
1719 | void PFMINRtoR(int to, int from) { | |
1720 | write16(0x0f0f); | |
1721 | ModRM(3, to, from); | |
1722 | write8(0x94); | |
1723 | } |