15db43fd54563a8e2197b60ad03e3b445cf62bdc
[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, 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
103 static 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
118 static 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
134 static 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
170 static 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
207 static 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
227 static 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
247 static 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
291 void 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
301 void genlink_subblock(void)
302 {
303    free_all_registers();
304    jmp(dst->addr+4);
305 }
306
307 #ifdef COMPARE_CORE
308 void 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
341 void 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
361 void 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
372 void 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
380 void 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
388 void genfin_block(void)
389 {
390    gencallinterp((unsigned long long)cached_interpreter_table.FIN_BLOCK, 0);
391 }
392
393 void 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
409 void gennop(void)
410 {
411 }
412
413 void 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
439 void 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
469 void 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
496 void 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
529 void 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
566 void 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
593 void 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
610 void 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
631 void 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
651 void 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
672 void 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
696 void 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
714 void 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
735 void 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
756 void 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
774 void 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
795 void 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
816 void 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
834 void 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
855 void 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
876 void 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
894 void 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
910 void 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
926 void 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
944 void 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
962 void 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
978 void 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
994 void 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
1010 void 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
1024 void 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
1043 void 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
1064 void 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
1088 void 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
1109 void 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
1127 void 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
1148 void 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
1169 void 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
1187 void 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
1208 void 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
1229 void 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
1247 void 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
1268 void 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
1289 void 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
1307 void 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
1323 void 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
1336 void 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
1344 void 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
1352 void 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
1402 void 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
1452 void 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
1460 void 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
1510 void 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
1561 void 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
1612 void 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
1620 void 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
1669 void 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
1736 void 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
1803 void 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
1811 void 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
1877 void 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
1885 void 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
1893 void 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
1901 void 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
1914 void 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
1960 void 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
2008 void gencache(void)
2009 {
2010 }
2011
2012 void 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
2063 void 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
2130 void 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
2200 void 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
2269 void 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
2277 void 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