root/drivers/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   billm@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 #include "control_w.h"
  18 
  19 
  20 
  21 void fclex(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  22 {
  23   partial_status &= ~(SW_Backward|SW_Summary|SW_Stack_Fault|SW_Precision|
  24                    SW_Underflow|SW_Overflow|SW_Zero_Div|SW_Denorm_Op|
  25                    SW_Invalid);
  26   NO_NET_DATA_EFFECT;
  27   FPU_entry_eip = ip_offset;               /* We want no net effect */
  28 }
  29 
  30 /* Needs to be externally visible */
  31 void finit()
     /* [previous][next][first][last][top][bottom][index][help] */
  32 {
  33   int r;
  34   control_word = 0x037f;
  35   partial_status = 0;
  36   top = 0;            /* We don't keep top in the status word internally. */
  37   for (r = 0; r < 8; r++)
  38     {
  39       regs[r].tag = TW_Empty;
  40     }
  41   /* The behaviour is different to that detailed in
  42      Section 15.1.6 of the Intel manual */
  43   data_operand_offset = 0;
  44   operand_selector = 0;
  45   NO_NET_DATA_EFFECT;
  46   FPU_entry_op_cs = 0;
  47   FPU_entry_eip = ip_offset = 0;
  48 }
  49 
  50 static FUNC const finit_table[] = {
  51   Un_impl, Un_impl, fclex, finit, Un_impl, Un_impl, Un_impl, Un_impl
  52 };
  53 
  54 void finit_()
     /* [previous][next][first][last][top][bottom][index][help] */
  55 {
  56   (finit_table[FPU_rm])();
  57 }
  58 
  59 
  60 static void fstsw_ax(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  61 {
  62   *(short *) &FPU_EAX = status_word();
  63   NO_NET_INSTR_EFFECT;
  64 }
  65 
  66 static FUNC const fstsw_table[] = {
  67   fstsw_ax, Un_impl, Un_impl, Un_impl, Un_impl, Un_impl, Un_impl, Un_impl
  68 };
  69 
  70 void fstsw_()
     /* [previous][next][first][last][top][bottom][index][help] */
  71 {
  72   (fstsw_table[FPU_rm])();
  73 }
  74 
  75 
  76 
  77 static void fnop(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  78 {
  79 }
  80 
  81 static FUNC const fp_nop_table[] = {
  82   fnop, Un_impl, Un_impl, Un_impl, Un_impl, Un_impl, Un_impl, Un_impl
  83 };
  84 
  85 void fp_nop()
     /* [previous][next][first][last][top][bottom][index][help] */
  86 {
  87   (fp_nop_table[FPU_rm])();
  88 }
  89 
  90 
  91 void fld_i_()
     /* [previous][next][first][last][top][bottom][index][help] */
  92 {
  93   FPU_REG *st_new_ptr;
  94 
  95   if ( STACK_OVERFLOW )
  96     { stack_overflow(); return; }
  97 
  98   /* fld st(i) */
  99   if ( NOT_EMPTY(FPU_rm) )
 100     { reg_move(&st(FPU_rm), st_new_ptr); push(); }
 101   else
 102     {
 103       if ( control_word & EX_Invalid )
 104         {
 105           /* The masked response */
 106           push();
 107           stack_underflow();
 108         }
 109       else
 110         EXCEPTION(EX_StackUnder);
 111     }
 112 
 113 }
 114 
 115 
 116 void fxch_i()
     /* [previous][next][first][last][top][bottom][index][help] */
 117 {
 118   /* fxch st(i) */
 119   FPU_REG t;
 120   register FPU_REG *sti_ptr = &st(FPU_rm);
 121 
 122   if ( FPU_st0_tag == TW_Empty )
 123     {
 124       if ( sti_ptr->tag == TW_Empty )
 125         {
 126           stack_underflow();
 127           stack_underflow_i(FPU_rm);
 128           return;
 129         }
 130       if ( control_word & CW_Invalid )
 131         reg_move(sti_ptr, FPU_st0_ptr);   /* Masked response */
 132       stack_underflow_i(FPU_rm);
 133       return;
 134     }
 135   if ( sti_ptr->tag == TW_Empty )
 136     {
 137       if ( control_word & CW_Invalid )
 138         reg_move(FPU_st0_ptr, sti_ptr);   /* Masked response */
 139       stack_underflow();
 140       return;
 141     }
 142   clear_C1();
 143   reg_move(FPU_st0_ptr, &t);
 144   reg_move(sti_ptr, FPU_st0_ptr);
 145   reg_move(&t, sti_ptr);
 146 }
 147 
 148 
 149 void ffree_()
     /* [previous][next][first][last][top][bottom][index][help] */
 150 {
 151   /* ffree st(i) */
 152   st(FPU_rm).tag = TW_Empty;
 153 }
 154 
 155 
 156 void ffreep()
     /* [previous][next][first][last][top][bottom][index][help] */
 157 {
 158   /* ffree st(i) + pop - unofficial code */
 159   st(FPU_rm).tag = TW_Empty;
 160   pop();
 161 }
 162 
 163 
 164 void fst_i_()
     /* [previous][next][first][last][top][bottom][index][help] */
 165 {
 166   /* fst st(i) */
 167   reg_move(FPU_st0_ptr, &st(FPU_rm));
 168 }
 169 
 170 
 171 void fstp_i()
     /* [previous][next][first][last][top][bottom][index][help] */
 172 {
 173   /* fstp st(i) */
 174   reg_move(FPU_st0_ptr, &st(FPU_rm));
 175   pop();
 176 }
 177 

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