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