Core commit. Compile and run on the OpenPandora
[mupen64plus-pandora.git] / source / mupen64plus-core / src / r4300 / x86 / regcache.c
CommitLineData
451ab91e 1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Mupen64plus - regcache.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 "regcache.h"
25
26#include "r4300/recomp.h"
27#include "r4300/r4300.h"
28#include "r4300/recomph.h"
29
30static unsigned int* reg_content[8];
31static precomp_instr* last_access[8];
32static precomp_instr* free_since[8];
33static int dirty[8];
34static int r64[8];
35static unsigned int* r0;
36
37void init_cache(precomp_instr* start)
38{
39 int i;
40 for (i=0; i<8; i++)
41 {
42 last_access[i] = NULL;
43 free_since[i] = start;
44 }
45 r0 = (unsigned int*)reg;
46}
47
48void free_all_registers(void)
49{
50#if defined(PROFILE_R4300)
51 int freestart = code_length;
52 int flushed = 0;
53#endif
54
55 int i;
56 for (i=0; i<8; i++)
57 {
58#if defined(PROFILE_R4300)
59 if (last_access[i] && dirty[i]) flushed = 1;
60#endif
61 if (last_access[i]) free_register(i);
62 else
63 {
64 while (free_since[i] <= dst)
65 {
66 free_since[i]->reg_cache_infos.needed_registers[i] = NULL;
67 free_since[i]++;
68 }
69 }
70 }
71
72#if defined(PROFILE_R4300)
73 if (flushed == 1)
74 {
75 long x86addr = (long) ((*inst_pointer) + freestart);
76 int mipsop = -5;
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
82 }
83#endif
84}
85
86// this function frees a specific X86 GPR
87void free_register(int reg)
88{
89 precomp_instr *last;
90
91 if (last_access[reg] != NULL &&
92 r64[reg] != -1 && (int)reg_content[reg] != (int)reg_content[r64[reg]]-4)
93 {
94 free_register(r64[reg]);
95 return;
96 }
97
98 if (last_access[reg] != NULL) last = last_access[reg]+1;
99 else last = free_since[reg];
100
101 while (last <= dst)
102 {
103 if (last_access[reg] != NULL && dirty[reg])
104 last->reg_cache_infos.needed_registers[reg] = reg_content[reg];
105 else
106 last->reg_cache_infos.needed_registers[reg] = NULL;
107
108 if (last_access[reg] != NULL && r64[reg] != -1)
109 {
110 if (dirty[r64[reg]])
111 last->reg_cache_infos.needed_registers[r64[reg]] = reg_content[r64[reg]];
112 else
113 last->reg_cache_infos.needed_registers[r64[reg]] = NULL;
114 }
115
116 last++;
117 }
118 if (last_access[reg] == NULL)
119 {
120 free_since[reg] = dst+1;
121 return;
122 }
123
124 if (dirty[reg])
125 {
126 mov_m32_reg32(reg_content[reg], reg);
127 if (r64[reg] == -1)
128 {
129 sar_reg32_imm8(reg, 31);
130 mov_m32_reg32((unsigned int*)reg_content[reg]+1, reg);
131 }
132 else mov_m32_reg32(reg_content[r64[reg]], r64[reg]);
133 }
134 last_access[reg] = NULL;
135 free_since[reg] = dst+1;
136 if (r64[reg] != -1)
137 {
138 last_access[r64[reg]] = NULL;
139 free_since[r64[reg]] = dst+1;
140 }
141}
142
143int lru_register(void)
144{
145 unsigned int oldest_access = 0xFFFFFFFF;
146 int i, reg = 0;
147 for (i=0; i<8; i++)
148 {
149 if (i != ESP && (unsigned int)last_access[i] < oldest_access)
150 {
151 oldest_access = (int)last_access[i];
152 reg = i;
153 }
154 }
155 return reg;
156}
157
158int lru_register_exc1(int exc1)
159{
160 unsigned int oldest_access = 0xFFFFFFFF;
161 int i, reg = 0;
162 for (i=0; i<8; i++)
163 {
164 if (i != ESP && i != exc1 && (unsigned int)last_access[i] < oldest_access)
165 {
166 oldest_access = (int)last_access[i];
167 reg = i;
168 }
169 }
170 return reg;
171}
172
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
177int allocate_register(unsigned int *addr)
178{
179 unsigned int oldest_access = 0xFFFFFFFF;
180 int reg = 0, i;
181
182 // is it already cached ?
183 if (addr != NULL)
184 {
185 for (i=0; i<8; i++)
186 {
187 if (last_access[i] != NULL && reg_content[i] == addr)
188 {
189 precomp_instr *last = last_access[i]+1;
190
191 while (last <= dst)
192 {
193 last->reg_cache_infos.needed_registers[i] = reg_content[i];
194 last++;
195 }
196 last_access[i] = dst;
197 if (r64[i] != -1)
198 {
199 last = last_access[r64[i]]+1;
200
201 while (last <= dst)
202 {
203 last->reg_cache_infos.needed_registers[r64[i]] = reg_content[r64[i]];
204 last++;
205 }
206 last_access[r64[i]] = dst;
207 }
208
209 return i;
210 }
211 }
212 }
213
214 // if it's not cached, we take the least recently used register
215 for (i=0; i<8; i++)
216 {
217 if (i != ESP && (unsigned int)last_access[i] < oldest_access)
218 {
219 oldest_access = (int)last_access[i];
220 reg = i;
221 }
222 }
223
224 if (last_access[reg]) free_register(reg);
225 else
226 {
227 while (free_since[reg] <= dst)
228 {
229 free_since[reg]->reg_cache_infos.needed_registers[reg] = NULL;
230 free_since[reg]++;
231 }
232 }
233
234 last_access[reg] = dst;
235 reg_content[reg] = addr;
236 dirty[reg] = 0;
237 r64[reg] = -1;
238
239 if (addr != NULL)
240 {
241 if (addr == r0 || addr == r0+1)
242 xor_reg32_reg32(reg, reg);
243 else
244 mov_reg32_m32(reg, addr);
245 }
246
247 return reg;
248}
249
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
252int allocate_64_register1(unsigned int *addr)
253{
254 int reg1, reg2, i;
255
256 // is it already cached as a 32 bits value ?
257 for (i=0; i<8; i++)
258 {
259 if (last_access[i] != NULL && reg_content[i] == addr)
260 {
261 if (r64[i] == -1)
262 {
263 allocate_register(addr);
264 reg2 = allocate_register(dirty[i] ? NULL : addr+1);
265 r64[i] = reg2;
266 r64[reg2] = i;
267
268 if (dirty[i])
269 {
270 reg_content[reg2] = addr+1;
271 dirty[reg2] = 1;
272 mov_reg32_reg32(reg2, i);
273 sar_reg32_imm8(reg2, 31);
274 }
275
276 return i;
277 }
278 }
279 }
280
281 reg1 = allocate_register(addr);
282 reg2 = allocate_register(addr+1);
283 r64[reg1] = reg2;
284 r64[reg2] = reg1;
285
286 return reg1;
287}
288
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
291int allocate_64_register2(unsigned int *addr)
292{
293 int reg1, reg2, i;
294
295 // is it already cached as a 32 bits value ?
296 for (i=0; i<8; i++)
297 {
298 if (last_access[i] != NULL && reg_content[i] == addr)
299 {
300 if (r64[i] == -1)
301 {
302 allocate_register(addr);
303 reg2 = allocate_register(dirty[i] ? NULL : addr+1);
304 r64[i] = reg2;
305 r64[reg2] = i;
306
307 if (dirty[i])
308 {
309 reg_content[reg2] = addr+1;
310 dirty[reg2] = 1;
311 mov_reg32_reg32(reg2, i);
312 sar_reg32_imm8(reg2, 31);
313 }
314
315 return reg2;
316 }
317 }
318 }
319
320 reg1 = allocate_register(addr);
321 reg2 = allocate_register(addr+1);
322 r64[reg1] = reg2;
323 r64[reg2] = reg1;
324
325 return reg2;
326}
327
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
332int is64(unsigned int *addr)
333{
334 int i;
335 for (i=0; i<8; i++)
336 {
337 if (last_access[i] != NULL && reg_content[i] == addr)
338 {
339 if (r64[i] == -1) return 0;
340 return 1;
341 }
342 }
343 return -1;
344}
345
346int allocate_register_w(unsigned int *addr)
347{
348 unsigned int oldest_access = 0xFFFFFFFF;
349 int reg = 0, i;
350
351 // is it already cached ?
352 for (i=0; i<8; i++)
353 {
354 if (last_access[i] != NULL && reg_content[i] == addr)
355 {
356 precomp_instr *last = last_access[i]+1;
357
358 while (last <= dst)
359 {
360 last->reg_cache_infos.needed_registers[i] = NULL;
361 last++;
362 }
363 last_access[i] = dst;
364 dirty[i] = 1;
365 if (r64[i] != -1)
366 {
367 last = last_access[r64[i]]+1;
368 while (last <= dst)
369 {
370 last->reg_cache_infos.needed_registers[r64[i]] = NULL;
371 last++;
372 }
373 free_since[r64[i]] = dst+1;
374 last_access[r64[i]] = NULL;
375 r64[i] = -1;
376 }
377
378 return i;
379 }
380 }
381
382 // if it's not cached, we take the least recently used register
383 for (i=0; i<8; i++)
384 {
385 if (i != ESP && (unsigned int)last_access[i] < oldest_access)
386 {
387 oldest_access = (int)last_access[i];
388 reg = i;
389 }
390 }
391
392 if (last_access[reg]) free_register(reg);
393 else
394 {
395 while (free_since[reg] <= dst)
396 {
397 free_since[reg]->reg_cache_infos.needed_registers[reg] = NULL;
398 free_since[reg]++;
399 }
400 }
401
402 last_access[reg] = dst;
403 reg_content[reg] = addr;
404 dirty[reg] = 1;
405 r64[reg] = -1;
406
407 return reg;
408}
409
410int allocate_64_register1_w(unsigned int *addr)
411{
412 int reg1, reg2, i;
413
414 // is it already cached as a 32 bits value ?
415 for (i=0; i<8; i++)
416 {
417 if (last_access[i] != NULL && reg_content[i] == addr)
418 {
419 if (r64[i] == -1)
420 {
421 allocate_register_w(addr);
422 reg2 = lru_register();
423 if (last_access[reg2]) free_register(reg2);
424 else
425 {
426 while (free_since[reg2] <= dst)
427 {
428 free_since[reg2]->reg_cache_infos.needed_registers[reg2] = NULL;
429 free_since[reg2]++;
430 }
431 }
432 r64[i] = reg2;
433 r64[reg2] = i;
434 last_access[reg2] = dst;
435
436 reg_content[reg2] = addr+1;
437 dirty[reg2] = 1;
438 mov_reg32_reg32(reg2, i);
439 sar_reg32_imm8(reg2, 31);
440
441 return i;
442 }
443 else
444 {
445 last_access[i] = dst;
446 last_access[r64[i]] = dst;
447 dirty[i] = dirty[r64[i]] = 1;
448 return i;
449 }
450 }
451 }
452
453 reg1 = allocate_register_w(addr);
454 reg2 = lru_register();
455 if (last_access[reg2]) free_register(reg2);
456 else
457 {
458 while (free_since[reg2] <= dst)
459 {
460 free_since[reg2]->reg_cache_infos.needed_registers[reg2] = NULL;
461 free_since[reg2]++;
462 }
463 }
464 r64[reg1] = reg2;
465 r64[reg2] = reg1;
466 last_access[reg2] = dst;
467 reg_content[reg2] = addr+1;
468 dirty[reg2] = 1;
469
470 return reg1;
471}
472
473int allocate_64_register2_w(unsigned int *addr)
474{
475 int reg1, reg2, i;
476
477 // is it already cached as a 32 bits value ?
478 for (i=0; i<8; i++)
479 {
480 if (last_access[i] != NULL && reg_content[i] == addr)
481 {
482 if (r64[i] == -1)
483 {
484 allocate_register_w(addr);
485 reg2 = lru_register();
486 if (last_access[reg2]) free_register(reg2);
487 else
488 {
489 while (free_since[reg2] <= dst)
490 {
491 free_since[reg2]->reg_cache_infos.needed_registers[reg2] = NULL;
492 free_since[reg2]++;
493 }
494 }
495 r64[i] = reg2;
496 r64[reg2] = i;
497 last_access[reg2] = dst;
498
499 reg_content[reg2] = addr+1;
500 dirty[reg2] = 1;
501 mov_reg32_reg32(reg2, i);
502 sar_reg32_imm8(reg2, 31);
503
504 return reg2;
505 }
506 else
507 {
508 last_access[i] = dst;
509 last_access[r64[i]] = dst;
510 dirty[i] = dirty[r64[i]] = 1;
511 return r64[i];
512 }
513 }
514 }
515
516 reg1 = allocate_register_w(addr);
517 reg2 = lru_register();
518 if (last_access[reg2]) free_register(reg2);
519 else
520 {
521 while (free_since[reg2] <= dst)
522 {
523 free_since[reg2]->reg_cache_infos.needed_registers[reg2] = NULL;
524 free_since[reg2]++;
525 }
526 }
527 r64[reg1] = reg2;
528 r64[reg2] = reg1;
529 last_access[reg2] = dst;
530 reg_content[reg2] = addr+1;
531 dirty[reg2] = 1;
532
533 return reg2;
534}
535
536void set_register_state(int reg, unsigned int *addr, int d)
537{
538 last_access[reg] = dst;
539 reg_content[reg] = addr;
540 r64[reg] = -1;
541 dirty[reg] = d;
542}
543
544void set_64_register_state(int reg1, int reg2, unsigned int *addr, int d)
545{
546 last_access[reg1] = dst;
547 last_access[reg2] = dst;
548 reg_content[reg1] = addr;
549 reg_content[reg2] = addr+1;
550 r64[reg1] = reg2;
551 r64[reg2] = reg1;
552 dirty[reg1] = d;
553 dirty[reg2] = d;
554}
555
556void force_32(int reg)
557{
558 if (r64[reg] != -1)
559 {
560 precomp_instr *last = last_access[reg]+1;
561
562 while (last <= dst)
563 {
564 if (dirty[reg])
565 last->reg_cache_infos.needed_registers[reg] = reg_content[reg];
566 else
567 last->reg_cache_infos.needed_registers[reg] = NULL;
568
569 if (dirty[r64[reg]])
570 last->reg_cache_infos.needed_registers[r64[reg]] = reg_content[r64[reg]];
571 else
572 last->reg_cache_infos.needed_registers[r64[reg]] = NULL;
573
574 last++;
575 }
576
577 if (dirty[reg])
578 {
579 mov_m32_reg32(reg_content[reg], reg);
580 mov_m32_reg32(reg_content[r64[reg]], r64[reg]);
581 dirty[reg] = 0;
582 }
583 last_access[r64[reg]] = NULL;
584 free_since[r64[reg]] = dst+1;
585 r64[reg] = -1;
586 }
587}
588
589void allocate_register_manually(int reg, unsigned int *addr)
590{
591 int i;
592
593 if (last_access[reg] != NULL && reg_content[reg] == addr)
594 {
595 precomp_instr *last = last_access[reg]+1;
596
597 while (last <= dst)
598 {
599 last->reg_cache_infos.needed_registers[reg] = reg_content[reg];
600 last++;
601 }
602 last_access[reg] = dst;
603 if (r64[reg] != -1)
604 {
605 last = last_access[r64[reg]]+1;
606
607 while (last <= dst)
608 {
609 last->reg_cache_infos.needed_registers[r64[reg]] = reg_content[r64[reg]];
610 last++;
611 }
612 last_access[r64[reg]] = dst;
613 }
614 return;
615 }
616
617 if (last_access[reg]) free_register(reg);
618 else
619 {
620 while (free_since[reg] <= dst)
621 {
622 free_since[reg]->reg_cache_infos.needed_registers[reg] = NULL;
623 free_since[reg]++;
624 }
625 }
626
627 // is it already cached ?
628 for (i=0; i<8; i++)
629 {
630 if (last_access[i] != NULL && reg_content[i] == addr)
631 {
632 precomp_instr *last = last_access[i]+1;
633
634 while (last <= dst)
635 {
636 last->reg_cache_infos.needed_registers[i] = reg_content[i];
637 last++;
638 }
639 last_access[i] = dst;
640 if (r64[i] != -1)
641 {
642 last = last_access[r64[i]]+1;
643
644 while (last <= dst)
645 {
646 last->reg_cache_infos.needed_registers[r64[i]] = reg_content[r64[i]];
647 last++;
648 }
649 last_access[r64[i]] = dst;
650 }
651
652 mov_reg32_reg32(reg, i);
653 last_access[reg] = dst;
654 r64[reg] = r64[i];
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;
660
661 return;
662 }
663 }
664
665 last_access[reg] = dst;
666 reg_content[reg] = addr;
667 dirty[reg] = 0;
668 r64[reg] = -1;
669
670 if (addr != NULL)
671 {
672 if (addr == r0 || addr == r0+1)
673 xor_reg32_reg32(reg, reg);
674 else
675 mov_reg32_m32(reg, addr);
676 }
677}
678
679void allocate_register_manually_w(int reg, unsigned int *addr, int load)
680{
681 int i;
682
683 if (last_access[reg] != NULL && reg_content[reg] == addr)
684 {
685 precomp_instr *last = last_access[reg]+1;
686
687 while (last <= dst)
688 {
689 last->reg_cache_infos.needed_registers[reg] = reg_content[reg];
690 last++;
691 }
692 last_access[reg] = dst;
693
694 if (r64[reg] != -1)
695 {
696 last = last_access[r64[reg]]+1;
697
698 while (last <= dst)
699 {
700 last->reg_cache_infos.needed_registers[r64[reg]] = reg_content[r64[reg]];
701 last++;
702 }
703 last_access[r64[reg]] = NULL;
704 free_since[r64[reg]] = dst+1;
705 r64[reg] = -1;
706 }
707 dirty[reg] = 1;
708 return;
709 }
710
711 if (last_access[reg]) free_register(reg);
712 else
713 {
714 while (free_since[reg] <= dst)
715 {
716 free_since[reg]->reg_cache_infos.needed_registers[reg] = NULL;
717 free_since[reg]++;
718 }
719 }
720
721 // is it already cached ?
722 for (i=0; i<8; i++)
723 {
724 if (last_access[i] != NULL && reg_content[i] == addr)
725 {
726 precomp_instr *last = last_access[i]+1;
727
728 while (last <= dst)
729 {
730 last->reg_cache_infos.needed_registers[i] = reg_content[i];
731 last++;
732 }
733 last_access[i] = dst;
734 if (r64[i] != -1)
735 {
736 last = last_access[r64[i]]+1;
737 while (last <= dst)
738 {
739 last->reg_cache_infos.needed_registers[r64[i]] = NULL;
740 last++;
741 }
742 free_since[r64[i]] = dst+1;
743 last_access[r64[i]] = NULL;
744 r64[i] = -1;
745 }
746
747 if (load)
748 mov_reg32_reg32(reg, i);
749 last_access[reg] = dst;
750 dirty[reg] = 1;
751 r64[reg] = -1;
752 reg_content[reg] = reg_content[i];
753 free_since[i] = dst+1;
754 last_access[i] = NULL;
755
756 return;
757 }
758 }
759
760 last_access[reg] = dst;
761 reg_content[reg] = addr;
762 dirty[reg] = 1;
763 r64[reg] = -1;
764
765 if (addr != NULL && load)
766 {
767 if (addr == r0 || addr == r0+1)
768 xor_reg32_reg32(reg, reg);
769 else
770 mov_reg32_m32(reg, addr);
771 }
772}
773
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]
785// 0xC3 ret
786// total : 62 bytes
787static void build_wrapper(precomp_instr *instr, unsigned char* code, precomp_block* block)
788{
789 int i;
790 int j=0;
791
792#if defined(PROFILE_R4300)
793 long x86addr = (long) code;
794 int mipsop = -4;
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
797#endif
798
799 code[j++] = 0x81;
800 code[j++] = 0xEC;
801 code[j++] = 0x04;
802 code[j++] = 0x00;
803 code[j++] = 0x00;
804 code[j++] = 0x00;
805
806 code[j++] = 0xA1;
807 *((unsigned int*)&code[j]) = (unsigned int)(&block->code);
808 j+=4;
809
810 code[j++] = 0x05;
811 *((unsigned int*)&code[j]) = (unsigned int)instr->local_addr;
812 j+=4;
813
814 code[j++] = 0x89;
815 code[j++] = 0x04;
816 code[j++] = 0x24;
817
818 for (i=0; i<8; i++)
819 {
820 if (instr->reg_cache_infos.needed_registers[i] != NULL)
821 {
822 code[j++] = 0x8B;
823 code[j++] = (i << 3) | 5;
824 *((unsigned int*)&code[j]) =
825 (unsigned int)instr->reg_cache_infos.needed_registers[i];
826 j+=4;
827 }
828 }
829
830 code[j++] = 0xC3;
831}
832
833void build_wrappers(precomp_instr *instr, int start, int end, precomp_block* block)
834{
835 int i, reg;;
836 for (i=start; i<end; i++)
837 {
838 instr[i].reg_cache_infos.need_map = 0;
839 for (reg=0; reg<8; reg++)
840 {
841 if (instr[i].reg_cache_infos.needed_registers[reg] != NULL)
842 {
843 instr[i].reg_cache_infos.need_map = 1;
844 build_wrapper(&instr[i], instr[i].reg_cache_infos.jump_wrapper, block);
845 break;
846 }
847 }
848 }
849}
850
851void simplify_access(void)
852{
853 int i;
854 dst->local_addr = code_length;
855 for(i=0; i<8; i++) dst->reg_cache_infos.needed_registers[i] = NULL;
856}
857