pcsxr-1.9.92
[pcsx_rearmed.git] / libpcsxcore / ix86 / ix86.c
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 }