Annotation of coherent/b/lib/libc/crt/i386/dmul.s, revision 1.1

1.1     ! root        1: //////////
        !             2: / libc/crt/i386/dmul.s
        !             3: / i386 C runtime library.
        !             4: / IEEE software floating point support.
        !             5: //////////
        !             6: 
        !             7: //////////
        !             8: / double _dmul(double d)
        !             9: / Return d * %edx:eax in %edx:%eax.
        !            10: /
        !            11: / In 32-bit dwords:
        !            12: / A    = hiA:loA
        !            13: / B    = hiB:loB
        !            14: / A*B  = hi(hiA*hiB):lo(hiA*hiB)
        !            15: /      +             hi(hiA*loB):lo(hiA*loB)
        !            16: /      +             hi(loA*hiB):lo(loA*hiB)
        !            17: /      +                         lo(loA*loB):lo(loA*loB)
        !            18: / Multiplying two n bit quantities produces a 2*n-1 or 2*n bit result.
        !            19: / Thus, multiplying two 53 bit quantities produces a 105 or 106 bit result.
        !            20: / We want a normalized 53-bit result, so the lo-order dword above is irrelevant.
        !            21: //////////
        !            22: 
        !            23: d      .equ    8
        !            24: BIAS   .equ    1023
        !            25: EXPMASK        .equ    0x7FF00000
        !            26: MANMASK        .equ    0x000FFFFF
        !            27: SGNMASK        .equ    0x80000000
        !            28: HIDDEN .equ    0x00100000
        !            29: 
        !            30:        .globl  _dmul
        !            31: 
        !            32: _dmul:
        !            33:        push    %ebp
        !            34:        movl    %ebp, %esp
        !            35:        push    %esi
        !            36:        push    %edi
        !            37:        push    %ebx
        !            38:        push    %ecx
        !            39: 
        !            40:        movl    %esi, d+4(%ebp)
        !            41:        movl    %edi, d(%ebp)           / d to ESI:EDI, call it A
        !            42:                                        / now done with EBP as index register
        !            43: 
        !            44:        / Check for special cases +-0.0 and +-infinity on each side.
        !            45:        movl    %ebx, %esi
        !            46:        andl    %ebx, $EXPMASK
        !            47:        jz      ?retlhs                 / A is 0.0, return it; ignore denormal
        !            48:        cmpl    %ebx, $EXPMASK
        !            49:        jz      ?retlhs                 / A is +-infinity or NaN, return it
        !            50:        movl    %ecx, %edx
        !            51:        andl    %ecx, $EXPMASK
        !            52:        jz      ?done                   / B is 0.0, return it; ignore denormal
        !            53:        cmpl    %ecx, $EXPMASK
        !            54:        jz      ?done                   / B is +-infinity or NaN, return it
        !            55: 
        !            56:        / Compute result sign.
        !            57:        movl    %ebp, %edx
        !            58:        xorl    %ebp, %esi
        !            59:        andl    %ebp, $SGNMASK
        !            60:        push    %ebp                    / save result sign bit
        !            61: 
        !            62:        / Compute result exponent.
        !            63:        shrl    %ebx, $20               / A biased exp in EBX
        !            64:        shrl    %ecx, $20               / B biased exp in ECX
        !            65:        subl    %ecx, $BIAS             / unbiased
        !            66:        addl    %ecx, %ebx              / form biased result exponent
        !            67:        jl      ?zero                   / underflow, return 0.0
        !            68:        cmpl    %ecx, $EXPMASK>>20
        !            69:        jge     ?inf                    / overflow, return +-infinity
        !            70:        movl    %ebp, %ecx              / save result exponent in EBP
        !            71: 
        !            72:        / Perform the 64*64 bit multiply.
        !            73:        andl    %esi, $MANMASK
        !            74:        orl     %esi, $HIDDEN           / extract A mantissa, restore hidden bit
        !            75:        andl    %edx, $MANMASK
        !            76:        orl     %edx, $HIDDEN           / extract B mantissa, restore hidden bit
        !            77:        movl    %ecx, %edx
        !            78:        movl    %ebx, %eax              / B mantissa to ECX:EBX
        !            79: 
        !            80:        mul     %edi                    / loA*loB
        !            81:        push    %edx                    / save hi(loA*loB), ignore lo dword
        !            82:        movl    %eax, %ebx              / loB
        !            83:        mul     %esi                    / hiA*loB
        !            84:        xchgl   %edi, %eax              / lo(hiA*loB) to EDI, loA to EAX
        !            85:        movl    %ebx, %edx              / hi(hiA*loB) to EBX
        !            86:        mul     %ecx                    / loA*hiB
        !            87:        xchgl   %esi, %eax              / lo(loA*hiB) to ESI, hiA to EAX
        !            88:        xchgl   %ecx, %edx              / hi(loA*hiB) to ECX, hiB to EDX
        !            89:        mul     %edx                    / hiA*hiB, leave in EDX:EAX
        !            90: 
        !            91:        / Add partial products to obtain 96 bit product in EDX:EAX:ESI.
        !            92:        / This is really a 105-32=73 or 106-32=74 bit value, higher bits are 0.
        !            93:        addl    %esi, %edi
        !            94:        adcl    %eax, %ebx
        !            95:        adcl    %edx, $0
        !            96:        pop     %edi                    / hi(loA*loB)
        !            97:        addl    %esi, %edi
        !            98:        adcl    %eax, %ecx
        !            99:        adcl    %edx, $0
        !           100: 
        !           101:        / Normalize the result mantissa.
        !           102:        / The product presently contains 73 or 74 bits.
        !           103:        / The normalized result contains 53+32 = 85 bits.
        !           104:        movb    %cl, $12                / shift count to CL
        !           105:        testl   %edx, $0x200            / examine product bit 74
        !           106:        jz      ?L0                     / 73 bit product
        !           107:        decb    %cl                     / 74 bit product, decrement shift count
        !           108:        incl    %ebp                    / and bump the exponent
        !           109: 
        !           110: ?L0:
        !           111:        / Shift EDX:EAX:ESI left by CL bits.
        !           112:        shld    %edx, %eax, %cl
        !           113:        shld    %eax, %esi, %cl
        !           114:        shll    %esi, %cl
        !           115: 
        !           116:        / Round up result if appropriate.
        !           117:        shll    %esi, $1                / high bit of lo 64 bits to CF
        !           118: ?addcarry:
        !           119:        adcl    %eax, $0
        !           120:        adcl    %edx, $0
        !           121:        testl   %edx, $HIDDEN<<1
        !           122:        jnz     ?carry
        !           123: 
        !           124:        / Pack result mantissa from EDX:EAX, exponent from EBP, sign from stack.
        !           125: ?pack:
        !           126:        andl    %edx, $MANMASK          / mask off hidden bit
        !           127:        orl     %ebp, %ebp
        !           128:        jle     ?zero                   / exponent underflow, return 0.0
        !           129:        cmp     %ebp, $EXPMASK>>20
        !           130:        jge     ?inf                    / exponent overflow, return infinity
        !           131:        shll    %ebp, $20               / position exponent
        !           132:        orl     %edx, %ebp              / pack mantissa and exponent
        !           133:        pop     %ecx
        !           134:        orl     %edx, %ecx              / pack with sign
        !           135: 
        !           136:        / Return the value from EDX:EAX.
        !           137: ?done:
        !           138:        pop     %ecx
        !           139:        pop     %ebx
        !           140:        pop     %edi
        !           141:        pop     %esi
        !           142:        pop     %ebp
        !           143:        ret
        !           144: 
        !           145:        / Rounding generated carry past hidden bit, shift one bit right.
        !           146: ?carry:
        !           147:        incl    %ebp                    / bump the exponent
        !           148:        shrd    %eax, %edx, $1
        !           149:        pushfl
        !           150:        shrl    %edx, $1
        !           151:        popfl
        !           152:        jmp     ?addcarry
        !           153: 
        !           154:        / Return the value from ESI:EDI.
        !           155: ?retlhs:
        !           156:        xchgl   %esi, %edx
        !           157:        xchgl   %edi, %eax
        !           158:        jmp     ?done
        !           159: 
        !           160: ?inf:
        !           161:        pop     %edx                    / pop result sign bit
        !           162:        orl     %edx, $EXPMASK          / max exp, zero mantissa for infinity
        !           163:        jmp     ?L2
        !           164: 
        !           165: ?zero:
        !           166:        pop     %edx                    / pop sign bit and ignore
        !           167:        subl    %edx, %edx              / return 0.0
        !           168: ?L2:
        !           169:        subl    %eax, %eax
        !           170:        jmp     ?done
        !           171: 
        !           172: / end of libc/crt/i386/dmul.s

unix.superglobalmegacorp.com

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