Raymond Toy pushed to branch master at cmucl / cmucl

Commits:

2 changed files:

Changes:

  • src/lisp/Config.x86_common
    ... ... @@ -110,6 +110,7 @@ OPENLIBM_SRCS = \
    110 110
     	$(OPENLIBM_DIR)/e_hypotf.c \
    
    111 111
     	$(OPENLIBM_DIR)/e_log10f.c \
    
    112 112
     	$(OPENLIBM_DIR)/e_logf.c \
    
    113
    +	$(OPENLIBM_DIR)/e_log2f.c \
    
    113 114
     	$(OPENLIBM_DIR)/e_powf.c \
    
    114 115
     	$(OPENLIBM_DIR)/e_rem_pio2f.c \
    
    115 116
     	$(OPENLIBM_DIR)/e_sinhf.c \
    

  • src/lisp/openlibm/e_log2f.c
    1
    +/*
    
    2
    + * ====================================================
    
    3
    + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
    
    4
    + *
    
    5
    + * Developed at SunPro, a Sun Microsystems, Inc. business.
    
    6
    + * Permission to use, copy, modify, and distribute this
    
    7
    + * software is freely granted, provided that this notice
    
    8
    + * is preserved.
    
    9
    + * ====================================================
    
    10
    + */
    
    11
    +
    
    12
    +#include "cdefs-compat.h"
    
    13
    +//__FBSDID("$FreeBSD: src/lib/msun/src/e_log2f.c,v 1.5 2011/10/15 05:23:28 das Exp $");
    
    14
    +
    
    15
    +/*
    
    16
    + * Float version of e_log2.c.  See the latter for most comments.
    
    17
    + */
    
    18
    +
    
    19
    +#include <openlibm_math.h>
    
    20
    +
    
    21
    +#include "math_private.h"
    
    22
    +#include "k_logf.h"
    
    23
    +
    
    24
    +// VBS
    
    25
    +#define float_t float
    
    26
    +
    
    27
    +static const float
    
    28
    +two25      =  3.3554432000e+07, /* 0x4c000000 */
    
    29
    +ivln2hi    =  1.4428710938e+00, /* 0x3fb8b000 */
    
    30
    +ivln2lo    = -1.7605285393e-04; /* 0xb9389ad4 */
    
    31
    +
    
    32
    +static const float zero   =  0.0;
    
    33
    +
    
    34
    +OLM_DLLEXPORT float
    
    35
    +__ieee754_log2f(float x)
    
    36
    +{
    
    37
    +	float f,hfsq,hi,lo,r,y;
    
    38
    +	int32_t i,k,hx;
    
    39
    +
    
    40
    +	GET_FLOAT_WORD(hx,x);
    
    41
    +
    
    42
    +	k=0;
    
    43
    +	if (hx < 0x00800000) {			/* x < 2**-126  */
    
    44
    +	    if ((hx&0x7fffffff)==0)
    
    45
    +		return -two25/zero;		/* log(+-0)=-inf */
    
    46
    +	    if (hx<0) return (x-x)/zero;	/* log(-#) = NaN */
    
    47
    +	    k -= 25; x *= two25; /* subnormal number, scale up x */
    
    48
    +	    GET_FLOAT_WORD(hx,x);
    
    49
    +	}
    
    50
    +	if (hx >= 0x7f800000) return x+x;
    
    51
    +	if (hx == 0x3f800000)
    
    52
    +	    return zero;			/* log(1) = +0 */
    
    53
    +	k += (hx>>23)-127;
    
    54
    +	hx &= 0x007fffff;
    
    55
    +	i = (hx+(0x4afb0d))&0x800000;
    
    56
    +	SET_FLOAT_WORD(x,hx|(i^0x3f800000));	/* normalize x or x/2 */
    
    57
    +	k += (i>>23);
    
    58
    +	y = (float)k;
    
    59
    +	f = x - (float)1.0;
    
    60
    +	hfsq = (float)0.5*f*f;
    
    61
    +	r = k_log1pf(f);
    
    62
    +
    
    63
    +	/*
    
    64
    +	 * We no longer need to avoid falling into the multi-precision
    
    65
    +	 * calculations due to compiler bugs breaking Dekker's theorem.
    
    66
    +	 * Keep avoiding this as an optimization.  See e_log2.c for more
    
    67
    +	 * details (some details are here only because the optimization
    
    68
    +	 * is not yet available in double precision).
    
    69
    +	 *
    
    70
    +	 * Another compiler bug turned up.  With gcc on i386,
    
    71
    +	 * (ivln2lo + ivln2hi) would be evaluated in float precision
    
    72
    +	 * despite runtime evaluations using double precision.  So we
    
    73
    +	 * must cast one of its terms to float_t.  This makes the whole
    
    74
    +	 * expression have type float_t, so return is forced to waste
    
    75
    +	 * time clobbering its extra precision.
    
    76
    +	 */
    
    77
    +	if (sizeof(float_t) > sizeof(float))
    
    78
    +		return (r - hfsq + f) * ((float_t)ivln2lo + ivln2hi) + y;
    
    79
    +
    
    80
    +	hi = f - hfsq;
    
    81
    +	GET_FLOAT_WORD(hx,hi);
    
    82
    +	SET_FLOAT_WORD(hi,hx&0xfffff000);
    
    83
    +	lo = (f - hi) - hfsq + r;
    
    84
    +	return (lo+hi)*ivln2lo + lo*ivln2hi + hi*ivln2hi + y;
    
    85
    +}