2 * Copyright (c) 1992 Helsinki University of Technology
5 * Permission to use, copy, modify and distribute this software and its
6 * documentation is hereby granted, provided that both the copyright
7 * notice and this permission notice appear in all copies of the
8 * software, derivative works or modified versions, and any portions
9 * thereof, and that both notices appear in supporting documentation.
11 * HELSINKI UNIVERSITY OF TECHNOLOGY ALLOWS FREE USE OF THIS SOFTWARE IN
12 * ITS "AS IS" CONDITION. HELSINKI UNIVERSITY OF TECHNOLOGY DISCLAIMS ANY
13 * LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE
14 * USE OF THIS SOFTWARE.
18 * 29-Apr-92 Tero Kivinen (kivinen) at Helsinki University of Technology
21 * $Id: modf.s,v 1.1 1993/09/17 18:43:46 phil Exp $
25 * double modf (value, iptr)
26 * double value, *iptr;
28 * Modf returns the fractional part of "value",
29 * and stores the integer part indirectly through "iptr".
32 #include <machine/asm.h>
36 movl
8(fp
),f0 /* value */
37 movd
12(fp
),r0 /* higher 32 bit of value */
38 lshd
-20,r0 /* extract exponent */
39 andd
0x7ff,r0 /* 11 lower bits */
40 cmpd r0,1023+30 /* compare if it's int part can fit in int */
41 bgt modf_overflow
/* nope else it's ok to truncld it to int*/
42 truncld
f0,r0 /* get integer part */
43 movdl
r0,f2 /* convert back to float */
44 movl
f2,0(16(fp
)) /* move integer part to *iptr */
45 subl
f2,f0 /* return fract. part = value - *iptr */
49 subd
1023+20,r0 /* bias 1023, and upper part of
50 floating point mantissa part */
51 movqd
-1,r2 /* generate mask to get fract. part */
52 cmpd r0,32 /* if value > 2^52 (20+32) then all int part */
54 negd
r0,r0 /* shift right */
56 comd
r2,r2 /* get fractional part complement mask */
57 movd
8(fp
),r1 /* get lower 32 bit of value */
58 andd
r2,r1 /* mask fractional part off leave ip part */
59 movd
r1,0(16(fp
)) /* store ip part to *iptr */
60 movd
12(fp
),4(16(fp
)) /* store other half to *iptr */
61 subl
0(16(fp
)),f0 /* return fract. part = value - *iptr */
65 movl
8(fp
),0(16(fp
)) /* copy value to *iptr */
66 movdl
0,f0 /* return 0 for fract. part */