?? math.c
字號:
"0: ex %0,0(1)" : /* no output */ : "a" (reg<<4),"a" (¤t->thread.fp_regs.fprs[reg].d) : "1" );}static inline void emu_load_rege(int reg) { if ((reg&9) != 0) /* test if reg in {0,2,4,6} */ return; asm volatile ( /* load reg from fp_regs.fprs[reg] */ " bras 1,0f\n" " le 0,0(%1)\n" "0: ex %0,0(1)" : /* no output */ : "a" (reg<<4), "a" (¤t->thread.fp_regs.fprs[reg].f) : "1" );}static inline void emu_store_regd(int reg) { if ((reg&9) != 0) /* test if reg in {0,2,4,6} */ return; asm volatile ( /* store reg to fp_regs.fprs[reg] */ " bras 1,0f\n" " std 0,0(%1)\n" "0: ex %0,0(1)" : /* no output */ : "a" (reg<<4), "a" (¤t->thread.fp_regs.fprs[reg].d) : "1" );}static inline void emu_store_rege(int reg) { if ((reg&9) != 0) /* test if reg in {0,2,4,6} */ return; asm volatile ( /* store reg to fp_regs.fprs[reg] */ " bras 1,0f\n" " ste 0,0(%1)\n" "0: ex %0,0(1)" : /* no output */ : "a" (reg<<4), "a" (¤t->thread.fp_regs.fprs[reg].f) : "1" );}int math_emu_b3(__u8 *opcode, struct pt_regs * regs) { int _fex = 0; static const __u8 format_table[256] = { [0x00] = 0x03,[0x01] = 0x03,[0x02] = 0x03,[0x03] = 0x03, [0x04] = 0x0f,[0x05] = 0x0d,[0x06] = 0x0e,[0x07] = 0x0d, [0x08] = 0x03,[0x09] = 0x03,[0x0a] = 0x03,[0x0b] = 0x03, [0x0c] = 0x0f,[0x0d] = 0x03,[0x0e] = 0x06,[0x0f] = 0x06, [0x10] = 0x02,[0x11] = 0x02,[0x12] = 0x02,[0x13] = 0x02, [0x14] = 0x03,[0x15] = 0x02,[0x16] = 0x01,[0x17] = 0x03, [0x18] = 0x02,[0x19] = 0x02,[0x1a] = 0x02,[0x1b] = 0x02, [0x1c] = 0x02,[0x1d] = 0x02,[0x1e] = 0x05,[0x1f] = 0x05, [0x40] = 0x01,[0x41] = 0x01,[0x42] = 0x01,[0x43] = 0x01, [0x44] = 0x12,[0x45] = 0x0d,[0x46] = 0x11,[0x47] = 0x04, [0x48] = 0x01,[0x49] = 0x01,[0x4a] = 0x01,[0x4b] = 0x01, [0x4c] = 0x01,[0x4d] = 0x01,[0x53] = 0x06,[0x57] = 0x06, [0x5b] = 0x05,[0x5f] = 0x05,[0x84] = 0x13,[0x8c] = 0x13, [0x94] = 0x09,[0x95] = 0x08,[0x96] = 0x07,[0x98] = 0x0c, [0x99] = 0x0b,[0x9a] = 0x0a }; static const void *jump_table[256]= { [0x00] = emu_lpebr,[0x01] = emu_lnebr,[0x02] = emu_ltebr, [0x03] = emu_lcebr,[0x04] = emu_ldebr,[0x05] = emu_lxdbr, [0x06] = emu_lxebr,[0x07] = emu_mxdbr,[0x08] = emu_kebr, [0x09] = emu_cebr, [0x0a] = emu_aebr, [0x0b] = emu_sebr, [0x0c] = emu_mdebr,[0x0d] = emu_debr, [0x0e] = emu_maebr, [0x0f] = emu_msebr,[0x10] = emu_lpdbr,[0x11] = emu_lndbr, [0x12] = emu_ltdbr,[0x13] = emu_lcdbr,[0x14] = emu_sqebr, [0x15] = emu_sqdbr,[0x16] = emu_sqxbr,[0x17] = emu_meebr, [0x18] = emu_kdbr, [0x19] = emu_cdbr, [0x1a] = emu_adbr, [0x1b] = emu_sdbr, [0x1c] = emu_mdbr, [0x1d] = emu_ddbr, [0x1e] = emu_madbr,[0x1f] = emu_msdbr,[0x40] = emu_lpxbr, [0x41] = emu_lnxbr,[0x42] = emu_ltxbr,[0x43] = emu_lcxbr, [0x44] = emu_ledbr,[0x45] = emu_ldxbr,[0x46] = emu_lexbr, [0x47] = emu_fixbr,[0x48] = emu_kxbr, [0x49] = emu_cxbr, [0x4a] = emu_axbr, [0x4b] = emu_sxbr, [0x4c] = emu_mxbr, [0x4d] = emu_dxbr, [0x53] = emu_diebr,[0x57] = emu_fiebr, [0x5b] = emu_didbr,[0x5f] = emu_fidbr,[0x84] = emu_sfpc, [0x8c] = emu_efpc, [0x94] = emu_cefbr,[0x95] = emu_cdfbr, [0x96] = emu_cxfbr,[0x98] = emu_cfebr,[0x99] = emu_cfdbr, [0x9a] = emu_cfxbr }; switch (format_table[opcode[1]]) { case 1: /* RRE format, long double operation */ if (opcode[3] & 0x22) return SIGILL; emu_store_regd((opcode[3] >> 4) & 15); emu_store_regd(((opcode[3] >> 4) & 15) + 2); emu_store_regd(opcode[3] & 15); emu_store_regd((opcode[3] & 15) + 2); /* call the emulation function */ _fex = ((int (*)(struct pt_regs *,int, int)) jump_table[opcode[1]]) (regs, opcode[3] >> 4, opcode[3] & 15); emu_load_regd((opcode[3] >> 4) & 15); emu_load_regd(((opcode[3] >> 4) & 15) + 2); emu_load_regd(opcode[3] & 15); emu_load_regd((opcode[3] & 15) + 2); break; case 2: /* RRE format, double operation */ emu_store_regd((opcode[3] >> 4) & 15); emu_store_regd(opcode[3] & 15); /* call the emulation function */ _fex = ((int (*)(struct pt_regs *, int, int)) jump_table[opcode[1]]) (regs, opcode[3] >> 4, opcode[3] & 15); emu_load_regd((opcode[3] >> 4) & 15); emu_load_regd(opcode[3] & 15); break; case 3: /* RRE format, float operation */ emu_store_rege((opcode[3] >> 4) & 15); emu_store_rege(opcode[3] & 15); /* call the emulation function */ _fex = ((int (*)(struct pt_regs *, int, int)) jump_table[opcode[1]]) (regs, opcode[3] >> 4, opcode[3] & 15); emu_load_rege((opcode[3] >> 4) & 15); emu_load_rege(opcode[3] & 15); break; case 4: /* RRF format, long double operation */ if (opcode[3] & 0x22) return SIGILL; emu_store_regd((opcode[3] >> 4) & 15); emu_store_regd(((opcode[3] >> 4) & 15) + 2); emu_store_regd(opcode[3] & 15); emu_store_regd((opcode[3] & 15) + 2); /* call the emulation function */ _fex = ((int (*)(struct pt_regs *, int, int, int)) jump_table[opcode[1]]) (regs, opcode[3] >> 4, opcode[3] & 15, opcode[2] >> 4); emu_load_regd((opcode[3] >> 4) & 15); emu_load_regd(((opcode[3] >> 4) & 15) + 2); emu_load_regd(opcode[3] & 15); emu_load_regd((opcode[3] & 15) + 2); break; case 5: /* RRF format, double operation */ emu_store_regd((opcode[2] >> 4) & 15); emu_store_regd((opcode[3] >> 4) & 15); emu_store_regd(opcode[3] & 15); /* call the emulation function */ _fex = ((int (*)(struct pt_regs *, int, int, int)) jump_table[opcode[1]]) (regs, opcode[3] >> 4, opcode[3] & 15, opcode[2] >> 4); emu_load_regd((opcode[2] >> 4) & 15); emu_load_regd((opcode[3] >> 4) & 15); emu_load_regd(opcode[3] & 15); break; case 6: /* RRF format, float operation */ emu_store_rege((opcode[2] >> 4) & 15); emu_store_rege((opcode[3] >> 4) & 15); emu_store_rege(opcode[3] & 15); /* call the emulation function */ _fex = ((int (*)(struct pt_regs *, int, int, int)) jump_table[opcode[1]]) (regs, opcode[3] >> 4, opcode[3] & 15, opcode[2] >> 4); emu_load_rege((opcode[2] >> 4) & 15); emu_load_rege((opcode[3] >> 4) & 15); emu_load_rege(opcode[3] & 15); break; case 7: /* RRE format, cxfbr instruction */ /* call the emulation function */ if (opcode[3] & 0x20) return SIGILL; _fex = ((int (*)(struct pt_regs *, int, int)) jump_table[opcode[1]]) (regs, opcode[3] >> 4, opcode[3] & 15); emu_load_regd((opcode[3] >> 4) & 15); emu_load_regd(((opcode[3] >> 4) & 15) + 2); break; case 8: /* RRE format, cdfbr instruction */ /* call the emulation function */ _fex = ((int (*)(struct pt_regs *, int, int)) jump_table[opcode[1]]) (regs, opcode[3] >> 4, opcode[3] & 15); emu_load_regd((opcode[3] >> 4) & 15); break; case 9: /* RRE format, cefbr instruction */ /* call the emulation function */ _fex = ((int (*)(struct pt_regs *, int, int)) jump_table[opcode[1]]) (regs, opcode[3] >> 4, opcode[3] & 15); emu_load_rege((opcode[3] >> 4) & 15); break; case 10: /* RRF format, cfxbr instruction */ if ((opcode[2] & 128) == 128 || (opcode[2] & 96) == 32) /* mask of { 2,3,8-15 } is invalid */ return SIGILL; if (opcode[3] & 2) return SIGILL; emu_store_regd(opcode[3] & 15); emu_store_regd((opcode[3] & 15) + 2); /* call the emulation function */ _fex = ((int (*)(struct pt_regs *, int, int, int)) jump_table[opcode[1]]) (regs, opcode[3] >> 4, opcode[3] & 15, opcode[2] >> 4); break; case 11: /* RRF format, cfdbr instruction */ if ((opcode[2] & 128) == 128 || (opcode[2] & 96) == 32) /* mask of { 2,3,8-15 } is invalid */ return SIGILL; emu_store_regd(opcode[3] & 15); /* call the emulation function */ _fex = ((int (*)(struct pt_regs *, int, int, int)) jump_table[opcode[1]]) (regs, opcode[3] >> 4, opcode[3] & 15, opcode[2] >> 4); break; case 12: /* RRF format, cfebr instruction */ if ((opcode[2] & 128) == 128 || (opcode[2] & 96) == 32) /* mask of { 2,3,8-15 } is invalid */ return SIGILL; emu_store_rege(opcode[3] & 15); /* call the emulation function */ _fex = ((int (*)(struct pt_regs *, int, int, int)) jump_table[opcode[1]]) (regs, opcode[3] >> 4, opcode[3] & 15, opcode[2] >> 4); break; case 13: /* RRE format, ldxbr & mdxbr instruction */ /* double store but long double load */ if (opcode[3] & 0x20) return SIGILL; emu_store_regd((opcode[3] >> 4) & 15); emu_store_regd(opcode[3] & 15); /* call the emulation function */ _fex = ((int (*)(struct pt_regs *, int, int)) jump_table[opcode[1]]) (regs, opcode[3] >> 4, opcode[3] & 15); emu_load_regd((opcode[3] >> 4) & 15); emu_load_regd(((opcode[3] >> 4) & 15) + 2); break; case 14: /* RRE format, ldxbr & mdxbr instruction */ /* float store but long double load */ if (opcode[3] & 0x20) return SIGILL; emu_store_rege((opcode[3] >> 4) & 15); emu_store_rege(opcode[3] & 15); /* call the emulation function */ _fex = ((int (*)(struct pt_regs *, int, int)) jump_table[opcode[1]]) (regs, opcode[3] >> 4, opcode[3] & 15); emu_load_regd((opcode[3] >> 4) & 15); emu_load_regd(((opcode[3] >> 4) & 15) + 2); break; case 15: /* 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 */ _fex = ((int (*)(struct pt_regs *, int, int)) jump_table[opcode[1]]) (regs, opcode[3] >> 4, opcode[3] & 15); emu_load_regd((opcode[3] >> 4) & 15); break; case 16: /* RRE format, ldxbr instruction */ /* long double store but double load */ if (opcode[3] & 2) return SIGILL; emu_store_regd(opcode[3] & 15); emu_store_regd((opcode[3] & 15) + 2); /* call the emulation function */ _fex = ((int (*)(struct pt_regs *, int, int)) jump_table[opcode[1]]) (regs, opcode[3] >> 4, opcode[3] & 15); emu_load_regd((opcode[3] >> 4) & 15); break; case 17: /* RRE format, ldxbr instruction */ /* long double store but float load */ if (opcode[3] & 2) return SIGILL; emu_store_regd(opcode[3] & 15); emu_store_regd((opcode[3] & 15) + 2); /* call the emulation function */ _fex = ((int (*)(struct pt_regs *, int, int)) jump_table[opcode[1]]) (regs, opcode[3] >> 4, opcode[3] & 15); emu_load_rege((opcode[3] >> 4) & 15); break; case 18: /* RRE format, ledbr instruction */ /* double store but float load */ emu_store_regd(opcode[3] & 15); /* call the emulation function */ _fex = ((int (*)(struct pt_regs *, int, int)) jump_table[opcode[1]]) (regs, opcode[3] >> 4, opcode[3] & 15); emu_load_rege((opcode[3] >> 4) & 15); break; case 19: /* RRE format, efpc & sfpc instruction */ /* call the emulation function */ _fex = ((int (*)(struct pt_regs *, int, int)) jump_table[opcode[1]]) (regs, opcode[3] >> 4, opcode[3] & 15); break; default: /* invalid operation */ return SIGILL; } if (_fex != 0) { current->thread.fp_regs.fpc |= _fex; if (current->thread.fp_regs.fpc & (_fex << 8)) return SIGFPE; } return 0;}static void* calc_addr(struct pt_regs *regs, int rx, int rb, int disp){ addr_t addr; rx &= 15; rb &= 15; addr = disp & 0xfff; addr += (rx != 0) ? regs->gprs[rx] : 0; /* + index */ addr += (rb != 0) ? regs->gprs[rb] : 0; /* + base */ return (void*) addr;} int math_emu_ed(__u8 *opcode, struct pt_regs * regs) { int _fex = 0; static const __u8 format_table[256] = { [0x04] = 0x06,[0x05] = 0x05,[0x06] = 0x07,[0x07] = 0x05, [0x08] = 0x02,[0x09] = 0x02,[0x0a] = 0x02,[0x0b] = 0x02, [0x0c] = 0x06,[0x0d] = 0x02,[0x0e] = 0x04,[0x0f] = 0x04, [0x10] = 0x08,[0x11] = 0x09,[0x12] = 0x0a,[0x14] = 0x02, [0x15] = 0x01,[0x17] = 0x02,[0x18] = 0x01,[0x19] = 0x01, [0x1a] = 0x01,[0x1b] = 0x01,[0x1c] = 0x01,[0x1d] = 0x01, [0x1e] = 0x03,[0x1f] = 0x03, }; static const void *jump_table[]= { [0x04] = emu_ldeb,[0x05] = emu_lxdb,[0x06] = emu_lxeb, [0x07] = emu_mxdb,[0x08] = emu_keb, [0x09] = emu_ceb, [0x0a] = emu_aeb, [0x0b] = emu_seb, [0x0c] = emu_mdeb, [0x0d] = emu_deb, [0x0e] = emu_maeb,[0x0f] = emu_mseb, [0x10] = emu_tceb,[0x11] = emu_tcdb,[0x12] = emu_tcxb, [0x14] = emu_sqeb,[0x15] = emu_sqdb,[0x17] = emu_meeb, [0x18] = emu_kdb, [0x19] = emu_cdb, [0x1a] = emu_adb, [0x1b] = emu_sdb, [0x1c] = emu_mdb, [0x1d] = emu_ddb, [0x1e] = emu_madb,[0x1f] = emu_msdb }; switch (format_table[opcode[5]]) { case 1: /* RXE format, double 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); mathemu_copy_from_user(&temp, dxb, 8); /* call the emulation function */ _fex = ((int (*)(struct pt_regs *, int, double *)) jump_table[opcode[5]]) (regs, opcode[1] >> 4, (double *) &temp); emu_load_regd((opcode[1] >> 4) & 15); break; } case 2: /* RXE format, float 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); mathemu_get_user(temp, dxb); /* call the emulation function */ _fex = ((int (*)(struct pt_regs *, int, float *)) jump_table[opcode[5]]) (regs, opcode[1] >> 4, (float *) &temp); emu_load_rege((opcode[1] >> 4) & 15); break; } case 3: /* RXF format, double constant */ { __u64 *dxb, temp; __u32 opc; emu_store_regd((opcode[1] >> 4) & 15); emu_store_regd((opcode[4] >> 4) & 15); opc = *((__u32 *) opcode); dxb = (__u64 *) calc_addr(regs, opc >> 16, opc >> 12, opc); mathemu_copy_from_user(&temp, dxb, 8); /* call the emulation function */ _fex = ((int (*)(struct pt_regs *, int, double *, int)) jump_table[opcode[5]]) (regs, opcode[1] >> 4, (double *) &temp, opcode[4] >> 4); emu_load_regd((opcode[1] >> 4) & 15); break; } case 4: /* RXF format, float constant */ { __u32 *dxb, temp; __u32 opc; emu_store_rege((opcode
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -