aboutsummaryrefslogtreecommitdiff
path: root/src/fake86/modregrm.h
blob: 026e0307107738d3e41eeaa68bc45b9940041586 (plain) (blame)
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