1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Mupen64plus - regcache.c *
3 * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
4 * Copyright (C) 2002 Hacktarux *
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. *
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. *
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 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
26 #include "r4300/recomp.h"
27 #include "r4300/r4300.h"
28 #include "r4300/recomph.h"
30 static unsigned int* reg_content[8];
31 static precomp_instr* last_access[8];
32 static precomp_instr* free_since[8];
35 static unsigned int* r0;
37 void init_cache(precomp_instr* start)
42 last_access[i] = NULL;
43 free_since[i] = start;
45 r0 = (unsigned int*)reg;
48 void free_all_registers(void)
50 #if defined(PROFILE_R4300)
51 int freestart = code_length;
58 #if defined(PROFILE_R4300)
59 if (last_access[i] && dirty[i]) flushed = 1;
61 if (last_access[i]) free_register(i);
64 while (free_since[i] <= dst)
66 free_since[i]->reg_cache_infos.needed_registers[i] = NULL;
72 #if defined(PROFILE_R4300)
75 long x86addr = (long) ((*inst_pointer) + freestart);
77 fwrite(&mipsop, 1, 4, pfProfile); /* -5 = regcache flushing */
78 fwrite(&x86addr, 1, sizeof(char *), pfProfile); // write pointer to start of register cache flushing instructions
79 x86addr = (long) ((*inst_pointer) + code_length);
80 fwrite(&src, 1, 4, pfProfile); // write 4-byte MIPS opcode for current instruction
81 fwrite(&x86addr, 1, sizeof(char *), pfProfile); // write pointer to dynamically generated x86 code for this MIPS instruction
86 // this function frees a specific X86 GPR
87 void free_register(int reg)
91 if (last_access[reg] != NULL &&
92 r64[reg] != -1 && (int)reg_content[reg] != (int)reg_content[r64[reg]]-4)
94 free_register(r64[reg]);
98 if (last_access[reg] != NULL) last = last_access[reg]+1;
99 else last = free_since[reg];
103 if (last_access[reg] != NULL && dirty[reg])
104 last->reg_cache_infos.needed_registers[reg] = reg_content[reg];
106 last->reg_cache_infos.needed_registers[reg] = NULL;
108 if (last_access[reg] != NULL && r64[reg] != -1)
111 last->reg_cache_infos.needed_registers[r64[reg]] = reg_content[r64[reg]];
113 last->reg_cache_infos.needed_registers[r64[reg]] = NULL;
118 if (last_access[reg] == NULL)
120 free_since[reg] = dst+1;
126 mov_m32_reg32(reg_content[reg], reg);
129 sar_reg32_imm8(reg, 31);
130 mov_m32_reg32((unsigned int*)reg_content[reg]+1, reg);
132 else mov_m32_reg32(reg_content[r64[reg]], r64[reg]);
134 last_access[reg] = NULL;
135 free_since[reg] = dst+1;
138 last_access[r64[reg]] = NULL;
139 free_since[r64[reg]] = dst+1;
143 int lru_register(void)
145 unsigned int oldest_access = 0xFFFFFFFF;
149 if (i != ESP && (unsigned int)last_access[i] < oldest_access)
151 oldest_access = (int)last_access[i];
158 int lru_register_exc1(int exc1)
160 unsigned int oldest_access = 0xFFFFFFFF;
164 if (i != ESP && i != exc1 && (unsigned int)last_access[i] < oldest_access)
166 oldest_access = (int)last_access[i];
173 // this function finds a register to put the data contained in addr,
174 // if there was another value before it's cleanly removed of the
175 // register cache. After that, the register number is returned.
176 // If data are already cached, the function only returns the register number
177 int allocate_register(unsigned int *addr)
179 unsigned int oldest_access = 0xFFFFFFFF;
182 // is it already cached ?
187 if (last_access[i] != NULL && reg_content[i] == addr)
189 precomp_instr *last = last_access[i]+1;
193 last->reg_cache_infos.needed_registers[i] = reg_content[i];
196 last_access[i] = dst;
199 last = last_access[r64[i]]+1;
203 last->reg_cache_infos.needed_registers[r64[i]] = reg_content[r64[i]];
206 last_access[r64[i]] = dst;
214 // if it's not cached, we take the least recently used register
217 if (i != ESP && (unsigned int)last_access[i] < oldest_access)
219 oldest_access = (int)last_access[i];
224 if (last_access[reg]) free_register(reg);
227 while (free_since[reg] <= dst)
229 free_since[reg]->reg_cache_infos.needed_registers[reg] = NULL;
234 last_access[reg] = dst;
235 reg_content[reg] = addr;
241 if (addr == r0 || addr == r0+1)
242 xor_reg32_reg32(reg, reg);
244 mov_reg32_m32(reg, addr);
250 // this function is similar to allocate_register except it loads
251 // a 64 bits value, and return the register number of the LSB part
252 int allocate_64_register1(unsigned int *addr)
256 // is it already cached as a 32 bits value ?
259 if (last_access[i] != NULL && reg_content[i] == addr)
263 allocate_register(addr);
264 reg2 = allocate_register(dirty[i] ? NULL : addr+1);
270 reg_content[reg2] = addr+1;
272 mov_reg32_reg32(reg2, i);
273 sar_reg32_imm8(reg2, 31);
281 reg1 = allocate_register(addr);
282 reg2 = allocate_register(addr+1);
289 // this function is similar to allocate_register except it loads
290 // a 64 bits value, and return the register number of the MSB part
291 int allocate_64_register2(unsigned int *addr)
295 // is it already cached as a 32 bits value ?
298 if (last_access[i] != NULL && reg_content[i] == addr)
302 allocate_register(addr);
303 reg2 = allocate_register(dirty[i] ? NULL : addr+1);
309 reg_content[reg2] = addr+1;
311 mov_reg32_reg32(reg2, i);
312 sar_reg32_imm8(reg2, 31);
320 reg1 = allocate_register(addr);
321 reg2 = allocate_register(addr+1);
328 // this function checks if the data located at addr are cached in a register
329 // and then, it returns 1 if it's a 64 bit value
330 // 0 if it's a 32 bit value
331 // -1 if it's not cached
332 int is64(unsigned int *addr)
337 if (last_access[i] != NULL && reg_content[i] == addr)
339 if (r64[i] == -1) return 0;
346 int allocate_register_w(unsigned int *addr)
348 unsigned int oldest_access = 0xFFFFFFFF;
351 // is it already cached ?
354 if (last_access[i] != NULL && reg_content[i] == addr)
356 precomp_instr *last = last_access[i]+1;
360 last->reg_cache_infos.needed_registers[i] = NULL;
363 last_access[i] = dst;
367 last = last_access[r64[i]]+1;
370 last->reg_cache_infos.needed_registers[r64[i]] = NULL;
373 free_since[r64[i]] = dst+1;
374 last_access[r64[i]] = NULL;
382 // if it's not cached, we take the least recently used register
385 if (i != ESP && (unsigned int)last_access[i] < oldest_access)
387 oldest_access = (int)last_access[i];
392 if (last_access[reg]) free_register(reg);
395 while (free_since[reg] <= dst)
397 free_since[reg]->reg_cache_infos.needed_registers[reg] = NULL;
402 last_access[reg] = dst;
403 reg_content[reg] = addr;
410 int allocate_64_register1_w(unsigned int *addr)
414 // is it already cached as a 32 bits value ?
417 if (last_access[i] != NULL && reg_content[i] == addr)
421 allocate_register_w(addr);
422 reg2 = lru_register();
423 if (last_access[reg2]) free_register(reg2);
426 while (free_since[reg2] <= dst)
428 free_since[reg2]->reg_cache_infos.needed_registers[reg2] = NULL;
434 last_access[reg2] = dst;
436 reg_content[reg2] = addr+1;
438 mov_reg32_reg32(reg2, i);
439 sar_reg32_imm8(reg2, 31);
445 last_access[i] = dst;
446 last_access[r64[i]] = dst;
447 dirty[i] = dirty[r64[i]] = 1;
453 reg1 = allocate_register_w(addr);
454 reg2 = lru_register();
455 if (last_access[reg2]) free_register(reg2);
458 while (free_since[reg2] <= dst)
460 free_since[reg2]->reg_cache_infos.needed_registers[reg2] = NULL;
466 last_access[reg2] = dst;
467 reg_content[reg2] = addr+1;
473 int allocate_64_register2_w(unsigned int *addr)
477 // is it already cached as a 32 bits value ?
480 if (last_access[i] != NULL && reg_content[i] == addr)
484 allocate_register_w(addr);
485 reg2 = lru_register();
486 if (last_access[reg2]) free_register(reg2);
489 while (free_since[reg2] <= dst)
491 free_since[reg2]->reg_cache_infos.needed_registers[reg2] = NULL;
497 last_access[reg2] = dst;
499 reg_content[reg2] = addr+1;
501 mov_reg32_reg32(reg2, i);
502 sar_reg32_imm8(reg2, 31);
508 last_access[i] = dst;
509 last_access[r64[i]] = dst;
510 dirty[i] = dirty[r64[i]] = 1;
516 reg1 = allocate_register_w(addr);
517 reg2 = lru_register();
518 if (last_access[reg2]) free_register(reg2);
521 while (free_since[reg2] <= dst)
523 free_since[reg2]->reg_cache_infos.needed_registers[reg2] = NULL;
529 last_access[reg2] = dst;
530 reg_content[reg2] = addr+1;
536 void set_register_state(int reg, unsigned int *addr, int d)
538 last_access[reg] = dst;
539 reg_content[reg] = addr;
544 void set_64_register_state(int reg1, int reg2, unsigned int *addr, int d)
546 last_access[reg1] = dst;
547 last_access[reg2] = dst;
548 reg_content[reg1] = addr;
549 reg_content[reg2] = addr+1;
556 void force_32(int reg)
560 precomp_instr *last = last_access[reg]+1;
565 last->reg_cache_infos.needed_registers[reg] = reg_content[reg];
567 last->reg_cache_infos.needed_registers[reg] = NULL;
570 last->reg_cache_infos.needed_registers[r64[reg]] = reg_content[r64[reg]];
572 last->reg_cache_infos.needed_registers[r64[reg]] = NULL;
579 mov_m32_reg32(reg_content[reg], reg);
580 mov_m32_reg32(reg_content[r64[reg]], r64[reg]);
583 last_access[r64[reg]] = NULL;
584 free_since[r64[reg]] = dst+1;
589 void allocate_register_manually(int reg, unsigned int *addr)
593 if (last_access[reg] != NULL && reg_content[reg] == addr)
595 precomp_instr *last = last_access[reg]+1;
599 last->reg_cache_infos.needed_registers[reg] = reg_content[reg];
602 last_access[reg] = dst;
605 last = last_access[r64[reg]]+1;
609 last->reg_cache_infos.needed_registers[r64[reg]] = reg_content[r64[reg]];
612 last_access[r64[reg]] = dst;
617 if (last_access[reg]) free_register(reg);
620 while (free_since[reg] <= dst)
622 free_since[reg]->reg_cache_infos.needed_registers[reg] = NULL;
627 // is it already cached ?
630 if (last_access[i] != NULL && reg_content[i] == addr)
632 precomp_instr *last = last_access[i]+1;
636 last->reg_cache_infos.needed_registers[i] = reg_content[i];
639 last_access[i] = dst;
642 last = last_access[r64[i]]+1;
646 last->reg_cache_infos.needed_registers[r64[i]] = reg_content[r64[i]];
649 last_access[r64[i]] = dst;
652 mov_reg32_reg32(reg, i);
653 last_access[reg] = dst;
655 if (r64[reg] != -1) r64[r64[reg]] = reg;
656 dirty[reg] = dirty[i];
657 reg_content[reg] = reg_content[i];
658 free_since[i] = dst+1;
659 last_access[i] = NULL;
665 last_access[reg] = dst;
666 reg_content[reg] = addr;
672 if (addr == r0 || addr == r0+1)
673 xor_reg32_reg32(reg, reg);
675 mov_reg32_m32(reg, addr);
679 void allocate_register_manually_w(int reg, unsigned int *addr, int load)
683 if (last_access[reg] != NULL && reg_content[reg] == addr)
685 precomp_instr *last = last_access[reg]+1;
689 last->reg_cache_infos.needed_registers[reg] = reg_content[reg];
692 last_access[reg] = dst;
696 last = last_access[r64[reg]]+1;
700 last->reg_cache_infos.needed_registers[r64[reg]] = reg_content[r64[reg]];
703 last_access[r64[reg]] = NULL;
704 free_since[r64[reg]] = dst+1;
711 if (last_access[reg]) free_register(reg);
714 while (free_since[reg] <= dst)
716 free_since[reg]->reg_cache_infos.needed_registers[reg] = NULL;
721 // is it already cached ?
724 if (last_access[i] != NULL && reg_content[i] == addr)
726 precomp_instr *last = last_access[i]+1;
730 last->reg_cache_infos.needed_registers[i] = reg_content[i];
733 last_access[i] = dst;
736 last = last_access[r64[i]]+1;
739 last->reg_cache_infos.needed_registers[r64[i]] = NULL;
742 free_since[r64[i]] = dst+1;
743 last_access[r64[i]] = NULL;
748 mov_reg32_reg32(reg, i);
749 last_access[reg] = dst;
752 reg_content[reg] = reg_content[i];
753 free_since[i] = dst+1;
754 last_access[i] = NULL;
760 last_access[reg] = dst;
761 reg_content[reg] = addr;
765 if (addr != NULL && load)
767 if (addr == r0 || addr == r0+1)
768 xor_reg32_reg32(reg, reg);
770 mov_reg32_m32(reg, addr);
774 // 0x81 0xEC 0x4 0x0 0x0 0x0 sub esp, 4
775 // 0xA1 0xXXXXXXXX mov eax, XXXXXXXX (&code start)
776 // 0x05 0xXXXXXXXX add eax, XXXXXXXX (local_addr)
777 // 0x89 0x04 0x24 mov [esp], eax
778 // 0x8B (reg<<3)|5 0xXXXXXXXX mov eax, [XXXXXXXX]
779 // 0x8B (reg<<3)|5 0xXXXXXXXX mov ebx, [XXXXXXXX]
780 // 0x8B (reg<<3)|5 0xXXXXXXXX mov ecx, [XXXXXXXX]
781 // 0x8B (reg<<3)|5 0xXXXXXXXX mov edx, [XXXXXXXX]
782 // 0x8B (reg<<3)|5 0xXXXXXXXX mov ebp, [XXXXXXXX]
783 // 0x8B (reg<<3)|5 0xXXXXXXXX mov esi, [XXXXXXXX]
784 // 0x8B (reg<<3)|5 0xXXXXXXXX mov edi, [XXXXXXXX]
787 static void build_wrapper(precomp_instr *instr, unsigned char* code, precomp_block* block)
792 #if defined(PROFILE_R4300)
793 long x86addr = (long) code;
795 fwrite(&mipsop, 1, 4, pfProfile); // write 4-byte MIPS opcode
796 fwrite(&x86addr, 1, sizeof(char *), pfProfile); // write pointer to dynamically generated x86 code for this MIPS instruction
807 *((unsigned int*)&code[j]) = (unsigned int)(&block->code);
811 *((unsigned int*)&code[j]) = (unsigned int)instr->local_addr;
820 if (instr->reg_cache_infos.needed_registers[i] != NULL)
823 code[j++] = (i << 3) | 5;
824 *((unsigned int*)&code[j]) =
825 (unsigned int)instr->reg_cache_infos.needed_registers[i];
833 void build_wrappers(precomp_instr *instr, int start, int end, precomp_block* block)
836 for (i=start; i<end; i++)
838 instr[i].reg_cache_infos.need_map = 0;
839 for (reg=0; reg<8; reg++)
841 if (instr[i].reg_cache_infos.needed_registers[reg] != NULL)
843 instr[i].reg_cache_infos.need_map = 1;
844 build_wrapper(&instr[i], instr[i].reg_cache_infos.jump_wrapper, block);
851 void simplify_access(void)
854 dst->local_addr = code_length;
855 for(i=0; i<8; i++) dst->reg_cache_infos.needed_registers[i] = NULL;