int ptrace_set_bpt(struct task_struct *child) { unsigned long pc,next; unsigned short insn; pc = get_reg(child,PT_PC); next = insn_length((unsigned char *)pc) + pc; insn = get_fs_word(pc); if (insn == 0x5470) { /* rts */ unsigned long sp; sp = get_reg(child,PT_USP); next = get_fs_long(sp); } else if ((insn & 0xfb00) != 0x5800) { /* jmp / jsr */ int regs; const short reg_tbl[]={PT_ER0,PT_ER1,PT_ER2,PT_ER3, PT_ER4,PT_ER5,PT_ER6,PT_USP}; switch(insn & 0xfb00) { case 0x5900: regs = (insn & 0x0070) >> 8; next = get_reg(child,reg_tbl[regs]); break; case 0x5a00: next = get_fs_long(pc+2) & 0x00ffffff; break; case 0x5b00: /* unneccessary? */ next = *(unsigned long *)(insn & 0xff); break; } } else if (((insn & 0xf000) == 0x4000) || ((insn &0xff00) == 0x5500)) {
static int do_fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, int kspc) { int i, start; u_short *red, *green, *blue, *transp; u_int hred, hgreen, hblue, htransp; red = cmap->red; green = cmap->green; blue = cmap->blue; transp = cmap->transp; start = cmap->start; if (start < 0) return(-EINVAL); for (i = 0; i < cmap->len; i++) { if (kspc) { hred = *red; hgreen = *green; hblue = *blue; htransp = transp ? *transp : 0; } else { hred = get_fs_word(red); hgreen = get_fs_word(green); hblue = get_fs_word(blue); htransp = transp ? get_fs_word(transp) : 0; } hred = CNVT_TOHW(hred, var->red.length); hgreen = CNVT_TOHW(hgreen, var->green.length); hblue = CNVT_TOHW(hblue, var->blue.length); htransp = CNVT_TOHW(htransp, var->transp.length); red++; green++; blue++; if (transp) transp++; if (fbhw->setcolreg(start++, hred, hgreen, hblue, htransp)) return(0); } return(0); }
asmlinkage int sys_setgroups(int gidsetsize, gid_t *grouplist) { int i; if (!suser()) return -EPERM; if (gidsetsize > NGROUPS) return -EINVAL; for (i = 0; i < gidsetsize; i++, grouplist++) { current->groups[i] = get_fs_word((unsigned short *) grouplist); } if (i < NGROUPS) current->groups[i] = NOGROUP; return 0; }
static void do_emu(struct info * info) { unsigned short code; temp_real tmp; char * address; if (I387.cwd & I387.swd & 0x3f) I387.swd |= 0x8000; else I387.swd &= 0x7fff; ORIG_EIP = EIP; /* 0x0007 means user code space */ if (CS != 0x000F) { printk("math_emulate: %04x:%08x\n\r",CS,EIP); panic("Math emulation needed in kernel"); } code = get_fs_word((unsigned short *) EIP); bswapw(code); code &= 0x7ff; I387.fip = EIP; *(unsigned short *) &I387.fcs = CS; *(1+(unsigned short *) &I387.fcs) = code; EIP += 2; switch (code) { case 0x1d0: /* fnop */ return; case 0x1d1: case 0x1d2: case 0x1d3: case 0x1d4: case 0x1d5: case 0x1d6: case 0x1d7: math_abort(info,1<<(SIGILL-1)); case 0x1e0: ST(0).exponent ^= 0x8000; return; case 0x1e1: ST(0).exponent &= 0x7fff; return; case 0x1e2: case 0x1e3: math_abort(info,1<<(SIGILL-1)); case 0x1e4: ftst(PST(0)); return; case 0x1e5: printk("fxam not implemented\n\r"); math_abort(info,1<<(SIGILL-1)); case 0x1e6: case 0x1e7: math_abort(info,1<<(SIGILL-1)); case 0x1e8: fpush(); ST(0) = CONST1; return; case 0x1e9: fpush(); ST(0) = CONSTL2T; return; case 0x1ea: fpush(); ST(0) = CONSTL2E; return; case 0x1eb: fpush(); ST(0) = CONSTPI; return; case 0x1ec: fpush(); ST(0) = CONSTLG2; return; case 0x1ed: fpush(); ST(0) = CONSTLN2; return; case 0x1ee: fpush(); ST(0) = CONSTZ; return; case 0x1ef: math_abort(info,1<<(SIGILL-1)); case 0x1f0: case 0x1f1: case 0x1f2: case 0x1f3: case 0x1f4: case 0x1f5: case 0x1f6: case 0x1f7: case 0x1f8: case 0x1f9: case 0x1fa: case 0x1fb: case 0x1fc: case 0x1fd: case 0x1fe: case 0x1ff: printk("%04x fxxx not implemented\n\r",code + 0xc800); math_abort(info,1<<(SIGILL-1)); case 0x2e9: fucom(PST(1),PST(0)); fpop(); fpop(); return; case 0x3d0: case 0x3d1: return; case 0x3e2: I387.swd &= 0x7f00; return; case 0x3e3: I387.cwd = 0x037f; I387.swd = 0x0000; I387.twd = 0x0000; return; case 0x3e4: return; case 0x6d9: fcom(PST(1),PST(0)); fpop(); fpop(); return; case 0x7e0: *(short *) &EAX = I387.swd; return; } switch (code >> 3) { case 0x18: fadd(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(0)); return; case 0x19: fmul(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(0)); return; case 0x1a: fcom(PST(code & 7),&tmp); real_to_real(&tmp,&ST(0)); return; case 0x1b: fcom(PST(code & 7),&tmp); real_to_real(&tmp,&ST(0)); fpop(); return; case 0x1c: real_to_real(&ST(code & 7),&tmp); tmp.exponent ^= 0x8000; fadd(PST(0),&tmp,&tmp); real_to_real(&tmp,&ST(0)); return; case 0x1d: ST(0).exponent ^= 0x8000; fadd(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(0)); return; case 0x1e: fdiv(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(0)); return; case 0x1f: fdiv(PST(code & 7),PST(0),&tmp); real_to_real(&tmp,&ST(0)); return; case 0x38: fpush(); ST(0) = ST((code & 7)+1); return; case 0x39: fxchg(&ST(0),&ST(code & 7)); return; case 0x3b: ST(code & 7) = ST(0); fpop(); return; case 0x98: fadd(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(code & 7)); return; case 0x99: fmul(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(code & 7)); return; case 0x9a: fcom(PST(code & 7),PST(0)); return; case 0x9b: fcom(PST(code & 7),PST(0)); fpop(); return; case 0x9c: ST(code & 7).exponent ^= 0x8000; fadd(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(code & 7)); return; case 0x9d: real_to_real(&ST(0),&tmp); tmp.exponent ^= 0x8000; fadd(PST(code & 7),&tmp,&tmp); real_to_real(&tmp,&ST(code & 7)); return; case 0x9e: fdiv(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(code & 7)); return; case 0x9f: fdiv(PST(code & 7),PST(0),&tmp); real_to_real(&tmp,&ST(code & 7)); return; case 0xb8: printk("ffree not implemented\n\r"); math_abort(info,1<<(SIGILL-1)); case 0xb9: fxchg(&ST(0),&ST(code & 7)); return; case 0xba: ST(code & 7) = ST(0); return; case 0xbb: ST(code & 7) = ST(0); fpop(); return; case 0xbc: fucom(PST(code & 7),PST(0)); return; case 0xbd: fucom(PST(code & 7),PST(0)); fpop(); return; case 0xd8: fadd(PST(code & 7),PST(0),&tmp); real_to_real(&tmp,&ST(code & 7)); fpop(); return; case 0xd9: fmul(PST(code & 7),PST(0),&tmp); real_to_real(&tmp,&ST(code & 7)); fpop(); return; case 0xda: fcom(PST(code & 7),PST(0)); fpop(); return; case 0xdc: ST(code & 7).exponent ^= 0x8000; fadd(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(code & 7)); fpop(); return; case 0xdd: real_to_real(&ST(0),&tmp); tmp.exponent ^= 0x8000; fadd(PST(code & 7),&tmp,&tmp); real_to_real(&tmp,&ST(code & 7)); fpop(); return; case 0xde: fdiv(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(code & 7)); fpop(); return; case 0xdf: fdiv(PST(code & 7),PST(0),&tmp); real_to_real(&tmp,&ST(code & 7)); fpop(); return; case 0xf8: printk("ffree not implemented\n\r"); math_abort(info,1<<(SIGILL-1)); fpop(); return; case 0xf9: fxchg(&ST(0),&ST(code & 7)); return; case 0xfa: case 0xfb: ST(code & 7) = ST(0); fpop(); return; } switch ((code>>3) & 0xe7) { case 0x22: put_short_real(PST(0),info,code); return; case 0x23: put_short_real(PST(0),info,code); fpop(); return; case 0x24: address = ea(info,code); for (code = 0 ; code < 7 ; code++) { ((long *) & I387)[code] = get_fs_long((unsigned long *) address); address += 4; } return; case 0x25: address = ea(info,code); *(unsigned short *) &I387.cwd = get_fs_word((unsigned short *) address); return; case 0x26: address = ea(info,code); verify_area(address,28); for (code = 0 ; code < 7 ; code++) { put_fs_long( ((long *) & I387)[code], (unsigned long *) address); address += 4; } return; case 0x27: address = ea(info,code); verify_area(address,2); put_fs_word(I387.cwd,(short *) address); return; case 0x62: put_long_int(PST(0),info,code); return; case 0x63: put_long_int(PST(0),info,code); fpop(); return; case 0x65: fpush(); get_temp_real(&tmp,info,code); real_to_real(&tmp,&ST(0)); return; case 0x67: put_temp_real(PST(0),info,code); fpop(); return; case 0xa2: put_long_real(PST(0),info,code); return; case 0xa3: put_long_real(PST(0),info,code); fpop(); return; case 0xa4: address = ea(info,code); for (code = 0 ; code < 27 ; code++) { ((long *) & I387)[code] = get_fs_long((unsigned long *) address); address += 4; } return; case 0xa6: address = ea(info,code); verify_area(address,108); for (code = 0 ; code < 27 ; code++) { put_fs_long( ((long *) & I387)[code], (unsigned long *) address); address += 4; } I387.cwd = 0x037f; I387.swd = 0x0000; I387.twd = 0x0000; return; case 0xa7: address = ea(info,code); verify_area(address,2); put_fs_word(I387.swd,(short *) address); return; case 0xe2: put_short_int(PST(0),info,code); return; case 0xe3: put_short_int(PST(0),info,code); fpop(); return; case 0xe4: fpush(); get_BCD(&tmp,info,code); real_to_real(&tmp,&ST(0)); return; case 0xe5: fpush(); get_longlong_int(&tmp,info,code); real_to_real(&tmp,&ST(0)); return; case 0xe6: put_BCD(PST(0),info,code); fpop(); return; case 0xe7: put_longlong_int(PST(0),info,code); fpop(); return; } switch (code >> 9) { case 0: get_short_real(&tmp,info,code); break; case 1: get_long_int(&tmp,info,code); break; case 2: get_long_real(&tmp,info,code); break; case 4: get_short_int(&tmp,info,code); } switch ((code>>3) & 0x27) { case 0: fadd(&tmp,PST(0),&tmp); real_to_real(&tmp,&ST(0)); return; case 1: fmul(&tmp,PST(0),&tmp); real_to_real(&tmp,&ST(0)); return; case 2: fcom(&tmp,PST(0)); return; case 3: fcom(&tmp,PST(0)); fpop(); return; case 4: tmp.exponent ^= 0x8000; fadd(&tmp,PST(0),&tmp); real_to_real(&tmp,&ST(0)); return; case 5: ST(0).exponent ^= 0x8000; fadd(&tmp,PST(0),&tmp); real_to_real(&tmp,&ST(0)); return; case 6: fdiv(PST(0),&tmp,&tmp); real_to_real(&tmp,&ST(0)); return; case 7: fdiv(&tmp,PST(0),&tmp); real_to_real(&tmp,&ST(0)); return; } if ((code & 0x138) == 0x100) { fpush(); real_to_real(&tmp,&ST(0)); return; } printk("Unknown math-insns: %04x:%08x %04x\n\r",CS,EIP,code); math_abort(info,1<<(SIGFPE-1)); }
static int math_emulate(struct trapframe * info) { unsigned short code; temp_real tmp; char * address; u_long oldeip; /* ever used fp? */ if ((((struct pcb *)curproc->p_addr)->pcb_flags & FP_SOFTFP) == 0) { ((struct pcb *)curproc->p_addr)->pcb_flags |= FP_SOFTFP; I387.cwd = 0x037f; I387.swd = 0x0000; I387.twd = 0x0000; } if (I387.cwd & I387.swd & 0x3f) I387.swd |= 0x8000; else I387.swd &= 0x7fff; oldeip = info->tf_eip; /* 0x001f means user code space */ if ((u_short)info->tf_cs != 0x001F) { printf("math_emulate: %04x:%08lx\n", (u_short)info->tf_cs, oldeip); panic("?Math emulation needed in kernel?"); } code = get_fs_word((unsigned short *) oldeip); bswapw(code); code &= 0x7ff; I387.fip = oldeip; *(unsigned short *) &I387.fcs = (u_short) info->tf_cs; *(1+(unsigned short *) &I387.fcs) = code; info->tf_eip += 2; switch (code) { case 0x1d0: /* fnop */ return(0); case 0x1d1: case 0x1d2: case 0x1d3: /* fst to 32-bit mem */ case 0x1d4: case 0x1d5: case 0x1d6: case 0x1d7: math_abort(info,SIGILL); case 0x1e0: /* fchs */ ST(0).exponent ^= 0x8000; return(0); case 0x1e1: /* fabs */ ST(0).exponent &= 0x7fff; return(0); case 0x1e2: case 0x1e3: math_abort(info,SIGILL); case 0x1e4: /* ftst */ ftst(PST(0)); return(0); case 0x1e5: /* fxam */ printf("fxam not implemented\n"); math_abort(info,SIGILL); case 0x1e6: case 0x1e7: /* fldenv */ math_abort(info,SIGILL); case 0x1e8: /* fld1 */ fpush(); ST(0) = CONST1; return(0); case 0x1e9: /* fld2t */ fpush(); ST(0) = CONSTL2T; return(0); case 0x1ea: /* fld2e */ fpush(); ST(0) = CONSTL2E; return(0); case 0x1eb: /* fldpi */ fpush(); ST(0) = CONSTPI; return(0); case 0x1ec: /* fldlg2 */ fpush(); ST(0) = CONSTLG2; return(0); case 0x1ed: /* fldln2 */ fpush(); ST(0) = CONSTLN2; return(0); case 0x1ee: /* fldz */ fpush(); ST(0) = CONSTZ; return(0); case 0x1ef: math_abort(info,SIGILL); case 0x1f0: /* f2xm1 */ case 0x1f1: /* fyl2x */ case 0x1f2: /* fptan */ case 0x1f3: /* fpatan */ case 0x1f4: /* fxtract */ case 0x1f5: /* fprem1 */ case 0x1f6: /* fdecstp */ case 0x1f7: /* fincstp */ case 0x1f8: /* fprem */ case 0x1f9: /* fyl2xp1 */ case 0x1fa: /* fsqrt */ case 0x1fb: /* fsincos */ case 0x1fe: /* fsin */ case 0x1ff: /* fcos */ uprintf( "math_emulate: instruction %04x not implemented\n", code + 0xd800); math_abort(info,SIGILL); case 0x1fc: /* frndint */ frndint(PST(0),&tmp); real_to_real(&tmp,&ST(0)); return(0); case 0x1fd: /* fscale */ /* incomplete and totally inadequate -wfj */ Fscale(PST(0), PST(1), &tmp); real_to_real(&tmp,&ST(0)); return(0); /* 19 Sep 92*/ case 0x2e9: /* ????? */ /* if this should be a fucomp ST(0),ST(1) , it must be a 0x3e9 ATS */ fucom(PST(1),PST(0)); fpop(); fpop(); return(0); case 0x3d0: case 0x3d1: /* fist ?? */ return(0); case 0x3e2: /* fclex */ I387.swd &= 0x7f00; return(0); case 0x3e3: /* fninit */ I387.cwd = 0x037f; I387.swd = 0x0000; I387.twd = 0x0000; return(0); case 0x3e4: return(0); case 0x6d9: /* fcompp */ fcom(PST(1),PST(0)); fpop(); fpop(); return(0); case 0x7e0: /* fstsw ax */ *(short *) &info->tf_eax = I387.swd; return(0); } switch (code >> 3) { case 0x18: /* fadd */ fadd(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(0)); return(0); case 0x19: /* fmul */ fmul(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(0)); return(0); case 0x1a: /* fcom */ fcom(PST(code & 7),PST(0)); return(0); case 0x1b: /* fcomp */ fcom(PST(code & 7),PST(0)); fpop(); return(0); case 0x1c: /* fsubr */ real_to_real(&ST(code & 7),&tmp); tmp.exponent ^= 0x8000; fadd(PST(0),&tmp,&tmp); real_to_real(&tmp,&ST(0)); return(0); case 0x1d: /* fsub */ ST(0).exponent ^= 0x8000; fadd(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(0)); return(0); case 0x1e: /* fdivr */ fdiv(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(0)); return(0); case 0x1f: /* fdiv */ fdiv(PST(code & 7),PST(0),&tmp); real_to_real(&tmp,&ST(0)); return(0); case 0x38: /* fld */ fpush(); ST(0) = ST((code & 7)+1); /* why plus 1 ????? ATS */ return(0); case 0x39: /* fxch */ fxchg(&ST(0),&ST(code & 7)); return(0); case 0x3b: /* ??? ??? wrong ???? ATS */ ST(code & 7) = ST(0); fpop(); return(0); case 0x98: /* fadd */ fadd(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(code & 7)); return(0); case 0x99: /* fmul */ fmul(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(code & 7)); return(0); case 0x9a: /* ???? , my manual don't list a direction bit for fcom , ??? ATS */ fcom(PST(code & 7),PST(0)); return(0); case 0x9b: /* same as above , ATS */ fcom(PST(code & 7),PST(0)); fpop(); return(0); case 0x9c: /* fsubr */ ST(code & 7).exponent ^= 0x8000; fadd(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(code & 7)); return(0); case 0x9d: /* fsub */ real_to_real(&ST(0),&tmp); tmp.exponent ^= 0x8000; fadd(PST(code & 7),&tmp,&tmp); real_to_real(&tmp,&ST(code & 7)); return(0); case 0x9e: /* fdivr */ fdiv(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(code & 7)); return(0); case 0x9f: /* fdiv */ fdiv(PST(code & 7),PST(0),&tmp); real_to_real(&tmp,&ST(code & 7)); return(0); case 0xb8: /* ffree */ printf("ffree not implemented\n"); math_abort(info,SIGILL); case 0xb9: /* fstp ???? where is the pop ? ATS */ fxchg(&ST(0),&ST(code & 7)); return(0); case 0xba: /* fst */ ST(code & 7) = ST(0); return(0); case 0xbb: /* ????? encoding of fstp to mem ? ATS */ ST(code & 7) = ST(0); fpop(); return(0); case 0xbc: /* fucom */ fucom(PST(code & 7),PST(0)); return(0); case 0xbd: /* fucomp */ fucom(PST(code & 7),PST(0)); fpop(); return(0); case 0xd8: /* faddp */ fadd(PST(code & 7),PST(0),&tmp); real_to_real(&tmp,&ST(code & 7)); fpop(); return(0); case 0xd9: /* fmulp */ fmul(PST(code & 7),PST(0),&tmp); real_to_real(&tmp,&ST(code & 7)); fpop(); return(0); case 0xda: /* ??? encoding of ficom with 16 bit mem ? ATS */ fcom(PST(code & 7),PST(0)); fpop(); return(0); case 0xdc: /* fsubrp */ ST(code & 7).exponent ^= 0x8000; fadd(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(code & 7)); fpop(); return(0); case 0xdd: /* fsubp */ real_to_real(&ST(0),&tmp); tmp.exponent ^= 0x8000; fadd(PST(code & 7),&tmp,&tmp); real_to_real(&tmp,&ST(code & 7)); fpop(); return(0); case 0xde: /* fdivrp */ fdiv(PST(0),PST(code & 7),&tmp); real_to_real(&tmp,&ST(code & 7)); fpop(); return(0); case 0xdf: /* fdivp */ fdiv(PST(code & 7),PST(0),&tmp); real_to_real(&tmp,&ST(code & 7)); fpop(); return(0); case 0xf8: /* fild 16-bit mem ???? ATS */ printf("ffree not implemented\n"); math_abort(info,SIGILL); fpop(); return(0); case 0xf9: /* ????? ATS */ fxchg(&ST(0),&ST(code & 7)); return(0); case 0xfa: /* fist 16-bit mem ? ATS */ case 0xfb: /* fistp 16-bit mem ? ATS */ ST(code & 7) = ST(0); fpop(); return(0); } switch ((code>>3) & 0xe7) { case 0x22: put_short_real(PST(0),info,code); return(0); case 0x23: put_short_real(PST(0),info,code); fpop(); return(0); case 0x24: address = ea(info,code); for (code = 0 ; code < 7 ; code++) { ((long *) & I387)[code] = get_fs_long((unsigned long *) address); address += 4; } return(0); case 0x25: address = ea(info,code); *(unsigned short *) &I387.cwd = get_fs_word((unsigned short *) address); return(0); case 0x26: address = ea(info,code); /*verify_area(address,28);*/ for (code = 0 ; code < 7 ; code++) { put_fs_long( ((long *) & I387)[code], (unsigned long *) address); address += 4; } return(0); case 0x27: address = ea(info,code); /*verify_area(address,2);*/ put_fs_word(I387.cwd,(short *) address); return(0); case 0x62: put_long_int(PST(0),info,code); return(0); case 0x63: put_long_int(PST(0),info,code); fpop(); return(0); case 0x65: fpush(); get_temp_real(&tmp,info,code); real_to_real(&tmp,&ST(0)); return(0); case 0x67: put_temp_real(PST(0),info,code); fpop(); return(0); case 0xa2: put_long_real(PST(0),info,code); return(0); case 0xa3: put_long_real(PST(0),info,code); fpop(); return(0); case 0xa4: address = ea(info,code); for (code = 0 ; code < 27 ; code++) { ((long *) & I387)[code] = get_fs_long((unsigned long *) address); address += 4; } return(0); case 0xa6: address = ea(info,code); /*verify_area(address,108);*/ for (code = 0 ; code < 27 ; code++) { put_fs_long( ((long *) & I387)[code], (unsigned long *) address); address += 4; } I387.cwd = 0x037f; I387.swd = 0x0000; I387.twd = 0x0000; return(0); case 0xa7: address = ea(info,code); /*verify_area(address,2);*/ put_fs_word(I387.swd,(short *) address); return(0); case 0xe2: put_short_int(PST(0),info,code); return(0); case 0xe3: put_short_int(PST(0),info,code); fpop(); return(0); case 0xe4: fpush(); get_BCD(&tmp,info,code); real_to_real(&tmp,&ST(0)); return(0); case 0xe5: fpush(); get_longlong_int(&tmp,info,code); real_to_real(&tmp,&ST(0)); return(0); case 0xe6: put_BCD(PST(0),info,code); fpop(); return(0); case 0xe7: put_longlong_int(PST(0),info,code); fpop(); return(0); } switch (code >> 9) { case 0: get_short_real(&tmp,info,code); break; case 1: get_long_int(&tmp,info,code); break; case 2: get_long_real(&tmp,info,code); break; case 4: get_short_int(&tmp,info,code); } switch ((code>>3) & 0x27) { case 0: fadd(&tmp,PST(0),&tmp); real_to_real(&tmp,&ST(0)); return(0); case 1: fmul(&tmp,PST(0),&tmp); real_to_real(&tmp,&ST(0)); return(0); case 2: fcom(&tmp,PST(0)); return(0); case 3: fcom(&tmp,PST(0)); fpop(); return(0); case 4: tmp.exponent ^= 0x8000; fadd(&tmp,PST(0),&tmp); real_to_real(&tmp,&ST(0)); return(0); case 5: ST(0).exponent ^= 0x8000; fadd(&tmp,PST(0),&tmp); real_to_real(&tmp,&ST(0)); return(0); case 6: fdiv(PST(0),&tmp,&tmp); real_to_real(&tmp,&ST(0)); return(0); case 7: fdiv(&tmp,PST(0),&tmp); real_to_real(&tmp,&ST(0)); return(0); } if ((code & 0x138) == 0x100) { fpush(); real_to_real(&tmp,&ST(0)); return(0); } printf("Unknown math-insns: %04x:%08x %04x\n",(u_short)info->tf_cs, info->tf_eip,code); math_abort(info,SIGFPE); }
void load_store_instr(char type) { FPU_REG *pop_ptr; /* We need a version of FPU_st0_ptr which won't change. */ pop_ptr = NULL; /* Initialized just to stop compiler warnings. */ switch ( type_table[(int) (unsigned) type] ) { case _NONE_: break; case _REG0_: pop_ptr = &st(0); /* Some of these instructions pop after storing */ FPU_st0_ptr = pop_ptr; /* Set the global variables. */ FPU_st0_tag = FPU_st0_ptr->tag; break; case _PUSH_: { pop_ptr = &st(-1); if ( pop_ptr->tag != TW_Empty ) { stack_overflow(); return; } top--; } break; case _null_: return Un_impl(); #ifdef PARANOID default: return EXCEPTION(EX_INTERNAL); #endif PARANOID } switch ( type ) { case 000: /* fld m32real */ reg_load_single(); reg_move(&FPU_loaded_data, pop_ptr); break; case 001: /* fild m32int */ reg_load_int32(); reg_move(&FPU_loaded_data, pop_ptr); break; case 002: /* fld m64real */ reg_load_double(); reg_move(&FPU_loaded_data, pop_ptr); break; case 003: /* fild m16int */ reg_load_int16(); reg_move(&FPU_loaded_data, pop_ptr); break; case 010: /* fst m32real */ reg_store_single(); break; case 011: /* fist m32int */ reg_store_int32(); break; case 012: /* fst m64real */ reg_store_double(); break; case 013: /* fist m16int */ reg_store_int16(); break; case 014: /* fstp m32real */ if ( reg_store_single() ) pop_0(); /* pop only if the number was actually stored (see the 80486 manual p16-28) */ break; case 015: /* fistp m32int */ if ( reg_store_int32() ) pop_0(); /* pop only if the number was actually stored (see the 80486 manual p16-28) */ break; case 016: /* fstp m64real */ if ( reg_store_double() ) pop_0(); /* pop only if the number was actually stored (see the 80486 manual p16-28) */ break; case 017: /* fistp m16int */ if ( reg_store_int16() ) pop_0(); /* pop only if the number was actually stored (see the 80486 manual p16-28) */ break; case 020: /* fldenv m14/28byte */ fldenv(); break; case 022: /* frstor m94/108byte */ frstor(); break; case 023: /* fbld m80dec */ reg_load_bcd(); reg_move(&FPU_loaded_data, pop_ptr); break; case 024: /* fldcw */ RE_ENTRANT_CHECK_OFF control_word = get_fs_word((unsigned short *) FPU_data_address); RE_ENTRANT_CHECK_ON #ifdef NO_UNDERFLOW_TRAP if ( !(control_word & EX_Underflow) ) { control_word |= EX_Underflow; } #endif FPU_data_address = (void *)data_operand_offset; /* We want no net effect */ FPU_entry_eip = ip_offset; /* We want no net effect */ break; case 025: /* fld m80real */ reg_load_extended(); reg_move(&FPU_loaded_data, pop_ptr); break; case 027: /* fild m64int */ reg_load_int64(); reg_move(&FPU_loaded_data, pop_ptr); break; case 030: /* fstenv m14/28byte */ fstenv(); FPU_data_address = (void *)data_operand_offset; /* We want no net effect */ FPU_entry_eip = ip_offset; /* We want no net effect */ break; case 032: /* fsave */ fsave(); FPU_data_address = (void *)data_operand_offset; /* We want no net effect */ FPU_entry_eip = ip_offset; /* We want no net effect */ break; case 033: /* fbstp m80dec */ if ( reg_store_bcd() ) pop_0(); /* pop only if the number was actually stored (see the 80486 manual p16-28) */ break; case 034: /* fstcw m16int */ RE_ENTRANT_CHECK_OFF verify_area(VERIFY_WRITE,FPU_data_address,2); put_fs_word(control_word, (short *) FPU_data_address); RE_ENTRANT_CHECK_ON FPU_data_address = (void *)data_operand_offset; /* We want no net effect */ FPU_entry_eip = ip_offset; /* We want no net effect */ break; case 035: /* fstp m80real */ if ( reg_store_extended() ) pop_0(); /* pop only if the number was actually stored (see the 80486 manual p16-28) */ break; case 036: /* fstsw m2byte */ status_word &= ~SW_TOP; status_word |= (top&7) << SW_TOPS; RE_ENTRANT_CHECK_OFF verify_area(VERIFY_WRITE,FPU_data_address,2); put_fs_word(status_word,(short *) FPU_data_address); RE_ENTRANT_CHECK_ON FPU_data_address = (void *)data_operand_offset; /* We want no net effect */ FPU_entry_eip = ip_offset; /* We want no net effect */ break; case 037: /* fistp m64int */ if ( reg_store_int64() ) pop_0(); /* pop only if the number was actually stored (see the 80486 manual p16-28) */ break; } }
/* set the current selection. Invoked by ioctl(). */ int set_selection(const unsigned long arg, struct tty_struct *tty) { int sel_mode, new_sel_start, new_sel_end, spc; char *bp, *obp; int i, ps, pe; do_unblank_screen(); { unsigned short *args, xs, ys, xe, ye; args = (unsigned short *)(arg + 1); xs = get_fs_word(args++) - 1; ys = get_fs_word(args++) - 1; xe = get_fs_word(args++) - 1; ye = get_fs_word(args++) - 1; sel_mode = get_fs_word(args); xs = limit(xs, video_num_columns - 1); ys = limit(ys, video_num_lines - 1); xe = limit(xe, video_num_columns - 1); ye = limit(ye, video_num_lines - 1); ps = ys * video_size_row + (xs << 1); pe = ye * video_size_row + (xe << 1); if (sel_mode == 4) { /* useful for screendump without selection highlights */ clear_selection(); return 0; } if (mouse_reporting() && (sel_mode & 16)) { mouse_report(tty, sel_mode & 15, xs, ys); return 0; } } if (ps > pe) /* make sel_start <= sel_end */ { int tmp = ps; ps = pe; pe = tmp; } if (sel_cons != fg_console) { clear_selection(); sel_cons = fg_console; } switch (sel_mode) { case 0: /* character-by-character selection */ new_sel_start = ps; new_sel_end = pe; break; case 1: /* word-by-word selection */ spc = isspace(sel_pos(ps)); for (new_sel_start = ps; ; ps -= 2) { if ((spc && !isspace(sel_pos(ps))) || (!spc && !inword(sel_pos(ps)))) break; new_sel_start = ps; if (!(ps % video_size_row)) break; } spc = isspace(sel_pos(pe)); for (new_sel_end = pe; ; pe += 2) { if ((spc && !isspace(sel_pos(pe))) || (!spc && !inword(sel_pos(pe)))) break; new_sel_end = pe; if (!((pe + 2) % video_size_row)) break; } break; case 2: /* line-by-line selection */ new_sel_start = ps - ps % video_size_row; new_sel_end = pe + video_size_row - pe % video_size_row - 2; break; case 3: highlight_pointer(pe); return 0; default: return -EINVAL; } /* remove the pointer */ highlight_pointer(-1); /* select to end of line if on trailing space */ if (new_sel_end > new_sel_start && !atedge(new_sel_end) && isspace(sel_pos(new_sel_end))) { for (pe = new_sel_end + 2; ; pe += 2) if (!isspace(sel_pos(pe)) || atedge(pe)) break; if (isspace(sel_pos(pe))) new_sel_end = pe; } if (sel_start == -1) /* no current selection */ highlight(new_sel_start, new_sel_end); else if (new_sel_start == sel_start) { if (new_sel_end == sel_end) /* no action required */ return 0; else if (new_sel_end > sel_end) /* extend to right */ highlight(sel_end + 2, new_sel_end); else /* contract from right */ highlight(new_sel_end + 2, sel_end); } else if (new_sel_end == sel_end) { if (new_sel_start < sel_start) /* extend to left */ highlight(new_sel_start, sel_start - 2); else /* contract from left */ highlight(sel_start, new_sel_start - 2); } else /* some other case; start selection from scratch */ { clear_selection(); highlight(new_sel_start, new_sel_end); } sel_start = new_sel_start; sel_end = new_sel_end; if (sel_buffer) kfree(sel_buffer); sel_buffer = kmalloc((sel_end-sel_start)/2+1, GFP_KERNEL); if (!sel_buffer) { printk("selection: kmalloc() failed\n"); clear_selection(); return -ENOMEM; } obp = bp = sel_buffer; for (i = sel_start; i <= sel_end; i += 2) { *bp = sel_pos(i); if (!isspace(*bp++)) obp = bp; if (! ((i + 2) % video_size_row)) { /* strip trailing blanks from line and add newline, unless non-space at end of line. */ if (obp != bp) { bp = obp; *bp++ = '\r'; } obp = bp; } } sel_buffer_lth = bp - sel_buffer; return 0; }