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

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