|
|
1.1 ! root 1: .file "reg_u_mul.S" ! 2: /*---------------------------------------------------------------------------+ ! 3: | reg_u_mul.S | ! 4: | | ! 5: | Core multiplication routine | ! 6: | | ! 7: | Copyright (C) 1992 W. Metzenthen, 22 Parker St, Ormond, Vic 3163, | ! 8: | Australia. E-mail [email protected] | ! 9: | | ! 10: | | ! 11: +---------------------------------------------------------------------------*/ ! 12: ! 13: /*---------------------------------------------------------------------------+ ! 14: | Basic multiplication routine. | ! 15: | Does not check the resulting exponent for overflow/underflow | ! 16: | | ! 17: | Internal working is at approx 96 bits. | ! 18: | Result is rounded to nearest 64 bits, using "nearest or even". | ! 19: +---------------------------------------------------------------------------*/ ! 20: ! 21: #include "exception.h" ! 22: #include "fpu_asm.h" ! 23: ! 24: ! 25: ! 26: .data ! 27: .align 2,0 ! 28: accum_1: ! 29: .long 0 ! 30: ! 31: ! 32: .text ! 33: .align 2,144 ! 34: ! 35: .globl reg_u_mul ! 36: reg_u_mul: ! 37: pushl %ebp ! 38: movl %esp,%ebp ! 39: pushl %esi ! 40: pushl %edi ! 41: pushl %ebx ! 42: ! 43: movl PARAM1,%esi ! 44: movl PARAM2,%ecx ! 45: ! 46: #ifdef PARANOID ! 47: testl $0x80000000,SIGH(%esi) ! 48: jz xL_bugged ! 49: testl $0x80000000,SIGH(%ecx) ! 50: jz xL_bugged ! 51: #endif PARANOID ! 52: ! 53: xorl %edi,%edi ! 54: xorl %ebx,%ebx ! 55: ! 56: movl SIGL(%esi),%eax ! 57: mull SIGL(%ecx) ! 58: // movl %eax,accum_0 ! 59: movl %edx,accum_1 ! 60: ! 61: movl SIGL(%esi),%eax ! 62: mull SIGH(%ecx) ! 63: addl %eax,accum_1 ! 64: adcl %edx,%ebx ! 65: // adcl $0,%edi // overflow here is not possible ! 66: ! 67: movl SIGH(%esi),%eax ! 68: mull SIGL(%ecx) ! 69: addl %eax,accum_1 ! 70: adcl %edx,%ebx ! 71: adcl $0,%edi ! 72: ! 73: movl SIGH(%esi),%eax ! 74: mull SIGH(%ecx) ! 75: addl %eax,%ebx ! 76: adcl %edx,%edi ! 77: ! 78: movl EXP(%esi),%eax /* Compute the exponent */ ! 79: addl EXP(%ecx),%eax ! 80: // Have now finished with the sources ! 81: movl PARAM3,%esi // Point to the destination ! 82: movl %eax,EXP(%esi) ! 83: ! 84: // Now make sure that the result is normalized ! 85: testl $0x80000000,%edi ! 86: jnz L20 ! 87: ! 88: /* Normalize by shifting left one bit */ ! 89: // shll $1,accum_0 // If using this, change next to rcll ! 90: shll $1,accum_1 ! 91: rcll $1,%ebx ! 92: rcll $1,%edi ! 93: decl EXP(%esi) ! 94: ! 95: L20: ! 96: /* Do the rounding */ ! 97: cmpl $0x80000000,accum_1 ! 98: jc L40 ! 99: ! 100: jne L30 ! 101: ! 102: /* 0x80000000, round up only if previous bit is 1 */ ! 103: testl $1,%ebx ! 104: jz L40 ! 105: ! 106: L30: ! 107: addl $1,%ebx ! 108: adcl $0,%edi ! 109: ! 110: /* An overflow can occur here (rare!) */ ! 111: jc xL_overflow_adjust ! 112: ! 113: L40: ! 114: /* Copy the result to the destination register */ ! 115: movl %ebx,SIGL(%esi) ! 116: movl %edi,SIGH(%esi) ! 117: ! 118: xL_exit: ! 119: popl %ebx ! 120: popl %edi ! 121: popl %esi ! 122: leave ! 123: ret ! 124: ! 125: ! 126: xL_overflow_adjust: ! 127: rcrl $1, %edi ! 128: incl EXP(%esi) ! 129: jmp L40 ! 130: ! 131: #ifdef PARANOID ! 132: xL_bugged: ! 133: pushl EX_INTERNAL|0x205 ! 134: call EXCEPTION ! 135: pop %ebx ! 136: jmp xL_exit ! 137: #endif PARANOID
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.