Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libmupen64plus/mupen64plus-core/src/r4300/x86/gspecial.c
2 views
1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
* Mupen64plus - gspecial.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 <stdio.h>
23
24
#include "assemble.h"
25
#include "interpret.h"
26
27
#include "r4300/recomph.h"
28
#include "r4300/recomp.h"
29
#include "r4300/r4300.h"
30
#include "r4300/ops.h"
31
#include "r4300/macros.h"
32
#include "r4300/exception.h"
33
34
void gensll(void)
35
{
36
#ifdef INTERPRET_SLL
37
gencallinterp((unsigned int)cached_interpreter_table.SLL, 0);
38
#else
39
int rt = allocate_register((unsigned int *)dst->f.r.rt);
40
int rd = allocate_register_w((unsigned int *)dst->f.r.rd);
41
42
mov_reg32_reg32(rd, rt);
43
shl_reg32_imm8(rd, dst->f.r.sa);
44
#endif
45
}
46
47
void gensrl(void)
48
{
49
#ifdef INTERPRET_SRL
50
gencallinterp((unsigned int)cached_interpreter_table.SRL, 0);
51
#else
52
int rt = allocate_register((unsigned int *)dst->f.r.rt);
53
int rd = allocate_register_w((unsigned int *)dst->f.r.rd);
54
55
mov_reg32_reg32(rd, rt);
56
shr_reg32_imm8(rd, dst->f.r.sa);
57
#endif
58
}
59
60
void gensra(void)
61
{
62
#ifdef INTERPRET_SRA
63
gencallinterp((unsigned int)cached_interpreter_table.SRA, 0);
64
#else
65
int rt = allocate_register((unsigned int *)dst->f.r.rt);
66
int rd = allocate_register_w((unsigned int *)dst->f.r.rd);
67
68
mov_reg32_reg32(rd, rt);
69
sar_reg32_imm8(rd, dst->f.r.sa);
70
#endif
71
}
72
73
void gensllv(void)
74
{
75
#ifdef INTERPRET_SLLV
76
gencallinterp((unsigned int)cached_interpreter_table.SLLV, 0);
77
#else
78
int rt, rd;
79
allocate_register_manually(ECX, (unsigned int *)dst->f.r.rs);
80
81
rt = allocate_register((unsigned int *)dst->f.r.rt);
82
rd = allocate_register_w((unsigned int *)dst->f.r.rd);
83
84
if (rd != ECX)
85
{
86
mov_reg32_reg32(rd, rt);
87
shl_reg32_cl(rd);
88
}
89
else
90
{
91
int temp = lru_register();
92
free_register(temp);
93
mov_reg32_reg32(temp, rt);
94
shl_reg32_cl(temp);
95
mov_reg32_reg32(rd, temp);
96
}
97
#endif
98
}
99
100
void gensrlv(void)
101
{
102
#ifdef INTERPRET_SRLV
103
gencallinterp((unsigned int)cached_interpreter_table.SRLV, 0);
104
#else
105
int rt, rd;
106
allocate_register_manually(ECX, (unsigned int *)dst->f.r.rs);
107
108
rt = allocate_register((unsigned int *)dst->f.r.rt);
109
rd = allocate_register_w((unsigned int *)dst->f.r.rd);
110
111
if (rd != ECX)
112
{
113
mov_reg32_reg32(rd, rt);
114
shr_reg32_cl(rd);
115
}
116
else
117
{
118
int temp = lru_register();
119
free_register(temp);
120
mov_reg32_reg32(temp, rt);
121
shr_reg32_cl(temp);
122
mov_reg32_reg32(rd, temp);
123
}
124
#endif
125
}
126
127
void gensrav(void)
128
{
129
#ifdef INTERPRET_SRAV
130
gencallinterp((unsigned int)cached_interpreter_table.SRAV, 0);
131
#else
132
int rt, rd;
133
allocate_register_manually(ECX, (unsigned int *)dst->f.r.rs);
134
135
rt = allocate_register((unsigned int *)dst->f.r.rt);
136
rd = allocate_register_w((unsigned int *)dst->f.r.rd);
137
138
if (rd != ECX)
139
{
140
mov_reg32_reg32(rd, rt);
141
sar_reg32_cl(rd);
142
}
143
else
144
{
145
int temp = lru_register();
146
free_register(temp);
147
mov_reg32_reg32(temp, rt);
148
sar_reg32_cl(temp);
149
mov_reg32_reg32(rd, temp);
150
}
151
#endif
152
}
153
154
void genjr(void)
155
{
156
#ifdef INTERPRET_JR
157
gencallinterp((unsigned int)cached_interpreter_table.JR, 1);
158
#else
159
static unsigned int precomp_instr_size = sizeof(precomp_instr);
160
unsigned int diff =
161
(unsigned int)(&dst->local_addr) - (unsigned int)(dst);
162
unsigned int diff_need =
163
(unsigned int)(&dst->reg_cache_infos.need_map) - (unsigned int)(dst);
164
unsigned int diff_wrap =
165
(unsigned int)(&dst->reg_cache_infos.jump_wrapper) - (unsigned int)(dst);
166
167
if (((dst->addr & 0xFFF) == 0xFFC &&
168
(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
169
{
170
gencallinterp((unsigned int)cached_interpreter_table.JR, 1);
171
return;
172
}
173
174
free_all_registers();
175
simplify_access();
176
mov_eax_memoffs32((unsigned int *)dst->f.i.rs);
177
mov_memoffs32_eax((unsigned int *)&local_rs);
178
179
gendelayslot();
180
181
mov_eax_memoffs32((unsigned int *)&local_rs);
182
mov_memoffs32_eax((unsigned int *)&last_addr);
183
184
gencheck_interupt_reg();
185
186
mov_eax_memoffs32((unsigned int *)&local_rs);
187
mov_reg32_reg32(EBX, EAX);
188
and_eax_imm32(0xFFFFF000);
189
cmp_eax_imm32(dst_block->start & 0xFFFFF000);
190
je_near_rj(0);
191
192
jump_start_rel32();
193
194
mov_m32_reg32(&jump_to_address, EBX);
195
mov_m32_imm32((unsigned int*)(&PC), (unsigned int)(dst+1));
196
mov_reg32_imm32(EAX, (unsigned int)jump_to_func);
197
call_reg32(EAX);
198
199
jump_end_rel32();
200
201
mov_reg32_reg32(EAX, EBX);
202
sub_eax_imm32(dst_block->start);
203
shr_reg32_imm8(EAX, 2);
204
mul_m32((unsigned int *)(&precomp_instr_size));
205
206
mov_reg32_preg32pimm32(EBX, EAX, (unsigned int)(dst_block->block)+diff_need);
207
cmp_reg32_imm32(EBX, 1);
208
jne_rj(7);
209
210
add_eax_imm32((unsigned int)(dst_block->block)+diff_wrap); // 5
211
jmp_reg32(EAX); // 2
212
213
mov_reg32_preg32pimm32(EAX, EAX, (unsigned int)(dst_block->block)+diff);
214
add_reg32_m32(EAX, (unsigned int *)(&dst_block->code));
215
216
jmp_reg32(EAX);
217
#endif
218
}
219
220
void genjalr(void)
221
{
222
#ifdef INTERPRET_JALR
223
gencallinterp((unsigned int)cached_interpreter_table.JALR, 0);
224
#else
225
static unsigned int precomp_instr_size = sizeof(precomp_instr);
226
unsigned int diff =
227
(unsigned int)(&dst->local_addr) - (unsigned int)(dst);
228
unsigned int diff_need =
229
(unsigned int)(&dst->reg_cache_infos.need_map) - (unsigned int)(dst);
230
unsigned int diff_wrap =
231
(unsigned int)(&dst->reg_cache_infos.jump_wrapper) - (unsigned int)(dst);
232
233
if (((dst->addr & 0xFFF) == 0xFFC &&
234
(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
235
{
236
gencallinterp((unsigned int)cached_interpreter_table.JALR, 1);
237
return;
238
}
239
240
free_all_registers();
241
simplify_access();
242
mov_eax_memoffs32((unsigned int *)dst->f.r.rs);
243
mov_memoffs32_eax((unsigned int *)&local_rs);
244
245
gendelayslot();
246
247
mov_m32_imm32((unsigned int *)(dst-1)->f.r.rd, dst->addr+4);
248
if ((dst->addr+4) & 0x80000000)
249
mov_m32_imm32(((unsigned int *)(dst-1)->f.r.rd)+1, 0xFFFFFFFF);
250
else
251
mov_m32_imm32(((unsigned int *)(dst-1)->f.r.rd)+1, 0);
252
253
mov_eax_memoffs32((unsigned int *)&local_rs);
254
mov_memoffs32_eax((unsigned int *)&last_addr);
255
256
gencheck_interupt_reg();
257
258
mov_eax_memoffs32((unsigned int *)&local_rs);
259
mov_reg32_reg32(EBX, EAX);
260
and_eax_imm32(0xFFFFF000);
261
cmp_eax_imm32(dst_block->start & 0xFFFFF000);
262
je_near_rj(0);
263
264
jump_start_rel32();
265
266
mov_m32_reg32(&jump_to_address, EBX);
267
mov_m32_imm32((unsigned int*)(&PC), (unsigned int)(dst+1));
268
mov_reg32_imm32(EAX, (unsigned int)jump_to_func);
269
call_reg32(EAX);
270
271
jump_end_rel32();
272
273
mov_reg32_reg32(EAX, EBX);
274
sub_eax_imm32(dst_block->start);
275
shr_reg32_imm8(EAX, 2);
276
mul_m32((unsigned int *)(&precomp_instr_size));
277
278
mov_reg32_preg32pimm32(EBX, EAX, (unsigned int)(dst_block->block)+diff_need);
279
cmp_reg32_imm32(EBX, 1);
280
jne_rj(7);
281
282
add_eax_imm32((unsigned int)(dst_block->block)+diff_wrap); // 5
283
jmp_reg32(EAX); // 2
284
285
mov_reg32_preg32pimm32(EAX, EAX, (unsigned int)(dst_block->block)+diff);
286
add_reg32_m32(EAX, (unsigned int *)(&dst_block->code));
287
288
jmp_reg32(EAX);
289
#endif
290
}
291
292
void gensyscall(void)
293
{
294
#ifdef INTERPRET_SYSCALL
295
gencallinterp((unsigned int)cached_interpreter_table.SYSCALL, 0);
296
#else
297
free_all_registers();
298
simplify_access();
299
mov_m32_imm32(&Cause, 8 << 2);
300
gencallinterp((unsigned int)exception_general, 0);
301
#endif
302
}
303
304
void gensync(void)
305
{
306
}
307
308
void genmfhi(void)
309
{
310
#ifdef INTERPRET_MFHI
311
gencallinterp((unsigned int)cached_interpreter_table.MFHI, 0);
312
#else
313
int rd1 = allocate_64_register1_w((unsigned int*)dst->f.r.rd);
314
int rd2 = allocate_64_register2_w((unsigned int*)dst->f.r.rd);
315
int hi1 = allocate_64_register1((unsigned int*)&hi);
316
int hi2 = allocate_64_register2((unsigned int*)&hi);
317
318
mov_reg32_reg32(rd1, hi1);
319
mov_reg32_reg32(rd2, hi2);
320
#endif
321
}
322
323
void genmthi(void)
324
{
325
#ifdef INTERPRET_MTHI
326
gencallinterp((unsigned int)cached_interpreter_table.MTHI, 0);
327
#else
328
int hi1 = allocate_64_register1_w((unsigned int*)&hi);
329
int hi2 = allocate_64_register2_w((unsigned int*)&hi);
330
int rs1 = allocate_64_register1((unsigned int*)dst->f.r.rs);
331
int rs2 = allocate_64_register2((unsigned int*)dst->f.r.rs);
332
333
mov_reg32_reg32(hi1, rs1);
334
mov_reg32_reg32(hi2, rs2);
335
#endif
336
}
337
338
void genmflo(void)
339
{
340
#ifdef INTERPRET_MFLO
341
gencallinterp((unsigned int)cached_interpreter_table.MFLO, 0);
342
#else
343
int rd1 = allocate_64_register1_w((unsigned int*)dst->f.r.rd);
344
int rd2 = allocate_64_register2_w((unsigned int*)dst->f.r.rd);
345
int lo1 = allocate_64_register1((unsigned int*)&lo);
346
int lo2 = allocate_64_register2((unsigned int*)&lo);
347
348
mov_reg32_reg32(rd1, lo1);
349
mov_reg32_reg32(rd2, lo2);
350
#endif
351
}
352
353
void genmtlo(void)
354
{
355
#ifdef INTERPRET_MTLO
356
gencallinterp((unsigned int)cached_interpreter_table.MTLO, 0);
357
#else
358
int lo1 = allocate_64_register1_w((unsigned int*)&lo);
359
int lo2 = allocate_64_register2_w((unsigned int*)&lo);
360
int rs1 = allocate_64_register1((unsigned int*)dst->f.r.rs);
361
int rs2 = allocate_64_register2((unsigned int*)dst->f.r.rs);
362
363
mov_reg32_reg32(lo1, rs1);
364
mov_reg32_reg32(lo2, rs2);
365
#endif
366
}
367
368
void gendsllv(void)
369
{
370
#ifdef INTERPRET_DSLLV
371
gencallinterp((unsigned int)cached_interpreter_table.DSLLV, 0);
372
#else
373
int rt1, rt2, rd1, rd2;
374
allocate_register_manually(ECX, (unsigned int *)dst->f.r.rs);
375
376
rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
377
rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
378
rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd);
379
rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd);
380
381
if (rd1 != ECX && rd2 != ECX)
382
{
383
mov_reg32_reg32(rd1, rt1);
384
mov_reg32_reg32(rd2, rt2);
385
shld_reg32_reg32_cl(rd2,rd1);
386
shl_reg32_cl(rd1);
387
test_reg32_imm32(ECX, 0x20);
388
je_rj(4);
389
mov_reg32_reg32(rd2, rd1); // 2
390
xor_reg32_reg32(rd1, rd1); // 2
391
}
392
else
393
{
394
int temp1, temp2;
395
force_32(ECX);
396
temp1 = lru_register();
397
temp2 = lru_register_exc1(temp1);
398
free_register(temp1);
399
free_register(temp2);
400
401
mov_reg32_reg32(temp1, rt1);
402
mov_reg32_reg32(temp2, rt2);
403
shld_reg32_reg32_cl(temp2, temp1);
404
shl_reg32_cl(temp1);
405
test_reg32_imm32(ECX, 0x20);
406
je_rj(4);
407
mov_reg32_reg32(temp2, temp1); // 2
408
xor_reg32_reg32(temp1, temp1); // 2
409
410
mov_reg32_reg32(rd1, temp1);
411
mov_reg32_reg32(rd2, temp2);
412
}
413
#endif
414
}
415
416
void gendsrlv(void)
417
{
418
#ifdef INTERPRET_DSRLV
419
gencallinterp((unsigned int)cached_interpreter_table.DSRLV, 0);
420
#else
421
int rt1, rt2, rd1, rd2;
422
allocate_register_manually(ECX, (unsigned int *)dst->f.r.rs);
423
424
rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
425
rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
426
rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd);
427
rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd);
428
429
if (rd1 != ECX && rd2 != ECX)
430
{
431
mov_reg32_reg32(rd1, rt1);
432
mov_reg32_reg32(rd2, rt2);
433
shrd_reg32_reg32_cl(rd1,rd2);
434
shr_reg32_cl(rd2);
435
test_reg32_imm32(ECX, 0x20);
436
je_rj(4);
437
mov_reg32_reg32(rd1, rd2); // 2
438
xor_reg32_reg32(rd2, rd2); // 2
439
}
440
else
441
{
442
int temp1, temp2;
443
force_32(ECX);
444
temp1 = lru_register();
445
temp2 = lru_register_exc1(temp1);
446
free_register(temp1);
447
free_register(temp2);
448
449
mov_reg32_reg32(temp1, rt1);
450
mov_reg32_reg32(temp2, rt2);
451
shrd_reg32_reg32_cl(temp1, temp2);
452
shr_reg32_cl(temp2);
453
test_reg32_imm32(ECX, 0x20);
454
je_rj(4);
455
mov_reg32_reg32(temp1, temp2); // 2
456
xor_reg32_reg32(temp2, temp2); // 2
457
458
mov_reg32_reg32(rd1, temp1);
459
mov_reg32_reg32(rd2, temp2);
460
}
461
#endif
462
}
463
464
void gendsrav(void)
465
{
466
#ifdef INTERPRET_DSRAV
467
gencallinterp((unsigned int)cached_interpreter_table.DSRAV, 0);
468
#else
469
int rt1, rt2, rd1, rd2;
470
allocate_register_manually(ECX, (unsigned int *)dst->f.r.rs);
471
472
rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
473
rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
474
rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd);
475
rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd);
476
477
if (rd1 != ECX && rd2 != ECX)
478
{
479
mov_reg32_reg32(rd1, rt1);
480
mov_reg32_reg32(rd2, rt2);
481
shrd_reg32_reg32_cl(rd1,rd2);
482
sar_reg32_cl(rd2);
483
test_reg32_imm32(ECX, 0x20);
484
je_rj(5);
485
mov_reg32_reg32(rd1, rd2); // 2
486
sar_reg32_imm8(rd2, 31); // 3
487
}
488
else
489
{
490
int temp1, temp2;
491
force_32(ECX);
492
temp1 = lru_register();
493
temp2 = lru_register_exc1(temp1);
494
free_register(temp1);
495
free_register(temp2);
496
497
mov_reg32_reg32(temp1, rt1);
498
mov_reg32_reg32(temp2, rt2);
499
shrd_reg32_reg32_cl(temp1, temp2);
500
sar_reg32_cl(temp2);
501
test_reg32_imm32(ECX, 0x20);
502
je_rj(5);
503
mov_reg32_reg32(temp1, temp2); // 2
504
sar_reg32_imm8(temp2, 31); // 3
505
506
mov_reg32_reg32(rd1, temp1);
507
mov_reg32_reg32(rd2, temp2);
508
}
509
#endif
510
}
511
512
void genmult(void)
513
{
514
#ifdef INTERPRET_MULT
515
gencallinterp((unsigned int)cached_interpreter_table.MULT, 0);
516
#else
517
int rs, rt;
518
allocate_register_manually_w(EAX, (unsigned int *)&lo, 0);
519
allocate_register_manually_w(EDX, (unsigned int *)&hi, 0);
520
rs = allocate_register((unsigned int*)dst->f.r.rs);
521
rt = allocate_register((unsigned int*)dst->f.r.rt);
522
mov_reg32_reg32(EAX, rs);
523
imul_reg32(rt);
524
#endif
525
}
526
527
void genmultu(void)
528
{
529
#ifdef INTERPRET_MULTU
530
gencallinterp((unsigned int)cached_interpreter_table.MULTU, 0);
531
#else
532
int rs, rt;
533
allocate_register_manually_w(EAX, (unsigned int *)&lo, 0);
534
allocate_register_manually_w(EDX, (unsigned int *)&hi, 0);
535
rs = allocate_register((unsigned int*)dst->f.r.rs);
536
rt = allocate_register((unsigned int*)dst->f.r.rt);
537
mov_reg32_reg32(EAX, rs);
538
mul_reg32(rt);
539
#endif
540
}
541
542
void gendiv(void)
543
{
544
#ifdef INTERPRET_DIV
545
gencallinterp((unsigned int)cached_interpreter_table.DIV, 0);
546
#else
547
int rs, rt;
548
allocate_register_manually_w(EAX, (unsigned int *)&lo, 0);
549
allocate_register_manually_w(EDX, (unsigned int *)&hi, 0);
550
rs = allocate_register((unsigned int*)dst->f.r.rs);
551
rt = allocate_register((unsigned int*)dst->f.r.rt);
552
cmp_reg32_imm32(rt, 0);
553
je_rj((rs == EAX ? 0 : 2) + 1 + 2);
554
mov_reg32_reg32(EAX, rs); // 0 or 2
555
cdq(); // 1
556
idiv_reg32(rt); // 2
557
#endif
558
}
559
560
void gendivu(void)
561
{
562
#ifdef INTERPRET_DIVU
563
gencallinterp((unsigned int)cached_interpreter_table.DIVU, 0);
564
#else
565
int rs, rt;
566
allocate_register_manually_w(EAX, (unsigned int *)&lo, 0);
567
allocate_register_manually_w(EDX, (unsigned int *)&hi, 0);
568
rs = allocate_register((unsigned int*)dst->f.r.rs);
569
rt = allocate_register((unsigned int*)dst->f.r.rt);
570
cmp_reg32_imm32(rt, 0);
571
je_rj((rs == EAX ? 0 : 2) + 2 + 2);
572
mov_reg32_reg32(EAX, rs); // 0 or 2
573
xor_reg32_reg32(EDX, EDX); // 2
574
div_reg32(rt); // 2
575
#endif
576
}
577
578
void gendmult(void)
579
{
580
gencallinterp((unsigned int)cached_interpreter_table.DMULT, 0);
581
}
582
583
void gendmultu(void)
584
{
585
#ifdef INTERPRET_DMULTU
586
gencallinterp((unsigned int)cached_interpreter_table.DMULTU, 0);
587
#else
588
free_all_registers();
589
simplify_access();
590
591
mov_eax_memoffs32((unsigned int *)dst->f.r.rs);
592
mul_m32((unsigned int *)dst->f.r.rt); // EDX:EAX = temp1
593
mov_memoffs32_eax((unsigned int *)(&lo));
594
595
mov_reg32_reg32(EBX, EDX); // EBX = temp1>>32
596
mov_eax_memoffs32((unsigned int *)dst->f.r.rs);
597
mul_m32((unsigned int *)(dst->f.r.rt)+1);
598
add_reg32_reg32(EBX, EAX);
599
adc_reg32_imm32(EDX, 0);
600
mov_reg32_reg32(ECX, EDX); // ECX:EBX = temp2
601
602
mov_eax_memoffs32((unsigned int *)(dst->f.r.rs)+1);
603
mul_m32((unsigned int *)dst->f.r.rt); // EDX:EAX = temp3
604
605
add_reg32_reg32(EBX, EAX);
606
adc_reg32_imm32(ECX, 0); // ECX:EBX = result2
607
mov_m32_reg32((unsigned int*)(&lo)+1, EBX);
608
609
mov_reg32_reg32(ESI, EDX); // ESI = temp3>>32
610
mov_eax_memoffs32((unsigned int *)(dst->f.r.rs)+1);
611
mul_m32((unsigned int *)(dst->f.r.rt)+1);
612
add_reg32_reg32(EAX, ESI);
613
adc_reg32_imm32(EDX, 0); // EDX:EAX = temp4
614
615
add_reg32_reg32(EAX, ECX);
616
adc_reg32_imm32(EDX, 0); // EDX:EAX = result3
617
mov_memoffs32_eax((unsigned int *)(&hi));
618
mov_m32_reg32((unsigned int *)(&hi)+1, EDX);
619
#endif
620
}
621
622
void genddiv(void)
623
{
624
gencallinterp((unsigned int)cached_interpreter_table.DDIV, 0);
625
}
626
627
void genddivu(void)
628
{
629
gencallinterp((unsigned int)cached_interpreter_table.DDIVU, 0);
630
}
631
632
void genadd(void)
633
{
634
#ifdef INTERPRET_ADD
635
gencallinterp((unsigned int)cached_interpreter_table.ADD, 0);
636
#else
637
int rs = allocate_register((unsigned int *)dst->f.r.rs);
638
int rt = allocate_register((unsigned int *)dst->f.r.rt);
639
int rd = allocate_register_w((unsigned int *)dst->f.r.rd);
640
641
if (rt != rd && rs != rd)
642
{
643
mov_reg32_reg32(rd, rs);
644
add_reg32_reg32(rd, rt);
645
}
646
else
647
{
648
int temp = lru_register();
649
free_register(temp);
650
mov_reg32_reg32(temp, rs);
651
add_reg32_reg32(temp, rt);
652
mov_reg32_reg32(rd, temp);
653
}
654
#endif
655
}
656
657
void genaddu(void)
658
{
659
#ifdef INTERPRET_ADDU
660
gencallinterp((unsigned int)cached_interpreter_table.ADDU, 0);
661
#else
662
int rs = allocate_register((unsigned int *)dst->f.r.rs);
663
int rt = allocate_register((unsigned int *)dst->f.r.rt);
664
int rd = allocate_register_w((unsigned int *)dst->f.r.rd);
665
666
if (rt != rd && rs != rd)
667
{
668
mov_reg32_reg32(rd, rs);
669
add_reg32_reg32(rd, rt);
670
}
671
else
672
{
673
int temp = lru_register();
674
free_register(temp);
675
mov_reg32_reg32(temp, rs);
676
add_reg32_reg32(temp, rt);
677
mov_reg32_reg32(rd, temp);
678
}
679
#endif
680
}
681
682
void gensub(void)
683
{
684
#ifdef INTERPRET_SUB
685
gencallinterp((unsigned int)cached_interpreter_table.SUB, 0);
686
#else
687
int rs = allocate_register((unsigned int *)dst->f.r.rs);
688
int rt = allocate_register((unsigned int *)dst->f.r.rt);
689
int rd = allocate_register_w((unsigned int *)dst->f.r.rd);
690
691
if (rt != rd && rs != rd)
692
{
693
mov_reg32_reg32(rd, rs);
694
sub_reg32_reg32(rd, rt);
695
}
696
else
697
{
698
int temp = lru_register();
699
free_register(temp);
700
mov_reg32_reg32(temp, rs);
701
sub_reg32_reg32(temp, rt);
702
mov_reg32_reg32(rd, temp);
703
}
704
#endif
705
}
706
707
void gensubu(void)
708
{
709
#ifdef INTERPRET_SUBU
710
gencallinterp((unsigned int)cached_interpreter_table.SUBU, 0);
711
#else
712
int rs = allocate_register((unsigned int *)dst->f.r.rs);
713
int rt = allocate_register((unsigned int *)dst->f.r.rt);
714
int rd = allocate_register_w((unsigned int *)dst->f.r.rd);
715
716
if (rt != rd && rs != rd)
717
{
718
mov_reg32_reg32(rd, rs);
719
sub_reg32_reg32(rd, rt);
720
}
721
else
722
{
723
int temp = lru_register();
724
free_register(temp);
725
mov_reg32_reg32(temp, rs);
726
sub_reg32_reg32(temp, rt);
727
mov_reg32_reg32(rd, temp);
728
}
729
#endif
730
}
731
732
void genand(void)
733
{
734
#ifdef INTERPRET_AND
735
gencallinterp((unsigned int)cached_interpreter_table.AND, 0);
736
#else
737
int rs1 = allocate_64_register1((unsigned int *)dst->f.r.rs);
738
int rs2 = allocate_64_register2((unsigned int *)dst->f.r.rs);
739
int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
740
int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
741
int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd);
742
int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd);
743
744
if (rt1 != rd1 && rs1 != rd1)
745
{
746
mov_reg32_reg32(rd1, rs1);
747
mov_reg32_reg32(rd2, rs2);
748
and_reg32_reg32(rd1, rt1);
749
and_reg32_reg32(rd2, rt2);
750
}
751
else
752
{
753
int temp = lru_register();
754
free_register(temp);
755
mov_reg32_reg32(temp, rs1);
756
and_reg32_reg32(temp, rt1);
757
mov_reg32_reg32(rd1, temp);
758
mov_reg32_reg32(temp, rs2);
759
and_reg32_reg32(temp, rt2);
760
mov_reg32_reg32(rd2, temp);
761
}
762
#endif
763
}
764
765
void genor(void)
766
{
767
#ifdef INTERPRET_OR
768
gencallinterp((unsigned int)cached_interpreter_table.OR, 0);
769
#else
770
int rs1 = allocate_64_register1((unsigned int *)dst->f.r.rs);
771
int rs2 = allocate_64_register2((unsigned int *)dst->f.r.rs);
772
int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
773
int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
774
int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd);
775
int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd);
776
777
if (rt1 != rd1 && rs1 != rd1)
778
{
779
mov_reg32_reg32(rd1, rs1);
780
mov_reg32_reg32(rd2, rs2);
781
or_reg32_reg32(rd1, rt1);
782
or_reg32_reg32(rd2, rt2);
783
}
784
else
785
{
786
int temp = lru_register();
787
free_register(temp);
788
mov_reg32_reg32(temp, rs1);
789
or_reg32_reg32(temp, rt1);
790
mov_reg32_reg32(rd1, temp);
791
mov_reg32_reg32(temp, rs2);
792
or_reg32_reg32(temp, rt2);
793
mov_reg32_reg32(rd2, temp);
794
}
795
#endif
796
}
797
798
void genxor(void)
799
{
800
#ifdef INTERPRET_XOR
801
gencallinterp((unsigned int)cached_interpreter_table.XOR, 0);
802
#else
803
int rs1 = allocate_64_register1((unsigned int *)dst->f.r.rs);
804
int rs2 = allocate_64_register2((unsigned int *)dst->f.r.rs);
805
int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
806
int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
807
int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd);
808
int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd);
809
810
if (rt1 != rd1 && rs1 != rd1)
811
{
812
mov_reg32_reg32(rd1, rs1);
813
mov_reg32_reg32(rd2, rs2);
814
xor_reg32_reg32(rd1, rt1);
815
xor_reg32_reg32(rd2, rt2);
816
}
817
else
818
{
819
int temp = lru_register();
820
free_register(temp);
821
mov_reg32_reg32(temp, rs1);
822
xor_reg32_reg32(temp, rt1);
823
mov_reg32_reg32(rd1, temp);
824
mov_reg32_reg32(temp, rs2);
825
xor_reg32_reg32(temp, rt2);
826
mov_reg32_reg32(rd2, temp);
827
}
828
#endif
829
}
830
831
void gennor(void)
832
{
833
#ifdef INTERPRET_NOR
834
gencallinterp((unsigned int)cached_interpreter_table.NOR, 0);
835
#else
836
int rs1 = allocate_64_register1((unsigned int *)dst->f.r.rs);
837
int rs2 = allocate_64_register2((unsigned int *)dst->f.r.rs);
838
int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
839
int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
840
int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd);
841
int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd);
842
843
if (rt1 != rd1 && rs1 != rd1)
844
{
845
mov_reg32_reg32(rd1, rs1);
846
mov_reg32_reg32(rd2, rs2);
847
or_reg32_reg32(rd1, rt1);
848
or_reg32_reg32(rd2, rt2);
849
not_reg32(rd1);
850
not_reg32(rd2);
851
}
852
else
853
{
854
int temp = lru_register();
855
free_register(temp);
856
mov_reg32_reg32(temp, rs1);
857
or_reg32_reg32(temp, rt1);
858
mov_reg32_reg32(rd1, temp);
859
mov_reg32_reg32(temp, rs2);
860
or_reg32_reg32(temp, rt2);
861
mov_reg32_reg32(rd2, temp);
862
not_reg32(rd1);
863
not_reg32(rd2);
864
}
865
#endif
866
}
867
868
void genslt(void)
869
{
870
#ifdef INTERPRET_SLT
871
gencallinterp((unsigned int)cached_interpreter_table.SLT, 0);
872
#else
873
int rs1 = allocate_64_register1((unsigned int *)dst->f.r.rs);
874
int rs2 = allocate_64_register2((unsigned int *)dst->f.r.rs);
875
int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
876
int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
877
int rd = allocate_register_w((unsigned int *)dst->f.r.rd);
878
879
cmp_reg32_reg32(rs2, rt2);
880
jl_rj(13);
881
jne_rj(4); // 2
882
cmp_reg32_reg32(rs1, rt1); // 2
883
jl_rj(7); // 2
884
mov_reg32_imm32(rd, 0); // 5
885
jmp_imm_short(5); // 2
886
mov_reg32_imm32(rd, 1); // 5
887
#endif
888
}
889
890
void gensltu(void)
891
{
892
#ifdef INTERPRET_SLTU
893
gencallinterp((unsigned int)cached_interpreter_table.SLTU, 0);
894
#else
895
int rs1 = allocate_64_register1((unsigned int *)dst->f.r.rs);
896
int rs2 = allocate_64_register2((unsigned int *)dst->f.r.rs);
897
int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
898
int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
899
int rd = allocate_register_w((unsigned int *)dst->f.r.rd);
900
901
cmp_reg32_reg32(rs2, rt2);
902
jb_rj(13);
903
jne_rj(4); // 2
904
cmp_reg32_reg32(rs1, rt1); // 2
905
jb_rj(7); // 2
906
mov_reg32_imm32(rd, 0); // 5
907
jmp_imm_short(5); // 2
908
mov_reg32_imm32(rd, 1); // 5
909
#endif
910
}
911
912
void gendadd(void)
913
{
914
#ifdef INTERPRET_DADD
915
gencallinterp((unsigned int)cached_interpreter_table.DADD, 0);
916
#else
917
int rs1 = allocate_64_register1((unsigned int *)dst->f.r.rs);
918
int rs2 = allocate_64_register2((unsigned int *)dst->f.r.rs);
919
int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
920
int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
921
int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd);
922
int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd);
923
924
if (rt1 != rd1 && rs1 != rd1)
925
{
926
mov_reg32_reg32(rd1, rs1);
927
mov_reg32_reg32(rd2, rs2);
928
add_reg32_reg32(rd1, rt1);
929
adc_reg32_reg32(rd2, rt2);
930
}
931
else
932
{
933
int temp = lru_register();
934
free_register(temp);
935
mov_reg32_reg32(temp, rs1);
936
add_reg32_reg32(temp, rt1);
937
mov_reg32_reg32(rd1, temp);
938
mov_reg32_reg32(temp, rs2);
939
adc_reg32_reg32(temp, rt2);
940
mov_reg32_reg32(rd2, temp);
941
}
942
#endif
943
}
944
945
void gendaddu(void)
946
{
947
#ifdef INTERPRET_DADDU
948
gencallinterp((unsigned int)cached_interpreter_table.DADDU, 0);
949
#else
950
int rs1 = allocate_64_register1((unsigned int *)dst->f.r.rs);
951
int rs2 = allocate_64_register2((unsigned int *)dst->f.r.rs);
952
int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
953
int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
954
int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd);
955
int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd);
956
957
if (rt1 != rd1 && rs1 != rd1)
958
{
959
mov_reg32_reg32(rd1, rs1);
960
mov_reg32_reg32(rd2, rs2);
961
add_reg32_reg32(rd1, rt1);
962
adc_reg32_reg32(rd2, rt2);
963
}
964
else
965
{
966
int temp = lru_register();
967
free_register(temp);
968
mov_reg32_reg32(temp, rs1);
969
add_reg32_reg32(temp, rt1);
970
mov_reg32_reg32(rd1, temp);
971
mov_reg32_reg32(temp, rs2);
972
adc_reg32_reg32(temp, rt2);
973
mov_reg32_reg32(rd2, temp);
974
}
975
#endif
976
}
977
978
void gendsub(void)
979
{
980
#ifdef INTERPRET_DSUB
981
gencallinterp((unsigned int)cached_interpreter_table.DSUB, 0);
982
#else
983
int rs1 = allocate_64_register1((unsigned int *)dst->f.r.rs);
984
int rs2 = allocate_64_register2((unsigned int *)dst->f.r.rs);
985
int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
986
int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
987
int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd);
988
int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd);
989
990
if (rt1 != rd1 && rs1 != rd1)
991
{
992
mov_reg32_reg32(rd1, rs1);
993
mov_reg32_reg32(rd2, rs2);
994
sub_reg32_reg32(rd1, rt1);
995
sbb_reg32_reg32(rd2, rt2);
996
}
997
else
998
{
999
int temp = lru_register();
1000
free_register(temp);
1001
mov_reg32_reg32(temp, rs1);
1002
sub_reg32_reg32(temp, rt1);
1003
mov_reg32_reg32(rd1, temp);
1004
mov_reg32_reg32(temp, rs2);
1005
sbb_reg32_reg32(temp, rt2);
1006
mov_reg32_reg32(rd2, temp);
1007
}
1008
#endif
1009
}
1010
1011
void gendsubu(void)
1012
{
1013
#ifdef INTERPRET_DSUBU
1014
gencallinterp((unsigned int)cached_interpreter_table.DSUBU, 0);
1015
#else
1016
int rs1 = allocate_64_register1((unsigned int *)dst->f.r.rs);
1017
int rs2 = allocate_64_register2((unsigned int *)dst->f.r.rs);
1018
int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
1019
int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
1020
int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd);
1021
int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd);
1022
1023
if (rt1 != rd1 && rs1 != rd1)
1024
{
1025
mov_reg32_reg32(rd1, rs1);
1026
mov_reg32_reg32(rd2, rs2);
1027
sub_reg32_reg32(rd1, rt1);
1028
sbb_reg32_reg32(rd2, rt2);
1029
}
1030
else
1031
{
1032
int temp = lru_register();
1033
free_register(temp);
1034
mov_reg32_reg32(temp, rs1);
1035
sub_reg32_reg32(temp, rt1);
1036
mov_reg32_reg32(rd1, temp);
1037
mov_reg32_reg32(temp, rs2);
1038
sbb_reg32_reg32(temp, rt2);
1039
mov_reg32_reg32(rd2, temp);
1040
}
1041
#endif
1042
}
1043
1044
void genteq(void)
1045
{
1046
gencallinterp((unsigned int)cached_interpreter_table.TEQ, 0);
1047
}
1048
1049
void gendsll(void)
1050
{
1051
#ifdef INTERPRET_DSLL
1052
gencallinterp((unsigned int)cached_interpreter_table.DSLL, 0);
1053
#else
1054
int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
1055
int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
1056
int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd);
1057
int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd);
1058
1059
mov_reg32_reg32(rd1, rt1);
1060
mov_reg32_reg32(rd2, rt2);
1061
shld_reg32_reg32_imm8(rd2, rd1, dst->f.r.sa);
1062
shl_reg32_imm8(rd1, dst->f.r.sa);
1063
if (dst->f.r.sa & 0x20)
1064
{
1065
mov_reg32_reg32(rd2, rd1);
1066
xor_reg32_reg32(rd1, rd1);
1067
}
1068
#endif
1069
}
1070
1071
void gendsrl(void)
1072
{
1073
#ifdef INTERPRET_DSRL
1074
gencallinterp((unsigned int)cached_interpreter_table.DSRL, 0);
1075
#else
1076
int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
1077
int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
1078
int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd);
1079
int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd);
1080
1081
mov_reg32_reg32(rd1, rt1);
1082
mov_reg32_reg32(rd2, rt2);
1083
shrd_reg32_reg32_imm8(rd1, rd2, dst->f.r.sa);
1084
shr_reg32_imm8(rd2, dst->f.r.sa);
1085
if (dst->f.r.sa & 0x20)
1086
{
1087
mov_reg32_reg32(rd1, rd2);
1088
xor_reg32_reg32(rd2, rd2);
1089
}
1090
#endif
1091
}
1092
1093
void gendsra(void)
1094
{
1095
#ifdef INTERPRET_DSRA
1096
gencallinterp((unsigned int)cached_interpreter_table.DSRA, 0);
1097
#else
1098
int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
1099
int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
1100
int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd);
1101
int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd);
1102
1103
mov_reg32_reg32(rd1, rt1);
1104
mov_reg32_reg32(rd2, rt2);
1105
shrd_reg32_reg32_imm8(rd1, rd2, dst->f.r.sa);
1106
sar_reg32_imm8(rd2, dst->f.r.sa);
1107
if (dst->f.r.sa & 0x20)
1108
{
1109
mov_reg32_reg32(rd1, rd2);
1110
sar_reg32_imm8(rd2, 31);
1111
}
1112
#endif
1113
}
1114
1115
void gendsll32(void)
1116
{
1117
#ifdef INTERPRET_DSLL32
1118
gencallinterp((unsigned int)cached_interpreter_table.DSLL32, 0);
1119
#else
1120
int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
1121
int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd);
1122
int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd);
1123
1124
mov_reg32_reg32(rd2, rt1);
1125
shl_reg32_imm8(rd2, dst->f.r.sa);
1126
xor_reg32_reg32(rd1, rd1);
1127
#endif
1128
}
1129
1130
void gendsrl32(void)
1131
{
1132
#ifdef INTERPRET_DSRL32
1133
gencallinterp((unsigned int)cached_interpreter_table.DSRL32, 0);
1134
#else
1135
int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
1136
int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd);
1137
int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd);
1138
1139
mov_reg32_reg32(rd1, rt2);
1140
shr_reg32_imm8(rd1, dst->f.r.sa);
1141
xor_reg32_reg32(rd2, rd2);
1142
#endif
1143
}
1144
1145
void gendsra32(void)
1146
{
1147
#ifdef INTERPRET_DSRA32
1148
gencallinterp((unsigned int)cached_interpreter_table.DSRA32, 0);
1149
#else
1150
int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
1151
int rd = allocate_register_w((unsigned int *)dst->f.r.rd);
1152
1153
mov_reg32_reg32(rd, rt2);
1154
sar_reg32_imm8(rd, dst->f.r.sa);
1155
#endif
1156
}
1157
1158
1159