1/* 2 * Written by J.T. Conklin <jtc@netbsd.org>. 3 * Public domain. 4 * 5 * Correct handling of y==-inf <drepper@gnu> 6 */ 7 8#include <machine/asm.h> 9 10RCSID("$NetBSD: e_scalb.S,v 1.4 1995/05/08 23:49:52 jtc Exp $") 11 12#ifdef __ELF__ 13 .section .rodata 14#else 15 .text 16#endif 17 18 .align ALIGNARG(4) 19 ASM_TYPE_DIRECTIVE(zero_nan,@object) 20zero_nan: 21 .double 0.0 22nan: .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f 23minus_zero: 24 .byte 0, 0, 0, 0, 0, 0, 0, 0x80 25 .byte 0, 0, 0, 0, 0, 0, 0xff, 0x7f 26 ASM_SIZE_DIRECTIVE(zero_nan) 27 28 29#ifdef PIC 30#define MO(op) op##@GOTOFF(%ecx) 31#define MOX(op,x,f) op##@GOTOFF(%ecx,x,f) 32#else 33#define MO(op) op 34#define MOX(op,x,f) op(,x,f) 35#endif 36 37 .text 38ENTRY(__ieee754_scalb) 39 fldl 12(%esp) 40 fxam 41 fnstsw 42 fldl 4(%esp) 43 andl $0x4700, %eax 44 cmpl $0x0700, %eax 45 je 1f 46 andl $0x4500, %eax 47 cmpl $0x0100, %eax 48 je 2f 49 fxam 50 fnstsw 51 andl $0x4500, %eax 52 cmpl $0x0100, %eax 53 je 3f 54 fld %st(1) 55 frndint 56 fcomp %st(2) 57 fnstsw 58 sahf 59 jne 4f 60 fscale 61 fstp %st(1) 62 ret 63 64 /* y is -inf */ 651: fxam 66#ifdef PIC 67 call 1f 681: popl %ecx 69 addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx 70#endif 71 fnstsw 72 movl 8(%esp), %edx 73 shrl $5, %eax 74 fstp %st 75 fstp %st 76 andl $0x80000000, %edx 77 andl $8, %eax 78 jnz 4f 79 shrl $27, %edx 80 addl %edx, %eax 81 fldl MOX(zero_nan, %eax, 1) 82 ret 83 84 /* The result is NaN, but we must not raise an exception. 85 So use a variable. */ 862: fstp %st 87 fstp %st 88#ifdef PIC 89 call 1f 901: popl %ecx 91 addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx 92#endif 93 fldl MO(nan) 94 ret 95 96 /* The first parameter is a NaN. Return it. */ 973: fstp %st(1) 98 ret 99 100 /* Return NaN and raise the invalid exception. */ 1014: fstp %st 102 fstp %st 103 fldz 104 fdiv %st 105 ret 106END(__ieee754_scalb) 107