Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libmupen64plus/mupen64plus-core/src/r4300/pure_interp.c
2 views
1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
* Mupen64plus - pure_interp.c *
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
#include <stdlib.h>
23
#include <math.h>
24
25
#include "api/m64p_types.h"
26
#include "api/callbacks.h"
27
#include "api/debugger.h"
28
#include "memory/memory.h"
29
#include "main/rom.h"
30
#include "osal/preproc.h"
31
32
#include "r4300.h"
33
#include "ops.h"
34
#include "exception.h"
35
#include "macros.h"
36
#include "interupt.h"
37
38
#ifdef DBG
39
#include "debugger/dbg_types.h"
40
#include "debugger/debugger.h"
41
#endif
42
43
static precomp_instr interp_PC;
44
unsigned int op;
45
46
static void prefetch(void);
47
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) \
53
{ \
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) \
59
{ \
60
interp_PC.addr += 4; \
61
delay_slot=1; \
62
prefetch(); \
63
PC->ops(); \
64
update_count(); \
65
delay_slot=0; \
66
if (take_jump && !skip_jump) \
67
{ \
68
if (link_register != &reg[0]) \
69
{ \
70
*link_register=interp_PC.addr; \
71
sign_extended(*link_register); \
72
} \
73
interp_PC.addr = jump_target; \
74
} \
75
} \
76
else \
77
{ \
78
interp_PC.addr += 8; \
79
update_count(); \
80
} \
81
last_addr = interp_PC.addr; \
82
if (next_interupt <= Count) gen_interupt(); \
83
} \
84
static void name##_IDLE(void) \
85
{ \
86
const int take_jump = (condition); \
87
int skip; \
88
if (cop1 && check_cop1_unusable()) return; \
89
if (take_jump) \
90
{ \
91
update_count(); \
92
skip = next_interupt - Count; \
93
if (skip > 3) Count += (skip & 0xFFFFFFFC); \
94
else name(); \
95
} \
96
else name(); \
97
}
98
#define CHECK_MEMORY()
99
100
#include "interpreter.def"
101
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));
107
#endif
108
109
static cpu_instruction_table pure_interpreter_table = {
110
LB,
111
LBU,
112
LH,
113
LHU,
114
LW,
115
LWL,
116
LWR,
117
SB,
118
SH,
119
SW,
120
SWL,
121
SWR,
122
123
LD,
124
LDL,
125
LDR,
126
LL,
127
LWU,
128
SC,
129
SD,
130
SDL,
131
SDR,
132
SYNC,
133
134
ADDI,
135
ADDIU,
136
SLTI,
137
SLTIU,
138
ANDI,
139
ORI,
140
XORI,
141
LUI,
142
143
DADDI,
144
DADDIU,
145
146
ADD,
147
ADDU,
148
SUB,
149
SUBU,
150
SLT,
151
SLTU,
152
AND,
153
OR,
154
XOR,
155
NOR,
156
157
DADD,
158
DADDU,
159
DSUB,
160
DSUBU,
161
162
MULT,
163
MULTU,
164
DIV,
165
DIVU,
166
MFHI,
167
MTHI,
168
MFLO,
169
MTLO,
170
171
DMULT,
172
DMULTU,
173
DDIV,
174
DDIVU,
175
176
J,
177
J, // _OUT (unused)
178
J_IDLE,
179
JAL,
180
JAL, // _OUT (unused)
181
JAL_IDLE,
182
JR,
183
JALR,
184
BEQ,
185
BEQ, // _OUT (unused)
186
BEQ_IDLE,
187
BNE,
188
BNE, // _OUT (unused)
189
BNE_IDLE,
190
BLEZ,
191
BLEZ, // _OUT (unused)
192
BLEZ_IDLE,
193
BGTZ,
194
BGTZ, // _OUT (unused)
195
BGTZ_IDLE,
196
BLTZ,
197
BLTZ, // _OUT (unused)
198
BLTZ_IDLE,
199
BGEZ,
200
BGEZ, // _OUT (unused)
201
BGEZ_IDLE,
202
BLTZAL,
203
BLTZAL, // _OUT (unused)
204
BLTZAL_IDLE,
205
BGEZAL,
206
BGEZAL, // _OUT (unused)
207
BGEZAL_IDLE,
208
209
BEQL,
210
BEQL, // _OUT (unused)
211
BEQL_IDLE,
212
BNEL,
213
BNEL, // _OUT (unused)
214
BNEL_IDLE,
215
BLEZL,
216
BLEZL, // _OUT (unused)
217
BLEZL_IDLE,
218
BGTZL,
219
BGTZL, // _OUT (unused)
220
BGTZL_IDLE,
221
BLTZL,
222
BLTZL, // _OUT (unused)
223
BLTZL_IDLE,
224
BGEZL,
225
BGEZL, // _OUT (unused)
226
BGEZL_IDLE,
227
BLTZALL,
228
BLTZALL, // _OUT (unused)
229
BLTZALL_IDLE,
230
BGEZALL,
231
BGEZALL, // _OUT (unused)
232
BGEZALL_IDLE,
233
BC1TL,
234
BC1TL, // _OUT (unused)
235
BC1TL_IDLE,
236
BC1FL,
237
BC1FL, // _OUT (unused)
238
BC1FL_IDLE,
239
240
SLL,
241
SRL,
242
SRA,
243
SLLV,
244
SRLV,
245
SRAV,
246
247
DSLL,
248
DSRL,
249
DSRA,
250
DSLLV,
251
DSRLV,
252
DSRAV,
253
DSLL32,
254
DSRL32,
255
DSRA32,
256
257
MTC0,
258
MFC0,
259
260
TLBR,
261
TLBWI,
262
TLBWR,
263
TLBP,
264
CACHE,
265
ERET,
266
267
LWC1,
268
SWC1,
269
MTC1,
270
MFC1,
271
CTC1,
272
CFC1,
273
BC1T,
274
BC1T, // _OUT (unused)
275
BC1T_IDLE,
276
BC1F,
277
BC1F, // _OUT (unused)
278
BC1F_IDLE,
279
280
DMFC1,
281
DMTC1,
282
LDC1,
283
SDC1,
284
285
CVT_S_D,
286
CVT_S_W,
287
CVT_S_L,
288
CVT_D_S,
289
CVT_D_W,
290
CVT_D_L,
291
CVT_W_S,
292
CVT_W_D,
293
CVT_L_S,
294
CVT_L_D,
295
296
ROUND_W_S,
297
ROUND_W_D,
298
ROUND_L_S,
299
ROUND_L_D,
300
301
TRUNC_W_S,
302
TRUNC_W_D,
303
TRUNC_L_S,
304
TRUNC_L_D,
305
306
CEIL_W_S,
307
CEIL_W_D,
308
CEIL_L_S,
309
CEIL_L_D,
310
311
FLOOR_W_S,
312
FLOOR_W_D,
313
FLOOR_L_S,
314
FLOOR_L_D,
315
316
ADD_S,
317
ADD_D,
318
319
SUB_S,
320
SUB_D,
321
322
MUL_S,
323
MUL_D,
324
325
DIV_S,
326
DIV_D,
327
328
ABS_S,
329
ABS_D,
330
331
MOV_S,
332
MOV_D,
333
334
NEG_S,
335
NEG_D,
336
337
SQRT_S,
338
SQRT_D,
339
340
C_F_S,
341
C_F_D,
342
C_UN_S,
343
C_UN_D,
344
C_EQ_S,
345
C_EQ_D,
346
C_UEQ_S,
347
C_UEQ_D,
348
C_OLT_S,
349
C_OLT_D,
350
C_ULT_S,
351
C_ULT_D,
352
C_OLE_S,
353
C_OLE_D,
354
C_ULE_S,
355
C_ULE_D,
356
C_SF_S,
357
C_SF_D,
358
C_NGLE_S,
359
C_NGLE_D,
360
C_SEQ_S,
361
C_SEQ_D,
362
C_NGL_S,
363
C_NGL_D,
364
C_LT_S,
365
C_LT_D,
366
C_NGE_S,
367
C_NGE_D,
368
C_LE_S,
369
C_LE_D,
370
C_NGT_S,
371
C_NGT_D,
372
373
SYSCALL,
374
375
TEQ,
376
377
NOP,
378
RESERVED,
379
NI,
380
381
NULL, // FIN_BLOCK
382
NULL, // NOTCOMPILED
383
NULL, // NOTCOMPILED2
384
};
385
386
static void prefetch(void)
387
{
388
unsigned int *mem = fast_mem_access(interp_PC.addr);
389
if (mem != NULL)
390
{
391
prefetch_opcode(mem[0], mem[1]);
392
}
393
else
394
{
395
DebugMessage(M64MSG_ERROR, "prefetch() execute address :%x", PC->addr);
396
stop=1;
397
}
398
}
399
400
void pure_interpreter(void)
401
{
402
stop=0;
403
PC = &interp_PC;
404
PC->addr = last_addr = 0xa4000040;
405
406
/*#ifdef DBG
407
if (g_DebuggerActive)
408
update_debugger(PC->addr);
409
#endif*/
410
411
current_instruction_table = pure_interpreter_table;
412
413
while (!stop)
414
{
415
prefetch();
416
#ifdef COMPARE_CORE
417
CoreCompareCallback();
418
#endif
419
#ifdef DBG
420
if (g_DebuggerActive) update_debugger(PC->addr, -1);
421
#endif
422
TRACECB();
423
PC->ops();
424
}
425
}
426
427