drc: fix JALR with non-r31 return register
[pcsx_rearmed.git] / libpcsxcore / new_dynarec / emu_if.c
... / ...
CommitLineData
1// pending_exception?
2// swi 0 in do_unalignedwritestub?
3#include <stdio.h>
4
5#include "emu_if.h"
6#include "../psxmem.h"
7#include "../psxhle.h"
8
9//#define memprintf printf
10#define memprintf(...)
11//#define evprintf printf
12#define evprintf(...)
13
14char invalid_code[0x100000];
15
16void MTC0_()
17{
18 extern void psxMTC0();
19
20 memprintf("ari64 MTC0 %08x\n", psxRegs.code);
21 psxMTC0();
22 pending_exception = 1; /* FIXME? */
23}
24
25void gen_interupt()
26{
27 evprintf("ari64_gen_interupt\n");
28 evprintf(" +ge %08x, %d->%d\n", psxRegs.pc, psxRegs.cycle, next_interupt);
29#ifdef DRC_DBG
30 psxRegs.cycle += 2;
31#endif
32
33 psxBranchTest();
34
35 next_interupt = psxNextsCounter + psxNextCounter;
36 evprintf(" -ge %08x, %d->%d\n", psxRegs.pc, psxRegs.cycle, next_interupt);
37
38 pending_exception = 1; /* FIXME */
39}
40
41void check_interupt()
42{
43 printf("ari64_check_interupt\n");
44}
45
46void read_nomem_new()
47{
48 printf("ari64_read_nomem_new\n");
49}
50
51static void read_mem8()
52{
53 memprintf("ari64_read_mem8 %08x, PC~=%08x\n", address, psxRegs.pc);
54 readmem_word = psxMemRead8(address) & 0xff;
55}
56
57static void read_mem16()
58{
59 memprintf("ari64_read_mem16 %08x, PC~=%08x\n", address, psxRegs.pc);
60 readmem_word = psxMemRead16(address) & 0xffff;
61}
62
63static void read_mem32()
64{
65 memprintf("ari64_read_mem32 %08x, PC~=%08x\n", address, psxRegs.pc);
66 readmem_word = psxMemRead32(address);
67}
68
69static void write_mem8()
70{
71 memprintf("ari64_write_mem8 %08x, %02x, PC~=%08x\n", address, byte, psxRegs.pc);
72 psxMemWrite8(address, byte);
73}
74
75static void write_mem16()
76{
77 memprintf("ari64_write_mem16 %08x, %04x, PC~=%08x\n", address, hword, psxRegs.pc);
78 psxMemWrite16(address, hword);
79}
80
81static void write_mem32()
82{
83 memprintf("ari64_write_mem32 %08x, %08x, PC~=%08x\n", address, word, psxRegs.pc);
84 psxMemWrite32(address, word);
85}
86
87void (*readmem[0x10000])();
88void (*readmemb[0x10000])();
89void (*readmemh[0x10000])();
90void (*writemem[0x10000])();
91void (*writememb[0x10000])();
92void (*writememh[0x10000])();
93
94void *gte_handlers[64];
95
96/* from gte.txt.. not sure if this is any good. */
97const char gte_cycletab[64] = {
98 /* 1 2 3 4 5 6 7 8 9 a b c d e f */
99 0, 15, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 6, 0, 0, 0,
100 8, 8, 8, 19, 13, 0, 44, 0, 0, 0, 0, 17, 11, 0, 14, 0,
101 30, 0, 0, 0, 0, 0, 0, 0, 5, 8, 17, 0, 0, 5, 6, 0,
102 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 39,
103};
104
105static int ari64_init()
106{
107 extern void (*psxCP2[64])();
108 extern void psxNULL();
109 size_t i;
110
111 new_dynarec_init();
112
113 for (i = 0; i < sizeof(readmem) / sizeof(readmem[0]); i++) {
114 readmemb[i] = read_mem8;
115 readmemh[i] = read_mem16;
116 readmem[i] = read_mem32;
117 writememb[i] = write_mem8;
118 writememh[i] = write_mem16;
119 writemem[i] = write_mem32;
120 }
121
122 for (i = 0; i < sizeof(gte_handlers) / sizeof(gte_handlers[0]); i++)
123 if (psxCP2[i] != psxNULL)
124 gte_handlers[i] = psxCP2[i];
125
126 return 0;
127}
128
129static void ari64_reset()
130{
131 /* hmh */
132 printf("ari64_reset\n");
133}
134
135static void ari64_execute()
136{
137 next_interupt = psxNextsCounter + psxNextCounter;
138
139 evprintf("psxNextsCounter %d, psxNextCounter %d\n", psxNextsCounter, psxNextCounter);
140 evprintf("ari64_execute %08x, %d->%d\n", psxRegs.pc, psxRegs.cycle, next_interupt);
141 new_dyna_start();
142 evprintf("ari64_execute end %08x, %d->%d\n", psxRegs.pc, psxRegs.cycle, next_interupt);
143}
144
145static void ari64_clear(u32 Addr, u32 Size)
146{
147}
148
149static void ari64_shutdown()
150{
151 new_dynarec_cleanup();
152}
153
154extern void intExecute();
155extern void intExecuteT();
156extern void intExecuteBlock();
157extern void intExecuteBlockT();
158#ifndef DRC_DBG
159#define intExecuteT intExecute
160#define intExecuteBlockT intExecuteBlock
161#endif
162
163R3000Acpu psxRec = {
164 ari64_init,
165 ari64_reset,
166#if 1
167 ari64_execute,
168 ari64_execute,
169#else
170 intExecuteT,
171 intExecuteBlockT,
172#endif
173 ari64_clear,
174 ari64_shutdown
175};
176
177// TODO: rm
178#ifndef DRC_DBG
179void do_insn_trace() {}
180void do_insn_cmp() {}
181#endif
182
183#if defined(__x86_64__) || defined(__i386__)
184unsigned int address, readmem_word, word;
185unsigned short hword;
186unsigned char byte;
187int pending_exception;
188unsigned int next_interupt;
189void new_dynarec_init() {}
190void new_dyna_start() {}
191void new_dynarec_cleanup() {}
192#endif
193
194#ifdef DRC_DBG
195
196#include <stddef.h>
197static FILE *f;
198extern u32 last_io_addr;
199
200static void dump_mem(const char *fname, void *mem, size_t size)
201{
202 FILE *f1 = fopen(fname, "wb");
203 if (f1 == NULL)
204 f1 = fopen(strrchr(fname, '/') + 1, "wb");
205 fwrite(mem, 1, size, f1);
206 fclose(f1);
207}
208
209void do_insn_trace(void)
210{
211 static psxRegisters oldregs;
212 static u32 old_io_addr = (u32)-1;
213 static u32 old_io_data = 0xbad0c0de;
214 u32 *allregs_p = (void *)&psxRegs;
215 u32 *allregs_o = (void *)&oldregs;
216 u32 *io_data;
217 int i;
218 u8 byte;
219
220//last_io_addr = 0x5e2c8;
221 if (f == NULL)
222 f = fopen("tracelog", "wb");
223
224 oldregs.code = psxRegs.code; // don't care
225 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
226 if (allregs_p[i] != allregs_o[i]) {
227 fwrite(&i, 1, 1, f);
228 fwrite(&allregs_p[i], 1, 4, f);
229 allregs_o[i] = allregs_p[i];
230 }
231 }
232 if (old_io_addr != last_io_addr) {
233 byte = 0xfd;
234 fwrite(&byte, 1, 1, f);
235 fwrite(&last_io_addr, 1, 4, f);
236 old_io_addr = last_io_addr;
237 }
238 io_data = (void *)(psxM + (last_io_addr&0x1ffffc));
239 if (old_io_data != *io_data) {
240 byte = 0xfe;
241 fwrite(&byte, 1, 1, f);
242 fwrite(io_data, 1, 4, f);
243 old_io_data = *io_data;
244 }
245 byte = 0xff;
246 fwrite(&byte, 1, 1, f);
247
248#if 0
249 if (psxRegs.cycle == 190230) {
250 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram_i.dump", psxM, 0x200000);
251 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs_i.dump", psxH, 0x10000);
252 printf("dumped\n");
253 exit(1);
254 }
255#endif
256}
257
258static const char *regnames[offsetof(psxRegisters, intCycle) / 4] = {
259 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
260 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
261 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
262 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
263 "lo", "hi",
264 "C0_0", "C0_1", "C0_2", "C0_3", "C0_4", "C0_5", "C0_6", "C0_7",
265 "C0_8", "C0_9", "C0_10", "C0_11", "C0_12", "C0_13", "C0_14", "C0_15",
266 "C0_16", "C0_17", "C0_18", "C0_19", "C0_20", "C0_21", "C0_22", "C0_23",
267 "C0_24", "C0_25", "C0_26", "C0_27", "C0_28", "C0_29", "C0_30", "C0_31",
268
269 "C2D0", "C2D1", "C2D2", "C2D3", "C2D4", "C2D5", "C2D6", "C2D7",
270 "C2D8", "C2D9", "C2D10", "C2D11", "C2D12", "C2D13", "C2D14", "C2D15",
271 "C2D16", "C2D17", "C2D18", "C2D19", "C2D20", "C2D21", "C2D22", "C2D23",
272 "C2D24", "C2D25", "C2D26", "C2D27", "C2D28", "C2D29", "C2D30", "C2D31",
273
274 "C2C0", "C2C1", "C2C2", "C2C3", "C2C4", "C2C5", "C2C6", "C2C7",
275 "C2C8", "C2C9", "C2C10", "C2C11", "C2C12", "C2C13", "C2C14", "C2C15",
276 "C2C16", "C2C17", "C2C18", "C2C19", "C2C20", "C2C21", "C2C22", "C2C23",
277 "C2C24", "C2C25", "C2C26", "C2C27", "C2C28", "C2C29", "C2C30", "C2C31",
278
279 "PC", "code", "cycle", "interrupt",
280};
281
282static struct {
283 int reg;
284 u32 val, val_expect;
285 u32 pc, cycle;
286} miss_log[64];
287static int miss_log_i;
288#define miss_log_len (sizeof(miss_log)/sizeof(miss_log[0]))
289#define miss_log_mask (miss_log_len-1)
290
291static void miss_log_add(int reg, u32 val, u32 val_expect, u32 pc, u32 cycle)
292{
293 miss_log[miss_log_i].reg = reg;
294 miss_log[miss_log_i].val = val;
295 miss_log[miss_log_i].val_expect = val_expect;
296 miss_log[miss_log_i].pc = pc;
297 miss_log[miss_log_i].cycle = cycle;
298 miss_log_i = (miss_log_i + 1) & miss_log_mask;
299}
300
301void breakme() {}
302
303void do_insn_cmp(void)
304{
305 static psxRegisters rregs;
306 static u32 mem_addr, mem_val;
307 u32 *allregs_p = (void *)&psxRegs;
308 u32 *allregs_e = (void *)&rregs;
309 static u32 ppc, failcount;
310 int i, ret, bad = 0;
311 u8 code;
312
313 if (f == NULL)
314 f = fopen("tracelog", "rb");
315
316 while (1) {
317 if ((ret = fread(&code, 1, 1, f)) <= 0)
318 break;
319 if (ret <= 0)
320 break;
321 if (code == 0xff)
322 break;
323 if (code == 0xfd) {
324 if ((ret = fread(&mem_addr, 1, 4, f)) <= 0)
325 break;
326 continue;
327 }
328 if (code == 0xfe) {
329 if ((ret = fread(&mem_val, 1, 4, f)) <= 0)
330 break;
331 continue;
332 }
333 if ((ret = fread(&allregs_e[code], 1, 4, f)) <= 0)
334 break;
335 }
336
337 if (ret <= 0) {
338 printf("EOF?\n");
339 goto end;
340 }
341
342 psxRegs.code = rregs.code; // don't care
343psxRegs.cycle = rregs.cycle;
344psxRegs.CP0.r[9] = rregs.CP0.r[9]; // Count
345
346//if (psxRegs.cycle == 166172) breakme();
347//if (psxRegs.cycle > 11296376) printf("pc=%08x %u %08x\n", psxRegs.pc, psxRegs.cycle, psxRegs.interrupt);
348
349 mem_addr &= 0x1ffffc;
350
351 if (memcmp(&psxRegs, &rregs, offsetof(psxRegisters, intCycle)) == 0 &&
352 mem_val == *(u32 *)(psxM + mem_addr)
353 ) {
354 failcount = 0;
355 goto ok;
356 }
357
358 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
359 if (allregs_p[i] != allregs_e[i]) {
360 miss_log_add(i, allregs_p[i], allregs_e[i], psxRegs.pc, psxRegs.cycle);
361 bad++;
362 }
363 }
364
365 if (mem_val != *(u32 *)(psxM + mem_addr)) {
366 printf("bad mem @%08x: %08x %08x\n", mem_addr, *(u32 *)(psxM + mem_addr), mem_val);
367 goto end;
368 }
369
370 if (psxRegs.pc == rregs.pc && bad < 6 && failcount < 32) {
371 static int last_mcycle;
372 if (last_mcycle != psxRegs.cycle >> 20) {
373 printf("%u\n", psxRegs.cycle);
374 last_mcycle = psxRegs.cycle >> 20;
375 }
376 failcount++;
377 goto ok;
378 }
379
380end:
381 for (i = 0; i < miss_log_len; i++, miss_log_i = (miss_log_i + 1) & miss_log_mask)
382 printf("bad %5s: %08x %08x, pc=%08x, cycle %u\n",
383 regnames[miss_log[miss_log_i].reg], miss_log[miss_log_i].val,
384 miss_log[miss_log_i].val_expect, miss_log[miss_log_i].pc, miss_log[miss_log_i].cycle);
385 printf("-- %d\n", bad);
386 for (i = 0; i < 8; i++)
387 printf("r%d=%08x r%2d=%08x r%2d=%08x r%2d=%08x\n", i, allregs_p[i],
388 i+8, allregs_p[i+8], i+16, allregs_p[i+16], i+24, allregs_p[i+23]);
389 printf("PC: %08x/%08x, cycle %u\n", psxRegs.pc, ppc, psxRegs.cycle);
390 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram.dump", psxM, 0x200000);
391 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs.dump", psxH, 0x10000);
392 exit(1);
393ok:
394 psxRegs.cycle = rregs.cycle + 2; // sync timing
395 ppc = psxRegs.pc;
396}
397
398#endif