#include "emu.h" #include "rmov.h" extern "C" void shld(void *); extern "C" void shrd(void *); void fsqrt() { if (empty()) return; if (st().tag == TW_Z) return; if (st().exp == EXP_MAX) return; if (st().sign == SIGN_NEG) return exception(EX_I); unsigned long long val = *(unsigned long long *)(&st().sigl); unsigned long long result = 0; unsigned long long side = 0; unsigned long long left = 0; int digit = 0; int i; if (st().exp & 1) { shrd(&val); st().exp++; } int exp = (st().exp - EXP_BIAS - 1)/2 - 64; while (!(((long *)&result)[1] & 0x80000000)) { left = (left << 2) + (val >> 62); shld(&val); shld(&val); if (left >= side*2 + 1) { left -= side*2+1; side = (side+1)*2; shld(&result); result |= 1; } else { side *= 2; shld(&result); } exp++; } st().exp = exp + EXP_BIAS; st().sigl = result & 0xffffffff; st().sigh = result >> 32; st().tag = TW_V; } void frndint() { if (empty()) return; long long tmp; if (st().exp > EXP_BIAS+62) return; r_mov(st(), &tmp); r_mov(&tmp, st()); } FUNC emu_17_table[] = { emu_bad, emu_bad, fsqrt, emu_bad, frndint, emu_bad, emu_bad, emu_bad }; void emu_17() { if (modrm > 0277) { (emu_17_table[modrm&7])(); } else { // fstcw m16int *(short *)get_modrm() = control_word; } }