1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Mupen64plus - gregimm.c *
3 * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
4 * Copyright (C) 2007 Richard Goedeken (Richard42) *
5 * Copyright (C) 2002 Hacktarux *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
21 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
26 #include "interpret.h"
28 #include "r4300/recomph.h"
29 #include "r4300/recomp.h"
30 #include "r4300/r4300.h"
31 #include "r4300/ops.h"
32 #include "r4300/macros.h"
34 #include "memory/memory.h"
36 static void genbltz_test(void)
38 int rs_64bit = is64((unsigned int *)dst->f.i.rs);
42 int rs = allocate_register_32((unsigned int *)dst->f.i.rs);
44 cmp_reg32_imm32(rs, 0);
45 setl_m8rel((unsigned char *) &branch_taken);
47 else if (rs_64bit == -1)
49 cmp_m32rel_imm32(((unsigned int *)dst->f.i.rs)+1, 0);
50 setl_m8rel((unsigned char *) &branch_taken);
54 int rs = allocate_register_64((unsigned long long *)dst->f.i.rs);
56 cmp_reg64_imm8(rs, 0);
57 setl_m8rel((unsigned char *) &branch_taken);
63 #if defined(COUNT_INSTR)
64 inc_m32rel(&instr_count[47]);
67 gencallinterp((unsigned long long)cached_interpreter_table.BLTZ, 1);
69 if (((dst->addr & 0xFFF) == 0xFFC &&
70 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
72 gencallinterp((unsigned long long)cached_interpreter_table.BLTZ, 1);
82 void genbltz_out(void)
84 #if defined(COUNT_INSTR)
85 inc_m32rel(&instr_count[47]);
87 #ifdef INTERPRET_BLTZ_OUT
88 gencallinterp((unsigned long long)cached_interpreter_table.BLTZ_OUT, 1);
90 if (((dst->addr & 0xFFF) == 0xFFC &&
91 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
93 gencallinterp((unsigned long long)cached_interpreter_table.BLTZ_OUT, 1);
103 void genbltz_idle(void)
105 #ifdef INTERPRET_BLTZ_IDLE
106 gencallinterp((unsigned long long)cached_interpreter_table.BLTZ_IDLE, 1);
108 if (((dst->addr & 0xFFF) == 0xFFC &&
109 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
111 gencallinterp((unsigned long long)cached_interpreter_table.BLTZ_IDLE, 1);
121 static void genbgez_test(void)
123 int rs_64bit = is64((unsigned int *)dst->f.i.rs);
127 int rs = allocate_register_32((unsigned int *)dst->f.i.rs);
128 cmp_reg32_imm32(rs, 0);
129 setge_m8rel((unsigned char *) &branch_taken);
131 else if (rs_64bit == -1)
133 cmp_m32rel_imm32(((unsigned int *)dst->f.i.rs)+1, 0);
134 setge_m8rel((unsigned char *) &branch_taken);
138 int rs = allocate_register_64((unsigned long long *)dst->f.i.rs);
139 cmp_reg64_imm8(rs, 0);
140 setge_m8rel((unsigned char *) &branch_taken);
146 #if defined(COUNT_INSTR)
147 inc_m32rel(&instr_count[48]);
149 #ifdef INTERPRET_BGEZ
150 gencallinterp((unsigned long long)cached_interpreter_table.BGEZ, 1);
152 if (((dst->addr & 0xFFF) == 0xFFC &&
153 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
155 gencallinterp((unsigned long long)cached_interpreter_table.BGEZ, 1);
165 void genbgez_out(void)
167 #if defined(COUNT_INSTR)
168 inc_m32rel(&instr_count[48]);
170 #ifdef INTERPRET_BGEZ_OUT
171 gencallinterp((unsigned long long)cached_interpreter_table.BGEZ_OUT, 1);
173 if (((dst->addr & 0xFFF) == 0xFFC &&
174 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
176 gencallinterp((unsigned long long)cached_interpreter_table.BGEZ_OUT, 1);
186 void genbgez_idle(void)
188 #ifdef INTERPRET_BGEZ_IDLE
189 gencallinterp((unsigned long long)cached_interpreter_table.BGEZ_IDLE, 1);
191 if (((dst->addr & 0xFFF) == 0xFFC &&
192 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
194 gencallinterp((unsigned long long)cached_interpreter_table.BGEZ_IDLE, 1);
206 #if defined(COUNT_INSTR)
207 inc_m32rel(&instr_count[49]);
209 #ifdef INTERPRET_BLTZL
210 gencallinterp((unsigned long long)cached_interpreter_table.BLTZL, 1);
212 if (((dst->addr & 0xFFF) == 0xFFC &&
213 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
215 gencallinterp((unsigned long long)cached_interpreter_table.BLTZL, 1);
220 free_all_registers();
225 void genbltzl_out(void)
227 #if defined(COUNT_INSTR)
228 inc_m32rel(&instr_count[49]);
230 #ifdef INTERPRET_BLTZL_OUT
231 gencallinterp((unsigned long long)cached_interpreter_table.BLTZL_OUT, 1);
233 if (((dst->addr & 0xFFF) == 0xFFC &&
234 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
236 gencallinterp((unsigned long long)cached_interpreter_table.BLTZL_OUT, 1);
241 free_all_registers();
246 void genbltzl_idle(void)
248 #ifdef INTERPRET_BLTZL_IDLE
249 gencallinterp((unsigned long long)cached_interpreter_table.BLTZL_IDLE, 1);
251 if (((dst->addr & 0xFFF) == 0xFFC &&
252 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
254 gencallinterp((unsigned long long)cached_interpreter_table.BLTZL_IDLE, 1);
266 #if defined(COUNT_INSTR)
267 inc_m32rel(&instr_count[50]);
269 #ifdef INTERPRET_BGEZL
270 gencallinterp((unsigned long long)cached_interpreter_table.BGEZL, 1);
272 if (((dst->addr & 0xFFF) == 0xFFC &&
273 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
275 gencallinterp((unsigned long long)cached_interpreter_table.BGEZL, 1);
280 free_all_registers();
285 void genbgezl_out(void)
287 #if defined(COUNT_INSTR)
288 inc_m32rel(&instr_count[50]);
290 #ifdef INTERPRET_BGEZL_OUT
291 gencallinterp((unsigned long long)cached_interpreter_table.BGEZL_OUT, 1);
293 if (((dst->addr & 0xFFF) == 0xFFC &&
294 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
296 gencallinterp((unsigned long long)cached_interpreter_table.BGEZL_OUT, 1);
301 free_all_registers();
306 void genbgezl_idle(void)
308 #ifdef INTERPRET_BGEZL_IDLE
309 gencallinterp((unsigned long long)cached_interpreter_table.BGEZL_IDLE, 1);
311 if (((dst->addr & 0xFFF) == 0xFFC &&
312 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
314 gencallinterp((unsigned long long)cached_interpreter_table.BGEZL_IDLE, 1);
324 static void genbranchlink(void)
326 int r31_64bit = is64((unsigned int*)®[31]);
330 int r31 = allocate_register_32_w((unsigned int *)®[31]);
332 mov_reg32_imm32(r31, dst->addr+8);
334 else if (r31_64bit == -1)
336 mov_m32rel_imm32((unsigned int *)®[31], dst->addr + 8);
337 if (dst->addr & 0x80000000)
338 mov_m32rel_imm32(((unsigned int *)®[31])+1, 0xFFFFFFFF);
340 mov_m32rel_imm32(((unsigned int *)®[31])+1, 0);
344 int r31 = allocate_register_64_w((unsigned long long *)®[31]);
346 mov_reg32_imm32(r31, dst->addr+8);
347 movsxd_reg64_reg32(r31, r31);
353 #if defined(COUNT_INSTR)
354 inc_m32rel(&instr_count[51]);
356 #ifdef INTERPRET_BLTZAL
357 gencallinterp((unsigned long long)cached_interpreter_table.BLTZAL, 1);
359 if (((dst->addr & 0xFFF) == 0xFFC &&
360 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
362 gencallinterp((unsigned long long)cached_interpreter_table.BLTZAL, 1);
373 void genbltzal_out(void)
375 #if defined(COUNT_INSTR)
376 inc_m32rel(&instr_count[51]);
378 #ifdef INTERPRET_BLTZAL_OUT
379 gencallinterp((unsigned long long)cached_interpreter_table.BLTZAL_OUT, 1);
381 if (((dst->addr & 0xFFF) == 0xFFC &&
382 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
384 gencallinterp((unsigned long long)cached_interpreter_table.BLTZAL_OUT, 1);
395 void genbltzal_idle(void)
397 #ifdef INTERPRET_BLTZAL_IDLE
398 gencallinterp((unsigned long long)cached_interpreter_table.BLTZAL_IDLE, 1);
400 if (((dst->addr & 0xFFF) == 0xFFC &&
401 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
403 gencallinterp((unsigned long long)cached_interpreter_table.BLTZAL_IDLE, 1);
416 #if defined(COUNT_INSTR)
417 inc_m32rel(&instr_count[52]);
419 #ifdef INTERPRET_BGEZAL
420 gencallinterp((unsigned long long)cached_interpreter_table.BGEZAL, 1);
422 if (((dst->addr & 0xFFF) == 0xFFC &&
423 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
425 gencallinterp((unsigned long long)cached_interpreter_table.BGEZAL, 1);
436 void genbgezal_out(void)
438 #if defined(COUNT_INSTR)
439 inc_m32rel(&instr_count[52]);
441 #ifdef INTERPRET_BGEZAL_OUT
442 gencallinterp((unsigned long long)cached_interpreter_table.BGEZAL_OUT, 1);
444 if (((dst->addr & 0xFFF) == 0xFFC &&
445 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
447 gencallinterp((unsigned long long)cached_interpreter_table.BGEZAL_OUT, 1);
458 void genbgezal_idle(void)
460 #ifdef INTERPRET_BGEZAL_IDLE
461 gencallinterp((unsigned long long)cached_interpreter_table.BGEZAL_IDLE, 1);
463 if (((dst->addr & 0xFFF) == 0xFFC &&
464 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
466 gencallinterp((unsigned long long)cached_interpreter_table.BGEZAL_IDLE, 1);
477 void genbltzall(void)
479 #if defined(COUNT_INSTR)
480 inc_m32rel(&instr_count[53]);
482 #ifdef INTERPRET_BLTZALL
483 gencallinterp((unsigned long long)cached_interpreter_table.BLTZALL, 1);
485 if (((dst->addr & 0xFFF) == 0xFFC &&
486 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
488 gencallinterp((unsigned long long)cached_interpreter_table.BLTZALL, 1);
494 free_all_registers();
499 void genbltzall_out(void)
501 #if defined(COUNT_INSTR)
502 inc_m32rel(&instr_count[53]);
504 #ifdef INTERPRET_BLTZALL_OUT
505 gencallinterp((unsigned long long)cached_interpreter_table.BLTZALL_OUT, 1);
507 if (((dst->addr & 0xFFF) == 0xFFC &&
508 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
510 gencallinterp((unsigned long long)cached_interpreter_table.BLTZALL_OUT, 1);
516 free_all_registers();
521 void genbltzall_idle(void)
523 #ifdef INTERPRET_BLTZALL_IDLE
524 gencallinterp((unsigned long long)cached_interpreter_table.BLTZALL_IDLE, 1);
526 if (((dst->addr & 0xFFF) == 0xFFC &&
527 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
529 gencallinterp((unsigned long long)cached_interpreter_table.BLTZALL_IDLE, 1);
540 void genbgezall(void)
542 #if defined(COUNT_INSTR)
543 inc_m32rel(&instr_count[54]);
545 #ifdef INTERPRET_BGEZALL
546 gencallinterp((unsigned long long)cached_interpreter_table.BGEZALL, 1);
548 if (((dst->addr & 0xFFF) == 0xFFC &&
549 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
551 gencallinterp((unsigned long long)cached_interpreter_table.BGEZALL, 1);
557 free_all_registers();
562 void genbgezall_out(void)
564 #if defined(COUNT_INSTR)
565 inc_m32rel(&instr_count[54]);
567 #ifdef INTERPRET_BGEZALL_OUT
568 gencallinterp((unsigned long long)cached_interpreter_table.BGEZALL_OUT, 1);
570 if (((dst->addr & 0xFFF) == 0xFFC &&
571 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
573 gencallinterp((unsigned long long)cached_interpreter_table.BGEZALL_OUT, 1);
579 free_all_registers();
584 void genbgezall_idle(void)
586 #ifdef INTERPRET_BGEZALL_IDLE
587 gencallinterp((unsigned long long)cached_interpreter_table.BGEZALL_IDLE, 1);
589 if (((dst->addr & 0xFFF) == 0xFFC &&
590 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
592 gencallinterp((unsigned long long)cached_interpreter_table.BGEZALL_IDLE, 1);