20 #include <linux/stddef.h>
22 #include <asm/uaccess.h>
29 #define FPU_WRITE_BIT 0x10
31 static int reg_offset[] = {
42 #define REG_(x) (*(long *)(reg_offset[(x)] + (u_char *)FPU_info->regs))
44 static int reg_offset_vm86[] = {
54 #define VM86_REG_(x) (*(unsigned short *) \
55 (reg_offset_vm86[((unsigned)x)] + (u_char *)FPU_info->regs))
57 static int reg_offset_pm[] = {
67 #define PM_REG_(x) (*(unsigned short *) \
68 (reg_offset_pm[((unsigned)x)] + (u_char *)FPU_info->regs))
71 static int sib(
int mod,
unsigned long *fpu_eip)
82 index = (base >> 3) & 7;
85 if ((mod == 0) && (base == 5))
96 offset += (
REG_(index)) << ss;
105 offset += displacement;
108 }
else if (mod == 2 || base == 5) {
114 offset += displacement;
132 return (
unsigned long)
VM86_REG_(segment) << 4;
136 static long pm_address(
u_char FPU_modrm,
u_char segment,
163 address = base_address +
offset;
166 if (limit < base_address)
171 seg_top = 0xffffffff;
173 seg_top = base_address + (1 << 20);
174 if (seg_top < base_address)
175 seg_top = 0xffffffff;
179 ((seg_top - address) >= 255 ? 255 : seg_top -
address);
182 (address >
limit) || (address < base_address) ? 0 :
183 ((limit -
address) >= 254 ? 255 : limit - address + 1);
212 unsigned rm = FPU_modrm & 7;
225 mod = (FPU_modrm >> 6) & 3;
227 if (rm == 4 && mod != 3) {
228 address = sib(mod, fpu_eip);
230 cpu_reg_ptr = &
REG_(rm);
245 address = *cpu_reg_ptr;
270 address += *cpu_reg_ptr;
297 unsigned rm = FPU_modrm & 7;
309 mod = (FPU_modrm >> 6) & 3;
318 (
unsigned short __user *)(*fpu_eip));