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