1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Mupen64plus - pure_interp.c *
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 "api/m64p_types.h"
26 #include "api/callbacks.h"
27 #include "api/debugger.h"
28 #include "memory/memory.h"
30 #include "osal/preproc.h"
34 #include "exception.h"
39 #include "debugger/dbg_types.h"
40 #include "debugger/debugger.h"
43 static precomp_instr interp_PC;
46 static void prefetch(void);
48 #define PCADDR interp_PC.addr
49 #define ADD_TO_PC(x) interp_PC.addr += x*4;
50 #define DECLARE_INSTRUCTION(name) static void name(void)
51 #define DECLARE_JUMP(name, destination, condition, link, likely, cop1) \
52 static void name(void) \
54 const int take_jump = (condition); \
55 const unsigned int jump_target = (destination); \
56 long long int *link_register = (link); \
57 if (cop1 && check_cop1_unusable()) return; \
58 if (!likely || take_jump) \
60 interp_PC.addr += 4; \
66 if (take_jump && !skip_jump) \
68 if (link_register != ®[0]) \
70 *link_register=interp_PC.addr; \
71 sign_extended(*link_register); \
73 interp_PC.addr = jump_target; \
78 interp_PC.addr += 8; \
81 last_addr = interp_PC.addr; \
82 if (next_interupt <= Count) gen_interupt(); \
84 static void name##_IDLE(void) \
86 const int take_jump = (condition); \
88 if (cop1 && check_cop1_unusable()) return; \
92 skip = next_interupt - Count; \
93 if (skip > 3) Count += (skip & 0xFFFFFFFC); \
98 #define CHECK_MEMORY()
100 #include "interpreter.def"
102 // two functions are defined from the macros above but never used
103 // these prototype declarations will prevent a warning
104 #if defined(__GNUC__)
105 void JR_IDLE(void) __attribute__((used));
106 void JALR_IDLE(void) __attribute__((used));
109 static cpu_instruction_table pure_interpreter_table = {
180 JAL, // _OUT (unused)
185 BEQ, // _OUT (unused)
188 BNE, // _OUT (unused)
191 BLEZ, // _OUT (unused)
194 BGTZ, // _OUT (unused)
197 BLTZ, // _OUT (unused)
200 BGEZ, // _OUT (unused)
203 BLTZAL, // _OUT (unused)
206 BGEZAL, // _OUT (unused)
210 BEQL, // _OUT (unused)
213 BNEL, // _OUT (unused)
216 BLEZL, // _OUT (unused)
219 BGTZL, // _OUT (unused)
222 BLTZL, // _OUT (unused)
225 BGEZL, // _OUT (unused)
228 BLTZALL, // _OUT (unused)
231 BGEZALL, // _OUT (unused)
234 BC1TL, // _OUT (unused)
237 BC1FL, // _OUT (unused)
274 BC1T, // _OUT (unused)
277 BC1F, // _OUT (unused)
383 NULL, // NOTCOMPILED2
386 static void prefetch(void)
388 unsigned int *mem = fast_mem_access(interp_PC.addr);
391 prefetch_opcode(mem[0], mem[1]);
395 DebugMessage(M64MSG_ERROR, "prefetch() execute address :%x", PC->addr);
400 void pure_interpreter(void)
404 PC->addr = last_addr = 0xa4000040;
407 if (g_DebuggerActive)
408 update_debugger(PC->addr);
411 current_instruction_table = pure_interpreter_table;
417 CoreCompareCallback();
420 if (g_DebuggerActive) update_debugger(PC->addr);