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