This source file includes following definitions.
- sib
- get_address
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include <linux/stddef.h>
22
23 #include <asm/segment.h>
24
25 #include "fpu_system.h"
26 #include "exception.h"
27 #include "fpu_emu.h"
28
29 static int reg_offset[] = {
30 offsetof(struct info,___eax),
31 offsetof(struct info,___ecx),
32 offsetof(struct info,___edx),
33 offsetof(struct info,___ebx),
34 offsetof(struct info,___esp),
35 offsetof(struct info,___ebp),
36 offsetof(struct info,___esi),
37 offsetof(struct info,___edi)
38 };
39
40 #define REG_(x) (*(long *)(reg_offset[(x)]+(char *) FPU_info))
41
42
43
44 static void *sib(int mod)
45 {
46 unsigned char ss,index,base;
47 long offset;
48
49 RE_ENTRANT_CHECK_OFF;
50 FPU_code_verify_area(1);
51 base = get_fs_byte((char *) FPU_EIP);
52 RE_ENTRANT_CHECK_ON;
53 FPU_EIP++;
54 ss = base >> 6;
55 index = (base >> 3) & 7;
56 base &= 7;
57
58 if ((mod == 0) && (base == 5))
59 offset = 0;
60 else
61 offset = REG_(base);
62
63 if (index == 4)
64 {
65
66
67 if ( ss )
68 EXCEPTION(EX_Invalid);
69 }
70 else
71 {
72 offset += (REG_(index)) << ss;
73 }
74
75 if (mod == 1)
76 {
77
78 RE_ENTRANT_CHECK_OFF;
79 FPU_code_verify_area(1);
80 offset += (signed char) get_fs_byte((char *) FPU_EIP);
81 RE_ENTRANT_CHECK_ON;
82 FPU_EIP++;
83 }
84 else if (mod == 2 || base == 5)
85 {
86
87 RE_ENTRANT_CHECK_OFF;
88 FPU_code_verify_area(4);
89 offset += (signed) get_fs_long((unsigned long *) FPU_EIP);
90 RE_ENTRANT_CHECK_ON;
91 FPU_EIP += 4;
92 }
93
94 return (void *) offset;
95 }
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115 void get_address(unsigned char FPU_modrm, overrides override)
116 {
117 unsigned char mod;
118 long *cpu_reg_ptr;
119 int offset = 0;
120
121 #ifndef PECULIAR_486
122
123 FPU_data_selector = FPU_DS;
124 #endif PECULIAR_486
125
126 mod = (FPU_modrm >> 6) & 3;
127
128 if (FPU_rm == 4 && mod != 3)
129 {
130 FPU_data_address = sib(mod);
131 return;
132 }
133
134 cpu_reg_ptr = & REG_(FPU_rm);
135 switch (mod)
136 {
137 case 0:
138 if (FPU_rm == 5)
139 {
140
141 RE_ENTRANT_CHECK_OFF;
142 if ( override.address_size == ADDR_SIZE_PREFIX )
143 {
144 FPU_code_verify_area(2);
145 offset = get_fs_word((unsigned short *) FPU_EIP);
146 FPU_EIP += 2;
147 }
148 else
149 {
150 FPU_code_verify_area(4);
151 offset = get_fs_long((unsigned long *) FPU_EIP);
152 FPU_EIP += 4;
153 }
154 RE_ENTRANT_CHECK_ON;
155 FPU_data_address = (void *) offset;
156 return;
157 }
158 else
159 {
160 FPU_data_address = (void *)*cpu_reg_ptr;
161
162 return;
163 }
164 case 1:
165
166 RE_ENTRANT_CHECK_OFF;
167 FPU_code_verify_area(1);
168 offset = (signed char) get_fs_byte((char *) FPU_EIP);
169 RE_ENTRANT_CHECK_ON;
170 FPU_EIP++;
171 break;
172 case 2:
173
174 RE_ENTRANT_CHECK_OFF;
175 if ( override.address_size == ADDR_SIZE_PREFIX )
176 {
177 FPU_code_verify_area(2);
178 offset = (signed) get_fs_word((unsigned short *) FPU_EIP);
179 FPU_EIP += 2;
180 }
181 else
182 {
183 FPU_code_verify_area(4);
184 offset = (signed) get_fs_long((unsigned long *) FPU_EIP);
185 FPU_EIP += 4;
186 }
187 RE_ENTRANT_CHECK_ON;
188 break;
189 case 3:
190
191 EXCEPTION(EX_Invalid);
192 }
193
194 FPU_data_address = offset + (char *)*cpu_reg_ptr;
195 if ( override.address_size == ADDR_SIZE_PREFIX )
196 FPU_data_address = (void *)((long)FPU_data_address & 0xffff);
197 }