Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libmupen64plus/mupen64plus-core/src/r4300/x86/gr4300.c
2 views
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
2051
2052