This source file includes following definitions.
- sib
- get_address
1
2
3
4
5
6
7
8
9
10
11
12
13 #include <linux/stddef.h>
14 #include <linux/math_emu.h>
15
16 #include <asm/segment.h>
17
18 #include "fpu_system.h"
19 #include "exception.h"
20 #include "fpu_emu.h"
21
22
23
24 static int reg_offset[] = {
25 offsetof(struct info,___eax),
26 offsetof(struct info,___ecx),
27 offsetof(struct info,___edx),
28 offsetof(struct info,___ebx),
29 offsetof(struct info,___esp),
30 offsetof(struct info,___ebp),
31 offsetof(struct info,___esi),
32 offsetof(struct info,___edi)
33 };
34
35 #define REG_(x) (*(long *)(reg_offset[(x)]+(char *) FPU_info))
36
37
38 void *FPU_data_address;
39
40
41
42 static void *sib(int mod)
43 {
44 unsigned char ss,index,base;
45 long offset;
46
47 base = get_fs_byte((char *) FPU_EIP);
48 FPU_EIP++;
49 ss = base >> 6;
50 index = (base >> 3) & 7;
51 base &= 7;
52
53 if ((mod == 0) && (base == 5))
54 offset = 0;
55 else
56 offset = REG_(base);
57
58 if (index == 4)
59 {
60
61
62 if ( ss )
63 EXCEPTION(EX_Invalid);
64 }
65 else
66 {
67 offset += (REG_(index)) << ss;
68 }
69
70 if (mod == 1)
71 {
72
73 offset += (signed char) get_fs_byte((char *) FPU_EIP);
74 FPU_EIP++;
75 }
76 else if (mod == 2 || base == 5)
77 {
78
79 offset += (signed) get_fs_long((unsigned long *) FPU_EIP);
80 FPU_EIP += 4;
81 }
82
83 return (void *) offset;
84 }
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104 void get_address(void)
105 {
106 unsigned char mod;
107 long *cpu_reg_ptr;
108 int offset;
109
110 mod = (FPU_modrm >> 6) & 3;
111
112 if (FPU_rm == 4 && mod != 3)
113 {
114 FPU_data_address = sib(mod);
115 return;
116 }
117
118 cpu_reg_ptr = & REG_(FPU_rm);
119 switch (mod)
120 {
121 case 0:
122 if (FPU_rm == 5)
123 {
124
125 offset = get_fs_long((unsigned long *) FPU_EIP);
126 FPU_EIP += 4;
127 FPU_data_address = (void *) offset;
128 return;
129 }
130 else
131 {
132 FPU_data_address = (void *)*cpu_reg_ptr;
133
134 return;
135 }
136 case 1:
137
138 offset = (signed char) get_fs_byte((char *) FPU_EIP);
139 FPU_EIP++;
140 break;
141 case 2:
142
143 offset = (signed) get_fs_long((unsigned long *) FPU_EIP);
144 FPU_EIP += 4;
145 break;
146 case 3:
147
148 EXCEPTION(EX_Invalid);
149 }
150
151 FPU_data_address = offset + (char *)*cpu_reg_ptr;
152 }