RICE: OOT Fix from mupen64plus-ae team
[mupen64plus-pandora.git] / source / mupen64plus-core / src / r4300 / x86_64 / gr4300.c
CommitLineData
451ab91e 1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Mupen64plus - gr4300.c *
3 * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
4 * Copyright (C) 2007 Richard Goedeken (Richard42) *
5 * Copyright (C) 2002 Hacktarux *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
21 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
22
23#include "assemble.h"
24#include "regcache.h"
25#include "interpret.h"
26
27#include "api/debugger.h"
28
29#include "r4300/r4300.h"
30#include "r4300/macros.h"
31#include "r4300/interupt.h"
32#include "r4300/ops.h"
33#include "r4300/recomph.h"
34#include "r4300/exception.h"
35
36#include "memory/memory.h"
37
38#if !defined(offsetof)
39# define offsetof(TYPE,MEMBER) ((unsigned int) &((TYPE*)0)->MEMBER)
40#endif
41
42#if defined(COUNT_INSTR)
43unsigned int instr_count[132];
44char instr_name[][10] =
45{
46 "reserved", "NI", "J", "JAL", "BEQ", "BNE", "BLEZ", "BGTZ",
47 "ADDI", "ADDIU", "SLTI", "SLTIU", "ANDI", "ORI", "XORI", "LUI",
48 "BEQL", "BNEL", "BLEZL", "BGTZL", "DADDI", "DADDIU", "LDL", "LDR",
49 "LB", "LH", "LW", "LWL", "LBU", "LHU", "LWU", "LWR",
50 "SB", "SH", "SW", "SWL", "SWR", "SDL", "SDR", "LWC1",
51 "LDC1", "LD", "LL", "SWC1", "SDC1", "SD", "SC", "BLTZ",
52 "BGEZ", "BLTZL", "BGEZL", "BLTZAL", "BGEZAL", "BLTZALL", "BGEZALL", "SLL",
53 "SRL", "SRA", "SLLV", "SRLV", "SRAV", "JR", "JALR", "SYSCALL",
54 "MFHI", "MTHI", "MFLO", "MTLO", "DSLLV", "DSRLV", "DSRAV", "MULT",
55 "MULTU", "DIV", "DIVU", "DMULT", "DMULTU", "DDIV", "DDIVU", "ADD",
56 "ADDU", "SUB", "SUBU", "AND", "OR", "XOR", "NOR", "SLT",
57 "SLTU", "DADD", "DADDU", "DSUB", "DSUBU", "DSLL", "DSRL", "DSRA",
58 "TEQ", "DSLL32", "DSRL32", "DSRA32", "BC1F", "BC1T", "BC1FL", "BC1TL",
59 "TLBWI", "TLBP", "TLBR", "TLBWR", "ERET", "MFC0", "MTC0", "MFC1",
60 "DMFC1", "CFC1", "MTC1", "DMTC1", "CTC1", "f.CVT", "f.CMP", "f.ADD",
61 "f.SUB", "f.MUL", "f.DIV", "f.SQRT", "f.ABS", "f.MOV", "f.NEG", "f.ROUND",
62 "f.TRUNC", "f.CEIL", "f.FLOOR"
63};
64unsigned int instr_type[131] = { 9, 10, 6, 6, 7, 7, 7, 7, 3, 3, 4, 4, 3, 4, 4, 0,
65 7, 7, 7, 7, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
66 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 7,
67 7, 7, 7, 7, 7, 7, 7, 3, 3, 3, 3, 3, 3, 6, 6, 10,
68 2, 2, 2, 2, 4, 4, 4, 3, 3, 3, 3, 4, 4, 4, 4, 3,
69 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
70 8, 4, 4, 4, 7, 7, 7, 7, 10, 10, 10, 10, 8, 2, 2, 2,
71 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 2, 5, 5,
72 5, 5, 5 };
73char instr_typename[][20] = { "Load", "Store", "Data move/convert", "32-bit math", "64-bit math", "Float Math",
74 "Jump", "Branch", "Exceptions", "Reserved", "Other" };
75#endif
76
77extern unsigned int op;
78
79static precomp_instr fake_instr;
80#ifdef COMPARE_CORE
81static long long debug_reg_storage[8];
82#endif
83
84int branch_taken = 0;
85
86/* static functions */
87
88static void genupdate_count(unsigned int addr)
89{
90#if !defined(COMPARE_CORE) && !defined(DBG)
91 mov_reg32_imm32(EAX, addr);
92 sub_xreg32_m32rel(EAX, (unsigned int*)(&last_addr));
93 shr_reg32_imm8(EAX, 1);
94 add_m32rel_xreg32((unsigned int*)(&Count), EAX);
95#else
96 mov_reg64_imm64(RAX, (unsigned long long) (dst+1));
97 mov_m64rel_xreg64((unsigned long long *)(&PC), RAX);
98 mov_reg64_imm64(RAX, (unsigned long long)update_count);
99 call_reg64(RAX);
100#endif
101}
102
103static void gencheck_interupt(unsigned long long instr_structure)
104{
105 mov_xreg32_m32rel(EAX, (void*)(&next_interupt));
106 cmp_xreg32_m32rel(EAX, (void*)&Count);
107 ja_rj(0);
108 jump_start_rel8();
109
110 mov_reg64_imm64(RAX, (unsigned long long) instr_structure);
111 mov_m64rel_xreg64((unsigned long long *)(&PC), RAX);
112 mov_reg64_imm64(RAX, (unsigned long long) gen_interupt);
113 call_reg64(RAX);
114
115 jump_end_rel8();
116}
117
118static void gencheck_interupt_out(unsigned int addr)
119{
120 mov_xreg32_m32rel(EAX, (void*)(&next_interupt));
121 cmp_xreg32_m32rel(EAX, (void*)&Count);
122 ja_rj(0);
123 jump_start_rel8();
124
125 mov_m32rel_imm32((unsigned int*)(&fake_instr.addr), addr);
126 mov_reg64_imm64(RAX, (unsigned long long) (&fake_instr));
127 mov_m64rel_xreg64((unsigned long long *)(&PC), RAX);
128 mov_reg64_imm64(RAX, (unsigned long long) gen_interupt);
129 call_reg64(RAX);
130
131 jump_end_rel8();
132}
133
134static void genbeq_test(void)
135{
136 int rs_64bit = is64((unsigned int *)dst->f.i.rs);
137 int rt_64bit = is64((unsigned int *)dst->f.i.rt);
138
139 if (rs_64bit == 0 && rt_64bit == 0)
140 {
141 int rs = allocate_register_32((unsigned int *)dst->f.i.rs);
142 int rt = allocate_register_32((unsigned int *)dst->f.i.rt);
143
144 cmp_reg32_reg32(rs, rt);
145 sete_m8rel((unsigned char *) &branch_taken);
146 }
147 else if (rs_64bit == -1)
148 {
149 int rt = allocate_register_64((unsigned long long *)dst->f.i.rt);
150
151 cmp_xreg64_m64rel(rt, (unsigned long long *) dst->f.i.rs);
152 sete_m8rel((unsigned char *) &branch_taken);
153 }
154 else if (rt_64bit == -1)
155 {
156 int rs = allocate_register_64((unsigned long long *)dst->f.i.rs);
157
158 cmp_xreg64_m64rel(rs, (unsigned long long *)dst->f.i.rt);
159 sete_m8rel((unsigned char *) &branch_taken);
160 }
161 else
162 {
163 int rs = allocate_register_64((unsigned long long *)dst->f.i.rs);
164 int rt = allocate_register_64((unsigned long long *)dst->f.i.rt);
165 cmp_reg64_reg64(rs, rt);
166 sete_m8rel((unsigned char *) &branch_taken);
167 }
168}
169
170static void genbne_test(void)
171{
172 int rs_64bit = is64((unsigned int *)dst->f.i.rs);
173 int rt_64bit = is64((unsigned int *)dst->f.i.rt);
174
175 if (rs_64bit == 0 && rt_64bit == 0)
176 {
177 int rs = allocate_register_32((unsigned int *)dst->f.i.rs);
178 int rt = allocate_register_32((unsigned int *)dst->f.i.rt);
179
180 cmp_reg32_reg32(rs, rt);
181 setne_m8rel((unsigned char *) &branch_taken);
182 }
183 else if (rs_64bit == -1)
184 {
185 int rt = allocate_register_64((unsigned long long *) dst->f.i.rt);
186
187 cmp_xreg64_m64rel(rt, (unsigned long long *)dst->f.i.rs);
188 setne_m8rel((unsigned char *) &branch_taken);
189 }
190 else if (rt_64bit == -1)
191 {
192 int rs = allocate_register_64((unsigned long long *) dst->f.i.rs);
193
194 cmp_xreg64_m64rel(rs, (unsigned long long *)dst->f.i.rt);
195 setne_m8rel((unsigned char *) &branch_taken);
196 }
197 else
198 {
199 int rs = allocate_register_64((unsigned long long *)dst->f.i.rs);
200 int rt = allocate_register_64((unsigned long long *)dst->f.i.rt);
201
202 cmp_reg64_reg64(rs, rt);
203 setne_m8rel((unsigned char *) &branch_taken);
204 }
205}
206
207static void genblez_test(void)
208{
209 int rs_64bit = is64((unsigned int *)dst->f.i.rs);
210
211 if (rs_64bit == 0)
212 {
213 int rs = allocate_register_32((unsigned int *)dst->f.i.rs);
214
215 cmp_reg32_imm32(rs, 0);
216 setle_m8rel((unsigned char *) &branch_taken);
217 }
218 else
219 {
220 int rs = allocate_register_64((unsigned long long *)dst->f.i.rs);
221
222 cmp_reg64_imm8(rs, 0);
223 setle_m8rel((unsigned char *) &branch_taken);
224 }
225}
226
227static void genbgtz_test(void)
228{
229 int rs_64bit = is64((unsigned int *)dst->f.i.rs);
230
231 if (rs_64bit == 0)
232 {
233 int rs = allocate_register_32((unsigned int *)dst->f.i.rs);
234
235 cmp_reg32_imm32(rs, 0);
236 setg_m8rel((unsigned char *) &branch_taken);
237 }
238 else
239 {
240 int rs = allocate_register_64((unsigned long long *)dst->f.i.rs);
241
242 cmp_reg64_imm8(rs, 0);
243 setg_m8rel((unsigned char *) &branch_taken);
244 }
245}
246
247static void ld_register_alloc(int *pGpr1, int *pGpr2, int *pBase1, int *pBase2)
248{
249 int gpr1, gpr2, base1, base2 = 0;
250
251#ifdef COMPARE_CORE
252 free_registers_move_start(); // to maintain parity with 32-bit core
253#endif
254
255 if (dst->f.i.rs == dst->f.i.rt)
256 {
257 allocate_register_32((unsigned int*)dst->f.r.rs); // tell regcache we need to read RS register here
258 gpr1 = allocate_register_32_w((unsigned int*)dst->f.r.rt); // tell regcache we will modify RT register during this instruction
259 gpr2 = lock_register(lru_register()); // free and lock least recently used register for usage here
260 add_reg32_imm32(gpr1, (int)dst->f.i.immediate);
261 mov_reg32_reg32(gpr2, gpr1);
262 }
263 else
264 {
265 gpr2 = allocate_register_32((unsigned int*)dst->f.r.rs); // tell regcache we need to read RS register here
266 gpr1 = allocate_register_32_w((unsigned int*)dst->f.r.rt); // tell regcache we will modify RT register during this instruction
267 free_register(gpr2); // write out gpr2 if dirty because I'm going to trash it right now
268 add_reg32_imm32(gpr2, (int)dst->f.i.immediate);
269 mov_reg32_reg32(gpr1, gpr2);
270 lock_register(gpr2); // lock the freed gpr2 it so it doesn't get returned in the lru query
271 }
272 base1 = lock_register(lru_base_register()); // get another lru register
273 if (!fast_memory)
274 {
275 base2 = lock_register(lru_base_register()); // and another one if necessary
276 unlock_register(base2);
277 }
278 unlock_register(base1); // unlock the locked registers (they are
279 unlock_register(gpr2);
280 set_register_state(gpr1, NULL, 0, 0); // clear gpr1 state because it hasn't been written yet -
281 // we don't want it to be pushed/popped around read_rdramX call
282 *pGpr1 = gpr1;
283 *pGpr2 = gpr2;
284 *pBase1 = base1;
285 *pBase2 = base2;
286}
287
288
289/* global functions */
290
291void gennotcompiled(void)
292{
293 free_registers_move_start();
294
295 mov_reg64_imm64(RAX, (unsigned long long) dst);
296 mov_memoffs64_rax((unsigned long long *) &PC); /* RIP-relative will not work here */
297 mov_reg64_imm64(RAX, (unsigned long long) cached_interpreter_table.NOTCOMPILED);
298 call_reg64(RAX);
299}
300
301void genlink_subblock(void)
302{
303 free_all_registers();
304 jmp(dst->addr+4);
305}
306
307#ifdef COMPARE_CORE
308void gendebug(void)
309{
310 free_all_registers();
311
312 mov_memoffs64_rax((unsigned long long *) &debug_reg_storage);
313 mov_reg64_imm64(RAX, (unsigned long long) &debug_reg_storage);
314 mov_preg64pimm8_reg64(RAX, 8, RBX);
315 mov_preg64pimm8_reg64(RAX, 16, RCX);
316 mov_preg64pimm8_reg64(RAX, 24, RDX);
317 mov_preg64pimm8_reg64(RAX, 32, RSP);
318 mov_preg64pimm8_reg64(RAX, 40, RBP);
319 mov_preg64pimm8_reg64(RAX, 48, RSI);
320 mov_preg64pimm8_reg64(RAX, 56, RDI);
321
322 mov_reg64_imm64(RAX, (unsigned long long) dst);
323 mov_memoffs64_rax((unsigned long long *) &PC);
324 mov_reg32_imm32(EAX, (unsigned int) src);
325 mov_memoffs32_eax((unsigned int *) &op);
326 mov_reg64_imm64(RAX, (unsigned long long) CoreCompareCallback);
327 call_reg64(RAX);
328
329 mov_reg64_imm64(RAX, (unsigned long long) &debug_reg_storage);
330 mov_reg64_preg64pimm8(RDI, RAX, 56);
331 mov_reg64_preg64pimm8(RSI, RAX, 48);
332 mov_reg64_preg64pimm8(RBP, RAX, 40);
333 mov_reg64_preg64pimm8(RSP, RAX, 32);
334 mov_reg64_preg64pimm8(RDX, RAX, 24);
335 mov_reg64_preg64pimm8(RCX, RAX, 16);
336 mov_reg64_preg64pimm8(RBX, RAX, 8);
337 mov_reg64_preg64(RAX, RAX);
338}
339#endif
340
341void gencallinterp(unsigned long addr, int jump)
342{
343 free_registers_move_start();
344
345 if (jump)
346 mov_m32rel_imm32((unsigned int*)(&dyna_interp), 1);
347
348 mov_reg64_imm64(RAX, (unsigned long long) dst);
349 mov_m64rel_xreg64((unsigned long long *)(&PC), RAX);
350 mov_reg64_imm64(RAX, addr);
351 call_reg64(RAX);
352
353 if (jump)
354 {
355 mov_m32rel_imm32((unsigned int*)(&dyna_interp), 0);
356 mov_reg64_imm64(RAX, (unsigned long long)dyna_jump);
357 call_reg64(RAX);
358 }
359}
360
361void gendelayslot(void)
362{
363 mov_m32rel_imm32((void*)(&delay_slot), 1);
364 recompile_opcode();
365
366 free_all_registers();
367 genupdate_count(dst->addr+4);
368
369 mov_m32rel_imm32((void*)(&delay_slot), 0);
370}
371
372void genni(void)
373{
374#if defined(COUNT_INSTR)
375 inc_m32rel(&instr_count[1]);
376#endif
377 gencallinterp((unsigned long long)cached_interpreter_table.NI, 0);
378}
379
380void genreserved(void)
381{
382#if defined(COUNT_INSTR)
383 inc_m32rel(&instr_count[0]);
384#endif
385 gencallinterp((unsigned long long)cached_interpreter_table.RESERVED, 0);
386}
387
388void genfin_block(void)
389{
390 gencallinterp((unsigned long long)cached_interpreter_table.FIN_BLOCK, 0);
391}
392
393void gencheck_interupt_reg(void) // addr is in EAX
394{
395 mov_xreg32_m32rel(EBX, (void*)&next_interupt);
396 cmp_xreg32_m32rel(EBX, (void*)&Count);
397 ja_rj(0);
398 jump_start_rel8();
399
400 mov_m32rel_xreg32((unsigned int*)(&fake_instr.addr), EAX);
401 mov_reg64_imm64(RAX, (unsigned long long) (&fake_instr));
402 mov_m64rel_xreg64((unsigned long long *)(&PC), RAX);
403 mov_reg64_imm64(RAX, (unsigned long long) gen_interupt);
404 call_reg64(RAX);
405
406 jump_end_rel8();
407}
408
409void gennop(void)
410{
411}
412
413void genj(void)
414{
415#if defined(COUNT_INSTR)
416 inc_m32rel(&instr_count[2]);
417#endif
418#ifdef INTERPRET_J
419 gencallinterp((unsigned long long)cached_interpreter_table.J, 1);
420#else
421 unsigned int naddr;
422
423 if (((dst->addr & 0xFFF) == 0xFFC &&
424 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
425 {
426 gencallinterp((unsigned long long)cached_interpreter_table.J, 1);
427 return;
428 }
429
430 gendelayslot();
431 naddr = ((dst-1)->f.j.inst_index<<2) | (dst->addr & 0xF0000000);
432
433 mov_m32rel_imm32((void*)(&last_addr), naddr);
434 gencheck_interupt((unsigned long long) &actual->block[(naddr-actual->start)/4]);
435 jmp(naddr);
436#endif
437}
438
439void genj_out(void)
440{
441#if defined(COUNT_INSTR)
442 inc_m32rel(&instr_count[2]);
443#endif
444#ifdef INTERPRET_J_OUT
445 gencallinterp((unsigned long long)cached_interpreter_table.J_OUT, 1);
446#else
447 unsigned int naddr;
448
449 if (((dst->addr & 0xFFF) == 0xFFC &&
450 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
451 {
452 gencallinterp((unsigned long long)cached_interpreter_table.J_OUT, 1);
453 return;
454 }
455
456 gendelayslot();
457 naddr = ((dst-1)->f.j.inst_index<<2) | (dst->addr & 0xF0000000);
458
459 mov_m32rel_imm32((void*)(&last_addr), naddr);
460 gencheck_interupt_out(naddr);
461 mov_m32rel_imm32(&jump_to_address, naddr);
462 mov_reg64_imm64(RAX, (unsigned long long) (dst+1));
463 mov_m64rel_xreg64((unsigned long long *)(&PC), RAX);
464 mov_reg64_imm64(RAX, (unsigned long long)jump_to_func);
465 call_reg64(RAX);
466#endif
467}
468
469void genj_idle(void)
470{
471#if defined(COUNT_INSTR)
472 inc_m32rel(&instr_count[2]);
473#endif
474#ifdef INTERPRET_J_IDLE
475 gencallinterp((unsigned long long)cached_interpreter_table.J_IDLE, 1);
476#else
477 if (((dst->addr & 0xFFF) == 0xFFC &&
478 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
479 {
480 gencallinterp((unsigned long long)cached_interpreter_table.J_IDLE, 1);
481 return;
482 }
483
484 mov_xreg32_m32rel(EAX, (unsigned int *)(&next_interupt));
485 sub_xreg32_m32rel(EAX, (unsigned int *)(&Count));
486 cmp_reg32_imm8(EAX, 3);
487 jbe_rj(12);
488
489 and_eax_imm32(0xFFFFFFFC); // 5
490 add_m32rel_xreg32((unsigned int *)(&Count), EAX); // 7
491
492 genj();
493#endif
494}
495
496void genjal(void)
497{
498#if defined(COUNT_INSTR)
499 inc_m32rel(&instr_count[3]);
500#endif
501#ifdef INTERPRET_JAL
502 gencallinterp((unsigned long long)cached_interpreter_table.JAL, 1);
503#else
504 unsigned int naddr;
505
506 if (((dst->addr & 0xFFF) == 0xFFC &&
507 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
508 {
509 gencallinterp((unsigned long long)cached_interpreter_table.JAL, 1);
510 return;
511 }
512
513 gendelayslot();
514
515 mov_m32rel_imm32((unsigned int *)(reg + 31), dst->addr + 4);
516 if (((dst->addr + 4) & 0x80000000))
517 mov_m32rel_imm32((unsigned int *)(&reg[31])+1, 0xFFFFFFFF);
518 else
519 mov_m32rel_imm32((unsigned int *)(&reg[31])+1, 0);
520
521 naddr = ((dst-1)->f.j.inst_index<<2) | (dst->addr & 0xF0000000);
522
523 mov_m32rel_imm32((void*)(&last_addr), naddr);
524 gencheck_interupt((unsigned long long) &actual->block[(naddr-actual->start)/4]);
525 jmp(naddr);
526#endif
527}
528
529void genjal_out(void)
530{
531#if defined(COUNT_INSTR)
532 inc_m32rel(&instr_count[3]);
533#endif
534#ifdef INTERPRET_JAL_OUT
535 gencallinterp((unsigned long long)cached_interpreter_table.JAL_OUT, 1);
536#else
537 unsigned int naddr;
538
539 if (((dst->addr & 0xFFF) == 0xFFC &&
540 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
541 {
542 gencallinterp((unsigned long long)cached_interpreter_table.JAL_OUT, 1);
543 return;
544 }
545
546 gendelayslot();
547
548 mov_m32rel_imm32((unsigned int *)(reg + 31), dst->addr + 4);
549 if (((dst->addr + 4) & 0x80000000))
550 mov_m32rel_imm32((unsigned int *)(&reg[31])+1, 0xFFFFFFFF);
551 else
552 mov_m32rel_imm32((unsigned int *)(&reg[31])+1, 0);
553
554 naddr = ((dst-1)->f.j.inst_index<<2) | (dst->addr & 0xF0000000);
555
556 mov_m32rel_imm32((void*)(&last_addr), naddr);
557 gencheck_interupt_out(naddr);
558 mov_m32rel_imm32(&jump_to_address, naddr);
559 mov_reg64_imm64(RAX, (unsigned long long) (dst+1));
560 mov_m64rel_xreg64((unsigned long long *)(&PC), RAX);
561 mov_reg64_imm64(RAX, (unsigned long long) jump_to_func);
562 call_reg64(RAX);
563#endif
564}
565
566void genjal_idle(void)
567{
568#if defined(COUNT_INSTR)
569 inc_m32rel(&instr_count[3]);
570#endif
571#ifdef INTERPRET_JAL_IDLE
572 gencallinterp((unsigned long long)cached_interpreter_table.JAL_IDLE, 1);
573#else
574 if (((dst->addr & 0xFFF) == 0xFFC &&
575 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
576 {
577 gencallinterp((unsigned long long)cached_interpreter_table.JAL_IDLE, 1);
578 return;
579 }
580
581 mov_xreg32_m32rel(EAX, (unsigned int *)(&next_interupt));
582 sub_xreg32_m32rel(EAX, (unsigned int *)(&Count));
583 cmp_reg32_imm8(EAX, 3);
584 jbe_rj(12);
585
586 and_eax_imm32(0xFFFFFFFC); // 5
587 add_m32rel_xreg32((unsigned int *)(&Count), EAX); // 7
588
589 genjal();
590#endif
591}
592
593void gentest(void)
594{
595 cmp_m32rel_imm32((unsigned int *)(&branch_taken), 0);
596 je_near_rj(0);
597 jump_start_rel32();
598
599 mov_m32rel_imm32((void*)(&last_addr), dst->addr + (dst-1)->f.i.immediate*4);
600 gencheck_interupt((unsigned long long) (dst + (dst-1)->f.i.immediate));
601 jmp(dst->addr + (dst-1)->f.i.immediate*4);
602
603 jump_end_rel32();
604
605 mov_m32rel_imm32((void*)(&last_addr), dst->addr + 4);
606 gencheck_interupt((unsigned long long)(dst + 1));
607 jmp(dst->addr + 4);
608}
609
610void genbeq(void)
611{
612#if defined(COUNT_INSTR)
613 inc_m32rel(&instr_count[4]);
614#endif
615#ifdef INTERPRET_BEQ
616 gencallinterp((unsigned long long)cached_interpreter_table.BEQ, 1);
617#else
618 if (((dst->addr & 0xFFF) == 0xFFC &&
619 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
620 {
621 gencallinterp((unsigned long long)cached_interpreter_table.BEQ, 1);
622 return;
623 }
624
625 genbeq_test();
626 gendelayslot();
627 gentest();
628#endif
629}
630
631void gentest_out(void)
632{
633 cmp_m32rel_imm32((unsigned int *)(&branch_taken), 0);
634 je_near_rj(0);
635 jump_start_rel32();
636
637 mov_m32rel_imm32((void*)(&last_addr), dst->addr + (dst-1)->f.i.immediate*4);
638 gencheck_interupt_out(dst->addr + (dst-1)->f.i.immediate*4);
639 mov_m32rel_imm32(&jump_to_address, dst->addr + (dst-1)->f.i.immediate*4);
640 mov_reg64_imm64(RAX, (unsigned long long) (dst+1));
641 mov_m64rel_xreg64((unsigned long long *)(&PC), RAX);
642 mov_reg64_imm64(RAX, (unsigned long long) jump_to_func);
643 call_reg64(RAX);
644 jump_end_rel32();
645
646 mov_m32rel_imm32((void*)(&last_addr), dst->addr + 4);
647 gencheck_interupt((unsigned long long) (dst + 1));
648 jmp(dst->addr + 4);
649}
650
651void genbeq_out(void)
652{
653#if defined(COUNT_INSTR)
654 inc_m32rel(&instr_count[4]);
655#endif
656#ifdef INTERPRET_BEQ_OUT
657 gencallinterp((unsigned long long)cached_interpreter_table.BEQ_OUT, 1);
658#else
659 if (((dst->addr & 0xFFF) == 0xFFC &&
660 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
661 {
662 gencallinterp((unsigned long long)cached_interpreter_table.BEQ_OUT, 1);
663 return;
664 }
665
666 genbeq_test();
667 gendelayslot();
668 gentest_out();
669#endif
670}
671
672void gentest_idle(void)
673{
674 int reg;
675
676 reg = lru_register();
677 free_register(reg);
678
679 cmp_m32rel_imm32((unsigned int *)(&branch_taken), 0);
680 je_near_rj(0);
681 jump_start_rel32();
682
683 mov_xreg32_m32rel(reg, (unsigned int *)(&next_interupt));
684 sub_xreg32_m32rel(reg, (unsigned int *)(&Count));
685 cmp_reg32_imm8(reg, 3);
686 jbe_rj(0);
687 jump_start_rel8();
688
689 and_reg32_imm32(reg, 0xFFFFFFFC);
690 add_m32rel_xreg32((unsigned int *)(&Count), reg);
691
692 jump_end_rel8();
693 jump_end_rel32();
694}
695
696void genbeq_idle(void)
697{
698#ifdef INTERPRET_BEQ_IDLE
699 gencallinterp((unsigned long long)cached_interpreter_table.BEQ_IDLE, 1);
700#else
701 if (((dst->addr & 0xFFF) == 0xFFC &&
702 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
703 {
704 gencallinterp((unsigned long long)cached_interpreter_table.BEQ_IDLE, 1);
705 return;
706 }
707
708 genbeq_test();
709 gentest_idle();
710 genbeq();
711#endif
712}
713
714void genbne(void)
715{
716#if defined(COUNT_INSTR)
717 inc_m32rel(&instr_count[5]);
718#endif
719#ifdef INTERPRET_BNE
720 gencallinterp((unsigned long long)cached_interpreter_table.BNE, 1);
721#else
722 if (((dst->addr & 0xFFF) == 0xFFC &&
723 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
724 {
725 gencallinterp((unsigned long long)cached_interpreter_table.BNE, 1);
726 return;
727 }
728
729 genbne_test();
730 gendelayslot();
731 gentest();
732#endif
733}
734
735void genbne_out(void)
736{
737#if defined(COUNT_INSTR)
738 inc_m32rel(&instr_count[5]);
739#endif
740#ifdef INTERPRET_BNE_OUT
741 gencallinterp((unsigned long long)cached_interpreter_table.BNE_OUT, 1);
742#else
743 if (((dst->addr & 0xFFF) == 0xFFC &&
744 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
745 {
746 gencallinterp((unsigned long long)cached_interpreter_table.BNE_OUT, 1);
747 return;
748 }
749
750 genbne_test();
751 gendelayslot();
752 gentest_out();
753#endif
754}
755
756void genbne_idle(void)
757{
758#ifdef INTERPRET_BNE_IDLE
759 gencallinterp((unsigned long long)cached_interpreter_table.BNE_IDLE, 1);
760#else
761 if (((dst->addr & 0xFFF) == 0xFFC &&
762 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
763 {
764 gencallinterp((unsigned long long)cached_interpreter_table.BNE_IDLE, 1);
765 return;
766 }
767
768 genbne_test();
769 gentest_idle();
770 genbne();
771#endif
772}
773
774void genblez(void)
775{
776#if defined(COUNT_INSTR)
777 inc_m32rel(&instr_count[6]);
778#endif
779#ifdef INTERPRET_BLEZ
780 gencallinterp((unsigned long long)cached_interpreter_table.BLEZ, 1);
781#else
782 if (((dst->addr & 0xFFF) == 0xFFC &&
783 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
784 {
785 gencallinterp((unsigned long long)cached_interpreter_table.BLEZ, 1);
786 return;
787 }
788
789 genblez_test();
790 gendelayslot();
791 gentest();
792#endif
793}
794
795void genblez_out(void)
796{
797#if defined(COUNT_INSTR)
798 inc_m32rel(&instr_count[6]);
799#endif
800#ifdef INTERPRET_BLEZ_OUT
801 gencallinterp((unsigned long long)cached_interpreter_table.BLEZ_OUT, 1);
802#else
803 if (((dst->addr & 0xFFF) == 0xFFC &&
804 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
805 {
806 gencallinterp((unsigned long long)cached_interpreter_table.BLEZ_OUT, 1);
807 return;
808 }
809
810 genblez_test();
811 gendelayslot();
812 gentest_out();
813#endif
814}
815
816void genblez_idle(void)
817{
818#ifdef INTERPRET_BLEZ_IDLE
819 gencallinterp((unsigned long long)cached_interpreter_table.BLEZ_IDLE, 1);
820#else
821 if (((dst->addr & 0xFFF) == 0xFFC &&
822 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
823 {
824 gencallinterp((unsigned long long)cached_interpreter_table.BLEZ_IDLE, 1);
825 return;
826 }
827
828 genblez_test();
829 gentest_idle();
830 genblez();
831#endif
832}
833
834void genbgtz(void)
835{
836#if defined(COUNT_INSTR)
837 inc_m32rel(&instr_count[7]);
838#endif
839#ifdef INTERPRET_BGTZ
840 gencallinterp((unsigned long long)cached_interpreter_table.BGTZ, 1);
841#else
842 if (((dst->addr & 0xFFF) == 0xFFC &&
843 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
844 {
845 gencallinterp((unsigned long long)cached_interpreter_table.BGTZ, 1);
846 return;
847 }
848
849 genbgtz_test();
850 gendelayslot();
851 gentest();
852#endif
853}
854
855void genbgtz_out(void)
856{
857#if defined(COUNT_INSTR)
858 inc_m32rel(&instr_count[7]);
859#endif
860#ifdef INTERPRET_BGTZ_OUT
861 gencallinterp((unsigned long long)cached_interpreter_table.BGTZ_OUT, 1);
862#else
863 if (((dst->addr & 0xFFF) == 0xFFC &&
864 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
865 {
866 gencallinterp((unsigned long long)cached_interpreter_table.BGTZ_OUT, 1);
867 return;
868 }
869
870 genbgtz_test();
871 gendelayslot();
872 gentest_out();
873#endif
874}
875
876void genbgtz_idle(void)
877{
878#ifdef INTERPRET_BGTZ_IDLE
879 gencallinterp((unsigned long long)cached_interpreter_table.BGTZ_IDLE, 1);
880#else
881 if (((dst->addr & 0xFFF) == 0xFFC &&
882 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
883 {
884 gencallinterp((unsigned long long)cached_interpreter_table.BGTZ_IDLE, 1);
885 return;
886 }
887
888 genbgtz_test();
889 gentest_idle();
890 genbgtz();
891#endif
892}
893
894void genaddi(void)
895{
896#if defined(COUNT_INSTR)
897 inc_m32rel(&instr_count[8]);
898#endif
899#ifdef INTERPRET_ADDI
900 gencallinterp((unsigned long long)cached_interpreter_table.ADDI, 0);
901#else
902 int rs = allocate_register_32((unsigned int *)dst->f.i.rs);
903 int rt = allocate_register_32_w((unsigned int *)dst->f.i.rt);
904
905 mov_reg32_reg32(rt, rs);
906 add_reg32_imm32(rt,(int)dst->f.i.immediate);
907#endif
908}
909
910void genaddiu(void)
911{
912#if defined(COUNT_INSTR)
913 inc_m32rel(&instr_count[9]);
914#endif
915#ifdef INTERPRET_ADDIU
916 gencallinterp((unsigned long long)cached_interpreter_table.ADDIU, 0);
917#else
918 int rs = allocate_register_32((unsigned int *)dst->f.i.rs);
919 int rt = allocate_register_32_w((unsigned int *)dst->f.i.rt);
920
921 mov_reg32_reg32(rt, rs);
922 add_reg32_imm32(rt,(int)dst->f.i.immediate);
923#endif
924}
925
926void genslti(void)
927{
928#if defined(COUNT_INSTR)
929 inc_m32rel(&instr_count[10]);
930#endif
931#ifdef INTERPRET_SLTI
932 gencallinterp((unsigned long long)cached_interpreter_table.SLTI, 0);
933#else
934 int rs = allocate_register_64((unsigned long long *) dst->f.i.rs);
935 int rt = allocate_register_64_w((unsigned long long *) dst->f.i.rt);
936 int imm = (int) dst->f.i.immediate;
937
938 cmp_reg64_imm32(rs, imm);
939 setl_reg8(rt);
940 and_reg64_imm8(rt, 1);
941#endif
942}
943
944void gensltiu(void)
945{
946#if defined(COUNT_INSTR)
947 inc_m32rel(&instr_count[11]);
948#endif
949#ifdef INTERPRET_SLTIU
950 gencallinterp((unsigned long long)cached_interpreter_table.SLTIU, 0);
951#else
952 int rs = allocate_register_64((unsigned long long *)dst->f.i.rs);
953 int rt = allocate_register_64_w((unsigned long long *)dst->f.i.rt);
954 int imm = (int) dst->f.i.immediate;
955
956 cmp_reg64_imm32(rs, imm);
957 setb_reg8(rt);
958 and_reg64_imm8(rt, 1);
959#endif
960}
961
962void genandi(void)
963{
964#if defined(COUNT_INSTR)
965 inc_m32rel(&instr_count[12]);
966#endif
967#ifdef INTERPRET_ANDI
968 gencallinterp((unsigned long long)cached_interpreter_table.ANDI, 0);
969#else
970 int rs = allocate_register_64((unsigned long long *)dst->f.i.rs);
971 int rt = allocate_register_64_w((unsigned long long *)dst->f.i.rt);
972
973 mov_reg64_reg64(rt, rs);
974 and_reg64_imm32(rt, (unsigned short)dst->f.i.immediate);
975#endif
976}
977
978void genori(void)
979{
980#if defined(COUNT_INSTR)
981 inc_m32rel(&instr_count[13]);
982#endif
983#ifdef INTERPRET_ORI
984 gencallinterp((unsigned long long)cached_interpreter_table.ORI, 0);
985#else
986 int rs = allocate_register_64((unsigned long long *) dst->f.i.rs);
987 int rt = allocate_register_64_w((unsigned long long *) dst->f.i.rt);
988
989 mov_reg64_reg64(rt, rs);
990 or_reg64_imm32(rt, (unsigned short)dst->f.i.immediate);
991#endif
992}
993
994void genxori(void)
995{
996#if defined(COUNT_INSTR)
997 inc_m32rel(&instr_count[14]);
998#endif
999#ifdef INTERPRET_XORI
1000 gencallinterp((unsigned long long)cached_interpreter_table.XORI, 0);
1001#else
1002 int rs = allocate_register_64((unsigned long long *)dst->f.i.rs);
1003 int rt = allocate_register_64_w((unsigned long long *)dst->f.i.rt);
1004
1005 mov_reg64_reg64(rt, rs);
1006 xor_reg64_imm32(rt, (unsigned short)dst->f.i.immediate);
1007#endif
1008}
1009
1010void genlui(void)
1011{
1012#if defined(COUNT_INSTR)
1013 inc_m32rel(&instr_count[15]);
1014#endif
1015#ifdef INTERPRET_LUI
1016 gencallinterp((unsigned long long)cached_interpreter_table.LUI, 0);
1017#else
1018 int rt = allocate_register_32_w((unsigned int *)dst->f.i.rt);
1019
1020 mov_reg32_imm32(rt, (unsigned int)dst->f.i.immediate << 16);
1021#endif
1022}
1023
1024void gentestl(void)
1025{
1026 cmp_m32rel_imm32((unsigned int *)(&branch_taken), 0);
1027 je_near_rj(0);
1028 jump_start_rel32();
1029
1030 gendelayslot();
1031 mov_m32rel_imm32((void*)(&last_addr), dst->addr + (dst-1)->f.i.immediate*4);
1032 gencheck_interupt((unsigned long long) (dst + (dst-1)->f.i.immediate));
1033 jmp(dst->addr + (dst-1)->f.i.immediate*4);
1034
1035 jump_end_rel32();
1036
1037 genupdate_count(dst->addr-4);
1038 mov_m32rel_imm32((void*)(&last_addr), dst->addr + 4);
1039 gencheck_interupt((unsigned long long) (dst + 1));
1040 jmp(dst->addr + 4);
1041}
1042
1043void genbeql(void)
1044{
1045#if defined(COUNT_INSTR)
1046 inc_m32rel(&instr_count[16]);
1047#endif
1048#ifdef INTERPRET_BEQL
1049 gencallinterp((unsigned long long)cached_interpreter_table.BEQL, 1);
1050#else
1051 if (((dst->addr & 0xFFF) == 0xFFC &&
1052 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
1053 {
1054 gencallinterp((unsigned long long)cached_interpreter_table.BEQL, 1);
1055 return;
1056 }
1057
1058 genbeq_test();
1059 free_all_registers();
1060 gentestl();
1061#endif
1062}
1063
1064void gentestl_out(void)
1065{
1066 cmp_m32rel_imm32((unsigned int *)(&branch_taken), 0);
1067 je_near_rj(0);
1068 jump_start_rel32();
1069
1070 gendelayslot();
1071 mov_m32rel_imm32((void*)(&last_addr), dst->addr + (dst-1)->f.i.immediate*4);
1072 gencheck_interupt_out(dst->addr + (dst-1)->f.i.immediate*4);
1073 mov_m32rel_imm32(&jump_to_address, dst->addr + (dst-1)->f.i.immediate*4);
1074
1075 mov_reg64_imm64(RAX, (unsigned long long) (dst+1));
1076 mov_m64rel_xreg64((unsigned long long *)(&PC), RAX);
1077 mov_reg64_imm64(RAX, (unsigned long long) jump_to_func);
1078 call_reg64(RAX);
1079
1080 jump_end_rel32();
1081
1082 genupdate_count(dst->addr-4);
1083 mov_m32rel_imm32((void*)(&last_addr), dst->addr + 4);
1084 gencheck_interupt((unsigned long long) (dst + 1));
1085 jmp(dst->addr + 4);
1086}
1087
1088void genbeql_out(void)
1089{
1090#if defined(COUNT_INSTR)
1091 inc_m32rel(&instr_count[16]);
1092#endif
1093#ifdef INTERPRET_BEQL_OUT
1094 gencallinterp((unsigned long long)cached_interpreter_table.BEQL_OUT, 1);
1095#else
1096 if (((dst->addr & 0xFFF) == 0xFFC &&
1097 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
1098 {
1099 gencallinterp((unsigned long long)cached_interpreter_table.BEQL_OUT, 1);
1100 return;
1101 }
1102
1103 genbeq_test();
1104 free_all_registers();
1105 gentestl_out();
1106#endif
1107}
1108
1109void genbeql_idle(void)
1110{
1111#ifdef INTERPRET_BEQL_IDLE
1112 gencallinterp((unsigned long long)cached_interpreter_table.BEQL_IDLE, 1);
1113#else
1114 if (((dst->addr & 0xFFF) == 0xFFC &&
1115 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
1116 {
1117 gencallinterp((unsigned long long)cached_interpreter_table.BEQL_IDLE, 1);
1118 return;
1119 }
1120
1121 genbeq_test();
1122 gentest_idle();
1123 genbeql();
1124#endif
1125}
1126
1127void genbnel(void)
1128{
1129#if defined(COUNT_INSTR)
1130 inc_m32rel(&instr_count[17]);
1131#endif
1132#ifdef INTERPRET_BNEL
1133 gencallinterp((unsigned long long)cached_interpreter_table.BNEL, 1);
1134#else
1135 if (((dst->addr & 0xFFF) == 0xFFC &&
1136 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
1137 {
1138 gencallinterp((unsigned long long)cached_interpreter_table.BNEL, 1);
1139 return;
1140 }
1141
1142 genbne_test();
1143 free_all_registers();
1144 gentestl();
1145#endif
1146}
1147
1148void genbnel_out(void)
1149{
1150#if defined(COUNT_INSTR)
1151 inc_m32rel(&instr_count[17]);
1152#endif
1153#ifdef INTERPRET_BNEL_OUT
1154 gencallinterp((unsigned long long)cached_interpreter_table.BNEL_OUT, 1);
1155#else
1156 if (((dst->addr & 0xFFF) == 0xFFC &&
1157 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
1158 {
1159 gencallinterp((unsigned long long)cached_interpreter_table.BNEL_OUT, 1);
1160 return;
1161 }
1162
1163 genbne_test();
1164 free_all_registers();
1165 gentestl_out();
1166#endif
1167}
1168
1169void genbnel_idle(void)
1170{
1171#ifdef INTERPRET_BNEL_IDLE
1172 gencallinterp((unsigned long long)cached_interpreter_table.BNEL_IDLE, 1);
1173#else
1174 if (((dst->addr & 0xFFF) == 0xFFC &&
1175 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
1176 {
1177 gencallinterp((unsigned long long)cached_interpreter_table.BNEL_IDLE, 1);
1178 return;
1179 }
1180
1181 genbne_test();
1182 gentest_idle();
1183 genbnel();
1184#endif
1185}
1186
1187void genblezl(void)
1188{
1189#if defined(COUNT_INSTR)
1190 inc_m32rel(&instr_count[18]);
1191#endif
1192#ifdef INTERPRET_BLEZL
1193 gencallinterp((unsigned long long)cached_interpreter_table.BLEZL, 1);
1194#else
1195 if (((dst->addr & 0xFFF) == 0xFFC &&
1196 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
1197 {
1198 gencallinterp((unsigned long long)cached_interpreter_table.BLEZL, 1);
1199 return;
1200 }
1201
1202 genblez_test();
1203 free_all_registers();
1204 gentestl();
1205#endif
1206}
1207
1208void genblezl_out(void)
1209{
1210#if defined(COUNT_INSTR)
1211 inc_m32rel(&instr_count[18]);
1212#endif
1213#ifdef INTERPRET_BLEZL_OUT
1214 gencallinterp((unsigned long long)cached_interpreter_table.BLEZL_OUT, 1);
1215#else
1216 if (((dst->addr & 0xFFF) == 0xFFC &&
1217 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
1218 {
1219 gencallinterp((unsigned long long)cached_interpreter_table.BLEZL_OUT, 1);
1220 return;
1221 }
1222
1223 genblez_test();
1224 free_all_registers();
1225 gentestl_out();
1226#endif
1227}
1228
1229void genblezl_idle(void)
1230{
1231#ifdef INTERPRET_BLEZL_IDLE
1232 gencallinterp((unsigned long long)cached_interpreter_table.BLEZL_IDLE, 1);
1233#else
1234 if (((dst->addr & 0xFFF) == 0xFFC &&
1235 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
1236 {
1237 gencallinterp((unsigned long long)cached_interpreter_table.BLEZL_IDLE, 1);
1238 return;
1239 }
1240
1241 genblez_test();
1242 gentest_idle();
1243 genblezl();
1244#endif
1245}
1246
1247void genbgtzl(void)
1248{
1249#if defined(COUNT_INSTR)
1250 inc_m32rel(&instr_count[19]);
1251#endif
1252#ifdef INTERPRET_BGTZL
1253 gencallinterp((unsigned long long)cached_interpreter_table.BGTZL, 1);
1254#else
1255 if (((dst->addr & 0xFFF) == 0xFFC &&
1256 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
1257 {
1258 gencallinterp((unsigned long long)cached_interpreter_table.BGTZL, 1);
1259 return;
1260 }
1261
1262 genbgtz_test();
1263 free_all_registers();
1264 gentestl();
1265#endif
1266}
1267
1268void genbgtzl_out(void)
1269{
1270#if defined(COUNT_INSTR)
1271 inc_m32rel(&instr_count[19]);
1272#endif
1273#ifdef INTERPRET_BGTZL_OUT
1274 gencallinterp((unsigned long long)cached_interpreter_table.BGTZL_OUT, 1);
1275#else
1276 if (((dst->addr & 0xFFF) == 0xFFC &&
1277 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
1278 {
1279 gencallinterp((unsigned long long)cached_interpreter_table.BGTZL_OUT, 1);
1280 return;
1281 }
1282
1283 genbgtz_test();
1284 free_all_registers();
1285 gentestl_out();
1286#endif
1287}
1288
1289void genbgtzl_idle(void)
1290{
1291#ifdef INTERPRET_BGTZL_IDLE
1292 gencallinterp((unsigned long long)cached_interpreter_table.BGTZL_IDLE, 1);
1293#else
1294 if (((dst->addr & 0xFFF) == 0xFFC &&
1295 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
1296 {
1297 gencallinterp((unsigned long long)cached_interpreter_table.BGTZL_IDLE, 1);
1298 return;
1299 }
1300
1301 genbgtz_test();
1302 gentest_idle();
1303 genbgtzl();
1304#endif
1305}
1306
1307void gendaddi(void)
1308{
1309#if defined(COUNT_INSTR)
1310 inc_m32rel(&instr_count[20]);
1311#endif
1312#ifdef INTERPRET_DADDI
1313 gencallinterp((unsigned long long)cached_interpreter_table.DADDI, 0);
1314#else
1315 int rs = allocate_register_64((unsigned long long *)dst->f.i.rs);
1316 int rt = allocate_register_64_w((unsigned long long *)dst->f.i.rt);
1317
1318 mov_reg64_reg64(rt, rs);
1319 add_reg64_imm32(rt, (int) dst->f.i.immediate);
1320#endif
1321}
1322
1323void gendaddiu(void)
1324{
1325#ifdef INTERPRET_DADDIU
1326 gencallinterp((unsigned long long)cached_interpreter_table.DADDIU, 0);
1327#else
1328 int rs = allocate_register_64((unsigned long long *)dst->f.i.rs);
1329 int rt = allocate_register_64_w((unsigned long long *)dst->f.i.rt);
1330
1331 mov_reg64_reg64(rt, rs);
1332 add_reg64_imm32(rt, (int) dst->f.i.immediate);
1333#endif
1334}
1335
1336void genldl(void)
1337{
1338#if defined(COUNT_INSTR)
1339 inc_m32rel(&instr_count[22]);
1340#endif
1341 gencallinterp((unsigned long long)cached_interpreter_table.LDL, 0);
1342}
1343
1344void genldr(void)
1345{
1346#if defined(COUNT_INSTR)
1347 inc_m32rel(&instr_count[23]);
1348#endif
1349 gencallinterp((unsigned long long)cached_interpreter_table.LDR, 0);
1350}
1351
1352void genlb(void)
1353{
1354 int gpr1, gpr2, base1, base2 = 0;
1355#if defined(COUNT_INSTR)
1356 inc_m32rel(&instr_count[24]);
1357#endif
1358#ifdef INTERPRET_LB
1359 gencallinterp((unsigned long long)cached_interpreter_table.LB, 0);
1360#else
1361 free_registers_move_start();
1362
1363 ld_register_alloc(&gpr1, &gpr2, &base1, &base2);
1364
1365 mov_reg64_imm64(base1, (unsigned long long) readmemb);
1366 if(fast_memory)
1367 {
1368 and_reg32_imm32(gpr1, 0xDF800000);
1369 cmp_reg32_imm32(gpr1, 0x80000000);
1370 }
1371 else
1372 {
1373 mov_reg64_imm64(base2, (unsigned long long) read_rdramb);
1374 shr_reg32_imm8(gpr1, 16);
1375 mov_reg64_preg64x8preg64(gpr1, gpr1, base1);
1376 cmp_reg64_reg64(gpr1, base2);
1377 }
1378 je_rj(0);
1379 jump_start_rel8();
1380
1381 mov_reg64_imm64(gpr1, (unsigned long long) (dst+1));
1382 mov_m64rel_xreg64((unsigned long long *)(&PC), gpr1);
1383 mov_m32rel_xreg32((unsigned int *)(&address), gpr2);
1384 mov_reg64_imm64(gpr1, (unsigned long long) dst->f.i.rt);
1385 mov_m64rel_xreg64((unsigned long long *)(&rdword), gpr1);
1386 shr_reg32_imm8(gpr2, 16);
1387 mov_reg64_preg64x8preg64(gpr2, gpr2, base1);
1388 call_reg64(gpr2);
1389 movsx_xreg32_m8rel(gpr1, (unsigned char *)dst->f.i.rt);
1390 jmp_imm_short(24);
1391
1392 jump_end_rel8();
1393 mov_reg64_imm64(base1, (unsigned long long) rdram); // 10
1394 and_reg32_imm32(gpr2, 0x7FFFFF); // 6
1395 xor_reg8_imm8(gpr2, 3); // 4
1396 movsx_reg32_8preg64preg64(gpr1, gpr2, base1); // 4
1397
1398 set_register_state(gpr1, (unsigned int*)dst->f.i.rt, 1, 0);
1399#endif
1400}
1401
1402void genlh(void)
1403{
1404 int gpr1, gpr2, base1, base2 = 0;
1405#if defined(COUNT_INSTR)
1406 inc_m32rel(&instr_count[25]);
1407#endif
1408#ifdef INTERPRET_LH
1409 gencallinterp((unsigned long long)cached_interpreter_table.LH, 0);
1410#else
1411 free_registers_move_start();
1412
1413 ld_register_alloc(&gpr1, &gpr2, &base1, &base2);
1414
1415 mov_reg64_imm64(base1, (unsigned long long) readmemh);
1416 if(fast_memory)
1417 {
1418 and_reg32_imm32(gpr1, 0xDF800000);
1419 cmp_reg32_imm32(gpr1, 0x80000000);
1420 }
1421 else
1422 {
1423 mov_reg64_imm64(base2, (unsigned long long) read_rdramh);
1424 shr_reg32_imm8(gpr1, 16);
1425 mov_reg64_preg64x8preg64(gpr1, gpr1, base1);
1426 cmp_reg64_reg64(gpr1, base2);
1427 }
1428 je_rj(0);
1429 jump_start_rel8();
1430
1431 mov_reg64_imm64(gpr1, (unsigned long long) (dst+1));
1432 mov_m64rel_xreg64((unsigned long long *)(&PC), gpr1);
1433 mov_m32rel_xreg32((unsigned int *)(&address), gpr2);
1434 mov_reg64_imm64(gpr1, (unsigned long long) dst->f.i.rt);
1435 mov_m64rel_xreg64((unsigned long long *)(&rdword), gpr1);
1436 shr_reg32_imm8(gpr2, 16);
1437 mov_reg64_preg64x8preg64(gpr2, gpr2, base1);
1438 call_reg64(gpr2);
1439 movsx_xreg32_m16rel(gpr1, (unsigned short *)dst->f.i.rt);
1440 jmp_imm_short(24);
1441
1442 jump_end_rel8();
1443 mov_reg64_imm64(base1, (unsigned long long) rdram); // 10
1444 and_reg32_imm32(gpr2, 0x7FFFFF); // 6
1445 xor_reg8_imm8(gpr2, 2); // 4
1446 movsx_reg32_16preg64preg64(gpr1, gpr2, base1); // 4
1447
1448 set_register_state(gpr1, (unsigned int*)dst->f.i.rt, 1, 0);
1449#endif
1450}
1451
1452void genlwl(void)
1453{
1454#if defined(COUNT_INSTR)
1455 inc_m32rel(&instr_count[27]);
1456#endif
1457 gencallinterp((unsigned long long)cached_interpreter_table.LWL, 0);
1458}
1459
1460void genlw(void)
1461{
1462 int gpr1, gpr2, base1, base2 = 0;
1463#if defined(COUNT_INSTR)
1464 inc_m32rel(&instr_count[26]);
1465#endif
1466#ifdef INTERPRET_LW
1467 gencallinterp((unsigned long long)cached_interpreter_table.LW, 0);
1468#else
1469 free_registers_move_start();
1470
1471 ld_register_alloc(&gpr1, &gpr2, &base1, &base2);
1472
1473 mov_reg64_imm64(base1, (unsigned long long) readmem);
1474 if(fast_memory)
1475 {
1476 and_reg32_imm32(gpr1, 0xDF800000);
1477 cmp_reg32_imm32(gpr1, 0x80000000);
1478 }
1479 else
1480 {
1481 mov_reg64_imm64(base2, (unsigned long long) read_rdram);
1482 shr_reg32_imm8(gpr1, 16);
1483 mov_reg64_preg64x8preg64(gpr1, gpr1, base1);
1484 cmp_reg64_reg64(gpr1, base2);
1485 }
1486 jne_rj(21);
1487
1488 mov_reg64_imm64(base1, (unsigned long long) rdram); // 10
1489 and_reg32_imm32(gpr2, 0x7FFFFF); // 6
1490 mov_reg32_preg64preg64(gpr1, gpr2, base1); // 3
1491 jmp_imm_short(0); // 2
1492 jump_start_rel8();
1493
1494 mov_reg64_imm64(gpr1, (unsigned long long) (dst+1));
1495 mov_m64rel_xreg64((unsigned long long *)(&PC), gpr1);
1496 mov_m32rel_xreg32((unsigned int *)(&address), gpr2);
1497 mov_reg64_imm64(gpr1, (unsigned long long) dst->f.i.rt);
1498 mov_m64rel_xreg64((unsigned long long *)(&rdword), gpr1);
1499 shr_reg32_imm8(gpr2, 16);
1500 mov_reg64_preg64x8preg64(gpr1, gpr2, base1);
1501 call_reg64(gpr1);
1502 mov_xreg32_m32rel(gpr1, (unsigned int *)(dst->f.i.rt));
1503
1504 jump_end_rel8();
1505
1506 set_register_state(gpr1, (unsigned int*)dst->f.i.rt, 1, 0); // set gpr1 state as dirty, and bound to r4300 reg RT
1507#endif
1508}
1509
1510void genlbu(void)
1511{
1512 int gpr1, gpr2, base1, base2 = 0;
1513#if defined(COUNT_INSTR)
1514 inc_m32rel(&instr_count[28]);
1515#endif
1516#ifdef INTERPRET_LBU
1517 gencallinterp((unsigned long long)cached_interpreter_table.LBU, 0);
1518#else
1519 free_registers_move_start();
1520
1521 ld_register_alloc(&gpr1, &gpr2, &base1, &base2);
1522
1523 mov_reg64_imm64(base1, (unsigned long long) readmemb);
1524 if(fast_memory)
1525 {
1526 and_reg32_imm32(gpr1, 0xDF800000);
1527 cmp_reg32_imm32(gpr1, 0x80000000);
1528 }
1529 else
1530 {
1531 mov_reg64_imm64(base2, (unsigned long long) read_rdramb);
1532 shr_reg32_imm8(gpr1, 16);
1533 mov_reg64_preg64x8preg64(gpr1, gpr1, base1);
1534 cmp_reg64_reg64(gpr1, base2);
1535 }
1536 je_rj(0);
1537 jump_start_rel8();
1538
1539 mov_reg64_imm64(gpr1, (unsigned long long) (dst+1));
1540 mov_m64rel_xreg64((unsigned long long *)(&PC), gpr1);
1541 mov_m32rel_xreg32((unsigned int *)(&address), gpr2);
1542 mov_reg64_imm64(gpr1, (unsigned long long) dst->f.i.rt);
1543 mov_m64rel_xreg64((unsigned long long *)(&rdword), gpr1);
1544 shr_reg32_imm8(gpr2, 16);
1545 mov_reg64_preg64x8preg64(gpr2, gpr2, base1);
1546 call_reg64(gpr2);
1547 mov_xreg32_m32rel(gpr1, (unsigned int *)dst->f.i.rt);
1548 jmp_imm_short(23);
1549
1550 jump_end_rel8();
1551 mov_reg64_imm64(base1, (unsigned long long) rdram); // 10
1552 and_reg32_imm32(gpr2, 0x7FFFFF); // 6
1553 xor_reg8_imm8(gpr2, 3); // 4
1554 mov_reg32_preg64preg64(gpr1, gpr2, base1); // 3
1555
1556 and_reg32_imm32(gpr1, 0xFF);
1557 set_register_state(gpr1, (unsigned int*)dst->f.i.rt, 1, 0);
1558#endif
1559}
1560
1561void genlhu(void)
1562{
1563 int gpr1, gpr2, base1, base2 = 0;
1564#if defined(COUNT_INSTR)
1565 inc_m32rel(&instr_count[29]);
1566#endif
1567#ifdef INTERPRET_LHU
1568 gencallinterp((unsigned long long)cached_interpreter_table.LHU, 0);
1569#else
1570 free_registers_move_start();
1571
1572 ld_register_alloc(&gpr1, &gpr2, &base1, &base2);
1573
1574 mov_reg64_imm64(base1, (unsigned long long) readmemh);
1575 if(fast_memory)
1576 {
1577 and_reg32_imm32(gpr1, 0xDF800000);
1578 cmp_reg32_imm32(gpr1, 0x80000000);
1579 }
1580 else
1581 {
1582 mov_reg64_imm64(base2, (unsigned long long) read_rdramh);
1583 shr_reg32_imm8(gpr1, 16);
1584 mov_reg64_preg64x8preg64(gpr1, gpr1, base1);
1585 cmp_reg64_reg64(gpr1, base2);
1586 }
1587 je_rj(0);
1588 jump_start_rel8();
1589
1590 mov_reg64_imm64(gpr1, (unsigned long long) (dst+1));
1591 mov_m64rel_xreg64((unsigned long long *)(&PC), gpr1);
1592 mov_m32rel_xreg32((unsigned int *)(&address), gpr2);
1593 mov_reg64_imm64(gpr1, (unsigned long long) dst->f.i.rt);
1594 mov_m64rel_xreg64((unsigned long long *)(&rdword), gpr1);
1595 shr_reg32_imm8(gpr2, 16);
1596 mov_reg64_preg64x8preg64(gpr2, gpr2, base1);
1597 call_reg64(gpr2);
1598 mov_xreg32_m32rel(gpr1, (unsigned int *)dst->f.i.rt);
1599 jmp_imm_short(23);
1600
1601 jump_end_rel8();
1602 mov_reg64_imm64(base1, (unsigned long long) rdram); // 10
1603 and_reg32_imm32(gpr2, 0x7FFFFF); // 6
1604 xor_reg8_imm8(gpr2, 2); // 4
1605 mov_reg32_preg64preg64(gpr1, gpr2, base1); // 3
1606
1607 and_reg32_imm32(gpr1, 0xFFFF);
1608 set_register_state(gpr1, (unsigned int*)dst->f.i.rt, 1, 0);
1609#endif
1610}
1611
1612void genlwr(void)
1613{
1614#if defined(COUNT_INSTR)
1615 inc_m32rel(&instr_count[31]);
1616#endif
1617 gencallinterp((unsigned long long)cached_interpreter_table.LWR, 0);
1618}
1619
1620void genlwu(void)
1621{
1622 int gpr1, gpr2, base1, base2 = 0;
1623#if defined(COUNT_INSTR)
1624 inc_m32rel(&instr_count[30]);
1625#endif
1626#ifdef INTERPRET_LWU
1627 gencallinterp((unsigned long long)cached_interpreter_table.LWU, 0);
1628#else
1629 free_registers_move_start();
1630
1631 ld_register_alloc(&gpr1, &gpr2, &base1, &base2);
1632
1633 mov_reg64_imm64(base1, (unsigned long long) readmem);
1634 if(fast_memory)
1635 {
1636 and_reg32_imm32(gpr1, 0xDF800000);
1637 cmp_reg32_imm32(gpr1, 0x80000000);
1638 }
1639 else
1640 {
1641 mov_reg64_imm64(base2, (unsigned long long) read_rdram);
1642 shr_reg32_imm8(gpr1, 16);
1643 mov_reg64_preg64x8preg64(gpr1, gpr1, base1);
1644 cmp_reg64_reg64(gpr1, base2);
1645 }
1646 je_rj(0);
1647 jump_start_rel8();
1648
1649 mov_reg64_imm64(gpr1, (unsigned long long) (dst+1));
1650 mov_m64rel_xreg64((unsigned long long *)(&PC), gpr1);
1651 mov_m32rel_xreg32((unsigned int *)(&address), gpr2);
1652 mov_reg64_imm64(gpr1, (unsigned long long) dst->f.i.rt);
1653 mov_m64rel_xreg64((unsigned long long *)(&rdword), gpr1);
1654 shr_reg32_imm8(gpr2, 16);
1655 mov_reg64_preg64x8preg64(gpr2, gpr2, base1);
1656 call_reg64(gpr2);
1657 mov_xreg32_m32rel(gpr1, (unsigned int *)dst->f.i.rt);
1658 jmp_imm_short(19);
1659
1660 jump_end_rel8();
1661 mov_reg64_imm64(base1, (unsigned long long) rdram); // 10
1662 and_reg32_imm32(gpr2, 0x7FFFFF); // 6
1663 mov_reg32_preg64preg64(gpr1, gpr2, base1); // 3
1664
1665 set_register_state(gpr1, (unsigned int*)dst->f.i.rt, 1, 1);
1666#endif
1667}
1668
1669void gensb(void)
1670{
1671#if defined(COUNT_INSTR)
1672 inc_m32rel(&instr_count[32]);
1673#endif
1674#ifdef INTERPRET_SB
1675 gencallinterp((unsigned long long)cached_interpreter_table.SB, 0);
1676#else
1677 free_registers_move_start();
1678
1679 mov_xreg8_m8rel(CL, (unsigned char *)dst->f.i.rt);
1680 mov_xreg32_m32rel(EAX, (unsigned int *)dst->f.i.rs);
1681 add_eax_imm32((int)dst->f.i.immediate);
1682 mov_reg32_reg32(EBX, EAX);
1683 mov_reg64_imm64(RSI, (unsigned long long) writememb);
1684 if(fast_memory)
1685 {
1686 and_eax_imm32(0xDF800000);
1687 cmp_eax_imm32(0x80000000);
1688 }
1689 else
1690 {
1691 mov_reg64_imm64(RDI, (unsigned long long) write_rdramb);
1692 shr_reg32_imm8(EAX, 16);
1693 mov_reg64_preg64x8preg64(RAX, RAX, RSI);
1694 cmp_reg64_reg64(RAX, RDI);
1695 }
1696 je_rj(49);
1697
1698 mov_reg64_imm64(RAX, (unsigned long long) (dst+1)); // 10
1699 mov_m64rel_xreg64((unsigned long long *)(&PC), RAX); // 7
1700 mov_m32rel_xreg32((unsigned int *)(&address), EBX); // 7
1701 mov_m8rel_xreg8((unsigned char *)(&cpu_byte), CL); // 7
1702 shr_reg32_imm8(EBX, 16); // 3
1703 mov_reg64_preg64x8preg64(RBX, RBX, RSI); // 4
1704 call_reg64(RBX); // 2
1705 mov_xreg32_m32rel(EAX, (unsigned int *)(&address)); // 7
1706 jmp_imm_short(25); // 2
1707
1708 mov_reg64_imm64(RSI, (unsigned long long) rdram); // 10
1709 mov_reg32_reg32(EAX, EBX); // 2
1710 and_reg32_imm32(EBX, 0x7FFFFF); // 6
1711 xor_reg8_imm8(BL, 3); // 4
1712 mov_preg64preg64_reg8(RBX, RSI, CL); // 3
1713
1714 mov_reg64_imm64(RSI, (unsigned long long) invalid_code);
1715 mov_reg32_reg32(EBX, EAX);
1716 shr_reg32_imm8(EBX, 12);
1717 cmp_preg64preg64_imm8(RBX, RSI, 0);
1718 jne_rj(65);
1719
1720 mov_reg64_imm64(RDI, (unsigned long long) blocks); // 10
1721 mov_reg32_reg32(ECX, EBX); // 2
1722 mov_reg64_preg64x8preg64(RBX, RBX, RDI); // 4
1723 mov_reg64_preg64pimm32(RBX, RBX, (int) offsetof(precomp_block, block)); // 7
1724 mov_reg64_imm64(RDI, (unsigned long long) cached_interpreter_table.NOTCOMPILED); // 10
1725 and_eax_imm32(0xFFF); // 5
1726 shr_reg32_imm8(EAX, 2); // 3
1727 mov_reg32_imm32(EDX, sizeof(precomp_instr)); // 5
1728 mul_reg32(EDX); // 2
1729 mov_reg64_preg64preg64pimm32(RAX, RAX, RBX, (int) offsetof(precomp_instr, ops)); // 8
1730 cmp_reg64_reg64(RAX, RDI); // 3
1731 je_rj(4); // 2
1732 mov_preg64preg64_imm8(RCX, RSI, 1); // 4
1733#endif
1734}
1735
1736void gensh(void)
1737{
1738#if defined(COUNT_INSTR)
1739 inc_m32rel(&instr_count[33]);
1740#endif
1741#ifdef INTERPRET_SH
1742 gencallinterp((unsigned long long)cached_interpreter_table.SH, 0);
1743#else
1744 free_registers_move_start();
1745
1746 mov_xreg16_m16rel(CX, (unsigned short *)dst->f.i.rt);
1747 mov_xreg32_m32rel(EAX, (unsigned int *)dst->f.i.rs);
1748 add_eax_imm32((int)dst->f.i.immediate);
1749 mov_reg32_reg32(EBX, EAX);
1750 mov_reg64_imm64(RSI, (unsigned long long) writememh);
1751 if(fast_memory)
1752 {
1753 and_eax_imm32(0xDF800000);
1754 cmp_eax_imm32(0x80000000);
1755 }
1756 else
1757 {
1758 mov_reg64_imm64(RDI, (unsigned long long) write_rdramh);
1759 shr_reg32_imm8(EAX, 16);
1760 mov_reg64_preg64x8preg64(RAX, RAX, RSI);
1761 cmp_reg64_reg64(RAX, RDI);
1762 }
1763 je_rj(50);
1764
1765 mov_reg64_imm64(RAX, (unsigned long long) (dst+1)); // 10
1766 mov_m64rel_xreg64((unsigned long long *)(&PC), RAX); // 7
1767 mov_m32rel_xreg32((unsigned int *)(&address), EBX); // 7
1768 mov_m16rel_xreg16((unsigned short *)(&hword), CX); // 8
1769 shr_reg32_imm8(EBX, 16); // 3
1770 mov_reg64_preg64x8preg64(RBX, RBX, RSI); // 4
1771 call_reg64(RBX); // 2
1772 mov_xreg32_m32rel(EAX, (unsigned int *)(&address)); // 7
1773 jmp_imm_short(26); // 2
1774
1775 mov_reg64_imm64(RSI, (unsigned long long) rdram); // 10
1776 mov_reg32_reg32(EAX, EBX); // 2
1777 and_reg32_imm32(EBX, 0x7FFFFF); // 6
1778 xor_reg8_imm8(BL, 2); // 4
1779 mov_preg64preg64_reg16(RBX, RSI, CX); // 4
1780
1781 mov_reg64_imm64(RSI, (unsigned long long) invalid_code);
1782 mov_reg32_reg32(EBX, EAX);
1783 shr_reg32_imm8(EBX, 12);
1784 cmp_preg64preg64_imm8(RBX, RSI, 0);
1785 jne_rj(65);
1786
1787 mov_reg64_imm64(RDI, (unsigned long long) blocks); // 10
1788 mov_reg32_reg32(ECX, EBX); // 2
1789 mov_reg64_preg64x8preg64(RBX, RBX, RDI); // 4
1790 mov_reg64_preg64pimm32(RBX, RBX, (int) offsetof(precomp_block, block)); // 7
1791 mov_reg64_imm64(RDI, (unsigned long long) cached_interpreter_table.NOTCOMPILED); // 10
1792 and_eax_imm32(0xFFF); // 5
1793 shr_reg32_imm8(EAX, 2); // 3
1794 mov_reg32_imm32(EDX, sizeof(precomp_instr)); // 5
1795 mul_reg32(EDX); // 2
1796 mov_reg64_preg64preg64pimm32(RAX, RAX, RBX, (int) offsetof(precomp_instr, ops)); // 8
1797 cmp_reg64_reg64(RAX, RDI); // 3
1798 je_rj(4); // 2
1799 mov_preg64preg64_imm8(RCX, RSI, 1); // 4
1800#endif
1801}
1802
1803void genswl(void)
1804{
1805#if defined(COUNT_INSTR)
1806 inc_m32rel(&instr_count[35]);
1807#endif
1808 gencallinterp((unsigned long long)cached_interpreter_table.SWL, 0);
1809}
1810
1811void gensw(void)
1812{
1813#if defined(COUNT_INSTR)
1814 inc_m32rel(&instr_count[34]);
1815#endif
1816#ifdef INTERPRET_SW
1817 gencallinterp((unsigned long long)cached_interpreter_table.SW, 0);
1818#else
1819 free_registers_move_start();
1820
1821 mov_xreg32_m32rel(ECX, (unsigned int *)dst->f.i.rt);
1822 mov_xreg32_m32rel(EAX, (unsigned int *)dst->f.i.rs);
1823 add_eax_imm32((int)dst->f.i.immediate);
1824 mov_reg32_reg32(EBX, EAX);
1825 mov_reg64_imm64(RSI, (unsigned long long) writemem);
1826 if(fast_memory)
1827 {
1828 and_eax_imm32(0xDF800000);
1829 cmp_eax_imm32(0x80000000);
1830 }
1831 else
1832 {
1833 mov_reg64_imm64(RDI, (unsigned long long) write_rdram);
1834 shr_reg32_imm8(EAX, 16);
1835 mov_reg64_preg64x8preg64(RAX, RAX, RSI);
1836 cmp_reg64_reg64(RAX, RDI);
1837 }
1838 je_rj(49);
1839
1840 mov_reg64_imm64(RAX, (unsigned long long) (dst+1)); // 10
1841 mov_m64rel_xreg64((unsigned long long *)(&PC), RAX); // 7
1842 mov_m32rel_xreg32((unsigned int *)(&address), EBX); // 7
1843 mov_m32rel_xreg32((unsigned int *)(&word), ECX); // 7
1844 shr_reg32_imm8(EBX, 16); // 3
1845 mov_reg64_preg64x8preg64(RBX, RBX, RSI); // 4
1846 call_reg64(RBX); // 2
1847 mov_xreg32_m32rel(EAX, (unsigned int *)(&address)); // 7
1848 jmp_imm_short(21); // 2
1849
1850 mov_reg64_imm64(RSI, (unsigned long long) rdram); // 10
1851 mov_reg32_reg32(EAX, EBX); // 2
1852 and_reg32_imm32(EBX, 0x7FFFFF); // 6
1853 mov_preg64preg64_reg32(RBX, RSI, ECX); // 3
1854
1855 mov_reg64_imm64(RSI, (unsigned long long) invalid_code);
1856 mov_reg32_reg32(EBX, EAX);
1857 shr_reg32_imm8(EBX, 12);
1858 cmp_preg64preg64_imm8(RBX, RSI, 0);
1859 jne_rj(65);
1860
1861 mov_reg64_imm64(RDI, (unsigned long long) blocks); // 10
1862 mov_reg32_reg32(ECX, EBX); // 2
1863 mov_reg64_preg64x8preg64(RBX, RBX, RDI); // 4
1864 mov_reg64_preg64pimm32(RBX, RBX, (int) offsetof(precomp_block, block)); // 7
1865 mov_reg64_imm64(RDI, (unsigned long long) cached_interpreter_table.NOTCOMPILED); // 10
1866 and_eax_imm32(0xFFF); // 5
1867 shr_reg32_imm8(EAX, 2); // 3
1868 mov_reg32_imm32(EDX, sizeof(precomp_instr)); // 5
1869 mul_reg32(EDX); // 2
1870 mov_reg64_preg64preg64pimm32(RAX, RAX, RBX, (int) offsetof(precomp_instr, ops)); // 8
1871 cmp_reg64_reg64(RAX, RDI); // 3
1872 je_rj(4); // 2
1873 mov_preg64preg64_imm8(RCX, RSI, 1); // 4
1874#endif
1875}
1876
1877void gensdl(void)
1878{
1879#if defined(COUNT_INSTR)
1880 inc_m32rel(&instr_count[37]);
1881#endif
1882 gencallinterp((unsigned long long)cached_interpreter_table.SDL, 0);
1883}
1884
1885void gensdr(void)
1886{
1887#if defined(COUNT_INSTR)
1888 inc_m32rel(&instr_count[38]);
1889#endif
1890 gencallinterp((unsigned long long)cached_interpreter_table.SDR, 0);
1891}
1892
1893void genswr(void)
1894{
1895#if defined(COUNT_INSTR)
1896 inc_m32rel(&instr_count[36]);
1897#endif
1898 gencallinterp((unsigned long long)cached_interpreter_table.SWR, 0);
1899}
1900
1901void gencheck_cop1_unusable(void)
1902{
1903 free_registers_move_start();
1904
1905 test_m32rel_imm32((unsigned int*)&Status, 0x20000000);
1906 jne_rj(0);
1907 jump_start_rel8();
1908
1909 gencallinterp((unsigned long long)check_cop1_unusable, 0);
1910
1911 jump_end_rel8();
1912}
1913
1914void genlwc1(void)
1915{
1916#if defined(COUNT_INSTR)
1917 inc_m32rel(&instr_count[39]);
1918#endif
1919#ifdef INTERPRET_LWC1
1920 gencallinterp((unsigned long long)cached_interpreter_table.LWC1, 0);
1921#else
1922 gencheck_cop1_unusable();
1923
1924 mov_xreg32_m32rel(EAX, (unsigned int *)(&reg[dst->f.lf.base]));
1925 add_eax_imm32((int)dst->f.lf.offset);
1926 mov_reg32_reg32(EBX, EAX);
1927 mov_reg64_imm64(RSI, (unsigned long long) readmem);
1928 if(fast_memory)
1929 {
1930 and_eax_imm32(0xDF800000);
1931 cmp_eax_imm32(0x80000000);
1932 }
1933 else
1934 {
1935 mov_reg64_imm64(RDI, (unsigned long long) read_rdram);
1936 shr_reg32_imm8(EAX, 16);
1937 mov_reg64_preg64x8preg64(RAX, RAX, RSI);
1938 cmp_reg64_reg64(RAX, RDI);
1939 }
1940 je_rj(49);
1941
1942 mov_reg64_imm64(RAX, (unsigned long long) (dst+1)); // 10
1943 mov_m64rel_xreg64((unsigned long long *)(&PC), RAX); // 7
1944 mov_m32rel_xreg32((unsigned int *)(&address), EBX); // 7
1945 mov_xreg64_m64rel(RDX, (unsigned long long *)(&reg_cop1_simple[dst->f.lf.ft])); // 7
1946 mov_m64rel_xreg64((unsigned long long *)(&rdword), RDX); // 7
1947 shr_reg32_imm8(EBX, 16); // 3
1948 mov_reg64_preg64x8preg64(RBX, RBX, RSI); // 4
1949 call_reg64(RBX); // 2
1950 jmp_imm_short(28); // 2
1951
1952 mov_reg64_imm64(RSI, (unsigned long long) rdram); // 10
1953 and_reg32_imm32(EBX, 0x7FFFFF); // 6
1954 mov_reg32_preg64preg64(EAX, RBX, RSI); // 3
1955 mov_xreg64_m64rel(RBX, (unsigned long long *)(&reg_cop1_simple[dst->f.lf.ft])); // 7
1956 mov_preg64_reg32(RBX, EAX); // 2
1957#endif
1958}
1959
1960void genldc1(void)
1961{
1962#if defined(COUNT_INSTR)
1963 inc_m32rel(&instr_count[40]);
1964#endif
1965#ifdef INTERPRET_LDC1
1966 gencallinterp((unsigned long long)cached_interpreter_table.LDC1, 0);
1967#else
1968 gencheck_cop1_unusable();
1969
1970 mov_xreg32_m32rel(EAX, (unsigned int *)(&reg[dst->f.lf.base]));
1971 add_eax_imm32((int)dst->f.lf.offset);
1972 mov_reg32_reg32(EBX, EAX);
1973 mov_reg64_imm64(RSI, (unsigned long long) readmemd);
1974 if(fast_memory)
1975 {
1976 and_eax_imm32(0xDF800000);
1977 cmp_eax_imm32(0x80000000);
1978 }
1979 else
1980 {
1981 mov_reg64_imm64(RDI, (unsigned long long) read_rdramd);
1982 shr_reg32_imm8(EAX, 16);
1983 mov_reg64_preg64x8preg64(RAX, RAX, RSI);
1984 cmp_reg64_reg64(RAX, RDI);
1985 }
1986 je_rj(49);
1987
1988 mov_reg64_imm64(RAX, (unsigned long long) (dst+1)); // 10
1989 mov_m64rel_xreg64((unsigned long long *)(&PC), RAX); // 7
1990 mov_m32rel_xreg32((unsigned int *)(&address), EBX); // 7
1991 mov_xreg64_m64rel(RDX, (unsigned long long *)(&reg_cop1_double[dst->f.lf.ft])); // 7
1992 mov_m64rel_xreg64((unsigned long long *)(&rdword), RDX); // 7
1993 shr_reg32_imm8(EBX, 16); // 3
1994 mov_reg64_preg64x8preg64(RBX, RBX, RSI); // 4
1995 call_reg64(RBX); // 2
1996 jmp_imm_short(39); // 2
1997
1998 mov_reg64_imm64(RSI, (unsigned long long) rdram); // 10
1999 and_reg32_imm32(EBX, 0x7FFFFF); // 6
2000 mov_reg64_preg64preg64(RAX, RBX, RSI); // 4
2001 mov_xreg64_m64rel(RBX, (unsigned long long *)(&reg_cop1_double[dst->f.lf.ft])); // 7
2002 mov_preg64pimm32_reg32(RBX, 4, EAX); // 6
2003 shr_reg64_imm8(RAX, 32); // 4
2004 mov_preg64_reg32(RBX, EAX); // 2
2005#endif
2006}
2007
2008void gencache(void)
2009{
2010}
2011
2012void genld(void)
2013{
2014#if defined(COUNT_INSTR)
2015 inc_m32rel(&instr_count[41]);
2016#endif
2017#ifdef INTERPRET_LD
2018 gencallinterp((unsigned long long)cached_interpreter_table.LD, 0);
2019#else
2020 free_registers_move_start();
2021
2022 mov_xreg32_m32rel(EAX, (unsigned int *)dst->f.i.rs);
2023 add_eax_imm32((int)dst->f.i.immediate);
2024 mov_reg32_reg32(EBX, EAX);
2025 mov_reg64_imm64(RSI, (unsigned long long) readmemd);
2026 if(fast_memory)
2027 {
2028 and_eax_imm32(0xDF800000);
2029 cmp_eax_imm32(0x80000000);
2030 }
2031 else
2032 {
2033 mov_reg64_imm64(RDI, (unsigned long long) read_rdramd);
2034 shr_reg32_imm8(EAX, 16);
2035 mov_reg64_preg64x8preg64(RAX, RAX, RSI);
2036 cmp_reg64_reg64(RAX, RDI);
2037 }
2038 je_rj(59);
2039
2040 mov_reg64_imm64(RAX, (unsigned long long) (dst+1)); // 10
2041 mov_m64rel_xreg64((unsigned long long *)(&PC), RAX); // 7
2042 mov_m32rel_xreg32((unsigned int *)(&address), EBX); // 7
2043 mov_reg64_imm64(RAX, (unsigned long long) dst->f.i.rt); // 10
2044 mov_m64rel_xreg64((unsigned long long *)(&rdword), RAX); // 7
2045 shr_reg32_imm8(EBX, 16); // 3
2046 mov_reg64_preg64x8preg64(RBX, RBX, RSI); // 4
2047 call_reg64(RBX); // 2
2048 mov_xreg64_m64rel(RAX, (unsigned long long *)(dst->f.i.rt)); // 7
2049 jmp_imm_short(33); // 2
2050
2051 mov_reg64_imm64(RSI, (unsigned long long) rdram); // 10
2052 and_reg32_imm32(EBX, 0x7FFFFF); // 6
2053
2054 mov_reg32_preg64preg64(EAX, RBX, RSI); // 3
2055 mov_reg32_preg64preg64pimm32(EBX, RBX, RSI, 4); // 7
2056 shl_reg64_imm8(RAX, 32); // 4
2057 or_reg64_reg64(RAX, RBX); // 3
2058
2059 set_register_state(RAX, (unsigned int*)dst->f.i.rt, 1, 1);
2060#endif
2061}
2062
2063void genswc1(void)
2064{
2065#if defined(COUNT_INSTR)
2066 inc_m32rel(&instr_count[43]);
2067#endif
2068#ifdef INTERPRET_SWC1
2069 gencallinterp((unsigned long long)cached_interpreter_table.SWC1, 0);
2070#else
2071 gencheck_cop1_unusable();
2072
2073 mov_xreg64_m64rel(RDX, (unsigned long long *)(&reg_cop1_simple[dst->f.lf.ft]));
2074 mov_reg32_preg64(ECX, RDX);
2075 mov_xreg32_m32rel(EAX, (unsigned int *)(&reg[dst->f.lf.base]));
2076 add_eax_imm32((int)dst->f.lf.offset);
2077 mov_reg32_reg32(EBX, EAX);
2078 mov_reg64_imm64(RSI, (unsigned long long) writemem);
2079 if(fast_memory)
2080 {
2081 and_eax_imm32(0xDF800000);
2082 cmp_eax_imm32(0x80000000);
2083 }
2084 else
2085 {
2086 mov_reg64_imm64(RDI, (unsigned long long) write_rdram);
2087 shr_reg32_imm8(EAX, 16);
2088 mov_reg64_preg64x8preg64(RAX, RAX, RSI);
2089 cmp_reg64_reg64(RAX, RDI);
2090 }
2091 je_rj(49);
2092
2093 mov_reg64_imm64(RAX, (unsigned long long) (dst+1)); // 10
2094 mov_m64rel_xreg64((unsigned long long *)(&PC), RAX); // 7
2095 mov_m32rel_xreg32((unsigned int *)(&address), EBX); // 7
2096 mov_m32rel_xreg32((unsigned int *)(&word), ECX); // 7
2097 shr_reg32_imm8(EBX, 16); // 3
2098 mov_reg64_preg64x8preg64(RBX, RBX, RSI); // 4
2099 call_reg64(RBX); // 2
2100 mov_xreg32_m32rel(EAX, (unsigned int *)(&address)); // 7
2101 jmp_imm_short(21); // 2
2102
2103 mov_reg64_imm64(RSI, (unsigned long long) rdram); // 10
2104 mov_reg32_reg32(EAX, EBX); // 2
2105 and_reg32_imm32(EBX, 0x7FFFFF); // 6
2106 mov_preg64preg64_reg32(RBX, RSI, ECX); // 3
2107
2108 mov_reg64_imm64(RSI, (unsigned long long) invalid_code);
2109 mov_reg32_reg32(EBX, EAX);
2110 shr_reg32_imm8(EBX, 12);
2111 cmp_preg64preg64_imm8(RBX, RSI, 0);
2112 jne_rj(65);
2113
2114 mov_reg64_imm64(RDI, (unsigned long long) blocks); // 10
2115 mov_reg32_reg32(ECX, EBX); // 2
2116 mov_reg64_preg64x8preg64(RBX, RBX, RDI); // 4
2117 mov_reg64_preg64pimm32(RBX, RBX, (int) offsetof(precomp_block, block)); // 7
2118 mov_reg64_imm64(RDI, (unsigned long long) cached_interpreter_table.NOTCOMPILED); // 10
2119 and_eax_imm32(0xFFF); // 5
2120 shr_reg32_imm8(EAX, 2); // 3
2121 mov_reg32_imm32(EDX, sizeof(precomp_instr)); // 5
2122 mul_reg32(EDX); // 2
2123 mov_reg64_preg64preg64pimm32(RAX, RAX, RBX, (int) offsetof(precomp_instr, ops)); // 8
2124 cmp_reg64_reg64(RAX, RDI); // 3
2125 je_rj(4); // 2
2126 mov_preg64preg64_imm8(RCX, RSI, 1); // 4
2127#endif
2128}
2129
2130void gensdc1(void)
2131{
2132#if defined(COUNT_INSTR)
2133 inc_m32rel(&instr_count[44]);
2134#endif
2135#ifdef INTERPRET_SDC1
2136 gencallinterp((unsigned long long)cached_interpreter_table.SDC1, 0);
2137#else
2138 gencheck_cop1_unusable();
2139
2140 mov_xreg64_m64rel(RSI, (unsigned long long *)(&reg_cop1_double[dst->f.lf.ft]));
2141 mov_reg32_preg64(ECX, RSI);
2142 mov_reg32_preg64pimm32(EDX, RSI, 4);
2143 mov_xreg32_m32rel(EAX, (unsigned int *)(&reg[dst->f.lf.base]));
2144 add_eax_imm32((int)dst->f.lf.offset);
2145 mov_reg32_reg32(EBX, EAX);
2146 mov_reg64_imm64(RSI, (unsigned long long) writememd);
2147 if(fast_memory)
2148 {
2149 and_eax_imm32(0xDF800000);
2150 cmp_eax_imm32(0x80000000);
2151 }
2152 else
2153 {
2154 mov_reg64_imm64(RDI, (unsigned long long) write_rdramd);
2155 shr_reg32_imm8(EAX, 16);
2156 mov_reg64_preg64x8preg64(RAX, RAX, RSI);
2157 cmp_reg64_reg64(RAX, RDI);
2158 }
2159 je_rj(56);
2160
2161 mov_reg64_imm64(RAX, (unsigned long long) (dst+1)); // 10
2162 mov_m64rel_xreg64((unsigned long long *)(&PC), RAX); // 7
2163 mov_m32rel_xreg32((unsigned int *)(&address), EBX); // 7
2164 mov_m32rel_xreg32((unsigned int *)(&dword), ECX); // 7
2165 mov_m32rel_xreg32((unsigned int *)(&dword)+1, EDX); // 7
2166 shr_reg32_imm8(EBX, 16); // 3
2167 mov_reg64_preg64x8preg64(RBX, RBX, RSI); // 4
2168 call_reg64(RBX); // 2
2169 mov_xreg32_m32rel(EAX, (unsigned int *)(&address)); // 7
2170 jmp_imm_short(28); // 2
2171
2172 mov_reg64_imm64(RSI, (unsigned long long) rdram); // 10
2173 mov_reg32_reg32(EAX, EBX); // 2
2174 and_reg32_imm32(EBX, 0x7FFFFF); // 6
2175 mov_preg64preg64pimm32_reg32(RBX, RSI, 4, ECX); // 7
2176 mov_preg64preg64_reg32(RBX, RSI, EDX); // 3
2177
2178 mov_reg64_imm64(RSI, (unsigned long long) invalid_code);
2179 mov_reg32_reg32(EBX, EAX);
2180 shr_reg32_imm8(EBX, 12);
2181 cmp_preg64preg64_imm8(RBX, RSI, 0);
2182 jne_rj(65);
2183
2184 mov_reg64_imm64(RDI, (unsigned long long) blocks); // 10
2185 mov_reg32_reg32(ECX, EBX); // 2
2186 mov_reg64_preg64x8preg64(RBX, RBX, RDI); // 4
2187 mov_reg64_preg64pimm32(RBX, RBX, (int) offsetof(precomp_block, block)); // 7
2188 mov_reg64_imm64(RDI, (unsigned long long) cached_interpreter_table.NOTCOMPILED); // 10
2189 and_eax_imm32(0xFFF); // 5
2190 shr_reg32_imm8(EAX, 2); // 3
2191 mov_reg32_imm32(EDX, sizeof(precomp_instr)); // 5
2192 mul_reg32(EDX); // 2
2193 mov_reg64_preg64preg64pimm32(RAX, RAX, RBX, (int) offsetof(precomp_instr, ops)); // 8
2194 cmp_reg64_reg64(RAX, RDI); // 3
2195 je_rj(4); // 2
2196 mov_preg64preg64_imm8(RCX, RSI, 1); // 4
2197#endif
2198}
2199
2200void gensd(void)
2201{
2202#if defined(COUNT_INSTR)
2203 inc_m32rel(&instr_count[45]);
2204#endif
2205#ifdef INTERPRET_SD
2206 gencallinterp((unsigned long long)cached_interpreter_table.SD, 0);
2207#else
2208 free_registers_move_start();
2209
2210 mov_xreg32_m32rel(ECX, (unsigned int *)dst->f.i.rt);
2211 mov_xreg32_m32rel(EDX, ((unsigned int *)dst->f.i.rt)+1);
2212 mov_xreg32_m32rel(EAX, (unsigned int *)dst->f.i.rs);
2213 add_eax_imm32((int)dst->f.i.immediate);
2214 mov_reg32_reg32(EBX, EAX);
2215 mov_reg64_imm64(RSI, (unsigned long long) writememd);
2216 if(fast_memory)
2217 {
2218 and_eax_imm32(0xDF800000);
2219 cmp_eax_imm32(0x80000000);
2220 }
2221 else
2222 {
2223 mov_reg64_imm64(RDI, (unsigned long long) write_rdramd);
2224 shr_reg32_imm8(EAX, 16);
2225 mov_reg64_preg64x8preg64(RAX, RAX, RSI);
2226 cmp_reg64_reg64(RAX, RDI);
2227 }
2228 je_rj(56);
2229
2230 mov_reg64_imm64(RAX, (unsigned long long) (dst+1)); // 10
2231 mov_m64rel_xreg64((unsigned long long *)(&PC), RAX); // 7
2232 mov_m32rel_xreg32((unsigned int *)(&address), EBX); // 7
2233 mov_m32rel_xreg32((unsigned int *)(&dword), ECX); // 7
2234 mov_m32rel_xreg32((unsigned int *)(&dword)+1, EDX); // 7
2235 shr_reg32_imm8(EBX, 16); // 3
2236 mov_reg64_preg64x8preg64(RBX, RBX, RSI); // 4
2237 call_reg64(RBX); // 2
2238 mov_xreg32_m32rel(EAX, (unsigned int *)(&address)); // 7
2239 jmp_imm_short(28); // 2
2240
2241 mov_reg64_imm64(RSI, (unsigned long long) rdram); // 10
2242 mov_reg32_reg32(EAX, EBX); // 2
2243 and_reg32_imm32(EBX, 0x7FFFFF); // 6
2244 mov_preg64preg64pimm32_reg32(RBX, RSI, 4, ECX); // 7
2245 mov_preg64preg64_reg32(RBX, RSI, EDX); // 3
2246
2247 mov_reg64_imm64(RSI, (unsigned long long) invalid_code);
2248 mov_reg32_reg32(EBX, EAX);
2249 shr_reg32_imm8(EBX, 12);
2250 cmp_preg64preg64_imm8(RBX, RSI, 0);
2251 jne_rj(65);
2252
2253 mov_reg64_imm64(RDI, (unsigned long long) blocks); // 10
2254 mov_reg32_reg32(ECX, EBX); // 2
2255 mov_reg64_preg64x8preg64(RBX, RBX, RDI); // 4
2256 mov_reg64_preg64pimm32(RBX, RBX, (int) offsetof(precomp_block, block)); // 7
2257 mov_reg64_imm64(RDI, (unsigned long long) cached_interpreter_table.NOTCOMPILED); // 10
2258 and_eax_imm32(0xFFF); // 5
2259 shr_reg32_imm8(EAX, 2); // 3
2260 mov_reg32_imm32(EDX, sizeof(precomp_instr)); // 5
2261 mul_reg32(EDX); // 2
2262 mov_reg64_preg64preg64pimm32(RAX, RAX, RBX, (int) offsetof(precomp_instr, ops)); // 8
2263 cmp_reg64_reg64(RAX, RDI); // 3
2264 je_rj(4); // 2
2265 mov_preg64preg64_imm8(RCX, RSI, 1); // 4
2266#endif
2267}
2268
2269void genll(void)
2270{
2271#if defined(COUNT_INSTR)
2272 inc_m32rel(&instr_count[42]);
2273#endif
2274 gencallinterp((unsigned long long)cached_interpreter_table.LL, 0);
2275}
2276
2277void gensc(void)
2278{
2279#if defined(COUNT_INSTR)
2280 inc_m32rel(&instr_count[46]);
2281#endif
2282 gencallinterp((unsigned long long)cached_interpreter_table.SC, 0);
2283}
2284