Core commit. Compile and run on the OpenPandora
[mupen64plus-pandora.git] / source / mupen64plus-core / src / r4300 / x86 / gregimm.c
CommitLineData
451ab91e 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
35static 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
69void 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
87void 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
105void 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
123static 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
157void 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
175void 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
193void 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
211void 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
229void 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
247void 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
265void 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
283void 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
301void 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
319static 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
350void 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
369void 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
388void 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
407void 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
426void 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
445void 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
464void 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
483void 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
502void 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
521void 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
540void 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
559void 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