Core commit. Compile and run on the OpenPandora
[mupen64plus-pandora.git] / source / mupen64plus-core / src / r4300 / x86 / assemble.h
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
31 extern 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
60 extern int branch_taken;
61
62 void jump_start_rel8(void);
63 void jump_end_rel8(void);
64 void jump_start_rel32(void);
65 void jump_end_rel32(void);
66 void add_jump(unsigned int pc_addr, unsigned int mi_addr);
67
68 static 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
79 static 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
90 static osal_inline void mov_eax_memoffs32(unsigned int *memoffs32)
91 {
92    put8(0xA1);
93    put32((unsigned int)(memoffs32));
94 }
95
96 static osal_inline void mov_memoffs32_eax(unsigned int *memoffs32)
97 {
98    put8(0xA3);
99    put32((unsigned int)(memoffs32));
100 }
101
102 static 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
109 static 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
117 static 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
125 static 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
132 static osal_inline void cmp_reg32_reg32(int reg1, int reg2)
133 {
134    put8(0x39);
135    put8((reg2 << 3) | reg1 | 0xC0);
136 }
137
138 static osal_inline void cmp_reg32_imm8(int reg32, unsigned char imm8)
139 {
140    put8(0x83);
141    put8(0xF8 + reg32);
142    put8(imm8);
143 }
144
145 static 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
153 static osal_inline void cmp_reg32_imm32(int reg32, unsigned int imm32)
154 {
155    put8(0x81);
156    put8(0xF8 + reg32);
157    put32(imm32);
158 }
159
160 static osal_inline void test_reg32_imm32(int reg32, unsigned int imm32)
161 {
162    put8(0xF7);
163    put8(0xC0 + reg32);
164    put32(imm32);
165 }
166
167 static 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
175 static 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
182 static 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
189 static osal_inline void sub_reg32_reg32(int reg1, int reg2)
190 {
191    put8(0x29);
192    put8((reg2 << 3) | reg1 | 0xC0);
193 }
194
195 static osal_inline void sbb_reg32_reg32(int reg1, int reg2)
196 {
197    put8(0x19);
198    put8((reg2 << 3) | reg1 | 0xC0);
199 }
200
201 static osal_inline void sub_reg32_imm32(int reg32, unsigned int imm32)
202 {
203    put8(0x81);
204    put8(0xE8 + reg32);
205    put32(imm32);
206 }
207
208 static osal_inline void sub_eax_imm32(unsigned int imm32)
209 {
210    put8(0x2D);
211    put32(imm32);
212 }
213
214 static osal_inline void jne_rj(unsigned char saut)
215 {
216    put8(0x75);
217    put8(saut);
218 }
219
220 static osal_inline void je_rj(unsigned char saut)
221 {
222    put8(0x74);
223    put8(saut);
224 }
225
226 static osal_inline void jb_rj(unsigned char saut)
227 {
228    put8(0x72);
229    put8(saut);
230 }
231
232 static osal_inline void jbe_rj(unsigned char saut)
233 {
234    put8(0x76);
235    put8(saut);
236 }
237
238 static osal_inline void ja_rj(unsigned char saut)
239 {
240    put8(0x77);
241    put8(saut);
242 }
243
244 static osal_inline void jae_rj(unsigned char saut)
245 {
246    put8(0x73);
247    put8(saut);
248 }
249
250 static osal_inline void jle_rj(unsigned char saut)
251 {
252    put8(0x7E);
253    put8(saut);
254 }
255
256 static osal_inline void jge_rj(unsigned char saut)
257 {
258    put8(0x7D);
259    put8(saut);
260 }
261
262 static osal_inline void jg_rj(unsigned char saut)
263 {
264    put8(0x7F);
265    put8(saut);
266 }
267
268 static osal_inline void jl_rj(unsigned char saut)
269 {
270    put8(0x7C);
271    put8(saut);
272 }
273
274 static osal_inline void jp_rj(unsigned char saut)
275 {
276    put8(0x7A);
277    put8(saut);
278 }
279
280 static osal_inline void je_near_rj(unsigned int saut)
281 {
282    put8(0x0F);
283    put8(0x84);
284    put32(saut);
285 }
286
287 static osal_inline void mov_reg32_imm32(int reg32, unsigned int imm32)
288 {
289    put8(0xB8+reg32);
290    put32(imm32);
291 }
292
293 static osal_inline void jmp_imm_short(char saut)
294 {
295    put8(0xEB);
296    put8(saut);
297 }
298
299 static 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
307 static osal_inline void or_reg32_reg32(unsigned int reg1, unsigned int reg2)
308 {
309    put8(0x09);
310    put8(0xC0 | (reg2 << 3) | reg1);
311 }
312
313 static osal_inline void and_reg32_reg32(unsigned int reg1, unsigned int reg2)
314 {
315    put8(0x21);
316    put8(0xC0 | (reg2 << 3) | reg1);
317 }
318
319 static 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
327 static osal_inline void xor_reg32_reg32(unsigned int reg1, unsigned int reg2)
328 {
329    put8(0x31);
330    put8(0xC0 | (reg2 << 3) | reg1);
331 }
332
333 static 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
341 static 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
348 static osal_inline void inc_m32(unsigned int *m32)
349 {
350    put8(0xFF);
351    put8(0x05);
352    put32((unsigned int)(m32));
353 }
354
355 static 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
363 static osal_inline void cmp_eax_imm32(unsigned int imm32)
364 {
365    put8(0x3D);
366    put32(imm32);
367 }
368
369 static 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
377 static 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
384 static osal_inline void cdq(void)
385 {
386    put8(0x99);
387 }
388
389 static 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
396 static osal_inline void call_reg32(unsigned int reg32)
397 {
398    put8(0xFF);
399    put8(0xD0+reg32);
400 }
401
402 static 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
409 static osal_inline void shr_reg32_cl(unsigned int reg32)
410 {
411    put8(0xD3);
412    put8(0xE8+reg32);
413 }
414
415 static osal_inline void sar_reg32_cl(unsigned int reg32)
416 {
417    put8(0xD3);
418    put8(0xF8+reg32);
419 }
420
421 static osal_inline void shl_reg32_cl(unsigned int reg32)
422 {
423    put8(0xD3);
424    put8(0xE0+reg32);
425 }
426
427 static 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
434 static 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
442 static 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
449 static 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
456 static 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
464 static osal_inline void mul_m32(unsigned int *m32)
465 {
466    put8(0xF7);
467    put8(0x25);
468    put32((unsigned int)(m32));
469 }
470
471 static osal_inline void imul_reg32(unsigned int reg32)
472 {
473    put8(0xF7);
474    put8(0xE8+reg32);
475 }
476
477 static osal_inline void mul_reg32(unsigned int reg32)
478 {
479    put8(0xF7);
480    put8(0xE0+reg32);
481 }
482
483 static osal_inline void idiv_reg32(unsigned int reg32)
484 {
485    put8(0xF7);
486    put8(0xF8+reg32);
487 }
488
489 static osal_inline void div_reg32(unsigned int reg32)
490 {
491    put8(0xF7);
492    put8(0xF0+reg32);
493 }
494
495 static osal_inline void add_reg32_reg32(unsigned int reg1, unsigned int reg2)
496 {
497    put8(0x01);
498    put8(0xC0 | (reg2 << 3) | reg1);
499 }
500
501 static osal_inline void adc_reg32_reg32(unsigned int reg1, unsigned int reg2)
502 {
503    put8(0x11);
504    put8(0xC0 | (reg2 << 3) | reg1);
505 }
506
507 static 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
514 static 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
521 static osal_inline void jmp_reg32(unsigned int reg32)
522 {
523    put8(0xFF);
524    put8(0xE0 + reg32);
525 }
526
527 static osal_inline void mov_reg32_preg32(unsigned int reg1, unsigned int reg2)
528 {
529    put8(0x8B);
530    put8((reg1 << 3) | reg2);
531 }
532
533 static osal_inline void mov_preg32_reg32(int reg1, int reg2)
534 {
535    put8(0x89);
536    put8((reg2 << 3) | reg1);
537 }
538
539 static 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
547 static 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
554 static 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
562 static 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
569 static 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
577 static 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
585 static 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
592 static osal_inline void add_eax_imm32(unsigned int imm32)
593 {
594    put8(0x05);
595    put32(imm32);
596 }
597
598 static 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
605 static 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
612 static 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
619 static osal_inline void and_eax_imm32(unsigned int imm32)
620 {
621    put8(0x25);
622    put32(imm32);
623 }
624
625 static osal_inline void and_reg32_imm32(int reg32, unsigned int imm32)
626 {
627    put8(0x81);
628    put8(0xE0 + reg32);
629    put32(imm32);
630 }
631
632 static osal_inline void or_reg32_imm32(int reg32, unsigned int imm32)
633 {
634    put8(0x81);
635    put8(0xC8 + reg32);
636    put32(imm32);
637 }
638
639 static osal_inline void xor_reg32_imm32(int reg32, unsigned int imm32)
640 {
641    put8(0x81);
642    put8(0xF0 + reg32);
643    put32(imm32);
644 }
645
646 static osal_inline void xor_reg8_imm8(int reg8, unsigned char imm8)
647 {
648    put8(0x80);
649    put8(0xF0 + reg8);
650    put8(imm8);
651 }
652
653 static 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
660 static osal_inline void not_reg32(unsigned int reg32)
661 {
662    put8(0xF7);
663    put8(0xD0 + reg32);
664 }
665
666 static 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
674 static 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
682 static 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
690 static 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
698 static osal_inline void fldcw_m16(unsigned short *m16)
699 {
700    put8(0xD9);
701    put8(0x2D);
702    put32((unsigned int)(m16));
703 }
704
705 static osal_inline void fld_preg32_dword(int reg32)
706 {
707    put8(0xD9);
708    put8(reg32);
709 }
710
711 static osal_inline void fdiv_preg32_dword(int reg32)
712 {
713    put8(0xD8);
714    put8(0x30 + reg32);
715 }
716
717 static osal_inline void fstp_preg32_dword(int reg32)
718 {
719    put8(0xD9);
720    put8(0x18 + reg32);
721 }
722
723 static osal_inline void fchs(void)
724 {
725    put8(0xD9);
726    put8(0xE0);
727 }
728
729 static osal_inline void fstp_preg32_qword(int reg32)
730 {
731    put8(0xDD);
732    put8(0x18 + reg32);
733 }
734
735 static osal_inline void fadd_preg32_dword(int reg32)
736 {
737    put8(0xD8);
738    put8(reg32);
739 }
740
741 static osal_inline void fsub_preg32_dword(int reg32)
742 {
743    put8(0xD8);
744    put8(0x20 + reg32);
745 }
746
747 static osal_inline void fmul_preg32_dword(int reg32)
748 {
749    put8(0xD8);
750    put8(0x08 + reg32);
751 }
752
753 static osal_inline void fistp_preg32_dword(int reg32)
754 {
755    put8(0xDB);
756    put8(0x18 + reg32);
757 }
758
759 static osal_inline void fistp_preg32_qword(int reg32)
760 {
761    put8(0xDF);
762    put8(0x38 + reg32);
763 }
764
765 static osal_inline void fld_preg32_qword(int reg32)
766 {
767    put8(0xDD);
768    put8(reg32);
769 }
770
771 static osal_inline void fild_preg32_qword(int reg32)
772 {
773    put8(0xDF);
774    put8(0x28+reg32);
775 }
776
777 static osal_inline void fild_preg32_dword(int reg32)
778 {
779    put8(0xDB);
780    put8(reg32);
781 }
782
783 static osal_inline void fadd_preg32_qword(int reg32)
784 {
785    put8(0xDC);
786    put8(reg32);
787 }
788
789 static osal_inline void fdiv_preg32_qword(int reg32)
790 {
791    put8(0xDC);
792    put8(0x30 + reg32);
793 }
794
795 static osal_inline void fsub_preg32_qword(int reg32)
796 {
797    put8(0xDC);
798    put8(0x20 + reg32);
799 }
800
801 static osal_inline void fmul_preg32_qword(int reg32)
802 {
803    put8(0xDC);
804    put8(0x08 + reg32);
805 }
806
807 static osal_inline void fsqrt(void)
808 {
809    put8(0xD9);
810    put8(0xFA);
811 }
812
813 static osal_inline void fabs_(void)
814 {
815    put8(0xD9);
816    put8(0xE1);
817 }
818
819 static osal_inline void fcomip_fpreg(int fpreg)
820 {
821    put8(0xDF);
822    put8(0xF0 + fpreg);
823 }
824
825 static osal_inline void fucomip_fpreg(int fpreg)
826 {
827    put8(0xDF);
828    put8(0xE8 + fpreg);
829 }
830
831 static osal_inline void ffree_fpreg(int fpreg)
832 {
833    put8(0xDD);
834    put8(0xC0 + fpreg);
835 }
836
837 #endif // ASSEMBLE_H
838