Annotation of coherent/b/kernel/emulator/load_store.c, revision 1.1.1.1

1.1       root        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 [email protected]    |
                      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)
                     48: {
                     49:   FPU_REG *pop_ptr;  /* We need a version of FPU_st0_ptr which won't change. */
                     50: 
                     51:   pop_ptr = NULL;
                     52:   switch ( type_table[(int) (unsigned) type] )
                     53:     {
                     54:     case _NONE_:
                     55:       break;
                     56:     case _REG0_:
                     57:       pop_ptr = &st(0);       /* Some of these instructions pop after
                     58:                                 storing */
                     59: 
                     60:       FPU_st0_ptr = pop_ptr;      /* Set the global variables. */
                     61:       FPU_st0_tag = FPU_st0_ptr->tag;
                     62:       break;
                     63:     case _PUSH_:
                     64:       {
                     65:        pop_ptr = &st(-1);
                     66:        if ( pop_ptr->tag != TW_Empty )
                     67:          { stack_overflow(); return; }
                     68:        top--;
                     69:       }
                     70:       break;
                     71:     case _null_:
                     72:       return Un_impl();
                     73: #ifdef PARANOID
                     74:     default:
                     75:       return EXCEPTION(EX_INTERNAL);
                     76: #endif PARANOID
                     77:     }
                     78: 
                     79: switch ( type )
                     80:   {
                     81:   case 000:       /* fld m32real */
                     82:     reg_load_single();
                     83:     reg_move(&FPU_loaded_data, pop_ptr);
                     84:     break;
                     85:   case 001:      /* fild m32int */
                     86:     reg_load_int32();
                     87:     reg_move(&FPU_loaded_data, pop_ptr);
                     88:     break;
                     89:   case 002:      /* fld m64real */
                     90:     reg_load_double();
                     91:     reg_move(&FPU_loaded_data, pop_ptr);
                     92:     break;
                     93:   case 003:      /* fild m16int */
                     94:     reg_load_int16();
                     95:     reg_move(&FPU_loaded_data, pop_ptr);
                     96:     break;
                     97:   case 010:      /* fst m32real */
                     98:     reg_store_single();
                     99:     break;
                    100:   case 011:      /* fist m32int */
                    101:     reg_store_int32();
                    102:     break;
                    103:   case 012:     /* fst m64real */
                    104:     reg_store_double();
                    105:     break;
                    106:   case 013:     /* fist m16int */
                    107:     reg_store_int16();
                    108:     break;
                    109:   case 014:     /* fstp m32real */
                    110:     if ( reg_store_single() )
                    111:       pop_0();  /* pop only if the number was actually stored
                    112:                 (see the 80486 manual p16-28) */
                    113:     break;
                    114:   case 015:     /* fistp m32int */
                    115:     if ( reg_store_int32() )
                    116:       pop_0();  /* pop only if the number was actually stored
                    117:                 (see the 80486 manual p16-28) */
                    118:     break;
                    119:   case 016:     /* fstp m64real */
                    120:     if ( reg_store_double() )
                    121:       pop_0();  /* pop only if the number was actually stored
                    122:                 (see the 80486 manual p16-28) */
                    123:     break;
                    124:   case 017:     /* fistp m16int */
                    125:     if ( reg_store_int16() )
                    126:       pop_0();  /* pop only if the number was actually stored
                    127:                 (see the 80486 manual p16-28) */
                    128:     break;
                    129:   case 020:     /* fldenv  m14/28byte */
                    130:     fldenv();
                    131:     break;
                    132:   case 022:     /* frstor m94/108byte */
                    133:     frstor();
                    134:     break;
                    135:   case 023:     /* fbld m80dec */
                    136:     reg_load_bcd();
                    137:     reg_move(&FPU_loaded_data, pop_ptr);
                    138:     break;
                    139:   case 024:     /* fldcw */
                    140:     RE_ENTRANT_CHECK_OFF
                    141:     control_word = get_fs_word((unsigned short *) FPU_data_address);
                    142:     RE_ENTRANT_CHECK_ON
                    143: #ifdef NO_UNDERFLOW_TRAP
                    144:     if ( !(control_word & EX_Underflow) )
                    145:       {
                    146:        control_word |= EX_Underflow;
                    147:       }
                    148: #endif
                    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 025:      /* fld m80real */
                    153:     reg_load_extended();
                    154:     reg_move(&FPU_loaded_data, pop_ptr);
                    155:     break;
                    156:   case 027:      /* fild m64int */
                    157:     reg_load_int64();
                    158:     reg_move(&FPU_loaded_data, pop_ptr);
                    159:     break;
                    160:   case 030:     /* fstenv  m14/28byte */
                    161:     fstenv();
                    162:     FPU_data_address = (void *)data_operand_offset; /* We want no net effect */
                    163:     FPU_entry_eip = ip_offset;               /* We want no net effect */
                    164:     break;
                    165:   case 032:      /* fsave */
                    166:     fsave();
                    167:     finit_instr();
                    168:     FPU_data_address = (void *)data_operand_offset; /* We want no net effect */
                    169:     FPU_entry_eip = ip_offset;               /* We want no net effect */
                    170:     break;
                    171:   case 033:      /* fbstp m80dec */
                    172:     if ( reg_store_bcd() )
                    173:       pop_0();  /* pop only if the number was actually stored
                    174:                 (see the 80486 manual p16-28) */
                    175:     break;
                    176:   case 034:      /* fstcw m16int */
                    177:     RE_ENTRANT_CHECK_OFF
                    178: #ifdef COHERENT
                    179:     if (verify_area(FPU_data_address,2))
                    180:            put_fs_word(control_word, (short *) FPU_data_address);
                    181: #else
                    182:     verify_area(FPU_data_address,2);
                    183:     put_fs_word(control_word, (short *) FPU_data_address);
                    184: #endif
                    185:     RE_ENTRANT_CHECK_ON
                    186:     FPU_data_address = (void *)data_operand_offset; /* We want no net effect */
                    187:     FPU_entry_eip = ip_offset;               /* We want no net effect */
                    188:     break;
                    189:   case 035:      /* fstp m80real */
                    190:     if ( reg_store_extended() )
                    191:       pop_0();  /* pop only if the number was actually stored
                    192:                 (see the 80486 manual p16-28) */
                    193:     break;
                    194:   case 036:      /* fstsw m2byte */
                    195:     status_word &= ~SW_TOP;
                    196:     status_word |= (top&7) << SW_TOPS;
                    197:     RE_ENTRANT_CHECK_OFF
                    198: #ifdef COHERENT
                    199:     if (verify_area(FPU_data_address,2))
                    200:            put_fs_word(status_word,(short *) FPU_data_address);
                    201: #else
                    202:     verify_area(FPU_data_address,2);
                    203:     put_fs_word(status_word,(short *) FPU_data_address);
                    204: #endif
                    205:     RE_ENTRANT_CHECK_ON
                    206:     FPU_data_address = (void *)data_operand_offset; /* We want no net effect */
                    207:     FPU_entry_eip = ip_offset;               /* We want no net effect */
                    208:     break;
                    209:   case 037:      /* fistp m64int */
                    210:     if ( reg_store_int64() )
                    211:       pop_0();  /* pop only if the number was actually stored
                    212:                 (see the 80486 manual p16-28) */
                    213:     break;
                    214:   }
                    215: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.