root/kernel/FPU-emu/fpu_aux.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. fclex
  2. finit
  3. finit_
  4. fstsw_ax
  5. fstsw_
  6. fnop
  7. fp_nop
  8. fld_i_
  9. fxch_i
  10. ffree_
  11. ffreep
  12. fst_i_
  13. fstp_i

   1 /*---------------------------------------------------------------------------+
   2  |  fpu_aux.c                                                                |
   3  |                                                                           |
   4  | Code to implement some of the FPU auxiliary instructions.                 |
   5  |                                                                           |
   6  | Copyright (C) 1992,1993                                                   |
   7  |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
   8  |                       Australia.  E-mail apm233m@vaxc.cc.monash.edu.au    |
   9  |                                                                           |
  10  |                                                                           |
  11  +---------------------------------------------------------------------------*/
  12 
  13 #include "fpu_system.h"
  14 #include "exception.h"
  15 #include "fpu_emu.h"
  16 #include "status_w.h"
  17 
  18 
  19 
  20 void fclex(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  21 {
  22   status_word &= ~(SW_Backward|SW_Summary|SW_Stack_Fault|SW_Precision|
  23                    SW_Underflow|SW_Overflow|SW_Zero_Div|SW_Denorm_Op|
  24                    SW_Invalid);
  25   FPU_entry_eip = ip_offset;               /* We want no net effect */
  26 }
  27 
  28 /* Needs to be externally visible */
  29 void finit()
     /* [previous][next][first][last][top][bottom][index][help] */
  30 {
  31   int r;
  32   control_word = 0x037f;
  33   status_word = 0;
  34   top = 0;            /* We don't keep top in the status word internally. */
  35   for (r = 0; r < 8; r++)
  36     {
  37       regs[r].tag = TW_Empty;
  38     }
  39   FPU_entry_eip = ip_offset = 0;
  40 }
  41 
  42 static FUNC finit_table[] = {
  43   Un_impl, Un_impl, fclex, finit, Un_impl, Un_impl, Un_impl, Un_impl
  44 };
  45 
  46 void finit_()
     /* [previous][next][first][last][top][bottom][index][help] */
  47 {
  48   (finit_table[FPU_rm])();
  49 }
  50 
  51 
  52 static void fstsw_ax(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  53 {
  54 
  55   status_word &= ~SW_Top;
  56   status_word |= (top&7) << SW_Top_Shift;
  57 
  58   *(short *) &FPU_EAX = status_word;
  59 
  60 }
  61 
  62 static FUNC fstsw_table[] = {
  63   fstsw_ax, Un_impl, Un_impl, Un_impl, Un_impl, Un_impl, Un_impl, Un_impl
  64 };
  65 
  66 void fstsw_()
     /* [previous][next][first][last][top][bottom][index][help] */
  67 {
  68   (fstsw_table[FPU_rm])();
  69 }
  70 
  71 
  72 
  73 static void fnop(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  74 {
  75 }
  76 
  77 FUNC fp_nop_table[] = {
  78   fnop, Un_impl, Un_impl, Un_impl, Un_impl, Un_impl, Un_impl, Un_impl
  79 };
  80 
  81 void fp_nop()
     /* [previous][next][first][last][top][bottom][index][help] */
  82 {
  83   (fp_nop_table[FPU_rm])();
  84 }
  85 
  86 
  87 void fld_i_()
     /* [previous][next][first][last][top][bottom][index][help] */
  88 {
  89   FPU_REG *st_new_ptr;
  90 
  91   if ( STACK_OVERFLOW )
  92     { stack_overflow(); return; }
  93 
  94   /* fld st(i) */
  95   if ( NOT_EMPTY(FPU_rm) )
  96     { reg_move(&st(FPU_rm), st_new_ptr); push(); }
  97   else
  98     {
  99       if ( control_word & EX_Invalid )
 100         {
 101           /* The masked response */
 102           push();
 103           stack_underflow();
 104         }
 105       else
 106         EXCEPTION(EX_StackUnder);
 107     }
 108 
 109 }
 110 
 111 
 112 void fxch_i()
     /* [previous][next][first][last][top][bottom][index][help] */
 113 {
 114   /* fxch st(i) */
 115   FPU_REG t;
 116   register FPU_REG *sti_ptr = &st(FPU_rm);
 117 
 118   if ( FPU_st0_tag == TW_Empty )
 119     {
 120       if ( sti_ptr->tag == TW_Empty )
 121         {
 122           stack_underflow();
 123           stack_underflow_i(FPU_rm);
 124           return;
 125         }
 126       reg_move(sti_ptr, FPU_st0_ptr);
 127       stack_underflow_i(FPU_rm);
 128       return;
 129     }
 130   if ( sti_ptr->tag == TW_Empty )
 131     {
 132       reg_move(FPU_st0_ptr, sti_ptr);
 133       stack_underflow();
 134       return;
 135     }
 136   reg_move(FPU_st0_ptr, &t);
 137   reg_move(sti_ptr, FPU_st0_ptr);
 138   reg_move(&t, sti_ptr);
 139 }
 140 
 141 
 142 void ffree_()
     /* [previous][next][first][last][top][bottom][index][help] */
 143 {
 144   /* ffree st(i) */
 145   st(FPU_rm).tag = TW_Empty;
 146 }
 147 
 148 
 149 void ffreep()
     /* [previous][next][first][last][top][bottom][index][help] */
 150 {
 151   /* ffree st(i) + pop - unofficial code */
 152   st(FPU_rm).tag = TW_Empty;
 153   pop();
 154 }
 155 
 156 
 157 void fst_i_()
     /* [previous][next][first][last][top][bottom][index][help] */
 158 {
 159   /* fst st(i) */
 160   reg_move(FPU_st0_ptr, &st(FPU_rm));
 161 }
 162 
 163 
 164 void fstp_i()
     /* [previous][next][first][last][top][bottom][index][help] */
 165 {
 166   /* fstp st(i) */
 167   reg_move(FPU_st0_ptr, &st(FPU_rm));
 168   pop();
 169 }
 170 

/* [previous][next][first][last][top][bottom][index][help] */