Annotation of kernel/machdep/i386/fp_emul/fp_divmul.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   "divmul.s"
                     26: 
                     27:        .ident  "@(#)kern-fp:divmul.s   1.1"
                     28: 
                     29: // ***********************************************************************
                     30: //
                     31: //                     m u l d i v . 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: //             preforms floating-point divide of unpacked
                     44: //             non-zero, valid numbers.
                     45: //             performs floating-point multiply of unpacked
                     46: //             non-zero, valid numbers.
                     47: //
                     48: //     public procedures:
                     49: //             mulx                    mult
                     50: //             divx                    divid
                     51: //
                     52: // ****************************************************************************
                     53: //
                     54: //...september 16, 1983...
                     55: //
                     56: //     .file   *a_mdm*
                     57: //$nolist
                     58: #include       "fp_e80387.h"
                     59: //$list
                     60:        .text   //a_med segment er      public
                     61: //
                     62: //     extrn   sticky_right_shift,one_left_normalize
                     63: //     extrn   clear_5w,test_5w,test_3w,set_5w
                     64: //     extrn   get_precision,set_i_error
                     65: //     extrn   left_shift_result_cl
                     66: //
                     67:        .globl  accel_divx
                     68:        .globl  divx
                     69:        .globl  divid
                     70:        .globl  log_divx
                     71:        .globl  mulx
                     72:        .globl  mult
                     73: //
                     74:        ALIGN
                     75: quotient_length:       
                     76:        .byte   28,36,57,68     // incremented and changed to
                     77: log_quotient_length:   
                     78:        .byte   28,36,60,68     // a byte table on 12/02/82.
                     79:                                                // for unknown reasons, divx
                     80:                                                // doesnt work with 53-bit
                     81:                                                // precision from log function
                     82: low_quotient_byte:     
                     83:        .byte   offset_result+6,offset_result+4
                     84:        .byte   offset_result+2,offset_result+1
                     85: //$eject
                     86: // *********************************************************************
                     87: //                     accel_divx:
                     88: //                     **********
                     89: //     function:
                     90: //              fractional divide. result_frac <-- frac1/frac2.
                     91: //
                     92: //     inputs:
                     93: //             frac2 is assumed to be normalized and non-zero.
                     94: //
                     95: //     outputs:
                     96: //             the sticky bit is set for result_frac
                     97: //             the remainder for ((frac1)/2)mod(frac2) is left in frac1
                     98: //
                     99: //     data accessed:
                    100: //             - dword_frac1           offset_operand2
                    101: //             - dword_frac2           result_dword_frac
                    102: //             - lsb_result            offset_operand1
                    103: //
                    104: //     data changed:
                    105: //             - dword_frac1           result_dword_frac
                    106: //             - lsb_result
                    107: //
                    108: //     procedures called:
                    109: //             sticky_right_shift              get_precision
                    110: //
                    111: // *********************************************************************
                    112:        ALIGN
                    113: divisor_dwords:        
                    114:        .byte   1,2,2,2
                    115: quotient_dwords:       
                    116:        .byte   1,2,2,3
                    117: 
                    118: #define        r_apprx_j       extra_dword_reg(%ebp)
                    119: #define        q_apprx_j       extra_dword_reg+4(%ebp)
                    120: #define        carry   extra_dword_reg+8(%ebp)
                    121: 
                    122:        ALIGN
                    123: accel_divx:    //proc
                    124: clr_quo:
                    125:        mov     $offset_result,%edi
                    126:        call    clear_6w                        // clears eax as well.
                    127:        mov     $offset_operand1,%edi   // shift frac1 (here, the dividend)
                    128:        movb    $1,%cl                                  // right by 1 bit
                    129:        call    sticky_right_shift
                    130:        call    get_precision
                    131:        cmpb    prec64,%dl
                    132:        je      prec_to_base
                    133:        movb    dword_frac1+3(%ebp),%cl
                    134:        movb    %cl,lsb_result
                    135: prec_to_base:
                    136:        movzbl  %dl,%ebx
                    137:        movl    $quotient_dwords,%edi   //(edi) has offset quotient_dwords table
                    138:        movzbl  %cs:(%ebx,%edi),%ecx    // q holds the number of dwords
                    139:        movb    %cl,q                   // to be produced for the quotient.
                    140:        lea     dword_frac1+frac64(%ebp),%esi
                    141:        push    %ss:4(%esi)
                    142: 
                    143:        testb   $1, is16bit(%ebp)
                    144:        jz      prec_32
                    145:        movzwl  %sp, %edx
                    146:        jmp     prec_32c        
                    147:        ALIGN
                    148: prec_32:
                    149:        mov     %esp,%edx         // edx holds the offset relative to ss of the
                    150:                                     // interim partial remainders highest dword.
                    151: prec_32c:
                    152:        dec     %ecx
                    153:        jnz     push_dvdnd
                    154:        inc     %ecx
                    155:        FALLSTHRU
                    156: push_dvdnd:
                    157:        push    %ss:(%esi)
                    158:        sub     $4,%esi
                    159:        LOOP(push_dvdnd)
                    160: set_up_push_dvsr:
                    161:        mov     %ecx,%eax               // ecx is 0 here.
                    162:        movl    $divisor_dwords,%edi
                    163:        movb    %cs:(%ebx,%edi),%cl     // bit_ct holds the number of
                    164:        movb    %cl,bit_ct                      // dwords in the divisor.
                    165:        FALLSTHRU
                    166: push_zeroes:
                    167:        push    %eax
                    168:        LOOP(push_zeroes)
                    169:        mov     %edx,%ebx         // ebx holds the offset relative to ss of the
                    170:                                     // interim partial remainders highest word.
                    171:        mov     %eax,%edi       // edi is index to words of quotient.
                    172:        movb    q,%cl
                    173: main_loop:
                    174:        push    %ecx
                    175:        mov     %ss:(%ebx),%edx
                    176:        cmp     dword_frac2+frac32(%ebp),%edx // is dvsr(1) = prem(j)?
                    177:        jne     do_divide
                    178:        movl    $0x0ffffffff,%eax       // eax <-- apprx_q(j) = 2**32 - 1
                    179:        movl    %ss:-4(%ebx),%edx       // edx <-- prem(j+1)
                    180:        jmp     get_r_apprx_j
                    181:        ALIGN
                    182: do_divide:
                    183:        movl    %ss:-4(%ebx),%eax       // (edx,eax) <-- prem(j) * 2**32 + prem(j+1)
                    184:        divl    dword_frac2+frac32(%ebp)
                    185:        mov     %eax,q_apprx_j
                    186:        mov     %edx,r_apprx_j
                    187:        jmp     test_q_apprx_j
                    188:        ALIGN
                    189: dec_q_apprx_j:
                    190:        mov     q_apprx_j,%eax
                    191:        dec     %eax
                    192:        mov     r_apprx_j,%edx
                    193: get_r_apprx_j:
                    194:        mov     %eax,q_apprx_j
                    195:        add     dword_frac2+frac32(%ebp),%edx // r_apprx_j <-- edx + dvsr(1)
                    196:        jc      adjst_prem
                    197:        mov     %edx,r_apprx_j
                    198: test_q_apprx_j:
                    199:        mov     q_apprx_j,%eax
                    200:        mull    dword_frac2+frac64(%ebp) // (edx,eax) <-- dvsr(2)*q_apprx_j
                    201:        cmp     r_apprx_j,%edx
                    202:        jb      adjst_prem
                    203:        ja      dec_q_apprx_j
                    204:        cmp     %ss:-8(%ebx),%eax       // is eax > prem(j+2)?
                    205:        ja      dec_q_apprx_j
                    206: adjst_prem:
                    207:        xor     %eax,%eax
                    208:        mov     %eax,carry
                    209:        movb    bit_ct,%al
                    210:        mov     %eax,%ecx
                    211:        shl     $2,%eax
                    212:        neg     %eax
                    213:        mov     %eax,%esi
                    214:        FALLSTHRU
                    215: prem_loop:
                    216:        mov     sign2(%ebp,%esi),%eax
                    217:        mull    q_apprx_j
                    218:        sub     %eax,%ss:(%ebx,%esi)
                    219:        jnc     sbtrct_carry
                    220:        inc     %edx
                    221: sbtrct_carry:
                    222:        mov     carry,%eax
                    223:        sub     %eax,%ss:(%ebx,%esi)
                    224:        jnc     next_carry
                    225:        inc     %edx
                    226: next_carry:
                    227:        mov     %edx,carry
                    228:        add     $4,%esi
                    229:        LOOP(prem_loop)
                    230: //             
                    231:        sub     %edx,%ss:(%ebx,%esi)   // here, esi = 0.
                    232:        jnc     next_j
                    233:        decl    q_apprx_j
                    234:        movb    bit_ct,%cl
                    235:        mov     %ecx,%eax
                    236:        shl     $2,%eax
                    237:        neg     %eax
                    238:        mov     %eax,%esi
                    239:        clc
                    240:        FALLSTHRU
                    241: fix_prem_loop:
                    242:        mov     sign2(%ebp,%esi),%eax
                    243:        adc     %eax,%ss:(%ebx,%esi)
                    244:        add     $4,%esi
                    245:        LOOP(fix_prem_loop)
                    246: //
                    247:        adc     %ecx,%ss:(%ebx,%esi)
                    248: next_j:
                    249:        mov     q_apprx_j,%eax
                    250:        mov     %eax,result_dword_frac+frac32(%ebp,%edi)
                    251:        pop     %ecx
                    252:        dec     %ecx
                    253:        jz      get_sticky_bit
                    254:        sub     $4,%ebx
                    255:        sub     $4,%edi
                    256:        jmp     main_loop
                    257:        ALIGN
                    258: //
                    259: get_sticky_bit:
                    260:        mov     %ecx,%eax
                    261:        mov     %eax,%esi
                    262:        movb    bit_ct,%cl
                    263:        shlb    $1,%cl
                    264:        FALLSTHRU
                    265: sticky_loop:
                    266: //     orw     %ax,%ss:(%ebx+%esi-2) // bug in asm386 hardcoded
                    267:        .byte   0x066,0x36,0x00b,0x44,0x33,0x0fe
                    268: 
                    269:        sub     $2,%esi
                    270:        LOOP(sticky_loop)
                    271:        orb     %al,%ah
                    272:        orb     %ah,lsb_result
                    273:        mov     %ecx,%esi
                    274:        movb    bit_ct,%cl
                    275: //     
                    276:        FALLSTHRU
                    277: stor_rmndr:
                    278: //     movl    %eax,%ss:(%ebx+%esi-4) // bug in asm386 hard coded
                    279:        .byte   0x36,0x8b,0x44,0x33,0x0fc
                    280: 
                    281:        mov     %eax,dword_frac1+frac32(%ebp,%esi)
                    282:        sub     $4,%esi
                    283:        LOOP(stor_rmndr)
                    284: //
                    285:        movb    q,%cl
                    286:        addb    bit_ct,%cl
                    287:        cmpb    $2,%cl
                    288:        jne     get_stack_dwords
                    289:        inc     %ecx
                    290: get_stack_dwords:
                    291:        shl     $2,%ecx
                    292:        add     %ecx,%esp                  //   restore stack
                    293: //
                    294:        ret
                    295: //accel_divx   endp
                    296: // *********************************************************************
                    297: //                     divx:
                    298: //                     ****
                    299: //     function:
                    300: //              fractional divide. result_frac <-- frac1/frac2.
                    301: //
                    302: //     inputs:
                    303: //             frac2 is assumed to be normalized and non-zero.
                    304: //
                    305: //     outputs:
                    306: //             the sticky bit is set for result_frac
                    307: //             the remainder is left in frac1
                    308: //
                    309: //     data accessed:
                    310: //             - word_frac1            offset_operand2
                    311: //             - word_frac2            result_word_frac
                    312: //             - lsb_result
                    313: //
                    314: //     data changed:
                    315: //             - word_frac1            result_word_frac
                    316: //             - lsb_result
                    317: //
                    318: //     procedures called:
                    319: //             sticky_right_shift              get_precision
                    320: //
                    321: // *********************************************************************
                    322:        ALIGN
                    323: divx:  //proc
                    324:        push    $quotient_length                // set normal entry ptr
                    325:        jmp     clear_quotient
                    326:        ALIGN
                    327: log_divx:
                    328:        push    $log_quotient_length    // set log entry ptr
                    329: clear_quotient:
                    330:        mov     $offset_result,%edi
                    331:        call    clear_6w
                    332:        mov     $offset_operand2,%edi           //shift frac2 (divisor)
                    333:        movb    $1,%cl                          //right by 1 bit
                    334:        call    sticky_right_shift
                    335:        call    get_precision
                    336:        movzbl  %dl, %ebx
                    337:        pop     %edi            //retrieve offset quotient length table
                    338:        movb    %cs:(%ebx,%edi),%al                     // bit_ct holds
                    339:        movb    %al,bit_ct                      // the quotient bits
                    340:        movzbl  %cs:low_quotient_byte(%ebx),%eax        //(edi) points to low-
                    341:                                        //order byte of quotient
                    342:        mov     %eax,%edi
                    343:        movl    dword_frac1(%ebp),%eax          //load dividend (frac1)
                    344:        movl    dword_frac1+frac64(%ebp),%ebx  // in frac1
                    345:        movl    dword_frac1+frac32(%ebp),%edx
                    346:        .long   0x02d8ac0f      //shrd   eax, ebx, 2
                    347:        .long   0x02d3ac0f      //shrd   ebx, edx, 2
                    348:        shrl    $2,%edx                         //shift dvdnd rt 2 bits
                    349:        jmp     subtract_divisor
                    350:        ALIGN
                    351: frac_divide_loop:
                    352:        shll    $1,%eax                         //shift dvdnd (partial
                    353:        rcll    $1,%ebx                         //remainder) lft one bit
                    354:        rcll    $1,%edx
                    355:        jc      quotient_bit_0                  //jump if cy from shift
                    356:        orb     $0x20,frac80(%ebp,%edi)         // *shift in* a 1-bit
                    357: subtract_divisor:
                    358:        subl    dword_frac2(%ebp),%eax          //subtract divisor from
                    359:        sbbl    dword_frac2+frac64(%ebp),%ebx           //partial remainder
                    360:        sbbl    dword_frac2+frac32(%ebp),%edx
                    361:        jmp     shift_quotient_left
                    362:        ALIGN
                    363: quotient_bit_0:
                    364:        call    add_divisor                     // add divisor to prem
                    365: shift_quotient_left:
                    366:        call    shift_result_left
                    367:        decb    bit_ct                          // decrement bit count
                    368:        jnz     frac_divide_loop                //  next quotient bit
                    369:        andl    %edx,%edx                       // branch if remainder
                    370:        js      adjust_remainder                //  is negative
                    371:        orb     $0x20,frac80(%ebp,%edi)         // *shift in* last 1-bit
                    372:        jmp     store_remainder
                    373:        ALIGN
                    374: adjust_remainder:
                    375:        call    add_divisor                     //add divisor to prem
                    376: store_remainder:
                    377:        movl    %eax,dword_frac1(%ebp)          //store partial rmndr
                    378:        movl    %ebx,dword_frac1+frac64(%ebp)  // in frac1
                    379:        movl    %edx,dword_frac1+frac32(%ebp)
                    380:        orl     %ebx,%eax                       //set sticky bits if
                    381:        orl     %edx,%eax                       //partial rmndr non-zero
                    382:        .long   0x10c2a40f              // shld edx, eax, 16
                    383:        orw     %dx, %ax
                    384:        orb     %al,%ah
                    385:        movb    %ah,lsb_result
                    386:        ret
                    387:        ALIGN
                    388: add_divisor:
                    389:        addl    dword_frac2(%ebp),%eax          //store partial rmndr
                    390:        adcl    dword_frac2+frac64(%ebp),%ebx  // in frac1
                    391:        adcl    dword_frac2+frac32(%ebp),%edx
                    392:        ret
                    393:        ALIGN
                    394: shift_result_left:
                    395:        shll    $1,result_dword_frac(%ebp)
                    396:        rcll    $1,result_dword_frac+frac64(%ebp)
                    397:        rcll    $1,result_dword_frac+frac32(%ebp)
                    398:        ret
                    399: //divx endp
                    400: //$eject
                    401: // *************************************************************************
                    402: //                     divid:
                    403: //                     ******
                    404: //     function:
                    405: //             floating-point divide.
                    406: //
                    407: //     inputs:
                    408: //             assumes operands are unpacked, non-zero, and valid
                    409: //
                    410: //     outputs:
                    411: //             calculates unpacked result and returns with al
                    412: //             set to true if underflow is possible, false if
                    413: //             overflow is possible.  the quotient is left in
                    414: //             the result, and the remainder is left in frac1.
                    415: //
                    416: //     data accessed:
                    417: //             - expon1                        expon2
                    418: //             - msb_frac2                     offset_result
                    419: //             - result_sign                   result_expon
                    420: //             - result_word_frac
                    421: //
                    422: //     data changed:
                    423: //             - result_sign                   result_expon
                    424: //             - result_word_frac
                    425: //
                    426: //     procedures called:
                    427: //             divx                            one_left_normalize
                    428: //             set_i_error                     get_precision
                    429: //             left_shift_result_cl
                    430: //
                    431: // *************************************************************************
                    432:        ALIGN
                    433: divid: //proc
                    434:        movl    dword_expon1,%eax               // stack underflow possible
                    435:        subl    dword_expon2,%eax               // flag (sign bit)
                    436:        addl    $exponent_bias,%eax     //form biased exponent
                    437:        movl    %eax,dword_result_expon
                    438:        movb    sign1(%ebp),%al         // sign = '+' if sign1 = sign2
                    439:        xorb    sign2(%ebp),%al
                    440:        movb    %al,result_sign(%ebp)
                    441: fractional_divide:
                    442:        call    accel_divx
                    443: //             The following five lines are not to be used when accel_divx
                    444: //     does the division instead of divx.
                    445: //     call    get_precision
                    446: //     cmpb    prec53,%dl              /if double precision, shift
                    447: //     jne     norm_quotient           / quotient left 3 bits
                    448: //     movb    $3,%cl
                    449: //     call    left_shift_result_cl
                    450: norm_quotient:
                    451:        mov     $offset_result,%edi     //normalize by 1 left
                    452:        jmp     one_left_normalize      // shift, if unnormalized
                    453:        ALIGN
                    454: //divid        endp
                    455: //$eject
                    456: // **********************************************************************
                    457: //                     mult:
                    458: //                     ****
                    459: //     function:
                    460: //             floating point multiply.
                    461: //
                    462: //     inputs:
                    463: //             assumes operands are unpacked, valid, non-zero.
                    464: //
                    465: //     outputs:
                    466: //             calculates unpacked result and returns with al set
                    467: //             to true if underflow is possible, false if overflow
                    468: //             is possible.
                    469: //
                    470: //     data accessed:
                    471: //             - sign1                 expon1
                    472: //             - sign2                 expon2
                    473: //             - offset_result         result_sign
                    474: //             - result_expon
                    475: //
                    476: //     data changed:
                    477: //             - result
                    478: //
                    479: //     procedures called:
                    480: //             mulx                            norm_quotient
                    481: //
                    482: // ****************************************************************************
                    483:        ALIGN
                    484: mult:  //proc
                    485:        movl    dword_expon1,%eax               //form doubly-biased exponent
                    486:        addl    dword_expon2,%eax               //if high bit set, underflow
                    487:        subl    $exponent_bias-1,%eax   //form singly-biased exponent
                    488:        movl    %eax,dword_result_expon
                    489:        movb    sign1(%ebp),%al         // result sign = sign1 xor sign2
                    490:        xorb    sign2(%ebp),%al
                    491:        movb    %al,result_sign(%ebp)
                    492:        call    mulx
                    493:        movl    $offset_result, %edi    //normalize by 1 left
                    494:        jmp     one_left_normalize      // shift if unnormalized 
                    495: //mult endp
                    496: //$eject
                    497: // **********************************************************************
                    498: //                     mulx:
                    499: //                     *****
                    500: //     function:
                    501: //             fractional multiply. result_frac <-- frac1 * frac2.
                    502: //
                    503: //     inputs:
                    504: //             assumes the operands are unpacked, valid, non-zero.
                    505: //
                    506: //     outputs:
                    507: //             product in result_frac (sticky indicator left in low bit)
                    508: //
                    509: //     data accessed:
                    510: //             - word_frac1                    offset_operand1
                    511: //             - word_frac2                    offset_operand2
                    512: //             - extra_word_reg                lsb_result
                    513: //             - offset_result
                    514: //
                    515: //     data changed:
                    516: //             - extra_word_reg                offset_result
                    517: //
                    518: //     procedures called:
                    519: //             clear_5w                        set_5w
                    520: //             test_3w                         test_5w
                    521: //
                    522: // ************************************************************************
                    523:        ALIGN
                    524: mulx:  //proc
                    525:        push    %ds                     // save a?msr
                    526:        movl    $extra_dword_reg,%edi // ss:bp+di => extra_word_reg
                    527:        push    %ss
                    528:        pop     %ds
                    529:        lea     (%ebp,%edi),%ebx                // ds:bx also => extra_word_reg
                    530:        call    clear_6w                // clear extra_word_reg
                    531:        movl    $offset_result,%edi     // clear result_frac
                    532:        call    set_6w
                    533:        movl    $frac32,%ecx            // load s.p. offset
                    534:        movl    $offset_operand2,%edi   //di => to multiplier
                    535:        call    test_4w                 //if low 3 words <> zero,
                    536:        jnz     examine_frac1           // branch if non single
                    537:        add     %ecx,%edi                       //frac2 is s. p.,
                    538:        add     %ecx,%ebx                       //so adjust pointers
                    539: examine_frac1:
                    540:        movl    $offset_operand1,%esi   //si points to multiplicand
                    541:        movl    frac64(%ebp,%esi),%eax  //if low 3 words = zero,
                    542:        orl     (%ebp,%esi),%eax        //then single precision
                    543:        jnz     do_frac_multiply
                    544:        add     %ecx,%esi                       //frac1 is s. p.,
                    545:        add     %ecx,%ebx                       //so adjust pointers
                    546: do_frac_multiply:
                    547:        push    %edi                    // save frac2 offset
                    548:        movl    (%ebp,%edi),%edi                // load multiplier
                    549:        xorl    %ecx,%ecx                       //clear cx
                    550:        movl    (%ebp,%esi),%eax                // multiply first word
                    551:        mull    %edi
                    552:        addl    %eax,(%ebx)                     //add to partial product
                    553:        adcl    %edx,%ecx                       // cx initially 0
                    554:        cmpl    $offset_operand1, %esi
                    555:        je      mult_scnd
                    556:        movl    %ecx, 4(%ebx)           //multiplicand is s. p. so
                    557:        jmp     end_of_mul_loop         //go to multipliers next word
                    558: mult_scnd:
                    559:        movl    4(%ebp,%esi),%eax       // multiply second word
                    560:        mull    %edi
                    561:        addl    %ecx,%eax
                    562:        adcl    $0,%edx
                    563:        xorl    %ecx,%ecx
                    564:        addl    %eax,4(%ebx)            //add to partial product
                    565:        adcl    %edx,%ecx
                    566:        movl    8(%ebp,%esi), %eax
                    567:        mull    %edi
                    568:        addl    %ecx, %eax
                    569:        adcl    $0, %edx
                    570:        addl    %eax, 8(%ebx)
                    571:        adcl    $0, %edx
                    572:        movl    %edx, 12(%ebx)
                    573: end_of_mul_loop:
                    574:        pop     %edi                    // reload frac2 offset
                    575:        addl    $4, %ebx                //adjust pointers for next iteration
                    576:        addl    $4, %edi
                    577:        cmp     $(offset_operand2+12),%edi
                    578:        jne     do_frac_multiply
                    579:        movl    $extra_dword_reg,%edi //set sticky bit if any extra
                    580:        call    test_6w                 // reg words are nonzero
                    581:        jz      frac_mult_done
                    582:        orb     $0x01,lsb_result
                    583: frac_mult_done:
                    584:        pop     %ds                     // restore a?msr
                    585:        ret
                    586: //mulx endp
                    587: //
                    588: //a_med        ends
                    589: //
                    590: //     end

unix.superglobalmegacorp.com

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