Core commit. Compile and run on the OpenPandora
[mupen64plus-pandora.git] / source / mupen64plus-core / src / r4300 / x86_64 / gcop1.c
CommitLineData
451ab91e 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 *
6 * *
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. *
11 * *
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. *
16 * *
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 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
22
23#include <stdio.h>
24
25#include "assemble.h"
26#include "interpret.h"
27
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"
33
34#include "memory/memory.h"
35
36void genmfc1(void)
37{
38#if defined(COUNT_INSTR)
39 inc_m32rel(&instr_count[111]);
40#endif
41#ifdef INTERPRET_MFC1
42 gencallinterp((unsigned long long)cached_interpreter_table.MFC1, 0);
43#else
44 gencheck_cop1_unusable();
45 mov_xreg64_m64rel(RAX, (unsigned long long *)(&reg_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);
50#endif
51}
52
53void gendmfc1(void)
54{
55#if defined(COUNT_INSTR)
56 inc_m32rel(&instr_count[112]);
57#endif
58#ifdef INTERPRET_DMFC1
59 gencallinterp((unsigned long long)cached_interpreter_table.DMFC1, 0);
60#else
61 gencheck_cop1_unusable();
62 mov_xreg64_m64rel(RAX, (unsigned long long *) (&reg_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);
67#endif
68}
69
70void gencfc1(void)
71{
72#if defined(COUNT_INSTR)
73 inc_m32rel(&instr_count[113]);
74#endif
75#ifdef INTERPRET_CFC1
76 gencallinterp((unsigned long long)cached_interpreter_table.CFC1, 0);
77#else
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);
84#endif
85}
86
87void genmtc1(void)
88{
89#if defined(COUNT_INSTR)
90 inc_m32rel(&instr_count[114]);
91#endif
92#ifdef INTERPRET_MTC1
93 gencallinterp((unsigned long long)cached_interpreter_table.MTC1, 0);
94#else
95 gencheck_cop1_unusable();
96 mov_xreg32_m32rel(EAX, (unsigned int*)dst->f.r.rt);
97 mov_xreg64_m64rel(RBX, (unsigned long long *)(&reg_cop1_simple[dst->f.r.nrd]));
98 mov_preg64_reg32(RBX, EAX);
99#endif
100}
101
102void gendmtc1(void)
103{
104#if defined(COUNT_INSTR)
105 inc_m32rel(&instr_count[115]);
106#endif
107#ifdef INTERPRET_DMTC1
108 gencallinterp((unsigned long long)cached_interpreter_table.DMTC1, 0);
109#else
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 *)(&reg_cop1_double[dst->f.r.nrd]));
114 mov_preg64_reg32(RDX, EAX);
115 mov_preg64pimm32_reg32(RDX, 4, EBX);
116#endif
117}
118
119void genctc1(void)
120{
121#if defined(COUNT_INSTR)
122 inc_m32rel(&instr_count[116]);
123#endif
124#ifdef INTERPRET_CTC1
125 gencallinterp((unsigned long long)cached_interpreter_table.CTC1, 0);
126#else
127 gencheck_cop1_unusable();
128
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);
132 and_eax_imm32(3);
133
134 cmp_eax_imm32(0);
135 jne_rj(13);
136 mov_m32rel_imm32((unsigned int*)&rounding_mode, 0x33F); // 11
137 jmp_imm_short(51); // 2
138
139 cmp_eax_imm32(1); // 5
140 jne_rj(13); // 2
141 mov_m32rel_imm32((unsigned int*)&rounding_mode, 0xF3F); // 11
142 jmp_imm_short(31); // 2
143
144 cmp_eax_imm32(2); // 5
145 jne_rj(13); // 2
146 mov_m32rel_imm32((unsigned int*)&rounding_mode, 0xB3F); // 11
147 jmp_imm_short(11); // 2
148
149 mov_m32rel_imm32((unsigned int*)&rounding_mode, 0x73F); // 11
150
151 fldcw_m16rel((unsigned short*)&rounding_mode);
152#endif
153}
154