removed fpu reentrant checking (we are know that FPU is not reentrant)

fixed code duplication in fpu_tags.c
This commit is contained in:
Stanislav Shwartsman 2004-02-11 19:40:25 +00:00
parent 292c271034
commit 8e88595465
5 changed files with 28 additions and 155 deletions

View File

@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------+
| errors.c |
| $Id: errors.c,v 1.16 2004-02-06 22:27:59 danielg4 Exp $
| $Id: errors.c,v 1.17 2004-02-11 19:40:25 sshwarts Exp $
| |
| The error handling functions for wm-FPU-emu |
| |
@ -99,9 +99,6 @@ printk(" CW: ic=%d rc=%ld%ld pc=%ld%ld iem=%d ef=%d%d%d%d%d%d\n",
}
printk("%s\n", tag_desc[(int) (unsigned) tagi]);
}
RE_ENTRANT_CHECK_ON;
}
#endif

View File

@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------+
| fpu_emu.h |
| $Id: fpu_emu.h,v 1.21 2004-02-10 00:23:12 danielg4 Exp $
| $Id: fpu_emu.h,v 1.22 2004-02-11 19:40:25 sshwarts Exp $
| |
| Copyright (C) 1992,1993,1994,1997 |
| W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
@ -64,19 +64,6 @@
#include "fpu_system.h"
/*
#define RE_ENTRANT_CHECKING
*/
#ifdef RE_ENTRANT_CHECKING
extern u_char emulating;
# define RE_ENTRANT_CHECK_OFF emulating = 0
# define RE_ENTRANT_CHECK_ON emulating = 1
#else
# define RE_ENTRANT_CHECK_OFF
# define RE_ENTRANT_CHECK_ON
#endif /* ifdef RE_ENTRANT_CHECKING */
#define FWAIT_OPCODE 0x9b
#define OP_SIZE_PREFIX 0x66
#define ADDR_SIZE_PREFIX 0x67

View File

