ALL: Huge upstream synch + PerRom DelaySI & CountPerOp parameters
[mupen64plus-pandora.git] / source / mupen64plus-core / src / r4300 / x86 / gr4300.c
CommitLineData
451ab91e 1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Mupen64plus - gr4300.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 "assemble.h"
23#include "interpret.h"
24#include "regcache.h"
25
26#include "api/debugger.h"
27
28#include "r4300/r4300.h"
29#include "r4300/macros.h"
30#include "r4300/interupt.h"
31#include "r4300/ops.h"
32#include "r4300/recomph.h"
33#include "r4300/exception.h"
34
35#include "memory/memory.h"
36
37extern unsigned int op;
38
39static precomp_instr fake_instr;
40#ifdef COMPARE_CORE
41static int eax, ebx, ecx, edx, esp, ebp, esi, edi;
42#endif
43
44int branch_taken;
45
46/* static functions */
47
48static void genupdate_count(unsigned int addr)
49{
2d262872 50#if !defined(COMPARE_CORE) && !defined(DBG)
451ab91e 51 mov_reg32_imm32(EAX, addr);
52 sub_reg32_m32(EAX, (unsigned int*)(&last_addr));
2d262872 53 shr_reg32_imm8(EAX, 2);
54 mov_reg32_m32(EDX, &count_per_op);
55 mul_reg32(EDX);
451ab91e 56 add_m32_reg32((unsigned int*)(&Count), EAX);
57#else
58 mov_m32_imm32((unsigned int*)(&PC), (unsigned int)(dst+1));
59 mov_reg32_imm32(EAX, (unsigned int)update_count);
60 call_reg32(EAX);
61#endif
451ab91e 62}
63
64static void gencheck_interupt(unsigned int instr_structure)
65{
66 mov_eax_memoffs32(&next_interupt);
67 cmp_reg32_m32(EAX, &Count);
68 ja_rj(17);
69 mov_m32_imm32((unsigned int*)(&PC), instr_structure); // 10
70 mov_reg32_imm32(EAX, (unsigned int)gen_interupt); // 5
71 call_reg32(EAX); // 2
72}
73
74static void gencheck_interupt_out(unsigned int addr)
75{
76 mov_eax_memoffs32(&next_interupt);
77 cmp_reg32_m32(EAX, &Count);
78 ja_rj(27);
79 mov_m32_imm32((unsigned int*)(&fake_instr.addr), addr);
80 mov_m32_imm32((unsigned int*)(&PC), (unsigned int)(&fake_instr));
81 mov_reg32_imm32(EAX, (unsigned int)gen_interupt);
82 call_reg32(EAX);
83}
84
85static void genbeq_test(void)
86{
87 int rs_64bit = is64((unsigned int *)dst->f.i.rs);
88 int rt_64bit = is64((unsigned int *)dst->f.i.rt);
89
90 if (!rs_64bit && !rt_64bit)
91 {
92 int rs = allocate_register((unsigned int *)dst->f.i.rs);
93 int rt = allocate_register((unsigned int *)dst->f.i.rt);
94
95 cmp_reg32_reg32(rs, rt);
96 jne_rj(12);
97 mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10
98 jmp_imm_short(10); // 2
99 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10
100 }
101 else if (rs_64bit == -1)
102 {
103 int rt1 = allocate_64_register1((unsigned int *)dst->f.i.rt);
104 int rt2 = allocate_64_register2((unsigned int *)dst->f.i.rt);
105
106 cmp_reg32_m32(rt1, (unsigned int *)dst->f.i.rs);
107 jne_rj(20);
108 cmp_reg32_m32(rt2, ((unsigned int *)dst->f.i.rs)+1); // 6
109 jne_rj(12); // 2
110 mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10
111 jmp_imm_short(10); // 2
112 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10
113 }
114 else if (rt_64bit == -1)
115 {
116 int rs1 = allocate_64_register1((unsigned int *)dst->f.i.rs);
117 int rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs);
118
119 cmp_reg32_m32(rs1, (unsigned int *)dst->f.i.rt);
120 jne_rj(20);
121 cmp_reg32_m32(rs2, ((unsigned int *)dst->f.i.rt)+1); // 6
122 jne_rj(12); // 2
123 mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10
124 jmp_imm_short(10); // 2
125 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10
126 }
127 else
128 {
129 int rs1, rs2, rt1, rt2;
130 if (!rs_64bit)
131 {
132 rt1 = allocate_64_register1((unsigned int *)dst->f.i.rt);
133 rt2 = allocate_64_register2((unsigned int *)dst->f.i.rt);
134 rs1 = allocate_64_register1((unsigned int *)dst->f.i.rs);
135 rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs);
136 }
137 else
138 {
139 rs1 = allocate_64_register1((unsigned int *)dst->f.i.rs);
140 rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs);
141 rt1 = allocate_64_register1((unsigned int *)dst->f.i.rt);
142 rt2 = allocate_64_register2((unsigned int *)dst->f.i.rt);
143 }
144 cmp_reg32_reg32(rs1, rt1);
145 jne_rj(16);
146 cmp_reg32_reg32(rs2, rt2); // 2
147 jne_rj(12); // 2
148 mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10
149 jmp_imm_short(10); // 2
150 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10
151 }
152}
153
154static void genbne_test(void)
155{
156 int rs_64bit = is64((unsigned int *)dst->f.i.rs);
157 int rt_64bit = is64((unsigned int *)dst->f.i.rt);
158
159 if (!rs_64bit && !rt_64bit)
160 {
161 int rs = allocate_register((unsigned int *)dst->f.i.rs);
162 int rt = allocate_register((unsigned int *)dst->f.i.rt);
163
164 cmp_reg32_reg32(rs, rt);
165 je_rj(12);
166 mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10
167 jmp_imm_short(10); // 2
168 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10
169 }
170 else if (rs_64bit == -1)
171 {
172 int rt1 = allocate_64_register1((unsigned int *)dst->f.i.rt);
173 int rt2 = allocate_64_register2((unsigned int *)dst->f.i.rt);
174
175 cmp_reg32_m32(rt1, (unsigned int *)dst->f.i.rs);
176 jne_rj(20);
177 cmp_reg32_m32(rt2, ((unsigned int *)dst->f.i.rs)+1); // 6
178 jne_rj(12); // 2
179 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10
180 jmp_imm_short(10); // 2
181 mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10
182 }
183 else if (rt_64bit == -1)
184 {
185 int rs1 = allocate_64_register1((unsigned int *)dst->f.i.rs);
186 int rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs);
187
188 cmp_reg32_m32(rs1, (unsigned int *)dst->f.i.rt);
189 jne_rj(20);
190 cmp_reg32_m32(rs2, ((unsigned int *)dst->f.i.rt)+1); // 6
191 jne_rj(12); // 2
192 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10
193 jmp_imm_short(10); // 2
194 mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10
195 }
196 else
197 {
198 int rs1, rs2, rt1, rt2;
199 if (!rs_64bit)
200 {
201 rt1 = allocate_64_register1((unsigned int *)dst->f.i.rt);
202 rt2 = allocate_64_register2((unsigned int *)dst->f.i.rt);
203 rs1 = allocate_64_register1((unsigned int *)dst->f.i.rs);
204 rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs);
205 }
206 else
207 {
208 rs1 = allocate_64_register1((unsigned int *)dst->f.i.rs);
209 rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs);
210 rt1 = allocate_64_register1((unsigned int *)dst->f.i.rt);
211 rt2 = allocate_64_register2((unsigned int *)dst->f.i.rt);
212 }
213 cmp_reg32_reg32(rs1, rt1);
214 jne_rj(16);
215 cmp_reg32_reg32(rs2, rt2); // 2
216 jne_rj(12); // 2
217 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10
218 jmp_imm_short(10); // 2
219 mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10
220 }
221}
222
223static void genblez_test(void)
224{
225 int rs_64bit = is64((unsigned int *)dst->f.i.rs);
226
227 if (!rs_64bit)
228 {
229 int rs = allocate_register((unsigned int *)dst->f.i.rs);
230
231 cmp_reg32_imm32(rs, 0);
232 jg_rj(12);
233 mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10
234 jmp_imm_short(10); // 2
235 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10
236 }
237 else if (rs_64bit == -1)
238 {
239 cmp_m32_imm32(((unsigned int *)dst->f.i.rs)+1, 0);
240 jg_rj(14);
241 jne_rj(24); // 2
242 cmp_m32_imm32((unsigned int *)dst->f.i.rs, 0); // 10
243 je_rj(12); // 2
244 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10
245 jmp_imm_short(10); // 2
246 mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10
247 }
248 else
249 {
250 int rs1 = allocate_64_register1((unsigned int *)dst->f.i.rs);
251 int rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs);
252
253 cmp_reg32_imm32(rs2, 0);
254 jg_rj(10);
255 jne_rj(20); // 2
256 cmp_reg32_imm32(rs1, 0); // 6
257 je_rj(12); // 2
258 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10
259 jmp_imm_short(10); // 2
260 mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10
261 }
262}
263
264static void genbgtz_test(void)
265{
266 int rs_64bit = is64((unsigned int *)dst->f.i.rs);
267
268 if (!rs_64bit)
269 {
270 int rs = allocate_register((unsigned int *)dst->f.i.rs);
271
272 cmp_reg32_imm32(rs, 0);
273 jle_rj(12);
274 mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10
275 jmp_imm_short(10); // 2
276 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10
277 }
278 else if (rs_64bit == -1)
279 {
280 cmp_m32_imm32(((unsigned int *)dst->f.i.rs)+1, 0);
281 jl_rj(14);
282 jne_rj(24); // 2
283 cmp_m32_imm32((unsigned int *)dst->f.i.rs, 0); // 10
284 jne_rj(12); // 2
285 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10
286 jmp_imm_short(10); // 2
287 mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10
288 }
289 else
290 {
291 int rs1 = allocate_64_register1((unsigned int *)dst->f.i.rs);
292 int rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs);
293
294 cmp_reg32_imm32(rs2, 0);
295 jl_rj(10);
296 jne_rj(20); // 2
297 cmp_reg32_imm32(rs1, 0); // 6
298 jne_rj(12); // 2
299 mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10
300 jmp_imm_short(10); // 2
301 mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10
302 }
303}
304
305
306/* global functions */
307
308void gennotcompiled(void)
309{
310 free_all_registers();
311 simplify_access();
312
313 mov_m32_imm32((unsigned int*)(&PC), (unsigned int)(dst));
314 mov_reg32_imm32(EAX, (unsigned int)cached_interpreter_table.NOTCOMPILED);
315 call_reg32(EAX);
316}
317
318void genlink_subblock(void)
319{
320 free_all_registers();
321 jmp(dst->addr+4);
322}
323
324#ifdef COMPARE_CORE
325void gendebug(void)
326{
327 free_all_registers();
328 mov_m32_reg32((unsigned int*)&eax, EAX);
329 mov_m32_reg32((unsigned int*)&ebx, EBX);
330 mov_m32_reg32((unsigned int*)&ecx, ECX);
331 mov_m32_reg32((unsigned int*)&edx, EDX);
332 mov_m32_reg32((unsigned int*)&esp, ESP);
333 mov_m32_reg32((unsigned int*)&ebp, EBP);
334 mov_m32_reg32((unsigned int*)&esi, ESI);
335 mov_m32_reg32((unsigned int*)&edi, EDI);
336
337 mov_m32_imm32((unsigned int*)(&PC), (unsigned int)(dst));
338 mov_m32_imm32((unsigned int*)(&op), (unsigned int)(src));
339 mov_reg32_imm32(EAX, (unsigned int) CoreCompareCallback);
340 call_reg32(EAX);
341
342 mov_reg32_m32(EAX, (unsigned int*)&eax);
343 mov_reg32_m32(EBX, (unsigned int*)&ebx);
344 mov_reg32_m32(ECX, (unsigned int*)&ecx);
345 mov_reg32_m32(EDX, (unsigned int*)&edx);
346 mov_reg32_m32(ESP, (unsigned int*)&esp);
347 mov_reg32_m32(EBP, (unsigned int*)&ebp);
348 mov_reg32_m32(ESI, (unsigned int*)&esi);
349 mov_reg32_m32(EDI, (unsigned int*)&edi);
350}
351#endif
352
353void gencallinterp(unsigned long addr, int jump)
354{
355 free_all_registers();
356 simplify_access();
357 if (jump)
358 mov_m32_imm32((unsigned int*)(&dyna_interp), 1);
359 mov_m32_imm32((unsigned int*)(&PC), (unsigned int)(dst));
360 mov_reg32_imm32(EAX, addr);
361 call_reg32(EAX);
362 if (jump)
363 {
364 mov_m32_imm32((unsigned int*)(&dyna_interp), 0);
365 mov_reg32_imm32(EAX, (unsigned int)dyna_jump);
366 call_reg32(EAX);
367 }
368}
369
370void gendelayslot(void)
371{
372 mov_m32_imm32(&delay_slot, 1);
373 recompile_opcode();
374
375 free_all_registers();
376 genupdate_count(dst->addr+4);
377
378 mov_m32_imm32(&delay_slot, 0);
379}
380
381void genni(void)
382{
383 gencallinterp((unsigned int)cached_interpreter_table.NI, 0);
384}
385
386void genreserved(void)
387{
388 gencallinterp((unsigned int)cached_interpreter_table.RESERVED, 0);
389}
390
391void genfin_block(void)
392{
393 gencallinterp((unsigned int)cached_interpreter_table.FIN_BLOCK, 0);
394}
395
396void gencheck_interupt_reg(void) // addr is in EAX
397{
398 mov_reg32_m32(EBX, &next_interupt);
399 cmp_reg32_m32(EBX, &Count);
400 ja_rj(22);
401 mov_memoffs32_eax((unsigned int*)(&fake_instr.addr)); // 5
402 mov_m32_imm32((unsigned int*)(&PC), (unsigned int)(&fake_instr)); // 10
403 mov_reg32_imm32(EAX, (unsigned int)gen_interupt); // 5
404 call_reg32(EAX); // 2
405}
406
407void gennop(void)
408{
409}
410
411void genj(void)
412{
413#ifdef INTERPRET_J
414 gencallinterp((unsigned int)cached_interpreter_table.J, 1);
415#else
416 unsigned int naddr;
417
418 if (((dst->addr & 0xFFF) == 0xFFC &&
419 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
420 {
421 gencallinterp((unsigned int)cached_interpreter_table.J, 1);
422 return;
423 }
424
425 gendelayslot();
426 naddr = ((dst-1)->f.j.inst_index<<2) | (dst->addr & 0xF0000000);
427
428 mov_m32_imm32(&last_addr, naddr);
429 gencheck_interupt((unsigned int)&actual->block[(naddr-actual->start)/4]);
430 jmp(naddr);
431#endif
432}
433
434void genj_out(void)
435{
436#ifdef INTERPRET_J_OUT
437 gencallinterp((unsigned int)cached_interpreter_table.J_OUT, 1);
438#else
439 unsigned int naddr;
440
441 if (((dst->addr & 0xFFF) == 0xFFC &&
442 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
443 {
444 gencallinterp((unsigned int)cached_interpreter_table.J_OUT, 1);
445 return;
446 }
447
448 gendelayslot();
449 naddr = ((dst-1)->f.j.inst_index<<2) | (dst->addr & 0xF0000000);
450
451 mov_m32_imm32(&last_addr, naddr);
452 gencheck_interupt_out(naddr);
453 mov_m32_imm32(&jump_to_address, naddr);
454 mov_m32_imm32((unsigned int*)(&PC), (unsigned int)(dst+1));
455 mov_reg32_imm32(EAX, (unsigned int)jump_to_func);
456 call_reg32(EAX);
457#endif
458}
459
460void genj_idle(void)
461{
462#ifdef INTERPRET_J_IDLE
463 gencallinterp((unsigned int)cached_interpreter_table.J_IDLE, 1);
464#else
465 if (((dst->addr & 0xFFF) == 0xFFC &&
466 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
467 {
468 gencallinterp((unsigned int)cached_interpreter_table.J_IDLE, 1);
469 return;
470 }
471
472 mov_eax_memoffs32((unsigned int *)(&next_interupt));
473 sub_reg32_m32(EAX, (unsigned int *)(&Count));
474 cmp_reg32_imm8(EAX, 3);
475 jbe_rj(11);
476
477 and_eax_imm32(0xFFFFFFFC); // 5
478 add_m32_reg32((unsigned int *)(&Count), EAX); // 6
479
480 genj();
481#endif
482}
483
484void genjal(void)
485{
486#ifdef INTERPRET_JAL
487 gencallinterp((unsigned int)cached_interpreter_table.JAL, 1);
488#else
489 unsigned int naddr;
490
491 if (((dst->addr & 0xFFF) == 0xFFC &&
492 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
493 {
494 gencallinterp((unsigned int)cached_interpreter_table.JAL, 1);
495 return;
496 }
497
498 gendelayslot();
499
500 mov_m32_imm32((unsigned int *)(reg + 31), dst->addr + 4);
501 if (((dst->addr + 4) & 0x80000000))
502 mov_m32_imm32((unsigned int *)(&reg[31])+1, 0xFFFFFFFF);
503 else
504 mov_m32_imm32((unsigned int *)(&reg[31])+1, 0);
505
506 naddr = ((dst-1)->f.j.inst_index<<2) | (dst->addr & 0xF0000000);
507
508 mov_m32_imm32(&last_addr, naddr);
509 gencheck_interupt((unsigned int)&actual->block[(naddr-actual->start)/4]);
510 jmp(naddr);
511#endif
512}
513
514void genjal_out(void)
515{
516#ifdef INTERPRET_JAL_OUT
517 gencallinterp((unsigned int)cached_interpreter_table.JAL_OUT, 1);
518#else
519 unsigned int naddr;
520
521 if (((dst->addr & 0xFFF) == 0xFFC &&
522 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
523 {
524 gencallinterp((unsigned int)cached_interpreter_table.JAL_OUT, 1);
525 return;
526 }
527
528 gendelayslot();
529
530 mov_m32_imm32((unsigned int *)(reg + 31), dst->addr + 4);
531 if (((dst->addr + 4) & 0x80000000))
532 mov_m32_imm32((unsigned int *)(&reg[31])+1, 0xFFFFFFFF);
533 else
534 mov_m32_imm32((unsigned int *)(&reg[31])+1, 0);
535
536 naddr = ((dst-1)->f.j.inst_index<<2) | (dst->addr & 0xF0000000);
537
538 mov_m32_imm32(&last_addr, naddr);
539 gencheck_interupt_out(naddr);
540 mov_m32_imm32(&jump_to_address, naddr);
541 mov_m32_imm32((unsigned int*)(&PC), (unsigned int)(dst+1));
542 mov_reg32_imm32(EAX, (unsigned int)jump_to_func);
543 call_reg32(EAX);
544#endif
545}
546
547void genjal_idle(void)
548{
549#ifdef INTERPRET_JAL_IDLE
550 gencallinterp((unsigned int)cached_interpreter_table.JAL_IDLE, 1);
551#else
552 if (((dst->addr & 0xFFF) == 0xFFC &&
553 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
554 {
555 gencallinterp((unsigned int)cached_interpreter_table.JAL_IDLE, 1);
556 return;
557 }
558
559 mov_eax_memoffs32((unsigned int *)(&next_interupt));
560 sub_reg32_m32(EAX, (unsigned int *)(&Count));
561 cmp_reg32_imm8(EAX, 3);
562 jbe_rj(11);
563
564 and_eax_imm32(0xFFFFFFFC);
565 add_m32_reg32((unsigned int *)(&Count), EAX);
566
567 genjal();
568#endif
569}
570
571void gentest(void)
572{
573 cmp_m32_imm32((unsigned int *)(&branch_taken), 0);
574 je_near_rj(0);
575
576 jump_start_rel32();
577
578 mov_m32_imm32(&last_addr, dst->addr + (dst-1)->f.i.immediate*4);
579 gencheck_interupt((unsigned int)(dst + (dst-1)->f.i.immediate));
580 jmp(dst->addr + (dst-1)->f.i.immediate*4);
581
582 jump_end_rel32();
583
584 mov_m32_imm32(&last_addr, dst->addr + 4);
585 gencheck_interupt((unsigned int)(dst + 1));
586 jmp(dst->addr + 4);
587}
588
589void genbeq(void)
590{
591#ifdef INTERPRET_BEQ
592 gencallinterp((unsigned int)cached_interpreter_table.BEQ, 1);
593#else
594 if (((dst->addr & 0xFFF) == 0xFFC &&
595 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
596 {
597 gencallinterp((unsigned int)cached_interpreter_table.BEQ, 1);
598 return;
599 }
600
601 genbeq_test();
602 gendelayslot();
603 gentest();
604#endif
605}
606
607void gentest_out(void)
608{
609 cmp_m32_imm32((unsigned int *)(&branch_taken), 0);
610 je_near_rj(0);
611
612 jump_start_rel32();
613
614 mov_m32_imm32(&last_addr, dst->addr + (dst-1)->f.i.immediate*4);
615 gencheck_interupt_out(dst->addr + (dst-1)->f.i.immediate*4);
616 mov_m32_imm32(&jump_to_address, dst->addr + (dst-1)->f.i.immediate*4);
617 mov_m32_imm32((unsigned int*)(&PC), (unsigned int)(dst+1));
618 mov_reg32_imm32(EAX, (unsigned int)jump_to_func);
619 call_reg32(EAX);
620
621 jump_end_rel32();
622
623 mov_m32_imm32(&last_addr, dst->addr + 4);
624 gencheck_interupt((unsigned int)(dst + 1));
625 jmp(dst->addr + 4);
626}
627
628void genbeq_out(void)
629{
630#ifdef INTERPRET_BEQ_OUT
631 gencallinterp((unsigned int)cached_interpreter_table.BEQ_OUT, 1);
632#else
633 if (((dst->addr & 0xFFF) == 0xFFC &&
634 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
635 {
636 gencallinterp((unsigned int)cached_interpreter_table.BEQ_OUT, 1);
637 return;
638 }
639
640 genbeq_test();
641 gendelayslot();
642 gentest_out();
643#endif
644}
645
646void gentest_idle(void)
647{
648 int reg;
649
650 reg = lru_register();
651 free_register(reg);
652
653 cmp_m32_imm32((unsigned int *)(&branch_taken), 0);
654 je_near_rj(0);
655
656 jump_start_rel32();
657
658 mov_reg32_m32(reg, (unsigned int *)(&next_interupt));
659 sub_reg32_m32(reg, (unsigned int *)(&Count));
660 cmp_reg32_imm8(reg, 5);
661 jbe_rj(18);
662
663 sub_reg32_imm32(reg, 2); // 6
664 and_reg32_imm32(reg, 0xFFFFFFFC); // 6
665 add_m32_reg32((unsigned int *)(&Count), reg); // 6
666
667 jump_end_rel32();
668}
669
670void genbeq_idle(void)
671{
672#ifdef INTERPRET_BEQ_IDLE
673 gencallinterp((unsigned int)cached_interpreter_table.BEQ_IDLE, 1);
674#else
675 if (((dst->addr & 0xFFF) == 0xFFC &&
676 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
677 {
678 gencallinterp((unsigned int)cached_interpreter_table.BEQ_IDLE, 1);
679 return;
680 }
681
682 genbeq_test();
683 gentest_idle();
684 genbeq();
685#endif
686}
687
688void genbne(void)
689{
690#ifdef INTERPRET_BNE
691 gencallinterp((unsigned int)cached_interpreter_table.BNE, 1);
692#else
693 if (((dst->addr & 0xFFF) == 0xFFC &&
694 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
695 {
696 gencallinterp((unsigned int)cached_interpreter_table.BNE, 1);
697 return;
698 }
699
700 genbne_test();
701 gendelayslot();
702 gentest();
703#endif
704}
705
706void genbne_out(void)
707{
708#ifdef INTERPRET_BNE_OUT
709 gencallinterp((unsigned int)cached_interpreter_table.BNE_OUT, 1);
710#else
711 if (((dst->addr & 0xFFF) == 0xFFC &&
712 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
713 {
714 gencallinterp((unsigned int)cached_interpreter_table.BNE_OUT, 1);
715 return;
716 }
717
718 genbne_test();
719 gendelayslot();
720 gentest_out();
721#endif
722}
723
724void genbne_idle(void)
725{
726#ifdef INTERPRET_BNE_IDLE
727 gencallinterp((unsigned int)cached_interpreter_table.BNE_IDLE, 1);
728#else
729 if (((dst->addr & 0xFFF) == 0xFFC &&
730 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
731 {
732 gencallinterp((unsigned int)cached_interpreter_table.BNE_IDLE, 1);
733 return;
734 }
735
736 genbne_test();
737 gentest_idle();
738 genbne();
739#endif
740}
741
742void genblez(void)
743{
744#ifdef INTERPRET_BLEZ
745 gencallinterp((unsigned int)cached_interpreter_table.BLEZ, 1);
746#else
747 if (((dst->addr & 0xFFF) == 0xFFC &&
748 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
749 {
750 gencallinterp((unsigned int)cached_interpreter_table.BLEZ, 1);
751 return;
752 }
753
754 genblez_test();
755 gendelayslot();
756 gentest();
757#endif
758}
759
760void genblez_out(void)
761{
762#ifdef INTERPRET_BLEZ_OUT
763 gencallinterp((unsigned int)cached_interpreter_table.BLEZ_OUT, 1);
764#else
765 if (((dst->addr & 0xFFF) == 0xFFC &&
766 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
767 {
768 gencallinterp((unsigned int)cached_interpreter_table.BLEZ_OUT, 1);
769 return;
770 }
771
772 genblez_test();
773 gendelayslot();
774 gentest_out();
775#endif
776}
777
778void genblez_idle(void)
779{
780#ifdef INTERPRET_BLEZ_IDLE
781 gencallinterp((unsigned int)cached_interpreter_table.BLEZ_IDLE, 1);
782#else
783 if (((dst->addr & 0xFFF) == 0xFFC &&
784 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
785 {
786 gencallinterp((unsigned int)cached_interpreter_table.BLEZ_IDLE, 1);
787 return;
788 }
789
790 genblez_test();
791 gentest_idle();
792 genblez();
793#endif
794}
795
796void genbgtz(void)
797{
798#ifdef INTERPRET_BGTZ
799 gencallinterp((unsigned int)cached_interpreter_table.BGTZ, 1);
800#else
801 if (((dst->addr & 0xFFF) == 0xFFC &&
802 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
803 {
804 gencallinterp((unsigned int)cached_interpreter_table.BGTZ, 1);
805 return;
806 }
807
808 genbgtz_test();
809 gendelayslot();
810 gentest();
811#endif
812}
813
814void genbgtz_out(void)
815{
816#ifdef INTERPRET_BGTZ_OUT
817 gencallinterp((unsigned int)cached_interpreter_table.BGTZ_OUT, 1);
818#else
819 if (((dst->addr & 0xFFF) == 0xFFC &&
820 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
821 {
822 gencallinterp((unsigned int)cached_interpreter_table.BGTZ_OUT, 1);
823 return;
824 }
825
826 genbgtz_test();
827 gendelayslot();
828 gentest_out();
829#endif
830}
831
832void genbgtz_idle(void)
833{
834#ifdef INTERPRET_BGTZ_IDLE
835 gencallinterp((unsigned int)cached_interpreter_table.BGTZ_IDLE, 1);
836#else
837 if (((dst->addr & 0xFFF) == 0xFFC &&
838 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
839 {
840 gencallinterp((unsigned int)cached_interpreter_table.BGTZ_IDLE, 1);
841 return;
842 }
843
844 genbgtz_test();
845 gentest_idle();
846 genbgtz();
847#endif
848}
849
850void genaddi(void)
851{
852#ifdef INTERPRET_ADDI
853 gencallinterp((unsigned int)cached_interpreter_table.ADDI, 0);
854#else
855 int rs = allocate_register((unsigned int *)dst->f.i.rs);
856 int rt = allocate_register_w((unsigned int *)dst->f.i.rt);
857
858 mov_reg32_reg32(rt, rs);
859 add_reg32_imm32(rt,(int)dst->f.i.immediate);
860#endif
861}
862
863void genaddiu(void)
864{
865#ifdef INTERPRET_ADDIU
866 gencallinterp((unsigned int)cached_interpreter_table.ADDIU, 0);
867#else
868 int rs = allocate_register((unsigned int *)dst->f.i.rs);
869 int rt = allocate_register_w((unsigned int *)dst->f.i.rt);
870
871 mov_reg32_reg32(rt, rs);
872 add_reg32_imm32(rt,(int)dst->f.i.immediate);
873#endif
874}
875
876void genslti(void)
877{
878#ifdef INTERPRET_SLTI
879 gencallinterp((unsigned int)cached_interpreter_table.SLTI, 0);
880#else
881 int rs1 = allocate_64_register1((unsigned int *)dst->f.i.rs);
882 int rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs);
883 int rt = allocate_register_w((unsigned int *)dst->f.i.rt);
884 long long imm = (long long)dst->f.i.immediate;
885
886 cmp_reg32_imm32(rs2, (unsigned int)(imm >> 32));
887 jl_rj(17);
888 jne_rj(8); // 2
889 cmp_reg32_imm32(rs1, (unsigned int)imm); // 6
890 jl_rj(7); // 2
891 mov_reg32_imm32(rt, 0); // 5
892 jmp_imm_short(5); // 2
893 mov_reg32_imm32(rt, 1); // 5
894#endif
895}
896
897void gensltiu(void)
898{
899#ifdef INTERPRET_SLTIU
900 gencallinterp((unsigned int)cached_interpreter_table.SLTIU, 0);
901#else
902 int rs1 = allocate_64_register1((unsigned int *)dst->f.i.rs);
903 int rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs);
904 int rt = allocate_register_w((unsigned int *)dst->f.i.rt);
905 long long imm = (long long)dst->f.i.immediate;
906
907 cmp_reg32_imm32(rs2, (unsigned int)(imm >> 32));
908 jb_rj(17);
909 jne_rj(8); // 2
910 cmp_reg32_imm32(rs1, (unsigned int)imm); // 6
911 jb_rj(7); // 2
912 mov_reg32_imm32(rt, 0); // 5
913 jmp_imm_short(5); // 2
914 mov_reg32_imm32(rt, 1); // 5
915#endif
916}
917
918void genandi(void)
919{
920#ifdef INTERPRET_ANDI
921 gencallinterp((unsigned int)cached_interpreter_table.ANDI, 0);
922#else
923 int rs = allocate_register((unsigned int *)dst->f.i.rs);
924 int rt = allocate_register_w((unsigned int *)dst->f.i.rt);
925
926 mov_reg32_reg32(rt, rs);
927 and_reg32_imm32(rt, (unsigned short)dst->f.i.immediate);
928#endif
929}
930
931void genori(void)
932{
933#ifdef INTERPRET_ORI
934 gencallinterp((unsigned int)cached_interpreter_table.ORI, 0);
935#else
936 int rs1 = allocate_64_register1((unsigned int *)dst->f.i.rs);
937 int rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs);
938 int rt1 = allocate_64_register1_w((unsigned int *)dst->f.i.rt);
939 int rt2 = allocate_64_register2_w((unsigned int *)dst->f.i.rt);
940
941 mov_reg32_reg32(rt1, rs1);
942 mov_reg32_reg32(rt2, rs2);
943 or_reg32_imm32(rt1, (unsigned short)dst->f.i.immediate);
944#endif
945}
946
947void genxori(void)
948{
949#ifdef INTERPRET_XORI
950 gencallinterp((unsigned int)cached_interpreter_table.XORI, 0);
951#else
952 int rs1 = allocate_64_register1((unsigned int *)dst->f.i.rs);
953 int rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs);
954 int rt1 = allocate_64_register1_w((unsigned int *)dst->f.i.rt);
955 int rt2 = allocate_64_register2_w((unsigned int *)dst->f.i.rt);
956
957 mov_reg32_reg32(rt1, rs1);
958 mov_reg32_reg32(rt2, rs2);
959 xor_reg32_imm32(rt1, (unsigned short)dst->f.i.immediate);
960#endif
961}
962
963void genlui(void)
964{
965#ifdef INTERPRET_LUI
966 gencallinterp((unsigned int)cached_interpreter_table.LUI, 0);
967#else
968 int rt = allocate_register_w((unsigned int *)dst->f.i.rt);
969
970 mov_reg32_imm32(rt, (unsigned int)dst->f.i.immediate << 16);
971#endif
972}
973
974void gentestl(void)
975{
976 cmp_m32_imm32((unsigned int *)(&branch_taken), 0);
977 je_near_rj(0);
978
979 jump_start_rel32();
980
981 gendelayslot();
982 mov_m32_imm32(&last_addr, dst->addr + (dst-1)->f.i.immediate*4);
983 gencheck_interupt((unsigned int)(dst + (dst-1)->f.i.immediate));
984 jmp(dst->addr + (dst-1)->f.i.immediate*4);
985
986 jump_end_rel32();
987
988 genupdate_count(dst->addr+4);
989 mov_m32_imm32(&last_addr, dst->addr + 4);
990 gencheck_interupt((unsigned int)(dst + 1));
991 jmp(dst->addr + 4);
992}
993
994void genbeql(void)
995{
996#ifdef INTERPRET_BEQL
997 gencallinterp((unsigned int)cached_interpreter_table.BEQL, 1);
998#else
999 if (((dst->addr & 0xFFF) == 0xFFC &&
1000 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
1001 {
1002 gencallinterp((unsigned int)cached_interpreter_table.BEQL, 1);
1003 return;
1004 }
1005
1006 genbeq_test();
1007 free_all_registers();
1008 gentestl();
1009#endif
1010}
1011
1012void gentestl_out(void)
1013{
1014 cmp_m32_imm32((unsigned int *)(&branch_taken), 0);
1015 je_near_rj(0);
1016
1017 jump_start_rel32();
1018
1019 gendelayslot();
1020 mov_m32_imm32(&last_addr, dst->addr + (dst-1)->f.i.immediate*4);
1021 gencheck_interupt_out(dst->addr + (dst-1)->f.i.immediate*4);
1022 mov_m32_imm32(&jump_to_address, dst->addr + (dst-1)->f.i.immediate*4);
1023 mov_m32_imm32((unsigned int*)(&PC), (unsigned int)(dst+1));
1024 mov_reg32_imm32(EAX, (unsigned int)jump_to_func);
1025 call_reg32(EAX);
1026
1027 jump_end_rel32();
1028
1029 genupdate_count(dst->addr+4);
1030 mov_m32_imm32(&last_addr, dst->addr + 4);
1031 gencheck_interupt((unsigned int)(dst + 1));
1032 jmp(dst->addr + 4);
1033}
1034
1035void genbeql_out(void)
1036{
1037#ifdef INTERPRET_BEQL_OUT
1038 gencallinterp((unsigned int)cached_interpreter_table.BEQL_OUT, 1);
1039#else
1040 if (((dst->addr & 0xFFF) == 0xFFC &&
1041 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
1042 {
1043 gencallinterp((unsigned int)cached_interpreter_table.BEQL_OUT, 1);
1044 return;
1045 }
1046
1047 genbeq_test();
1048 free_all_registers();
1049 gentestl_out();
1050#endif
1051}
1052
1053void genbeql_idle(void)
1054{
1055#ifdef INTERPRET_BEQL_IDLE
1056 gencallinterp((unsigned int)cached_interpreter_table.BEQL_IDLE, 1);
1057#else
1058 if (((dst->addr & 0xFFF) == 0xFFC &&
1059 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
1060 {
1061 gencallinterp((unsigned int)cached_interpreter_table.BEQL_IDLE, 1);
1062 return;
1063 }
1064
1065 genbeq_test();
1066 gentest_idle();
1067 genbeql();
1068#endif
1069}
1070
1071void genbnel(void)
1072{
1073#ifdef INTERPRET_BNEL
1074 gencallinterp((unsigned int)cached_interpreter_table.BNEL, 1);
1075#else
1076 if (((dst->addr & 0xFFF) == 0xFFC &&
1077 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
1078 {
1079 gencallinterp((unsigned int)cached_interpreter_table.BNEL, 1);
1080 return;
1081 }
1082
1083 genbne_test();
1084 free_all_registers();
1085 gentestl();
1086#endif
1087}
1088
1089void genbnel_out(void)
1090{
1091#ifdef INTERPRET_BNEL_OUT
1092 gencallinterp((unsigned int)cached_interpreter_table.BNEL_OUT, 1);
1093#else
1094 if (((dst->addr & 0xFFF) == 0xFFC &&
1095 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
1096 {
1097 gencallinterp((unsigned int)cached_interpreter_table.BNEL_OUT, 1);
1098 return;
1099 }
1100
1101 genbne_test();
1102 free_all_registers();
1103 gentestl_out();
1104#endif
1105}
1106
1107void genbnel_idle(void)
1108{
1109#ifdef INTERPRET_BNEL_IDLE
1110 gencallinterp((unsigned int)cached_interpreter_table.BNEL_IDLE, 1);
1111#else
1112 if (((dst->addr & 0xFFF) == 0xFFC &&
1113 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
1114 {
1115 gencallinterp((unsigned int)cached_interpreter_table.BNEL_IDLE, 1);
1116 return;
1117 }
1118
1119 genbne_test();
1120 gentest_idle();
1121 genbnel();
1122#endif
1123}
1124
1125void genblezl(void)
1126{
1127#ifdef INTERPRET_BLEZL
1128 gencallinterp((unsigned int)cached_interpreter_table.BLEZL, 1);
1129#else
1130 if (((dst->addr & 0xFFF) == 0xFFC &&
1131 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
1132 {
1133 gencallinterp((unsigned int)cached_interpreter_table.BLEZL, 1);
1134 return;
1135 }
1136
1137 genblez_test();
1138 free_all_registers();
1139 gentestl();
1140#endif
1141}
1142
1143void genblezl_out(void)
1144{
1145#ifdef INTERPRET_BLEZL_OUT
1146 gencallinterp((unsigned int)cached_interpreter_table.BLEZL_OUT, 1);
1147#else
1148 if (((dst->addr & 0xFFF) == 0xFFC &&
1149 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
1150 {
1151 gencallinterp((unsigned int)cached_interpreter_table.BLEZL_OUT, 1);
1152 return;
1153 }
1154
1155 genblez_test();
1156 free_all_registers();
1157 gentestl_out();
1158#endif
1159}
1160
1161void genblezl_idle(void)
1162{
1163#ifdef INTERPRET_BLEZL_IDLE
1164 gencallinterp((unsigned int)cached_interpreter_table.BLEZL_IDLE, 1);
1165#else
1166 if (((dst->addr & 0xFFF) == 0xFFC &&
1167 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
1168 {
1169 gencallinterp((unsigned int)cached_interpreter_table.BLEZL_IDLE, 1);
1170 return;
1171 }
1172
1173 genblez_test();
1174 gentest_idle();
1175 genblezl();
1176#endif
1177}
1178
1179void genbgtzl(void)
1180{
1181#ifdef INTERPRET_BGTZL
1182 gencallinterp((unsigned int)cached_interpreter_table.BGTZL, 1);
1183#else
1184 if (((dst->addr & 0xFFF) == 0xFFC &&
1185 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
1186 {
1187 gencallinterp((unsigned int)cached_interpreter_table.BGTZL, 1);
1188 return;
1189 }
1190
1191 genbgtz_test();
1192 free_all_registers();
1193 gentestl();
1194#endif
1195}
1196
1197void genbgtzl_out(void)
1198{
1199#ifdef INTERPRET_BGTZL_OUT
1200 gencallinterp((unsigned int)cached_interpreter_table.BGTZL_OUT, 1);
1201#else
1202 if (((dst->addr & 0xFFF) == 0xFFC &&
1203 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
1204 {
1205 gencallinterp((unsigned int)cached_interpreter_table.BGTZL_OUT, 1);
1206 return;
1207 }
1208
1209 genbgtz_test();
1210 free_all_registers();
1211 gentestl_out();
1212#endif
1213}
1214
1215void genbgtzl_idle(void)
1216{
1217#ifdef INTERPRET_BGTZL_IDLE
1218 gencallinterp((unsigned int)cached_interpreter_table.BGTZL_IDLE, 1);
1219#else
1220 if (((dst->addr & 0xFFF) == 0xFFC &&
1221 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
1222 {
1223 gencallinterp((unsigned int)cached_interpreter_table.BGTZL_IDLE, 1);
1224 return;
1225 }
1226
1227 genbgtz_test();
1228 gentest_idle();
1229 genbgtzl();
1230#endif
1231}
1232
1233void gendaddi(void)
1234{
1235#ifdef INTERPRET_DADDI
1236 gencallinterp((unsigned int)cached_interpreter_table.DADDI, 0);
1237#else
1238 int rs1 = allocate_64_register1((unsigned int *)dst->f.i.rs);
1239 int rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs);
1240 int rt1 = allocate_64_register1_w((unsigned int *)dst->f.i.rt);
1241 int rt2 = allocate_64_register2_w((unsigned int *)dst->f.i.rt);
1242
1243 mov_reg32_reg32(rt1, rs1);
1244 mov_reg32_reg32(rt2, rs2);
1245 add_reg32_imm32(rt1, dst->f.i.immediate);
1246 adc_reg32_imm32(rt2, (int)dst->f.i.immediate>>31);
1247#endif
1248}
1249
1250void gendaddiu(void)
1251{
1252#ifdef INTERPRET_DADDIU
1253 gencallinterp((unsigned int)cached_interpreter_table.DADDIU, 0);
1254#else
1255 int rs1 = allocate_64_register1((unsigned int *)dst->f.i.rs);
1256 int rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs);
1257 int rt1 = allocate_64_register1_w((unsigned int *)dst->f.i.rt);
1258 int rt2 = allocate_64_register2_w((unsigned int *)dst->f.i.rt);
1259
1260 mov_reg32_reg32(rt1, rs1);
1261 mov_reg32_reg32(rt2, rs2);
1262 add_reg32_imm32(rt1, dst->f.i.immediate);
1263 adc_reg32_imm32(rt2, (int)dst->f.i.immediate>>31);
1264#endif
1265}
1266
1267void genldl(void)
1268{
1269 gencallinterp((unsigned int)cached_interpreter_table.LDL, 0);
1270}
1271
1272void genldr(void)
1273{
1274 gencallinterp((unsigned int)cached_interpreter_table.LDR, 0);
1275}
1276
1277void genlb(void)
1278{
1279#ifdef INTERPRET_LB
1280 gencallinterp((unsigned int)cached_interpreter_table.LB, 0);
1281#else
1282 free_all_registers();
1283 simplify_access();
1284 mov_eax_memoffs32((unsigned int *)dst->f.i.rs);
1285 add_eax_imm32((int)dst->f.i.immediate);
1286 mov_reg32_reg32(EBX, EAX);
1287 if(fast_memory)
1288 {
1289 and_eax_imm32(0xDF800000);
1290 cmp_eax_imm32(0x80000000);
1291 }
1292 else
1293 {
1294 shr_reg32_imm8(EAX, 16);
1295 mov_reg32_preg32x4pimm32(EAX, EAX, (unsigned int)readmemb);
1296 cmp_reg32_imm32(EAX, (unsigned int)read_rdramb);
1297 }
1298 je_rj(47);
1299
1300 mov_m32_imm32((unsigned int *)&PC, (unsigned int)(dst+1)); // 10
1301 mov_m32_reg32((unsigned int *)(&address), EBX); // 6
1302 mov_m32_imm32((unsigned int *)(&rdword), (unsigned int)dst->f.i.rt); // 10
1303 shr_reg32_imm8(EBX, 16); // 3
1304 mov_reg32_preg32x4pimm32(EBX, EBX, (unsigned int)readmemb); // 7
1305 call_reg32(EBX); // 2
1306 movsx_reg32_m8(EAX, (unsigned char *)dst->f.i.rt); // 7
1307 jmp_imm_short(16); // 2
1308
1309 and_reg32_imm32(EBX, 0x7FFFFF); // 6
1310 xor_reg8_imm8(BL, 3); // 3
1311 movsx_reg32_8preg32pimm32(EAX, EBX, (unsigned int)rdram); // 7
1312
1313 set_register_state(EAX, (unsigned int*)dst->f.i.rt, 1);
1314#endif
1315}
1316
1317void genlh(void)
1318{
1319#ifdef INTERPRET_LH
1320 gencallinterp((unsigned int)cached_interpreter_table.LH, 0);
1321#else
1322 free_all_registers();
1323 simplify_access();
1324 mov_eax_memoffs32((unsigned int *)dst->f.i.rs);
1325 add_eax_imm32((int)dst->f.i.immediate);
1326 mov_reg32_reg32(EBX, EAX);
1327 if(fast_memory)
1328 {
1329 and_eax_imm32(0xDF800000);
1330 cmp_eax_imm32(0x80000000);
1331 }
1332 else
1333 {
1334 shr_reg32_imm8(EAX, 16);
1335 mov_reg32_preg32x4pimm32(EAX, EAX, (unsigned int)readmemh);
1336 cmp_reg32_imm32(EAX, (unsigned int)read_rdramh);
1337 }
1338 je_rj(47);
1339
1340 mov_m32_imm32((unsigned int *)&PC, (unsigned int)(dst+1)); // 10
1341 mov_m32_reg32((unsigned int *)(&address), EBX); // 6
1342 mov_m32_imm32((unsigned int *)(&rdword), (unsigned int)dst->f.i.rt); // 10
1343 shr_reg32_imm8(EBX, 16); // 3
1344 mov_reg32_preg32x4pimm32(EBX, EBX, (unsigned int)readmemh); // 7
1345 call_reg32(EBX); // 2
1346 movsx_reg32_m16(EAX, (unsigned short *)dst->f.i.rt); // 7
1347 jmp_imm_short(16); // 2
1348
1349 and_reg32_imm32(EBX, 0x7FFFFF); // 6
1350 xor_reg8_imm8(BL, 2); // 3
1351 movsx_reg32_16preg32pimm32(EAX, EBX, (unsigned int)rdram); // 7
1352
1353 set_register_state(EAX, (unsigned int*)dst->f.i.rt, 1);
1354#endif
1355}
1356
1357void genlwl(void)
1358{
1359 gencallinterp((unsigned int)cached_interpreter_table.LWL, 0);
1360}
1361
1362void genlw(void)
1363{
1364#ifdef INTERPRET_LW
1365 gencallinterp((unsigned int)cached_interpreter_table.LW, 0);
1366#else
1367 free_all_registers();
1368 simplify_access();
1369 mov_eax_memoffs32((unsigned int *)dst->f.i.rs);
1370 add_eax_imm32((int)dst->f.i.immediate);
1371 mov_reg32_reg32(EBX, EAX);
1372 if(fast_memory)
1373 {
1374 and_eax_imm32(0xDF800000);
1375 cmp_eax_imm32(0x80000000);
1376 }
1377 else
1378 {
1379 shr_reg32_imm8(EAX, 16);
1380 mov_reg32_preg32x4pimm32(EAX, EAX, (unsigned int)readmem);
1381 cmp_reg32_imm32(EAX, (unsigned int)read_rdram);
1382 }
1383 je_rj(45);
1384
1385 mov_m32_imm32((unsigned int *)&PC, (unsigned int)(dst+1)); // 10
1386 mov_m32_reg32((unsigned int *)(&address), EBX); // 6
1387 mov_m32_imm32((unsigned int *)(&rdword), (unsigned int)dst->f.i.rt); // 10
1388 shr_reg32_imm8(EBX, 16); // 3
1389 mov_reg32_preg32x4pimm32(EBX, EBX, (unsigned int)readmem); // 7
1390 call_reg32(EBX); // 2
1391 mov_eax_memoffs32((unsigned int *)(dst->f.i.rt)); // 5
1392 jmp_imm_short(12); // 2
1393
1394 and_reg32_imm32(EBX, 0x7FFFFF); // 6
1395 mov_reg32_preg32pimm32(EAX, EBX, (unsigned int)rdram); // 6
1396
1397 set_register_state(EAX, (unsigned int*)dst->f.i.rt, 1);
1398#endif
1399}
1400
1401void genlbu(void)
1402{
1403#ifdef INTERPRET_LBU
1404 gencallinterp((unsigned int)cached_interpreter_table.LBU, 0);
1405#else
1406 free_all_registers();
1407 simplify_access();
1408 mov_eax_memoffs32((unsigned int *)dst->f.i.rs);
1409 add_eax_imm32((int)dst->f.i.immediate);
1410 mov_reg32_reg32(EBX, EAX);
1411 if(fast_memory)
1412 {
1413 and_eax_imm32(0xDF800000);
1414 cmp_eax_imm32(0x80000000);
1415 }
1416 else
1417 {
1418 shr_reg32_imm8(EAX, 16);
1419 mov_reg32_preg32x4pimm32(EAX, EAX, (unsigned int)readmemb);
1420 cmp_reg32_imm32(EAX, (unsigned int)read_rdramb);
1421 }
1422 je_rj(46);
1423
1424 mov_m32_imm32((unsigned int *)&PC, (unsigned int)(dst+1)); // 10
1425 mov_m32_reg32((unsigned int *)(&address), EBX); // 6
1426 mov_m32_imm32((unsigned int *)(&rdword), (unsigned int)dst->f.i.rt); // 10
1427 shr_reg32_imm8(EBX, 16); // 3
1428 mov_reg32_preg32x4pimm32(EBX, EBX, (unsigned int)readmemb); // 7
1429 call_reg32(EBX); // 2
1430 mov_reg32_m32(EAX, (unsigned int *)dst->f.i.rt); // 6
1431 jmp_imm_short(15); // 2
1432
1433 and_reg32_imm32(EBX, 0x7FFFFF); // 6
1434 xor_reg8_imm8(BL, 3); // 3
1435 mov_reg32_preg32pimm32(EAX, EBX, (unsigned int)rdram); // 6
1436
1437 and_eax_imm32(0xFF);
1438
1439 set_register_state(EAX, (unsigned int*)dst->f.i.rt, 1);
1440#endif
1441}
1442
1443void genlhu(void)
1444{
1445#ifdef INTERPRET_LHU
1446 gencallinterp((unsigned int)cached_interpreter_table.LHU, 0);
1447#else
1448 free_all_registers();
1449 simplify_access();
1450 mov_eax_memoffs32((unsigned int *)dst->f.i.rs);
1451 add_eax_imm32((int)dst->f.i.immediate);
1452 mov_reg32_reg32(EBX, EAX);
1453 if(fast_memory)
1454 {
1455 and_eax_imm32(0xDF800000);
1456 cmp_eax_imm32(0x80000000);
1457 }
1458 else
1459 {
1460 shr_reg32_imm8(EAX, 16);
1461 mov_reg32_preg32x4pimm32(EAX, EAX, (unsigned int)readmemh);
1462 cmp_reg32_imm32(EAX, (unsigned int)read_rdramh);
1463 }
1464 je_rj(46);
1465
1466 mov_m32_imm32((unsigned int *)&PC, (unsigned int)(dst+1)); // 10
1467 mov_m32_reg32((unsigned int *)(&address), EBX); // 6
1468 mov_m32_imm32((unsigned int *)(&rdword), (unsigned int)dst->f.i.rt); // 10
1469 shr_reg32_imm8(EBX, 16); // 3
1470 mov_reg32_preg32x4pimm32(EBX, EBX, (unsigned int)readmemh); // 7
1471 call_reg32(EBX); // 2
1472 mov_reg32_m32(EAX, (unsigned int *)dst->f.i.rt); // 6
1473 jmp_imm_short(15); // 2
1474
1475 and_reg32_imm32(EBX, 0x7FFFFF); // 6
1476 xor_reg8_imm8(BL, 2); // 3
1477 mov_reg32_preg32pimm32(EAX, EBX, (unsigned int)rdram); // 6
1478
1479 and_eax_imm32(0xFFFF);
1480
1481 set_register_state(EAX, (unsigned int*)dst->f.i.rt, 1);
1482#endif
1483}
1484
1485void genlwr(void)
1486{
1487 gencallinterp((unsigned int)cached_interpreter_table.LWR, 0);
1488}
1489
1490void genlwu(void)
1491{
1492#ifdef INTERPRET_LWU
1493 gencallinterp((unsigned int)cached_interpreter_table.LWU, 0);
1494#else
1495 free_all_registers();
1496 simplify_access();
1497 mov_eax_memoffs32((unsigned int *)dst->f.i.rs);
1498 add_eax_imm32((int)dst->f.i.immediate);
1499 mov_reg32_reg32(EBX, EAX);
1500 if(fast_memory)
1501 {
1502 and_eax_imm32(0xDF800000);
1503 cmp_eax_imm32(0x80000000);
1504 }
1505 else
1506 {
1507 shr_reg32_imm8(EAX, 16);
1508 mov_reg32_preg32x4pimm32(EAX, EAX, (unsigned int)readmem);
1509 cmp_reg32_imm32(EAX, (unsigned int)read_rdram);
1510 }
1511 je_rj(45);
1512
1513 mov_m32_imm32((unsigned int *)(&PC), (unsigned int)(dst+1)); // 10
1514 mov_m32_reg32((unsigned int *)(&address), EBX); // 6
1515 mov_m32_imm32((unsigned int *)(&rdword), (unsigned int)dst->f.i.rt); // 10
1516 shr_reg32_imm8(EBX, 16); // 3
1517 mov_reg32_preg32x4pimm32(EBX, EBX, (unsigned int)readmem); // 7
1518 call_reg32(EBX); // 2
1519 mov_eax_memoffs32((unsigned int *)(dst->f.i.rt)); // 5
1520 jmp_imm_short(12); // 2
1521
1522 and_reg32_imm32(EBX, 0x7FFFFF); // 6
1523 mov_reg32_preg32pimm32(EAX, EBX, (unsigned int)rdram); // 6
1524
1525 xor_reg32_reg32(EBX, EBX);
1526
1527 set_64_register_state(EAX, EBX, (unsigned int*)dst->f.i.rt, 1);
1528#endif
1529}
1530
1531void gensb(void)
1532{
1533#ifdef INTERPRET_SB
1534 gencallinterp((unsigned int)cached_interpreter_table.SB, 0);
1535#else
1536 free_all_registers();
1537 simplify_access();
1538 mov_reg8_m8(CL, (unsigned char *)dst->f.i.rt);
1539 mov_eax_memoffs32((unsigned int *)dst->f.i.rs);
1540 add_eax_imm32((int)dst->f.i.immediate);
1541 mov_reg32_reg32(EBX, EAX);
1542 if(fast_memory)
1543 {
1544 and_eax_imm32(0xDF800000);
1545 cmp_eax_imm32(0x80000000);
1546 }
1547 else
1548 {
1549 shr_reg32_imm8(EAX, 16);
1550 mov_reg32_preg32x4pimm32(EAX, EAX, (unsigned int)writememb);
1551 cmp_reg32_imm32(EAX, (unsigned int)write_rdramb);
1552 }
1553 je_rj(41);
1554
1555 mov_m32_imm32((unsigned int *)(&PC), (unsigned int)(dst+1)); // 10
1556 mov_m32_reg32((unsigned int *)(&address), EBX); // 6
1557 mov_m8_reg8((unsigned char *)(&cpu_byte), CL); // 6
1558 shr_reg32_imm8(EBX, 16); // 3
1559 mov_reg32_preg32x4pimm32(EBX, EBX, (unsigned int)writememb); // 7
1560 call_reg32(EBX); // 2
1561 mov_eax_memoffs32((unsigned int *)(&address)); // 5
1562 jmp_imm_short(17); // 2
1563
1564 mov_reg32_reg32(EAX, EBX); // 2
1565 and_reg32_imm32(EBX, 0x7FFFFF); // 6
1566 xor_reg8_imm8(BL, 3); // 3
1567 mov_preg32pimm32_reg8(EBX, (unsigned int)rdram, CL); // 6
1568
1569 mov_reg32_reg32(EBX, EAX);
1570 shr_reg32_imm8(EBX, 12);
1571 cmp_preg32pimm32_imm8(EBX, (unsigned int)invalid_code, 0);
1572 jne_rj(54);
1573 mov_reg32_reg32(ECX, EBX); // 2
1574 shl_reg32_imm8(EBX, 2); // 3
1575 mov_reg32_preg32pimm32(EBX, EBX, (unsigned int)blocks); // 6
1576 mov_reg32_preg32pimm32(EBX, EBX, (int)&actual->block - (int)actual); // 6
1577 and_eax_imm32(0xFFF); // 5
1578 shr_reg32_imm8(EAX, 2); // 3
1579 mov_reg32_imm32(EDX, sizeof(precomp_instr)); // 5
1580 mul_reg32(EDX); // 2
1581 mov_reg32_preg32preg32pimm32(EAX, EAX, EBX, (int)&dst->ops - (int)dst); // 7
1582 cmp_reg32_imm32(EAX, (unsigned int)cached_interpreter_table.NOTCOMPILED); // 6
1583 je_rj(7); // 2
1584 mov_preg32pimm32_imm8(ECX, (unsigned int)invalid_code, 1); // 7
1585#endif
1586}
1587
1588void gensh(void)
1589{
1590#ifdef INTERPRET_SH
1591 gencallinterp((unsigned int)cached_interpreter_table.SH, 0);
1592#else
1593 free_all_registers();
1594 simplify_access();
1595 mov_reg16_m16(CX, (unsigned short *)dst->f.i.rt);
1596 mov_eax_memoffs32((unsigned int *)dst->f.i.rs);
1597 add_eax_imm32((int)dst->f.i.immediate);
1598 mov_reg32_reg32(EBX, EAX);
1599 if(fast_memory)
1600 {
1601 and_eax_imm32(0xDF800000);
1602 cmp_eax_imm32(0x80000000);
1603 }
1604 else
1605 {
1606 shr_reg32_imm8(EAX, 16);
1607 mov_reg32_preg32x4pimm32(EAX, EAX, (unsigned int)writememh);
1608 cmp_reg32_imm32(EAX, (unsigned int)write_rdramh);
1609 }
1610 je_rj(42);
1611
1612 mov_m32_imm32((unsigned int *)(&PC), (unsigned int)(dst+1)); // 10
1613 mov_m32_reg32((unsigned int *)(&address), EBX); // 6
1614 mov_m16_reg16((unsigned short *)(&hword), CX); // 7
1615 shr_reg32_imm8(EBX, 16); // 3
1616 mov_reg32_preg32x4pimm32(EBX, EBX, (unsigned int)writememh); // 7
1617 call_reg32(EBX); // 2
1618 mov_eax_memoffs32((unsigned int *)(&address)); // 5
1619 jmp_imm_short(18); // 2
1620
1621 mov_reg32_reg32(EAX, EBX); // 2
1622 and_reg32_imm32(EBX, 0x7FFFFF); // 6
1623 xor_reg8_imm8(BL, 2); // 3
1624 mov_preg32pimm32_reg16(EBX, (unsigned int)rdram, CX); // 7
1625
1626 mov_reg32_reg32(EBX, EAX);
1627 shr_reg32_imm8(EBX, 12);
1628 cmp_preg32pimm32_imm8(EBX, (unsigned int)invalid_code, 0);
1629 jne_rj(54);
1630 mov_reg32_reg32(ECX, EBX); // 2
1631 shl_reg32_imm8(EBX, 2); // 3
1632 mov_reg32_preg32pimm32(EBX, EBX, (unsigned int)blocks); // 6
1633 mov_reg32_preg32pimm32(EBX, EBX, (int)&actual->block - (int)actual); // 6
1634 and_eax_imm32(0xFFF); // 5
1635 shr_reg32_imm8(EAX, 2); // 3
1636 mov_reg32_imm32(EDX, sizeof(precomp_instr)); // 5
1637 mul_reg32(EDX); // 2
1638 mov_reg32_preg32preg32pimm32(EAX, EAX, EBX, (int)&dst->ops - (int)dst); // 7
1639 cmp_reg32_imm32(EAX, (unsigned int)cached_interpreter_table.NOTCOMPILED); // 6
1640 je_rj(7); // 2
1641 mov_preg32pimm32_imm8(ECX, (unsigned int)invalid_code, 1); // 7
1642#endif
1643}
1644
1645void genswl(void)
1646{
1647 gencallinterp((unsigned int)cached_interpreter_table.SWL, 0);
1648}
1649
1650void gensw(void)
1651{
1652#ifdef INTERPRET_SW
1653 gencallinterp((unsigned int)cached_interpreter_table.SW, 0);
1654#else
1655 free_all_registers();
1656 simplify_access();
1657 mov_reg32_m32(ECX, (unsigned int *)dst->f.i.rt);
1658 mov_eax_memoffs32((unsigned int *)dst->f.i.rs);
1659 add_eax_imm32((int)dst->f.i.immediate);
1660 mov_reg32_reg32(EBX, EAX);
1661 if(fast_memory)
1662 {
1663 and_eax_imm32(0xDF800000);
1664 cmp_eax_imm32(0x80000000);
1665 }
1666 else
1667 {
1668 shr_reg32_imm8(EAX, 16);
1669 mov_reg32_preg32x4pimm32(EAX, EAX, (unsigned int)writemem);
1670 cmp_reg32_imm32(EAX, (unsigned int)write_rdram);
1671 }
1672 je_rj(41);
1673
1674 mov_m32_imm32((unsigned int *)(&PC), (unsigned int)(dst+1)); // 10
1675 mov_m32_reg32((unsigned int *)(&address), EBX); // 6
1676 mov_m32_reg32((unsigned int *)(&word), ECX); // 6
1677 shr_reg32_imm8(EBX, 16); // 3
1678 mov_reg32_preg32x4pimm32(EBX, EBX, (unsigned int)writemem); // 7
1679 call_reg32(EBX); // 2
1680 mov_eax_memoffs32((unsigned int *)(&address)); // 5
1681 jmp_imm_short(14); // 2
1682
1683 mov_reg32_reg32(EAX, EBX); // 2
1684 and_reg32_imm32(EBX, 0x7FFFFF); // 6
1685 mov_preg32pimm32_reg32(EBX, (unsigned int)rdram, ECX); // 6
1686
1687 mov_reg32_reg32(EBX, EAX);
1688 shr_reg32_imm8(EBX, 12);
1689 cmp_preg32pimm32_imm8(EBX, (unsigned int)invalid_code, 0);
1690 jne_rj(54);
1691 mov_reg32_reg32(ECX, EBX); // 2
1692 shl_reg32_imm8(EBX, 2); // 3
1693 mov_reg32_preg32pimm32(EBX, EBX, (unsigned int)blocks); // 6
1694 mov_reg32_preg32pimm32(EBX, EBX, (int)&actual->block - (int)actual); // 6
1695 and_eax_imm32(0xFFF); // 5
1696 shr_reg32_imm8(EAX, 2); // 3
1697 mov_reg32_imm32(EDX, sizeof(precomp_instr)); // 5
1698 mul_reg32(EDX); // 2
1699 mov_reg32_preg32preg32pimm32(EAX, EAX, EBX, (int)&dst->ops - (int)dst); // 7
1700 cmp_reg32_imm32(EAX, (unsigned int)cached_interpreter_table.NOTCOMPILED); // 6
1701 je_rj(7); // 2
1702 mov_preg32pimm32_imm8(ECX, (unsigned int)invalid_code, 1); // 7
1703#endif
1704}
1705
1706void gensdl(void)
1707{
1708 gencallinterp((unsigned int)cached_interpreter_table.SDL, 0);
1709}
1710
1711void gensdr(void)
1712{
1713 gencallinterp((unsigned int)cached_interpreter_table.SDR, 0);
1714}
1715
1716void genswr(void)
1717{
1718 gencallinterp((unsigned int)cached_interpreter_table.SWR, 0);
1719}
1720
1721void gencheck_cop1_unusable(void)
1722{
1723 free_all_registers();
1724 simplify_access();
1725 test_m32_imm32((unsigned int*)&Status, 0x20000000);
1726 jne_rj(0);
1727
1728 jump_start_rel8();
1729
1730 gencallinterp((unsigned int)check_cop1_unusable, 0);
1731
1732 jump_end_rel8();
1733}
1734
1735void genlwc1(void)
1736{
1737#ifdef INTERPRET_LWC1
1738 gencallinterp((unsigned int)cached_interpreter_table.LWC1, 0);
1739#else
1740 gencheck_cop1_unusable();
1741
1742 mov_eax_memoffs32((unsigned int *)(&reg[dst->f.lf.base]));
1743 add_eax_imm32((int)dst->f.lf.offset);
1744 mov_reg32_reg32(EBX, EAX);
1745 if(fast_memory)
1746 {
1747 and_eax_imm32(0xDF800000);
1748 cmp_eax_imm32(0x80000000);
1749 }
1750 else
1751 {
1752 shr_reg32_imm8(EAX, 16);
1753 mov_reg32_preg32x4pimm32(EAX, EAX, (unsigned int)readmem);
1754 cmp_reg32_imm32(EAX, (unsigned int)read_rdram);
1755 }
1756 je_rj(42);
1757
1758 mov_m32_imm32((unsigned int *)(&PC), (unsigned int)(dst+1)); // 10
1759 mov_m32_reg32((unsigned int *)(&address), EBX); // 6
1760 mov_reg32_m32(EDX, (unsigned int*)(&reg_cop1_simple[dst->f.lf.ft])); // 6
1761 mov_m32_reg32((unsigned int *)(&rdword), EDX); // 6
1762 shr_reg32_imm8(EBX, 16); // 3
1763 mov_reg32_preg32x4pimm32(EBX, EBX, (unsigned int)readmem); // 7
1764 call_reg32(EBX); // 2
1765 jmp_imm_short(20); // 2
1766
1767 and_reg32_imm32(EBX, 0x7FFFFF); // 6
1768 mov_reg32_preg32pimm32(EAX, EBX, (unsigned int)rdram); // 6
1769 mov_reg32_m32(EBX, (unsigned int*)(&reg_cop1_simple[dst->f.lf.ft])); // 6
1770 mov_preg32_reg32(EBX, EAX); // 2
1771#endif
1772}
1773
1774void genldc1(void)
1775{
1776#ifdef INTERPRET_LDC1
1777 gencallinterp((unsigned int)cached_interpreter_table.LDC1, 0);
1778#else
1779 gencheck_cop1_unusable();
1780
1781 mov_eax_memoffs32((unsigned int *)(&reg[dst->f.lf.base]));
1782 add_eax_imm32((int)dst->f.lf.offset);
1783 mov_reg32_reg32(EBX, EAX);
1784 if(fast_memory)
1785 {
1786 and_eax_imm32(0xDF800000);
1787 cmp_eax_imm32(0x80000000);
1788 }
1789 else
1790 {
1791 shr_reg32_imm8(EAX, 16);
1792 mov_reg32_preg32x4pimm32(EAX, EAX, (unsigned int)readmemd);
1793 cmp_reg32_imm32(EAX, (unsigned int)read_rdramd);
1794 }
1795 je_rj(42);
1796
1797 mov_m32_imm32((unsigned int *)(&PC), (unsigned int)(dst+1)); // 10
1798 mov_m32_reg32((unsigned int *)(&address), EBX); // 6
1799 mov_reg32_m32(EDX, (unsigned int*)(&reg_cop1_double[dst->f.lf.ft])); // 6
1800 mov_m32_reg32((unsigned int *)(&rdword), EDX); // 6
1801 shr_reg32_imm8(EBX, 16); // 3
1802 mov_reg32_preg32x4pimm32(EBX, EBX, (unsigned int)readmemd); // 7
1803 call_reg32(EBX); // 2
1804 jmp_imm_short(32); // 2
1805
1806 and_reg32_imm32(EBX, 0x7FFFFF); // 6
1807 mov_reg32_preg32pimm32(EAX, EBX, ((unsigned int)rdram)+4); // 6
1808 mov_reg32_preg32pimm32(ECX, EBX, ((unsigned int)rdram)); // 6
1809 mov_reg32_m32(EBX, (unsigned int*)(&reg_cop1_double[dst->f.lf.ft])); // 6
1810 mov_preg32_reg32(EBX, EAX); // 2
1811 mov_preg32pimm32_reg32(EBX, 4, ECX); // 6
1812#endif
1813}
1814
1815void gencache(void)
1816{
1817}
1818
1819void genld(void)
1820{
1821#ifdef INTERPRET_LD
1822 gencallinterp((unsigned int)cached_interpreter_table.LD, 0);
1823#else
1824 free_all_registers();
1825 simplify_access();
1826 mov_eax_memoffs32((unsigned int *)dst->f.i.rs);
1827 add_eax_imm32((int)dst->f.i.immediate);
1828 mov_reg32_reg32(EBX, EAX);
1829 if(fast_memory)
1830 {
1831 and_eax_imm32(0xDF800000);
1832 cmp_eax_imm32(0x80000000);
1833 }
1834 else
1835 {
1836 shr_reg32_imm8(EAX, 16);
1837 mov_reg32_preg32x4pimm32(EAX, EAX, (unsigned int)readmemd);
1838 cmp_reg32_imm32(EAX, (unsigned int)read_rdramd);
1839 }
1840 je_rj(51);
1841
1842 mov_m32_imm32((unsigned int *)(&PC), (unsigned int)(dst+1)); // 10
1843 mov_m32_reg32((unsigned int *)(&address), EBX); // 6
1844 mov_m32_imm32((unsigned int *)(&rdword), (unsigned int)dst->f.i.rt); // 10
1845 shr_reg32_imm8(EBX, 16); // 3
1846 mov_reg32_preg32x4pimm32(EBX, EBX, (unsigned int)readmemd); // 7
1847 call_reg32(EBX); // 2
1848 mov_eax_memoffs32((unsigned int *)(dst->f.i.rt)); // 5
1849 mov_reg32_m32(ECX, (unsigned int *)(dst->f.i.rt)+1); // 6
1850 jmp_imm_short(18); // 2
1851
1852 and_reg32_imm32(EBX, 0x7FFFFF); // 6
1853 mov_reg32_preg32pimm32(EAX, EBX, ((unsigned int)rdram)+4); // 6
1854 mov_reg32_preg32pimm32(ECX, EBX, ((unsigned int)rdram)); // 6
1855
1856 set_64_register_state(EAX, ECX, (unsigned int*)dst->f.i.rt, 1);
1857#endif
1858}
1859
1860void genswc1(void)
1861{
1862#ifdef INTERPRET_SWC1
1863 gencallinterp((unsigned int)cached_interpreter_table.SWC1, 0);
1864#else
1865 gencheck_cop1_unusable();
1866
1867 mov_reg32_m32(EDX, (unsigned int*)(&reg_cop1_simple[dst->f.lf.ft]));
1868 mov_reg32_preg32(ECX, EDX);
1869 mov_eax_memoffs32((unsigned int *)(&reg[dst->f.lf.base]));
1870 add_eax_imm32((int)dst->f.lf.offset);
1871 mov_reg32_reg32(EBX, EAX);
1872 if(fast_memory)
1873 {
1874 and_eax_imm32(0xDF800000);
1875 cmp_eax_imm32(0x80000000);
1876 }
1877 else
1878 {
1879 shr_reg32_imm8(EAX, 16);
1880 mov_reg32_preg32x4pimm32(EAX, EAX, (unsigned int)writemem);
1881 cmp_reg32_imm32(EAX, (unsigned int)write_rdram);
1882 }
1883 je_rj(41);
1884
1885 mov_m32_imm32((unsigned int *)(&PC), (unsigned int)(dst+1)); // 10
1886 mov_m32_reg32((unsigned int *)(&address), EBX); // 6
1887 mov_m32_reg32((unsigned int *)(&word), ECX); // 6
1888 shr_reg32_imm8(EBX, 16); // 3
1889 mov_reg32_preg32x4pimm32(EBX, EBX, (unsigned int)writemem); // 7
1890 call_reg32(EBX); // 2
1891 mov_eax_memoffs32((unsigned int *)(&address)); // 5
1892 jmp_imm_short(14); // 2
1893
1894 mov_reg32_reg32(EAX, EBX); // 2
1895 and_reg32_imm32(EBX, 0x7FFFFF); // 6
1896 mov_preg32pimm32_reg32(EBX, (unsigned int)rdram, ECX); // 6
1897
1898 mov_reg32_reg32(EBX, EAX);
1899 shr_reg32_imm8(EBX, 12);
1900 cmp_preg32pimm32_imm8(EBX, (unsigned int)invalid_code, 0);
1901 jne_rj(54);
1902 mov_reg32_reg32(ECX, EBX); // 2
1903 shl_reg32_imm8(EBX, 2); // 3
1904 mov_reg32_preg32pimm32(EBX, EBX, (unsigned int)blocks); // 6
1905 mov_reg32_preg32pimm32(EBX, EBX, (int)&actual->block - (int)actual); // 6
1906 and_eax_imm32(0xFFF); // 5
1907 shr_reg32_imm8(EAX, 2); // 3
1908 mov_reg32_imm32(EDX, sizeof(precomp_instr)); // 5
1909 mul_reg32(EDX); // 2
1910 mov_reg32_preg32preg32pimm32(EAX, EAX, EBX, (int)&dst->ops - (int)dst); // 7
1911 cmp_reg32_imm32(EAX, (unsigned int)cached_interpreter_table.NOTCOMPILED); // 6
1912 je_rj(7); // 2
1913 mov_preg32pimm32_imm8(ECX, (unsigned int)invalid_code, 1); // 7
1914#endif
1915}
1916
1917void gensdc1(void)
1918{
1919#ifdef INTERPRET_SDC1
1920 gencallinterp((unsigned int)cached_interpreter_table.SDC1, 0);
1921#else
1922 gencheck_cop1_unusable();
1923
1924 mov_reg32_m32(ESI, (unsigned int*)(&reg_cop1_double[dst->f.lf.ft]));
1925 mov_reg32_preg32(ECX, ESI);
1926 mov_reg32_preg32pimm32(EDX, ESI, 4);
1927 mov_eax_memoffs32((unsigned int *)(&reg[dst->f.lf.base]));
1928 add_eax_imm32((int)dst->f.lf.offset);
1929 mov_reg32_reg32(EBX, EAX);
1930 if(fast_memory)
1931 {
1932 and_eax_imm32(0xDF800000);
1933 cmp_eax_imm32(0x80000000);
1934 }
1935 else
1936 {
1937 shr_reg32_imm8(EAX, 16);
1938 mov_reg32_preg32x4pimm32(EAX, EAX, (unsigned int)writememd);
1939 cmp_reg32_imm32(EAX, (unsigned int)write_rdramd);
1940 }
1941 je_rj(47);
1942
1943 mov_m32_imm32((unsigned int *)(&PC), (unsigned int)(dst+1)); // 10
1944 mov_m32_reg32((unsigned int *)(&address), EBX); // 6
1945 mov_m32_reg32((unsigned int *)(&dword), ECX); // 6
1946 mov_m32_reg32((unsigned int *)(&dword)+1, EDX); // 6
1947 shr_reg32_imm8(EBX, 16); // 3
1948 mov_reg32_preg32x4pimm32(EBX, EBX, (unsigned int)writememd); // 7
1949 call_reg32(EBX); // 2
1950 mov_eax_memoffs32((unsigned int *)(&address)); // 5
1951 jmp_imm_short(20); // 2
1952
1953 mov_reg32_reg32(EAX, EBX); // 2
1954 and_reg32_imm32(EBX, 0x7FFFFF); // 6
1955 mov_preg32pimm32_reg32(EBX, ((unsigned int)rdram)+4, ECX); // 6
1956 mov_preg32pimm32_reg32(EBX, ((unsigned int)rdram)+0, EDX); // 6
1957
1958 mov_reg32_reg32(EBX, EAX);
1959 shr_reg32_imm8(EBX, 12);
1960 cmp_preg32pimm32_imm8(EBX, (unsigned int)invalid_code, 0);
1961 jne_rj(54);
1962 mov_reg32_reg32(ECX, EBX); // 2
1963 shl_reg32_imm8(EBX, 2); // 3
1964 mov_reg32_preg32pimm32(EBX, EBX, (unsigned int)blocks); // 6
1965 mov_reg32_preg32pimm32(EBX, EBX, (int)&actual->block - (int)actual); // 6
1966 and_eax_imm32(0xFFF); // 5
1967 shr_reg32_imm8(EAX, 2); // 3
1968 mov_reg32_imm32(EDX, sizeof(precomp_instr)); // 5
1969 mul_reg32(EDX); // 2
1970 mov_reg32_preg32preg32pimm32(EAX, EAX, EBX, (int)&dst->ops - (int)dst); // 7
1971 cmp_reg32_imm32(EAX, (unsigned int)cached_interpreter_table.NOTCOMPILED); // 6
1972 je_rj(7); // 2
1973 mov_preg32pimm32_imm8(ECX, (unsigned int)invalid_code, 1); // 7
1974#endif
1975}
1976
1977void gensd(void)
1978{
1979#ifdef INTERPRET_SD
1980 gencallinterp((unsigned int)cached_interpreter_table.SD, 0);
1981#else
1982 free_all_registers();
1983 simplify_access();
1984
1985 mov_reg32_m32(ECX, (unsigned int *)dst->f.i.rt);
1986 mov_reg32_m32(EDX, ((unsigned int *)dst->f.i.rt)+1);
1987 mov_eax_memoffs32((unsigned int *)dst->f.i.rs);
1988 add_eax_imm32((int)dst->f.i.immediate);
1989 mov_reg32_reg32(EBX, EAX);
1990 if(fast_memory)
1991 {
1992 and_eax_imm32(0xDF800000);
1993 cmp_eax_imm32(0x80000000);
1994 }
1995 else
1996 {
1997 shr_reg32_imm8(EAX, 16);
1998 mov_reg32_preg32x4pimm32(EAX, EAX, (unsigned int)writememd);
1999 cmp_reg32_imm32(EAX, (unsigned int)write_rdramd);
2000 }
2001 je_rj(47);
2002
2003 mov_m32_imm32((unsigned int *)(&PC), (unsigned int)(dst+1)); // 10
2004 mov_m32_reg32((unsigned int *)(&address), EBX); // 6
2005 mov_m32_reg32((unsigned int *)(&dword), ECX); // 6
2006 mov_m32_reg32((unsigned int *)(&dword)+1, EDX); // 6
2007 shr_reg32_imm8(EBX, 16); // 3
2008 mov_reg32_preg32x4pimm32(EBX, EBX, (unsigned int)writememd); // 7
2009 call_reg32(EBX); // 2
2010 mov_eax_memoffs32((unsigned int *)(&address)); // 5
2011 jmp_imm_short(20); // 2
2012
2013 mov_reg32_reg32(EAX, EBX); // 2
2014 and_reg32_imm32(EBX, 0x7FFFFF); // 6
2015 mov_preg32pimm32_reg32(EBX, ((unsigned int)rdram)+4, ECX); // 6
2016 mov_preg32pimm32_reg32(EBX, ((unsigned int)rdram)+0, EDX); // 6
2017
2018 mov_reg32_reg32(EBX, EAX);
2019 shr_reg32_imm8(EBX, 12);
2020 cmp_preg32pimm32_imm8(EBX, (unsigned int)invalid_code, 0);
2021 jne_rj(54);
2022 mov_reg32_reg32(ECX, EBX); // 2
2023 shl_reg32_imm8(EBX, 2); // 3
2024 mov_reg32_preg32pimm32(EBX, EBX, (unsigned int)blocks); // 6
2025 mov_reg32_preg32pimm32(EBX, EBX, (int)&actual->block - (int)actual); // 6
2026 and_eax_imm32(0xFFF); // 5
2027 shr_reg32_imm8(EAX, 2); // 3
2028 mov_reg32_imm32(EDX, sizeof(precomp_instr)); // 5
2029 mul_reg32(EDX); // 2
2030 mov_reg32_preg32preg32pimm32(EAX, EAX, EBX, (int)&dst->ops - (int)dst); // 7
2031 cmp_reg32_imm32(EAX, (unsigned int)cached_interpreter_table.NOTCOMPILED); // 6
2032 je_rj(7); // 2
2033 mov_preg32pimm32_imm8(ECX, (unsigned int)invalid_code, 1); // 7
2034#endif
2035}
2036
2037void genll(void)
2038{
2039 gencallinterp((unsigned int)cached_interpreter_table.LL, 0);
2040}
2041
2042void gensc(void)
2043{
2044 gencallinterp((unsigned int)cached_interpreter_table.SC, 0);
2045}
2046