Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libmupen64plus/mupen64plus-core/src/r4300/x86/regcache.c
2 views
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
30
static unsigned int* reg_content[8];
31
static precomp_instr* last_access[8];
32
static precomp_instr* free_since[8];
33
static int dirty[8];
34
static int r64[8];
35
static unsigned int* r0;
36
37
void 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
48
void 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
87
void 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
143
int 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
158
int 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
177
int 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
252
int 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
291
int 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
332
int 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
346
int 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
410
int 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
473
int 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
536
void 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
544
void 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
556
void 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
589
void 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
679
void 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
787
static 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
833
void 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
851
void 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
858
859