1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
#include "config.h"
#ifdef CPU_ADDR_MODE_CACHE
struct addrmodecache_s addrcache[0x100000];
uint8_t addrcachevalid[0x100000];
uint32_t addrdatalen, dataisvalid, setvalidptr;
uint64_t cached_access_count = 0, uncached_access_count = 0;
#define modregrm() { \
tempaddr32 = (((uint32_t)savecs << 4) + ip) & 0xFFFFF; \
if (addrcachevalid[tempaddr32]) { \
switch (addrcache[tempaddr32].len) { \
case 0: \
dataisvalid = 1; \
break; \
case 1: \
if (addrcachevalid[tempaddr32+1]) dataisvalid = 1; else dataisvalid = 0; \
break; \
case 2: \
if (addrcachevalid[tempaddr32+1] && addrcachevalid[tempaddr32+2]) dataisvalid = 1; else dataisvalid = 0; \
break; \
} \
} else dataisvalid = 0; \
if (dataisvalid) { \
cached_access_count++; \
disp16 = addrcache[tempaddr32].disp16; \
segregs[regcs] = addrcache[tempaddr32].exitcs; \
ip = addrcache[tempaddr32].exitip; \
mode = addrcache[tempaddr32].mode; \
reg = addrcache[tempaddr32].reg; \
rm = addrcache[tempaddr32].rm; \
if ((!segoverride) && addrcache[tempaddr32].forcess) useseg = segregs[regss]; \
} else { \
uncached_access_count++; \
addrbyte = getmem8(segregs[regcs], ip); \
StepIP(1); \
mode = addrbyte >> 6; \
reg = (addrbyte >> 3) & 7; \
rm = addrbyte & 7; \
addrdatalen = 0; \
addrcache[tempaddr32].forcess = 0; \
switch(mode) \
{ \
case 0: \
if(rm == 6) { \
disp16 = getmem16(segregs[regcs], ip); \
addrdatalen = 2; \
StepIP(2); \
} \
if (((rm == 2) || (rm == 3))) { \
if (!segoverride) useseg = segregs[regss]; \
addrcache[tempaddr32].forcess = 1; \
} \
break; \
\
case 1: \
disp16 = signext(getmem8(segregs[regcs], ip)); \
addrdatalen = 1; \
StepIP(1); \
if (((rm == 2) || (rm == 3) || (rm == 6))) { \
if (!segoverride) useseg = segregs[regss]; \
addrcache[tempaddr32].forcess = 1; \
} \
break; \
\
case 2: \
disp16 = getmem16(segregs[regcs], ip); \
addrdatalen = 2; \
StepIP(2); \
if (((rm == 2) || (rm == 3) || (rm == 6))) { \
if (!segoverride) useseg = segregs[regss]; \
addrcache[tempaddr32].forcess = 1; \
} \
break; \
\
default: \
disp16 = 0; \
} \
addrcache[tempaddr32].disp16 = disp16; \
addrcache[tempaddr32].exitcs = segregs[regcs]; \
addrcache[tempaddr32].exitip = ip; \
addrcache[tempaddr32].mode = mode; \
addrcache[tempaddr32].reg = reg; \
addrcache[tempaddr32].rm = rm; \
addrcache[tempaddr32].len = addrdatalen; \
memset(&addrcachevalid[tempaddr32], 1, addrdatalen+1); \
} \
}
#else
#define modregrm() { \
addrbyte = getmem8(segregs[regcs], ip); \
StepIP(1); \
mode = addrbyte >> 6; \
reg = (addrbyte >> 3) & 7; \
rm = addrbyte & 7; \
switch(mode) \
{ \
case 0: \
if(rm == 6) { \
disp16 = getmem16(segregs[regcs], ip); \
StepIP(2); \
} \
if(((rm == 2) || (rm == 3)) && !segoverride) { \
useseg = segregs[regss]; \
} \
break; \
\
case 1: \
disp16 = signext(getmem8(segregs[regcs], ip)); \
StepIP(1); \
if(((rm == 2) || (rm == 3) || (rm == 6)) && !segoverride) { \
useseg = segregs[regss]; \
} \
break; \
\
case 2: \
disp16 = getmem16(segregs[regcs], ip); \
StepIP(2); \
if(((rm == 2) || (rm == 3) || (rm == 6)) && !segoverride) { \
useseg = segregs[regss]; \
} \
break; \
\
default: \
disp8 = 0; \
disp16 = 0; \
} \
}
#endif
|