Annotation of coherent/b/kernel/emulator/load_store.c, revision 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.