@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------+
| fpu_tags.c |
| $Id: fpu_tags.c,v 1.6 2003-08-07 18:54:03 sshwarts Exp $
| $Id: fpu_tags.c,v 1.7 2004-02-11 19:40:25 sshwarts Exp $
| |
| Set FPU register tags. |
| |
@ -15,65 +15,45 @@
#include "fpu_system.h"
#include "exception.h"
void FPU_pop(void)
{
FPU_tag_word |= 3 << ((FPU_tos & 7)*2);
FPU_tos++;
}
int FPU_gettag0(void)
{
return (FPU_tag_word >> ((FPU_tos & 7)*2)) & 3;
return FPU_gettag(FPU_tos);
}
int BX_CPP_AttrRegparmN(1)
FPU_gettagi(int stnr)
int BX_CPP_AttrRegparmN(1) FPU_gettagi(int stnr)
{
return (FPU_tag_word >> (((FPU_tos+stnr) & 7)*2)) & 3;
return FPU_gettag(FPU_tos+stnr);
}
int BX_CPP_AttrRegparmN(1)
FPU_gettag(int regnr)
int BX_CPP_AttrRegparmN(1) FPU_gettag(int regnr)
{
return (FPU_tag_word >> ((regnr & 7)*2)) & 3;
}
void BX_CPP_AttrRegparmN(1)
FPU_settag0(int tag)
void BX_CPP_AttrRegparmN(1) FPU_settag0(int tag)
{
int regnr = FPU_tos;
regnr &= 7;
FPU_tag_word &= ~(3 << (regnr*2));
FPU_tag_word |= (tag & 3) << (regnr*2);
FPU_settag(FPU_tos, tag);
}
void BX_CPP_AttrRegparmN(2)
FPU_settagi(int stnr, int tag)
void BX_CPP_AttrRegparmN(2) FPU_settagi(int stnr, int tag)
{
int regnr = stnr+FPU_tos;
regnr &= 7;
FPU_tag_word &= ~(3 << (regnr*2));
FPU_tag_word |= (tag & 3) << (regnr*2);
FPU_settag(stnr+FPU_tos, tag);
}
void BX_CPP_AttrRegparmN(2)
FPU_settag(int regnr, int tag)
void BX_CPP_AttrRegparmN(2) FPU_settag(int regnr, int tag)
{
regnr &= 7;
FPU_tag_word &= ~(3 << (regnr*2));
FPU_tag_word |= (tag & 3) << (regnr*2);
}
int BX_CPP_AttrRegparmN(1)
FPU_Special(FPU_REG const *ptr)
int BX_CPP_AttrRegparmN(1) FPU_Special(FPU_REG const *ptr)
{
int exp = exponent(ptr);
@ -86,48 +66,36 @@ FPU_Special(FPU_REG const *ptr)
return TW_NaN;
}
int BX_CPP_AttrRegparmN(1)
isNaN(FPU_REG const *ptr)
int BX_CPP_AttrRegparmN(1) isNaN(FPU_REG const *ptr)
{
return ( (exponent(ptr) == EXP_BIAS+EXP_OVER)
&& !((ptr->sigh == 0x80000000) && (ptr->sigl == 0)) );
return ((exponent(ptr) == EXP_BIAS+EXP_OVER)
&& !((ptr->sigh == 0x80000000) && (ptr->sigl == 0)));
}
int BX_CPP_AttrRegparmN(1)
FPU_empty_i(int stnr)
int BX_CPP_AttrRegparmN(1) FPU_empty_i(int stnr)
{
int regnr = (FPU_tos+stnr) & 7;
return ((FPU_tag_word >> (regnr*2)) & 3) == TAG_Empty;
return FPU_gettagi(stnr) == TAG_Empty;
}
int FPU_stackoverflow(FPU_REG **st_new_ptr)
{
*st_new_ptr = &st(-1);
return ((FPU_tag_word >> (((FPU_tos - 1) & 7)*2)) & 3) != TAG_Empty;
}
void BX_CPP_AttrRegparmN(3)
FPU_copy_to_regi(FPU_REG const *r, u_char tag, int stnr)
void BX_CPP_AttrRegparmN(3) FPU_copy_to_regi(FPU_REG const *r, u_char tag, int stnr)
{
reg_copy(r, &st(stnr));
FPU_settagi(stnr, tag);
}
void BX_CPP_AttrRegparmN(2)
FPU_copy_to_reg1(FPU_REG const *r, u_char tag)
void BX_CPP_AttrRegparmN(2) FPU_copy_to_reg1(FPU_REG const *r, u_char tag)
{
reg_copy(r, &st(1));
FPU_settagi(1, tag);
}
void BX_CPP_AttrRegparmN(2)
FPU_copy_to_reg0(FPU_REG const *r, u_char tag)
void BX_CPP_AttrRegparmN(2) FPU_copy_to_reg0(FPU_REG const *r, u_char tag)
{
reg_copy(r, &st(0));
FPU_settagi(0, tag);

View File

@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------+
| load_store.c |
| $Id: load_store.c,v 1.12 2003-10-04 12:32:56 sshwarts Exp $
| $Id: load_store.c,v 1.13 2004-02-11 19:40:25 sshwarts Exp $
| |
| This file contains most of the code to interpret the FPU instructions |
| which load and store from user memory. |
@ -174,10 +174,8 @@ int FPU_load_store(u_char type, fpu_addr_modes addr_modes,
FPU_settag0(loaded_tag);
break;
case 024: /* fldcw */
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_READ, data_address, 2);
FPU_get_user(FPU_control_word, data_address, 2);
RE_ENTRANT_CHECK_ON;
if ( FPU_partial_status & ~FPU_control_word & CW_Exceptions )
FPU_partial_status |= (SW_Summary | SW_Backward);
else
@ -209,10 +207,8 @@ int FPU_load_store(u_char type, fpu_addr_modes addr_modes,
(see the 80486 manual p16-28) */
break;
case 034: /* fstcw m16int */
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,data_address,2);
FPU_put_user(FPU_control_word, data_address, 2);
RE_ENTRANT_CHECK_ON;
return 1;
case 035: /* fstp m80real */
clear_C1();
@ -221,10 +217,8 @@ int FPU_load_store(u_char type, fpu_addr_modes addr_modes,
(see the 80486 manual p16-28) */
break;
case 036: /* fstsw m2byte */
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,data_address,2);
FPU_put_user(status_word(),data_address, 2);
RE_ENTRANT_CHECK_ON;
return 1;
case 037: /* fistp m64int */
clear_C1();

View File

@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------+
| reg_ld_str.c |
| $Id: reg_ld_str.c,v 1.18 2003-10-25 10:32:54 sshwarts Exp $
| $Id: reg_ld_str.c,v 1.19 2004-02-11 19:40:25 sshwarts Exp $
| |
| All of the functions which transfer data between user memory and FPU_REGs.|
| |
@ -96,17 +96,14 @@ FPU_load_extended(bx_address s, int stnr)
{
FPU_REG *sti_ptr = &st(stnr);
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_READ, s, 10);
FPU_get_user(sti_ptr->sigl, s+0, 4);
FPU_get_user(sti_ptr->sigh, s+4, 4);
FPU_get_user(sti_ptr->exp, s+8, 2);
RE_ENTRANT_CHECK_ON;
return FPU_tagof(sti_ptr);
}
/* Get a double from user memory */
int BX_CPP_AttrRegparmN(2)
FPU_load_double(bx_address dfloat, FPU_REG *loaded_data)
@ -114,11 +111,9 @@ FPU_load_double(bx_address dfloat, FPU_REG *loaded_data)
int exp, tag, negative;
u32 m64, l64;
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_READ, dfloat, 8);
FPU_get_user(m64, dfloat+4, 4);
FPU_get_user(l64, dfloat, 4);
RE_ENTRANT_CHECK_ON;
negative = (m64 & 0x80000000) ? SIGN_Negative : SIGN_Positive;
exp = ((m64 & 0x7ff00000) >> 20) - DOUBLE_Ebias + EXTENDED_Ebias;
@ -187,10 +182,8 @@ FPU_load_single(bx_address single, FPU_REG *loaded_data)
u32 m32;
int exp, tag, negative;
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_READ, single, 4);
FPU_get_user(m32, single, 4);
RE_ENTRANT_CHECK_ON;
negative = (m32 & 0x80000000) ? SIGN_Negative : SIGN_Positive;
@ -253,16 +246,14 @@ FPU_load_int64(bx_address _s)
int sign;
FPU_REG *st0_ptr = &st(0);
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_READ, _s, 8);
{
u32 chunk0, chunk1;
FPU_get_user(chunk0, _s+0, 4);
FPU_get_user(chunk1, _s+4, 4);
s = chunk0;
s |= (((u64)chunk1) << 32);
u32 chunk0, chunk1;
FPU_get_user(chunk0, _s+0, 4);
FPU_get_user(chunk1, _s+4, 4);
s = chunk0;
s |= (((u64)chunk1) << 32);
}
RE_ENTRANT_CHECK_ON;
if (s == 0)
{
@ -291,10 +282,8 @@ FPU_load_int32(bx_address _s, FPU_REG *loaded_data)
s32 s;
int negative;
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_READ, _s, 4);
FPU_get_user(s, _s, 4);
RE_ENTRANT_CHECK_ON;
if (s == 0)
{ reg_copy(&CONST_Z, loaded_data); return TAG_Zero; }
@ -320,11 +309,9 @@ FPU_load_int16(bx_address _s, FPU_REG *loaded_data)
{
s16 s, negative;
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_READ, _s, 2);
/* Cast as short to get the sign extended. */
FPU_get_user(s, _s, 2);
RE_ENTRANT_CHECK_ON;
if (s == 0)
{ reg_copy(&CONST_Z, loaded_data); return TAG_Zero; }
@ -354,24 +341,18 @@ FPU_load_bcd(bx_address s)
s64 l=0;
int sign;
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_READ, s, 10);
RE_ENTRANT_CHECK_ON;
for (pos = 8; pos >= 0; pos--)
{
l *= 10;
RE_ENTRANT_CHECK_OFF;
FPU_get_user(bcd, s+pos, 1);
RE_ENTRANT_CHECK_ON;
l += bcd >> 4;
l *= 10;
l += bcd & 0x0f;
}
RE_ENTRANT_CHECK_OFF;
FPU_get_user(sign, s+9, 1);
sign = sign & 0x80 ? SIGN_Negative : SIGN_Positive;
RE_ENTRANT_CHECK_ON;
if (l == 0)
{
@ -400,14 +381,10 @@ FPU_store_extended(FPU_REG *st0_ptr, u_char st0_tag, bx_address d)
if (st0_tag != TAG_Empty)
{
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE, d, 10);
FPU_put_user(st0_ptr->sigl, d, 4);
FPU_put_user(st0_ptr->sigh, d + 4, 4);
FPU_put_user(exponent16(st0_ptr), d + 8, 2);
RE_ENTRANT_CHECK_ON;
return 1;
}
@ -417,12 +394,10 @@ FPU_store_extended(FPU_REG *st0_ptr, u_char st0_tag, bx_address d)
{
/* The masked response */
/* Put out the QNaN indefinite */
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,d,10);
FPU_put_user(0, d, 4);
FPU_put_user(0xc0000000, d + 4, 4);
FPU_put_user(0xffff, d + 8, 2);
RE_ENTRANT_CHECK_ON;
return 1;
}
else
@ -647,11 +622,9 @@ FPU_store_double(FPU_REG *st0_ptr, u_char st0_tag, bx_address dfloat)
{
/* The masked response */
/* Put out the QNaN indefinite */
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,dfloat,8);
FPU_put_user(0, dfloat, 4);
FPU_put_user(0xfff80000, dfloat+4, 4);
RE_ENTRANT_CHECK_ON;
return 1;
}
else
@ -660,16 +633,12 @@ FPU_store_double(FPU_REG *st0_ptr, u_char st0_tag, bx_address dfloat)
if (getsign(st0_ptr))
l[1] |= 0x80000000;
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,dfloat,8);
FPU_put_user(l[0], dfloat, 4);
FPU_put_user(l[1], dfloat+4, 4);
RE_ENTRANT_CHECK_ON;
return 1;
}
/* Put a float into user memory */
int BX_CPP_AttrRegparmN(3)
FPU_store_single(FPU_REG *st0_ptr, u_char st0_tag, bx_address single)
@ -875,10 +844,8 @@ FPU_store_single(FPU_REG *st0_ptr, u_char st0_tag, bx_address single)
{
/* The masked response */
/* Put out the QNaN indefinite */
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,single,4);
FPU_put_user(0xffc00000, single, 4);
RE_ENTRANT_CHECK_ON;
return 1;
}
else
@ -894,15 +861,11 @@ FPU_store_single(FPU_REG *st0_ptr, u_char st0_tag, bx_address single)
if (getsign(st0_ptr))
templ |= 0x80000000;
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,single,4);
FPU_put_user(templ,single, 4);
RE_ENTRANT_CHECK_ON;
return 1;
}
/* Put a 64bit quantity into user memory */
int BX_CPP_AttrRegparmN(3)
FPU_store_int64(FPU_REG *st0_ptr, u_char st0_tag, bx_address d)
@ -961,16 +924,12 @@ FPU_store_int64(FPU_REG *st0_ptr, u_char st0_tag, bx_address d)
tll = -tll;
}
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,d,8);
FPU_put_user((u32) tll, d+0, 4);
FPU_put_user((u32) (tll>>32), d+4, 4);
RE_ENTRANT_CHECK_ON;
return 1;
}
/* Put a long into user memory */
int BX_CPP_AttrRegparmN(3)
FPU_store_int32(FPU_REG *st0_ptr, u_char st0_tag, bx_address d)
@ -1020,15 +979,11 @@ FPU_store_int32(FPU_REG *st0_ptr, u_char st0_tag, bx_address d)
t.sigl = -(s32)t.sigl;
}
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,d,4);
FPU_put_user(t.sigl, d, 4);
RE_ENTRANT_CHECK_ON;
return 1;
}
/* Put a short into user memory */
int BX_CPP_AttrRegparmN(3)
FPU_store_int16(FPU_REG *st0_ptr, u_char st0_tag, bx_address d)
@ -1078,15 +1033,11 @@ FPU_store_int16(FPU_REG *st0_ptr, u_char st0_tag, bx_address d)
t.sigl = -t.sigl;
}
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,d,2);
FPU_put_user((s16)t.sigl,d,2);
RE_ENTRANT_CHECK_ON;
return 1;
}
/* Put a packed bcd array into user memory */
int BX_CPP_AttrRegparmN(3)
FPU_store_bcd(FPU_REG *st0_ptr, u_char st0_tag, bx_address d)
@ -1128,14 +1079,12 @@ FPU_store_bcd(FPU_REG *st0_ptr, u_char st0_tag, bx_address d)
if (FPU_control_word & CW_Invalid)
{
/* Produce the QNaN "indefinite" */
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,d,10);
for ( i = 0; i < 7; i++)
FPU_put_user(0, d+i,1); /* These bytes "undefined" */
FPU_put_user(0xc0, d+7,1); /* This byte "undefined" */
FPU_put_user(0xff, d+8,1);
FPU_put_user(0xff, d+9,1);
RE_ENTRANT_CHECK_ON;
return 1;
}
else
@ -1147,20 +1096,14 @@ FPU_store_bcd(FPU_REG *st0_ptr, u_char st0_tag, bx_address d)
set_precision_flag(precision_loss);
}
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,d,10);
RE_ENTRANT_CHECK_ON;
for (i = 0; i < 9; i++)
{
b = FPU_div_small(&ll, 10);
b |= (FPU_div_small(&ll, 10)) << 4;
RE_ENTRANT_CHECK_OFF;
FPU_put_user(b,d+i,1);
RE_ENTRANT_CHECK_ON;
}
RE_ENTRANT_CHECK_OFF;
FPU_put_user(sign,d+9,1);
RE_ENTRANT_CHECK_ON;
return 1;
}
@ -1250,7 +1193,6 @@ fldenv(fpu_addr_modes addr_modes, bx_address s)
((addr_modes.default_mode == PM16)
^ (addr_modes.override.operand_size == OP_SIZE_PREFIX)))
{
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_READ, s, 0x0e);
FPU_get_user(FPU_control_word, s, 2);
FPU_get_user(FPU_partial_status, (s+2), 2);
@ -1259,7 +1201,6 @@ fldenv(fpu_addr_modes addr_modes, bx_address s)
FPU_get_user(FPU_instruction_address.selector, (s+8), 2);
FPU_get_user(FPU_operand_address.offset, (s+0x0a), 2);
FPU_get_user(FPU_operand_address.selector, (s+0x0c), 2);
RE_ENTRANT_CHECK_ON;
s += 0x0e;
if (addr_modes.default_mode == VM86)
{
@ -1270,7 +1211,6 @@ fldenv(fpu_addr_modes addr_modes, bx_address s)
}
else
{
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_READ, s, 0x1c);
FPU_get_user(FPU_control_word, s, 2);
FPU_get_user(FPU_partial_status, (s+4), 2);
@ -1280,7 +1220,6 @@ fldenv(fpu_addr_modes addr_modes, bx_address s)
FPU_get_user(FPU_instruction_address.opcode, (s+0x12), 2);
FPU_get_user(FPU_operand_address.offset, (s+0x14), 4);
FPU_get_user(FPU_operand_address.selector, (s+0x18), 4);
RE_ENTRANT_CHECK_ON;
s += 0x1c;
}
@ -1339,7 +1278,6 @@ frstor(fpu_addr_modes addr_modes, bx_address data_address)
int offset = (FPU_tos & 7) * sizeof(FPU_REG), other = 8*sizeof(FPU_REG) - offset;
/* Copy all registers in stack order. */
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_READ,s,80);
{
FPU_REG *fpu_reg_p;
@ -1363,7 +1301,6 @@ frstor(fpu_addr_modes addr_modes, bx_address data_address)
offset -= sizeof(FPU_REG);
}
}
RE_ENTRANT_CHECK_ON;
for (i = 0; i < 8; i++)
{
@ -1372,10 +1309,8 @@ frstor(fpu_addr_modes addr_modes, bx_address data_address)
/* The loaded data over-rides all other cases. */
FPU_settag(regnr, FPU_tagof(&st(i)));
}
}
bx_address BX_CPP_AttrRegparmN(2)
fstenv(fpu_addr_modes addr_modes, bx_address d)
{
@ -1383,7 +1318,6 @@ fstenv(fpu_addr_modes addr_modes, bx_address d)
((addr_modes.default_mode == PM16)
^ (addr_modes.override.operand_size == OP_SIZE_PREFIX)))
{
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,d,14);
#ifdef PECULIAR_486
FPU_put_user(FPU_control_word & ~0xe080, d, 4);
@ -1406,12 +1340,10 @@ fstenv(fpu_addr_modes addr_modes, bx_address d)
FPU_put_user(FPU_instruction_address.selector, (d+8), 2);
FPU_put_user(FPU_operand_address.selector, (d+0x0c), 2);
}
RE_ENTRANT_CHECK_ON;
d += 0x0e;
}
else
{
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE, d, 7*4);
#ifdef PECULIAR_486
FPU_control_word &= ~0xe080;
@ -1429,7 +1361,6 @@ fstenv(fpu_addr_modes addr_modes, bx_address d)
FPU_put_user((u32) i387.fcs, d+16, 4);
FPU_put_user((u32) i387.foo, d+20, 4);
FPU_put_user((u32) i387.fos, d+24, 4);
RE_ENTRANT_CHECK_ON;
d += 0x1c;
}
@ -1448,7 +1379,6 @@ fsave(fpu_addr_modes addr_modes, bx_address data_address)
d = fstenv(addr_modes, data_address);
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,d,80);
/* Copy all registers in stack order. */
@ -1474,9 +1404,6 @@ fsave(fpu_addr_modes addr_modes, bx_address data_address)
offset -= sizeof(FPU_REG);
}
}
RE_ENTRANT_CHECK_ON;
finit();
}
/*===========================================================================*/