diff options
Diffstat (limited to 'libc/i386fp/ldexp.x')
-rw-r--r-- | libc/i386fp/ldexp.x | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/libc/i386fp/ldexp.x b/libc/i386fp/ldexp.x new file mode 100644 index 0000000..bc9dd03 --- /dev/null +++ b/libc/i386fp/ldexp.x @@ -0,0 +1,74 @@ +! bcc 386 floating point routines (version 2) -- _ldexp +! authors: Timothy Murphy (tim@maths.tcd.ie), Bruce Evans + +#include "fplib.h" + + .extern fpoverflow + .extern fpunderflow + +! void ldexp(double value, int exponent); +! returns value * (2 ** exponent) + + .globl _ldexp + .align ALIGNMENT +_ldexp: +push ebx +#undef PC_SIZE +#define PC_SIZE 8 + mov ebx,PC_SIZE+D_HIGH[esp] ! upper dword of x + mov ecx,PC_SIZE+D_SIZE[esp] ! exponent arg + mov eax,ebx ! extract exponent (of x) here + and eax,#D_EXP_MASK +! jz exp_y_0 ! may need check for preposterous exponent arg too + + shr eax,#D_EXP_SHIFT ! shift to low bits just for testing + jz underflow ! denormal? + add eax,ecx ! test-add the exponents + jz underflow ! XXX probably need to fiddle norm bit + cmp eax,#D_EXP_INFINITE ! check if still within range + jae outofbounds ! the unsigned compare catches all overflow cases + ! because the exponent of x is non-negative + + shl ecx,#D_EXP_SHIFT ! shift exponent arg bits into final position ... + add ebx,ecx ! ... safe to add it to exponent of x now + mov eax,PC_SIZE+D_LOW[esp] ! lower dword of x +mov edx,ebx +pop ebx + ret + + + .align ALIGNMENT +outofbounds: + test ecx,ecx ! overflow or underflow? + jns overflow +underflow: + mov edx,ebx ! put sign in usual reg + push edi + push esi + mov edi,eax ! put exponent in usual reg + mov eax,2*GENREG_SIZE+PC_SIZE+D_LOW[esp] + ! put lower dword of x in usual reg + mov esi,ebx ! put upper dword of x in usual reg + and esi,#D_EXP_MASK | D_FRAC_MASK + test esi,#D_EXP_MASK + jz foo + and esi,#D_FRAC_MASK + or esi,#D_NORM_MASK +foo: + neg edi +! inc edi ! XXX ? + call fpunderflow + pop esi + pop edi + mov ebx,edx ! XXX = wrong reg +pop ebx + ret + + .align ALIGNMENT +overflow: + mov edx,ebx ! put sign in usual reg + call fpoverflow + mov eax,ecx ! XXX = wrong reg + mov ebx,edx ! XXX = wrong reg +pop ebx + ret |