patch-2.1.73 linux/arch/i386/math-emu/load_store.c
Next file: linux/arch/i386/math-emu/poly_2xm1.c
Previous file: linux/arch/i386/math-emu/get_address.c
Back to the patch index
Back to the overall index
- Lines: 251
- Date:
Tue Dec 9 17:57:09 1997
- Orig file:
v2.1.72/linux/arch/i386/math-emu/load_store.c
- Orig date:
Mon Oct 28 04:41:15 1996
diff -u --recursive --new-file v2.1.72/linux/arch/i386/math-emu/load_store.c linux/arch/i386/math-emu/load_store.c
@@ -4,9 +4,9 @@
| This file contains most of the code to interpret the FPU instructions |
| which load and store from user memory. |
| |
- | Copyright (C) 1992,1993,1994 |
+ | Copyright (C) 1992,1993,1994,1997 |
| W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
- | Australia. E-mail billm@vaxc.cc.monash.edu.au |
+ | Australia. E-mail billm@suburbia.net |
| |
| |
+---------------------------------------------------------------------------*/
@@ -32,10 +32,10 @@
#define _PUSH_ 3 /* Need to check for space to push onto stack */
#define _null_ 4 /* Function illegal or not implemented */
-#define pop_0() { st0_ptr->tag = TW_Empty; top++; }
+#define pop_0() { FPU_settag0(TAG_Empty); top++; }
-static unsigned char const type_table[32] = {
+static u_char const type_table[32] = {
_PUSH_, _PUSH_, _PUSH_, _PUSH_,
_null_, _null_, _null_, _null_,
_REG0_, _REG0_, _REG0_, _REG0_,
@@ -46,25 +46,27 @@
_NONE_, _REG0_, _NONE_, _REG0_
};
-unsigned char const data_sizes_16[32] = {
+u_char const data_sizes_16[32] = {
4, 4, 8, 2, 0, 0, 0, 0,
4, 4, 8, 2, 4, 4, 8, 2,
14, 0, 94, 10, 2, 10, 0, 8,
14, 0, 94, 10, 2, 10, 2, 8
};
-unsigned char const data_sizes_32[32] = {
+u_char const data_sizes_32[32] = {
4, 4, 8, 2, 0, 0, 0, 0,
4, 4, 8, 2, 4, 4, 8, 2,
28, 0,108, 10, 2, 10, 0, 8,
28, 0,108, 10, 2, 10, 2, 8
};
-int load_store_instr(unsigned char type, fpu_addr_modes addr_modes,
+int FPU_load_store(u_char type, fpu_addr_modes addr_modes,
void *data_address)
{
FPU_REG loaded_data;
FPU_REG *st0_ptr;
+ u_char st0_tag = TAG_Empty; /* This is just to stop a gcc warning. */
+ u_char loaded_tag;
st0_ptr = NULL; /* Initialized just to stop compiler warnings. */
@@ -93,13 +95,14 @@
case _REG0_:
st0_ptr = &st(0); /* Some of these instructions pop after
storing */
+ st0_tag = FPU_gettag0();
break;
case _PUSH_:
{
- st0_ptr = &st(-1);
- if ( st0_ptr->tag != TW_Empty )
- { stack_overflow(); return 0; }
+ if ( FPU_gettagi(-1) != TAG_Empty )
+ { FPU_stack_overflow(); return 0; }
top--;
+ st0_ptr = &st(0);
}
break;
case _null_:
@@ -116,92 +119,97 @@
{
case 000: /* fld m32real */
clear_C1();
- reg_load_single((float *)data_address, &loaded_data);
- if ( (loaded_data.tag == TW_NaN) &&
- real_2op_NaN(&loaded_data, &loaded_data, &loaded_data) )
+ loaded_tag = FPU_load_single((float *)data_address, &loaded_data);
+ if ( (loaded_tag == TAG_Special)
+ && isNaN(&loaded_data)
+ && (real_1op_NaN(&loaded_data) < 0) )
{
top++;
break;
}
- reg_move(&loaded_data, st0_ptr);
+ FPU_copy_to_reg0(&loaded_data, loaded_tag);
break;
case 001: /* fild m32int */
clear_C1();
- reg_load_int32((long *)data_address, st0_ptr);
+ loaded_tag = FPU_load_int32((long *)data_address, &loaded_data);
+ FPU_copy_to_reg0(&loaded_data, loaded_tag);
break;
case 002: /* fld m64real */
clear_C1();
- reg_load_double((double *)data_address, &loaded_data);
- if ( (loaded_data.tag == TW_NaN) &&
- real_2op_NaN(&loaded_data, &loaded_data, &loaded_data) )
+ loaded_tag = FPU_load_double((double *)data_address, &loaded_data);
+ if ( (loaded_tag == TAG_Special)
+ && isNaN(&loaded_data)
+ && (real_1op_NaN(&loaded_data) < 0) )
{
top++;
break;
}
- reg_move(&loaded_data, st0_ptr);
+ FPU_copy_to_reg0(&loaded_data, loaded_tag);
break;
case 003: /* fild m16int */
clear_C1();
- reg_load_int16((short *)data_address, st0_ptr);
+ loaded_tag = FPU_load_int16((short *)data_address, &loaded_data);
+ FPU_copy_to_reg0(&loaded_data, loaded_tag);
break;
case 010: /* fst m32real */
clear_C1();
- reg_store_single((float *)data_address, st0_ptr);
+ FPU_store_single(st0_ptr, st0_tag, (float *)data_address);
break;
case 011: /* fist m32int */
clear_C1();
- reg_store_int32((long *)data_address, st0_ptr);
+ FPU_store_int32(st0_ptr, st0_tag, (long *)data_address);
break;
case 012: /* fst m64real */
clear_C1();
- reg_store_double((double *)data_address, st0_ptr);
+ FPU_store_double(st0_ptr, st0_tag, (double *)data_address);
break;
case 013: /* fist m16int */
clear_C1();
- reg_store_int16((short *)data_address, st0_ptr);
+ FPU_store_int16(st0_ptr, st0_tag, (short *)data_address);
break;
case 014: /* fstp m32real */
clear_C1();
- if ( reg_store_single((float *)data_address, st0_ptr) )
+ if ( FPU_store_single(st0_ptr, st0_tag, (float *)data_address) )
pop_0(); /* pop only if the number was actually stored
(see the 80486 manual p16-28) */
break;
case 015: /* fistp m32int */
clear_C1();
- if ( reg_store_int32((long *)data_address, st0_ptr) )
+ if ( FPU_store_int32(st0_ptr, st0_tag, (long *)data_address) )
pop_0(); /* pop only if the number was actually stored
(see the 80486 manual p16-28) */
break;
case 016: /* fstp m64real */
clear_C1();
- if ( reg_store_double((double *)data_address, st0_ptr) )
+ if ( FPU_store_double(st0_ptr, st0_tag, (double *)data_address) )
pop_0(); /* pop only if the number was actually stored
(see the 80486 manual p16-28) */
break;
case 017: /* fistp m16int */
clear_C1();
- if ( reg_store_int16((short *)data_address, st0_ptr) )
+ if ( FPU_store_int16(st0_ptr, st0_tag, (short *)data_address) )
pop_0(); /* pop only if the number was actually stored
(see the 80486 manual p16-28) */
break;
case 020: /* fldenv m14/28byte */
- fldenv(addr_modes, (char *)data_address);
+ fldenv(addr_modes, (u_char *)data_address);
/* Ensure that the values just loaded are not changed by
fix-up operations. */
return 1;
case 022: /* frstor m94/108byte */
- frstor(addr_modes, (char *)data_address);
+ frstor(addr_modes, (u_char *)data_address);
/* Ensure that the values just loaded are not changed by
fix-up operations. */
return 1;
case 023: /* fbld m80dec */
clear_C1();
- reg_load_bcd((char *)data_address, st0_ptr);
+ loaded_tag = FPU_load_bcd((u_char *)data_address);
+ FPU_settag0(loaded_tag);
break;
case 024: /* fldcw */
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_READ, data_address, 2);
- get_user(control_word, (unsigned short *) data_address);
+ FPU_get_user(control_word, (unsigned short *) data_address);
RE_ENTRANT_CHECK_ON;
if ( partial_status & ~control_word & CW_Exceptions )
partial_status |= (SW_Summary | SW_Backward);
@@ -213,45 +221,47 @@
return 1;
case 025: /* fld m80real */
clear_C1();
- reg_load_extended((long double *)data_address, st0_ptr);
+ loaded_tag = FPU_load_extended((long double *)data_address, 0);
+ FPU_settag0(loaded_tag);
break;
case 027: /* fild m64int */
clear_C1();
- reg_load_int64((long long *)data_address, st0_ptr);
+ loaded_tag = FPU_load_int64((long long *)data_address);
+ FPU_settag0(loaded_tag);
break;
case 030: /* fstenv m14/28byte */
- fstenv(addr_modes, (char *)data_address);
+ fstenv(addr_modes, (u_char *)data_address);
return 1;
case 032: /* fsave */
- fsave(addr_modes, (char *)data_address);
+ fsave(addr_modes, (u_char *)data_address);
return 1;
case 033: /* fbstp m80dec */
clear_C1();
- if ( reg_store_bcd((char *)data_address, st0_ptr) )
+ if ( FPU_store_bcd(st0_ptr, st0_tag, (u_char *)data_address) )
pop_0(); /* pop only if the number was actually stored
(see the 80486 manual p16-28) */
break;
case 034: /* fstcw m16int */
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,data_address,2);
- put_user(control_word, (unsigned short *) data_address);
+ FPU_put_user(control_word, (unsigned short *) data_address);
RE_ENTRANT_CHECK_ON;
return 1;
case 035: /* fstp m80real */
clear_C1();
- if ( reg_store_extended((long double *)data_address, st0_ptr) )
+ if ( FPU_store_extended(st0_ptr, st0_tag, (long double *)data_address) )
pop_0(); /* pop only if the number was actually stored
(see the 80486 manual p16-28) */
break;
case 036: /* fstsw m2byte */
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,data_address,2);
- put_user(status_word(),(unsigned short *) data_address);
+ FPU_put_user(status_word(),(unsigned short *) data_address);
RE_ENTRANT_CHECK_ON;
return 1;
case 037: /* fistp m64int */
clear_C1();
- if ( reg_store_int64((long long *)data_address, st0_ptr) )
+ if ( FPU_store_int64(st0_ptr, st0_tag, (long long *)data_address) )
pop_0(); /* pop only if the number was actually stored
(see the 80486 manual p16-28) */
break;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov