root/arch/i386/math-emu/fpu_aux.c

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

DEFINITIONS

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

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