Annotation of kernel/machdep/i386/fp_emul/fp_store.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 "store.s"
                     26: 
                     27:        .ident  "@(#)kern-fp:store.s    1.1"
                     28: 
                     29: //$tt(*80387   emulator+++s    t       o       r       e+++*)
                     30: // ***************************************************************************
                     31: //
                     32: //                     s t o r e . m o d 
                     33: //                     ==================
                     34: //
                     35: //     =============================================================
                     36: //               intel corporation proprietary information
                     37: //    this software  is  supplied  under  the  terms  of  a  license
                     38: //    agreement  or non-disclosure agreement  with intel corporation
                     39: //    and  may not be copied nor disclosed except in accordance with
                     40: //    the terms of that agreement.                                  
                     41: //     ===============================================================
                     42: //
                     43: //     function:
                     44: //             implements 80387 store, fix, and storex instructions.
                     45: //
                     46: //     public procedures:
                     47: //             store   fix16   fix32   fix64   move_op_to_op
                     48: //
                     49: //     internal procedures:
                     50: //             extended_store          bcd_store
                     51: //             single_real_store       double_real_store
                     52: //             store_valid             int64_store
                     53: //             int16_store             int32_store
                     54: //
                     55: // ************************************************************************
                     56: //
                     57: //...december 12, 1986..
                     58: //
                     59: //$nolist
                     60: #include       "fp_e80387.h"
                     61: //$list
                     62:        .data   //a_msr segment rw      public
                     63: //     extrn   %gs:sr_masks,%gs:sr_flags,%gs:sr_errors,%gs:sr_controls
                     64: //a_msr        ends
                     65: //
                     66: //     assume  %ds:a_msr
                     67: //
                     68:        .text   //a_med segment er      public
                     69: //
                     70: //     extrn   pop_free,clear_6w,test_3w,subadd
                     71: //     extrn   gradual_underflow,right_shift_frac2_cl
                     72: //     extrn   special_round_test,directed_round_test
                     73: //     extrn   right_shift_result_cl,set_up_indefinite
                     74: //     extrn   right_shift_frac1_cl,sticky_right_shift
                     75: //     extrn   left_shift_frac1_cl,left_shift_result_cl
                     76: //     extrn   put_op1_result,divid,addition_normalize
                     77: //     extrn   round,get_precision,get_rnd_control
                     78: //     extrn   store_precision,set_i_error,i_masked_
                     79: //     extrn   set_o_error,o_masked_,set_p_error
                     80: //     extrn   set_u_error,test_4w,subtraction_normalize
                     81: //     extrn   p_error_,clear_p_error,add_to_frac
                     82: //     extrn   move_constant,set_stk_u_error,norm_denorm
                     83: //     extrn   %gs:sr_mem_offset
                     84: //     --------to be added for unix
                     85: //..           extrn   fpfulong:far,fpfushort:far,fpsulong:far,fpsushort:far
                     86: //
                     87:        .globl  store
                     88:        .globl  fix16
                     89:        .globl  fix32
                     90:        .globl  fix64
                     91:        .globl  move_op_to_op
                     92: //
                     93: store_routine: 
                     94:        .long   single_real_store,double_real_store,int16_store
                     95:        .long   int32_store,int64_store,extended_store
                     96:        .long   int16_store,int16_store,bcd_store
                     97: //
                     98: // *************************************************************************
                     99: //                     store:
                    100: //                     ******
                    101: //     function:
                    102: //             implements all store instructions .
                    103: //
                    104: //     inputs:
                    105: //             operand1; format of result.
                    106: //
                    107: //     outputs:
                    108: //             operand in *result_format* stored in memory
                    109: //             destination pointed to by es:di.
                    110: //
                    111: //     data accessed:
                    112: //             - result_rec_offset     result_format
                    113: //             - offset_operand1
                    114: //
                    115: //     data changed:
                    116: //             - result record
                    117: //
                    118: //     procedures called:
                    119: //             set_up_indefinite       store routine (result format)
                    120: //             i_masked?
                    121: //
                    122: // ****************************************************************************
                    123:        ALIGN
                    124: store: //proc
                    125:        jz      no_unmasked_stack_error         // branch if no stack error
                    126:        call    set_stk_u_error                 // stack underflow occurred
                    127:        testb   invalid_mask,%gs:sr_masks       // if unmasked, just exit
                    128:        jz      return                          // else, store indef set up
                    129: no_unmasked_stack_error:                       // in operand1 by fetch_an_op
                    130:        andb    $~a_mask,%gs:sr_flags   // clear a-bit
                    131: get_result_loc:
                    132:        cmpb    $reg,result_location(%ebp)
                    133:        jne     store_to_memory                         // branch if memop
                    134:        call    put_op1_result                          // give opnd1 as result
                    135:        jmp     pop_free
                    136:        ALIGN
                    137: store_to_memory:
                    138:        movzbl  result_format(%ebp),%ebx// call a different rtn
                    139:        shll    $2,%ebx                                 // for each of the
                    140:        cmp     $8,%ebx
                    141:        jge     go_to_storer                    // do store of temporary real
                    142:        cmpb    unsupp,tag1(%ebp)               // detect unsupported pattern
                    143:        jne     go_to_storer
                    144:        orb     invalid_mask,%gs:sr_errors      // set i_error
                    145:        testb   invalid_mask,%gs:sr_masks       // if unmasked, just exit
                    146:        jz      return                                  // else, set up indef in
                    147:        mov     $offset_operand1,%edi           // operand1. 
                    148:        call    set_up_indefinite
                    149: go_to_storer:
                    150:        jmp     *%cs:store_routine(%ebx)                        // output formats
                    151: //store        endp
                    152: //
                    153: // ****************************************************************************
                    154: //                     move_op_to_op:
                    155: //
                    156: //     function:
                    157: //             moves operand record (op1,op2,result_op,result2_op) to
                    158: //             another op.
                    159: //
                    160: //     inputs:
                    161: //             ss:esi points to the source, and
                    162: //             ss:edi points to the destination
                    163: //     outputs:
                    164: //             operand record in destination
                    165: //
                    166: //     data accessed:
                    167: //             operand or result variables
                    168: //
                    169: //     data changed:
                    170: //             operand or result variables
                    171: //
                    172: // *****************************************************************************
                    173:        ALIGN
                    174: move_op_to_op: //proc
                    175: //     push    %ds                     // save a?msr
                    176: //     push    %ss
                    177: //     pop     %ds
                    178:        push    %ss
                    179:        pop     %es
                    180:        mov     $((sign2-sign1)>> 2),%ecx / set record length
                    181: 
                    182:        /* FAST_MOVSL */
                    183:        push    %eax
                    184: 1:
                    185:        movl    %ss:0(%esi),%eax
                    186:        movl    %eax,%es:0(%edi)
                    187:        addl    $4,%esi 
                    188:        addl    $4,%edi 
                    189:        decl    %ecx    
                    190:        testl   %ecx,%ecx
                    191:        jg      1b
                    192: 
                    193:        pop     %eax
                    194: //     pop     %ds                     // reload a?msr
                    195: return:
                    196:        ret
                    197: //move_op_to_op        endp
                    198: //
                    199: // ***************************************************************************
                    200: //                     extended_store:
                    201: //                     ***************
                    202: //     function:
                    203: //             stores into double extended format.
                    204: //
                    205: //     inputs:
                    206: //             operand1
                    207: //
                    208: //     outputs:
                    209: //             double extended operand in memory.
                    210: //             stack popped if indicated
                    211: //
                    212: //     data accessed:
                    213: //             - mem_operand_pointer           sign1
                    214: //             - expon1                        word_frac1
                    215: //
                    216: //     data changed:
                    217: //
                    218: //     procedures called:
                    219: //             pop_free
                    220: //
                    221: // *****************************************************************************
                    222:        ALIGN
                    223: extended_store:        //proc
                    224:        les     mem_operand_pointer(%ebp),%edi  //move frac to memory
                    225: //     push    %ds                             // save a?msr
                    226: //     push    %ss
                    227: //     pop     %ds                             // set up source pointer
                    228:        lea     2+word_frac1,%esi
                    229:        
                    230:        /* FAST_MOVSL */
                    231:        movl    %ss:0(%esi),%ecx
                    232:        movl    %ecx,%es:0(%edi)
                    233:        movl    %ss:4(%esi),%ecx
                    234:        movl    %ecx,%es:4(%edi)
                    235: //     addl    $8,%esi
                    236: //     addl    $8,%edi
                    237: //     movl    $0,%ecx
                    238: 
                    239: //     pop     %ds                                             // reload a?msr
                    240:        movb    sign1(%ebp),%ah                 // merge sign & exponent
                    241:        andw    $0x8000,%ax                             // and move to memory
                    242:        orw     expon1(%ebp),%ax
                    243:        movw    %ax,%es:8(%edi)
                    244: 
                    245: //..
                    246: //..           pushad
                    247: //..           push    es
                    248: //..           push    edi
                    249: //..           push    ax
                    250: //..           call    fpsushort
                    251: //..           add     esp,12
                    252: //..           popad
                    253: //..           cld
                    254:        jmp     pop_free                                        // pop stack, if needed
                    255: //extended_store       endp
                    256: //
                    257: // ****************************************************************************
                    258: //                     bcd_store:
                    259: //                     **********
                    260: //     function:
                    261: //             stores into bcd format
                    262: //
                    263: //     inputs:
                    264: //             operand1
                    265: //
                    266: //     outputs:
                    267: //             bcd operand in memory; stack popped
                    268: //
                    269: //     data accessed:
                    270: //             - mem_operand_pointer           operation_type
                    271: //             - offset_operand1               sign1
                    272: //             - tag1                          word_frac1
                    273: //             - msb_frac1                     offset_operand1
                    274: //             - offset_operand2               sign2
                    275: //             - expon2                        word_frac2
                    276: //             - offset_operand2               offset_result
                    277: //             - result_expon                  result_word_frac
                    278: //             - msb_result                    offset_result
                    279: //
                    280: //     data changed:
                    281: //             - operation_type                word_frac1
                    282: //             - msb_frac1                     sign2
                    283: //             - expon2                        word_frac2
                    284: //             - result_word_frac              msb_result
                    285: //
                    286: //     procedures called:
                    287: //             move_op_to_op                   right_shift_frac1_cl
                    288: //             right_shift_frac2_cl    right_shift_result_cl
                    289: //             left_shift_frac1_cl             left_shift_result_cl
                    290: //             divid                                   clear_6w
                    291: //             pop_free                                test_4w
                    292: //             add_to_frac                             move_constant
                    293: //
                    294: // **************************************************************************
                    295: ten_18:        
                    296:        .value  0x0000,0x0000,0x0000,0x7640,0x6b3a,0x0de0b// frac for 10**18
                    297: //
                    298:        ALIGN
                    299: bcd_store:     //proc
                    300:        push    %gs:sr_masks                            // save current precision
                    301:        orb     prec64,%gs:sr_controls                  // and set to 64-bit
                    302:        cmpb    special,tag1(%ebp)                      // separate bcd cases
                    303:        jne     finite_value_
                    304:        jmp     store_signed_bcd
                    305:        ALIGN
                    306: finite_value_:
                    307:        cmpl    $0x07fff,dword_expon1            // is it a finite number?
                    308:        jne     check_bcd_denorm                        // yes, branch to valid
                    309: invalid_bcd:
                    310:        orb     invalid_mask,%gs:sr_errors      // set i_error
                    311:        testb   invalid_mask,%gs:sr_masks       // is i_error unmasked?
                    312:        jnz     store_bcd_indef
                    313:        jmp     bcd_store_done                  // no, so exit at once
                    314:        ALIGN
                    315: store_bcd_indef:                               // yes, store bcd_indef
                    316:        movl    $0, dword_frac1+frac80(%ebp)    // clear low frac
                    317:        movl    $0x80000000, dword_frac1+6(%ebp)// set only ms bit of hi frac
                    318:        movw    $0x0ffff, 8+word_frac1          //set msw to all ones,
                    319:        jmp     store_bcd_result                // and give as answer
                    320:        ALIGN
                    321: check_bcd_denorm:
                    322:        cmpb    denormd,tag1(%ebp)                      // separate bcd cases
                    323:        jne     round_to_int
                    324:        movl    $0x0001,dword_expon1    // if masked d-error, make valid
                    325:        movb    valid,tag1(%ebp)
                    326: round_to_int:
                    327:        mov     $0x403e,%eax
                    328:        cmp     %eax,dword_expon1               // if expon >= 63, then number
                    329:        jge     invalid_bcd                     // is already too big for bcd
                    330:        mov     $offset_operand1,%edi   // gradual uflow until expon=63
                    331:        push    %edi
                    332:        call    gradual_underflow
                    333:        pop     %edi                            // round to precision 64
                    334:        movb    prec64,%dl
                    335:        movb    false,%al
                    336:        call    round
                    337: detect_zero:
                    338:        xor     %eax,%eax
                    339:        mov     $dword_frac1+4,%edi     // if fraction = 0, result = 0
                    340:        call    test_4w
                    341:        jnz     below_10_to_18_
                    342:        mov     %eax,dword_expon1               // set result to true zero
                    343:        movb    special,tag1(%ebp)
                    344:        jmp     store_bcd_round_data
                    345:        ALIGN
                    346: below_10_to_18_:
                    347:        mov     4(%ebp,%edi),%edx
                    348:        cmp     $0x0de0b6b3,%edx
                    349:        ja      invalid_bcd
                    350:        mov     (%ebp,%edi),%eax
                    351:        jb      divide_by_10_to_9
                    352:        cmp     $0x0a7640000,%eax
                    353:        jae     invalid_bcd
                    354: divide_by_10_to_9:
                    355:        movl    $0,4(%ebp,%edi) // clear high dword of frac1
                    356:        movl    $0,(%ebp,%edi)// clear  low dword of 8 byte frac1 
                    357:        sub     $2,%edi                 // make edi point to 10 byte frac1
                    358:        mov     $0x3b9aca00,%ebx                // ten to the 9th, as hex ordinal
                    359:        div     %ebx
                    360:        push    %eax                                            // save quotient
                    361:        mov     $4,%ecx
                    362:        mov     $100,%ebx
                    363:        FALLSTHRU
                    364: next_pair_nibbles:
                    365:        mov     %edx,%eax
                    366:        xor     %edx,%edx
                    367:        div     %ebx
                    368:        xchgl   %edx,%eax
                    369:        aam
                    370: second_half_loop_start:
                    371:        shlb    $4,%ah
                    372:        orb     %ah,%al
                    373:        movb    %al,(%ebp,%edi)
                    374:        inc     %edi
                    375:        LOOP(next_pair_nibbles)
                    376: do_second_half_:
                    377:        pop     %eax
                    378:        or      %eax,%eax                                       // is eax 0?
                    379:        movb    %dl,(%ebp,%edi)
                    380:        jz      store_bcd_round_data
                    381:        push    %edx
                    382:        xor     %edx,%edx
                    383:        mov     $10,%ecx
                    384:        div     %ecx
                    385:        xchgl   %edx,%eax
                    386:        pop     %ecx
                    387:        movb    %al, %ah
                    388:        movb    %cl, %al
                    389:        push    $0
                    390:        mov     $5, %ecx
                    391:        jmp     second_half_loop_start
                    392:        ALIGN
                    393: store_bcd_round_data:
                    394:        cmpb    true,rnd1_inexact
                    395:        jne     store_signed_bcd
                    396:        orb     $inexact_mask,%gs:sr_errors
                    397:        cmpb    true,added_one
                    398:        jne     store_signed_bcd
                    399:        orb     $a_mask,%gs:sr_flags
                    400: store_signed_bcd:
                    401:        movb    sign1(%ebp),%ah                 // set sign in bcd number
                    402:        andb    $0x080,%ah
                    403:        movb    %ah,msb_frac1
                    404: store_bcd_result:
                    405:        les     %gs:sr_mem_offset,%edi  //move frac1 to memory
                    406: //     push    %ds                             // save a?msr
                    407: //     push    %ss
                    408: //     pop     %ds
                    409:        lea     word_frac1,%esi
                    410: 
                    411:        /* FAST_MOVSL */
                    412:        movl    %ss:0(%esi),%ecx
                    413:        movl    %ecx,%es:0(%edi)
                    414:        movl    %ss:4(%esi),%ecx
                    415:        movl    %ecx,%es:4(%edi)
                    416:        movw    %ss:8(%esi),%cx
                    417:        movw    %cx,%es:8(%edi)
                    418: //     addl    $10,%esi
                    419: //     addl    $10,%edi
                    420: //     movl    $0,%ecx
                    421: 
                    422: //     pop     %ds                                     // reload a?msr
                    423:        call    pop_free
                    424: bcd_store_done:
                    425:        pop     %gs:sr_masks                            // restore old setting
                    426:        ret
                    427: //bcd_store    endp
                    428: //
                    429: // *****************************************************************************
                    430: //                     single_real_store:
                    431: //                     ******************
                    432: //     function:
                    433: //             implements store to single-precision real format
                    434: //
                    435: //     inputs:
                    436: //             operand1
                    437: //
                    438: //     outputs:
                    439: //             single_precision real in memory;
                    440: //             stack popped if indicated.
                    441: //
                    442: //     data accessed:
                    443: //             - mem_operand_pointer           offset_operand1
                    444: //             - sign1                         tag1
                    445: //             - expon1                        word_frac
                    446: //             - msb_frac1
                    447: //
                    448: //     data changed:
                    449: //
                    450: //     procedures called:
                    451: //             round                           store_valid
                    452: //             addition_normalized             special_round_test
                    453: //             directed_round_test             gradual_underflow
                    454: //             pop_free                        test_3w
                    455: //             u_masked?                       set_o_error
                    456: //             o_masked?                       set_p_error
                    457: //             set_u_error                     set_i_masked?
                    458: //             store_denormd
                    459: //
                    460: // ************************************************************************
                    461:        ALIGN
                    462: single_real_store:     //proc
                    463:        push    $pop_free                               // return to pop_free
                    464:        les     mem_operand_pointer(%ebp),%edi  //set es:di to memop
                    465:        mov     low_extended_expon_for_single,%esi
                    466:        movb    prec24,%dl                              // 24-bit precision
                    467:        movb    tag1(%ebp),%al                  // load op1 tag
                    468:        cmpb    valid,%al
                    469:        je      single_valid                            // detect valid, infinity,
                    470:        cmpb    denormd,%al                             // denormd, invalid, and
                    471:        je      single_denormd                          // special cases
                    472:        cmpb    inv,%al                                 // check whether op1 is nan
                    473:        jne     single_special                          // branch unless op1 is nan
                    474:        testb   $0x40,msb_frac1                         // check whether nan is quiet
                    475:        jnz     single_special                          // branch if nan is quiet
                    476:        orb     invalid_mask,%gs:sr_errors      // set i_error for snan
                    477:        testb   invalid_mask,%gs:sr_masks       // if unmasked, just exit
                    478:        jz      special_return                          // else, change to qnan
                    479:        orb     $0x40,msb_frac1
                    480: single_special:
                    481:        mov     dword_frac1+frac32+1(%ebp),%ecx
                    482:        and     $0x807fffff,%ecx
                    483:        movzbl  expon1(%ebp),%eax
                    484:        shl     $23,%eax
                    485:        or      %ecx,%eax
                    486:        mov     %eax,%es:(%edi)
                    487: //..
                    488: //..           pushad
                    489: //..           push    es
                    490: //..           push    edi
                    491: //..           push    eax
                    492: //..           call    fpsulong
                    493: //..           add             esp,    12
                    494: //..           popad
                    495: //..           cld
                    496: //..
                    497: special_return:
                    498:        ret
                    499:        ALIGN
                    500: 
                    501: single_denormd:
                    502:        mov     $offset_operand1,%edi   // op1 is denormal or pseudo-denormal
                    503:        call    norm_denorm             // dont set d_error; just normalize
                    504: single_valid:
                    505:        mov     high_extended_expon_for_single,%edi // load parameter
                    506:        call    store_valid
                    507:        les     mem_operand_pointer(%ebp),%edi  // es:edi --> memop
                    508:        jz      single_infinity         // zf = 1 => store infinity
                    509:        js      single_max                      // sf = 1 => store max
                    510:        jc      single_qnan                     // cf = 1 => store qnan
                    511: single_store:
                    512:        mov     dword_frac1+frac32+1(%ebp),%eax
                    513:        and     $0x80ffffff,%eax
                    514:        test    $0x00ffffff,%eax
                    515:        jz      single_store_it
                    516:        and     $0x807fffff,%eax
                    517:        movzbl  expon1(%ebp),%ecx
                    518:        addb    $0x80,%cl
                    519:        shl     $23,%ecx
                    520:        or      %ecx,%eax
                    521: single_store_it:
                    522:        mov     %eax,%es:(%edi)
                    523: //..
                    524: //..           pushad
                    525: //..           push    es
                    526: //..           push    edi
                    527: //..           push    eax
                    528: //..           call    fpsulong
                    529: //..           add     esp,12
                    530: //..           popad
                    531: //..           cld
                    532: //..
                    533:        ret                                     //do needed pop or free
                    534:        ALIGN
                    535: 
                    536: single_max:
                    537:        mov     $0x7fffff7f,%eax
                    538:        jmp     single_sign_on
                    539:        ALIGN
                    540: single_infinity:
                    541:        mov     $0x8000007f,%eax
                    542: single_sign_on:
                    543:        orb     sign1(%ebp),%al
                    544:        ror     $8,%eax
                    545:        jmp     single_store_it
                    546:        ALIGN
                    547: single_qnan:
                    548:        movl    $0xffffffff,%es:(%edi)
                    549:        pop     %eax                            // skip pop or free
                    550:        ret                                     //   since this happens on error
                    551:        ALIGN
                    552: 
                    553: store_valid:
                    554:        push    %edi                            // stack high_expon
                    555:        push    %esi                            // stack low_expon
                    556:        push    %edx                            // stack prec control
                    557:        movb    false,%al                       // not second rounding
                    558:        mov     $offset_operand1,%edi   // round to prec (dl)
                    559: //     push    edi                                     ; round preserves edi
                    560:        call    round
                    561: //             pop             edi
                    562:        call    addition_normalize              // and renormalize
                    563:        pop     %edx                            // unstack prec control
                    564:        pop     %esi                            // unstack low_expon
                    565:        pop     %edi                            // unstack high_expon
                    566:        cmp     %esi,dword_expon1               // is underflow possible?
                    567:        jl      store_underflow_        // < low_expon, so underflow possible
                    568:        je      decrement_exponent              // no, = low_expon?
                    569:        cmp     %edi,dword_expon1               // no, > high_expon?
                    570:        jle     do_store_valid                  // no, store number
                    571:        orb     overflow_mask,%gs:sr_errors     // set o_error
                    572:        testb   overflow_mask,%gs:sr_masks      // if unmasked, violate ieee standard
                    573:        jnz     masked_overflow         // and abort without rounding source
                    574: unmasked_ov_underflow:
                    575: //
                    576: // the commentized instructions immediately following are appropriate for
                    577: // unmasked over/underflow response in accord with the ieee standard.  on the
                    578: // 80387, unmasked over/underflows on conversion leave for the trap handler the
                    579: // source operand, unmodified by rounding, exponent rebiasing, or anything else.
                    580: // therefore, to report that preliminary rounding was inexact or achieved by
                    581: // increasing the source seems inconsistent with the 80387s philosophy
                    582: // of entering an over/underflow trap handler with the 80387s state changed
                    583: // only insofar as the over/underflow flag has been set, so skip that report.
                    584: //
                    585: //     cmp     rnd1_inexact,   true            ; detect inexact result
                    586: //     jne     move_op1_to_87_tos              ; if exact, branch to replace source
                    587: //     or      %gs:sr_errors,  inexact_mask    ; else, set i_error
                    588: //     cmp     added_one,      true            ; was rounding done by adding one?
                    589: //     jne     move_op1_to_87_tos              ; if not, branch to replace source
                    590: //     or      %gs:sr_flags,   a_mask          ; else, set a_bit
                    591: //move_op1_to_87_tos:
                    592: //     mov     (ebp).result_location,  stack_top
                    593: //     pop     %edi            ; discard callers return address
                    594: //     pop     %edi            ; discard pop_free address
                    595: //     jmp     put_op1_result
                    596: //
                    597: // Instead, we return a special error condition (sf=0 zf=0 cf=1)
                    598: // to our caller, to cause a quiet NaN to be generated, as the 80387 does.
                    599:        movb    $1, %ah
                    600:        sahf
                    601:        ret
                    602:        ALIGN
                    603: 
                    604: masked_overflow:
                    605:        orb     $inexact_mask,%gs:sr_errors     // set inexact_error
                    606:        movb    %gs:sr_controls,%al                     // load control byte
                    607:        andb    $rnd_control_mask,%al   // mask in rounding control
                    608:        movb    rnd_up,%ah
                    609:        cmpb    %al,%ah
                    610:        js      store_valid_done                // branch if zf = 0 & sf = 1
                    611:        movb    sign1(%ebp),%al                         // get sign of op1
                    612:        call    special_round_test                      // after round test, cf=0
                    613:        pushf                           //  (zf=0 sf=1)/(zf=1 sf=0)
                    614:        js      pop_store_valid_done            // sf = 1 => store max
                    615:        orb     $a_mask,%gs:sr_flags                    // set a_bit
                    616: pop_store_valid_done:
                    617:        popf                                            // reload flags
                    618: store_valid_done:
                    619:        ret                                                                     // exit
                    620:        ALIGN
                    621: store_underflow_:
                    622:        testb   underflow_mask,%gs:sr_masks     // if underflow masked,
                    623:        jnz     check_masked_underflow  // then branch to check for inexact
                    624:        orb     underflow_mask,%gs:sr_errors// else, set u_error
                    625: //
                    626: // after the underflow exception has been set, the response to unmasked
                    627: // underflow ought to be the same as that to unmasked overflow.
                    628:        jmp     unmasked_ov_underflow
                    629:        ALIGN
                    630: 
                    631: check_masked_underflow:
                    632:        mov     $offset_operand1,%edi           // load op1 offset
                    633:        mov     %esi,%eax                               // load low exponent
                    634:        push    %edi                                    // save op1 offset
                    635:        push    %edx                                    // save prec control
                    636:        call    gradual_underflow                       // do gradual underflow
                    637:        pop     %edx                                    // reload prec control
                    638:        pop     %edi                                    // reload op1 offset
                    639:        movb    true,%al                                // perform second round
                    640:        call    round
                    641:        cmpw    $0,rnd_history                  // signal_u_error?
                    642:        je      decrement_exponent
                    643:        orb     underflow_mask+inexact_mask,%gs:sr_errors
                    644: decrement_exponent:
                    645:        testb   $0x80,msb_frac1                         // test msb of fraction
                    646:        jnz     do_store_valid          // dont decrement if 800..0h
                    647:        decw    expon1(%ebp)                            // else, decrement expon
                    648: do_store_valid:
                    649:        cmpw    $0,rnd_history                  // signal_p_error?
                    650:        je      adjust_flags
                    651:        orb     $inexact_mask,%gs:sr_errors     // signal_p_error.
                    652:        cmpb    true,added_one          // was rounding done by adding one?
                    653:        jne     adjust_flags            // if not, branch to adjust flags
                    654:        orb     $a_mask,%gs:sr_flags            // else, set a_bit
                    655: adjust_flags:
                    656:        xor     %eax,%eax               // cf = 0, sf = 0, zf = 0 for
                    657:        inc     %eax                    //  store valid exit
                    658:        ret
                    659: 
                    660: //single_real_store    endp
                    661: //
                    662: // ************************************************************************
                    663: //                     double_real_store:
                    664: //                     ******************
                    665: //     function:
                    666: //             implements store to double-precision real format
                    667: //
                    668: //     inputs:
                    669: //             operand1
                    670: //
                    671: //     outputs:
                    672: //             double precision real in memory;
                    673: //             stack popped if indicated.
                    674: //
                    675: //     data accessed:
                    676: //             - mem_operand_pointer           offset_operand1
                    677: //             - sign1                         tag1
                    678: //             - expon1                        word_frac1
                    679: //             - msb_frac1                     offset_operand1
                    680: //
                    681: //     data changed:
                    682: //             - sign1                         word_frac1
                    683: //
                    684: //     procedures called:
                    685: //             test_3w                         store_valid
                    686: //             right_shift_frac1_cl            pop_free
                    687: //             double_zero                     double_fill
                    688: //             store_denormd                   double_frac_mem
                    689: //
                    690: // ***************************************************************************
                    691:        ALIGN
                    692: double_real_store:     //proc
                    693:        push    $pop_free                               // return to pop_free
                    694:        mov     low_extended_expon_for_double,%esi
                    695:        movb    prec53,%dl                              // 53-bit precision
                    696:        movb    tag1(%ebp),%al                  // separate special cases
                    697:        cmpb    valid,%al
                    698:        je      double_valid
                    699:        cmpb    denormd,%al
                    700:        je      double_denormd
                    701:        cmpb    special,%al
                    702:        jne     inv_or_inf
                    703:        movw    $0x3c00,expon1(%ebp)
                    704:        jmp     double_frac_mem
                    705:        ALIGN
                    706: inv_or_inf:
                    707:        cmpb    inv,%al
                    708:        jne     double_special
                    709:        testb   $0x40,msb_frac1                 // check whether nan is quiet
                    710:        jnz     double_special                          // branch if nan is quiet
                    711:        orb     invalid_mask,%gs:sr_errors      // set i_error for snan
                    712:        testb   invalid_mask,%gs:sr_masks       // if unmasked, just exit
                    713:        jnz     make_dbl_qnan                           // else, change to qnan
                    714: dbl_special_return:
                    715:        ret
                    716:        ALIGN
                    717: make_dbl_qnan:
                    718:        orb     $0x40,msb_frac1
                    719: double_special:
                    720:        movw    $0x3c00+0x07ff,expon1(%ebp)
                    721:        jmp     double_frac_mem                 // store frac to memory
                    722:        ALIGN
                    723: double_denormd:
                    724:        mov     $offset_operand1,%edi   // op1 is denormal or pseudo-denormal
                    725:        call    norm_denorm             // dont set d_error; just normalize
                    726: double_valid:
                    727:        mov     high_extended_expon_for_double,%edi
                    728:        call    store_valid
                    729:        jz      double_infinity                 // zf = 1 ==> store infinity
                    730:        js      double_max                              // sf = 1 ==> store max
                    731:        jc      double_qnan                             // cf = 1 ==> store qnan
                    732: double_store:
                    733:        movb    3+lsb_frac1,%al // else store double
                    734:        cbtw
                    735:        mov     $dword_frac1+6,%edi
                    736:        call    test_3w
                    737:        jz      double_zero                             // store signed zero
                    738: double_frac_mem:
                    739:        movb    $3,%cl                                  // start by shifting
                    740:        call    right_shift_frac1_cl            // fraction right 3 bits
                    741:        les     mem_operand_pointer(%ebp),%edi  // es:edi points to memop
                    742: //     push    %ds                             // save a?msr
                    743: //     push    %ss
                    744: //     pop     %ds                             // set up source pointer
                    745:        lea     3+word_frac1,%esi               // move frac to memory
                    746: 
                    747:        /* FAST_MOVSL */
                    748:        movl    %ss:0(%esi),%ecx
                    749:        movl    %ecx,%es:0(%edi)
                    750:        movw    %ss:4(%esi),%ecx
                    751:        movw    %ecx,%es:4(%edi)
                    752: //     addl    $6,%esi
                    753: //     addl    $6,%edi
                    754: //     movl    $0,%ecx
                    755: 
                    756: //     pop     %ds                                     // reload a?msr
                    757:        movw    expon1(%ebp),%ax                // fetch high-order word,
                    758:        subw    $0x3c00,%ax                             // with expon, sign, and
                    759:        shlw    $4,%ax                          // top 4 bits of fraction
                    760:        andb    $0x0f,msb_frac1
                    761:        orb     msb_frac1,%al
                    762:        andb    $0x80,sign1(%ebp)
                    763:        orb     sign1(%ebp),%ah
                    764:        movw    %ax,%es:6(%edi)                         // es:di points to expon
                    765: //..
                    766: //..           pushad
                    767: //..           push    es
                    768: //..           push    edi
                    769: //..           push    ax
                    770: //..           call    fpsushort
                    771: //..           add     esp,12
                    772: //..           popad
                    773: //..           cld
                    774: //..
                    775: 
                    776:        ret                                     // do pop or free
                    777:        ALIGN
                    778: 
                    779: double_zero:
                    780:        xor     %eax,%eax                       // store +/- 0 to memory
                    781: double_fill:
                    782:        les     mem_operand_pointer(%ebp),%edi  // es:edi points to memop
                    783:        mov     %eax,%es:(%edi)
                    784: //..
                    785: //..           pushad
                    786: //..           push    es
                    787: //..           push    edi
                    788: //..           push    eax
                    789: //..           call    fpsulong
                    790: //..           add     esp,12
                    791: //..
                    792: 
                    793:        movw    %ax,%es:4(%edi)
                    794: //..
                    795: //..           push    es
                    796: //..           push    edi+4
                    797: //..           push    ax
                    798: //..           call    fpsushort
                    799: //..           add     esp,12
                    800: //..           popad
                    801: //..           cld
                    802: //..
                    803:        movb    sign1(%ebp),%ah
                    804:        andb    $0x80,%ah
                    805: double_expon:
                    806:        movw    %ax,%es:6(%edi)                 // store the exponent
                    807: //..
                    808: //..           pushad
                    809: //..           push    es
                    810: //..           push    edi+12
                    811: //..           push    ax
                    812: //..           call    fpsushort
                    813: //..           add     esp,12
                    814: //..           popad
                    815: //..           cld
                    816: //..
                    817:        ret
                    818:        ALIGN
                    819: 
                    820: double_max:
                    821:        mov     $0x0ffffffff,%eax                       // set fraction to ff..f
                    822:        call    double_fill
                    823:        movw    $0x7fef,%ax                             // set exponent to 7feh
                    824:        orb     sign1(%ebp),%ah                 // or sign bit
                    825:        jmp     double_expon
                    826:        ALIGN
                    827: double_infinity:
                    828:        call    double_zero                     // first clear the memop
                    829:        orw     $0x7ff0,%es:6(%edi)     // es:di -> memop
                    830: //..
                    831: //..           pushad
                    832: //..           push    es
                    833: //..           push    edi+6
                    834: //..           call    fpfushort
                    835: //..           or      ax,7ff0h
                    836: //..           push    ax
                    837: //..           call    fpsushort
                    838: //..           add     esp,12
                    839: //..           popad
                    840: //..           cld
                    841: //..
                    842:        ret
                    843:        ALIGN
                    844: double_qnan:
                    845:        mov     $0xffffffff,%eax                // set fraction to ff..f
                    846:        call    double_fill
                    847:        movw    $0xffff,%es:6(%edi)     // es:di -> memop (set exp to ff..f)
                    848:        pop     %eax                            // skip pop or free
                    849:        ret                                     //   since this happens on error
                    850: //double_real_store    endp
                    851: //
                    852: // ***********************************************************************
                    853: //             fix16:
                    854: //
                    855: //     function:
                    856: //              fixes valid number to a 16-bit integer.
                    857: //
                    858: //     inputs:
                    859: //              operand1
                    860: //
                    861: //     outputs:
                    862: //             16-bit integer in word_frac1 + 8;
                    863: //             overflow indication in zf (zf:1 => no overflow)
                    864: //
                    865: //     data accessed:
                    866: //             - offset_operand1               sign1
                    867: //             - expon1                        word_frac1
                    868: //             - offset_operand1
                    869: //
                    870: //     data changed:
                    871: //             - word_frac1                    extra_word_reg
                    872: //
                    873: //     procedures called:
                    874: //             sticky_right_shift              round
                    875: //             careful_round                   p_error?
                    876: //
                    877: // ***************************************************************************
                    878:        ALIGN
                    879: fix16: //proc
                    880:        mov     high_int16_exponent,%ecx                // calc shift amount
                    881:        sub     dword_expon1,%ecx                       // if expon1 > high expon
                    882:        js      no_fix16_ovf                    // then overflow (zf=0)
                    883:        cmp     max_int16_shift,%ecx                    // dont let shift amount
                    884:        jbe     do_shift_16                     // exceed max_int16_shift
                    885:        mov     max_int16_shift,%ecx
                    886: do_shift_16:
                    887:        mov     $offset_operand1,%edi           // shift frac1 by cl
                    888:        xorb    %al,%al
                    889:        call    sticky_right_shift
                    890:        mov     $offset_operand1,%edi           // round to 16-bit prec
                    891:        movb    prec16,%dl
                    892:        movb    false,%al
                    893:        call    round
                    894:        cmpb    false,%al                               // overflow if al=true
                    895:        jnz     no_fix16_ovf                            // round cy out (zf=1)
                    896:        cmpw    $0x8000,8+word_frac1
                    897:        jb      check_sign_16                           // no overflow if < 8000h
                    898:        ja      no_fix16_ovf                            // else, overflow (zf=0)
                    899:        cmpb    negative,sign1(%ebp)    // oflow if = 8000h and
                    900:        jnz     no_fix16_ovf                            // sign1 = pos (zf=0)
                    901: check_sign_16:
                    902:        movb    positive,%al                    // al is overflow flag
                    903:        cmpb    sign1(%ebp),%al                 // negate integer if
                    904:        jz      no_fix16_ovf                            // sign is neg (zf=1)
                    905:        negw    8+word_frac1
                    906:        xorb    %al,%al                                 // no overflow (zf=1)
                    907: no_fix16_ovf:
                    908:        ret
                    909: //fix16        endp
                    910: //
                    911: // ***********************************************************************
                    912: //                     int16_store:
                    913: //
                    914: //     function:
                    915: //             stores into 16-bit integer format
                    916: //
                    917: //     inputs:
                    918: //             operand1
                    919: //
                    920: //     outputs:
                    921: //             16-bit integer in memory operand location
                    922: //
                    923: //     data accessed:
                    924: //             - mem_operand_pointer           tag1
                    925: //             - word_frac1                    msb_frac1
                    926: //             - offset_operand1               extra_word_reg
                    927: //
                    928: //     data changed:
                    929: //
                    930: //     procedures called:
                    931: //             fix16                           pop_free
                    932: //             invalid_or_special              get_rnd_control
                    933: //             set_i_error                     i_masked?
                    934: //             set_p_error                     clear_p_error
                    935: //
                    936: // ************************************************************************
                    937:        ALIGN
                    938: int16_store:   //proc
                    939: //
                    940:        cmpb    valid,tag1(%ebp)
                    941:        je      valid_16
                    942:        cmpb    denormd,tag1(%ebp)
                    943:        jne     special_16
                    944: valid_16:
                    945:        call    fix16                           // make op1 a 16-bit int
                    946:        jnz     special_16                      // if zf=0, oflow on fix
                    947:        cmpw    $0,rnd_history
                    948:        je      store_16
                    949:        orb     $inexact_mask,%gs:sr_errors
                    950:        cmpb    true,added_one
                    951:        jne     store_16
                    952:        orb     $a_mask,%gs:sr_flags
                    953: store_16:
                    954:        movw    8+word_frac1,%ax        // move integer to memory
                    955: pointer_16:
                    956:        les     mem_operand_pointer(%ebp),%edi  //set es:di to location
                    957: finish_16:
                    958:        movw    %ax,%es:(%edi)          // store integer to mem
                    959: //..
                    960: //..           pushad
                    961: //..           push    es
                    962: //..           push    edi
                    963: //..           push    ax
                    964: //..           call    fpsushort
                    965: //..           add     esp,12
                    966: //..           popad
                    967: //..           cld
                    968: //..
                    969:        jmp     pop_free                        // pop stack and go home
                    970:        ALIGN
                    971: special_16:
                    972:        xorw    %ax,%ax
                    973:        cmpb    special,tag1(%ebp)              // is operand tagged special?
                    974:        je      pointer_16                              // yes, load memop ptr and exit
                    975:        orb     invalid_mask,%gs:sr_errors// no, set invalid error
                    976:        movw    $0x8000,%ax                     // load inv constant into ax
                    977:        testb   invalid_mask,%gs:sr_masks// is invalid error masked?
                    978:        jnz     pointer_16                              // yes, store invalid constant
                    979:        ret
                    980: //int16_store  endp
                    981: //
                    982: // ***********************************************************************
                    983: //             fix32:
                    984: //
                    985: //     function:
                    986: //              fixes valid number to a 32-bit integer.
                    987: //
                    988: //     inputs:
                    989: //              operand1
                    990: //
                    991: //     outputs:
                    992: //             32-bit integer in word_frac1 + 6;
                    993: //             overflow indication in zf (zf:1 => no overflow)
                    994: //
                    995: //     data accessed:
                    996: //             - offset_operand1               sign1
                    997: //             - dword_expon1                  word_frac1
                    998: //             - offset_operand1
                    999: //
                   1000: //     data changed:
                   1001: //             - word_frac1
                   1002: //
                   1003: //     procedures called:
                   1004: //             sticky_right_shift              round
                   1005: //
                   1006: // ***************************************************************************
                   1007:        ALIGN
                   1008: fix32: //proc
                   1009:        mov     high_int32_exponent,%ecx                // calc shift amount
                   1010:        sub     dword_expon1,%ecx                       // if expon1 > high expon
                   1011:        js      no_fix32_ovf                                    // then overflow (zf=0)
                   1012:        cmp     max_int32_shift,%ecx                    // dont let shift amount
                   1013:        jbe     do_shift_32                                             // exceed max_int32_shift
                   1014:        mov     max_int32_shift,%ecx
                   1015: do_shift_32:
                   1016:        mov     $offset_operand1,%edi           // shift frac1 by cl
                   1017:        xorb    %al,%al
                   1018:        call    sticky_right_shift
                   1019:        mov     $offset_operand1,%edi           // round to 16-bit prec
                   1020:        movb    prec32,%dl
                   1021:        movb    false,%al
                   1022:        call    round
                   1023:        cmpb    false,%al                               // overflow if al=true
                   1024:        jnz     no_fix32_ovf                            // round cy out (zf=1)
                   1025:        cmpl    $0x080000000,dword_frac1+frac32(%ebp)
                   1026:        jb      check_sign_32                           // no overflow if < 80000000h
                   1027:        ja      no_fix32_ovf                            // else, overflow (zf=0)
                   1028:        cmpb    negative,sign1(%ebp)    // oflow if = 80000000h and
                   1029:        jnz     no_fix32_ovf                            // sign1 = pos (zf=0)
                   1030: check_sign_32:
                   1031:        movb    positive,%al                    // al is overflow flag
                   1032:        cmpb    sign1(%ebp),%al                 // negate integer if
                   1033:        jz      no_fix32_ovf                            // sign is neg (zf=1)
                   1034:        negl    dword_frac1+frac32(%ebp)
                   1035:        xorb    %al,%al                                 // no overflow (zf=1)
                   1036: no_fix32_ovf:
                   1037:        ret
                   1038: //fix32        endp
                   1039: //
                   1040: // **************************************************************************
                   1041: //             int32_store:
                   1042: //
                   1043: //     function:
                   1044: //             stores into 32-bit integer format
                   1045: //
                   1046: //     input:
                   1047: //             operand1
                   1048: //
                   1049: //     output:
                   1050: //             32-bit integer in location pointed to by es:di.
                   1051: //
                   1052: //     data accessed:
                   1053: //             - mem_operand_pointer           offset_operand1
                   1054: //             - sign1                         tag1
                   1055: //             - expon1                        word_frac1
                   1056: //             - msb_frac1                     offset_operand1
                   1057: //
                   1058: //     data changed:
                   1059: //             - word_frac1
                   1060: //
                   1061: //     procedures called:
                   1062: //             pop_free
                   1063: //             fix32
                   1064: //
                   1065: // **************************************************************************
                   1066:        ALIGN
                   1067: int32_store:   //proc
                   1068:        cmpb    valid,tag1(%ebp)
                   1069:        je      valid_32
                   1070:        cmpb    denormd,tag1(%ebp)
                   1071:        jne     special_32
                   1072: valid_32:
                   1073:        call    fix32                           // make op1 a 32-bit int
                   1074:        jnz     special_32                      // if zf=0, oflow on fix
                   1075:        cmpw    $0,rnd_history
                   1076:        je      store_32
                   1077:        orb     $inexact_mask,%gs:sr_errors
                   1078:        cmpb    true,added_one
                   1079:        jne     store_32
                   1080:        orb     $a_mask,%gs:sr_flags
                   1081: store_32:
                   1082:        mov     dword_frac1+frac32(%ebp),%eax   // move integer to eax
                   1083: pointer_32:
                   1084:        les     mem_operand_pointer(%ebp),%edi  //set es:di to location
                   1085: finish_32:
                   1086:        mov     %eax,%es:(%edi)         // store integer to mem
                   1087: //..
                   1088: //..           pushad
                   1089: //..           push    es
                   1090: //..           push    edi
                   1091: //..           push    eax
                   1092: //..           call    fpsulong
                   1093: //..           add     esp,12
                   1094: //..           popad
                   1095: //..           cld
                   1096: //..
                   1097:        jmp     pop_free                        // pop stack and go home
                   1098:        ALIGN
                   1099: special_32:
                   1100:        xor     %eax,%eax
                   1101:        cmpb    special,tag1(%ebp)              // is operand tagged special?
                   1102:        je      pointer_32                              // yes, load memop ptr and exit
                   1103:        orb     invalid_mask,%gs:sr_errors// no, set invalid error
                   1104:        mov     $0x080000000,%eax       // load inv constant into ax
                   1105:        testb   invalid_mask,%gs:sr_masks// is invalid error masked?
                   1106:        jnz     pointer_32                              // yes, store invalid constant
                   1107:        ret
                   1108: //int32_store  endp
                   1109: //
                   1110: // ***********************************************************************
                   1111: //             fix64:
                   1112: //
                   1113: //     function:
                   1114: //              fixes valid number to a 64-bit integer.
                   1115: //
                   1116: //     inputs:
                   1117: //              operand1
                   1118: //
                   1119: //     outputs:
                   1120: //             64-bit integer in word_frac1 + 2;
                   1121: //             overflow indication in zf (zf:1 => no overflow)
                   1122: //
                   1123: //     data accessed:
                   1124: //             - offset_operand1               sign1
                   1125: //             - dword_expon1                  word_frac1
                   1126: //             - offset_operand1
                   1127: //
                   1128: //     data changed:
                   1129: //             - word_frac1
                   1130: //
                   1131: //     procedures called:
                   1132: //             sticky_right_shift              round
                   1133: //
                   1134: // ***************************************************************************
                   1135:        ALIGN
                   1136: fix64: //proc
                   1137:        mov     high_int64_exponent,%ecx                // calc shift amount
                   1138:        sub     dword_expon1,%ecx                       // if expon1 > high expon
                   1139:        js      no_fix64_ovf                            // then overflow (zf=0)
                   1140:        cmp     max_int64_shift,%ecx                    // dont let shift amount
                   1141:        jbe     do_shift_64                             // exceed max_int64_shift
                   1142:        mov     max_int64_shift,%ecx
                   1143: do_shift_64:
                   1144:        mov     $offset_operand1,%edi           // shift frac1 by cl
                   1145:        xorb    %al,%al
                   1146:        call    sticky_right_shift
                   1147:        mov     $offset_operand1,%edi           // round to 64-bit prec
                   1148:        movb    prec64,%dl
                   1149:        movb    false,%al
                   1150:        call    round
                   1151:        cmpb    false,%al                               // overflow if al=true
                   1152:        jnz     no_fix64_ovf                            // round cy out (zf=1)
                   1153:        cmpl    $0x080000000,dword_frac1+frac32(%ebp)
                   1154:        jb      check_sign_64                   // no overflow if < 80000000h
                   1155:        ja      no_fix64_ovf                            // else, overflow (zf=0)
                   1156:        cmp     $0,dword_frac1+frac64(%ebp)
                   1157:        jnz     no_fix64_ovf
                   1158:        cmpb    negative,sign1(%ebp)    // oflow if = 800..0h and
                   1159:        jnz     no_fix64_ovf                            // sign1 = pos (zf=0)
                   1160: check_sign_64:
                   1161:        movb    positive,%al                    // al is overflow flag
                   1162:        cmpb    sign1(%ebp),%al                 // negate integer if
                   1163:        jz      no_fix64_ovf                            // sign is neg (zf=1)
                   1164:        xor     %eax,%eax
                   1165:        negl    dword_frac1+frac64(%ebp)
                   1166:        sbb     dword_frac1+frac32(%ebp),%eax
                   1167:        mov     %eax,dword_frac1+frac32(%ebp)
                   1168:        xorb    %al,%al                                 // no overflow (zf=1)
                   1169: no_fix64_ovf:
                   1170:        ret
                   1171: //fix64        endp
                   1172: //
                   1173: // *****************************************************************************
                   1174: //                     int64_store:
                   1175: //                     ************
                   1176: //     function:
                   1177: //             stores into 64-bit integer format
                   1178: //
                   1179: //     input:
                   1180: //             operand1
                   1181: //
                   1182: //     output:
                   1183: //             64-bit integer in memory location pointed to by es:edi.
                   1184: //
                   1185: //     data accessed:
                   1186: //             - mem_operand_pointer           offset_operand1
                   1187: //             - sign1                         tag1
                   1188: //             - expon1                        word_frac1
                   1189: //             - msb_frac1                     offset_operand1
                   1190: //
                   1191: //     data changed:
                   1192: //             - word_frac1
                   1193: //
                   1194: //     procedures called:
                   1195: //             pop_free
                   1196: //
                   1197: // ***************************************************************************
                   1198:        ALIGN
                   1199: int64_store:   //proc
                   1200:        cmpb    valid,tag1(%ebp)
                   1201:        je      valid_64
                   1202:        cmpb    denormd,tag1(%ebp)
                   1203:        jne     special_64
                   1204: valid_64:
                   1205:        call    fix64                           // make op1 a 64-bit int
                   1206:        jnz     special_64                      // if zf=0, oflow on fix
                   1207:        cmpw    $0,rnd_history
                   1208:        je      store_64
                   1209:        orb     $inexact_mask,%gs:sr_errors
                   1210:        cmpb    true,added_one
                   1211:        jne     store_64
                   1212:        orb     $a_mask,%gs:sr_flags
                   1213: store_64:
                   1214:        mov     dword_frac1+frac64(%ebp),%eax   // move integer to edx:eax
                   1215:        mov     dword_frac1+frac32(%ebp),%edx   // move integer to edx:eax
                   1216: pointer_64:
                   1217:        les     mem_operand_pointer(%ebp),%edi  //set es:edi to location
                   1218: finish_64:
                   1219:        mov     %eax,%es:(%edi)         // store low integer to low mem
                   1220: //..
                   1221: //..           pushad
                   1222: //..           push    es
                   1223: //..           push    edi
                   1224: //..           push    eax
                   1225: //..           call    fpsulong
                   1226: //..           add     esp,12
                   1227: //..           popad
                   1228: //..           cld
                   1229: //..
                   1230:        mov     %edx,%es:4(%edi)                // store high integer to high mem
                   1231: //..
                   1232: //..           pushad
                   1233: //..           push    es
                   1234: //..           push    edi
                   1235: //..           push    edx
                   1236: //..           call    fpsulong
                   1237: //..           add     esp,12
                   1238: //..           popad
                   1239: //..           cld
                   1240: //..
                   1241:        jmp     pop_free                        // pop stack and go home
                   1242:        ALIGN
                   1243: special_64:
                   1244:        xor     %eax,%eax
                   1245:        cltd
                   1246:        cmpb    special,tag1(%ebp)              // is operand tagged special?
                   1247:        je      pointer_64                              // yes, load memop ptr and exit
                   1248:        orb     invalid_mask,%gs:sr_errors// no, set invalid error
                   1249:        mov     $0x080000000,%edx       // load inv constant into ax
                   1250:        testb   invalid_mask,%gs:sr_masks// is invalid error masked?
                   1251:        jnz     pointer_64              // yes, store invalid constant
                   1252:        ret
                   1253: 
                   1254: //int64_store  endp
                   1255: //
                   1256: //a_med        ends
                   1257: //
                   1258: //     end

unix.superglobalmegacorp.com

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