home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
vol_300
/
359_11
/
patch5.000
/
EMU387
/
E16.CC
< prev
next >
Wrap
C/C++ Source or Header
|
1991-09-11
|
3KB
|
194 lines
#include "emu.h"
#include "rmov.h"
#include "const.h"
#include "compare.h"
void f2xm1()
{
if (empty())
return;
reg xloga, val, rv, bottom, tmp;
long i;
r_mul(CONST_LN2, st(), xloga);
r_mov(xloga, val);
r_mov(xloga, rv);
for (i=2; i<16; i++)
{
r_mov(&i, bottom);
r_mul(val, xloga, tmp);
r_div(tmp, bottom, val);
r_add(val, rv, tmp);
r_mov(tmp, rv);
}
r_mov(rv, st());
}
// logb(x) = loga(x) / loga(b)
// log2(x) = loge(x) / loge(2)
void fyl2x()
{
if (empty())
return;
reg frac2, sum, div, term, pow, temp;
r_sub(st(), CONST_1, frac2);
r_add(st(), CONST_1, div);
r_div(frac2, div, sum);
r_mul(sum, sum, frac2);
r_mul(sum, st(1), pow);
for (long i=3; i<15; i+=2)
{
r_mul(pow, frac2, temp);
r_mov(temp, pow);
r_mov(&i, div);
r_div(temp, div, term);
r_add(term, sum, temp);
r_mov(temp, sum);
}
r_div(sum, CONST_LN2, temp);
temp.exp++;
r_mov(temp, st(1));
st().tag = TW_E;
top++;
}
void fptan()
{
extern void fsincos();
fsincos();
if (empty(1))
return;
reg tmp;
r_div(st(1), st(), tmp);
r_mov(tmp, st(1));
r_mov(CONST_1, st());
}
void fpatan()
{
if (empty(1))
return;
if (mag_same(st(), CONST_Z))
{
r_mov(CONST_PI2, st(1));
st().tag = TW_E;
top++;
return;
}
if (mag_same(st(1), CONST_Z))
{
r_mov(CONST_Z, st(1));
st().tag = TW_E;
top++;
return;
}
reg x2, sum, term, pow, temp;
int quadrant = 0;
if (st(1).sign == SIGN_NEG)
quadrant |= 1;
if (st(0).sign == SIGN_NEG)
quadrant |= 2;
st(1).sign = st().sign = SIGN_POS;
if (compare(st(1), st()) == COMP_A_GT_B)
{
quadrant |= 4;
r_mov(st(1), temp);
r_mov(st(), st(1));
r_mov(temp, st());
}
r_div(st(1), st(), sum);
r_mul(sum, sum, x2);
r_mov(sum, pow);
x2.sign ^= SIGN_POS^SIGN_NEG;
for (long i=3; i<25; i+=2)
{
r_mul(pow, x2, temp);
r_mov(temp, pow);
r_mov(&i, temp);
r_div(pow, temp, term);
r_add(sum, term, temp);
r_mov(temp, sum);
}
if (quadrant & 4)
{
r_sub(CONST_PI2, sum, temp);
r_mov(temp, sum);
}
if (quadrant & 2)
{
r_sub(CONST_PI, sum, temp);
r_mov(temp, sum);
}
if (quadrant & 1)
sum.sign ^= SIGN_POS^SIGN_NEG;
r_mov(sum, st(1));
st().tag = TW_E;
top++;
}
void fxtract()
{
if (empty())
return;
if (full())
return;
top--;
r_mov(st(1), st());
st().exp = EXP_BIAS;
long e = st(1).exp - EXP_BIAS;
r_mov(&e, st(1));
}
extern int fprem_do(reg&,reg&,int);
void fprem1()
{
if (empty(1))
return;
int q = fprem_do(st(), st(1), RC_RND);
if (q == -1)
setcc(SW_C2);
else
{
int c = 0;
if (q&4) c |= SW_C3;
if (q&2) c |= SW_C1;
if (q&1) c |= SW_C0;
setcc(c);
}
}
void fdecstp()
{
top--;
}
void fincstp()
{
top++;
}
FUNC emu_16_table[] = {
f2xm1, fyl2x, fptan, fpatan, fxtract, fprem1, fdecstp, fincstp
};
void emu_16()
{
if (modrm > 0277)
{
(emu_16_table[modrm&7])();
}
else
{
emu_bad();
}
}