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