Annotation of kernel/machdep/i386/fp_emul/fp_dcode.s, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: 
                     25:        .file   "dcode.s"
                     26: 
                     27:        .ident  "@(#)kern-fp:dcode.s    1.1"
                     28: 
                     29: // *************************************************************************
                     30: //
                     31: //                     d c o d e .m o d 
                     32: //                     ================
                     33: //
                     34: //     ================================================================
                     35: //               intel corporation proprietary information
                     36: //    this software  is  supplied  under  the  terms  of  a  license
                     37: //    agreement  or non-disclosure agreement  with intel corporation
                     38: //    and  may not be copied nor disclosed except in accordance with
                     39: //    the terms of that agreement.                                  
                     40: //     ================================================================
                     41: //
                     42: //     function:
                     43: //             converts the 80387 instruction into information
                     44: //               about the first operand, information about the
                     45: //               second operand, information about the result, 
                     46: //               and the operation type.  defines mem_operand_ptr.
                     47: //
                     48: //     public procedures:
                     49: //             e80387
                     50: //
                     51: // ****************************************************************************
                     52: //
                     53: //...March 3, 1987...
                     54: //
                     55: //        .file   *a_mdc*
                     56: //$nolist
                     57: #include       "fp_e80387.h"
                     58: //$list
                     59: //
                     60: //...declare stack segment...
                     61: //
                     62: //stack        stackseg        200
                     63: //
                     64: //...declare status register segment...
                     65: //
                     66:        .data   //a_msr segment rw      public
                     67: //     extrn   sr_masks,sr_errors,sr_instr_offset
                     68: //     extrn   sr_instr_base,sr_mem_offset,sr_mem_base
                     69: //a_msr        ends
                     70: //
                     71: //...declare status register selector segment...
                     72: //
                     73:        .data   //a_msrs        segment rw      public
                     74: // a_msr_selector: .long   a_msr
                     75: //a_msrs       ends
                     76: //
                     77:        .text   //a_med segment er      public
                     78: //
                     79: //     extrn   load,store,chsign,compar
                     80: //     extrn   arith,ldcw,save,restore
                     81: //     extrn   free_reg,abs_value,init,log
                     82: //     extrn   fxtrac,splog,exp,tan
                     83: //     extrn   arctan,sqrt,remr,intpt
                     84: //     extrn   scale,exchange,restore_status
                     85: //     extrn   stenv,stcw,stsw,load_con
                     86: //     extrn   decr_top,incr_top,clex,exam
                     87: //     extrn   fetch_an_op,sin,cos,sincos
                     88: //     extrn   rem1
                     89: //
                     90:        .globl  _e80387
                     91: 
                     92: // --------------------------------------JKD-----------------------
                     93: 
                     94: // --------------------------------------JKD-----------------------
                     95: 
                     96: //        .globl  a_msr_selector
                     97: //
                     98: // *********************************************************************
                     99: //
                    100: //     address table for instruction group decoding handlers
                    101: //
                    102: // *********************************************************************
                    103:                                                // 10-9-8  (mod = 3)::1
                    104: group_handler:  
                    105:        .long   arith_short_real        //  0 0 0  0
                    106:        .long   arith_top_reg           //  0 0 0  1
                    107:        .long   load_short_real         //  0 0 1  0
                    108:        .long   transcendentals         //  0 0 1  1
                    109:        .long   arith_short_int         //  0 1 0  0
                    110:        .long   double_pop              //  0 1 0  1
                    111:        .long   load_short_int          //  0 1 1  0
                    112:        .long   administrative          //  0 1 1  1
                    113:        .long   arith_long_real         //  1 0 0  0
                    114:        .long   arith_reg_top           //  1 0 0  1
                    115:        .long   load_long_real          //  1 0 1  0
                    116:        .long   store_reg               //  1 0 1  1
                    117:        .long   arith_word_int          //  1 1 0  0
                    118:        .long   arith_reg_pop           //  1 1 0  1
                    119:        .long   load_word_int           //  1 1 1  0
                    120:        .long   transfer_status         //  1 1 1  1
                    121: // *********************************************************************
                    122: //
                    123: //     address table for r/m decoding handlers
                    124: //
                    125: // *********************************************************************
                    126: rm_handler:    
                    127:        .long   rm_0                    // ea = (bx) + (si) + disp
                    128:        .long   rm_1                    // ea = (bx) + (di) + disp
                    129:        .long   rm_2                    // ea = (bp) + (si) + disp
                    130:        .long   rm_3                    // ea = (bp) + (di) + disp
                    131:        .long   rm_4                    // ea = (si) + disp
                    132:        .long   rm_5                    // ea = (di) + disp
                    133:        .long   rm_6                    // ea = (bp) + disp*
                    134:        .long   rm_7                    // ea = (bx) + disp
                    135: // *********************************************************************
                    136: //
                    137: //     address table for 32 bit base register decoding handlers
                    138: //
                    139: // *********************************************************************
                    140: base32:        
                    141:        .long   base_0                  // ea = (eax) + disp
                    142:        .long   base_1                  // ea = (ecx) + disp
                    143:        .long   base_2                  // ea = (edx) + disp
                    144:        .long   base_3                  // ea = (ebx) + disp
                    145:        .long   base_4                  // ea = (esp) + disp
                    146:        .long   base_5                  // ea = (ebp) + disp*
                    147:        .long   base_6                  // ea = (esi) + disp
                    148:        .long   base_7                  // ea = (edi) + disp
                    149: // *********************************************************************
                    150: //
                    151: //     address table for 32 bit index register decoding handlers
                    152: //
                    153: // *********************************************************************
                    154: index32:       
                    155:        .long   index_0                 // ea = (eax*ss) 
                    156:        .long   index_1                 // ea = (ecx*ss) 
                    157:        .long   index_2                 // ea = (edx*ss) 
                    158:        .long   index_3                 // ea = (ebx*ss) 
                    159:        .long   index_4                 // ea = (esp*ss) 
                    160:        .long   index_5                 // ea = (ebp*ss) 
                    161:        .long   index_6                 // ea = (esi*ss) 
                    162:        .long   index_7                 // ea = (edi*ss) 
                    163: // *********************************************************************
                    164: //
                    165: //     address table for instruction operations
                    166: //
                    167: // *********************************************************************
                    168: op_table:      
                    169:        .long   load,store,chsign,compar,free_reg,arith,arith,arith
                    170:        .long   arith,ldcw,save,restore,free_reg,abs_value,init
                    171:        .long   fxtrac,two_arg_trans,two_arg_trans,exp,tan
                    172:        .long   two_arg_trans,sqrt,remr,intpt,scale
                    173:        .long   exchange,free_reg,restore_status,stenv,stcw,stsw
                    174:        .long   load_con,load_con,load_con,load_con,load_con,load_con
                    175:        .long   load_con,decr_top,incr_top,clex,compar,exam,sin,cos,sincos
                    176:        .long   remr,compar
                    177: //
                    178: // *********************************************************************
                    179: //
                    180: //     arithmetic operation type decode table
                    181: //
                    182: // *********************************************************************
                    183:                                                //          5-4-3
                    184:        ALIGN
                    185: group_0a_0b_2a_4a_4b_6a_6b_op: 
                    186:        .byte   add_op  // fadd     0 0 0
                    187:        .byte   mul_op                  // fmul     0 0 1
                    188:        .byte   compar_op               // fcom     0 1 0
                    189:        .byte   compar_pop              // fcomp    0 1 1
                    190:        .byte   sub_op                  // fsub     1 0 0
                    191:        .byte   subr_op                 // fsubr    1 0 1
                    192:        .byte   div_op                  // fdiv     1 1 0
                    193:        .byte   divr_op                 // fdivr    1 1 1
                    194: //
                    195: // *********************************************************************
                    196: //
                    197: //     control word/environment operation type decode table
                    198: //
                    199: // *********************************************************************
                    200:                                                //          5-4-3
                    201:        ALIGN
                    202: group_1a_op:   
                    203:        .byte   load_op                 // fld      0 0 0
                    204:        .byte   error_op                // reserved 0 0 1
                    205:        .byte   store_op                // fst      0 1 0
                    206:        .byte   store_pop               // fstp     0 1 1
                    207:        .byte   ldenv_op                // fldenv   1 0 0
                    208:        .byte   ldcw_op                 // fldcw    1 0 1
                    209:        .byte   stenv_op                // fstenv   1 1 0
                    210:        .byte   stcw_op                 // fstsw    1 1 1
                    211: //
                    212: // *********************************************************************
                    213: //
                    214: //     load/exchange/nop operation decode table
                    215: //
                    216: // *********************************************************************
                    217:                                                //          5-4-3-2-1-0
                    218:        ALIGN
                    219: group_1ba_op:  
                    220:        .byte   load_op                 // fld      0 0 0 r e g
                    221:        .byte   exchange_op             // fxch     0 0 1 r e g
                    222:        .byte   null_op                 // fnop     0 1 1 r e g
                    223:        .byte   store_pop               // fstp *   0 1 1 r e g
                    224: //
                    225: // *********************************************************************
                    226: //
                    227: //     transcendental operation decode table
                    228: //
                    229: // *********************************************************************
                    230:                                                //          5-4-3-2-1-0
                    231:        ALIGN
                    232: group_1bb_op:  
                    233:        .byte   chsign_op               // fchs     1 0 0 0 0 0
                    234:        .byte   abs_op                  // fabs     1 0 0 0 0 1
                    235:        .byte   error_op                // reserved 1 0 0 0 1 0
                    236:        .byte   error_op                // reserved 1 0 0 0 1 1
                    237:        .byte   test_op                 // ftst     1 0 0 1 0 0
                    238:        .byte   exam_op                 // fxam     1 0 0 1 0 1
                    239:        .byte   error_op                // reserved 1 0 0 1 1 0
                    240:        .byte   error_op                // reserved 1 0 0 1 1 1
                    241:        .byte   load_1_op               // fld1     1 0 1 0 0 0
                    242:        .byte   load_l2t_op             // fldl2t   1 0 1 0 0 1
                    243:        .byte   load_l2e_op             // fldl2e   1 0 1 0 1 0
                    244:        .byte   load_pi_op              // fldpi    1 0 1 0 1 1
                    245:        .byte   load_lg2_op             // fldlg2   1 0 1 1 0 0
                    246:        .byte   load_ln2_op             // fldln2   1 0 1 1 0 1
                    247:        .byte   load_0_op               // fldz     1 0 1 1 1 0
                    248:        .byte   error_op                // reserved 1 0 1 1 1 1
                    249:        .byte   exp_op                  // f2xm1    1 1 0 0 0 0
                    250:        .byte   log_op                  // fyl2x    1 1 0 0 0 1
                    251:        .byte   tan_op                  // fptan    1 1 0 0 1 0
                    252:        .byte   arctan_op               // fpatan   1 1 0 0 1 1
                    253:        .byte   fxtrac_op               // fxtract  1 1 0 1 0 0
                    254:        .byte   rem1_op                 // fprem1   1 1 0 1 0 1
                    255:        .byte   decstp_op               // fdecstp  1 1 0 1 1 0
                    256:        .byte   incstp_op               // fincstp  1 1 0 1 1 1
                    257:        .byte   remr_op                 // fprem    1 1 1 0 0 0
                    258:        .byte   splog_op                // fyl2xp1  1 1 1 0 0 1
                    259:        .byte   sqrt_op                 // fsqrt    1 1 1 0 1 0
                    260:        .byte   sincos_op               // fsincos  1 1 1 0 1 1
                    261:        .byte   intpt_op                // frndint  1 1 1 1 0 0
                    262:        .byte   scale_op                // fscale   1 1 1 1 0 1
                    263:        .byte   sin_op                  // fsin     1 1 1 1 1 0
                    264:        .byte   cos_op              // fcos     1 1 1 1 1 1
                    265: //
                    266: // *********************************************************************
                    267: //
                    268: //     tempreal/bcd/short integer/long integer operation decode table
                    269: //
                    270: // *********************************************************************
                    271:                                                //          5-4-3
                    272:        ALIGN
                    273: group_3a_7a_op:        
                    274:        .byte   load_op                 // fild     0 0 0
                    275:        .byte   error_op                // reserved 0 0 1
                    276:        .byte   store_op                // fist     0 1 0
                    277:        .byte   store_pop               // fistp    0 1 1
                    278:        .byte   load_op                 // (fbld)   1 0 0
                    279:        .byte   load_op                 // f(i)ld   1 0 1
                    280:        .byte   store_pop               // (fbstp)  1 1 0
                    281:        .byte   store_pop               // f(i)stp  1 1 1
                    282: //
                    283: // *********************************************************************
                    284: //
                    285: //     clear exception/initialize operation decode table
                    286: //
                    287: // *********************************************************************
                    288:                                                //          5-4-3-2-1-0
                    289:        ALIGN
                    290: group_3b_op:   
                    291:        .byte   null_op                 // feni     1 0 0 0 0 0
                    292:        .byte   null_op                 // fdisi    1 0 0 0 0 1
                    293:        .byte   cler_op                 // fclex    1 0 0 0 1 0
                    294:        .byte   init_op                 // finit    1 0 0 0 1 1
                    295:        .byte   null_op                 // fsetpm   1 0 0 1 0 0
                    296:        .byte   error_op                // reserved 1 0 0 1 0 1
                    297:        .byte   error_op                // reserved 1 0 0 1 1 0
                    298:        .byte   error_op                // reserved 1 0 0 1 1 1
                    299: //
                    300: // *********************************************************************
                    301: //
                    302: //     restore/save operation decode table
                    303: //
                    304: // *********************************************************************
                    305:                                                //          5-4-3
                    306:        ALIGN
                    307: group_5a_op:   
                    308:        .byte   load_op                 // fld      0 0 0
                    309:        .byte   error_op                // reserved 0 0 1
                    310:        .byte   store_op                // fst      0 1 0
                    311:        .byte   store_pop               // fstp     0 1 1
                    312:        .byte   restore_op              // frstor   1 0 0
                    313:        .byte   error_op                // reserved 1 0 1
                    314:        .byte   save_op                 // fsave    1 1 0
                    315:        .byte   stsw_op                 // fstsw    1 1 1
                    316: //
                    317: // *********************************************************************
                    318: //
                    319: //     free register/store operation decode table
                    320: //
                    321: // *********************************************************************
                    322:                                                //          5-4-3
                    323:        ALIGN
                    324: group_5b_op:   
                    325:        .byte   free_op                 // ffree    0 0 0
                    326:        .byte   exchange_op             // fxch *   0 0 1
                    327:        .byte   store_op                // fst      0 1 0
                    328:        .byte   store_pop               // fstp     0 1 1
                    329:        .byte   ucom_op                 // fucom    1 0 0
                    330:        .byte   ucom_pop                // fucomp   1 0 1
                    331:        .byte   error_op                // reserved 1 1 0
                    332:        .byte   error_op                // reserved 1 1 1
                    333: //
                    334: // *********************************************************************
                    335: //
                    336: //     transfer status operation decode table
                    337: //
                    338: // *********************************************************************
                    339:                                                //          5-4-3
                    340:        ALIGN
                    341: group_7b_op:   
                    342:        .byte   free_op                 // ffree *  0 0 0
                    343:        .byte   exchange_op             // fxch *   0 0 1
                    344:        .byte   store_pop               // fstp *   0 1 0
                    345:        .byte   store_pop               // fstp *   0 1 1
                    346:        .byte   stsw_op                 // fstsw    1 0 0
                    347:        .byte   error_op                // reserved 1 0 1
                    348:        .byte   error_op                // reserved 1 1 0
                    349:        .byte   error_op                // reserved 1 1 1
                    350: //
                    351: // *********************************************************************
                    352: //
                    353: //     load/store environment/control word operand 1 loc/for table
                    354: //
                    355: // *********************************************************************
                    356:                                                     //          5-4-3
                    357:        ALIGN
                    358: group_1a_op1_lf:       
                    359:        .value  memory_opnd*0x100+single_real // fld      0 0 0
                    360:        .value  null*0x100+null              // reserved 0 0 1
                    361:        .value  stack_top*0x100+extended_fp   // fst      0 1 0
                    362:        .value  stack_top*0x100+extended_fp   // fstp     0 1 1
                    363:        .value  null*0x100+null               // fldenv   1 0 0
                    364:        .value  null*0x100+null               // fldcw    1 0 1
                    365:        .value  null*0x100+null              // fstenv   1 1 0
                    366:        .value  null*0x100+null              // fstcw    1 1 1
                    367: //
                    368: // *********************************************************************
                    369: //
                    370: //       transcendental operand/result format codes
                    371: //
                    372: // *********************************************************************
                    373: //
                    374: #define        null_fmt        0
                    375: #define        top_fmt         1       
                    376: #define        topm1_fmt       2       
                    377: #define        topp1_fmt       3
                    378: #define        op1     0x40
                    379: #define        op2     0x10
                    380: #define        res1    4
                    381: #define        res2    1
                    382: //
                    383: //     transcendental operand/result form at types
                    384: //
                    385: // #define     fprem_type      op1*top_fmt+op2*topm1_fmt+res1*top_fmt
                    386: #define        fprem_type      0x64
                    387: // #define     fyl2x_type      op1*top_fmt+op2*topm1_fmt+res1*topm1_fmt
                    388: #define        fyl2x_type      0x68
                    389: #define        fdecstp_type    null_fmt
                    390: #define        fchs_type       op1*top_fmt+res1*top_fmt
                    391: #define        fld1_type       res1*topp1_fmt
                    392: #define        ftst_type       op1*top_fmt
                    393: // #define     fptan_type      op1*top_fmt+res1*top_fmt+res2*topp1_fmt
                    394: #define        fptan_type      0x47
                    395: // #define     fpatan_type     op1*topm1_fmt+op2*top_fmt+res1*topm1_fmt
                    396: #define        fpatan_type     0x98
                    397: #define        fscale_type     op1*topm1_fmt+op2*top_fmt+res1*top_fmt
                    398: //
                    399: //fsin_type   equ op1*top_fmt + res1*top_fmt
                    400: //fcos_type   equ op1*top_fmt + res1*top_fmt
                    401: //
                    402: //     operand/result format/location table
                    403: //
                    404:        ALIGN
                    405: group_1bb_lf:  
                    406:        .value  null                                    // null_fmt
                    407:        .value  stack_top*0x100+extended_fp             // top_fmt
                    408:        .value  stack_top_minus_1*0x100+extended_fp     // topm1_fmt
                    409:        .value  stack_top_plus_1*0x100+extended_fp      // topp1_fmt
                    410: //
                    411: // *********************************************************************
                    412: //
                    413: //     transcendental operand/result format/location type table
                    414: //
                    415: // *********************************************************************
                    416:                                                //          5-4-3-2-1-0
                    417:        ALIGN
                    418: group_1bb_type:        
                    419:        .byte   fchs_type               // fchs     1 0 0 0 0 0
                    420:        .byte   fchs_type               // fabs     1 0 0 0 0 1
                    421:        .byte   fdecstp_type            // reserved 1 0 0 0 1 0
                    422:        .byte   fdecstp_type            // reserved 1 0 0 0 1 1
                    423:        .byte   ftst_type               // ftst     1 0 0 1 0 0
                    424:        .byte   ftst_type               // fxam     1 0 0 1 0 1
                    425:        .byte   fdecstp_type            // reserved 1 0 0 1 1 0
                    426:        .byte   fdecstp_type            // reserved 1 0 0 1 1 1
                    427:        .byte   fld1_type               // fld1     1 0 1 0 0 0
                    428:        .byte   fld1_type               // fldl2t   1 0 1 0 0 1
                    429:        .byte   fld1_type               // fldl2e   1 0 1 0 1 0
                    430:        .byte   fld1_type               // fldpi    1 0 1 0 1 1
                    431:        .byte   fld1_type               // fldlg2   1 0 1 1 0 0
                    432:        .byte   fld1_type               // fldln2   1 0 1 1 0 1
                    433:        .byte   fld1_type               // fldz     1 0 1 1 1 0
                    434:        .byte   fdecstp_type            // reserved 1 0 1 1 1 1
                    435:        .byte   fchs_type               // f2xm1    1 1 0 0 0 0
                    436:        .byte   fyl2x_type              // fyl2x    1 1 0 0 0 1
                    437:        .byte   fptan_type              // fptan    1 1 0 0 1 0
                    438:        .byte   fpatan_type             // fpatan   1 1 0 0 1 1
                    439:        .byte   fptan_type              // fxtract  1 1 0 1 0 0
                    440:        .byte   fprem_type              // fprem1   1 1 0 1 0 1
                    441:        .byte   fdecstp_type            // fdecstp  1 1 0 1 1 0
                    442:        .byte   fdecstp_type            // fincstp  1 1 0 1 1 1
                    443:        .byte   fprem_type              // fprem    1 1 1 0 0 0
                    444:        .byte   fyl2x_type              // fyl2xp1  1 1 1 0 0 1
                    445:        .byte   fchs_type               // fsqrt    1 1 1 0 1 0
                    446:        .byte   fptan_type              // fsincos  1 1 1 0 1 1
                    447:        .byte   fchs_type               // frndint  1 1 1 1 0 0
                    448:        .byte   fscale_type             // fscale   1 1 1 1 0 1
                    449:        .byte   fchs_type               // fsin     1 1 1 1 1 0
                    450:        .byte   fchs_type               // fcos     1 1 1 1 1 1
                    451: //
                    452: // *********************************************************************
                    453: //
                    454: //     load/store short integer/tempreal operand 1 format table
                    455: //
                    456: // *********************************************************************
                    457:                                                //          5-4-3
                    458:        ALIGN
                    459: group_3a_op1_fmt:      
                    460:        .byte   int32                   // fild     0 0 0
                    461:        .byte   null                    // reserved 0 0 1
                    462:        .byte   extended_fp             // fist     0 1 0
                    463:        .byte   extended_fp             // fistp    0 1 1
                    464:        .byte   null                    // reserved 1 0 0
                    465:        .byte   extended_fp             // fld      1 0 1
                    466:        .byte   null                    // reserved 1 1 0
                    467:        .byte   extended_fp             // fstp     1 1 1
                    468: // *********************************************************************
                    469: //
                    470: //     load/store integer/tempreal/bcd operand 1 location table
                    471: //
                    472: // *********************************************************************
                    473:                                                //          5-4-3
                    474:        ALIGN
                    475: group_3a_7a_op1_loc:   
                    476:        .byte   memory_opnd             // fild     0 0 0
                    477:        .byte   null                    // reserved 0 0 1
                    478:        .byte   stack_top               // fist     0 1 0
                    479:        .byte   stack_top               // fistp    0 1 1
                    480:        .byte   memory_opnd             // (fbld)   1 0 0
                    481:        .byte   memory_opnd             // f(i)ld   1 0 1
                    482:        .byte   stack_top               // (fbstp)  1 1 0
                    483:        .byte   stack_top               // f(i)stp  1 1 1
                    484: //
                    485: // *********************************************************************
                    486: //
                    487: //     load/store short integer/tempreal result format table
                    488: //
                    489: // *********************************************************************
                    490:                                                //          5-4-3
                    491:        ALIGN
                    492: group_3a_res_fmt:      
                    493:        .byte   extended_fp             // fild     0 0 0
                    494:        .byte   null                    // reserved 0 0 1
                    495:        .byte   int32                   // fist     0 1 0
                    496:        .byte   int32                   // fistp    0 1 1
                    497:        .byte   null                    // reserved 1 0 0
                    498:        .byte   extended_fp             // fld      1 0 1
                    499:        .byte   null                    // reserved 1 1 0
                    500:        .byte   extended_fp             // fstp     1 1 1
                    501: // *********************************************************************
                    502: //
                    503: //     load/store integer/tempreal/bcd result location table
                    504: //
                    505: // *********************************************************************
                    506:                                                //          5-4-3
                    507:        ALIGN
                    508: group_3a_7a_res_loc:   
                    509:        .byte   stack_top               // fild     0 0 0
                    510:        .byte   null                    // reserved 0 0 1
                    511:        .byte   memory_opnd             // fist     0 1 0
                    512:        .byte   memory_opnd             // fistp    0 1 1
                    513:        .byte   stack_top_plus_1        // (fbld)   1 0 0
                    514:        .byte   stack_top_plus_1        // f(i)ld   1 0 1
                    515:        .byte   memory_opnd             // (fbstp)  1 1 0
                    516:        .byte   memory_opnd             // f(i)stp  1 1 1
                    517: //
                    518: // *********************************************************************
                    519: //
                    520: //     load/store state/status word operand 1 loc/for table
                    521: //
                    522: // *********************************************************************
                    523:                                                     //          5-4-3
                    524:        ALIGN
                    525: group_5a_op1_lf:       
                    526:        .value  memory_opnd*0x100+double_real // fld      0 0 0
                    527:        .value  null*0x100+null              // reserved 0 0 1
                    528:        .value  stack_top*0x100+extended_fp   // fst      0 1 0
                    529:        .value  stack_top*0x100+extended_fp   // fstp     0 1 1
                    530:        .value  null*0x100+null               // frstor   1 0 0
                    531:        .value  null*0x100+null              // reserved 1 0 1
                    532:        .value  null*0x100+null              // fsave    1 1 0
                    533:        .value  null*0x100+null              // fstsw    1 1 1
                    534: // *********************************************************************
                    535: //
                    536: //     bcd/long integer operand 1 format table
                    537: //
                    538: // *********************************************************************
                    539:                                                //          5-4-3
                    540:        ALIGN
                    541: group_7a_op1_fmt:      
                    542:        .byte   int16                   // fild     0 0 0
                    543:        .byte   null                    // reserved 0 0 1
                    544:        .byte   extended_fp             // fist     0 1 0
                    545:        .byte   extended_fp             // fistp    0 1 1
                    546:        .byte   bcd                     // fbld     1 0 0
                    547:        .byte   int64                   // fild     1 0 1
                    548:        .byte   extended_fp             // fbstp    1 1 0
                    549:        .byte   extended_fp             // fistp    1 1 1
                    550: //
                    551: // *********************************************************************
                    552: //
                    553: //     bcd/long integer result format table
                    554: //
                    555: // *********************************************************************
                    556:                                                //          5-4-3
                    557:        ALIGN
                    558: group_7a_res_fmt:      
                    559:        .byte   extended_fp             // fild     0 0 0
                    560:        .byte   null                    // reserved 0 0 1
                    561:        .byte   int16                   // fist     0 1 0
                    562:        .byte   int16                   // fistp    0 1 1
                    563:        .byte   extended_fp             // fbld     1 0 0
                    564:        .byte   extended_fp             // fild     1 0 1
                    565:        .byte   bcd                     // fbstp    1 1 0
                    566:        .byte   int64                   // fistp    1 1 1
                    567: // for the return from e80387
                    568:        .set    KFL, 0x3bfff            // clear NT bit in flags
                    569:         .text
                    570: // ***********************************************************************
                    571: //                     e80387:
                    572: //
                    573: //     function:
                    574: //             executive program for 80387 emulator.
                    575: //             decode instruction, i.e. separate operation,operand
                    576: //             and result info; get memory operand pointer.
                    577: //
                    578: //     inputs:
                    579: //             instruction (in memory).
                    580: //
                    581: //     outputs:
                    582: //             op1, op2, operation, result, result2, and memory operand
                    583: //             pointer info
                    584: //
                    585: //     data accessed:
                    586: //             - op1_format                    op1_location
                    587: //             - op1_use_up                    op2_format
                    588: //             - op2_location                  op2_use_up
                    589: //             - operation_type                result_location
                    590: //             - result_format                 result2_format
                    591: //             - result2_location
                    592: //
                    593: //     data changed:
                    594: //             - mem_operand_pointer           op1_location
                    595: //             - op1_format                    op1_use_up
                    596: //             - op2_format                    op2_location
                    597: //             - op2_use_up                    result_location
                    598: //             - result_format                 result2_format
                    599: //             - result2_location
                    600: //
                    601: // ***************************************************************************
                    602: //     assume  %ds:a_med
                    603: //     ---------------------JKD
                    604: //     .data
                    605: //LJKD:
                    606: //     .string         * ADDRESS is %x %x\n*
                    607: //     .text
                    608: //
                    609: //     ---------------------JKD
                    610:        ALIGN
                    611: _e80387:       //proc
                    612:        movl    %esp, %ebp
                    613:        movl    0x4(%ebp),%esp          // pick up state pointer.
                    614:        subl    $(WORK_AREA_SIZE),%esp // stack space
                    615:        mov     %esp,%ebp               //set bp to global_reentrant_seg
                    616:        
                    617:        /* establish addressibility to the floating point state */
                    618:        push    $FPSTATESEL             // set window to fp registers
                    619:        pop     %gs                     // in u area
                    620: 
                    621:         /* clear the work area */
                    622:         lea     work_area(%ebp),%edi
                    623:         xorl    %eax,%eax
                    624:         movl    $WORK_AREA_WORDS,%ecx    // number of longs to clear.
                    625:        
                    626:        FALLSTHRU
                    627: 1:
                    628:         movl    %eax,0(%edi)
                    629:        addl    $4,%edi
                    630:        decl    %ecx
                    631:        testl   %ecx,%ecx
                    632:        jg      1b
                    633: 
                    634: /* always 32 bits */
                    635: //     movb    $0, is16bit(%ebp)       // record we are not 16 bit
                    636: 
                    637:        FALLSTHRU
                    638: continu_init:
                    639: 
                    640: #ifdef FP_COUNTERS
                    641:        /* this keeps track of how many floating point ops were emulated */
                    642:        push    %ss
                    643:        pop     %ds
                    644:        movl    $_fp_total,%ecx
                    645:        movl    0(%ecx),%eax
                    646:        inc     %eax
                    647:        movl    %eax,0(%ecx)
                    648: #endif /* FP_COUNTERS */
                    649: 
                    650:        movb    $null,%dl                       // initialize op1 and op2
                    651:        movb    %dl,%cl                 //  format registers to null
                    652:        MOVL    $do_nothing*0x100+do_nothing,%bx // initialize useups
                    653:        lds     saved_eip(%ebp),%esi // load instruction pointer
                    654: 
                    655:        movb    $1,oprnd_siz32(%ebp)    //set operand size=32
                    656:        movb    $1,addrs_siz32(%ebp)    //set address size=32
                    657: #ifdef MS_DOS
                    658:        lar     saved_cs(%ebp),%eax     //load access right byte of cs
                    659:        test    $0x00400000,%eax                //check 32 bit default ?
                    660:        jnz     get_opcode              //if yes continue
                    661:        decb    oprnd_siz32(%ebp)       //else default is 16bit
                    662:        decb    addrs_siz32(%ebp)
                    663: #endif /* MS_DOS */
                    664:        FALLSTHRU
                    665: get_opcode:    
                    666:        MOVL    (%esi),%ax              //load two bytes
                    667: 
                    668:        inc     %esi                    //inc pointer
                    669:        andb    $0x87,%al                       // is the first byte a prefix
                    670:        jns     get_opcode              // yes skip for now
                    671:        addb    $0x40,%ah                       // no, add 1 to mod
                    672:        rclb    $1,%al                  // cf set if mod = 3
                    673:        rolb    $1,%al                  // form handler table index
                    674:        MOVL    $0x3800,%si             // form bits 5-4-3 index in si
                    675:        andw    %ax,%si
                    676:        shrw    $11,%si
                    677:        MOVL    $0x001e,%di             // form group handler table
                    678:        andw    %ax,%di                 //  index in di
                    679:        shlw    $1,%di                  // take care of dd instead of dw
                    680:        push    %cs                     // copy cs to ds for addressing
                    681:        pop     %ds                     //  all the tables
                    682:        movswl  %si,%esi
                    683:        movswl  %di,%edi
                    684:        call    *%cs:group_handler(%edi)     // call the proper group handler
                    685:        andb    $0x07,%ah                       // store register number (r/m)
                    686:        movw    %ax,operation_type(%ebp)        // and operation type
                    687:        movw    %dx,op1_format(%ebp) // store operand and result
                    688:        movw    %cx,op2_format(%ebp) // formats and locations
                    689:        movw    %si,result_format(%ebp)
                    690:        movw    %di,result2_format(%ebp)
                    691:        movb    %bh,op1_use_up(%ebp)    // store op1 and op2 useups
                    692:        movb    %bl,op2_use_up(%ebp)
                    693:        lds     saved_eip(%ebp),%esi // load instruction pointer
                    694:        mov     %esi,instruction_pointer(%ebp) // save old pointer
                    695:        movw    %ds,instruction_pointer+4(%ebp)
                    696:        XORL    %cx,%cx                 // extended addressing = false
                    697:        xor     %ebx,%ebx
                    698:        FALLSTHRU
                    699: segment_ds:
                    700:        movw    saved_ds(%ebp),%dx      // assume ds is pointer base
                    701: get_mod_rm_byte:
                    702:        MOVL    (%esi),%ax      // load first two bytes again
                    703: 
                    704:        inc     %esi                    // bump instruction pointer
                    705:        andb    %al,%al                 // is there an override?
                    706:        js      got_mod_rm              // no, ah contains mod r/m byte
                    707:        cmpb    $0x67,%al                       // is there an address overide
                    708:        jne     check_prefix66          // no is it 66
                    709:        xorb    $1,addrs_siz32(%ebp)    //yes adjust address size
                    710:        jmp     get_mod_rm_byte
                    711:        ALIGN
                    712: check_prefix66:
                    713:        cmpb    $0x66,%al               //is it 66 overide
                    714:        jne     other_prefix            //no some other prefix
                    715:        xorb    $1,oprnd_siz32(%ebp)    //adjust operand size
                    716:        jmp     get_mod_rm_byte
                    717:        ALIGN
                    718: other_prefix:
                    719:        decw    %cx                     // yes, boolean = true
                    720:        MOVL    saved_fs(%ebp),%dx      // load fs: override
                    721:        cmpb    $0x64,%al                       // is it fs: ?
                    722:        je      get_mod_rm_byte         // yes, scan past prefix byte
                    723:        MOVL    saved_gs(%ebp),%dx      // load gs: override
                    724:        cmpb    $0x65,%al                       // is it gs: ?
                    725:        je      get_mod_rm_byte         // yes, scan past prefix byte
                    726:        MOVL    saved_es(%ebp),%dx      // load es: override
                    727:        cmpb    $0x26,%al                       // is it es: ?
                    728:        je      get_mod_rm_byte         // yes, scan past prefix byte
                    729:        MOVL    saved_cs(%ebp),%dx      // no, load cs: override
                    730:        cmpb    $0x2e,%al                       // is it cs: ?
                    731:        je      get_mod_rm_byte         // yes, scan past prefix byte
                    732:        MOVL    old_ss(%ebp),%dx                        // no, load ss: override
                    733:        cmpb    $0x36,%al                       // is it ss: ?
                    734:        je      get_mod_rm_byte         // yes, scan past prefix byte
                    735:        jmp     segment_ds              // no, assume ds: override
                    736:        ALIGN
                    737: got_mod_rm:
                    738: 
                    739:        inc     %esi                    // bump instruction pointer
                    740:        movb    %ah,%bl                 // save mod r/m in bl
                    741: 
                    742:        testb   $1,addrs_siz32(%ebp)    //check if 32bit addressing
                    743:        jnz     addrs_32_bit
                    744: 
                    745:        movzwl    (%esi),%eax      // load possible displacement
                    746: 
                    747:        push    %eax
                    748:        MOVL    saved_ds(%ebp), %ax     // restore %ds register to its initial
                    749:        movw    %ax, %ds                // value.
                    750:        pop     %eax
                    751: 
                    752:        cmpb    $0x0c0,%bl                      // is mod = 3?
                    753:        jnc     store_return            // yes, no memory operand
                    754:        shlb    $1,%bl                  // no, is mod = 2?
                    755:        jc      mod_2                   // yes, disp = disp-hi: disp-lo
                    756:        js      mod_1                   // branch if mod = 1
                    757:        andb    $0x0e,%bl                       // mod = 0
                    758:        cmpb    $0x0c,%bl                       // does r/m = 6?
                    759:        je      store_ea                // yes, ea = disp-hi: disp-lo
                    760:        xorw    %ax,%ax                 // no, disp = 0
                    761:        dec     %esi                    // subtract one for return
                    762:        FALLSTHRU
                    763: mod_1:
                    764:        dec     %esi                    // subtract one for return
                    765:        cbtw                             // extend disp to 16 bits
                    766: mod_2:
                    767:        and     $0x0000000e,%ebx                // ax now = real displacement
                    768:        shl     $1,%ebx                 // take care of dd instead of dw
                    769:        call    *%cs:rm_handler(%ebx)    // call r/m handler (cs <> ds)
                    770:        FALLSTHRU
                    771: store_ea:
                    772:        inc     %esi                    // add two for return address
                    773:        inc     %esi
                    774: store_on:
                    775:        movw    %dx,mem_operand_pointer+4(%ebp) // store base
                    776:        mov     %eax,mem_operand_pointer(%ebp) // store offset
                    777:        testb   $0x80,operation_type(%ebp)      // update sr_memop pointer?
                    778:        jnz     store_return            // no, must be administrative
                    779:        movw    %dx,%gs:sr_mem_base     // yes, store base in a?msr
                    780:        mov     %eax,%gs:sr_mem_offset  // store offset in a?msr
                    781:        FALLSTHRU
                    782: store_return:
                    783:        mov     %esi,saved_eip(%ebp)    // update return address
                    784:        mov     offset_op1_rec,%esi     //set up for fetch_an_op
                    785:        mov     $offset_operand1,%edi
                    786:        movl    $0, before_error_signals(%ebp)
                    787:        movl    $0, extra_dword_reg(%ebp)
                    788:        movl    $0, extra_dword_reg+4(%ebp)
                    789:        movl    $0, extra_dword_reg+8(%ebp)
                    790:        call    fetch_an_op             // fetch op1
                    791:        pushw   %ax                     //save stack error flag
                    792:        mov     offset_op2_rec,%esi     //set up for fetch_an_op
                    793:        mov     $offset_operand2,%edi
                    794:        call    fetch_an_op             // fetch op2
                    795:        popw    %bx                     // combine stack error flags
                    796:        orw     %bx,%ax                 // set/reset zf, clear cf
                    797:        movb    operation_type(%ebp),%bl        // load operation type
                    798:        rclb    $1,%bl                  // shift save ptrs flag to cf
                    799:        jnc     pending_unmasked_xcptns_// all non-administratives must check
                    800:        movb    operation_type(%ebp),%cl// duo-form administratives are all
                    801:        cmpb    $ldenv_op,%cl                   // treated as unwaited forms:
                    802:        ja      do_operation            // fnstenv, fnstcw, fnstsw, and fnclex
                    803:        cmpb    $init_op,%cl                                    // and fninit
                    804:        je      do_operation                            // and
                    805:        cmpb    $save_op,%cl            // fnsave all ignore pending unmasked
                    806:        je      do_operation                    // exceptions and just execute.
                    807:        FALLSTHRU
                    808: pending_unmasked_xcptns_:
                    809:        movb    %gs:sr_masks,%cl
                    810:        notb    %cl
                    811:        andb    $0x3f,%cl
                    812:        andb    %gs:sr_errors,%cl
                    813:        jz      no_pending_unmasked_xcptns
                    814:        int     $16
                    815:        jmp     pending_unmasked_xcptns_
                    816:        ALIGN
                    817: no_pending_unmasked_xcptns:
                    818:        testb   $0x80,operation_type(%ebp)
                    819:        jnz     do_operation
                    820:        push    %eax
                    821:        les     instruction_pointer(%ebp),%eax // load instruction ptr
                    822:        mov     %eax,%gs:sr_instr_offset        // store offset in status reg
                    823:        movw    %es,%gs:sr_instr_base   // store base in status reg
                    824:        pop     %eax
                    825:        FALLSTHRU
                    826: do_operation:
                    827:        movswl  %bx,%ebx
                    828:        rol     $1,%ebx                 //take care of dd
                    829:        orw     %ax,%ax         // give zf value expected by following call
                    830: 
                    831:        call    *%cs:op_table(%ebx)          // call instruction operator
                    832:        movb    %gs:sr_masks,%al                //set zf to false if any
                    833:        notb    %al                     // unmasked errors,
                    834:        andb    $0x7f,%al       //get rid of es bit
                    835:        andb    %gs:sr_errors,%al               //set al to 0 if none
                    836:        jz      release_stack
                    837:        movb    $0,%al
                    838:        movb    operation_type(%ebp),%cl
                    839:        testb   $0x80,%cl
                    840:        jz      mark_errors
                    841:        cmpb    $ldenv_op,%cl
                    842:        ja      get_done
                    843:        FALLSTHRU
                    844: mark_errors:
                    845:        orw     $0x8080, %gs:sr_errors  //taking care of es and B
                    846:        movb    $0x02,%al                       // load nonzero ie mask
                    847:        jmp     get_done
                    848:        ALIGN
                    849: release_stack:
                    850:        andw    $0x7f7f, %gs:sr_errors
                    851: get_done:
                    852: 
                    853:        /* 
                    854:         * This code checks if the next instruction is a floating point op.
                    855:         * If so, just process it and save the fault.
                    856:         */
                    857:        movl    saved_eip(%ebp), %esi
                    858:        movl    %esi,%edi
                    859: 
                    860: #if    0
                    861:        /* 
                    862:         * This is to test that we are not within 11 bytes of the end
                    863:         * of a page.  If we are, it is best to let the processor trap
                    864:         * into the kernel for the next instruction because the code page 
                    865:         * may not be in memory.  It is not good when the page is not in
                    866:         * memory and the kernel attempts to reference that location.
                    867:         */
                    868:        andl    $0xff5,%edi             // isolate bits that will be all ones
                    869:        xor     $0xff5,%edi             // are they all ones?
                    870:        jz      all_done                // yes - let processor handle it.
                    871:        andl    $0xfff,%edi             // start of a new page?
                    872:        jz      all_done                // yes - do not take a chance
                    873: #endif
                    874: 
                    875:        /*
                    876:         * The last check is to make sure we are not going through a
                    877:         * floating point loop which will not end.  After 5 instructions
                    878:         * return to user space.
                    879:         */
                    880:        mov     inst_counter(%ebp),%ecx // get count
                    881:        inc     %ecx
                    882:        mov     %ecx,inst_counter(%ebp)
                    883:        cmpb    $5,%cl                  // too many inst?
                    884:        jz      all_done                // yes return to user space
                    885: 
                    886:        /*
                    887:         * Now check if the next instruction is a floating point opcode.
                    888:         */
                    889:        movl    0(%esi),%ecx            
                    890:        andl    $0xf8,%ecx
                    891:        cmpl    $0xd8,%ecx              // escape sequence for fp instructions
                    892:        je      continu_init            // it is an fp instruction
                    893: 
                    894:        FALLSTHRU
                    895: all_done:
                    896: 
                    897:        andb    saved_flags+1(%ebp),%al         // interrupt enabled?
                    898:        jz      no_exception            // branch if no exception
                    899:        int     $16                     // 80387 exception interrupt
                    900:        FALLSTHRU
                    901: no_exception:
                    902: 
                    903:        addl    $(WORK_AREA_SIZE),%esp  // stack space
                    904: 
                    905:        popl    %gs
                    906:        popl    %fs
                    907:        popl    %es
                    908:        popl    %ds
                    909:        popa
                    910:        addl    $8, %esp        // get TRAPNO and ERROR off the stack
                    911: 
                    912:        // User may have set NT bit before doing a system call.
                    913:        // This would be bad, so we turn it off here.
                    914:        // On a system call, the flags get pushed, then popped.  Since the
                    915:        // VM bit always gets zeroed when pushed, we do not need to clear it.
                    916:        andl    $KFL, 8(%esp)    // clear the NT bit in the flags
                    917:        iret
                    918: 
                    919:        ALIGN
                    920: rm_0:
                    921:        addw    saved_ebx(%ebp),%ax     // ea = (bx) + (si) + disp
                    922: rm_4:
                    923:        addw    saved_esi(%ebp),%ax     // ea = (si) + disp
                    924:        ret
                    925:        ALIGN
                    926: rm_5:
                    927:        addw    saved_edi(%ebp),%ax     // ea = (di) + disp
                    928:        ret
                    929:        ALIGN
                    930: rm_1:
                    931:        addw    saved_edi(%ebp),%ax     // ea = (bx) + (di) + disp
                    932: rm_7:
                    933:        addw    saved_ebx(%ebp),%ax     // ea = (bx) + disp
                    934:        ret
                    935:        ALIGN
                    936: rm_2:
                    937:        addw    saved_esi(%ebp),%ax     // ea = (bp) + (si) + disp
                    938: rm_6:
                    939:        addw    saved_ebp(%ebp),%ax     // ea = (bp) + disp
                    940:        jcxz    segment_ss              // branch if no override given
                    941:        ret
                    942:        ALIGN
                    943: rm_3:
                    944:        addw    saved_edi(%ebp),%ax     // ea = (bp) + (di) + disp
                    945:        jmp     rm_6                    // merge with r/m = 6
                    946:        ALIGN
                    947: segment_ss:
                    948:        MOVL    old_ss(%ebp),%dx        // for r/m = 2, 3, or 6, the
                    949:        ret                             // standard base = ss
                    950:        ALIGN
                    951: //
                    952: addrs_32_bit:  
                    953:        xor     %edi,%edi                       //clear edi
                    954:        cmpb    $0xc0, %ah      
                    955:        jae     no_sib
                    956:        andb    $0x07,%ah                       //check if sib present
                    957:        cmpb    $0x04,%ah
                    958:        jne     no_sib                  //
                    959:        movb    (%esi),%bh              //yes get  sib byte
                    960:        inc     %esi
                    961:        FALLSTHRU
                    962: no_sib:
                    963:        mov     (%esi),%eax             //get displacement
                    964: 
                    965:        push    %ds
                    966:        pop     %fs                     / save selector
                    967: //
                    968: //     assume  %ds:a_msrs
                    969: //
                    970: //        push    a_msrs                  / push the dynamic selector
                    971: //        pop     %ds                     /  for the a?msr segment
                    972: //        push    a_msr_selector          / and load it into ds
                    973: //        pop     %ds
                    974: //
                    975: //     assume  %ds:a_msr               ; assume ds=a?msr from here on
                    976: //
                    977:        push    %eax
                    978:        MOVL    saved_ds(%ebp), %ax     // restore %ds register to its initial
                    979:        movw    %ax, %ds                //segment value.
                    980:        pop     %eax
                    981: 
                    982:        cmpb    $0x0c0,%bl                      // is mod = 3?
                    983:        jnc     store_return            // yes, no memory operand
                    984:        add     $4,%esi
                    985:        shlb    $1,%bl                  // no, is mod = 2?
                    986:        jc      mod32_2                 // yes, disp = disp-hi: disp-lo
                    987:        js      mod32_1                 // branch if mod = 1
                    988:        andb    $0x0e,%bl                       // mod = 0
                    989:        inc     %edi                    // set flag
                    990:        cmpb    $0x0a,%bl                       // does r/m = 5?i
                    991:        je      store_on                // yes, ea = disp-hi: disp-lo
                    992:        xor     %eax,%eax                       // no, disp = 0
                    993:        dec     %esi                    // subtract one for return
                    994:        FALLSTHRU
                    995: mod32_1:
                    996:        sub     $3,%esi                 // adjust esi
                    997:        movsbl  %al,%eax                // extend disp to 32 bits
                    998: mod32_2:
                    999:        andb    $0x0f,%bl                       //check if sib present
                   1000:        cmpb    $0x8,%bl
                   1001:        je      process_sib
                   1002:        and     $0x0000000e,%ebx                //no sib get base register
                   1003:        shl     $1,%ebx                 //form index in table
                   1004:        call    *%cs:base32(%ebx)
                   1005:        jmp     store_on                //store displacement
                   1006:        ALIGN
                   1007: 
                   1008: process_sib:   
                   1009:        movb    %bh,%bl                 //
                   1010:        and     %edi,%edi                       //edi=1 if mod=0
                   1011:        jz      get_base                //
                   1012:        andb    $0x07,%bh                       //get last 3 bits
                   1013:        cmpb    $0x05,%bh                       //if mod=0 and basereg=5,no base
                   1014:        jne     get_base
                   1015:        mov     %fs:(%esi),%eax         //get displacement
                   1016:        add     $4,%esi                 // adjust esi
                   1017:        jmp     get_sir                 //get sir
                   1018:        ALIGN
                   1019: 
                   1020: get_base:      
                   1021:        MOVL    %bx,%di                 //save bx
                   1022:        and     $0x00000007,%ebx                //form index in the base table
                   1023:        shl     $2,%ebx
                   1024:        call    *%cs:base32(%ebx)
                   1025:        MOVL    %di,%bx                 //restore bx
                   1026: 
                   1027:        FALLSTHRU
                   1028: get_sir:       
                   1029:        movb    %bl,%bh                 //load sib byte
                   1030:        andb    $0x038,%bh                      //get midle 3 bits
                   1031:        cmpb    $0x020,%bh                      //index=4 no index reg
                   1032:        je      store_on                //if no index jmp out
                   1033:        movb    %bl,%cl                 //save bl
                   1034:        rolb    $2,%cl                  //get high order 2 bits
                   1035:        andb    $0x03,%cl                       //in the low bits
                   1036:        shrb    $1,%bl                  //form index into table
                   1037:        and     $0x0000001c,%ebx
                   1038:        call    *%cs:index32(%ebx)               //add sir to displacement
                   1039:        jmp     store_on
                   1040:        ALIGN
                   1041: 
                   1042: base_0:        
                   1043:        add     saved_eax(%ebp),%eax
                   1044:        ret
                   1045:        ALIGN
                   1046: base_1:
                   1047:        add     saved_ecx(%ebp),%eax
                   1048:        ret
                   1049:        ALIGN
                   1050: base_2:
                   1051:        add     saved_edx(%ebp),%eax
                   1052:        ret
                   1053:        ALIGN
                   1054: base_3:
                   1055:        add     saved_ebx(%ebp),%eax
                   1056:        ret
                   1057:        ALIGN
                   1058: base_4:
                   1059:        add     old_esp(%ebp),%eax
                   1060:        jcxz    segmentss
                   1061:        ret
                   1062:        ALIGN
                   1063: base_5:
                   1064:        add     saved_ebp(%ebp),%eax
                   1065:        jcxz    segmentss
                   1066:        ret
                   1067:        ALIGN
                   1068: segmentss:     
                   1069:        MOVL    old_ss(%ebp),%dx                // for esp, ebp as base registers
                   1070:        ret
                   1071:        ALIGN
                   1072: 
                   1073: base_6:
                   1074:        add     saved_esi(%ebp),%eax
                   1075:        ret
                   1076:        ALIGN
                   1077: base_7:
                   1078:        add     saved_edi(%ebp),%eax
                   1079:        ret
                   1080:        ALIGN
                   1081: 
                   1082: index_0:       
                   1083:        mov     saved_eax(%ebp),%edi
                   1084:        shll    %cl,%edi
                   1085:        add     %edi,%eax
                   1086:        ret
                   1087:        ALIGN
                   1088: index_1:       
                   1089:        mov     saved_ecx(%ebp),%edi
                   1090:        shll    %cl,%edi
                   1091:        add     %edi,%eax
                   1092:        ret
                   1093:        ALIGN
                   1094: index_2:       
                   1095:        mov     saved_edx(%ebp),%edi
                   1096:        shll    %cl,%edi
                   1097:        add     %edi,%eax
                   1098:        ret
                   1099:        ALIGN
                   1100: index_3:       
                   1101:        mov     saved_ebx(%ebp),%edi
                   1102:        shll    %cl,%edi
                   1103:        add     %edi,%eax
                   1104: index_4:
                   1105:        ret
                   1106:        ALIGN
                   1107: index_5:       
                   1108:        mov     saved_ebp(%ebp),%edi
                   1109:        shll    %cl,%edi
                   1110:        add     %edi,%eax
                   1111:        ret
                   1112:        ALIGN
                   1113: index_6:       
                   1114:        mov     saved_esi(%ebp),%edi
                   1115:        shll    %cl,%edi
                   1116:        add     %edi,%eax
                   1117:        ret
                   1118:        ALIGN
                   1119: index_7:       
                   1120:        mov     saved_edi(%ebp),%edi
                   1121:        shll    %cl,%edi
                   1122:        add     %edi,%eax
                   1123:        ret
                   1124:        ALIGN
                   1125: 
                   1126: //
                   1127: //     assume  %ds:a_med
                   1128: // ****************************************************************************
                   1129: //
                   1130: //     instruction group decoding handlers
                   1131: //
                   1132: // ****************************************************************************
                   1133: //
                   1134: //     these handlers load all necessary operation, operand, and result
                   1135: //     information into the following registers for storage into the
                   1136: //     global data records upon return:
                   1137: //
                   1138: //      dh => op1_location             dl => op1_format (null)
                   1139: //      ch => op2_location             cl => op2_format (null)
                   1140: //      si => result_location/result_format
                   1141: //      di => result2_location/result2_format
                   1142: //      bh => op1_use_up (do_nothing)  bl => op2_use_up (do_nothing)
                   1143: //      ah => (mod r/m, reg byte)      al => operation_type
                   1144: //
                   1145: //     parentheses indicate initial values upon entry.
                   1146: //
                   1147: // ****************************************************************************
                   1148: //
                   1149: //     group 0a - standard arithmetic instructions with short-real operands
                   1150: //
                   1151: arith_short_real:
                   1152:        movb    $single_real,%cl                // op2 format is short real
                   1153: op1_top_op2_mem_0a:
                   1154:        movb    $memory_opnd,%ch                // op2 loc is memory operand
                   1155: op1_top_stand_arith_op_0a:
                   1156:        movb    group_0a_0b_2a_4a_4b_6a_6b_op(%esi),%al // arithmetic op
                   1157:        MOVL    %dx,%di                 // result2 format is null
                   1158:        MOVL    $(stack_top*0x100+extended_fp),%dx // op1 top extended_fp
                   1159:        MOVL    %dx,%si                 // result is same as op1
                   1160:        FALLSTHRU
                   1161: arith_op_0a:
                   1162:        cmpb    $subr_op,%al            // is it fsubr ?
                   1163:        je      fsubr_0a                // reverse operands
                   1164:        cmpb    $divr_op,%al            // is it fdivr ?
                   1165:        je      fdivr_0a                // reverse operands
                   1166:        cmpb    $compar_pop,%al         // is it fcomp ?
                   1167:        jne     exit_0a                 // no, return
                   1168:        movb    $compar_op,%al          // yes, op type is compare
                   1169:        movb    pop_stack,%bh           // op1 useup is pop stack
                   1170:        FALLSTHRU
                   1171: exit_0a:
                   1172:        ret
                   1173:        ALIGN
                   1174: fsubr_0a:
                   1175:        movb    $sub_op,%al             // operation type is subtract
                   1176:        jmp     swap_0a         // switch operand locations
                   1177:        ALIGN
                   1178: fdivr_0a:
                   1179:        movb    $div_op,%al             // operation type is division
                   1180: swap_0a:
                   1181:        xchgb   %bl,%bh                 // switch operand useups
                   1182:        xchgw   %cx,%dx                 // switch operand fmt/loc
                   1183:        ret
                   1184:        ALIGN
                   1185: //
                   1186: //     group 2a - standard arithmetic instructions with short integer operands
                   1187: //
                   1188: arith_short_int:
                   1189:        movb    $int32,%cl              // op2 format is short integer
                   1190:        jmp     op1_top_op2_mem_0a      // finish loading information
                   1191:        ALIGN
                   1192: //
                   1193: //     group 4a - standard arithmetic instructions with long-real operands
                   1194: //
                   1195: arith_long_real:
                   1196:        movb    $double_real,%cl                // op2 format is long real
                   1197:        jmp     op1_top_op2_mem_0a      // load rest of information
                   1198:        ALIGN
                   1199: //
                   1200: //     group 6a - standard arithmetic instructions with word-integer operands
                   1201: //
                   1202: arith_word_int:
                   1203:        movb    $int16,%cl              // op2 format is word integer
                   1204:        jmp     op1_top_op2_mem_0a      // load rest of information
                   1205:        ALIGN
                   1206: //
                   1207: //     group 0b - standard arithmetic instructions with inner-stack operands
                   1208: //
                   1209: arith_top_reg:
                   1210:        MOVL    $(reg*0x100+extended_fp),%cx // op2 is reg extended_fp
                   1211:        jmp     op1_top_stand_arith_op_0a // load rest of information
                   1212:        ALIGN
                   1213: //
                   1214: //     group 6b - reversed arithmetic with register operand and pop useup
                   1215: //
                   1216: arith_reg_pop:
                   1217:        movb    pop_stack,%bl           // op2 useup is pop stack
                   1218: //
                   1219: //     group 4b - reversed arithmetic instructions with inner-stack operands
                   1220: //
                   1221: arith_reg_top:
                   1222:        movb    group_0a_0b_2a_4a_4b_6a_6b_op(%esi),%al // arithmetic ops
                   1223:        MOVL    %dx,%di                 // result2 format is null
                   1224:        MOVL    $(stack_top*0x100+extended_fp),%dx // op1 top extended_fp
                   1225:        MOVL    $(reg*0x100+extended_fp),%cx // op2 is reg extended_fp
                   1226:        MOVL    %cx,%si                 // result is same as op2
                   1227:        jmp     arith_op_0a             // load rest of information
                   1228:        ALIGN
                   1229: //
                   1230: //     group 1a - load/store instructions with short-real operand
                   1231: //                load/store environment/control word with string operand
                   1232: //
                   1233: load_short_real:
                   1234:        movb    group_1a_op(%esi),%al   // load operation type
                   1235:        shlw    $1,%si                  // change byte index to word
                   1236:        movswl  %si,%esi
                   1237:        MOVL    group_1a_op1_lf(%esi),%dx       // load op1 loc/for
                   1238:        MOVL    $(memory_opnd*0x100+single_real),%si // result format
                   1239:        FALLSTHRU
                   1240: load_store_1a:
                   1241:        MOVL    %cx,%di                 // result2 format is null
                   1242:        cmpb    $load_op,%al            // is it fld?
                   1243:        je      fld_1a                  // result goes to stack top
                   1244:        cmpb    $store_pop,%al          // is it fstp?
                   1245:        je      fstp_1a                 // op1 useup is pop stack
                   1246:        cmpb    $store_op,%al           // is it fst?
                   1247:        je      fst_1a                  // result goes to memory
                   1248:        MOVL    %di,%si                 // else, result format is null
                   1249:        ret
                   1250:        ALIGN
                   1251: fld_1a:
                   1252:        MOVL    $(stack_top_plus_1*0x100+extended_fp),%si // result is top
                   1253:        ret
                   1254:        ALIGN
                   1255: fstp_1a:
                   1256:        movb    pop_stack,%bh           // op1 useup is pop stack
                   1257:        movb    $store_op,%al           // operation type is store
                   1258: fst_1a:
                   1259:        ret
                   1260:        ALIGN
                   1261: //
                   1262: //     group 3a - short integer/tempreal load/store instructions
                   1263: //
                   1264: load_short_int:
                   1265:        movb    group_3a_7a_op(%esi),%al        // load operation type
                   1266:        movb    group_3a_res_fmt(%esi),%dl      // load result format
                   1267:        movb    group_3a_7a_res_loc(%esi),%dh // load result location
                   1268:        pushw   %dx                     // push result fmt/loc
                   1269:        movb    group_3a_op1_fmt(%esi),%dl      // load op1 format
                   1270:        movb    group_3a_7a_op1_loc(%esi),%dh // load op1 location
                   1271:        popw    %si                     // pop result fmt/loc
                   1272:        jmp     load_store_1a           // finish loading information
                   1273:        ALIGN
                   1274: //
                   1275: //     group 5a - load/store instructions with long-real operand
                   1276: //                  load/store state/status word instructions
                   1277: //
                   1278: load_long_real:
                   1279:        movb    group_5a_op(%esi),%al   // load operation type
                   1280:        shlw    $1,%si                  // change byte index to word
                   1281:        movswl  %si,%esi
                   1282:        MOVL    group_5a_op1_lf(%esi),%dx       // load op1 loc/for
                   1283:        MOVL    $(memory_opnd*0x100+double_real),%si // result format
                   1284:        jmp     load_store_1a           // load rest of information
                   1285:        ALIGN
                   1286: //
                   1287: //     group 7a - load/store word-integer/bcd/long-integer instructions
                   1288: //
                   1289: load_word_int:
                   1290:        movb    group_3a_7a_op(%esi),%al        // load operation type
                   1291:        movb    group_7a_res_fmt(%esi),%dl      // load result format
                   1292:        movb    group_3a_7a_res_loc(%esi),%dh // load result location
                   1293:        pushw   %dx                     // push result fmt/loc
                   1294:        movb    group_7a_op1_fmt(%esi),%dl      // load op1 format
                   1295:        movb    group_3a_7a_op1_loc(%esi),%dh // load op1 location
                   1296:        popw    %si                     // pop result fmt/loc
                   1297:        jmp     load_store_1a           // finish loading information
                   1298:        ALIGN
                   1299: //
                   1300: //     group 1b - load/store/transcendental instructions with inner
                   1301: //                stack operands
                   1302: transcendentals:
                   1303:        testb   $0x20,%ah                       // does bit 5 = 0?
                   1304:        jz      group_1ba               // yes, its a load/store op
                   1305:        MOVL    $0x1f00,%si             // no, its a transcendental
                   1306:        andw    %ax,%si                 // calculate new table index
                   1307:        shrw    $8,%si                  // shift right one byte
                   1308:        movswl  %si,%esi
                   1309:        movb    group_1bb_type(%esi),%al        // load format/location type
                   1310:        rolb    $1,%al                  // rotate one left
                   1311:        movl    $4,%ecx                 // load loop count
                   1312:        FALLSTHRU
                   1313: load_lf_1bb:
                   1314:        rolb    $2,%al                  // shift next field into di
                   1315:        MOVL    $0x0006,%di             // form table index
                   1316:        andw    %ax,%di
                   1317:        movswl  %di,%edi
                   1318:        pushw   group_1bb_lf(%edi)      // stack next format/location
                   1319:        LOOP(load_lf_1bb)               // decode four fields
                   1320:        movb    group_1bb_op(%esi),%al  // load operation type
                   1321:        cmpb    $log_op,%al             // is it fyl2x?
                   1322:        je      pop_op1_1bb             // yes, operand 1 gets popped
                   1323:        cmpb    $splog_op,%al           // is it fyl2xp1?
                   1324:        je      pop_op1_1bb             // yes, operand 1 gets popped
                   1325:        cmpb    $arctan_op,%al          // is it fpatan?
                   1326:        jne     return_1bb              // no, load return information
                   1327:        FALLSTHRU
                   1328: pop_op1_1bb:
                   1329:        movb    pop_stack,%bh           // pop operand 1
                   1330: return_1bb:
                   1331:        popw    %di                     // load operand 1 information
                   1332:        popw    %si                     // load operand 2 information
                   1333:        popw    %cx                     // load result 1 information
                   1334:        popw    %dx                     // load result 2 information
                   1335:        ret
                   1336:        ALIGN
                   1337: group_1ba:
                   1338:        MOVL    %cx,%di                 // assume result2 always null
                   1339:        movb    group_1ba_op(%esi),%al  // load operation type
                   1340: load_store_1ba:
                   1341:        cmpb    $load_op,%al            // is it fld st(i) ?
                   1342:        je      fld_1ba                 // op1 is a register
                   1343:        cmpb    $exchange_op,%al                // is it fxch st(i) ?
                   1344:        je      fxch_1ba                // op1 is stack top
                   1345:        cmpb    $store_pop,%al          // is it fstp st(i)? *
                   1346:        je      fstp_1ba                // pop op1
                   1347:        cmpb    $store_op,%al           // is it fst st(i)?
                   1348:        je      fst_1ba                 // dont pop op1
                   1349:        MOVL    %di,%si                 // result format is null
                   1350:        ret
                   1351:        ALIGN
                   1352: fld_1ba:
                   1353:        MOVL    $(reg*0x100+extended_fp),%dx // op1 is a stack reg
                   1354:        MOVL    $(stack_top_plus_1*0x100+extended_fp),%si // result pushed
                   1355:        ret
                   1356:        ALIGN
                   1357: fxch_1ba:
                   1358:        MOVL    $(stack_top*0x100+extended_fp),%dx // op1 is stack top
                   1359:        MOVL    $(reg*0x100+extended_fp),%cx // op2 is a stack reg
                   1360:        MOVL    %cx,%si                 // result is the stack reg
                   1361:        MOVL    %dx,%di                 // result2 is the stack top
                   1362:        ret
                   1363:        ALIGN
                   1364: fstp_1ba:
                   1365:        movb    $store_op,%al           // operation type is store
                   1366:        movb    pop_stack,%bh           // op1 useup is pop stack
                   1367: fst_1ba:
                   1368:        MOVL    $(stack_top*0x100+extended_fp),%dx // op1 is stack top
                   1369:        MOVL    $(reg*0x100+extended_fp),%si // result is stack reg
                   1370:        ret
                   1371:        ALIGN
                   1372: //
                   1373: //     group 5b - free register/store to register instructions
                   1374: //
                   1375: store_reg:
                   1376:        movb    group_5b_op(%esi),%al   // load operation type
                   1377:        cmpb    $ucom_pop,%al
                   1378:        jne     test_ucom_op
                   1379:        movb    pop_stack,%bh
                   1380:        movb    $ucom_op,%al
                   1381:        FALLSTHRU
                   1382: test_ucom_op:
                   1383:        cmpb    $ucom_op,%al
                   1384:        jne     test_ffree_5b
                   1385:        MOVL    $(reg*0x100+extended_fp),%cx // op2 is reg extended_fp
                   1386:        MOVL    %dx,%di                 // result2 format is null
                   1387:        MOVL    %dx,%si                 // result format is null
                   1388:        MOVL    $(stack_top*0x100+extended_fp),%dx // op1 top extended_fp
                   1389:        ret
                   1390:        ALIGN
                   1391: test_ffree_5b:
                   1392:        cmpb    $free_op,%al            // is it ffree st(i)?
                   1393:        jne     load_store_1ba          // no, must be fst(p)/fxch
                   1394:        movb    free,%bh                        // yes, op1 useup is free
                   1395:        jmp     load_store_1ba          // load rest of information
                   1396:        ALIGN
                   1397: //
                   1398: //     group 7b - transfer status instruction
                   1399: //
                   1400: transfer_status:
                   1401:        movb    group_7b_op(%esi),%al   // load operation type
                   1402:        cmpb    $free_op,%al            // is it ffreep st(i) ?
                   1403:        jne     not_ffreep_7b           // no, useup is do nothing
                   1404:        movb    pop_stack,%bl           // yes, op1 useup is pop
                   1405:        FALLSTHRU
                   1406: not_ffreep_7b:
                   1407:        cmpb    $stsw_op,%al            // is it fstsw ax ?
                   1408:        jne     test_ffree_5b           // no, handle like group 5b
                   1409:        movb    $reg,%ch                // yes, op2 loc is reg
                   1410:        jmp     test_ffree_5b           // finish loading information
                   1411:        ALIGN
                   1412: //
                   1413: //     group 2b - fucompp
                   1414: //
                   1415: double_pop:    
                   1416:        cmpb    $0x029,%ah                      // is it fucompp
                   1417:        jne     reserved                // is a reserved instruction
                   1418:        movb    pop_stack,%bl           // op2 useup is pop stack
                   1419:        movb    pop_stack,%bh
                   1420:        movb    $ucom_op,%al
                   1421:        MOVL    $(reg*0x100+extended_fp),%cx // op2 is reg extended_fp
                   1422:        MOVL    %dx,%di                 // result2 format is null
                   1423:        MOVL    %dx,%si                 // result format is null
                   1424:        MOVL    $(stack_top*0x100+extended_fp),%dx // op1 top extended_fp
                   1425:        ret
                   1426:        ALIGN
                   1427: //
                   1428: //     group 2b - reserved
                   1429: //
                   1430: reserved:
                   1431:        movb    $error_op,%al           // illegal operation
                   1432: null_results_2b:
                   1433:        MOVL    %cx,%si                 // result is null
                   1434:        MOVL    %cx,%di                 // result2 is null
                   1435:        ret
                   1436:        ALIGN
                   1437: //
                   1438: //     group 3b - administrative instructions
                   1439: //
                   1440: administrative:
                   1441:        MOVL    $0x0700,%si             // calculate new table index
                   1442:        andw    %ax,%si
                   1443:        shrw    $8,%si                  // shift right one byte
                   1444:        movswl  %si,%esi
                   1445:        movb    group_3b_op(%esi),%al   // load operation type
                   1446:        jmp     null_results_2b         // result and result2 are null
                   1447: //
                   1448: //e80387       endp

unix.superglobalmegacorp.com

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