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 #include <asm/segment.h>
  14 
  15 #include "fpu_system.h"
  16 #include "exception.h"
  17 #include "fpu_emu.h"
  18 #include "status_w.h"
  19 
  20 
  21 #define _NONE_ 0
  22 #define _REG0_ 1   /* Need to check for not empty st(0) */
  23 #define _REGI_ 2   /* Need to check for not empty st(0) and st(rm) */
  24 #define _REGi_ 0   /* Uses st(rm) */
  25 #define _PUSH_ 3   /* Need to check for space to push onto stack */
  26 #define _null_ 4   /* Function illegal or not implemented */
  27 
  28 static unsigned char type_table[32] = {
  29   _PUSH_, _PUSH_, _PUSH_, _PUSH_,
  30   _null_, _null_, _null_, _null_,
  31   _REG0_, _REG0_, _REG0_, _REG0_,
  32   _REG0_, _REG0_, _REG0_, _REG0_,
  33   _null_, _null_, _NONE_, _PUSH_,
  34   _NONE_, _PUSH_, _null_, _PUSH_,
  35   _null_, _null_, _NONE_, _REG0_,
  36   _NONE_, _REG0_, _NONE_, _REG0_
  37   };
  38 
  39 void load_store_instr(char type)
     /* [previous][next][first][last][top][bottom][index][help] */
  40 {
  41   switch ( type_table[(int) (unsigned) type] )
  42     {
  43     case _NONE_:
  44       break;
  45     case _REG0_:
  46       break;
  47     case _PUSH_:
  48       {
  49         REG *st_new_ptr;
  50         if ( STACK_OVERFLOW )
  51           { stack_overflow(); return; }
  52         push();
  53       }
  54       break;
  55     case _null_:
  56       return Un_impl();
  57 #ifdef PARANOID
  58     default:
  59       return EXCEPTION(EX_INTERNAL);
  60 #endif PARANOID
  61     }
  62 
  63 switch ( type )
  64   {
  65   case 000:       /* fld m32real */
  66     reg_load_single();
  67     reg_move(&FPU_loaded_data, st0_ptr);
  68     break;
  69   case 001:      /* fild m32int */
  70     reg_load_int32();
  71     reg_move(&FPU_loaded_data, st0_ptr);
  72     break;
  73   case 002:      /* fld m64real */
  74     reg_load_double();
  75     reg_move(&FPU_loaded_data, st0_ptr);
  76     break;
  77   case 003:      /* fild m16int */
  78     reg_load_int16();
  79     reg_move(&FPU_loaded_data, st0_ptr);
  80     break;
  81   case 010:      /* fst m32real */
  82     reg_store_single();
  83     break;
  84   case 011:      /* fist m32int */
  85     reg_store_int32();
  86     break;
  87   case 012:     /* fst m64real */
  88     reg_store_double();
  89     break;
  90   case 013:     /* fist m16int */
  91     reg_store_int16();
  92     break;
  93   case 014:     /* fstp m32real */
  94     if ( reg_store_single() )
  95       pop();  /* pop only if the number was actually stored
  96                  (see the 80486 manual p16-28) */
  97     break;
  98   case 015:     /* fistp m32int */
  99     if ( reg_store_int32() )
 100       pop();  /* pop only if the number was actually stored
 101                  (see the 80486 manual p16-28) */
 102     break;
 103   case 016:     /* fstp m64real */
 104     if ( reg_store_double() )
 105       pop();  /* pop only if the number was actually stored
 106                  (see the 80486 manual p16-28) */
 107     break;
 108   case 017:     /* fistp m16int */
 109     if ( reg_store_int16() )
 110       pop();  /* pop only if the number was actually stored
 111                  (see the 80486 manual p16-28) */
 112     break;
 113   case 020:     /* fldenv  m14/28byte */
 114     fldenv();
 115     break;
 116   case 022:     /* frstor m94/108byte */
 117     frstor();
 118     break;
 119   case 023:     /* fbld m80dec */
 120     reg_load_bcd();
 121     reg_move(&FPU_loaded_data, st0_ptr);
 122     break;
 123   case 024:     /* fldcw */
 124     control_word = get_fs_word((unsigned short *) FPU_data_address);
 125 #ifdef NO_UNDERFLOW_TRAP
 126     if ( !(control_word & EX_Underflow) )
 127       {
 128         control_word |= EX_Underflow;
 129       }
 130 #endif
 131     FPU_data_address = (void *)data_operand_offset; /* We want no net effect */
 132     FPU_entry_eip = ip_offset;               /* We want no net effect */
 133     break;
 134   case 025:      /* fld m80real */
 135     reg_load_extended();
 136     reg_move(&FPU_loaded_data, st0_ptr);
 137     break;
 138   case 027:      /* fild m64int */
 139     reg_load_int64();
 140     reg_move(&FPU_loaded_data, st0_ptr);
 141     break;
 142   case 030:     /* fstenv  m14/28byte */
 143     fstenv();
 144     FPU_data_address = (void *)data_operand_offset; /* We want no net effect */
 145     FPU_entry_eip = ip_offset;               /* We want no net effect */
 146     break;
 147   case 032:      /* fsave */
 148     fsave();
 149     FPU_data_address = (void *)data_operand_offset; /* We want no net effect */
 150     FPU_entry_eip = ip_offset;               /* We want no net effect */
 151     break;
 152   case 033:      /* fbstp m80dec */
 153     if ( reg_store_bcd() )
 154       pop();  /* pop only if the number was actually stored
 155                  (see the 80486 manual p16-28) */
 156     break;
 157   case 034:      /* fstcw m16int */
 158     verify_area(FPU_data_address,2);
 159     put_fs_word(control_word, (short *) FPU_data_address);
 160     FPU_data_address = (void *)data_operand_offset; /* We want no net effect */
 161     FPU_entry_eip = ip_offset;               /* We want no net effect */
 162     break;
 163   case 035:      /* fstp m80real */
 164     if ( reg_store_extended() )
 165       pop();  /* pop only if the number was actually stored
 166                  (see the 80486 manual p16-28) */
 167     break;
 168   case 036:      /* fstsw m2byte */
 169     status_word &= ~SW_TOP;
 170     status_word |= (top&7) << SW_TOPS;
 171     verify_area(FPU_data_address,2);
 172     put_fs_word(status_word,(short *) FPU_data_address);
 173     FPU_data_address = (void *)data_operand_offset; /* We want no net effect */
 174     FPU_entry_eip = ip_offset;               /* We want no net effect */
 175     break;
 176   case 037:      /* fistp m64int */
 177     if ( reg_store_int64() )
 178       pop();  /* pop only if the number was actually stored
 179                  (see the 80486 manual p16-28) */
 180     break;
 181   }
 182 }

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