⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mathemu.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
                        (opcode[3]>>4,opcode[3]&15,opcode[2]>>4);                return 0;	case 9: /* RRE format, ldebr & mdebr instruction */		/* float store but double load */                emu_store_rege((opcode[3]>>4)&15);                emu_store_rege(opcode[3]&15);                /* call the emulation function */                ((void (*)(int, int))jump_table[opcode[1]])                        (opcode[3]>>4,opcode[3]&15);                emu_load_regd((opcode[3]>>4)&15);                return 0;        case 10: /* RRE format, ledbr instruction */		/* double store but float load */                emu_store_regd((opcode[3]>>4)&15);                emu_store_regd(opcode[3]&15);                /* call the emulation function */                ((void (*)(int, int))jump_table[opcode[1]])                        (opcode[3]>>4,opcode[3]&15);                emu_load_rege((opcode[3]>>4)&15);                return 0;        default:                return 1;        }}static void* calc_addr(struct pt_regs *regs,int rx,int rb,int disp){  rx &= 0xf;  rb &= 0xf;  disp &= 0xfff;  return (void*) ((rx != 0 ? regs->gprs[rx] : 0)  + /* index */            (rb != 0 ? regs->gprs[rb] : 0)  + /* base */         disp);}    int math_emu_ed(__u8 *opcode, struct pt_regs * regs) {        static const __u8 format_table[] = {                0, 0, 0, 0, 5, 1, 2, 1, 2, 2, 2, 2, 5, 2, 4, 4,                2, 1, 1, 0, 2, 1, 0, 2, 1, 1, 1, 1, 1, 1, 3, 3,                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0        };        static const void *jump_table[]= {                NULL,     NULL,     NULL,     NULL,                emu_ldeb, emu_lxdb, emu_lxeb, emu_mxdb,                emu_keb,  emu_ceb,  emu_aeb,  emu_seb,                emu_mdeb, emu_deb,  emu_maeb, emu_mseb,                emu_tceb, emu_tcdb, emu_tcxb, NULL,                emu_sqeb, emu_sqdb, NULL,     emu_meeb,                emu_kdb,  emu_cdb,  emu_adb,  emu_sdb,                emu_mdb,  emu_ddb,  emu_madb, emu_msdb        };        switch (format_table[opcode[5]]) {        case 1: /* RXE format, __u64 constant */ {                __u64 *dxb, temp;                __u32 opc;                emu_store_regd((opcode[1]>>4)&15);                opc = *((__u32 *) opcode);                dxb = (__u64 *) calc_addr(regs,opc>>16,opc>>12,opc);                /* FIXME: how to react if copy_from_user fails ? */                copy_from_user(&temp, dxb, 8);                /* call the emulation function */                ((void (*)(int, __u64))jump_table[opcode[5]])                        (opcode[1]>>4,temp);                emu_load_regd((opcode[1]>>4)&15);                return 0;        }        case 2: /* RXE format, __u32 constant */ {                __u32 *dxb, temp;                __u32 opc;                emu_store_rege((opcode[1]>>4)&15);                opc = *((__u32 *) opcode);                dxb = (__u32 *) calc_addr(regs,opc>>16,opc>>12,opc);                /* FIXME: how to react if get_user fails ? */                get_user(temp, dxb);                /* call the emulation function */                ((void (*)(int, __u32))jump_table[opcode[5]])                        (opcode[1]>>4,temp);                emu_load_rege((opcode[1]>>4)&15);                return 0;        }        case 3: /* RXF format, __u64 constant */ {                __u32 *dxb, temp;                __u32 opc;                emu_store_regd((opcode[1]>>4)&15);                opc = *((__u32 *) opcode);                dxb = (__u32 *) calc_addr(regs,opc>>16,opc>>12,opc);                /* FIXME: how to react if copy_from_user fails ? */                copy_from_user(&temp, dxb, 8);                /* call the emulation function */                ((void (*)(int, __u32, int))jump_table[opcode[5]])                        (opcode[1]>>4,temp,opcode[4]>>4);                emu_load_regd((opcode[1]>>4)&15);                return 0;        }        case 4: /* RXF format, __u32 constant */ {                __u32 *dxb, temp;                __u32 opc;                emu_store_rege((opcode[1]>>4)&15);                opc = *((__u32 *) opcode);                dxb = (__u32 *) calc_addr(regs,opc>>16,opc>>12,opc);                /* FIXME: how to react if get_user fails ? */                get_user(temp, dxb);                /* call the emulation function */                ((void (*)(int, __u32, int))jump_table[opcode[5]])                        (opcode[1]>>4,temp,opcode[4]>>4);                emu_load_rege((opcode[1]>>4)&15);                return 0;        }	case 5: /* RXE format, __u32 constant */                /* store_rege and load_regd */ 		{                __u32 *dxb, temp;                __u32 opc;                emu_store_rege((opcode[1]>>4)&15);                opc = *((__u32 *) opcode);                dxb = (__u32 *) calc_addr(regs,opc>>16,opc>>12,opc);                /* FIXME: how to react if get_user fails ? */                get_user(temp, dxb);                /* call the emulation function */                ((void (*)(int, __u32))jump_table[opcode[5]])                        (opcode[1]>>4,temp);                emu_load_regd((opcode[1]>>4)&15);                return 0;        }        default:                return 1;        }}/* * Emulate LDR Rx,Ry with Rx or Ry not in {0, 2, 4, 6} */void math_emu_ldr(__u8 *opcode) {        __u16 opc = *((__u16 *) opcode);        if ((opc & 0x0090) == 0) {         /* test if rx in {0,2,4,6} */                /* we got an exception therfore ry can't be in {0,2,4,6} */                __asm__ __volatile (       /* load rx from fp_regs.fprs[ry] */                        "     bras  1,0f\n"                        "     ld    0,0(%1)\n"                        "0:   ex    %0,0(1)"                        : /* no output */                        : "a" (opc&0x00f0),                          "a" (&current->thread.fp_regs.fprs[opc&0x000f].d)                        : "1" );        } else if ((opc & 0x0009) == 0) {  /* test if ry in {0,2,4,6} */                __asm__ __volatile (       /* store ry to fp_regs.fprs[rx] */                        "     bras  1,0f\n"                        "     std   0,0(%1)\n"                        "0:   ex    %0,0(1)"                        : /* no output */                        : "a" ((opc&0x000f)<<4),                          "a" (&current->thread.fp_regs.fprs[(opc&0x00f0)>>4].d)                        : "1" );        } else {                          /* move fp_regs.fprs[ry] to fp_regs.fprs[rx] */                current->thread.fp_regs.fprs[(opc&0x00f0)>>4] =                        current->thread.fp_regs.fprs[opc&0x000f];        }}/* * Emulate LER Rx,Ry with Rx or Ry not in {0, 2, 4, 6} */void math_emu_ler(__u8 *opcode) {        __u16 opc = *((__u16 *) opcode);        if ((opc & 0x0090) == 0) {         /* test if rx in {0,2,4,6} */                /* we got an exception therfore ry can't be in {0,2,4,6} */                __asm__ __volatile (       /* load rx from fp_regs.fprs[ry] */                        "     bras  1,0f\n"                        "     le    0,0(%1)\n"                        "0:   ex    %0,0(1)"                        : /* no output */                        : "a" (opc&0x00f0),                          "a" (&current->thread.fp_regs.fprs[opc&0x000f].f)                        : "1" );        } else if ((opc & 0x0009) == 0) {  /* test if ry in {0,2,4,6} */                __asm__ __volatile (       /* store ry to fp_regs.fprs[rx] */                        "     bras  1,0f\n"                        "     ste   0,0(%1)\n"                        "0:   ex    %0,0(1)"                        : /* no output */                        : "a" ((opc&0x000f)<<4),                          "a" (&current->thread.fp_regs.fprs[(opc&0x00f0)>>4].f)                        : "1" );        } else {                          /* move fp_regs.fprs[ry] to fp_regs.fprs[rx] */                current->thread.fp_regs.fprs[(opc&0x00f0)>>4] =                        current->thread.fp_regs.fprs[opc&0x000f];        }}/* * Emulate LD R,D(X,B) with R not in {0, 2, 4, 6} */void math_emu_ld(__u8 *opcode, struct pt_regs * regs) {        __u32 opc = *((__u32 *) opcode);        __u64 *dxb;        dxb = (__u64 *) calc_addr(regs,opc>>16,opc>>12,opc);        /* FIXME: how to react if copy_from_user fails ? */        copy_from_user(&current->thread.fp_regs.fprs[(opc>>20)&15].d, dxb, 8);}/* * Emulate LE R,D(X,B) with R not in {0, 2, 4, 6} */void math_emu_le(__u8 *opcode, struct pt_regs * regs) {        __u32 opc = *((__u32 *) opcode);        __u32 *mem, *dxb;        dxb = (__u32 *) calc_addr(regs,opc>>16,opc>>12,opc);        /* FIXME: how to react if get_user fails ? */        mem = (__u32 *) (&current->thread.fp_regs.fprs[(opc>>20)&15].f);        get_user(mem[0], dxb);}/* * Emulate STD R,D(X,B) with R not in {0, 2, 4, 6} */void math_emu_std(__u8 *opcode, struct pt_regs * regs) {        __u32 opc = *((__u32 *) opcode);        __u64 *dxb;        dxb = (__u64 *) calc_addr(regs,opc>>16,opc>>12,opc);        /* FIXME: how to react if copy_to_user fails ? */        copy_to_user(dxb, &current->thread.fp_regs.fprs[(opc>>20)&15].d, 8);}/* * Emulate STE R,D(X,B) with R not in {0, 2, 4, 6} */void math_emu_ste(__u8 *opcode, struct pt_regs * regs) {        __u32 opc = *((__u32 *) opcode);        __u32 *mem, *dxb;        dxb = (__u32 *) calc_addr(regs,opc>>16,opc>>12,opc);        /* FIXME: how to react if put_user fails ? */        mem = (__u32 *) (&current->thread.fp_regs.fprs[(opc>>20)&15].f);        put_user(mem[0], dxb);}/* * Emulate LFPC D(B) */int math_emu_lfpc(__u8 *opcode, struct pt_regs *regs) {        /* FIXME: how to do that ?!? */        return 0;}/* * Emulate STFPC D(B) */int math_emu_stfpc(__u8 *opcode, struct pt_regs *regs) {        /* FIXME: how to do that ?!? */        return 0;}/* * Emulate SRNM D(B) */int math_emu_srnm(__u8 *opcode, struct pt_regs *regs) {        /* FIXME: how to do that ?!? */        return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -