Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libmupen64plus/mupen64plus-core/src/r4300/x86/gregimm.c
2 views
1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
* Mupen64plus - gregimm.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
33
#include "memory/memory.h"
34
35
static void genbltz_test(void)
36
{
37
int rs_64bit = is64((unsigned int *)dst->f.i.rs);
38
39
if (!rs_64bit)
40
{
41
int rs = allocate_register((unsigned int *)dst->f.i.rs);
42
43
cmp_reg32_imm32(rs, 0);
44
jge_rj(12);
45
mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10
46
jmp_imm_short(10); // 2
47
mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10
48
}
49
else if (rs_64bit == -1)
50
{
51
cmp_m32_imm32(((unsigned int *)dst->f.i.rs)+1, 0);
52
jge_rj(12);
53
mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10
54
jmp_imm_short(10); // 2
55
mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10
56
}
57
else
58
{
59
int rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs);
60
61
cmp_reg32_imm32(rs2, 0);
62
jge_rj(12);
63
mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10
64
jmp_imm_short(10); // 2
65
mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10
66
}
67
}
68
69
void genbltz(void)
70
{
71
#ifdef INTERPRET_BLTZ
72
gencallinterp((unsigned int)cached_interpreter_table.BLTZ, 1);
73
#else
74
if (((dst->addr & 0xFFF) == 0xFFC &&
75
(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
76
{
77
gencallinterp((unsigned int)cached_interpreter_table.BLTZ, 1);
78
return;
79
}
80
81
genbltz_test();
82
gendelayslot();
83
gentest();
84
#endif
85
}
86
87
void genbltz_out(void)
88
{
89
#ifdef INTERPRET_BLTZ_OUT
90
gencallinterp((unsigned int)cached_interpreter_table.BLTZ_OUT, 1);
91
#else
92
if (((dst->addr & 0xFFF) == 0xFFC &&
93
(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
94
{
95
gencallinterp((unsigned int)cached_interpreter_table.BLTZ_OUT, 1);
96
return;
97
}
98
99
genbltz_test();
100
gendelayslot();
101
gentest_out();
102
#endif
103
}
104
105
void genbltz_idle(void)
106
{
107
#ifdef INTERPRET_BLTZ_IDLE
108
gencallinterp((unsigned int)cached_interpreter_table.BLTZ_IDLE, 1);
109
#else
110
if (((dst->addr & 0xFFF) == 0xFFC &&
111
(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
112
{
113
gencallinterp((unsigned int)cached_interpreter_table.BLTZ_IDLE, 1);
114
return;
115
}
116
117
genbltz_test();
118
gentest_idle();
119
genbltz();
120
#endif
121
}
122
123
static void genbgez_test(void)
124
{
125
int rs_64bit = is64((unsigned int *)dst->f.i.rs);
126
127
if (!rs_64bit)
128
{
129
int rs = allocate_register((unsigned int *)dst->f.i.rs);
130
131
cmp_reg32_imm32(rs, 0);
132
jl_rj(12);
133
mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10
134
jmp_imm_short(10); // 2
135
mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10
136
}
137
else if (rs_64bit == -1)
138
{
139
cmp_m32_imm32(((unsigned int *)dst->f.i.rs)+1, 0);
140
jl_rj(12);
141
mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10
142
jmp_imm_short(10); // 2
143
mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10
144
}
145
else
146
{
147
int rs2 = allocate_64_register2((unsigned int *)dst->f.i.rs);
148
149
cmp_reg32_imm32(rs2, 0);
150
jl_rj(12);
151
mov_m32_imm32((unsigned int *)(&branch_taken), 1); // 10
152
jmp_imm_short(10); // 2
153
mov_m32_imm32((unsigned int *)(&branch_taken), 0); // 10
154
}
155
}
156
157
void genbgez(void)
158
{
159
#ifdef INTERPRET_BGEZ
160
gencallinterp((unsigned int)cached_interpreter_table.BGEZ, 1);
161
#else
162
if (((dst->addr & 0xFFF) == 0xFFC &&
163
(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
164
{
165
gencallinterp((unsigned int)cached_interpreter_table.BGEZ, 1);
166
return;
167
}
168
169
genbgez_test();
170
gendelayslot();
171
gentest();
172
#endif
173
}
174
175
void genbgez_out(void)
176
{
177
#ifdef INTERPRET_BGEZ_OUT
178
gencallinterp((unsigned int)cached_interpreter_table.BGEZ_OUT, 1);
179
#else
180
if (((dst->addr & 0xFFF) == 0xFFC &&
181
(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
182
{
183
gencallinterp((unsigned int)cached_interpreter_table.BGEZ_OUT, 1);
184
return;
185
}
186
187
genbgez_test();
188
gendelayslot();
189
gentest_out();
190
#endif
191
}
192
193
void genbgez_idle(void)
194
{
195
#ifdef INTERPRET_BGEZ_IDLE
196
gencallinterp((unsigned int)cached_interpreter_table.BGEZ_IDLE, 1);
197
#else
198
if (((dst->addr & 0xFFF) == 0xFFC &&
199
(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
200
{
201
gencallinterp((unsigned int)cached_interpreter_table.BGEZ_IDLE, 1);
202
return;
203
}
204
205
genbgez_test();
206
gentest_idle();
207
genbgez();
208
#endif
209
}
210
211
void genbltzl(void)
212
{
213
#ifdef INTERPRET_BLTZL
214
gencallinterp((unsigned int)cached_interpreter_table.BLTZL, 1);
215
#else
216
if (((dst->addr & 0xFFF) == 0xFFC &&
217
(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
218
{
219
gencallinterp((unsigned int)cached_interpreter_table.BLTZL, 1);
220
return;
221
}
222
223
genbltz_test();
224
free_all_registers();
225
gentestl();
226
#endif
227
}
228
229
void genbltzl_out(void)
230
{
231
#ifdef INTERPRET_BLTZL_OUT
232
gencallinterp((unsigned int)cached_interpreter_table.BLTZL_OUT, 1);
233
#else
234
if (((dst->addr & 0xFFF) == 0xFFC &&
235
(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
236
{
237
gencallinterp((unsigned int)cached_interpreter_table.BLTZL_OUT, 1);
238
return;
239
}
240
241
genbltz_test();
242
free_all_registers();
243
gentestl_out();
244
#endif
245
}
246
247
void genbltzl_idle(void)
248
{
249
#ifdef INTERPRET_BLTZL_IDLE
250
gencallinterp((unsigned int)cached_interpreter_table.BLTZL_IDLE, 1);
251
#else
252
if (((dst->addr & 0xFFF) == 0xFFC &&
253
(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
254
{
255
gencallinterp((unsigned int)cached_interpreter_table.BLTZL_IDLE, 1);
256
return;
257
}
258
259
genbltz_test();
260
gentest_idle();
261
genbltzl();
262
#endif
263
}
264
265
void genbgezl(void)
266
{
267
#ifdef INTERPRET_BGEZL
268
gencallinterp((unsigned int)cached_interpreter_table.BGEZL, 1);
269
#else
270
if (((dst->addr & 0xFFF) == 0xFFC &&
271
(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
272
{
273
gencallinterp((unsigned int)cached_interpreter_table.BGEZL, 1);
274
return;
275
}
276
277
genbgez_test();
278
free_all_registers();
279
gentestl();
280
#endif
281
}
282
283
void genbgezl_out(void)
284
{
285
#ifdef INTERPRET_BGEZL_OUT
286
gencallinterp((unsigned int)cached_interpreter_table.BGEZL_OUT, 1);
287
#else
288
if (((dst->addr & 0xFFF) == 0xFFC &&
289
(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
290
{
291
gencallinterp((unsigned int)cached_interpreter_table.BGEZL_OUT, 1);
292
return;
293
}
294
295
genbgez_test();
296
free_all_registers();
297
gentestl_out();
298
#endif
299
}
300
301
void genbgezl_idle(void)
302
{
303
#ifdef INTERPRET_BGEZL_IDLE
304
gencallinterp((unsigned int)cached_interpreter_table.BGEZL_IDLE, 1);
305
#else
306
if (((dst->addr & 0xFFF) == 0xFFC &&
307
(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
308
{
309
gencallinterp((unsigned int)cached_interpreter_table.BGEZL_IDLE, 1);
310
return;
311
}
312
313
genbgez_test();
314
gentest_idle();
315
genbgezl();
316
#endif
317
}
318
319
static void genbranchlink(void)
320
{
321
int r31_64bit = is64((unsigned int*)&reg[31]);
322
323
if (!r31_64bit)
324
{
325
int r31 = allocate_register_w((unsigned int *)&reg[31]);
326
327
mov_reg32_imm32(r31, dst->addr+8);
328
}
329
else if (r31_64bit == -1)
330
{
331
mov_m32_imm32((unsigned int *)&reg[31], dst->addr + 8);
332
if (dst->addr & 0x80000000)
333
mov_m32_imm32(((unsigned int *)&reg[31])+1, 0xFFFFFFFF);
334
else
335
mov_m32_imm32(((unsigned int *)&reg[31])+1, 0);
336
}
337
else
338
{
339
int r311 = allocate_64_register1_w((unsigned int *)&reg[31]);
340
int r312 = allocate_64_register2_w((unsigned int *)&reg[31]);
341
342
mov_reg32_imm32(r311, dst->addr+8);
343
if (dst->addr & 0x80000000)
344
mov_reg32_imm32(r312, 0xFFFFFFFF);
345
else
346
mov_reg32_imm32(r312, 0);
347
}
348
}
349
350
void genbltzal(void)
351
{
352
#ifdef INTERPRET_BLTZAL
353
gencallinterp((unsigned int)cached_interpreter_table.BLTZAL, 1);
354
#else
355
if (((dst->addr & 0xFFF) == 0xFFC &&
356
(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
357
{
358
gencallinterp((unsigned int)cached_interpreter_table.BLTZAL, 1);
359
return;
360
}
361
362
genbltz_test();
363
genbranchlink();
364
gendelayslot();
365
gentest();
366
#endif
367
}
368
369
void genbltzal_out(void)
370
{
371
#ifdef INTERPRET_BLTZAL_OUT
372
gencallinterp((unsigned int)cached_interpreter_table.BLTZAL_OUT, 1);
373
#else
374
if (((dst->addr & 0xFFF) == 0xFFC &&
375
(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
376
{
377
gencallinterp((unsigned int)cached_interpreter_table.BLTZAL_OUT, 1);
378
return;
379
}
380
381
genbltz_test();
382
genbranchlink();
383
gendelayslot();
384
gentest_out();
385
#endif
386
}
387
388
void genbltzal_idle(void)
389
{
390
#ifdef INTERPRET_BLTZAL_IDLE
391
gencallinterp((unsigned int)cached_interpreter_table.BLTZAL_IDLE, 1);
392
#else
393
if (((dst->addr & 0xFFF) == 0xFFC &&
394
(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
395
{
396
gencallinterp((unsigned int)cached_interpreter_table.BLTZAL_IDLE, 1);
397
return;
398
}
399
400
genbltz_test();
401
genbranchlink();
402
gentest_idle();
403
genbltzal();
404
#endif
405
}
406
407
void genbgezal(void)
408
{
409
#ifdef INTERPRET_BGEZAL
410
gencallinterp((unsigned int)cached_interpreter_table.BGEZAL, 1);
411
#else
412
if (((dst->addr & 0xFFF) == 0xFFC &&
413
(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
414
{
415
gencallinterp((unsigned int)cached_interpreter_table.BGEZAL, 1);
416
return;
417
}
418
419
genbgez_test();
420
genbranchlink();
421
gendelayslot();
422
gentest();
423
#endif
424
}
425
426
void genbgezal_out(void)
427
{
428
#ifdef INTERPRET_BGEZAL_OUT
429
gencallinterp((unsigned int)cached_interpreter_table.BGEZAL_OUT, 1);
430
#else
431
if (((dst->addr & 0xFFF) == 0xFFC &&
432
(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
433
{
434
gencallinterp((unsigned int)cached_interpreter_table.BGEZAL_OUT, 1);
435
return;
436
}
437
438
genbgez_test();
439
genbranchlink();
440
gendelayslot();
441
gentest_out();
442
#endif
443
}
444
445
void genbgezal_idle(void)
446
{
447
#ifdef INTERPRET_BGEZAL_IDLE
448
gencallinterp((unsigned int)cached_interpreter_table.BGEZAL_IDLE, 1);
449
#else
450
if (((dst->addr & 0xFFF) == 0xFFC &&
451
(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
452
{
453
gencallinterp((unsigned int)cached_interpreter_table.BGEZAL_IDLE, 1);
454
return;
455
}
456
457
genbgez_test();
458
genbranchlink();
459
gentest_idle();
460
genbgezal();
461
#endif
462
}
463
464
void genbltzall(void)
465
{
466
#ifdef INTERPRET_BLTZALL
467
gencallinterp((unsigned int)cached_interpreter_table.BLTZALL, 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.BLTZALL, 1);
473
return;
474
}
475
476
genbltz_test();
477
genbranchlink();
478
free_all_registers();
479
gentestl();
480
#endif
481
}
482
483
void genbltzall_out(void)
484
{
485
#ifdef INTERPRET_BLTZALL_OUT
486
gencallinterp((unsigned int)cached_interpreter_table.BLTZALL_OUT, 1);
487
#else
488
if (((dst->addr & 0xFFF) == 0xFFC &&
489
(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
490
{
491
gencallinterp((unsigned int)cached_interpreter_table.BLTZALL_OUT, 1);
492
return;
493
}
494
495
genbltz_test();
496
genbranchlink();
497
free_all_registers();
498
gentestl_out();
499
#endif
500
}
501
502
void genbltzall_idle(void)
503
{
504
#ifdef INTERPRET_BLTZALL_IDLE
505
gencallinterp((unsigned int)cached_interpreter_table.BLTZALL_IDLE, 1);
506
#else
507
if (((dst->addr & 0xFFF) == 0xFFC &&
508
(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
509
{
510
gencallinterp((unsigned int)cached_interpreter_table.BLTZALL_IDLE, 1);
511
return;
512
}
513
514
genbltz_test();
515
genbranchlink();
516
gentest_idle();
517
genbltzall();
518
#endif
519
}
520
521
void genbgezall(void)
522
{
523
#ifdef INTERPRET_BGEZALL
524
gencallinterp((unsigned int)cached_interpreter_table.BGEZALL, 1);
525
#else
526
if (((dst->addr & 0xFFF) == 0xFFC &&
527
(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
528
{
529
gencallinterp((unsigned int)cached_interpreter_table.BGEZALL, 1);
530
return;
531
}
532
533
genbgez_test();
534
genbranchlink();
535
free_all_registers();
536
gentestl();
537
#endif
538
}
539
540
void genbgezall_out(void)
541
{
542
#ifdef INTERPRET_BGEZALL_OUT
543
gencallinterp((unsigned int)cached_interpreter_table.BGEZALL_OUT, 1);
544
#else
545
if (((dst->addr & 0xFFF) == 0xFFC &&
546
(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
547
{
548
gencallinterp((unsigned int)cached_interpreter_table.BGEZALL_OUT, 1);
549
return;
550
}
551
552
genbgez_test();
553
genbranchlink();
554
free_all_registers();
555
gentestl_out();
556
#endif
557
}
558
559
void genbgezall_idle(void)
560
{
561
#ifdef INTERPRET_BGEZALL_IDLE
562
gencallinterp((unsigned int)cached_interpreter_table.BGEZALL_IDLE, 1);
563
#else
564
if (((dst->addr & 0xFFF) == 0xFFC &&
565
(dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
566
{
567
gencallinterp((unsigned int)cached_interpreter_table.BGEZALL_IDLE, 1);
568
return;
569
}
570
571
genbgez_test();
572
genbranchlink();
573
gentest_idle();
574
genbgezall();
575
#endif
576
}
577
578
579