1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Mupen64plus - assemble.h *
3 * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
4 * Copyright (C) 2002 Hacktarux *
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. *
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. *
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 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
25 #include "r4300/recomph.h"
26 #include "api/callbacks.h"
27 #include "osal/preproc.h"
31 extern long long int reg[32];
60 extern int branch_taken;
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);
68 static osal_inline void put8(unsigned char octet)
70 (*inst_pointer)[code_length] = octet;
72 if (code_length == max_code_length)
74 *inst_pointer = (unsigned char *) realloc_exec(*inst_pointer, max_code_length, max_code_length+8192);
75 max_code_length += 8192;
79 static osal_inline void put32(unsigned int dword)
81 if ((code_length+4) >= max_code_length)
83 *inst_pointer = (unsigned char *) realloc_exec(*inst_pointer, max_code_length, max_code_length+8192);
84 max_code_length += 8192;
86 *((unsigned int *)(&(*inst_pointer)[code_length])) = dword;
90 static osal_inline void mov_eax_memoffs32(unsigned int *memoffs32)
93 put32((unsigned int)(memoffs32));
96 static osal_inline void mov_memoffs32_eax(unsigned int *memoffs32)
99 put32((unsigned int)(memoffs32));
102 static osal_inline void mov_m8_reg8(unsigned char *m8, int reg8)
105 put8((reg8 << 3) | 5);
106 put32((unsigned int)(m8));
109 static osal_inline void mov_reg16_m16(int reg16, unsigned short *m16)
113 put8((reg16 << 3) | 5);
114 put32((unsigned int)(m16));
117 static osal_inline void mov_m16_reg16(unsigned short *m16, int reg16)
121 put8((reg16 << 3) | 5);
122 put32((unsigned int)(m16));
125 static osal_inline void cmp_reg32_m32(int reg32, unsigned int *m32)
128 put8((reg32 << 3) | 5);
129 put32((unsigned int)(m32));
132 static osal_inline void cmp_reg32_reg32(int reg1, int reg2)
135 put8((reg2 << 3) | reg1 | 0xC0);
138 static osal_inline void cmp_reg32_imm8(int reg32, unsigned char imm8)
145 static osal_inline void cmp_preg32pimm32_imm8(int reg32, unsigned int imm32, unsigned char imm8)
153 static osal_inline void cmp_reg32_imm32(int reg32, unsigned int imm32)
160 static osal_inline void test_reg32_imm32(int reg32, unsigned int imm32)
167 static osal_inline void test_m32_imm32(unsigned int *m32, unsigned int imm32)
171 put32((unsigned int)m32);
175 static osal_inline void add_m32_reg32(unsigned int *m32, int reg32)
178 put8((reg32 << 3) | 5);
179 put32((unsigned int)(m32));
182 static osal_inline void sub_reg32_m32(int reg32, unsigned int *m32)
185 put8((reg32 << 3) | 5);
186 put32((unsigned int)(m32));
189 static osal_inline void sub_reg32_reg32(int reg1, int reg2)
192 put8((reg2 << 3) | reg1 | 0xC0);
195 static osal_inline void sbb_reg32_reg32(int reg1, int reg2)
198 put8((reg2 << 3) | reg1 | 0xC0);
201 static osal_inline void sub_reg32_imm32(int reg32, unsigned int imm32)
208 static osal_inline void sub_eax_imm32(unsigned int imm32)
214 static osal_inline void jne_rj(unsigned char saut)
220 static osal_inline void je_rj(unsigned char saut)
226 static osal_inline void jb_rj(unsigned char saut)
232 static osal_inline void jbe_rj(unsigned char saut)
238 static osal_inline void ja_rj(unsigned char saut)
244 static osal_inline void jae_rj(unsigned char saut)
250 static osal_inline void jle_rj(unsigned char saut)
256 static osal_inline void jge_rj(unsigned char saut)
262 static osal_inline void jg_rj(unsigned char saut)
268 static osal_inline void jl_rj(unsigned char saut)
274 static osal_inline void jp_rj(unsigned char saut)
280 static osal_inline void je_near_rj(unsigned int saut)
287 static osal_inline void mov_reg32_imm32(int reg32, unsigned int imm32)
293 static osal_inline void jmp_imm_short(char saut)
299 static osal_inline void or_m32_imm32(unsigned int *m32, unsigned int imm32)
303 put32((unsigned int)(m32));
307 static osal_inline void or_reg32_reg32(unsigned int reg1, unsigned int reg2)
310 put8(0xC0 | (reg2 << 3) | reg1);
313 static osal_inline void and_reg32_reg32(unsigned int reg1, unsigned int reg2)
316 put8(0xC0 | (reg2 << 3) | reg1);
319 static osal_inline void and_m32_imm32(unsigned int *m32, unsigned int imm32)
323 put32((unsigned int)(m32));
327 static osal_inline void xor_reg32_reg32(unsigned int reg1, unsigned int reg2)
330 put8(0xC0 | (reg2 << 3) | reg1);
333 static osal_inline void sub_m32_imm32(unsigned int *m32, unsigned int imm32)
337 put32((unsigned int)(m32));
341 static osal_inline void add_reg32_imm32(unsigned int reg32, unsigned int imm32)
348 static osal_inline void inc_m32(unsigned int *m32)
352 put32((unsigned int)(m32));
355 static osal_inline void cmp_m32_imm32(unsigned int *m32, unsigned int imm32)
359 put32((unsigned int)(m32));
363 static osal_inline void cmp_eax_imm32(unsigned int imm32)
369 static osal_inline void mov_m32_imm32(unsigned int *m32, unsigned int imm32)
373 put32((unsigned int)(m32));
377 static osal_inline void jmp(unsigned int mi_addr)
381 add_jump(code_length-4, mi_addr);
384 static osal_inline void cdq(void)
389 static osal_inline void mov_m32_reg32(unsigned int *m32, unsigned int reg32)
392 put8((reg32 << 3) | 5);
393 put32((unsigned int)(m32));
396 static osal_inline void call_reg32(unsigned int reg32)
402 static osal_inline void shr_reg32_imm8(unsigned int reg32, unsigned char imm8)
409 static osal_inline void shr_reg32_cl(unsigned int reg32)
415 static osal_inline void sar_reg32_cl(unsigned int reg32)
421 static osal_inline void shl_reg32_cl(unsigned int reg32)
427 static osal_inline void shld_reg32_reg32_cl(unsigned int reg1, unsigned int reg2)
431 put8(0xC0 | (reg2 << 3) | reg1);
434 static osal_inline void shld_reg32_reg32_imm8(unsigned int reg1, unsigned int reg2, unsigned char imm8)
438 put8(0xC0 | (reg2 << 3) | reg1);
442 static osal_inline void shrd_reg32_reg32_cl(unsigned int reg1, unsigned int reg2)
446 put8(0xC0 | (reg2 << 3) | reg1);
449 static osal_inline void sar_reg32_imm8(unsigned int reg32, unsigned char imm8)
456 static osal_inline void shrd_reg32_reg32_imm8(unsigned int reg1, unsigned int reg2, unsigned char imm8)
460 put8(0xC0 | (reg2 << 3) | reg1);
464 static osal_inline void mul_m32(unsigned int *m32)
468 put32((unsigned int)(m32));
471 static osal_inline void imul_reg32(unsigned int reg32)
477 static osal_inline void mul_reg32(unsigned int reg32)
483 static osal_inline void idiv_reg32(unsigned int reg32)
489 static osal_inline void div_reg32(unsigned int reg32)
495 static osal_inline void add_reg32_reg32(unsigned int reg1, unsigned int reg2)
498 put8(0xC0 | (reg2 << 3) | reg1);
501 static osal_inline void adc_reg32_reg32(unsigned int reg1, unsigned int reg2)
504 put8(0xC0 | (reg2 << 3) | reg1);
507 static osal_inline void add_reg32_m32(unsigned int reg32, unsigned int *m32)
510 put8((reg32 << 3) | 5);
511 put32((unsigned int)(m32));
514 static osal_inline void adc_reg32_imm32(unsigned int reg32, unsigned int imm32)
521 static osal_inline void jmp_reg32(unsigned int reg32)
527 static osal_inline void mov_reg32_preg32(unsigned int reg1, unsigned int reg2)
530 put8((reg1 << 3) | reg2);
533 static osal_inline void mov_preg32_reg32(int reg1, int reg2)
536 put8((reg2 << 3) | reg1);
539 static osal_inline void mov_reg32_preg32preg32pimm32(int reg1, int reg2, int reg3, unsigned int imm32)
542 put8((reg1 << 3) | 0x84);
543 put8(reg2 | (reg3 << 3));
547 static osal_inline void mov_reg32_preg32pimm32(int reg1, int reg2, unsigned int imm32)
550 put8(0x80 | (reg1 << 3) | reg2);
554 static osal_inline void mov_reg32_preg32x4pimm32(int reg1, int reg2, unsigned int imm32)
557 put8((reg1 << 3) | 4);
558 put8(0x80 | (reg2 << 3) | 5);
562 static osal_inline void mov_preg32pimm32_reg8(int reg32, unsigned int imm32, int reg8)
565 put8(0x80 | reg32 | (reg8 << 3));
569 static osal_inline void mov_preg32pimm32_imm8(int reg32, unsigned int imm32, unsigned char imm8)
577 static osal_inline void mov_preg32pimm32_reg16(int reg32, unsigned int imm32, int reg16)
581 put8(0x80 | reg32 | (reg16 << 3));
585 static osal_inline void mov_preg32pimm32_reg32(int reg1, unsigned int imm32, int reg2)
588 put8(0x80 | reg1 | (reg2 << 3));
592 static osal_inline void add_eax_imm32(unsigned int imm32)
598 static osal_inline void shl_reg32_imm8(unsigned int reg32, unsigned char imm8)
605 static osal_inline void mov_reg32_m32(unsigned int reg32, unsigned int* m32)
608 put8((reg32 << 3) | 5);
609 put32((unsigned int)(m32));
612 static osal_inline void mov_reg8_m8(int reg8, unsigned char *m8)
615 put8((reg8 << 3) | 5);
616 put32((unsigned int)(m8));
619 static osal_inline void and_eax_imm32(unsigned int imm32)
625 static osal_inline void and_reg32_imm32(int reg32, unsigned int imm32)
632 static osal_inline void or_reg32_imm32(int reg32, unsigned int imm32)
639 static osal_inline void xor_reg32_imm32(int reg32, unsigned int imm32)
646 static osal_inline void xor_reg8_imm8(int reg8, unsigned char imm8)
653 static osal_inline void mov_reg32_reg32(unsigned int reg1, unsigned int reg2)
655 if (reg1 == reg2) return;
657 put8(0xC0 | (reg2 << 3) | reg1);
660 static osal_inline void not_reg32(unsigned int reg32)
666 static osal_inline void movsx_reg32_m8(int reg32, unsigned char *m8)
670 put8((reg32 << 3) | 5);
671 put32((unsigned int)(m8));
674 static osal_inline void movsx_reg32_8preg32pimm32(int reg1, int reg2, unsigned int imm32)
678 put8((reg1 << 3) | reg2 | 0x80);
682 static osal_inline void movsx_reg32_16preg32pimm32(int reg1, int reg2, unsigned int imm32)
686 put8((reg1 << 3) | reg2 | 0x80);
690 static osal_inline void movsx_reg32_m16(int reg32, unsigned short *m16)
694 put8((reg32 << 3) | 5);
695 put32((unsigned int)(m16));
698 static osal_inline void fldcw_m16(unsigned short *m16)
702 put32((unsigned int)(m16));
705 static osal_inline void fld_preg32_dword(int reg32)
711 static osal_inline void fdiv_preg32_dword(int reg32)
717 static osal_inline void fstp_preg32_dword(int reg32)
723 static osal_inline void fchs(void)
729 static osal_inline void fstp_preg32_qword(int reg32)
735 static osal_inline void fadd_preg32_dword(int reg32)
741 static osal_inline void fsub_preg32_dword(int reg32)
747 static osal_inline void fmul_preg32_dword(int reg32)
753 static osal_inline void fistp_preg32_dword(int reg32)
759 static osal_inline void fistp_preg32_qword(int reg32)
765 static osal_inline void fld_preg32_qword(int reg32)
771 static osal_inline void fild_preg32_qword(int reg32)
777 static osal_inline void fild_preg32_dword(int reg32)
783 static osal_inline void fadd_preg32_qword(int reg32)
789 static osal_inline void fdiv_preg32_qword(int reg32)
795 static osal_inline void fsub_preg32_qword(int reg32)
801 static osal_inline void fmul_preg32_qword(int reg32)
807 static osal_inline void fsqrt(void)
813 static osal_inline void fabs_(void)
819 static osal_inline void fcomip_fpreg(int fpreg)
825 static osal_inline void fucomip_fpreg(int fpreg)
831 static osal_inline void ffree_fpreg(int fpreg)