home *** CD-ROM | disk | FTP | other *** search
- #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;
- }
- }
-