Added missing math functions and enhanced makefile.

This commit is contained in:
2016-10-24 02:15:12 +01:00
parent ca14ea631a
commit 7708511cba
6 changed files with 235 additions and 13 deletions

View File

@@ -1,6 +1,44 @@
ARCH = $(shell uname -m | sed s,i[3456789]86,ia32,)
# Try to guess host machine
ARCH = $(shell $(CC) -dumpmachine | cut -f1 -d- | sed s,i[3456789]86,ia32,)
OBJS = s_fabs.o k_rem_pio2.o e_rem_pio2.o k_cos.o k_sin.o s_cos.o s_sin.o Aclock.o
# Override amd64
ifeq ($(ARCH),amd64)
override ARCH := x86_64
endif
LIB = /usr/lib
ifeq ($(ARCH),amd64)
override LIB := /usr/lib64
endif
ifeq ($(ARCH),aarch64)
override LIB := /usr/lib64
endif
ifeq ($(ARCH),ia64)
CFLAGS += -mfixed-range=f32-f127
endif
ifeq ($(ARCH),ia32)
CFLAGS += -mno-mmx -mno-sse
endif
ifeq ($(ARCH),x86_64)
CFLAGS += -mno-red-zone -DEFI_FUNCTION_WRAPPER
endif
ifneq ($(ARCH),aarch64)
ifneq ($(ARCH),arm)
export HAVE_EFI_OBJCOPY=y
endif
endif
ifeq ($(ARCH),arm)
CFLAGS += -marm
endif
OBJS = s_fabs.o s_copysign.o s_scalbn.o s_floor.o k_rem_pio2.o e_rem_pio2.o k_cos.o k_sin.o s_cos.o s_sin.o Aclock.o
TARGET = aclock-efi-$(ARCH).efi
EFIINC = /usr/include/efi
@@ -10,14 +48,19 @@ EFILIB = /usr/lib64
EFI_CRT_OBJS = $(EFILIB)/crt0-efi-$(ARCH).o
EFI_LDS = $(EFILIB)/elf_$(ARCH)_efi.lds
CFLAGS = $(EFIINCS) -DGNU_EFI -fno-stack-protector -fpic \
-fshort-wchar -mno-red-zone -Wall
ifeq ($(ARCH),x86_64)
CFLAGS += -DEFI_FUNCTION_WRAPPER
endif
CFLAGS += $(EFIINCS) -DGNU_EFI -O2 -fpic -Wall -fshort-wchar -fno-strict-aliasing \
-fno-merge-constants -ffreestanding -fno-stack-protector
LDFLAGS = -nostdlib -znocombreloc -T $(EFI_LDS) -shared \
-Bsymbolic -L $(EFILIB) -L $(LIB) $(EFI_CRT_OBJS)
LDFLAGS = -nostdlib --no-undefined --build-id=sha1 -T $(EFI_LDS) -shared \
-Bsymbolic -L $(EFILIB) -L $(LIB) $(EFI_CRT_OBJS)
ifneq ($(HAVE_EFI_OBJCOPY),)
FORMAT := --target efi-app-$(ARCH)
else
SUBSYSTEM := 0xa
FORMAT := -O binary
LDFLAGS += --defsym=EFI_SUBSYSTEM=$(SUBSYSTEM)
endif
all: $(TARGET)
@@ -25,6 +68,6 @@ aclock-efi-$(ARCH).so: $(OBJS)
ld $(LDFLAGS) $(OBJS) -o $@ -lefi -lgnuefi
%.efi: %.so
objcopy -j .text -j .sdata -j .data -j .dynamic \
-j .dynsym -j .rel -j .rela -j .reloc \
--target=efi-app-$(ARCH) $^ binaries/$@
objcopy -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel \
-j .rela -j .rel.* -j .rela.* -j .rel* -j .rela* \
-j .reloc $(FORMAT) $^ binaries/$@

View File

