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