patch-2.1.73 linux/arch/i386/math-emu/fpu_aux.c
Next file: linux/arch/i386/math-emu/fpu_emu.h
Previous file: linux/arch/i386/math-emu/fpu_asm.h
Back to the patch index
Back to the overall index
- Lines: 160
- Date:
Tue Dec 9 17:57:09 1997
- Orig file:
v2.1.72/linux/arch/i386/math-emu/fpu_aux.c
- Orig date:
Thu Jun 2 00:28:23 1994
diff -u --recursive --new-file v2.1.72/linux/arch/i386/math-emu/fpu_aux.c linux/arch/i386/math-emu/fpu_aux.c
@@ -3,9 +3,9 @@
| |
| Code to implement some of the FPU auxiliary instructions. |
| |
- | Copyright (C) 1992,1993,1994 |
- | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
- | Australia. E-mail billm@vaxc.cc.monash.edu.au |
+ | Copyright (C) 1992,1993,1994,1997 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ | E-mail billm@suburbia.net |
| |
| |
+---------------------------------------------------------------------------*/
@@ -32,15 +32,11 @@
/* Needs to be externally visible */
void finit()
{
- int r;
control_word = 0x037f;
partial_status = 0;
top = 0; /* We don't keep top in the status word internally. */
- for (r = 0; r < 8; r++)
- {
- regs[r].tag = TW_Empty;
- }
- /* The behaviour is different to that detailed in
+ fpu_tag_word = 0xffff;
+ /* The behaviour is different from that detailed in
Section 15.1.6 of the Intel manual */
operand_address.offset = 0;
operand_address.selector = 0;
@@ -99,19 +95,27 @@
void fld_i_()
{
FPU_REG *st_new_ptr;
+ int i;
+ u_char tag;
if ( STACK_OVERFLOW )
- { stack_overflow(); return; }
+ { FPU_stack_overflow(); return; }
/* fld st(i) */
- if ( NOT_EMPTY(FPU_rm) )
- { reg_move(&st(FPU_rm), st_new_ptr); push(); }
+ i = FPU_rm;
+ if ( NOT_EMPTY(i) )
+ {
+ reg_copy(&st(i), st_new_ptr);
+ tag = FPU_gettagi(i);
+ push();
+ FPU_settag0(tag);
+ }
else
{
if ( control_word & CW_Invalid )
{
/* The masked response */
- stack_underflow();
+ FPU_stack_underflow();
}
else
EXCEPTION(EX_StackUnder);
@@ -124,61 +128,77 @@
{
/* fxch st(i) */
FPU_REG t;
- register FPU_REG *sti_ptr = &st(FPU_rm), *st0_ptr = &st(0);
+ int i = FPU_rm;
+ FPU_REG *st0_ptr = &st(0), *sti_ptr = &st(i);
+ long tag_word = fpu_tag_word;
+ int regnr = top & 7, regnri = ((regnr + i) & 7);
+ u_char st0_tag = (tag_word >> (regnr*2)) & 3;
+ u_char sti_tag = (tag_word >> (regnri*2)) & 3;
- if ( st0_ptr->tag == TW_Empty )
+ if ( st0_tag == TAG_Empty )
{
- if ( sti_ptr->tag == TW_Empty )
+ if ( sti_tag == TAG_Empty )
{
- stack_underflow();
- stack_underflow_i(FPU_rm);
+ FPU_stack_underflow();
+ FPU_stack_underflow_i(i);
return;
}
if ( control_word & CW_Invalid )
- reg_move(sti_ptr, st0_ptr); /* Masked response */
- stack_underflow_i(FPU_rm);
+ {
+ /* Masked response */
+ FPU_copy_to_reg0(sti_ptr, sti_tag);
+ }
+ FPU_stack_underflow_i(i);
return;
}
- if ( sti_ptr->tag == TW_Empty )
+ if ( sti_tag == TAG_Empty )
{
if ( control_word & CW_Invalid )
- reg_move(st0_ptr, sti_ptr); /* Masked response */
- stack_underflow();
+ {
+ /* Masked response */
+ FPU_copy_to_regi(st0_ptr, st0_tag, i);
+ }
+ FPU_stack_underflow();
return;
}
clear_C1();
- reg_move(st0_ptr, &t);
- reg_move(sti_ptr, st0_ptr);
- reg_move(&t, sti_ptr);
+
+ reg_copy(st0_ptr, &t);
+ reg_copy(sti_ptr, st0_ptr);
+ reg_copy(&t, sti_ptr);
+
+ tag_word &= ~(3 << (regnr*2)) & ~(3 << (regnri*2));
+ tag_word |= (sti_tag << (regnr*2)) | (st0_tag << (regnri*2));
+ fpu_tag_word = tag_word;
}
void ffree_()
{
/* ffree st(i) */
- st(FPU_rm).tag = TW_Empty;
+ FPU_settagi(FPU_rm, TAG_Empty);
}
void ffreep()
{
/* ffree st(i) + pop - unofficial code */
- st(FPU_rm).tag = TW_Empty;
- pop();
+ FPU_settagi(FPU_rm, TAG_Empty);
+ FPU_pop();
}
void fst_i_()
{
/* fst st(i) */
- reg_move(&st(0), &st(FPU_rm));
+ FPU_copy_to_regi(&st(0), FPU_gettag0(), FPU_rm);
}
void fstp_i()
{
/* fstp st(i) */
- reg_move(&st(0), &st(FPU_rm));
- pop();
+ FPU_copy_to_regi(&st(0), FPU_gettag0(), FPU_rm);
+ FPU_pop();
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov