root/kernel/FPU-emu/load_store.c

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

DEFINITIONS

This source file includes following definitions.
  1. load_store_instr

   1 /*---------------------------------------------------------------------------+
   2  |  load_store.c                                                             |
   3  |                                                                           |
   4  | This file contains most of the code to interpret the FPU instructions     |
   5  | which load and store from user memory.                                    |
   6  |                                                                           |
   7  | Copyright (C) 1992    W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
   8  |                       Australia.  E-mail apm233m@vaxc.cc.monash.edu.au    |
   9  |                                                                           |
  10  |                                                                           |
  11  +---------------------------------------------------------------------------*/
  12 
  13 /*---------------------------------------------------------------------------+
  14  | Note:                                                                     |
  15  |    The file contains code which accesses user memory.                     |
  16  |    Emulator static data may change when user memory is accessed, due to   |
  17  |    other processes using the emulator while swapping is in progress.      |
  18  +---------------------------------------------------------------------------*/
  19 
  20 #include <asm/segment.h>
  21 
  22 #include "fpu_system.h"
  23 #include "exception.h"
  24 #include "fpu_emu.h"
  25 #include "status_w.h"
  26 
  27 
  28 #define _NONE_ 0   /* FPU_st0_ptr etc not needed */
  29 #define _REG0_ 1   /* Will be storing st(0) */
  30 #define _PUSH_ 3   /* Need to check for space to push onto stack */
  31 #define _null_ 4   /* Function illegal or not implemented */
  32 
  33 #define pop_0() { pop_ptr->tag = TW_Empty; top++; }
  34 
  35 
  36 static unsigned char type_table[32] = {
  37   _PUSH_, _PUSH_, _PUSH_, _PUSH_,
  38   _null_, _null_, _null_, _null_,
  39   _REG0_, _REG0_, _REG0_, _REG0_,
  40   _REG0_, _REG0_, _REG0_, _REG0_,
  41   _null_, _null_, _NONE_, _PUSH_,
  42   _NONE_, _PUSH_, _null_, _PUSH_,
  43   _null_, _null_, _NONE_, _REG0_,
  44   _NONE_, _REG0_, _NONE_, _REG0_
  45   };
  46 
  47 void load_store_instr(char type)
     /* [previous][next][first][last][top][bottom][index][help] */
  48 {
  49   FPU_REG *pop_ptr;  /* We need a version of FPU_st0_ptr which won't change. */
  50 
  51   switch ( type_table[(int) (unsigned) type] )
  52     {
  53     case _NONE_:
  54       break;
  55     case _REG0_:
  56       pop_ptr = &st(0);       /* Some of these instructions pop after
  57                                  storing */
  58 
  59       FPU_st0_ptr = pop_ptr;      /* Set the global variables. */
  60       FPU_st0_tag = FPU_st0_ptr->tag;
  61       break;
  62     case _PUSH_:
  63       {
  64         pop_ptr = &st(-1);
  65         if ( pop_ptr->tag != TW_Empty )
  66           { stack_overflow(); return; }
  67         top--;
  68       }
  69       break;
  70     case _null_:
  71       return Un_impl();
  72 #ifdef PARANOID
  73     default:
  74       return EXCEPTION(EX_INTERNAL);
  75 #endif PARANOID
  76     }
  77 
  78 switch ( type )
  79   {
  80   case 000:       /* fld m32real */
  81     reg_load_single();
  82     reg_move(&FPU_loaded_data, pop_ptr);
  83     break;
  84   case 001:      /* fild m32int */
  85     reg_load_int32();
  86     reg_move(&FPU_loaded_data, pop_ptr);
  87     break;
  88   case 002:      /* fld m64real */
  89     reg_load_double();
  90     reg_move(&FPU_loaded_data, pop_ptr);
  91     break;
  92   case 003:      /* fild m16int */
  93     reg_load_int16();
  94     reg_move(&FPU_loaded_data, pop_ptr);
  95     break;
  96   case 010:      /* fst m32real */
  97     reg_store_single();
  98     break;
  99   case 011:      /* fist m32int */
 100     reg_store_int32();
 101     break;
 102   case 012:     /* fst m64real */
 103     reg_store_double();
 104     break;
 105   case 013:     /* fist m16int */
 106     reg_store_int16();
 107     break;
 108   case 014:     /* fstp m32real */
 109     if ( reg_store_single() )
 110       pop_0();  /* pop only if the number was actually stored
 111                  (see the 80486 manual p16-28) */
 112     break;
 113   case 015:     /* fistp m32int */
 114     if ( reg_store_int32() )
 115       pop_0();  /* pop only if the number was actually stored
 116                  (see the 80486 manual p16-28) */
 117     break;
 118   case 016:     /* fstp m64real */
 119     if ( reg_store_double() )
 120       pop_0();  /* pop only if the number was actually stored
 121                  (see the 80486 manual p16-28) */
 122     break;
 123   case 017:     /* fistp m16int */
 124     if ( reg_store_int16() )
 125       pop_0();  /* pop only if the number was actually stored
 126                  (see the 80486 manual p16-28) */
 127     break;
 128   case 020:     /* fldenv  m14/28byte */
 129     fldenv();
 130     break;
 131   case 022:     /* frstor m94/108byte */
 132     frstor();
 133     break;
 134   case 023:     /* fbld m80dec */
 135     reg_load_bcd();
 136     reg_move(&FPU_loaded_data, pop_ptr);
 137     break;
 138   case 024:     /* fldcw */
 139     RE_ENTRANT_CHECK_OFF
 140     control_word = get_fs_word((unsigned short *) FPU_data_address);
 141     RE_ENTRANT_CHECK_ON
 142 #ifdef NO_UNDERFLOW_TRAP
 143     if ( !(control_word & EX_Underflow) )
 144       {
 145         control_word |= EX_Underflow;
 146       }
 147 #endif
 148     FPU_data_address = (void *)data_operand_offset; /* We want no net effect */
 149     FPU_entry_eip = ip_offset;               /* We want no net effect */
 150     break;
 151   case 025:      /* fld m80real */
 152     reg_load_extended();
 153     reg_move(&FPU_loaded_data, pop_ptr);
 154     break;
 155   case 027:      /* fild m64int */
 156     reg_load_int64();
 157     reg_move(&FPU_loaded_data, pop_ptr);
 158     break;
 159   case 030:     /* fstenv  m14/28byte */
 160     fstenv();
 161     FPU_data_address = (void *)data_operand_offset; /* We want no net effect */
 162     FPU_entry_eip = ip_offset;               /* We want no net effect */
 163     break;
 164   case 032:      /* fsave */
 165     fsave();
 166     FPU_data_address = (void *)data_operand_offset; /* We want no net effect */
 167     FPU_entry_eip = ip_offset;               /* We want no net effect */
 168     break;
 169   case 033:      /* fbstp m80dec */
 170     if ( reg_store_bcd() )
 171       pop_0();  /* pop only if the number was actually stored
 172                  (see the 80486 manual p16-28) */
 173     break;
 174   case 034:      /* fstcw m16int */
 175     RE_ENTRANT_CHECK_OFF
 176     verify_area(FPU_data_address,2);
 177     put_fs_word(control_word, (short *) FPU_data_address);
 178     RE_ENTRANT_CHECK_ON
 179     FPU_data_address = (void *)data_operand_offset; /* We want no net effect */
 180     FPU_entry_eip = ip_offset;               /* We want no net effect */
 181     break;
 182   case 035:      /* fstp m80real */
 183     if ( reg_store_extended() )
 184       pop_0();  /* pop only if the number was actually stored
 185                  (see the 80486 manual p16-28) */
 186     break;
 187   case 036:      /* fstsw m2byte */
 188     status_word &= ~SW_TOP;
 189     status_word |= (top&7) << SW_TOPS;
 190     RE_ENTRANT_CHECK_OFF
 191     verify_area(FPU_data_address,2);
 192     put_fs_word(status_word,(short *) FPU_data_address);
 193     RE_ENTRANT_CHECK_ON
 194     FPU_data_address = (void *)data_operand_offset; /* We want no net effect */
 195     FPU_entry_eip = ip_offset;               /* We want no net effect */
 196     break;
 197   case 037:      /* fistp m64int */
 198     if ( reg_store_int64() )
 199       pop_0();  /* pop only if the number was actually stored
 200                  (see the 80486 manual p16-28) */
 201     break;
 202   }
 203 }

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