improve ARM feature detection
[pcsx_rearmed.git] / libpcsxcore / ix86 / ix86.c
CommitLineData
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
28s8 *x86Ptr;
29u8 *j8Ptr[32];
30u32 *j32Ptr[32];
31
32void x86Init() {
33}
34
35void x86SetPtr(char *ptr) {
36 x86Ptr = ptr;
37}
38
39void x86Shutdown() {
40}
41
42void 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
49void x86SetJ32(u32 *j32) {
50 *j32 = (x86Ptr - (s8*)j32) - 4;
51}
52
53void 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 */
95void MOV32RtoR(int to, int from) {
96 write8(0x89);
97 ModRM(3, from, to);
98}
99
100/* mov r32 to m32 */
101void MOV32RtoM(u32 to, int from) {
102 write8(0x89);
103 ModRM(0, from, DISP32);
104 write32(to);
105}
106
107/* mov m32 to r32 */
108void MOV32MtoR(int to, u32 from) {
109 write8(0x8B);
110 ModRM(0, to, DISP32);
111 write32(from);
112}
113
114/* mov [r32] to r32 */
115void MOV32RmtoR(int to, int from) {
116 write8(0x8B);
117 ModRM(0, to, from);
118}
119
120/* mov [r32][r32*scale] to r32 */
121void 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] */
128void MOV32RtoRm(int to, int from) {
129 write8(0x89);
130 ModRM(0, from, to);
131}
132
133/* mov r32 to [r32][r32*scale] */
134void 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 */
141void MOV32ItoR(int to, u32 from) {
142 write8(0xB8 | to);
143 write32(from);
144}
145
146/* mov imm32 to m32 */
147void 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 */
155void 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 */
163void 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 */
171void 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 */
180void MOV8RtoM(u32 to, int from) {
181 write8(0x88);
182 ModRM(0, from, DISP32);
183 write32(to);
184}
185
186/* mov m8 to r8 */
187void MOV8MtoR(int to, u32 from) {
188 write8(0x8A);
189 ModRM(0, to, DISP32);
190 write32(from);
191}
192
193/* mov imm8 to m8 */
194void 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 */
202void MOVSX32R8toR(int to, int from) {
203 write16(0xBE0F);
204 ModRM(3, to, from);
205}
206
207/* movsx m8 to r32 */
208void MOVSX32M8toR(int to, u32 from) {
209 write16(0xBE0F);
210 ModRM(0, to, DISP32);
211 write32(from);
212}
213
214/* movsx r16 to r32 */
215void MOVSX32R16toR(int to, int from) {
216 write16(0xBF0F);
217 ModRM(3, to, from);
218}
219
220/* movsx m16 to r32 */
221void MOVSX32M16toR(int to, u32 from) {
222 write16(0xBF0F);
223 ModRM(0, to, DISP32);
224 write32(from);
225}
226
227/* movzx r8 to r32 */
228void MOVZX32R8toR(int to, int from) {
229 write16(0xB60F);
230 ModRM(3, to, from);
231}
232
233/* movzx m8 to r32 */
234void MOVZX32M8toR(int to, u32 from) {
235 write16(0xB60F);
236 ModRM(0, to, DISP32);
237 write32(from);
238}
239
240/* movzx r16 to r32 */
241void MOVZX32R16toR(int to, int from) {
242 write16(0xB70F);
243 ModRM(3, to, from);
244}
245
246/* movzx m16 to r32 */
247void MOVZX32M16toR(int to, u32 from) {
248 write16(0xB70F);
249 ModRM(0, to, DISP32);
250 write32(from);
251}
252
253/* cmovne r32 to r32 */
254void CMOVNE32RtoR(int to, int from) {
255 CMOV32RtoR(0x45, to, from);
256}
257
258/* cmovne m32 to r32*/
259void CMOVNE32MtoR(int to, u32 from) {
260 CMOV32MtoR(0x45, to, from);
261}
262
263/* cmove r32 to r32*/
264void CMOVE32RtoR(int to, int from) {
265 CMOV32RtoR(0x44, to, from);
266}
267
268/* cmove m32 to r32*/
269void CMOVE32MtoR(int to, u32 from) {
270 CMOV32MtoR(0x44, to, from);
271}
272
273/* cmovg r32 to r32*/
274void CMOVG32RtoR(int to, int from) {
275 CMOV32RtoR(0x4F, to, from);
276}
277
278/* cmovg m32 to r32*/
279void CMOVG32MtoR(int to, u32 from) {
280 CMOV32MtoR(0x4F, to, from);
281}
282
283/* cmovge r32 to r32*/
284void CMOVGE32RtoR(int to, int from) {
285 CMOV32RtoR(0x4D, to, from);
286}
287
288/* cmovge m32 to r32*/
289void CMOVGE32MtoR(int to, u32 from) {
290 CMOV32MtoR(0x4D, to, from);
291}
292
293/* cmovl r32 to r32*/
294void CMOVL32RtoR(int to, int from) {
295 CMOV32RtoR(0x4C, to, from);
296}
297
298/* cmovl m32 to r32*/
299void CMOVL32MtoR(int to, u32 from) {
300 CMOV32MtoR(0x4C, to, from);
301}
302
303/* cmovle r32 to r32*/
304void CMOVLE32RtoR(int to, int from) {
305 CMOV32RtoR(0x4E, to, from);
306}
307
308/* cmovle m32 to r32*/
309void CMOVLE32MtoR(int to, u32 from) {
310 CMOV32MtoR(0x4E, to, from);
311}
312
313// arithmic instructions
314
315/* add imm32 to r32 */
316void 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 */
327void 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 */
335void ADD32RtoR(int to, int from) {
336 write8(0x01);
337 ModRM(3, from, to);
338}
339
340/* add r32 to m32 */
341void ADD32RtoM(u32 to, int from) {
342 write8(0x01);
343 ModRM(0, from, DISP32);
344 write32(to);
345}
346
347/* add m32 to r32 */
348void ADD32MtoR(int to, u32 from) {
349 write8(0x03);
350 ModRM(0, to, DISP32);
351 write32(from);
352}
353
354/* adc imm32 to r32 */
355void 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 */
366void ADC32RtoR(int to, int from) {
367 write8(0x11);
368 ModRM(3, from, to);
369}
370
371/* adc m32 to r32 */
372void ADC32MtoR(int to, u32 from) {
373 write8(0x13);
374 ModRM(0, to, DISP32);
375 write32(from);
376}
377
378/* inc r32 */
379void INC32R(int to) {
380 write8(0x40 + to);
381}
382
383/* inc m32 */
384void INC32M(u32 to) {
385 write8(0xFF);
386 ModRM(0, 0, DISP32);
387 write32(to);
388}
389
390/* sub imm32 to r32 */
391void 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 */
402void SUB32RtoR(int to, int from) {
403 write8(0x29);
404 ModRM(3, from, to);
405}
406
407/* sub m32 to r32 */
408void SUB32MtoR(int to, u32 from) {
409 write8(0x2B);
410 ModRM(0, to, DISP32);
411 write32(from);
412}
413
414/* sbb imm32 to r32 */
415void 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 */
426void SBB32RtoR(int to, int from) {
427 write8(0x19);
428 ModRM(3, from, to);
429}
430
431/* sbb m32 to r32 */
432void SBB32MtoR(int to, u32 from) {
433 write8(0x1B);
434 ModRM(0, to, DISP32);
435 write32(from);
436}
437
438/* dec r32 */
439void DEC32R(int to) {
440 write8(0x48 + to);
441}
442
443/* dec m32 */
444void DEC32M(u32 to) {
445 write8(0xFF);
446 ModRM(0, 1, DISP32);
447 write32(to);
448}
449
450/* mul eax by r32 to edx:eax */
451void MUL32R(int from) {
452 write8(0xF7);
453 ModRM(3, 4, from);
454}
455
456/* imul eax by r32 to edx:eax */
457void IMUL32R(int from) {
458 write8(0xF7);
459 ModRM(3, 5, from);
460}
461
462/* mul eax by m32 to edx:eax */
463void MUL32M(u32 from) {
464 write8(0xF7);
465 ModRM(0, 4, DISP32);
466 write32(from);
467}
468
469/* imul eax by m32 to edx:eax */
470void IMUL32M(u32 from) {
471 write8(0xF7);
472 ModRM(0, 5, DISP32);
473 write32(from);
474}
475
476/* imul r32 by r32 to r32 */
477void IMUL32RtoR(int to, int from) {
478 write16(0xAF0F);
479 ModRM(3, to, from);
480}
481
482/* div eax by r32 to edx:eax */
483void DIV32R(int from) {
484 write8(0xF7);
485 ModRM(3, 6, from);
486}
487
488/* idiv eax by r32 to edx:eax */
489void IDIV32R(int from) {
490 write8(0xF7);
491 ModRM(3, 7, from);
492}
493
494/* div eax by m32 to edx:eax */
495void DIV32M(u32 from) {
496 write8(0xF7);
497 ModRM(0, 6, DISP32);
498 write32(from);
499}
500
501/* idiv eax by m32 to edx:eax */
502void IDIV32M(u32 from) {
503 write8(0xF7);
504 ModRM(0, 7, DISP32);
505 write32(from);
506}
507
508// shifting instructions
509
510void 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 */
526void 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 */
539void SHL32CLtoR(int to) {
540 write8(0xD3);
541 ModRM(3, 4, to);
542}
543
544/* shr imm8 to r32 */
545void 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 */
558void SHR32CLtoR(int to) {
559 write8(0xD3);
560 ModRM(3, 5, to);
561}
562
563/* sar imm8 to r32 */
564void SAR32ItoR(int to, u8 from) {
565 write8(0xC1);
566 ModRM(3, 7, to);
567 write8(from);
568}
569
570/* sar cl to r32 */
571void SAR32CLtoR(int to) {
572 write8(0xD3);
573 ModRM(3, 7, to);
574}
575
576
577// logical instructions
578
579/* or imm32 to r32 */
580void 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 */
591void 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 */
599void OR32RtoR(int to, int from) {
600 write8(0x09);
601 ModRM(3, from, to);
602}
603
604/* or r32 to m32 */
605void OR32RtoM(u32 to, int from) {
606 write8(0x09);
607 ModRM(0, from, DISP32);
608 write32(to);
609}
610
611/* or m32 to r32 */
612void OR32MtoR(int to, u32 from) {
613 write8(0x0B);
614 ModRM(0, to, DISP32);
615 write32(from);
616}
617
618/* xor imm32 to r32 */
619void 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 */
630void 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 */
638void XOR32RtoR(int to, int from) {
639 write8(0x31);
640 ModRM(3, from, to);
641}
642
643/* xor r32 to m32 */
644void XOR32RtoM(u32 to, int from) {
645 write8(0x31);
646 ModRM(0, from, DISP32);
647 write32(to);
648}
649
650/* xor m32 to r32 */
651void XOR32MtoR(int to, u32 from) {
652 write8(0x33);
653 ModRM(0, to, DISP32);
654 write32(from);
655}
656
657/* and imm32 to r32 */
658void 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 */
669void 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 */
677void AND32RtoR(int to, int from) {
678 write8(0x21);
679 ModRM(3, from, to);
680}
681
682/* and r32 to m32 */
683void AND32RtoM(u32 to, int from) {
684 write8(0x21);
685 ModRM(0, from, DISP32);
686 write32(to);
687}
688
689/* and m32 to r32 */
690void AND32MtoR(int to, u32 from) {
691 write8(0x23);
692 ModRM(0, to, DISP32);
693 write32(from);
694}
695
696/* not r32 */
697void NOT32R(int from) {
698 write8(0xF7);
699 ModRM(3, 2, from);
700}
701
702/* neg r32 */
703void NEG32R(int from) {
704 write8(0xF7);
705 ModRM(3, 3, from);
706}
707
708// jump instructions
709
710/* jmp rel8 */
711u8* JMP8(u8 to) {
712 write8(0xEB);
713 write8(to);
714 return x86Ptr - 1;
715}
716
717/* jmp rel32 */
718u32* JMP32(u32 to) {
719 write8(0xE9);
720 write32(to);
721 return (u32*)(x86Ptr - 4);
722}
723
724/* jmp r32 */
725void JMP32R(int to) {
726 write8(0xFF);
727 ModRM(3, 4, to);
728}
729
730/* je rel8 */
731u8* JE8(u8 to) {
732 J8Rel(0x74, to);
733}
734
735/* jz rel8 */
736u8* JZ8(u8 to) {
737 J8Rel(0x74, to);
738}
739
740/* jg rel8 */
741u8* JG8(u8 to) {
742 J8Rel(0x7F, to);
743}
744
745/* jge rel8 */
746u8* JGE8(u8 to) {
747 J8Rel(0x7D, to);
748}
749
750/* jl rel8 */
751u8* JL8(u8 to) {
752 J8Rel(0x7C, to);
753}
754
755/* jle rel8 */
756u8* JLE8(u8 to) {
757 J8Rel(0x7E, to);
758}
759
760/* jne rel8 */
761u8* JNE8(u8 to) {
762 J8Rel(0x75, to);
763}
764
765/* jnz rel8 */
766u8* JNZ8(u8 to) {
767 J8Rel(0x75, to);
768}
769
770/* jng rel8 */
771u8* JNG8(u8 to) {
772 J8Rel(0x7E, to);
773}
774
775/* jnge rel8 */
776u8* JNGE8(u8 to) {
777 J8Rel(0x7C, to);
778}
779
780/* jnl rel8 */
781u8* JNL8(u8 to) {
782 J8Rel(0x7D, to);
783}
784
785/* jnle rel8 */
786u8* JNLE8(u8 to) {
787 J8Rel(0x7F, to);
788}
789
790/* jo rel8 */
791u8* JO8(u8 to) {
792 J8Rel(0x70, to);
793}
794
795/* jno rel8 */
796u8* JNO8(u8 to) {
797 J8Rel(0x71, to);
798}
799
800/* je rel32 */
801u32* JE32(u32 to) {
802 J32Rel(0x84, to);
803}
804
805/* jz rel32 */
806u32* JZ32(u32 to) {
807 J32Rel(0x84, to);
808}
809
810/* jg rel32 */
811u32* JG32(u32 to) {
812 J32Rel(0x8F, to);
813}
814
815/* jge rel32 */
816u32* JGE32(u32 to) {
817 J32Rel(0x8D, to);
818}
819
820/* jl rel32 */
821u32* JL32(u32 to) {
822 J32Rel(0x8C, to);
823}
824
825/* jle rel32 */
826u32* JLE32(u32 to) {
827 J32Rel(0x8E, to);
828}
829
830/* jne rel32 */
831u32* JNE32(u32 to) {
832 J32Rel(0x85, to);
833}
834
835/* jnz rel32 */
836u32* JNZ32(u32 to) {
837 J32Rel(0x85, to);
838}
839
840/* jng rel32 */
841u32* JNG32(u32 to) {
842 J32Rel(0x8E, to);
843}
844
845/* jnge rel32 */
846u32* JNGE32(u32 to) {
847 J32Rel(0x8C, to);
848}
849
850/* jnl rel32 */
851u32* JNL32(u32 to) {
852 J32Rel(0x8D, to);
853}
854
855/* jnle rel32 */
856u32* JNLE32(u32 to) {
857 J32Rel(0x8F, to);
858}
859
860/* jo rel32 */
861u32* JO32(u32 to) {
862 J32Rel(0x80, to);
863}
864
865/* jno rel32 */
866u32* JNO32(u32 to) {
867 J32Rel(0x81, to);
868}
869
870/* call func */
871void CALLFunc(u32 func) {
872 CALL32(func - ((u32)x86Ptr + 5));
873}
874
875/* call rel32 */
876void CALL32(u32 to) {
877 write8(0xE8);
878 write32(to);
879}
880
881/* call r32 */
882void CALL32R(int to) {
883 write8(0xFF);
884 ModRM(3, 2, to);
885}
886
887/* call m32 */
888void 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 */
897void 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 */
908void 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 */
916void CMP32RtoR(int to, int from) {
917 write8(0x39);
918 ModRM(3, from, to);
919}
920
921/* cmp m32 to r32 */
922void CMP32MtoR(int to, u32 from) {
923 write8(0x3B);
924 ModRM(0, to, DISP32);
925 write32(from);
926}
927
928/* test imm32 to r32 */
929void 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 */
940void TEST32RtoR(int to, int from) {
941 write8(0x85);
942 ModRM(3, from, to);
943}
944
945void BT32ItoR(int to,int from)
946{
947 write16(0xba0f);
948 write8(0xe0 | to);
949 write8(from);
950}
951
952/* sets r8 */
953void SETS8R(int to) {
954 SET8R(0x98, to);
955}
956/* setl r8 */
957void SETL8R(int to) {
958 SET8R(0x9C, to);
959}
960
961/* setb r8 */
962void SETB8R(int to) {
963 SET8R(0x92, to);
964}
965
966/* setnz r8 */
967void SETNZ8R(int to) {
968 SET8R(0x95,to);
969}
970
971/* cbw */
972void CBW() {
973 write16(0x9866);
974}
975
976/* cwd */
977void CWD() {
978 write8(0x98);
979}
980
981/* cdq */
982void CDQ() {
983 write8(0x99);
984}
985
986/* push r32 */
987void PUSH32R(int from) {
988 write8(0x50 | from);
989}
990
991/* push m32 */
992void PUSH32M(u32 from) {
993 write8(0xFF);
994 ModRM(0, 6, DISP32);
995 write32(from);
996}
997
998/* push imm32 */
999void PUSH32I(u32 from) {
1000 write8(0x68); write32(from);
1001}
1002
1003/* pop r32 */
1004void POP32R(int from) {
1005 write8(0x58 | from);
1006}
1007
1008/* pushad */
1009void PUSHA32() {
1010 write8(0x60);
1011}
1012
1013/* popad */
1014void POPA32() {
1015 write8(0x61);
1016}
1017
1018/* ret */
1019void 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 */
1029void FCOMP32(u32 from) {
1030 write8(0xD8);
1031 ModRM(0, 0x3, DISP32);
1032 write32(from);
1033}
1034
1035void FNSTSWtoAX() {
1036 write16(0xE0DF);
1037}
1038
1039/* fild m32 to fpu reg stack */
1040void FILD32(u32 from) {
1041 write8(0xDB);
1042 ModRM(0, 0x0, DISP32);
1043 write32(from);
1044}
1045
1046/* fistp m32 from fpu reg stack */
1047void FISTP32(u32 from) {
1048 write8(0xDB);
1049 ModRM(0, 0x3, DISP32);
1050 write32(from);
1051}
1052
1053/* fld m32 to fpu reg stack */
1054void FLD32(u32 from) {
1055 write8(0xD9);
1056 ModRM(0, 0x0, DISP32);
1057 write32(from);
1058}
1059
1060/* fstp m32 from fpu reg stack */
1061void 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 */
1070void FLDCW(u32 from) {
1071 write8(0xD9);
1072 ModRM(0, 0x5, DISP32);
1073 write32(from);
1074}
1075
1076/* fnstcw fpu control word to m16 */
1077void 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 */
1086void FADD32(u32 from) {
1087 write8(0xD8);
1088 ModRM(0, 0x0, DISP32);
1089 write32(from);
1090}
1091
1092/* fsub m32 to fpu reg stack */
1093void FSUB32(u32 from) {
1094 write8(0xD8);
1095 ModRM(0, 0x4, DISP32);
1096 write32(from);
1097}
1098
1099/* fmul m32 to fpu reg stack */
1100void FMUL32(u32 from) {
1101 write8(0xD8);
1102 ModRM(0, 0x1, DISP32);
1103 write32(from);
1104}
1105
1106/* fdiv m32 to fpu reg stack */
1107void FDIV32(u32 from) {
1108 write8(0xD8);
1109 ModRM(0, 0x6, DISP32);
1110 write32(from);
1111}
1112
1113/* fabs fpu reg stack */
1114void FABS() {
1115 write16(0xE1D9);
1116}
1117
1118/* fsqrt fpu reg stack */
1119void FSQRT() {
1120 write16(0xFAD9);
1121}
1122
1123/* fchs fpu reg stack */
1124void FCHS() {
1125 write16(0xE0D9);
1126}
1127
1128/********************/
1129/* MMX instructions */
1130/********************/
1131
1132// r64 = mm
1133
1134/* movq m64 to r64 */
1135void MOVQMtoR(int to, u32 from) {
1136 write16(0x6F0F);
1137 ModRM(0, to, DISP32);
1138 write32(from);
1139}
1140
1141/* movq r64 to m64 */
1142void MOVQRtoM(u32 to, int from) {
1143 write16(0x7F0F);
1144 ModRM(0, from, DISP32);
1145 write32(to);
1146}
1147
1148/* pand r64 to r64 */
1149void PANDRtoR(int to, int from) {
1150 write16(0xDB0F);
1151 ModRM(3, to, from);
1152}
1153
1154/* pand r64 to r64 */
1155void PANDNRtoR(int to, int from) {
1156 write16(0xDF0F);
1157 ModRM(3, to, from);
1158}
1159
1160/* por r64 to r64 */
1161void PORRtoR(int to, int from) {
1162 write16(0xEB0F);
1163 ModRM(3, to, from);
1164}
1165
1166/* pxor r64 to r64 */
1167void PXORRtoR(int to, int from) {
1168 write16(0xEF0F);
1169 ModRM(3, to, from);
1170}
1171
1172/* psllq r64 to r64 */
1173void PSLLQRtoR(int to, int from) {
1174 write16(0xF30F);
1175 ModRM(3, to, from);
1176}
1177
1178/* psllq m64 to r64 */
1179void PSLLQMtoR(int to, u32 from) {
1180 write16(0xF30F);
1181 ModRM(0, to, DISP32);
1182 write32(from);
1183}
1184
1185/* psllq imm8 to r64 */
1186void PSLLQItoR(int to, u8 from) {
1187 write16(0x730F);
1188 ModRM(3, 6, to);
1189 write8(from);
1190}
1191
1192/* psrlq r64 to r64 */
1193void PSRLQRtoR(int to, int from) {
1194 write16(0xD30F);
1195 ModRM(3, to, from);
1196}
1197
1198/* psrlq m64 to r64 */
1199void PSRLQMtoR(int to, u32 from) {
1200 write16(0xD30F);
1201 ModRM(0, to, DISP32);
1202 write32(from);
1203}
1204
1205/* psrlq imm8 to r64 */
1206void PSRLQItoR(int to, u8 from) {
1207 write16(0x730F);
1208 ModRM(3, 2, to);
1209 write8(from);
1210}
1211
1212/* paddusb r64 to r64 */
1213void PADDUSBRtoR(int to, int from) {
1214 write16(0xDC0F);
1215 ModRM(3, to, from);
1216}
1217
1218/* paddusb m64 to r64 */
1219void PADDUSBMtoR(int to, u32 from) {
1220 write16(0xDC0F);
1221 ModRM(0, to, DISP32);
1222 write32(from);
1223}
1224
1225/* paddusw r64 to r64 */
1226void PADDUSWRtoR(int to, int from) {
1227 write16(0xDD0F);
1228 ModRM(3, to, from);
1229}
1230
1231/* paddusw m64 to r64 */
1232void PADDUSWMtoR(int to, u32 from) {
1233 write16(0xDD0F);
1234 ModRM(0, to, DISP32);
1235 write32(from);
1236}
1237
1238/* paddb r64 to r64 */
1239void PADDBRtoR(int to, int from) {
1240 write16(0xFC0F);
1241 ModRM(3, to, from);
1242}
1243
1244/* paddb m64 to r64 */
1245void PADDBMtoR(int to, u32 from) {
1246 write16(0xFC0F);
1247 ModRM(0, to, DISP32);
1248 write32(from);
1249}
1250
1251/* paddw r64 to r64 */
1252void PADDWRtoR(int to, int from) {
1253 write16(0xFD0F);
1254 ModRM(3, to, from);
1255}
1256
1257/* paddw m64 to r64 */
1258void PADDWMtoR(int to, u32 from) {
1259 write16(0xFD0F);
1260 ModRM(0, to, DISP32);
1261 write32(from);
1262}
1263
1264/* paddd r64 to r64 */
1265void PADDDRtoR(int to, int from) {
1266 write16(0xFE0F);
1267 ModRM(3, to, from);
1268}
1269
1270/* paddd m64 to r64 */
1271void PADDDMtoR(int to, u32 from) {
1272 write16(0xFE0F);
1273 ModRM(0, to, DISP32);
1274 write32(from);
1275}
1276
1277/* emms */
1278void EMMS() {
1279 //use femms if we have 3dnow
1280 write16(0x0e0f);
1281 return;
1282}
1283
1284/* femms */
1285void FEMMS() {
1286 write16(0x770F);
1287 return;
1288}
1289
1290//Basara:changed
1291void PADDSBRtoR(int to, int from) {
1292 write16(0xEC0F);
1293 ModRM(3, to, from);
1294}
1295
1296void PADDSWRtoR(int to, int from) {
1297 write16(0xED0F);
1298 ModRM(3, to, from);
1299}
1300
1301void PADDSDRtoR(int to, int from) {
1302 write16(0xEE0F);
1303 ModRM(3, to, from);
1304}
1305
1306void PSUBSBRtoR(int to, int from) {
1307 write16(0xE80F);
1308 ModRM(3, to, from);
1309}
1310
1311void PSUBSWRtoR(int to, int from) {
1312 write16(0xE90F);
1313 ModRM(3, to, from);
1314}
1315
1316void PSUBSDRtoR(int to, int from) {
1317 write16(0xEA0F);
1318 ModRM(3, to, from);
1319}
1320
1321void PSUBBRtoR(int to, int from) {
1322 write16(0xF80F);
1323 ModRM(3, to, from);
1324}
1325
1326void PSUBWRtoR(int to, int from) {
1327 write16(0xF90F);
1328 ModRM(3, to, from);
1329}
1330
1331void 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.
1338void MOVQ64ItoR(int reg,u64 i)
1339{
1340 MOVQMtoR(reg,(u32)(x86Ptr)+2+7);
1341 JMP8(8);
1342 write64(i);
1343}
1344
1345void PSUBUSBRtoR(int to, int from) {
1346 write16(0xD80F);
1347 ModRM(3, to, from);
1348}
1349
1350void PSUBUSWRtoR(int to, int from) {
1351 write16(0xD90F);
1352 ModRM(3, to, from);
1353}
1354
1355void PMAXSWRtoR(int to,int from)
1356{
1357 write16(0xEE0F);
1358 ModRM(3, to, from);
1359}
1360
1361void PMINSWRtoR(int to,int from)
1362{
1363 write16(0xEA0F);
1364 ModRM(3, to, from);
1365}
1366
1367void PCMPEQBRtoR(int to,int from)
1368{
1369 write16(0x740F);
1370 ModRM(3, to, from);
1371}
1372
1373void PCMPEQWRtoR(int to,int from)
1374{
1375 write16(0x750F);
1376 ModRM(3, to, from);
1377}
1378
1379void PCMPEQDRtoR(int to,int from)
1380{
1381 write16(0x760F);
1382 ModRM(3, to, from);
1383}
1384
1385void PCMPGTBRtoR(int to,int from)
1386{
1387 write16(0x640F);
1388 ModRM(3, to, from);
1389}
1390
1391void PCMPGTWRtoR(int to,int from)
1392{
1393 write16(0x650F);
1394 ModRM(3, to, from);
1395}
1396
1397void PCMPGTDRtoR(int to,int from)
1398{
1399 write16(0x660F);
1400 ModRM(3, to, from);
1401}
1402
1403//Basara:Added 10.01.2003
1404void PSRLWItoR(int to,int from)
1405{
1406 write16(0x710f);
1407 ModRM(2, 2 , to);
1408 write8(from);
1409}
1410void PSRLDItoR(int to,int from)
1411{
1412 write16(0x720f);
1413 ModRM(2, 2 , to);
1414 write8(from);
1415}
1416
1417void PSLLWItoR(int to,int from)
1418{
1419 write16(0x710f);
1420 ModRM(3, 6 , to);
1421 write8(from);
1422}
1423
1424void PSLLDItoR(int to,int from)
1425{
1426 write16(0x720f);
1427 ModRM(3, 6 , to);
1428 write8(from);
1429}
1430
1431void PSRAWItoR(int to,int from)
1432{
1433 write16(0x710f);
1434 ModRM(3, 4 , to);
1435 write8(from);
1436}
1437
1438void PSRADItoR(int to,int from)
1439{
1440 write16(0x720f);
1441 ModRM(3, 4 , to);
1442 write8(from);
1443}
1444
1445/* por m64 to r64 */
1446void PORMtoR(int to, u32 from) {
1447 write16(0xEB0F);
1448 ModRM(0, to, DISP32);
1449 write32(from);
1450}
1451
1452/* pxor m64 to r64 */
1453void PXORMtoR(int to, u32 from) {
1454 write16(0xEF0F);
1455 ModRM(0, to, DISP32);
1456 write32(from);
1457}
1458
1459/* pand m64 to r64 */
1460void PANDMtoR(int to, u32 from) {
1461 write16(0xDB0F);
1462 ModRM(0, to, DISP32);
1463 write32(from);
1464}
1465
1466/* pandn m64 to r64 */
1467void PANDNMtoR(int to, u32 from) {
1468 write16(0xDF0F);
1469 ModRM(0, to, DISP32);
1470 write32(from);
1471}
1472
1473/* movd m32 to r64 */
1474void MOVDMtoR(int to, u32 from) {
1475 write16(0x6E0F);
1476 ModRM(0, to, DISP32);
1477 write32(from);
1478}
1479
1480/* movq r64 to m32 */
1481void MOVDRtoM(u32 to, int from) {
1482 write16(0x7E0F);
1483 ModRM(0, from, DISP32);
1484 write32(to);
1485}
1486
1487/* movd r32 to r64 */
1488void MOVD32RtoR(int to, int from) {
1489 write16(0x6E0F);
1490 ModRM(3, to,from);
1491}
1492
1493/* movq r64 to r32 */
1494void MOVD64RtoR(int to, int from) {
1495 write16(0x7E0F);
1496 ModRM(3, from,to);
1497}
1498
1499void MOVQRtoR(int to, int from) {
1500 write16(0x6F0F);
1501 ModRM(3, to,from);
1502}
1503
1504void PUNPCKHDQRtoR(int to, int from) {
1505 write16(0x6A0F);
1506 ModRM(3, to,from);
1507}
1508
1509void PUNPCKLDQRtoR(int to, int from) {
1510 write16(0x620F);
1511 ModRM(3, to,from);
1512}
1513
1514//////////////////////////////////////////////////////////////////////////
1515// SSE intructions
1516//////////////////////////////////////////////////////////////////////////
1517
1518void MOVAPSMtoR(int to, int from) {
1519 write16(0x280f);
1520 ModRM(0, to, DISP32);
1521 write32(from);
1522}
1523
1524void MOVAPSRtoM(int to, int from) {
1525 write16(0x2b0f);
1526 ModRM(0, from, DISP32);
1527 write32(to);
1528}
1529
1530void MOVAPSRtoR(int to, int from) {
1531 write16(0x290f);
1532 ModRM(3, to,from);
1533}
1534
1535void ORPSMtoR(int to, int from) {
1536 write16(0x560f);
1537 ModRM(0, to, DISP32);
1538 write32(from);
1539}
1540
1541void ORPSRtoR(int to, int from) {
1542 write16(0x560f);
1543 ModRM(3, to,from);
1544}
1545
1546void XORPSMtoR(int to, int from) {
1547 write16(0x570f);
1548 ModRM(0, to, DISP32);
1549 write32(from);
1550}
1551
1552void XORPSRtoR(int to, int from) {
1553 write16(0x570f);
1554 ModRM(3, to,from);
1555}
1556
1557void ANDPSMtoR(int to, int from) {
1558 write16(0x540f);
1559 ModRM(0, to, DISP32);
1560 write32(from);
1561}
1562
1563void ANDPSRtoR(int to, int from) {
1564 write16(0x540f);
1565 ModRM(3, to,from);
1566}
1567
1568/*
1569 3DNOW intructions
1570*/
1571
1572void PFCMPEQMtoR(int to, int from) {
1573 write16(0x0f0f);
1574 ModRM(0, to, DISP32);
1575 write32(from);
1576 write8(0xb0);
1577}
1578
1579void PFCMPGTMtoR(int to, int from) {
1580 write16(0x0f0f);
1581 ModRM(0, to, DISP32);
1582 write32(from);
1583 write8(0xa0);
1584}
1585
1586void PFCMPGEMtoR(int to, int from) {
1587 write16(0x0f0f);
1588 ModRM(0, to, DISP32);
1589 write32(from);
1590 write8(0x90);
1591}
1592
1593void PFADDMtoR(int to, int from) {
1594 write16(0x0f0f);
1595 ModRM(0, to, DISP32);
1596 write32(from);
1597 write8(0x9e);
1598}
1599
1600void PFADDRtoR(int to, int from) {
1601 write16(0x0f0f);
1602 ModRM(3, to, from);
1603 write8(0x9e);
1604}
1605
1606void PFSUBMtoR(int to, int from) {
1607 write16(0x0f0f);
1608 ModRM(0, to, DISP32);
1609 write32(from);
1610 write8(0x9a);
1611}
1612
1613void PFSUBRtoR(int to, int from) {
1614 write16(0x0f0f);
1615 ModRM(3, to, from);
1616 write8(0x9a);
1617}
1618
1619void PFMULMtoR(int to, int from) {
1620 write16(0x0f0f);
1621 ModRM(0, to, DISP32);
1622 write32(from);
1623 write8(0xb4);
1624}
1625
1626void PFMULRtoR(int to, int from) {
1627 write16(0x0f0f);
1628 ModRM(3, to,from);
1629 write8(0xb4);
1630}
1631
1632void PFRCPMtoR(int to, int from) {
1633 write16(0x0f0f);
1634 ModRM(0, to, DISP32);
1635 write32(from);
1636 write8(0x96);
1637}
1638
1639void PFRCPRtoR(int to, int from) {
1640 write16(0x0f0f);
1641 ModRM(3, to,from);
1642 write8(0x96);
1643}
1644
1645void PFRCPIT1RtoR(int to, int from) {
1646 write16(0x0f0f);
1647 ModRM(3, to,from);
1648 write8(0xa6);
1649}
1650
1651void PFRCPIT2RtoR(int to, int from) {
1652 write16(0x0f0f);
1653 ModRM(3, to,from);
1654 write8(0xb6);
1655}
1656
1657void PFRSQRTRtoR(int to, int from) {
1658 write16(0x0f0f);
1659 ModRM(3, to,from);
1660 write8(0x97);
1661}
1662
1663void PFRSQIT1RtoR(int to, int from) {
1664 write16(0x0f0f);
1665 ModRM(3, to,from);
1666 write8(0xa7);
1667}
1668
1669void PF2IDMtoR(int to, int from) {
1670 write16(0x0f0f);
1671 ModRM(0, to, DISP32);
1672 write32(from);
1673 write8(0x1d);
1674}
1675
1676void PF2IDRtoR(int to, int from) {
1677 write16(0x0f0f);
1678 ModRM(3, to, from);
1679 write8(0x1d);
1680}
1681
1682void PI2FDMtoR(int to, int from) {
1683 write16(0x0f0f);
1684 ModRM(0, to, DISP32);
1685 write32(from);
1686 write8(0x0d);
1687}
1688
1689void 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
1699void PFMAXMtoR(int to, int from) {
1700 write16(0x0f0f);
1701 ModRM(0, to, DISP32);
1702 write32(from);
1703 write8(0xa4);
1704}
1705
1706void PFMAXRtoR(int to, int from) {
1707 write16(0x0f0f);
1708 ModRM(3, to, from);
1709 write8(0xa4);
1710}
1711
1712void PFMINMtoR(int to, int from) {
1713 write16(0x0f0f);
1714 ModRM(0, to, DISP32);
1715 write32(from);
1716 write8(0x94);
1717}
1718
1719void PFMINRtoR(int to, int from) {
1720 write16(0x0f0f);
1721 ModRM(3, to, from);
1722 write8(0x94);
1723}