1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Mupen64plus - gcop1.c *
3 * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
4 * Copyright (C) 2007 Richard Goedeken (Richard42) *
5 * Copyright (C) 2002 Hacktarux *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
21 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
26 #include "interpret.h"
28 #include "r4300/recomph.h"
29 #include "r4300/recomp.h"
30 #include "r4300/r4300.h"
31 #include "r4300/ops.h"
32 #include "r4300/macros.h"
34 #include "memory/memory.h"
38 #if defined(COUNT_INSTR)
39 inc_m32rel(&instr_count[111]);
42 gencallinterp((unsigned long long)cached_interpreter_table.MFC1, 0);
44 gencheck_cop1_unusable();
45 mov_xreg64_m64rel(RAX, (unsigned long long *)(®_cop1_simple[dst->f.r.nrd]));
46 mov_reg32_preg64(EBX, RAX);
47 mov_m32rel_xreg32((unsigned int*)dst->f.r.rt, EBX);
48 sar_reg32_imm8(EBX, 31);
49 mov_m32rel_xreg32(((unsigned int*)dst->f.r.rt)+1, EBX);
55 #if defined(COUNT_INSTR)
56 inc_m32rel(&instr_count[112]);
58 #ifdef INTERPRET_DMFC1
59 gencallinterp((unsigned long long)cached_interpreter_table.DMFC1, 0);
61 gencheck_cop1_unusable();
62 mov_xreg64_m64rel(RAX, (unsigned long long *) (®_cop1_double[dst->f.r.nrd]));
63 mov_reg32_preg64(EBX, RAX);
64 mov_reg32_preg64pimm32(ECX, RAX, 4);
65 mov_m32rel_xreg32((unsigned int*)dst->f.r.rt, EBX);
66 mov_m32rel_xreg32(((unsigned int*)dst->f.r.rt)+1, ECX);
72 #if defined(COUNT_INSTR)
73 inc_m32rel(&instr_count[113]);
76 gencallinterp((unsigned long long)cached_interpreter_table.CFC1, 0);
78 gencheck_cop1_unusable();
79 if(dst->f.r.nrd == 31) mov_xreg32_m32rel(EAX, (unsigned int*)&FCR31);
80 else mov_xreg32_m32rel(EAX, (unsigned int*)&FCR0);
81 mov_m32rel_xreg32((unsigned int*)dst->f.r.rt, EAX);
82 sar_reg32_imm8(EAX, 31);
83 mov_m32rel_xreg32(((unsigned int*)dst->f.r.rt)+1, EAX);
89 #if defined(COUNT_INSTR)
90 inc_m32rel(&instr_count[114]);
93 gencallinterp((unsigned long long)cached_interpreter_table.MTC1, 0);
95 gencheck_cop1_unusable();
96 mov_xreg32_m32rel(EAX, (unsigned int*)dst->f.r.rt);
97 mov_xreg64_m64rel(RBX, (unsigned long long *)(®_cop1_simple[dst->f.r.nrd]));
98 mov_preg64_reg32(RBX, EAX);
104 #if defined(COUNT_INSTR)
105 inc_m32rel(&instr_count[115]);
107 #ifdef INTERPRET_DMTC1
108 gencallinterp((unsigned long long)cached_interpreter_table.DMTC1, 0);
110 gencheck_cop1_unusable();
111 mov_xreg32_m32rel(EAX, (unsigned int*)dst->f.r.rt);
112 mov_xreg32_m32rel(EBX, ((unsigned int*)dst->f.r.rt)+1);
113 mov_xreg64_m64rel(RDX, (unsigned long long *)(®_cop1_double[dst->f.r.nrd]));
114 mov_preg64_reg32(RDX, EAX);
115 mov_preg64pimm32_reg32(RDX, 4, EBX);
121 #if defined(COUNT_INSTR)
122 inc_m32rel(&instr_count[116]);
124 #ifdef INTERPRET_CTC1
125 gencallinterp((unsigned long long)cached_interpreter_table.CTC1, 0);
127 gencheck_cop1_unusable();
129 if (dst->f.r.nrd != 31) return;
130 mov_xreg32_m32rel(EAX, (unsigned int*)dst->f.r.rt);
131 mov_m32rel_xreg32((unsigned int*)&FCR31, EAX);
136 mov_m32rel_imm32((unsigned int*)&rounding_mode, 0x33F); // 11
137 jmp_imm_short(51); // 2
139 cmp_eax_imm32(1); // 5
141 mov_m32rel_imm32((unsigned int*)&rounding_mode, 0xF3F); // 11
142 jmp_imm_short(31); // 2
144 cmp_eax_imm32(2); // 5
146 mov_m32rel_imm32((unsigned int*)&rounding_mode, 0xB3F); // 11
147 jmp_imm_short(11); // 2
149 mov_m32rel_imm32((unsigned int*)&rounding_mode, 0x73F); // 11
151 fldcw_m16rel((unsigned short*)&rounding_mode);