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 void *FPU_data_address;
44
45
46
47 static void *sib(int mod)
48 {
49 unsigned char ss,index,base;
50 long offset;
51
52 RE_ENTRANT_CHECK_OFF
53 base = get_fs_byte((char *) FPU_EIP);
54 RE_ENTRANT_CHECK_ON
55 FPU_EIP++;
56 ss = base >> 6;
57 index = (base >> 3) & 7;
58 base &= 7;
59
60 if ((mod == 0) && (base == 5))
61 offset = 0;
62 else
63 offset = REG_(base);
64
65 if (index == 4)
66 {
67
68
69 if ( ss )
70 EXCEPTION(EX_Invalid);
71 }
72 else
73 {
74 offset += (REG_(index)) << ss;
75 }
76
77 if (mod == 1)
78 {
79
80 RE_ENTRANT_CHECK_OFF
81 offset += (signed char) get_fs_byte((char *) FPU_EIP);
82 RE_ENTRANT_CHECK_ON
83 FPU_EIP++;
84 }
85 else if (mod == 2 || base == 5)
86 {
87
88 RE_ENTRANT_CHECK_OFF
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)
116 {
117 unsigned char mod;
118 long *cpu_reg_ptr;
119 int offset = 0;
120
121 mod = (FPU_modrm >> 6) & 3;
122
123 if (FPU_rm == 4 && mod != 3)
124 {
125 FPU_data_address = sib(mod);
126 return;
127 }
128
129 cpu_reg_ptr = & REG_(FPU_rm);
130 switch (mod)
131 {
132 case 0:
133 if (FPU_rm == 5)
134 {
135
136 RE_ENTRANT_CHECK_OFF
137 offset = get_fs_long((unsigned long *) FPU_EIP);
138 RE_ENTRANT_CHECK_ON
139 FPU_EIP += 4;
140 FPU_data_address = (void *) offset;
141 return;
142 }
143 else
144 {
145 FPU_data_address = (void *)*cpu_reg_ptr;
146
147 return;
148 }
149 case 1:
150
151 RE_ENTRANT_CHECK_OFF
152 offset = (signed char) get_fs_byte((char *) FPU_EIP);
153 RE_ENTRANT_CHECK_ON
154 FPU_EIP++;
155 break;
156 case 2:
157
158 RE_ENTRANT_CHECK_OFF
159 offset = (signed) get_fs_long((unsigned long *) FPU_EIP);
160 RE_ENTRANT_CHECK_ON
161 FPU_EIP += 4;
162 break;
163 case 3:
164
165 EXCEPTION(EX_Invalid);
166 }
167
168 FPU_data_address = offset + (char *)*cpu_reg_ptr;
169 }