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 base = get_fs_byte((char *) FPU_EIP);
51 RE_ENTRANT_CHECK_ON
52 FPU_EIP++;
53 ss = base >> 6;
54 index = (base >> 3) & 7;
55 base &= 7;
56
57 if ((mod == 0) && (base == 5))
58 offset = 0;
59 else
60 offset = REG_(base);
61
62 if (index == 4)
63 {
64
65
66 if ( ss )
67 EXCEPTION(EX_Invalid);
68 }
69 else
70 {
71 offset += (REG_(index)) << ss;
72 }
73
74 if (mod == 1)
75 {
76
77 RE_ENTRANT_CHECK_OFF
78 offset += (signed char) get_fs_byte((char *) FPU_EIP);
79 RE_ENTRANT_CHECK_ON
80 FPU_EIP++;
81 }
82 else if (mod == 2 || base == 5)
83 {
84
85 RE_ENTRANT_CHECK_OFF
86 offset += (signed) get_fs_long((unsigned long *) FPU_EIP);
87 RE_ENTRANT_CHECK_ON
88 FPU_EIP += 4;
89 }
90
91 return (void *) offset;
92 }
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112 void get_address(unsigned char FPU_modrm)
113 {
114 unsigned char mod;
115 long *cpu_reg_ptr;
116 int offset = 0;
117
118 #ifndef PECULIAR_486
119
120 FPU_data_selector = FPU_DS;
121 #endif PECULIAR_486
122
123 mod = (FPU_modrm >> 6) & 3;
124
125 if (FPU_rm == 4 && mod != 3)
126 {
127 FPU_data_address = sib(mod);
128 return;
129 }
130
131 cpu_reg_ptr = & REG_(FPU_rm);
132 switch (mod)
133 {
134 case 0:
135 if (FPU_rm == 5)
136 {
137
138 RE_ENTRANT_CHECK_OFF
139 offset = get_fs_long((unsigned long *) FPU_EIP);
140 RE_ENTRANT_CHECK_ON
141 FPU_EIP += 4;
142 FPU_data_address = (void *) offset;
143 return;
144 }
145 else
146 {
147 FPU_data_address = (void *)*cpu_reg_ptr;
148
149 return;
150 }
151 case 1:
152
153 RE_ENTRANT_CHECK_OFF
154 offset = (signed char) get_fs_byte((char *) FPU_EIP);
155 RE_ENTRANT_CHECK_ON
156 FPU_EIP++;
157 break;
158 case 2:
159
160 RE_ENTRANT_CHECK_OFF
161 offset = (signed) get_fs_long((unsigned long *) FPU_EIP);
162 RE_ENTRANT_CHECK_ON
163 FPU_EIP += 4;
164 break;
165 case 3:
166
167 EXCEPTION(EX_Invalid);
168 }
169
170 FPU_data_address = offset + (char *)*cpu_reg_ptr;
171 }