@@ -169,7 +169,9 @@ __kernel_rem_pio2(double *x, double *y, int e0, int nx, int prec, const __INT32_
/* compute q[0],q[1],...q[jk] */
for (i=0;i<=jk;i++) {
for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; q[i] = fw;
for(j=0,fw=0.0;j<=jx;j++)
fw += x[j]*f[jx+i-j];
q[i] = fw;
}
jz = jk;

View File

@@ -64,6 +64,16 @@ typedef union
#endif
/* Get two 32 bit ints from a double. */
#define EXTRACT_WORDS(ix0,ix1,d) \
do { \
ieee_double_shape_type ew_u; \
ew_u.value = (d); \
(ix0) = ew_u.parts.msw; \
(ix1) = ew_u.parts.lsw; \
} while (0)
/* Get the more significant 32 bit int from a double. */
#define GET_HIGH_WORD(i,d) \
@@ -130,6 +140,12 @@ double sin(double Arg);
**/
double fabs(double Arg);
/** Compute the largest integer value not greater than Arg.
@param[in] Arg The value to compute the floor of.
@return The largest integer value not greater than Arg, expressed as a floating-point number.
**/
double floor(double);
/* ieee style elementary functions */
extern int __ieee754_rem_pio2 (double,double*);
@@ -138,4 +154,14 @@ extern double __kernel_sin (double, double, int);
extern double __kernel_cos (double, double);
extern int __kernel_rem_pio2 (double*,double*,int,int,int,const int*);
/**@{
C99, Posix, or NetBSD functions that are not part of the C95 specification.
**/
/*
* Functions callable from C, intended to support IEEE arithmetic.
*/
double scalbn(double, int);
double copysign(double, double);
#endif /* _MATH_PRIVATE_H_ */

29
s_copysign.c Normal file
View File

@@ -0,0 +1,29 @@
/* @(#)s_copysign.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
* copysign(double x, double y)
* copysign(x,y) returns a value with the magnitude of x and
* with the sign bit of y.
*/
#include "math_private.h"
double
copysign(double x, double y)
{
__UINT32_TYPE__ hx,hy;
GET_HIGH_WORD(hx,x);
GET_HIGH_WORD(hy,y);
SET_HIGH_WORD(x,(hx&0x7fffffff)|(hy&0x80000000));
return x;
}

68
s_floor.c Normal file
View File

@@ -0,0 +1,68 @@
/* @(#)s_floor.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
* floor(x)
* Return x rounded toward -inf to integral value
* Method:
* Bit twiddling.
* Exception:
* Inexact flag raised if x not equal to floor(x).
*/
#include "math_private.h"
static const double huge = 1.0e300;
double
floor(double x)
{
__INT32_TYPE__ i0,i1,j0;
__UINT32_TYPE__ i,j;
EXTRACT_WORDS(i0,i1,x);
j0 = ((i0>>20)&0x7ff)-0x3ff;
if(j0<20) {
if(j0<0) { /* raise inexact if x != 0 */
if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */
if(i0>=0) {i0=i1=0;}
else if(((i0&0x7fffffff)|i1)!=0)
{ i0=0xbff00000;i1=0;}
}
} else {
i = (0x000fffff)>>j0;
if(((i0&i)|i1)==0) return x; /* x is integral */
if(huge+x>0.0) { /* raise inexact flag */
if(i0<0) i0 += (0x00100000)>>j0;
i0 &= (~i); i1=0;
}
}
} else if (j0>51) {
if(j0==0x400) return x+x; /* inf or NaN */
else return x; /* x is integral */
} else {
i = ((__UINT32_TYPE__)(0xffffffff))>>(j0-20);
if((i1&i)==0) return x; /* x is integral */
if(huge+x>0.0) { /* raise inexact flag */
if(i0<0) {
if(j0==20) i0+=1;
else {
j = i1+(1<<(52-j0));
if((__INT32_TYPE__)j<i1) i0 +=1 ; /* got a carry */
i1=j;
}
}
i1 &= (~i);
}
}
INSERT_WORDS(x,i0,i1);
return x;
}

54
s_scalbn.c Normal file
View File

@@ -0,0 +1,54 @@
/* @(#)s_scalbn.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
* scalbn (double x, int n)
* scalbn(x,n) returns x* 2**n computed by exponent
* manipulation rather than by actually performing an
* exponentiation or a multiplication.
*/
#include "math_private.h"
static const double
two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */
huge = 1.0e+300,
tiny = 1.0e-300;
double
scalbn(double x, int n)
{
__INT32_TYPE__ k,hx,lx;
EXTRACT_WORDS(hx,lx,x);
k = (hx&0x7ff00000)>>20; /* extract exponent */
if (k==0) { /* 0 or subnormal x */
if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */
x *= two54;
GET_HIGH_WORD(hx,x);
k = ((hx&0x7ff00000)>>20) - 54;
if (n< -50000) return tiny*x; /*underflow*/
}
if (k==0x7ff) return x+x; /* NaN or Inf */
k = k+n;
if (k > 0x7fe) return huge*copysign(huge,x); /* overflow */
if (k > 0) /* normal result */
{SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); return x;}
if (k <= -54) {
if (n > 50000) /* in case integer overflow in n+k */
return huge*copysign(huge,x); /*overflow*/
else return tiny*copysign(tiny,x); /*underflow*/
}
k += 54; /* subnormal result */
SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20));
return x*twom54;
}