|
|
coherent
.file "reg_div.S" /*---------------------------------------------------------------------------+ | reg_div.S | | | | Divide one FPU_REG by another and put the result in a destination FPU_REG.| | | | Copyright (C) 1992 W. Metzenthen, 22 Parker St, Ormond, Vic 3163, | | Australia. E-mail [email protected] | | | | Call from C as: | | void reg_div(FPU_REG *a, FPU_REG *b, FPU_REG *dest) | | | +---------------------------------------------------------------------------*/ #include "exception.h" #include "fpu_asm.h" .text .align 2 .globl reg_div reg_div: pushl %ebp movl %esp,%ebp pushl %esi pushl %edi pushl %ebx movl PARAM1,%esi movl PARAM2,%ebx movl PARAM3,%edi movb TAG(%esi),%al orb TAG(%ebx),%al jne xL_div_special // Not (both numbers TW_Valid) // Both arguments are TW_Valid movl EXP(%esi),%edx movl EXP(%ebx),%eax subl %eax,%edx addl EXP_BIAS,%edx movl %edx,EXP(%edi) movb TW_Valid,TAG(%edi) movb SIGN(%esi),%cl cmpb %cl,SIGN(%ebx) / changed to get it through my assembler / setneb (%edi) // Set the sign, requires neg=1, pos=0 setne (%edi) add $SIGL_OFFSET,%ebx add $SIGL_OFFSET,%esi jmp divide_kernel /*-----------------------------------------------------------------------*/ xL_div_special: cmpb TW_NaN,TAG(%esi) // A NaN with anything to give NaN je xL_arg1_NaN cmpb TW_NaN,TAG(%ebx) // A NaN with anything to give NaN jne xL_no_NaN_arg // Operations on NaNs xL_arg1_NaN: xL_arg2_NaN: pushl %edi pushl %ebx pushl %esi call real_2op_NaN jmp xL78 // Invalid operations xL_zero_zero: xL_inf_inf: pushl %esi call arith_invalid jmp xL78 xL_no_NaN_arg: cmpb TW_Infinity,TAG(%esi) jne xL_arg1_not_inf cmpb TW_Infinity,TAG(%ebx) je xL_inf_inf // invalid operation // Note that p16-9 says that infinity/0 returns infinity jmp xL_copy_arg1 // Answer is Inf xL_arg1_not_inf: cmpb TW_Zero,TAG(%ebx) // Priority to div-by-zero error jne xL_arg2_not_zero cmpb TW_Zero,TAG(%esi) je xL_zero_zero // invalid operation // Division by zero error pushl %esi movb SIGN(%esi),%al xorb SIGN(%ebx),%al pushl %eax // lower 8 bits have the sign call divide_by_zero jmp xL78 xL_arg2_not_zero: cmpb TW_Infinity,TAG(%ebx) jne xL_arg2_not_inf jmp xL_return_zero // Answer is zero xL_arg2_not_inf: cmpb TW_Zero,TAG(%esi) jne xL_unknown_tags xL_copy_arg1: mov TAG(%esi),%ax mov %ax,TAG(%edi) movl EXP(%esi),%eax movl %eax,EXP(%edi) movl SIGL(%esi),%eax movl %eax,SIGL(%edi) movl SIGH(%esi),%eax movl %eax,SIGH(%edi) movb SIGN(%esi),%cl cmpb %cl,SIGN(%ebx) jne xL76 movb SIGN_POS,SIGN(%edi) jmp xL78 xL71: movb SIGN(%esi),%cl cmpb %cl,SIGN(%edi) jne xL76 movb SIGN_POS,SIGN(%ebx) jmp xL78 .align 2,0x90 xL76: movb SIGN_NEG,SIGN(%edi) xL78: leal -12(%ebp),%esp popl %ebx popl %edi popl %esi leave ret xL_return_zero: movb TW_Zero,TAG(%edi) jmp xL71 xL_unknown_tags: push EX_INTERNAL | 0x208 call EXCEPTION // Generate a NaN for unknown tags movl CONST_QNaN,%eax movl %eax,(%edi) movl CONST_QNaN+4,%eax movl %eax,SIGL(%edi) movl CONST_QNaN+8,%eax movl %eax,SIGH(%edi) jmp xL78
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.