Core commit. Compile and run on the OpenPandora
[mupen64plus-pandora.git] / source / mupen64plus-core / src / r4300 / x86 / assemble.h
CommitLineData
451ab91e 1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Mupen64plus - assemble.h *
3 * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
4 * Copyright (C) 2002 Hacktarux *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the *
18 * Free Software Foundation, Inc., *
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
20 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
21
22#ifndef ASSEMBLE_H
23#define ASSEMBLE_H
24
25#include "r4300/recomph.h"
26#include "api/callbacks.h"
27#include "osal/preproc.h"
28
29#include <stdlib.h>
30
31extern long long int reg[32];
32
33#define EAX 0
34#define ECX 1
35#define EDX 2
36#define EBX 3
37#define ESP 4
38#define EBP 5
39#define ESI 6
40#define EDI 7
41
42#define AX 0
43#define CX 1
44#define DX 2
45#define BX 3
46#define SP 4
47#define BP 5
48#define SI 6
49#define DI 7
50
51#define AL 0
52#define CL 1
53#define DL 2
54#define BL 3
55#define AH 4
56#define CH 5
57#define DH 6
58#define BH 7
59
60extern int branch_taken;
61
62void jump_start_rel8(void);
63void jump_end_rel8(void);
64void jump_start_rel32(void);
65void jump_end_rel32(void);
66void add_jump(unsigned int pc_addr, unsigned int mi_addr);
67
68static osal_inline void put8(unsigned char octet)
69{
70 (*inst_pointer)[code_length] = octet;
71 code_length++;
72 if (code_length == max_code_length)
73 {
74 *inst_pointer = (unsigned char *) realloc_exec(*inst_pointer, max_code_length, max_code_length+8192);
75 max_code_length += 8192;
76 }
77}
78
79static osal_inline void put32(unsigned int dword)
80{
81 if ((code_length+4) >= max_code_length)
82 {
83 *inst_pointer = (unsigned char *) realloc_exec(*inst_pointer, max_code_length, max_code_length+8192);
84 max_code_length += 8192;
85 }
86 *((unsigned int *)(&(*inst_pointer)[code_length])) = dword;
87 code_length+=4;
88}
89
90static osal_inline void mov_eax_memoffs32(unsigned int *memoffs32)
91{
92 put8(0xA1);
93 put32((unsigned int)(memoffs32));
94}
95
96static osal_inline void mov_memoffs32_eax(unsigned int *memoffs32)
97{
98 put8(0xA3);
99 put32((unsigned int)(memoffs32));
100}
101
102static osal_inline void mov_m8_reg8(unsigned char *m8, int reg8)
103{
104 put8(0x88);
105 put8((reg8 << 3) | 5);
106 put32((unsigned int)(m8));
107}
108
109static osal_inline void mov_reg16_m16(int reg16, unsigned short *m16)
110{
111 put8(0x66);
112 put8(0x8B);
113 put8((reg16 << 3) | 5);
114 put32((unsigned int)(m16));
115}
116
117static osal_inline void mov_m16_reg16(unsigned short *m16, int reg16)
118{
119 put8(0x66);
120 put8(0x89);
121 put8((reg16 << 3) | 5);
122 put32((unsigned int)(m16));
123}
124
125static osal_inline void cmp_reg32_m32(int reg32, unsigned int *m32)
126{
127 put8(0x3B);
128 put8((reg32 << 3) | 5);
129 put32((unsigned int)(m32));
130}
131
132static osal_inline void cmp_reg32_reg32(int reg1, int reg2)
133{
134 put8(0x39);
135 put8((reg2 << 3) | reg1 | 0xC0);
136}
137
138static osal_inline void cmp_reg32_imm8(int reg32, unsigned char imm8)
139{
140 put8(0x83);
141 put8(0xF8 + reg32);
142 put8(imm8);
143}
144
145static osal_inline void cmp_preg32pimm32_imm8(int reg32, unsigned int imm32, unsigned char imm8)
146{
147 put8(0x80);
148 put8(0xB8 + reg32);
149 put32(imm32);
150 put8(imm8);
151}
152
153static osal_inline void cmp_reg32_imm32(int reg32, unsigned int imm32)
154{
155 put8(0x81);
156 put8(0xF8 + reg32);
157 put32(imm32);
158}
159
160static osal_inline void test_reg32_imm32(int reg32, unsigned int imm32)
161{
162 put8(0xF7);
163 put8(0xC0 + reg32);
164 put32(imm32);
165}
166
167static osal_inline void test_m32_imm32(unsigned int *m32, unsigned int imm32)
168{
169 put8(0xF7);
170 put8(0x05);
171 put32((unsigned int)m32);
172 put32(imm32);
173}
174
175static osal_inline void add_m32_reg32(unsigned int *m32, int reg32)
176{
177 put8(0x01);
178 put8((reg32 << 3) | 5);
179 put32((unsigned int)(m32));
180}
181
182static osal_inline void sub_reg32_m32(int reg32, unsigned int *m32)
183{
184 put8(0x2B);
185 put8((reg32 << 3) | 5);
186 put32((unsigned int)(m32));
187}
188
189static osal_inline void sub_reg32_reg32(int reg1, int reg2)
190{
191 put8(0x29);
192 put8((reg2 << 3) | reg1 | 0xC0);
193}
194
195static osal_inline void sbb_reg32_reg32(int reg1, int reg2)
196{
197 put8(0x19);
198 put8((reg2 << 3) | reg1 | 0xC0);
199}
200
201static osal_inline void sub_reg32_imm32(int reg32, unsigned int imm32)
202{
203 put8(0x81);
204 put8(0xE8 + reg32);
205 put32(imm32);
206}
207
208static osal_inline void sub_eax_imm32(unsigned int imm32)
209{
210 put8(0x2D);
211 put32(imm32);
212}
213
214static osal_inline void jne_rj(unsigned char saut)
215{
216 put8(0x75);
217 put8(saut);
218}
219
220static osal_inline void je_rj(unsigned char saut)
221{
222 put8(0x74);
223 put8(saut);
224}
225
226static osal_inline void jb_rj(unsigned char saut)
227{
228 put8(0x72);
229 put8(saut);
230}
231
232static osal_inline void jbe_rj(unsigned char saut)
233{
234 put8(0x76);
235 put8(saut);
236}
237
238static osal_inline void ja_rj(unsigned char saut)
239{
240 put8(0x77);
241 put8(saut);
242}
243
244static osal_inline void jae_rj(unsigned char saut)
245{
246 put8(0x73);
247 put8(saut);
248}
249
250static osal_inline void jle_rj(unsigned char saut)
251{
252 put8(0x7E);
253 put8(saut);
254}
255
256static osal_inline void jge_rj(unsigned char saut)
257{
258 put8(0x7D);
259 put8(saut);
260}
261
262static osal_inline void jg_rj(unsigned char saut)
263{
264 put8(0x7F);
265 put8(saut);
266}
267
268static osal_inline void jl_rj(unsigned char saut)
269{
270 put8(0x7C);
271 put8(saut);
272}
273
274static osal_inline void jp_rj(unsigned char saut)
275{
276 put8(0x7A);
277 put8(saut);
278}
279
280static osal_inline void je_near_rj(unsigned int saut)
281{
282 put8(0x0F);
283 put8(0x84);
284 put32(saut);
285}
286
287static osal_inline void mov_reg32_imm32(int reg32, unsigned int imm32)
288{
289 put8(0xB8+reg32);
290 put32(imm32);
291}
292
293static osal_inline void jmp_imm_short(char saut)
294{
295 put8(0xEB);
296 put8(saut);
297}
298
299static osal_inline void or_m32_imm32(unsigned int *m32, unsigned int imm32)
300{
301 put8(0x81);
302 put8(0x0D);
303 put32((unsigned int)(m32));
304 put32(imm32);
305}
306
307static osal_inline void or_reg32_reg32(unsigned int reg1, unsigned int reg2)
308{
309 put8(0x09);
310 put8(0xC0 | (reg2 << 3) | reg1);
311}
312
313static osal_inline void and_reg32_reg32(unsigned int reg1, unsigned int reg2)
314{
315 put8(0x21);
316 put8(0xC0 | (reg2 << 3) | reg1);
317}
318
319static osal_inline void and_m32_imm32(unsigned int *m32, unsigned int imm32)
320{
321 put8(0x81);
322 put8(0x25);
323 put32((unsigned int)(m32));
324 put32(imm32);
325}
326
327static osal_inline void xor_reg32_reg32(unsigned int reg1, unsigned int reg2)
328{
329 put8(0x31);
330 put8(0xC0 | (reg2 << 3) | reg1);
331}
332
333static osal_inline void sub_m32_imm32(unsigned int *m32, unsigned int imm32)
334{
335 put8(0x81);
336 put8(0x2D);
337 put32((unsigned int)(m32));
338 put32(imm32);
339}
340
341static osal_inline void add_reg32_imm32(unsigned int reg32, unsigned int imm32)
342{
343 put8(0x81);
344 put8(0xC0+reg32);
345 put32(imm32);
346}
347
348static osal_inline void inc_m32(unsigned int *m32)
349{
350 put8(0xFF);
351 put8(0x05);
352 put32((unsigned int)(m32));
353}
354
355static osal_inline void cmp_m32_imm32(unsigned int *m32, unsigned int imm32)
356{
357 put8(0x81);
358 put8(0x3D);
359 put32((unsigned int)(m32));
360 put32(imm32);
361}
362
363static osal_inline void cmp_eax_imm32(unsigned int imm32)
364{
365 put8(0x3D);
366 put32(imm32);
367}
368
369static osal_inline void mov_m32_imm32(unsigned int *m32, unsigned int imm32)
370{
371 put8(0xC7);
372 put8(0x05);
373 put32((unsigned int)(m32));
374 put32(imm32);
375}
376
377static osal_inline void jmp(unsigned int mi_addr)
378{
379 put8(0xE9);
380 put32(0);
381 add_jump(code_length-4, mi_addr);
382}
383
384static osal_inline void cdq(void)
385{
386 put8(0x99);
387}
388
389static osal_inline void mov_m32_reg32(unsigned int *m32, unsigned int reg32)
390{
391 put8(0x89);
392 put8((reg32 << 3) | 5);
393 put32((unsigned int)(m32));
394}
395
396static osal_inline void call_reg32(unsigned int reg32)
397{
398 put8(0xFF);
399 put8(0xD0+reg32);
400}
401
402static osal_inline void shr_reg32_imm8(unsigned int reg32, unsigned char imm8)
403{
404 put8(0xC1);
405 put8(0xE8+reg32);
406 put8(imm8);
407}
408
409static osal_inline void shr_reg32_cl(unsigned int reg32)
410{
411 put8(0xD3);
412 put8(0xE8+reg32);
413}
414
415static osal_inline void sar_reg32_cl(unsigned int reg32)
416{
417 put8(0xD3);
418 put8(0xF8+reg32);
419}
420
421static osal_inline void shl_reg32_cl(unsigned int reg32)
422{
423 put8(0xD3);
424 put8(0xE0+reg32);
425}
426
427static osal_inline void shld_reg32_reg32_cl(unsigned int reg1, unsigned int reg2)
428{
429 put8(0x0F);
430 put8(0xA5);
431 put8(0xC0 | (reg2 << 3) | reg1);
432}
433
434static osal_inline void shld_reg32_reg32_imm8(unsigned int reg1, unsigned int reg2, unsigned char imm8)
435{
436 put8(0x0F);
437 put8(0xA4);
438 put8(0xC0 | (reg2 << 3) | reg1);
439 put8(imm8);
440}
441
442static osal_inline void shrd_reg32_reg32_cl(unsigned int reg1, unsigned int reg2)
443{
444 put8(0x0F);
445 put8(0xAD);
446 put8(0xC0 | (reg2 << 3) | reg1);
447}
448
449static osal_inline void sar_reg32_imm8(unsigned int reg32, unsigned char imm8)
450{
451 put8(0xC1);
452 put8(0xF8+reg32);
453 put8(imm8);
454}
455
456static osal_inline void shrd_reg32_reg32_imm8(unsigned int reg1, unsigned int reg2, unsigned char imm8)
457{
458 put8(0x0F);
459 put8(0xAC);
460 put8(0xC0 | (reg2 << 3) | reg1);
461 put8(imm8);
462}
463
464static osal_inline void mul_m32(unsigned int *m32)
465{
466 put8(0xF7);
467 put8(0x25);
468 put32((unsigned int)(m32));
469}
470
471static osal_inline void imul_reg32(unsigned int reg32)
472{
473 put8(0xF7);
474 put8(0xE8+reg32);
475}
476
477static osal_inline void mul_reg32(unsigned int reg32)
478{
479 put8(0xF7);
480 put8(0xE0+reg32);
481}
482
483static osal_inline void idiv_reg32(unsigned int reg32)
484{
485 put8(0xF7);
486 put8(0xF8+reg32);
487}
488
489static osal_inline void div_reg32(unsigned int reg32)
490{
491 put8(0xF7);
492 put8(0xF0+reg32);
493}
494
495static osal_inline void add_reg32_reg32(unsigned int reg1, unsigned int reg2)
496{
497 put8(0x01);
498 put8(0xC0 | (reg2 << 3) | reg1);
499}
500
501static osal_inline void adc_reg32_reg32(unsigned int reg1, unsigned int reg2)
502{
503 put8(0x11);
504 put8(0xC0 | (reg2 << 3) | reg1);
505}
506
507static osal_inline void add_reg32_m32(unsigned int reg32, unsigned int *m32)
508{
509 put8(0x03);
510 put8((reg32 << 3) | 5);
511 put32((unsigned int)(m32));
512}
513
514static osal_inline void adc_reg32_imm32(unsigned int reg32, unsigned int imm32)
515{
516 put8(0x81);
517 put8(0xD0 + reg32);
518 put32(imm32);
519}
520
521static osal_inline void jmp_reg32(unsigned int reg32)
522{
523 put8(0xFF);
524 put8(0xE0 + reg32);
525}
526
527static osal_inline void mov_reg32_preg32(unsigned int reg1, unsigned int reg2)
528{
529 put8(0x8B);
530 put8((reg1 << 3) | reg2);
531}
532
533static osal_inline void mov_preg32_reg32(int reg1, int reg2)
534{
535 put8(0x89);
536 put8((reg2 << 3) | reg1);
537}
538
539static osal_inline void mov_reg32_preg32preg32pimm32(int reg1, int reg2, int reg3, unsigned int imm32)
540{
541 put8(0x8B);
542 put8((reg1 << 3) | 0x84);
543 put8(reg2 | (reg3 << 3));
544 put32(imm32);
545}
546
547static osal_inline void mov_reg32_preg32pimm32(int reg1, int reg2, unsigned int imm32)
548{
549 put8(0x8B);
550 put8(0x80 | (reg1 << 3) | reg2);
551 put32(imm32);
552}
553
554static osal_inline void mov_reg32_preg32x4pimm32(int reg1, int reg2, unsigned int imm32)
555{
556 put8(0x8B);
557 put8((reg1 << 3) | 4);
558 put8(0x80 | (reg2 << 3) | 5);
559 put32(imm32);
560}
561
562static osal_inline void mov_preg32pimm32_reg8(int reg32, unsigned int imm32, int reg8)
563{
564 put8(0x88);
565 put8(0x80 | reg32 | (reg8 << 3));
566 put32(imm32);
567}
568
569static osal_inline void mov_preg32pimm32_imm8(int reg32, unsigned int imm32, unsigned char imm8)
570{
571 put8(0xC6);
572 put8(0x80 + reg32);
573 put32(imm32);
574 put8(imm8);
575}
576
577static osal_inline void mov_preg32pimm32_reg16(int reg32, unsigned int imm32, int reg16)
578{
579 put8(0x66);
580 put8(0x89);
581 put8(0x80 | reg32 | (reg16 << 3));
582 put32(imm32);
583}
584
585static osal_inline void mov_preg32pimm32_reg32(int reg1, unsigned int imm32, int reg2)
586{
587 put8(0x89);
588 put8(0x80 | reg1 | (reg2 << 3));
589 put32(imm32);
590}
591
592static osal_inline void add_eax_imm32(unsigned int imm32)
593{
594 put8(0x05);
595 put32(imm32);
596}
597
598static osal_inline void shl_reg32_imm8(unsigned int reg32, unsigned char imm8)
599{
600 put8(0xC1);
601 put8(0xE0 + reg32);
602 put8(imm8);
603}
604
605static osal_inline void mov_reg32_m32(unsigned int reg32, unsigned int* m32)
606{
607 put8(0x8B);
608 put8((reg32 << 3) | 5);
609 put32((unsigned int)(m32));
610}
611
612static osal_inline void mov_reg8_m8(int reg8, unsigned char *m8)
613{
614 put8(0x8A);
615 put8((reg8 << 3) | 5);
616 put32((unsigned int)(m8));
617}
618
619static osal_inline void and_eax_imm32(unsigned int imm32)
620{
621 put8(0x25);
622 put32(imm32);
623}
624
625static osal_inline void and_reg32_imm32(int reg32, unsigned int imm32)
626{
627 put8(0x81);
628 put8(0xE0 + reg32);
629 put32(imm32);
630}
631
632static osal_inline void or_reg32_imm32(int reg32, unsigned int imm32)
633{
634 put8(0x81);
635 put8(0xC8 + reg32);
636 put32(imm32);
637}
638
639static osal_inline void xor_reg32_imm32(int reg32, unsigned int imm32)
640{
641 put8(0x81);
642 put8(0xF0 + reg32);
643 put32(imm32);
644}
645
646static osal_inline void xor_reg8_imm8(int reg8, unsigned char imm8)
647{
648 put8(0x80);
649 put8(0xF0 + reg8);
650 put8(imm8);
651}
652
653static osal_inline void mov_reg32_reg32(unsigned int reg1, unsigned int reg2)
654{
655 if (reg1 == reg2) return;
656 put8(0x89);
657 put8(0xC0 | (reg2 << 3) | reg1);
658}
659
660static osal_inline void not_reg32(unsigned int reg32)
661{
662 put8(0xF7);
663 put8(0xD0 + reg32);
664}
665
666static osal_inline void movsx_reg32_m8(int reg32, unsigned char *m8)
667{
668 put8(0x0F);
669 put8(0xBE);
670 put8((reg32 << 3) | 5);
671 put32((unsigned int)(m8));
672}
673
674static osal_inline void movsx_reg32_8preg32pimm32(int reg1, int reg2, unsigned int imm32)
675{
676 put8(0x0F);
677 put8(0xBE);
678 put8((reg1 << 3) | reg2 | 0x80);
679 put32(imm32);
680}
681
682static osal_inline void movsx_reg32_16preg32pimm32(int reg1, int reg2, unsigned int imm32)
683{
684 put8(0x0F);
685 put8(0xBF);
686 put8((reg1 << 3) | reg2 | 0x80);
687 put32(imm32);
688}
689
690static osal_inline void movsx_reg32_m16(int reg32, unsigned short *m16)
691{
692 put8(0x0F);
693 put8(0xBF);
694 put8((reg32 << 3) | 5);
695 put32((unsigned int)(m16));
696}
697
698static osal_inline void fldcw_m16(unsigned short *m16)
699{
700 put8(0xD9);
701 put8(0x2D);
702 put32((unsigned int)(m16));
703}
704
705static osal_inline void fld_preg32_dword(int reg32)
706{
707 put8(0xD9);
708 put8(reg32);
709}
710
711static osal_inline void fdiv_preg32_dword(int reg32)
712{
713 put8(0xD8);
714 put8(0x30 + reg32);
715}
716
717static osal_inline void fstp_preg32_dword(int reg32)
718{
719 put8(0xD9);
720 put8(0x18 + reg32);
721}
722
723static osal_inline void fchs(void)
724{
725 put8(0xD9);
726 put8(0xE0);
727}
728
729static osal_inline void fstp_preg32_qword(int reg32)
730{
731 put8(0xDD);
732 put8(0x18 + reg32);
733}
734
735static osal_inline void fadd_preg32_dword(int reg32)
736{
737 put8(0xD8);
738 put8(reg32);
739}
740
741static osal_inline void fsub_preg32_dword(int reg32)
742{
743 put8(0xD8);
744 put8(0x20 + reg32);
745}
746
747static osal_inline void fmul_preg32_dword(int reg32)
748{
749 put8(0xD8);
750 put8(0x08 + reg32);
751}
752
753static osal_inline void fistp_preg32_dword(int reg32)
754{
755 put8(0xDB);
756 put8(0x18 + reg32);
757}
758
759static osal_inline void fistp_preg32_qword(int reg32)
760{
761 put8(0xDF);
762 put8(0x38 + reg32);
763}
764
765static osal_inline void fld_preg32_qword(int reg32)
766{
767 put8(0xDD);
768 put8(reg32);
769}
770
771static osal_inline void fild_preg32_qword(int reg32)
772{
773 put8(0xDF);
774 put8(0x28+reg32);
775}
776
777static osal_inline void fild_preg32_dword(int reg32)
778{
779 put8(0xDB);
780 put8(reg32);
781}
782
783static osal_inline void fadd_preg32_qword(int reg32)
784{
785 put8(0xDC);
786 put8(reg32);
787}
788
789static osal_inline void fdiv_preg32_qword(int reg32)
790{
791 put8(0xDC);
792 put8(0x30 + reg32);
793}
794
795static osal_inline void fsub_preg32_qword(int reg32)
796{
797 put8(0xDC);
798 put8(0x20 + reg32);
799}
800
801static osal_inline void fmul_preg32_qword(int reg32)
802{
803 put8(0xDC);
804 put8(0x08 + reg32);
805}
806
807static osal_inline void fsqrt(void)
808{
809 put8(0xD9);
810 put8(0xFA);
811}
812
813static osal_inline void fabs_(void)
814{
815 put8(0xD9);
816 put8(0xE1);
817}
818
819static osal_inline void fcomip_fpreg(int fpreg)
820{
821 put8(0xDF);
822 put8(0xF0 + fpreg);
823}
824
825static osal_inline void fucomip_fpreg(int fpreg)
826{
827 put8(0xDF);
828 put8(0xE8 + fpreg);
829}
830
831static osal_inline void ffree_fpreg(int fpreg)
832{
833 put8(0xDD);
834 put8(0xC0 + fpreg);
835}
836
837#endif // ASSEMBLE_H
838