Work more on waterbox and convert GPGX64 to use the new PERunner. Doesn't work yet.

This commit is contained in:
nattthebear 2017-05-20 17:18:31 -04:00
parent 6053cd6e35
commit a325969963
534 changed files with 319 additions and 74088 deletions

View File

@ -42,7 +42,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
try
{
Elf = new ElfRunner(Path.Combine(comm.CoreFileProvider.DllPath(), "gpgx.elf"), 8 * 1024 * 1024, 36 * 1024 * 1024, 4 * 1024 * 1024);
Elf = new PeRunner(comm.CoreFileProvider.DllPath(), "gpgx.exe", 8 * 1024 * 1024, 36 * 1024 * 1024, 4 * 1024 * 1024);
if (Elf.ShouldMonitor)
Core = BizInvoker.GetInvoker<LibGPGX>(Elf, Elf);
else
@ -152,7 +153,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx64
}
LibGPGX Core;
ElfRunner Elf;
PeRunner Elf;
DiscSystem.Disc CD;
DiscSystem.DiscSectorReader DiscSectorReader;

View File

@ -1,4 +1,5 @@
using BizHawk.Common;
using BizHawk.Common.BizInvoke;
using BizHawk.Emulation.Common;
using PeNet;
using System;
@ -12,7 +13,10 @@ namespace BizHawk.Emulation.Cores.Waterbox
{
public class PeRunner : Swappable, IImportResolver, IBinaryStateable
{
public class PeWrapper : IImportResolver, IBinaryStateable, IDisposable
/// <summary>
/// manages one PE file within the the set of loaded PE files
/// </summary>
private class PeWrapper : IImportResolver, IBinaryStateable, IDisposable
{
public Dictionary<int, IntPtr> ExportsByOrdinal { get; } = new Dictionary<int, IntPtr>();
/// <summary>
@ -37,6 +41,22 @@ namespace BizHawk.Emulation.Cores.Waterbox
public IntPtr EntryPoint { get; private set; }
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
private delegate bool DllEntry(IntPtr instance, int reason, IntPtr reserved);
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
private delegate void ExeEntry();
public bool RunDllEntry()
{
var entryThunk = (DllEntry)Marshal.GetDelegateForFunctionPointer(EntryPoint, typeof(DllEntry));
return entryThunk(Z.US(Start), 1, IntPtr.Zero); // DLL_PROCESS_ATTACH
}
public void RunExeEntry()
{
var entryThunk = (ExeEntry)Marshal.GetDelegateForFunctionPointer(EntryPoint, typeof(ExeEntry));
entryThunk();
}
public PeWrapper(string moduleName, byte[] fileData)
{
ModuleName = moduleName;
@ -89,22 +109,20 @@ namespace BizHawk.Emulation.Cores.Waterbox
LoadOffset = (long)Start - (long)_pe.ImageNtHeaders.OptionalHeader.ImageBase;
Memory = new MemoryBlock(Start, Size);
Memory.Activate();
Memory.Protect(Start, Size, MemoryBlock.Protection.RW);
// copy headers
{
ulong length = _pe.ImageNtHeaders.OptionalHeader.SizeOfHeaders;
Memory.Protect(Start, length, MemoryBlock.Protection.RW);
Marshal.Copy(_fileData, 0, Z.US(Start), (int)length);
}
Marshal.Copy(_fileData, 0, Z.US(Start), (int)_pe.ImageNtHeaders.OptionalHeader.SizeOfHeaders);
// copy sections
foreach (var s in _pe.ImageSectionHeaders)
{
ulong start = Start + s.VirtualAddress;
ulong length = s.VirtualSize;
ulong datalength = Math.Min(s.VirtualSize, s.SizeOfRawData);
Marshal.Copy(_fileData, (int)s.PointerToRawData, Z.US(start), (int)s.SizeOfRawData);
WaterboxUtils.ZeroMemory(Z.US(start + s.SizeOfRawData), (long)(length - s.SizeOfRawData));
Marshal.Copy(_fileData, (int)s.PointerToRawData, Z.US(start), (int)datalength);
WaterboxUtils.ZeroMemory(Z.US(start + datalength), (long)(length - datalength));
}
// apply relocations
@ -161,7 +179,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
module = new Dictionary<string, IntPtr>();
ImportsByModule.Add(import.DLL, module);
}
module.Add(import.Name, Z.US(import.Thunk));
module.Add(import.Name, Z.US(Start + import.Thunk));
}
}
@ -249,6 +267,186 @@ namespace BizHawk.Emulation.Cores.Waterbox
}
}
/// <summary>
/// serves as a standin for libpsxscl.so
/// </summary>
private class Psx
{
private readonly PeRunner _parent;
private readonly List<Delegate> _traps = new List<Delegate>();
public Psx(PeRunner parent)
{
_parent = parent;
}
[StructLayout(LayoutKind.Sequential)]
public struct PsxContext
{
public int Size;
public int Options;
public IntPtr SyscallVtable;
public IntPtr LdsoVtable;
public IntPtr PsxVtable;
public uint SysIdx;
public uint LibcIdx;
public IntPtr PthreadSurrogate;
public IntPtr PthreadCreate;
public IntPtr DoGlobalCtors;
public IntPtr DoGlobalDtors;
}
private IntPtr CreateVtable(string moduleName, ICollection<string> entries)
{
var imports = _parent._exports[moduleName];
var ret = Z.US(_parent._sealedheap.Allocate((ulong)(entries.Count * IntPtr.Size), 16));
var pointers = entries.Select(e =>
{
var ptr = imports.Resolve(e);
if (ptr == IntPtr.Zero)
{
var s = string.Format("Trapped on unimplemented function {0}:{1}", moduleName, e);
Action del = () => { throw new InvalidOperationException(e); };
_traps.Add(del);
ptr = Marshal.GetFunctionPointerForDelegate(del);
}
return ptr;
}).ToArray();
Marshal.Copy(pointers, 0, ret, pointers.Length);
return ret;
}
[BizExport(CallingConvention.Cdecl, EntryPoint = "__psx_init")]
public int PsxInit(ref int argc, ref IntPtr argv, ref IntPtr envp, [In, Out]ref PsxContext context)
{
{
// argc = 1, argv = ["foobar, NULL], envp = [NULL]
argc = 1;
var argArea = _parent._sealedheap.Allocate(32, 16);
argv = Z.US(argArea);
envp = Z.US(argArea + (uint)IntPtr.Size * 2);
Marshal.WriteIntPtr(Z.US(argArea), Z.US(argArea + 24));
Marshal.WriteInt64(Z.US(argArea + 24), 0x7261626f6f66);
}
context.SyscallVtable = CreateVtable("__syscalls", Enumerable.Range(0, 340).Select(i => "n" + i).ToList());
context.LdsoVtable = CreateVtable("__syscalls", new[] // ldso
{
"dladdr", "dlinfo", "dlsym", "dlopen", "dlclose", "dlerror", "reset_tls"
});
context.PsxVtable = CreateVtable("__syscalls", new[] // psx
{
"start_main", "convert_thread", "unmapself", "log_output"
});
var extraTable = CreateVtable("__syscalls", new[]
{
"pthread_surrogate", "pthread_create", "do_global_ctors", "do_global_dtors"
});
{
var tmp = new IntPtr[4];
Marshal.Copy(extraTable, tmp, 0, 4);
context.PthreadSurrogate = tmp[0];
context.PthreadCreate = tmp[1];
context.DoGlobalCtors = tmp[2];
context.DoGlobalDtors = tmp[3];
}
return 1;
}
}
/// <summary>
/// special emulator-functions
/// </summary>
private class Emu
{
private readonly PeRunner _parent;
public Emu(PeRunner parent)
{
_parent = parent;
}
public class EndOfMainException: Exception
{
}
[BizExport(CallingConvention.Cdecl, EntryPoint = "alloc_sealed")]
public IntPtr AllocSealed(UIntPtr size)
{
return Z.US(_parent._sealedheap.Allocate((ulong)size, 16));
}
[BizExport(CallingConvention.Cdecl, EntryPoint = "alloc_invisible")]
public IntPtr AllocInvisible(UIntPtr size)
{
return Z.US(_parent._invisibleheap.Allocate((ulong)size, 16));
}
[BizExport(CallingConvention.Cdecl, EntryPoint = "_debug_puts")]
public void DebugPuts(IntPtr s)
{
Console.WriteLine("_debug_puts:" + Marshal.PtrToStringAnsi(s));
}
[BizExport(CallingConvention.Cdecl, EntryPoint = "_leave_main")]
public void LeaveMain()
{
throw new EndOfMainException();
}
}
/// <summary>
/// syscall emulation layer, as well as a bit of other stuff
/// </summary>
private class Syscalls
{
private readonly PeRunner _parent;
public Syscalls(PeRunner parent)
{
_parent = parent;
}
[BizExport(CallingConvention.Cdecl, EntryPoint = "log_output")]
public void DebugPuts(IntPtr s)
{
Console.WriteLine("_psx_log_output:" + Marshal.PtrToStringAnsi(s));
}
[BizExport(CallingConvention.Cdecl, EntryPoint = "n12")]
public UIntPtr Brk(UIntPtr _p)
{
// does MUSL use this?
var heap = _parent._heap;
var start = heap.Memory.Start;
var end = start + heap.Used;
var max = heap.Memory.End;
var p = (ulong)_p;
if (p < start || p > max)
{
// failure: return current break
return Z.UU(end);
}
else if (p > end)
{
// increase size of heap
heap.Allocate(p - end, 1);
return Z.UU(p);
}
else if (p < end)
{
throw new InvalidOperationException("We don't support shrinking heaps");
}
else
{
// no change
return Z.UU(end);
}
}
}
// usual starting address for the executable
private static readonly ulong CanonicalStart = 0x0000036f00000000;
@ -282,26 +480,52 @@ namespace BizHawk.Emulation.Cores.Waterbox
/// </summary>
private Heap _invisibleheap;
/// <summary>
/// all loaded PE files
/// </summary>
private readonly List<PeWrapper> _modules = new List<PeWrapper>();
/// <summary>
/// anything at all that needs to be disposed on finish
/// </summary>
private readonly List<IDisposable> _disposeList = new List<IDisposable>();
/// <summary>
/// anything at all that needs its state saved and loaded
/// </summary>
private readonly List<IBinaryStateable> _savestateComponents = new List<IBinaryStateable>();
/// <summary>
/// all of the exports, including real PeWrapper ones and fake ones
/// </summary>
private readonly Dictionary<string, IImportResolver> _exports = new Dictionary<string, IImportResolver>();
private Psx _psx;
private Emu _emu;
private Syscalls _syscalls;
public PeRunner(string directory, string filename, ulong heapsize, ulong sealedheapsize, ulong invisibleheapsize)
{
Initialize(_nextStart);
Enter();
try
{
// load any predefined exports
_psx = new Psx(this);
_exports.Add("libpsxscl.so", BizExvoker.GetExvoker(_psx));
_emu = new Emu(this);
_exports.Add("libemuhost.so", BizExvoker.GetExvoker(_emu));
_syscalls = new Syscalls(this);
_exports.Add("__syscalls", BizExvoker.GetExvoker(_syscalls));
// load and connect all modules, starting with the executable
var todoModules = new Queue<string>();
todoModules.Enqueue(filename);
var loadedModules = new Dictionary<string, IImportResolver>();
while (todoModules.Count > 0)
{
var moduleName = todoModules.Dequeue();
if (!loadedModules.ContainsKey(moduleName))
if (!_exports.ContainsKey(moduleName))
{
var module = new PeWrapper(moduleName, File.ReadAllBytes(Path.Combine(directory, moduleName)));
module.Mount(_nextStart);
@ -310,7 +534,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
_savestateComponents.Add(module);
_disposeList.Add(module);
loadedModules.Add(moduleName, module);
_exports.Add(moduleName, module);
_modules.Add(module);
foreach (var name in module.ImportsByModule.Keys)
{
@ -323,7 +547,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
{
foreach (var name in module.ImportsByModule.Keys)
{
module.ConnectImports(name, loadedModules[name]);
module.ConnectImports(name, _exports[name]);
}
}
foreach (var module in _modules)
@ -352,6 +576,19 @@ namespace BizHawk.Emulation.Cores.Waterbox
AddMemoryBlock(_invisibleheap.Memory);
_savestateComponents.Add(_invisibleheap);
_disposeList.Add(_invisibleheap);
try
{
_modules[0].RunExeEntry();
throw new InvalidOperationException("main() returned!");
}
catch (Emu.EndOfMainException)
{ }
foreach (var m in _modules.Skip(1))
{
if (!m.RunDllEntry())
throw new InvalidOperationException("DllMain() returned false");
}
}
catch
{
@ -370,6 +607,14 @@ namespace BizHawk.Emulation.Cores.Waterbox
return _modules[0].Resolve(entryPoint);
}
public void Seal()
{
using (this.EnterExit())
{
_sealedheap.Seal();
}
}
public void SaveStateBinary(BinaryWriter bw)
{
using (this.EnterExit())
@ -406,6 +651,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
_disposeList.Clear();
PurgeMemoryBlocks();
_modules.Clear();
_exports.Clear();
_heap = null;
_sealedheap = null;
_invisibleheap = null;

Binary file not shown.

32
waterbox/emulibc/Makefile Normal file
View File

@ -0,0 +1,32 @@
CC = x86_64-nt64-midipix-gcc
CCFLAGS:= -Wall -O2# -mcmodel=large
TARGET = libemuhost.so
LDFLAGS = -shared
ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
SRCS:=$(shell find $(ROOT_DIR) -type f -name '*.c')
OBJ_DIR:=$(ROOT_DIR)/obj
_OBJS:=$(SRCS:.c=.o)
OBJS:=$(patsubst $(ROOT_DIR)%,$(OBJ_DIR)%,$(_OBJS))
$(OBJ_DIR)/%.o: %.c
@mkdir -p $(@D)
@$(CC) -c -o $@ $< $(CCFLAGS)
all: $(TARGET)
.PHONY: clean all
$(TARGET) : $(OBJS)
@$(CC) -o $@ $(LDFLAGS) $(CCFLAGS) $(OBJS)
clean:
rm -rf $(OBJ_DIR)
rm -f $(TARGET)
#install:
# $(CP) $(TARGET) $(DEST_$(ARCH))

View File

@ -0,0 +1,7 @@
#include "emulibc.h"
// this is just used to build a dummy .so file that isn't used
void *alloc_sealed(size_t size) { return NULL; }
void *alloc_invisible(size_t size) { return NULL; }
void _debug_puts(const char *s) { }
void _leave_main(void) { }

View File

@ -4,9 +4,9 @@
#include <stddef.h>
// mark an entry point or callback pointer
#define ECL_ENTRY __attribute__((ms_abi))
#define ECL_ENTRY
// mark a visible symbol
#define ECL_EXPORT __attribute__((visibility("default")))
#define ECL_EXPORT
// allocate memory from the "sealed" pool. this memory can never be freed,
// and can only be allocated or written to during the init phase. after that, the host
@ -22,4 +22,8 @@ void *alloc_invisible(size_t size);
// send a debug string somewhere, bypassing stdio
void _debug_puts(const char *);
// this might be used for something
void _leave_main(void);
#endif

View File

@ -1,32 +1,16 @@
CC = gcc
ARCH = 64
#MACHINE = $(shell $(CC) -dumpmachine)
#ifneq (,$(findstring i686,$(MACHINE)))
# ARCH = 32
#else ifneq (,$(findstring x86_64,$(MACHINE)))
# ARCH = 64
#else
# $(error Unknown arch)
#endif
CC = x86_64-nt64-midipix-gcc
CCFLAGS:=-Icore -Iutil -Icore/m68k -Icore/z80 -Icore/input_hw \
-Icore/cart_hw -Icore/cart_hw/svp -Icore/sound -Icore/ntsc -Icore/cd_hw \
-I../emulibc \
-Wall -Werror=pointer-to-int-cast -Werror=int-to-pointer-cast -Werror=implicit-function-declaration \
-std=c99 -fomit-frame-pointer -fvisibility=hidden \
-DLSB_FIRST -DUSE_32BPP_RENDERING -DINLINE=static\ __inline__ \
-ffreestanding -nostdinc -nostdlib \
-I../libc/includes -I../libc/internals \
-mcmodel=large -O2
-O2#-mcmodel=large
TARGET = gpgx.elf
TARGET = gpgx.exe
LDFLAGS_32 =
LDFLAGS_64 = -static
LDFLAGS = $(LDFLAGS_$(ARCH)) $(CCFLAGS)
#DEST_32 = ../../../../../output/dll
#DEST_64 = ../../../../../output64/dll
LDFLAGS = -Wl,--dynamicbase,--export-all-symbols
ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
SRCS:=$(shell find $(ROOT_DIR) -type f -name '*.c')
@ -43,8 +27,8 @@ all: $(TARGET)
.PHONY: clean all
$(TARGET) : $(OBJS) lscript
@$(CC) -o $@ $(LDFLAGS) -T lscript $(CCFLAGS) $(OBJS) ../libc/emulibc.a
$(TARGET) : $(OBJS)
@$(CC) -o $@ $(LDFLAGS) $(CCFLAGS) $(OBJS) ../emulibc/libemuhost.so
clean:
rm -rf $(OBJ_DIR)

View File

@ -713,3 +713,8 @@ GPGX_EX int gpgx_getregs(gpregister_t *regs)
return ret;
}
int main(void)
{
_leave_main();
}

View File

@ -1,228 +0,0 @@
/* dumped with -Wl,-verbose; base address moved
/* Script for -z combreloc: combine and sort reloc sections */
/* Copyright (C) 2014 Free Software Foundation, Inc.
Copying and distribution of this script, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. */
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64",
"elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(_start)
SEARCH_DIR("=/usr/x86_64-linux-gnu/lib64"); SEARCH_DIR("=/usr/local/lib/x86_64-linux-gnu"); SEARCH_DIR("=/usr/local/lib64"); SEARCH_DIR("=/lib/x86_64-linux-gnu"); SEARCH_DIR("=/lib64"); SEARCH_DIR("=/usr/lib/x86_64-linux-gnu"); SEARCH_DIR("=/usr/lib64"); SEARCH_DIR("=/usr/x86_64-linux-gnu/lib"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib");
SECTIONS
{
/* Read-only sections, merged into text segment: */
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x0000036f00000000)); . = SEGMENT_START("text-segment", 0x0000036f00000000) + SIZEOF_HEADERS;
.interp : { *(.interp) }
.note.gnu.build-id : { *(.note.gnu.build-id) }
.hash : { *(.hash) }
.gnu.hash : { *(.gnu.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rela.dyn :
{
*(.rela.init)
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
*(.rela.fini)
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
*(.rela.ctors)
*(.rela.dtors)
*(.rela.got)
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
*(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*)
*(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*)
*(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*)
*(.rela.ifunc)
}
.rela.plt :
{
*(.rela.plt)
PROVIDE_HIDDEN (__rela_iplt_start = .);
*(.rela.iplt)
PROVIDE_HIDDEN (__rela_iplt_end = .);
}
.init :
{
KEEP (*(SORT_NONE(.init)))
}
.plt : { *(.plt) *(.iplt) }
.plt.bnd : { *(.plt.bnd) }
.text :
{
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
*(.text.hot .text.hot.*)
*(.text .stub .text.* .gnu.linkonce.t.*)
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
}
.fini :
{
KEEP (*(SORT_NONE(.fini)))
}
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
.rodata1 : { *(.rodata1) }
.eh_frame_hdr : { *(.eh_frame_hdr) }
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table
.gcc_except_table.*) }
/* These sections are generated by the Sun/Oracle C++ compiler. */
.exception_ranges : ONLY_IF_RO { *(.exception_ranges
.exception_ranges*) }
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
. = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
/* Exception handling */
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
.exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) }
/* Thread Local Storage sections */
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
}
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
}
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
}
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
}
.jcr : { KEEP (*(.jcr)) }
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
.dynamic : { *(.dynamic) }
.got : { *(.got) *(.igot) }
. = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 24 ? 24 : 0, .);
.got.plt : { *(.got.plt) *(.igot.plt) }
.data :
{
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
}
.data1 : { *(.data1) }
_edata = .; PROVIDE (edata = .);
. = .;
__bss_start = .;
.bss :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections.
FIXME: Why do we need it? When there is no .bss section, we don't
pad the .data section. */
. = ALIGN(. != 0 ? 64 / 8 : 1);
}
.lbss :
{
*(.dynlbss)
*(.lbss .lbss.* .gnu.linkonce.lb.*)
*(LARGE_COMMON)
}
. = ALIGN(64 / 8);
. = SEGMENT_START("ldata-segment", .);
.lrodata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
{
*(.lrodata .lrodata.* .gnu.linkonce.lr.*)
}
.ldata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
{
*(.ldata .ldata.* .gnu.linkonce.l.*)
. = ALIGN(. != 0 ? 64 / 8 : 1);
}
. = ALIGN(64 / 8);
_end = .; PROVIDE (end = .);
. = DATA_SEGMENT_END (.);
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* DWARF 3 */
.debug_pubtypes 0 : { *(.debug_pubtypes) }
.debug_ranges 0 : { *(.debug_ranges) }
/* DWARF Extension. */
.debug_macro 0 : { *(.debug_macro) }
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
}

View File

@ -1,121 +0,0 @@
Creative Commons Legal Code
CC0 1.0 Universal
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
HEREUNDER.
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator
and subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for
the purpose of contributing to a commons of creative, cultural and
scientific works ("Commons") that the public can reliably and without fear
of later claims of infringement build upon, modify, incorporate in other
works, reuse and redistribute as freely as possible in any form whatsoever
and for any purposes, including without limitation commercial purposes.
These owners may contribute to the Commons to promote the ideal of a free
culture and the further production of creative, cultural and scientific
works, or to gain reputation or greater distribution for their Work in
part through the use and efforts of others.
For these and/or other purposes and motivations, and without any
expectation of additional consideration or compensation, the person
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
is an owner of Copyright and Related Rights in the Work, voluntarily
elects to apply CC0 to the Work and publicly distribute the Work under its
terms, with knowledge of his or her Copyright and Related Rights in the
Work and the meaning and intended legal effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not
limited to, the following:
i. the right to reproduce, adapt, distribute, perform, display,
communicate, and translate a Work;
ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or
likeness depicted in a Work;
iv. rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;
v. rights protecting the extraction, dissemination, use and reuse of data
in a Work;
vi. database rights (such as those arising under Directive 96/9/EC of the
European Parliament and of the Council of 11 March 1996 on the legal
protection of databases, and under any national implementation
thereof, including any amended or successor version of such
directive); and
vii. other similar, equivalent or corresponding rights throughout the
world based on applicable law or treaty, and any national
implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention
of, applicable law, Affirmer hereby overtly, fully, permanently,
irrevocably and unconditionally waives, abandons, and surrenders all of
Affirmer's Copyright and Related Rights and associated claims and causes
of action, whether now known or unknown (including existing as well as
future claims and causes of action), in the Work (i) in all territories
worldwide, (ii) for the maximum duration provided by applicable law or
treaty (including future time extensions), (iii) in any current or future
medium and for any number of copies, and (iv) for any purpose whatsoever,
including without limitation commercial, advertising or promotional
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
member of the public at large and to the detriment of Affirmer's heirs and
successors, fully intending that such Waiver shall not be subject to
revocation, rescission, cancellation, termination, or any other legal or
equitable action to disrupt the quiet enjoyment of the Work by the public
as contemplated by Affirmer's express Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason
be judged legally invalid or ineffective under applicable law, then the
Waiver shall be preserved to the maximum extent permitted taking into
account Affirmer's express Statement of Purpose. In addition, to the
extent the Waiver is so judged Affirmer hereby grants to each affected
person a royalty-free, non transferable, non sublicensable, non exclusive,
irrevocable and unconditional license to exercise Affirmer's Copyright and
Related Rights in the Work (i) in all territories worldwide, (ii) for the
maximum duration provided by applicable law or treaty (including future
time extensions), (iii) in any current or future medium and for any number
of copies, and (iv) for any purpose whatsoever, including without
limitation commercial, advertising or promotional purposes (the
"License"). The License shall be deemed effective as of the date CC0 was
applied by Affirmer to the Work. Should any part of the License for any
reason be judged legally invalid or ineffective under applicable law, such
partial invalidity or ineffectiveness shall not invalidate the remainder
of the License, and in such case Affirmer hereby affirms that he or she
will not (i) exercise any of his or her remaining Copyright and Related
Rights in the Work or (ii) assert any associated claims and causes of
action with respect to the Work, in either case contrary to Affirmer's
express Statement of Purpose.
4. Limitations and Disclaimers.
a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or
warranties of any kind concerning the Work, express, implied,
statutory or otherwise, including without limitation warranties of
title, merchantability, fitness for a particular purpose, non
infringement, or the absence of latent or other defects, accuracy, or
the present or absence of errors, whether or not discoverable, all to
the greatest extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other persons
that may apply to the Work or any use thereof, including without
limitation any person's Copyright and Related Rights in the Work.
Further, Affirmer disclaims responsibility for obtaining any necessary
consents, permissions or other rights required for any use of the
Work.
d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to
this CC0 or use of the Work.

View File

@ -1,41 +0,0 @@
CC:=gcc
TARGET:=emulibc.a
CFLAGS:=-Wall -Wextra -pedantic -Wno-unused-parameter -Wshadow \
-Wpointer-arith -Wwrite-strings -Wmissing-declarations \
-Wno-long-long -Wuninitialized -Wno-deprecated-declarations \
-Wredundant-decls -Winline -Wcast-align -Wno-format \
-Wnested-externs -Wstrict-prototypes -Wmissing-prototypes \
-Wno-unused-but-set-variable -Wno-parentheses \
-Iinternals -Iincludes -Icompileincludes \
-ffreestanding -std=c11 -D_PDCLIB_BUILD -nostdinc -nostdlib \
-mcmodel=large -O2
ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
SRCS:=$(shell find $(ROOT_DIR) -type f -name '*.c' -o -name '*.s')
OBJ_DIR:=$(ROOT_DIR)/obj
_OBJS:=$(SRCS:.c=.o)
_OBJS:=$(_OBJS:.s=.o)
OBJS:=$(patsubst $(ROOT_DIR)%,$(OBJ_DIR)%,$(_OBJS))
$(OBJ_DIR)/%.o: %.c
@mkdir -p $(@D)
@$(CC) -c -o $@ $< $(CFLAGS)
$(OBJ_DIR)/%.o: %.s
@mkdir -p $(@D)
@$(CC) -c -o $@ $< $(CFLAGS)
$(TARGET): $(OBJS)
@ar rcs $@ $^
all: $(TARGET)
.PHONY: clean all
clean:
rm -rf $(OBJ_DIR)
rm -f $(TARGET)
print-% : ; @echo $* = $($*)

View File

@ -1,110 +0,0 @@
Credits
=======
The vast majority of PDCLib is original work by me. I felt it was the only way
to ensure that the code was indeed free of third-party rights, and thus free to
be released into the Public Domain.
Another issue was that of coding style, quality and stability of the code, and
the urge to really understand every miniscule part of the code as to be able to
maintain it well once v1.0 has been released.
That is not to say there are no credits to be given. To the contrary:
Paul Edwards (author of the PDPCLIB), for inspirational code fragments, thanks.
P.J. Plauger (author of "The Standard C Library"), for a book without which I
would not have been able to create PDCLib at this quality, thanks.
Paul Bourke (author of mathlib), for allowing me access to a complete math
library under public domain terms so I could use it as a reference, thanks.
Peter ("Candy") Bindels (netizen of osdev.org), who located a copy of Cody
& Waite's "Software Manual for the Elementary Functions" for me and saved me
serious cash in the process, thanks.
Michael Moody, who contributed the generic implementation for <stdarg.h> to
the Public Domain which can now be found in <_PDCLIB_config.h>, thanks.
Rod Pemberton, for pointing out several flaws in early versions of PDCLib and
giving other valuable hints, thanks.
Brian Damgaard, for a very friendly exchange over the fine details of the
Quicksort algorithm and its implementation in PDCLib, thanks.
Rink Springer, for very precise bug reports including patches, and a heads-up
on the capabilities of PDCLib when I most needed it, thanks.
Everyone involved in the first, "public" attempt at PDCLib, for bearing with me
when I restarted from scratch, thanks.
Everyone bearing with me during the "stdio block", a period of many years in
which PDCLib received not a single update because I was stuck and could not
find the time and energy to work it out.
Lennart Frid<69>n and Sammy Nordstr<74>m, who have been great pals even after I sunk
some other project that had eaten countless hours of work between the three of
us, thanks.
My wife, daughter, and son for sharing husband and daddy with this strange
machine, thanks.
Style
=====
I followed a set of guidelines in creating PDCLib. If you find some piece that
does not adhere to them, that's a bug worth reporting. I mean it. I am a bit
obsessive when it comes to coding style. ;-)
- All the stuff that is not part of the standard specification is "hidden" in
the _PDCLIB_* namespace - functions, variables, macros, files, directories.
This is to make it easier to distinguish between what the standard dictates
and what I added to make PDCLib work.
- Any internal includes (i.e. those not specified by the standard) have their
header guards defined in the *including* file, for a tiny bit of compile-time
performance.
- I always try to minimize the use of local variables. Wherever possible I used
parameters passed by-value directly, and deferred declaration of locals to the
innermost block of statements, in hopes that it might reduce memory footprint
when the library is compiled with a compiler that is not that great at
optimization.
- Every function, every static data item that could possibly be shared, got its
own implementation file. This means the library itself is probably larger than
strictly necessary, and might take a couple of clock cycles longer to link,
but it reduces size of object files and executables.
- Where possible, I tried to share functionality between similar functions (as
can be seen in the atoi() and strtol() function families). This means one or
two additional function calls, but again reduces memory footprint and eases
maintenance of the library.
- Function arguments are named exactly as in the standard document.
- The standard is taken quite literally in places. For example, the default
implementations of memcpy() really copies char-wise. This runs contrary to
earlier claims of performance, but is consistent with the *letter* of the
standard, and you will probably use your compiler builtins (through a platform
overlay) anyhow.
- Every file has an Id tag, so that it is on file for *every* code file.
- PDCLib code has no bias towards POSIX; indeed the absence of POSIX tidbits is
one of its hallmarks. However, PDCLib also has no bias *against* POSIX, and
when one platform abstraction is as good as another, I chose the POSIX one for
sheer familiarity. (This is mainly referring to naming and parameter lists of
OS "glue" functions.)
- Identifiers are tersely named, but not cryptically abbreviated, and should be
intuitive enough to allow easy understanding of PDCLib inner workings.
- I disagree with the notion that good code needs no comments. Code tells you
*how*, but not the *why*, and you have to figure out the *what* yourself. So
I added comments to every nontrivial piece of code explaining my motives and
hopefully keeping overly ambitious editors from repeating my mistakes. The
header files especially should be self-documenting to the point of being a
suitable replacement for any library reference book you might be using.

View File

@ -1,46 +0,0 @@
Unicode Data Files include all data files under the directories
http://www.unicode.org/Public/, http://www.unicode.org/reports/, and
http://www.unicode.org/cldr/data/. Unicode Data Files do not include PDF online
code charts under the directory http://www.unicode.org/Public/. Software
includes any source code published in the Unicode Standard or under the
directories http://www.unicode.org/Public/, http://www.unicode.org/reports/, and
http://www.unicode.org/cldr/data/.
NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING,
INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S DATA FILES ("DATA FILES"),
AND/OR SOFTWARE ("SOFTWARE"), YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND
BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO
NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWAR.
COPYRIGHT AND PERMISSION NOTICE
Copyright © 1991-2013 Unicode, Inc. All rights reserved. Distributed under the
Terms of Use in http://www.unicode.org/copyright.html.
Permission is hereby granted, free of charge, to any person obtaining a copy of
the Unicode data files and any associated documentation (the "Data Files") or
Unicode software and any associated documentation (the "Software") to deal in
the Data Files or Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, and/or sell copies of
the Data Files or Software, and to permit persons to whom the Data Files or
Software are furnished to do so, provided that (a) the above copyright notice(s)
and this permission notice appear with all copies of the Data Files or Software,
(b) both the above copyright notice(s) and this permission notice appear in
associated documentation, and (c) there is clear notice in each modified Data
File or in the Software as well as in the documentation associated with the Data
File(s) or Software that the data or software has been modified.
THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD
PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR
SOFTWARE.
Except as contained in this notice, the name of a copyright holder shall not be
used in advertising or otherwise to promote the sale, use or other dealings in
these Data Files or Software without prior written authorization of the
copyright holder.

View File

@ -1,188 +0,0 @@
/* origin: FreeBSD /usr/src/lib/msun/src/math_private.h */
/*
* ====================================================
* 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.
* ====================================================
*/
#ifndef _LIBM_H
#define _LIBM_H
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <stdint.h>
#include <float.h>
#include <math.h>
#include <complex.h>
#include <endian.h>
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN
union ldshape {
long double f;
struct {
uint64_t m;
uint16_t se;
} i;
};
#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN
union ldshape {
long double f;
struct {
uint64_t lo;
uint32_t mid;
uint16_t top;
uint16_t se;
} i;
struct {
uint64_t lo;
uint64_t hi;
} i2;
};
#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __BIG_ENDIAN
union ldshape {
long double f;
struct {
uint16_t se;
uint16_t top;
uint32_t mid;
uint64_t lo;
} i;
struct {
uint64_t hi;
uint64_t lo;
} i2;
};
#else
#error Unsupported long double representation
#endif
#define FORCE_EVAL(x) do { \
if (sizeof(x) == sizeof(float)) { \
volatile float __x; \
__x = (x); \
} else if (sizeof(x) == sizeof(double)) { \
volatile double __x; \
__x = (x); \
} else { \
volatile long double __x; \
__x = (x); \
} \
} while(0)
/* Get two 32 bit ints from a double. */
#define EXTRACT_WORDS(hi,lo,d) \
do { \
union {double f; uint64_t i;} __u; \
__u.f = (d); \
(hi) = __u.i >> 32; \
(lo) = (uint32_t)__u.i; \
} while (0)
/* Get the more significant 32 bit int from a double. */
#define GET_HIGH_WORD(hi,d) \
do { \
union {double f; uint64_t i;} __u; \
__u.f = (d); \
(hi) = __u.i >> 32; \
} while (0)
/* Get the less significant 32 bit int from a double. */
#define GET_LOW_WORD(lo,d) \
do { \
union {double f; uint64_t i;} __u; \
__u.f = (d); \
(lo) = (uint32_t)__u.i; \
} while (0)
/* Set a double from two 32 bit ints. */
#define INSERT_WORDS(d,hi,lo) \
do { \
union {double f; uint64_t i;} __u; \
__u.i = ((uint64_t)(hi)<<32) | (uint32_t)(lo); \
(d) = __u.f; \
} while (0)
/* Set the more significant 32 bits of a double from an int. */
#define SET_HIGH_WORD(d,hi) \
do { \
union {double f; uint64_t i;} __u; \
__u.f = (d); \
__u.i &= 0xffffffff; \
__u.i |= (uint64_t)(hi) << 32; \
(d) = __u.f; \
} while (0)
/* Set the less significant 32 bits of a double from an int. */
#define SET_LOW_WORD(d,lo) \
do { \
union {double f; uint64_t i;} __u; \
__u.f = (d); \
__u.i &= 0xffffffff00000000ull; \
__u.i |= (uint32_t)(lo); \
(d) = __u.f; \
} while (0)
/* Get a 32 bit int from a float. */
#define GET_FLOAT_WORD(w,d) \
do { \
union {float f; uint32_t i;} __u; \
__u.f = (d); \
(w) = __u.i; \
} while (0)
/* Set a float from a 32 bit int. */
#define SET_FLOAT_WORD(d,w) \
do { \
union {float f; uint32_t i;} __u; \
__u.i = (w); \
(d) = __u.f; \
} while (0)
#undef __CMPLX
#undef CMPLX
#undef CMPLXF
#undef CMPLXL
#define __CMPLX(x, y, t) \
((union { _Complex t __z; t __xy[2]; }){.__xy = {(x),(y)}}.__z)
#define CMPLX(x, y) __CMPLX(x, y, double)
#define CMPLXF(x, y) __CMPLX(x, y, float)
#define CMPLXL(x, y) __CMPLX(x, y, long double)
/* fdlibm kernel functions */
int __rem_pio2_large(double*,double*,int,int,int);
int __rem_pio2(double,double*);
double __sin(double,double,int);
double __cos(double,double);
double __tan(double,double,int);
double __expo2(double);
double complex __ldexp_cexp(double complex,int);
int __rem_pio2f(float,double*);
float __sindf(double);
float __cosdf(double);
float __tandf(double,int);
float __expo2f(float);
float complex __ldexp_cexpf(float complex,int);
int __rem_pio2l(long double, long double *);
long double __sinl(long double, long double, int);
long double __cosl(long double, long double);
long double __tanl(long double, long double, int);
/* polynomial evaluation */
long double __polevll(long double, const long double *, int);
long double __p1evll(long double, const long double *, int);
#endif

View File

@ -1 +0,0 @@
includes for compiling the library only

View File

@ -1,11 +0,0 @@
This directory holds various "internals" of PDCLib:
- definitions of helper functions not specified by the standard (hidden in the
_PDCLIB_* namespace);
- definitions of data objects, both internal (like digits.c) and specified by
the standard (errno.c);
- test drivers for functionality that does not have its own implementation
file to put the test driver in.

View File

@ -1,139 +0,0 @@
/* ASCII codec
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <stdbool.h>
#ifndef REGTEST
#include <uchar.h>
#include "_PDCLIB_encoding.h"
static bool ascii_mbsinit( const mbstate_t *ps )
{ return 1; }
static bool asciitoc32(
char32_t *restrict *restrict p_outbuf,
size_t *restrict p_outsz,
const char *restrict *restrict p_inbuf,
size_t *restrict p_insz,
mbstate_t *restrict p_ps
)
{
while(*p_outsz && *p_insz) {
unsigned char c = **p_inbuf;
if(c > 127)
return false;
if(p_outbuf) {
**p_outbuf = c;
(*p_outbuf)++;
}
(*p_inbuf)++;
(*p_insz)--;
(*p_outsz)--;
}
return true;
}
static bool c32toascii(
char *restrict *restrict p_outbuf,
size_t *restrict p_outsz,
const char32_t *restrict *restrict p_inbuf,
size_t *restrict p_insz,
mbstate_t *restrict p_ps
)
{
while(*p_outsz && *p_insz) {
char32_t c = **p_inbuf;
if(c > 127)
return false;
if(p_outbuf) {
**p_outbuf = c;
(*p_outbuf)++;
}
(*p_inbuf)++;
(*p_insz)--;
(*p_outsz)--;
}
return true;
}
const struct _PDCLIB_charcodec_t _PDCLIB_ascii_codec = {
.__mbsinit = ascii_mbsinit,
.__mbstoc32s = asciitoc32,
.__c32stombs = c32toascii,
.__mb_max = 1,
};
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
// Valid conversion & back
char32_t c32out[5];
char32_t *c32ptr = &c32out[0];
size_t c32rem = 5;
char *chrptr = (char*) &abcde[0];
size_t chrrem = 5;
mbstate_t mbs = { 0 };
TESTCASE(asciitoc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs) == true);
TESTCASE(c32rem == 0);
TESTCASE(chrrem == 0);
TESTCASE(c32ptr == &c32out[5]);
TESTCASE(chrptr == &abcde[5]);
TESTCASE(c32out[0] == 'a' && c32out[1] == 'b' && c32out[2] == 'c' && \
c32out[3] == 'd' && c32out[4] == 'e');
char chrout[5];
c32ptr = &c32out[0];
c32rem = 5;
chrptr = &chrout[0];
chrrem = 5;
TESTCASE(c32toascii(&chrptr, &chrrem, &c32ptr, &c32rem, &mbs) == true);
TESTCASE(c32rem == 0);
TESTCASE(chrrem == 0);
TESTCASE(c32ptr == &c32out[5]);
TESTCASE(chrptr == &chrout[5]);
TESTCASE(memcmp(chrout, abcde, 5) == 0);
// Invalid conversions
char badascii = '\xC0';
c32ptr = &c32out[0];
c32rem = 5;
chrptr = &badascii;
chrrem = 1;
TESTCASE(asciitoc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs) == false);
TESTCASE(c32ptr == &c32out[0]);
TESTCASE(c32rem == 5);
TESTCASE(chrptr == &badascii);
TESTCASE(chrrem == 1);
char32_t baduni = 0xC0;
c32ptr = &baduni;
c32rem = 1;
chrptr = &chrout[0];
chrrem = 5;
TESTCASE(c32toascii(&chrptr, &chrrem, &c32ptr, &c32rem, &mbs) == false);
TESTCASE(c32ptr == &baduni);
TESTCASE(c32rem == 1);
TESTCASE(chrptr == &chrout[0]);
TESTCASE(chrrem == 5);
#endif
return TEST_RESULTS;
}
#endif

View File

@ -1,44 +0,0 @@
/* _PDCLIB_atomax( const char * )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "_PDCLIB_int.h"
#include <string.h>
#include <ctype.h>
_PDCLIB_intmax_t _PDCLIB_atomax( const char * s )
{
_PDCLIB_intmax_t rc = 0;
char sign = '+';
const char * x;
/* TODO: In other than "C" locale, additional patterns may be defined */
while ( isspace( *s ) ) ++s;
if ( *s == '+' ) ++s;
else if ( *s == '-' ) sign = *(s++);
/* TODO: Earlier version was missing tolower() but was not caught by tests */
while ( ( x = memchr( _PDCLIB_digits, tolower(*(s++)), 10 ) ) != NULL )
{
rc = rc * 10 + ( x - _PDCLIB_digits );
}
return ( sign == '+' ) ? rc : -rc;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
/* basic functionality */
TESTCASE( _PDCLIB_atomax( "123" ) == 123 );
/* testing skipping of leading whitespace and trailing garbage */
TESTCASE( _PDCLIB_atomax( " \n\v\t\f123xyz" ) == 123 );
#endif
return TEST_RESULTS;
}
#endif

View File

@ -1,36 +0,0 @@
/* _PDCLIB_closeall( void )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <stdio.h>
#ifndef REGTEST
#include "_PDCLIB_io.h"
extern _PDCLIB_file_t * _PDCLIB_filelist;
void _PDCLIB_closeall( void )
{
_PDCLIB_file_t * stream = _PDCLIB_filelist;
_PDCLIB_file_t * next;
while ( stream != NULL )
{
next = stream->next;
fclose( stream );
stream = next;
}
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
/* No testdriver */
return TEST_RESULTS;
}
#endif

View File

@ -1,30 +0,0 @@
/* _PDCLIB_digits
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "_PDCLIB_int.h"
#endif
char _PDCLIB_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
/* For _PDCLIB/print.c only; obsolete with ctype.h */
char _PDCLIB_Xdigits[] = "0123456789ABCDEF";
#ifdef TEST
#include "_PDCLIB_test.h"
#include <string.h>
int main( void )
{
#ifndef REGTEST
TESTCASE( strcmp( _PDCLIB_digits, "0123456789abcdefghijklmnopqrstuvwxyz" ) == 0 );
TESTCASE( strcmp( _PDCLIB_Xdigits, "0123456789ABCDEF" ) == 0 );
#endif
return TEST_RESULTS;
}
#endif

View File

@ -1,56 +0,0 @@
/* _PDCLIB_fileops
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include <stdio.h>
#include <stdint.h>
#include "_PDCLIB_glue.h"
#include <errno.h>
static bool readf( _PDCLIB_fd_t self, void * buf, size_t length,
size_t * numBytesRead )
{
errno = ENOTSUP;
return false;
}
static bool writef( _PDCLIB_fd_t self, const void * buf, size_t length,
size_t * numBytesWritten )
{
errno = ENOTSUP;
return false;
}
static bool seekf( _PDCLIB_fd_t self, int_fast64_t offset, int whence,
int_fast64_t* newPos )
{
errno = ENOTSUP;
return false;
}
static void closef( _PDCLIB_fd_t self )
{
errno = ENOTSUP;
}
const _PDCLIB_fileops_t _PDCLIB_fileops = {
.read = readf,
.write = writef,
.seek = seekf,
.close = closef,
};
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
// Tested by stdio test cases
return TEST_RESULTS;
}
#endif

View File

@ -1,29 +0,0 @@
/* _PDCLIB_initclocale( locale_t )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "_PDCLIB_clocale.h"
#include "_PDCLIB_locale.h"
void _PDCLIB_initclocale( locale_t l )
{
// TODO: There will be more added here...
l->_WCType = _PDCLIB_wcinfo;
l->_WCTypeSize = _PDCLIB_wcinfo_size;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main()
{
return TEST_RESULTS;
}
#endif

View File

@ -1,126 +0,0 @@
/* Latin-1 codec
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <stdbool.h>
#ifndef REGTEST
#include <uchar.h>
#include "_PDCLIB_encoding.h"
static bool latin1_mbsinit( const mbstate_t *ps )
{ return 1; }
static bool latin1toc32(
char32_t *restrict *restrict p_outbuf,
size_t *restrict p_outsz,
const char *restrict *restrict p_inbuf,
size_t *restrict p_insz,
mbstate_t *restrict p_ps
)
{
while(*p_outsz && *p_insz) {
unsigned char c = **p_inbuf;
if(p_outbuf) {
**p_outbuf = c;
(*p_outbuf)++;
}
(*p_inbuf)++;
(*p_insz)--;
(*p_outsz)--;
}
return true;
}
static bool c32tolatin1(
char *restrict *restrict p_outbuf,
size_t *restrict p_outsz,
const char32_t *restrict *restrict p_inbuf,
size_t *restrict p_insz,
mbstate_t *restrict p_ps
)
{
while(*p_outsz && *p_insz) {
char32_t c = **p_inbuf;
if(c > 255)
return false;
if(p_outbuf) {
**p_outbuf = c;
(*p_outbuf)++;
}
(*p_inbuf)++;
(*p_insz)--;
(*p_outsz)--;
}
return true;
}
const struct _PDCLIB_charcodec_t _PDCLIB_latin1_codec = {
.__mbsinit = latin1_mbsinit,
.__mbstoc32s = latin1toc32,
.__c32stombs = c32tolatin1,
.__mb_max = 1,
};
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
// Valid conversion & back
char32_t c32out[5];
char32_t *c32ptr = &c32out[0];
size_t c32rem = 5;
char *chrptr = (char*) &abcde[0];
size_t chrrem = 5;
mbstate_t mbs = { 0 };
TESTCASE(latin1toc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs) == true);
TESTCASE(c32rem == 0);
TESTCASE(chrrem == 0);
TESTCASE(c32ptr == &c32out[5]);
TESTCASE(chrptr == &abcde[5]);
TESTCASE(c32out[0] == 'a' && c32out[1] == 'b' && c32out[2] == 'c' && \
c32out[3] == 'd' && c32out[4] == 'e');
char chrout[5];
c32ptr = &c32out[0];
c32rem = 5;
chrptr = &chrout[0];
chrrem = 5;
TESTCASE(c32tolatin1(&chrptr, &chrrem, &c32ptr, &c32rem, &mbs) == true);
TESTCASE(c32rem == 0);
TESTCASE(chrrem == 0);
TESTCASE(c32ptr == &c32out[5]);
TESTCASE(chrptr == &chrout[5]);
TESTCASE(memcmp(chrout, abcde, 5) == 0);
// Invalid conversions
char32_t baduni = 0xFFFE;
c32ptr = &baduni;
c32rem = 1;
chrptr = &chrout[0];
chrrem = 5;
TESTCASE(c32tolatin1(&chrptr, &chrrem, &c32ptr, &c32rem, &mbs) == false);
TESTCASE(c32ptr == &baduni);
TESTCASE(c32rem == 1);
TESTCASE(chrptr == &chrout[0]);
TESTCASE(chrrem == 5);
#endif
return TEST_RESULTS;
}
#endif

View File

@ -1,37 +0,0 @@
/* _PDCLIB_open( char const * const, int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
/* This is a stub implementation of open.
*/
#include <stdio.h>
#include <errno.h>
#ifndef REGTEST
#include "_PDCLIB_glue.h"
bool _PDCLIB_open( _PDCLIB_fd_t * pFd, const _PDCLIB_fileops_t ** pOps,
char const * const filename, unsigned int mode )
{
errno = ENOTSUP;
return false;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
#include <stdlib.h>
#include <string.h>
int main( void )
{
return TEST_RESULTS;
}
#endif

View File

@ -1,18 +0,0 @@
/* _PDCLIB_seed
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
unsigned long int _PDCLIB_seed = 1;
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
/* no tests for raw data */
return TEST_RESULTS;
}
#endif

View File

@ -1,85 +0,0 @@
/* _PDCLIB_strtox_main( const char * *, int, _PDCLIB_uintmax_t, _PDCLIB_uintmax_t, int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <stdint.h>
#ifndef REGTEST
#include "_PDCLIB_int.h"
_PDCLIB_uintmax_t _PDCLIB_strtox_main( const char ** p, unsigned int base, uintmax_t error, uintmax_t limval, int limdigit, char * sign )
{
_PDCLIB_uintmax_t rc = 0;
int digit = -1;
const char * x;
while ( ( x = memchr( _PDCLIB_digits, tolower(**p), base ) ) != NULL )
{
digit = x - _PDCLIB_digits;
if ( ( rc < limval ) || ( ( rc == limval ) && ( digit <= limdigit ) ) )
{
rc = rc * base + (unsigned)digit;
++(*p);
}
else
{
errno = ERANGE;
/* TODO: Only if endptr != NULL - but do we really want *another* parameter? */
/* TODO: Earlier version was missing tolower() here but was not caught by tests */
while ( memchr( _PDCLIB_digits, tolower(**p), base ) != NULL ) ++(*p);
/* TODO: This is ugly, but keeps caller from negating the error value */
*sign = '+';
return error;
}
}
if ( digit == -1 )
{
*p = NULL;
return 0;
}
return rc;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
#include <errno.h>
int main( void )
{
#ifndef REGTEST
const char * p;
char test[] = "123_";
char fail[] = "xxx";
char sign = '-';
/* basic functionality */
p = test;
errno = 0;
TESTCASE( _PDCLIB_strtox_main( &p, 10u, (uintmax_t)999, (uintmax_t)12, 3, &sign ) == 123 );
TESTCASE( errno == 0 );
TESTCASE( p == &test[3] );
/* proper functioning to smaller base */
p = test;
TESTCASE( _PDCLIB_strtox_main( &p, 8u, (uintmax_t)999, (uintmax_t)12, 3, &sign ) == 0123 );
TESTCASE( errno == 0 );
TESTCASE( p == &test[3] );
/* overflowing subject sequence must still return proper endptr */
p = test;
TESTCASE( _PDCLIB_strtox_main( &p, 4u, (uintmax_t)999, (uintmax_t)1, 2, &sign ) == 999 );
TESTCASE( errno == ERANGE );
TESTCASE( p == &test[3] );
TESTCASE( sign == '+' );
/* testing conversion failure */
errno = 0;
p = fail;
sign = '-';
TESTCASE( _PDCLIB_strtox_main( &p, 10u, (uintmax_t)999, (uintmax_t)99, 8, &sign ) == 0 );
TESTCASE( p == NULL );
#endif
return TEST_RESULTS;
}
#endif

View File

@ -1,90 +0,0 @@
/* _PDCLIB_strtox_prelim( const char *, char *, int * )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <ctype.h>
#include <stddef.h>
#include <string.h>
#ifndef REGTEST
const char * _PDCLIB_strtox_prelim( const char * p, char * sign, int * base )
{
/* skipping leading whitespace */
while ( isspace( *p ) ) ++p;
/* determining / skipping sign */
if ( *p != '+' && *p != '-' ) *sign = '+';
else *sign = *(p++);
/* determining base */
if ( *p == '0' )
{
++p;
if ( ( *base == 0 || *base == 16 ) && ( *p == 'x' || *p == 'X' ) )
{
*base = 16;
++p;
/* catching a border case here: "0x" followed by a non-digit should
be parsed as the unprefixed zero.
We have to "rewind" the parsing; having the base set to 16 if it
was zero previously does not hurt, as the result is zero anyway.
*/
if ( memchr( _PDCLIB_digits, tolower(*p), *base ) == NULL )
{
p -= 2;
}
}
else if ( *base == 0 )
{
*base = 8;
}
else
{
--p;
}
}
else if ( ! *base )
{
*base = 10;
}
return ( ( *base >= 2 ) && ( *base <= 36 ) ) ? p : NULL;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
int base = 0;
char sign = '\0';
char test1[] = " 123";
char test2[] = "\t+0123";
char test3[] = "\v-0x123";
TESTCASE( _PDCLIB_strtox_prelim( test1, &sign, &base ) == &test1[2] );
TESTCASE( sign == '+' );
TESTCASE( base == 10 );
base = 0;
sign = '\0';
TESTCASE( _PDCLIB_strtox_prelim( test2, &sign, &base ) == &test2[3] );
TESTCASE( sign == '+' );
TESTCASE( base == 8 );
base = 0;
sign = '\0';
TESTCASE( _PDCLIB_strtox_prelim( test3, &sign, &base ) == &test3[4] );
TESTCASE( sign == '-' );
TESTCASE( base == 16 );
base = 10;
sign = '\0';
TESTCASE( _PDCLIB_strtox_prelim( test3, &sign, &base ) == &test3[2] );
TESTCASE( sign == '-' );
TESTCASE( base == 10 );
base = 1;
TESTCASE( _PDCLIB_strtox_prelim( test3, &sign, &base ) == NULL );
base = 37;
TESTCASE( _PDCLIB_strtox_prelim( test3, &sign, &base ) == NULL );
#endif
return TEST_RESULTS;
}
#endif

View File

@ -1,338 +0,0 @@
/* UTF-8 codec
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include <stdbool.h>
#include <stdint.h>
#include <uchar.h>
#include <assert.h>
#include "_PDCLIB_encoding.h"
/* Use of the mbstate:
*
* _StUC[0] is the current decoding state
* _St32[1] is the character accumulated so far
*/
static bool utf8_mbsinit( const mbstate_t *p_s )
{ return p_s->_StUC[0] == 0; }
enum {
DecStart = 0,
Dec2B2,
Dec3B2,
Dec3B3,
Dec4B2,
Dec4B3,
Dec4B4
};
#define state (p_s->_StUC[0])
#define accum (p_s->_St32[1])
#define START_CONVERSION \
bool result = true; \
#define END_CONVERSION \
end_conversion: \
return result
#define FINISH(_r) do { \
result = (_r); \
goto end_conversion; \
} while(0)
#define OUT32(_c) do { \
if(p_outbuf) \
(*((*p_outbuf)++)) = (_c); \
(*p_outsz)--; \
_PDCLIB_UNDEFINED(accum); \
state = DecStart; \
} while(0)
#define CHECK_CONTINUATION \
do { if((c & 0xC0) != 0x80) return false; } while(0)
static bool utf8toc32(
char32_t *restrict *restrict p_outbuf,
size_t *restrict p_outsz,
const char *restrict *restrict p_inbuf,
size_t *restrict p_insz,
mbstate_t *restrict p_s
)
{
START_CONVERSION
while(*p_outsz && *p_insz) {
unsigned char c = **p_inbuf;
char32_t c32;
switch(state) {
case DecStart:
// 1 byte
if(c <= 0x7F) {
OUT32(c);
} else if(c <= 0xDF) {
accum = (c & 0x1F) << 6;
state = Dec2B2;
} else if(c <= 0xEF) {
accum = (c & 0x0F) << 12;
state = Dec3B2;
} else if(c <= 0xF4) {
accum = (c & 0x07) << 18;
state = Dec4B2;
} else {
// 5+byte sequence illegal
FINISH(false);
}
break;
case Dec2B2:
CHECK_CONTINUATION;
c32 = accum | (c & 0x3F);
// Overlong sequence (e.g. NUL injection)
if(c32 <= 0x7F)
FINISH(false);
OUT32(c32);
break;
case Dec3B2:
CHECK_CONTINUATION;
accum |= (c & 0x3F) << 6;
state = Dec3B3;
break;
case Dec3B3:
CHECK_CONTINUATION;
c32 = accum | (c & 0x3F);
// Overlong
if(c32 <= 0x07FF)
FINISH(false);
// Surrogate
if(c32 >= 0xD800 && c32 <= 0xDFFF)
FINISH(false);
OUT32(c32);
break;
case Dec4B2:
CHECK_CONTINUATION;
accum |= (c & 0x3F) << 12;
state = Dec4B3;
break;
case Dec4B3:
CHECK_CONTINUATION;
accum |= (c & 0x3F) << 6;
state = Dec4B4;
break;
case Dec4B4:
CHECK_CONTINUATION;
c32 = accum | (c & 0x3F);
// Overlong
if(c32 <= 0xFFFF) FINISH(false);
// Not in Unicode
if(c32 > 0x10FFFF) FINISH(false);
OUT32(c32);
break;
default:
assert(!"Invalid state");
}
(*p_inbuf)++;
(*p_insz)--;
}
END_CONVERSION;
}
enum {
EncStart = 0,
Enc1R,
Enc2R,
Enc3R,
};
static bool c32toutf8(
char *restrict *restrict p_outbuf,
size_t *restrict p_outsz,
const char32_t *restrict *restrict p_inbuf,
size_t *restrict p_insz,
mbstate_t *restrict p_s
)
{
START_CONVERSION
while(*p_outsz) {
unsigned char outc = 0;
switch(state) {
case Enc3R:
outc = 0x80 | ((accum >> 12) & 0x3F);
state = Enc2R;
break;
case Enc2R:
outc = 0x80 | ((accum >> 6) & 0x3F);
state = Enc1R;
break;
case Enc1R:
outc = 0x80 | (accum & 0x3F);
state = EncStart;
_PDCLIB_UNDEFINED(accum);
break;
case EncStart:
if(*p_insz == 0)
FINISH(true);
accum = **p_inbuf;
(*p_inbuf)++;
(*p_insz)--;
if(accum <= 0x7F) {
outc = accum;
state = EncStart;
_PDCLIB_UNDEFINED(accum);
} else if(accum <= 0x7FF) {
outc = 0xC0 | (accum >> 6);
state = Enc1R;
} else if(accum <= 0xFFFF) {
outc = 0xE0 | (accum >> 12);
state = Enc2R;
} else if(accum <= 0x10FFFF) {
outc = 0xF0 | (accum >> 18);
state = Enc3R;
} else {
FINISH(false);
}
break;
}
if(p_outbuf) {
**p_outbuf = outc;
(*p_outbuf)++;
}
(*p_outsz)--;
}
END_CONVERSION;
}
const struct _PDCLIB_charcodec_t _PDCLIB_utf8_codec = {
.__mbsinit = utf8_mbsinit,
.__mbstoc32s = utf8toc32,
.__c32stombs = c32toutf8,
.__mb_max = 4,
};
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
// Valid conversion & back
static const char* input = "abcde" "\xDF\xBF" "\xEF\xBF\xBF"
"\xF4\x8F\xBF\xBF";
char32_t c32out[8];
char32_t *c32ptr = &c32out[0];
size_t c32rem = 8;
const char *chrptr = (char*) &input[0];
size_t chrrem = strlen(input);
mbstate_t mbs = { 0 };
TESTCASE(utf8toc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs));
TESTCASE(c32rem == 0);
TESTCASE(chrrem == 0);
TESTCASE(c32ptr == &c32out[8]);
TESTCASE(chrptr == &input[strlen(input)]);
TESTCASE(c32out[0] == 'a' && c32out[1] == 'b' && c32out[2] == 'c' &&
c32out[3] == 'd' && c32out[4] == 'e' && c32out[5] == 0x7FF &&
c32out[6] == 0xFFFF && c32out[7] == 0x10FFFF);
char chrout[strlen(input)];
c32ptr = &c32out[0];
c32rem = 8;
chrptr = &chrout[0];
chrrem = strlen(input);
TESTCASE(c32toutf8(&chrptr, &chrrem, &c32ptr, &c32rem, &mbs));
TESTCASE(c32rem == 0);
TESTCASE(chrrem == 0);
TESTCASE(c32ptr == &c32out[8]);
TESTCASE(chrptr == &chrout[strlen(input)]);
TESTCASE(memcmp(chrout, input, strlen(input)) == 0);
// Multi-part conversion
static const char* mpinput = "\xDF\xBF";
c32ptr = &c32out[0];
c32rem = 8;
chrptr = &mpinput[0];
chrrem = 1;
TESTCASE(utf8toc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs));
TESTCASE(c32ptr == &c32out[0]);
TESTCASE(c32rem == 8);
TESTCASE(chrptr == &mpinput[1]);
TESTCASE(chrrem == 0);
chrrem = 1;
TESTCASE(utf8toc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs));
TESTCASE(c32ptr == &c32out[1]);
TESTCASE(c32rem == 7);
TESTCASE(chrptr == &mpinput[2]);
TESTCASE(chrrem == 0);
// Invalid conversions
// Overlong nuls
const char* nul2 = "\xC0\x80";
c32ptr = &c32out[0];
c32rem = 8;
chrptr = &nul2[0];
chrrem = 2;
TESTCASE(utf8toc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs) == false);
memset(&mbs, 0, sizeof mbs);
const char* nul3 = "\xE0\x80\x80";
c32ptr = &c32out[0];
c32rem = 8;
chrptr = &nul3[0];
chrrem = 3;
TESTCASE(utf8toc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs) == false);
memset(&mbs, 0, sizeof mbs);
const char* nul4 = "\xF0\x80\x80\x80";
c32ptr = &c32out[0];
c32rem = 8;
chrptr = &nul4[0];
chrrem = 4;
TESTCASE(utf8toc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs) == false);
// Starting on a continuation
const char* cont = "\x80";
c32ptr = &c32out[0];
c32rem = 8;
chrptr = &cont[0];
chrrem = 1;
TESTCASE(utf8toc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs) == false);
#endif
return TEST_RESULTS;
}
#endif

View File

@ -1,67 +0,0 @@
/* _PDCLIB_assert( char const * )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#ifndef REGTEST
#include "_PDCLIB_aux.h"
void _PDCLIB_assert99( char const * const message1, char const * const function, char const * const message2 )
{
fputs( message1, stderr );
fputs( function, stderr );
fputs( message2, stderr );
abort();
}
void _PDCLIB_assert89( char const * const message )
{
fputs( message, stderr );
abort();
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
#include <signal.h>
static int EXPECTED_ABORT = 0;
static int UNEXPECTED_ABORT = 1;
static void aborthandler( int sig )
{
TESTCASE( ! EXPECTED_ABORT );
exit( (signed int)TEST_RESULTS );
}
#define NDEBUG
#include <assert.h>
static int disabled_test( void )
{
int i = 0;
assert( i == 0 ); /* NDEBUG set, condition met */
assert( i == 1 ); /* NDEBUG set, condition fails */
return i;
}
#undef NDEBUG
#include <assert.h>
int main( void )
{
TESTCASE( signal( SIGABRT, &aborthandler ) != SIG_ERR );
TESTCASE( disabled_test() == 0 );
assert( UNEXPECTED_ABORT ); /* NDEBUG not set, condition met */
assert( EXPECTED_ABORT ); /* NDEBUG not set, condition fails - should abort */
return TEST_RESULTS;
}
#endif

View File

@ -1,39 +0,0 @@
#include <stdint.h>
#include <stddef.h>
#include "_PDCLIB_glue.h"
#include <errno.h>
#include <emulibc.h>
ECL_EXPORT ECL_ENTRY __attribute__((noreturn)) void (*_ecl_trap)(void); // something very unexpected happened. should not return
ECL_EXPORT ECL_ENTRY void *(*_ecl_sbrk)(size_t n); // sbrk. won't return if the request can't be satisfied
ECL_EXPORT ECL_ENTRY void (*_ecl_debug_puts)(const char *); // low level debug write, doesn't involve STDIO
ECL_EXPORT ECL_ENTRY void *(*_ecl_sbrk_sealed)(size_t n); // allocate memory; see emulibc.h
ECL_EXPORT ECL_ENTRY void *(*_ecl_sbrk_invisible)(size_t n); // allocate memory; see emulibc.h
void *alloc_sealed(size_t size)
{
return _ecl_sbrk_sealed(size);
}
void *alloc_invisible(size_t size)
{
return _ecl_sbrk_invisible(size);
}
void _debug_puts(const char *s)
{
_ecl_debug_puts(s);
}
void *_PDCLIB_sbrk(size_t n)
{
void *ret = _ecl_sbrk(n);
return ret;
}
void _PDCLIB_Exit( int status )
{
_ecl_trap();
}

View File

@ -1,31 +0,0 @@
/* _PDCLIB_rename( const char *, const char * )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <stdio.h>
#ifndef REGTEST
#include "_PDCLIB_glue.h"
#include <errno.h>
int _PDCLIB_rename( const char * old, const char * new )
{
errno = ENOTSUP;
return -1;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
#include <stdlib.h>
int main( void )
{
return TEST_RESULTS;
}
#endif

View File

@ -1,113 +0,0 @@
/* stdarg
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <stdarg.h>
#include <limits.h>
#include <float.h>
#ifdef TEST
#include "_PDCLIB_test.h"
typedef int (*intfunc_t)( void );
enum tag_t
{
TAG_END,
TAG_INT,
TAG_LONG,
TAG_LLONG,
TAG_DBL,
TAG_LDBL,
TAG_INTPTR,
TAG_LDBLPTR,
TAG_FUNCPTR
};
static int dummy( void )
{
return INT_MAX;
}
static int test( enum tag_t s, ... )
{
enum tag_t tag = s;
va_list ap;
va_start( ap, s );
for (;;)
{
switch ( tag )
{
case TAG_INT:
{
TESTCASE( va_arg( ap, int ) == INT_MAX );
tag = va_arg( ap, enum tag_t );
break;
}
case TAG_LONG:
{
TESTCASE( va_arg( ap, long ) == LONG_MAX );
tag = va_arg( ap, enum tag_t );
break;
}
case TAG_LLONG:
{
TESTCASE( va_arg( ap, long long ) == LLONG_MAX );
tag = va_arg( ap, enum tag_t );
break;
}
case TAG_DBL:
{
TESTCASE( va_arg( ap, double ) == DBL_MAX );
tag = va_arg( ap, enum tag_t );
break;
}
case TAG_LDBL:
{
TESTCASE( va_arg( ap, long double ) == LDBL_MAX );
tag = va_arg( ap, enum tag_t );
break;
}
case TAG_INTPTR:
{
TESTCASE( *( va_arg( ap, int * ) ) == INT_MAX );
tag = va_arg( ap, enum tag_t );
break;
}
case TAG_LDBLPTR:
{
TESTCASE( *( va_arg( ap, long double * ) ) == LDBL_MAX );
tag = va_arg( ap, enum tag_t );
break;
}
case TAG_FUNCPTR:
{
intfunc_t function;
TESTCASE( ( function = va_arg( ap, intfunc_t ) ) == dummy );
TESTCASE( function() == INT_MAX );
tag = va_arg( ap, enum tag_t );
break;
}
case TAG_END:
{
va_end( ap );
return 0;
}
}
}
}
int main( void )
{
int x = INT_MAX;
long double d = LDBL_MAX;
test( TAG_END );
test( TAG_INT, INT_MAX, TAG_END );
test( TAG_LONG, LONG_MAX, TAG_LLONG, LLONG_MAX, TAG_END );
test( TAG_DBL, DBL_MAX, TAG_LDBL, LDBL_MAX, TAG_END );
test( TAG_INTPTR, &x, TAG_LDBLPTR, &d, TAG_FUNCPTR, dummy, TAG_END );
return TEST_RESULTS;
}
#endif

View File

@ -1,522 +0,0 @@
/* _PDCLIB_stdinit
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
/* This is an example initialization of stdin, stdout and stderr to the integer
file descriptors 0, 1, and 2, respectively. This applies for a great variety
of operating systems, including POSIX compliant ones.
*/
#include <stdio.h>
#include <locale.h>
#include <limits.h>
#ifndef REGTEST
#include "_PDCLIB_io.h"
#include "_PDCLIB_locale.h"
#include "_PDCLIB_encoding.h"
extern const _PDCLIB_fileops_t _PDCLIB_fileops;
/* In a POSIX system, stdin / stdout / stderr are equivalent to the (int) file
descriptors 0, 1, and 2 respectively.
*/
/* TODO: This is proof-of-concept, requires finetuning. */
static char _PDCLIB_sin_buffer[BUFSIZ];
static char _PDCLIB_sout_buffer[BUFSIZ];
static char _PDCLIB_serr_buffer[BUFSIZ];
static unsigned char _PDCLIB_sin_ungetbuf[_PDCLIB_UNGETCBUFSIZE];
static unsigned char _PDCLIB_sout_ungetbuf[_PDCLIB_UNGETCBUFSIZE];
static unsigned char _PDCLIB_serr_ungetbuf[_PDCLIB_UNGETCBUFSIZE];
static FILE _PDCLIB_serr = {
.ops = &_PDCLIB_fileops,
.buffer = _PDCLIB_serr_buffer,
.bufsize = BUFSIZ,
.bufidx = 0,
.bufend = 0,
.ungetidx = 0,
.ungetbuf = _PDCLIB_serr_ungetbuf,
.status = _IONBF | _PDCLIB_FWRITE | _PDCLIB_STATIC,
.filename = NULL,
.next = NULL,
};
static FILE _PDCLIB_sout = {
.ops = &_PDCLIB_fileops,
.buffer = _PDCLIB_sout_buffer,
.bufsize = BUFSIZ,
.bufidx = 0,
.bufend = 0,
.ungetidx = 0,
.ungetbuf = _PDCLIB_sout_ungetbuf,
.status = _IOLBF | _PDCLIB_FWRITE | _PDCLIB_STATIC,
.filename = NULL,
.next = &_PDCLIB_serr
};
static FILE _PDCLIB_sin = {
.ops = &_PDCLIB_fileops,
.buffer = _PDCLIB_sin_buffer,
.bufsize = BUFSIZ,
.bufidx = 0,
.bufend = 0,
.ungetidx = 0,
.ungetbuf = _PDCLIB_sin_ungetbuf,
.status = _IOLBF | _PDCLIB_FREAD | _PDCLIB_STATIC,
.filename = NULL,
.next = &_PDCLIB_sout
};
FILE *stdin = &_PDCLIB_sin;
FILE *stdout = &_PDCLIB_sout;
FILE *stderr = &_PDCLIB_serr;
FILE *_PDCLIB_filelist = &_PDCLIB_sin;
/* "C" locale - defaulting to ASCII-7.
1 kByte (+ 4 byte) of <ctype.h> data.
Each line: flags, lowercase, uppercase, collation.
*/
static const _PDCLIB_ctype_t global_ctype[] = {
{ /* EOF */ 0, 0, 0, 0 },
{ /* NUL */ _PDCLIB_CTYPE_CNTRL, 0x00, 0x00, 0x00 },
{ /* SOH */ _PDCLIB_CTYPE_CNTRL, 0x01, 0x01, 0x01 },
{ /* STX */ _PDCLIB_CTYPE_CNTRL, 0x02, 0x02, 0x02 },
{ /* ETX */ _PDCLIB_CTYPE_CNTRL, 0x03, 0x03, 0x03 },
{ /* EOT */ _PDCLIB_CTYPE_CNTRL, 0x04, 0x04, 0x04 },
{ /* ENQ */ _PDCLIB_CTYPE_CNTRL, 0x05, 0x05, 0x05 },
{ /* ACK */ _PDCLIB_CTYPE_CNTRL, 0x06, 0x06, 0x06 },
{ /* BEL */ _PDCLIB_CTYPE_CNTRL, 0x07, 0x07, 0x07 },
{ /* BS */ _PDCLIB_CTYPE_CNTRL, 0x08, 0x08, 0x08 },
{ /* HT */ _PDCLIB_CTYPE_CNTRL | _PDCLIB_CTYPE_BLANK | _PDCLIB_CTYPE_SPACE, 0x09, 0x09, 0x09 },
{ /* LF */ _PDCLIB_CTYPE_CNTRL | _PDCLIB_CTYPE_SPACE, 0x0A, 0x0A, 0x0A },
{ /* VT */ _PDCLIB_CTYPE_CNTRL | _PDCLIB_CTYPE_SPACE, 0x0B, 0x0B, 0x0B },
{ /* FF */ _PDCLIB_CTYPE_CNTRL | _PDCLIB_CTYPE_SPACE, 0x0C, 0x0C, 0x0C },
{ /* CR */ _PDCLIB_CTYPE_CNTRL | _PDCLIB_CTYPE_SPACE, 0x0D, 0x0D, 0x0D },
{ /* SO */ _PDCLIB_CTYPE_CNTRL, 0x0E, 0x0E, 0x0E },
{ /* SI */ _PDCLIB_CTYPE_CNTRL, 0x0F, 0x0F, 0x0F },
{ /* DLE */ _PDCLIB_CTYPE_CNTRL, 0x10, 0x10, 0x10 },
{ /* DC1 */ _PDCLIB_CTYPE_CNTRL, 0x11, 0x11, 0x11 },
{ /* DC2 */ _PDCLIB_CTYPE_CNTRL, 0x12, 0x12, 0x12 },
{ /* DC3 */ _PDCLIB_CTYPE_CNTRL, 0x13, 0x13, 0x13 },
{ /* DC4 */ _PDCLIB_CTYPE_CNTRL, 0x14, 0x14, 0x14 },
{ /* NAK */ _PDCLIB_CTYPE_CNTRL, 0x15, 0x15, 0x15 },
{ /* SYN */ _PDCLIB_CTYPE_CNTRL, 0x16, 0x16, 0x16 },
{ /* ETB */ _PDCLIB_CTYPE_CNTRL, 0x17, 0x17, 0x17 },
{ /* CAN */ _PDCLIB_CTYPE_CNTRL, 0x18, 0x18, 0x18 },
{ /* EM */ _PDCLIB_CTYPE_CNTRL, 0x19, 0x19, 0x19 },
{ /* SUB */ _PDCLIB_CTYPE_CNTRL, 0x1A, 0x1A, 0x1A },
{ /* ESC */ _PDCLIB_CTYPE_CNTRL, 0x1B, 0x1B, 0x1B },
{ /* FS */ _PDCLIB_CTYPE_CNTRL, 0x1C, 0x1C, 0x1C },
{ /* GS */ _PDCLIB_CTYPE_CNTRL, 0x1D, 0x1D, 0x1D },
{ /* RS */ _PDCLIB_CTYPE_CNTRL, 0x1E, 0x1E, 0x1E },
{ /* US */ _PDCLIB_CTYPE_CNTRL, 0x1F, 0x1F, 0x1F },
{ /* SP */ _PDCLIB_CTYPE_BLANK | _PDCLIB_CTYPE_SPACE, 0x20, 0x20, 0x20 },
{ /* '!' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x21, 0x21, 0x21 },
{ /* '"' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x22, 0x22, 0x22 },
{ /* '#' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x23, 0x23, 0x23 },
{ /* '$' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x24, 0x24, 0x24 },
{ /* '%' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x25, 0x25, 0x25 },
{ /* '&' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x26, 0x26, 0x26 },
{ /* ''' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x27, 0x27, 0x27 },
{ /* '(' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x28, 0x28, 0x28 },
{ /* ')' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x29, 0x29, 0x29 },
{ /* '*' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2A, 0x2A, 0x2A },
{ /* '+' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2B, 0x2B, 0x2B },
{ /* ',' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2C, 0x2C, 0x2C },
{ /* '-' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2D, 0x2D, 0x2D },
{ /* '.' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2E, 0x2E, 0x2E },
{ /* '/' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2F, 0x2F, 0x2F },
{ /* '0' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x30, 0x30, 0x30 },
{ /* '1' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x31, 0x31, 0x31 },
{ /* '2' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x32, 0x32, 0x32 },
{ /* '3' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x33, 0x33, 0x33 },
{ /* '4' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x34, 0x34, 0x34 },
{ /* '5' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x35, 0x35, 0x35 },
{ /* '6' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x36, 0x36, 0x36 },
{ /* '7' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x37, 0x37, 0x37 },
{ /* '8' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x38, 0x38, 0x38 },
{ /* '9' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x39, 0x39, 0x39 },
{ /* ':' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3A, 0x3A, 0x3A },
{ /* ';' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3B, 0x3B, 0x3B },
{ /* '<' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3C, 0x3C, 0x3C },
{ /* '=' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3D, 0x3D, 0x3D },
{ /* '>' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3E, 0x3E, 0x3E },
{ /* '?' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3F, 0x3F, 0x3F },
{ /* '@' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x40, 0x40, 0x40 },
{ /* 'A' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER | _PDCLIB_CTYPE_XDIGT, 0x41, 0x61, 0x41 },
{ /* 'B' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER | _PDCLIB_CTYPE_XDIGT, 0x42, 0x62, 0x42 },
{ /* 'C' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER | _PDCLIB_CTYPE_XDIGT, 0x43, 0x63, 0x43 },
{ /* 'D' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER | _PDCLIB_CTYPE_XDIGT, 0x44, 0x64, 0x44 },
{ /* 'E' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER | _PDCLIB_CTYPE_XDIGT, 0x45, 0x65, 0x45 },
{ /* 'F' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER | _PDCLIB_CTYPE_XDIGT, 0x46, 0x66, 0x46 },
{ /* 'G' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x47, 0x67, 0x47 },
{ /* 'H' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x48, 0x68, 0x48 },
{ /* 'I' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x49, 0x69, 0x49 },
{ /* 'J' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4A, 0x6A, 0x4A },
{ /* 'K' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4B, 0x6B, 0x4B },
{ /* 'L' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4C, 0x6C, 0x4C },
{ /* 'M' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4D, 0x6D, 0x4D },
{ /* 'N' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4E, 0x6E, 0x4E },
{ /* 'O' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4F, 0x6F, 0x4F },
{ /* 'P' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x50, 0x70, 0x50 },
{ /* 'Q' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x51, 0x71, 0x51 },
{ /* 'R' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x52, 0x72, 0x52 },
{ /* 'S' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x53, 0x73, 0x53 },
{ /* 'T' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x54, 0x74, 0x54 },
{ /* 'U' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x55, 0x75, 0x55 },
{ /* 'V' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x56, 0x76, 0x56 },
{ /* 'W' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x57, 0x77, 0x57 },
{ /* 'X' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x58, 0x78, 0x58 },
{ /* 'Y' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x59, 0x79, 0x59 },
{ /* 'Z' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x5A, 0x7A, 0x5A },
{ /* '[' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x5B, 0x5B, 0x5B },
{ /* '\' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x5C, 0x5C, 0x5C },
{ /* ']' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x5D, 0x5D, 0x5D },
{ /* '^' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x5E, 0x5E, 0x5E },
{ /* '_' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x5F, 0x5F, 0x5F },
{ /* '`' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x60, 0x60, 0x60 },
{ /* 'a' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER | _PDCLIB_CTYPE_XDIGT, 0x41, 0x61, 0x61 },
{ /* 'b' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER | _PDCLIB_CTYPE_XDIGT, 0x42, 0x62, 0x62 },
{ /* 'c' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER | _PDCLIB_CTYPE_XDIGT, 0x43, 0x63, 0x63 },
{ /* 'd' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER | _PDCLIB_CTYPE_XDIGT, 0x44, 0x64, 0x64 },
{ /* 'e' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER | _PDCLIB_CTYPE_XDIGT, 0x45, 0x65, 0x65 },
{ /* 'f' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER | _PDCLIB_CTYPE_XDIGT, 0x46, 0x66, 0x66 },
{ /* 'g' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x47, 0x67, 0x67 },
{ /* 'h' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x48, 0x68, 0x68 },
{ /* 'i' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x49, 0x69, 0x69 },
{ /* 'j' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4A, 0x6A, 0x6A },
{ /* 'k' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4B, 0x6B, 0x6B },
{ /* 'l' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4C, 0x6C, 0x6C },
{ /* 'm' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4D, 0x6D, 0x6D },
{ /* 'n' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4E, 0x6E, 0x6E },
{ /* 'o' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4F, 0x6F, 0x6F },
{ /* 'p' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x50, 0x70, 0x70 },
{ /* 'q' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x51, 0x71, 0x71 },
{ /* 'r' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x52, 0x72, 0x72 },
{ /* 's' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x53, 0x73, 0x73 },
{ /* 't' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x54, 0x74, 0x74 },
{ /* 'u' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x55, 0x75, 0x75 },
{ /* 'v' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x56, 0x76, 0x76 },
{ /* 'w' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x57, 0x77, 0x77 },
{ /* 'x' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x58, 0x78, 0x78 },
{ /* 'y' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x59, 0x79, 0x79 },
{ /* 'z' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x5A, 0x7A, 0x7A },
{ /* '{' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x7B, 0x7B, 0x7B },
{ /* '|' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x7C, 0x7C, 0x7C },
{ /* '}' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x7D, 0x7D, 0x7D },
{ /* '~' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x7E, 0x7E, 0x7E },
{ /* DEL */ _PDCLIB_CTYPE_CNTRL, 0x7F, 0x7F, 0x7F },
{ 0x00, 0x80, 0x80, 0x80 },
{ 0x00, 0x81, 0x81, 0x81 },
{ 0x00, 0x82, 0x82, 0x82 },
{ 0x00, 0x83, 0x83, 0x83 },
{ 0x00, 0x84, 0x84, 0x84 },
{ 0x00, 0x85, 0x85, 0x85 },
{ 0x00, 0x86, 0x86, 0x86 },
{ 0x00, 0x87, 0x87, 0x87 },
{ 0x00, 0x88, 0x88, 0x88 },
{ 0x00, 0x89, 0x89, 0x89 },
{ 0x00, 0x8A, 0x8A, 0x8A },
{ 0x00, 0x8B, 0x8B, 0x8B },
{ 0x00, 0x8C, 0x8C, 0x8C },
{ 0x00, 0x8D, 0x8D, 0x8D },
{ 0x00, 0x8E, 0x8E, 0x8E },
{ 0x00, 0x8F, 0x8F, 0x8F },
{ 0x00, 0x90, 0x90, 0x90 },
{ 0x00, 0x91, 0x91, 0x91 },
{ 0x00, 0x92, 0x92, 0x92 },
{ 0x00, 0x93, 0x93, 0x93 },
{ 0x00, 0x94, 0x94, 0x94 },
{ 0x00, 0x95, 0x95, 0x95 },
{ 0x00, 0x96, 0x96, 0x96 },
{ 0x00, 0x97, 0x97, 0x97 },
{ 0x00, 0x98, 0x98, 0x98 },
{ 0x00, 0x99, 0x99, 0x99 },
{ 0x00, 0x9A, 0x9A, 0x9A },
{ 0x00, 0x9B, 0x9B, 0x9B },
{ 0x00, 0x9C, 0x9C, 0x9C },
{ 0x00, 0x9D, 0x9D, 0x9D },
{ 0x00, 0x9E, 0x9E, 0x9E },
{ 0x00, 0x9F, 0x9F, 0x9F },
{ 0x00, 0xA0, 0xA0, 0xA0 },
{ 0x00, 0xA1, 0xA1, 0xA1 },
{ 0x00, 0xA2, 0xA2, 0xA2 },
{ 0x00, 0xA3, 0xA3, 0xA3 },
{ 0x00, 0xA4, 0xA4, 0xA4 },
{ 0x00, 0xA5, 0xA5, 0xA5 },
{ 0x00, 0xA6, 0xA6, 0xA6 },
{ 0x00, 0xA7, 0xA7, 0xA7 },
{ 0x00, 0xA8, 0xA8, 0xA8 },
{ 0x00, 0xA9, 0xA9, 0xA9 },
{ 0x00, 0xAA, 0xAA, 0xAA },
{ 0x00, 0xAB, 0xAB, 0xAB },
{ 0x00, 0xAC, 0xAC, 0xAC },
{ 0x00, 0xAD, 0xAD, 0xAD },
{ 0x00, 0xAE, 0xAE, 0xAE },
{ 0x00, 0xAF, 0xAF, 0xAF },
{ 0x00, 0xB0, 0xB0, 0xB0 },
{ 0x00, 0xB1, 0xB1, 0xB1 },
{ 0x00, 0xB2, 0xB2, 0xB2 },
{ 0x00, 0xB3, 0xB3, 0xB3 },
{ 0x00, 0xB4, 0xB4, 0xB4 },
{ 0x00, 0xB5, 0xB5, 0xB5 },
{ 0x00, 0xB6, 0xB6, 0xB6 },
{ 0x00, 0xB7, 0xB7, 0xB7 },
{ 0x00, 0xB8, 0xB8, 0xB8 },
{ 0x00, 0xB9, 0xB9, 0xB9 },
{ 0x00, 0xBA, 0xBA, 0xBA },
{ 0x00, 0xBB, 0xBB, 0xBB },
{ 0x00, 0xBC, 0xBC, 0xBC },
{ 0x00, 0xBD, 0xBD, 0xBD },
{ 0x00, 0xBE, 0xBE, 0xBE },
{ 0x00, 0xBF, 0xBF, 0xBF },
{ 0x00, 0xC0, 0xC0, 0xC0 },
{ 0x00, 0xC1, 0xC1, 0xC1 },
{ 0x00, 0xC2, 0xC2, 0xC2 },
{ 0x00, 0xC3, 0xC3, 0xC3 },
{ 0x00, 0xC4, 0xC4, 0xC4 },
{ 0x00, 0xC5, 0xC5, 0xC5 },
{ 0x00, 0xC6, 0xC6, 0xC6 },
{ 0x00, 0xC7, 0xC7, 0xC7 },
{ 0x00, 0xC8, 0xC8, 0xC8 },
{ 0x00, 0xC9, 0xC9, 0xC9 },
{ 0x00, 0xCA, 0xCA, 0xCA },
{ 0x00, 0xCB, 0xCB, 0xCB },
{ 0x00, 0xCC, 0xCC, 0xCC },
{ 0x00, 0xCD, 0xCD, 0xCD },
{ 0x00, 0xCE, 0xCE, 0xCE },
{ 0x00, 0xCF, 0xCF, 0xCF },
{ 0x00, 0xD0, 0xD0, 0xD0 },
{ 0x00, 0xD1, 0xD1, 0xD1 },
{ 0x00, 0xD2, 0xD2, 0xD2 },
{ 0x00, 0xD3, 0xD3, 0xD3 },
{ 0x00, 0xD4, 0xD4, 0xD4 },
{ 0x00, 0xD5, 0xD5, 0xD5 },
{ 0x00, 0xD6, 0xD6, 0xD6 },
{ 0x00, 0xD7, 0xD7, 0xD7 },
{ 0x00, 0xD8, 0xD8, 0xD8 },
{ 0x00, 0xD9, 0xD9, 0xD9 },
{ 0x00, 0xDA, 0xDA, 0xDA },
{ 0x00, 0xDB, 0xDB, 0xDB },
{ 0x00, 0xDC, 0xDC, 0xDC },
{ 0x00, 0xDD, 0xDD, 0xDD },
{ 0x00, 0xDE, 0xDE, 0xDE },
{ 0x00, 0xDF, 0xDF, 0xDF },
{ 0x00, 0xE0, 0xE0, 0xE0 },
{ 0x00, 0xE1, 0xE1, 0xE1 },
{ 0x00, 0xE2, 0xE2, 0xE2 },
{ 0x00, 0xE3, 0xE3, 0xE3 },
{ 0x00, 0xE4, 0xE4, 0xE4 },
{ 0x00, 0xE5, 0xE5, 0xE5 },
{ 0x00, 0xE6, 0xE6, 0xE6 },
{ 0x00, 0xE7, 0xE7, 0xE7 },
{ 0x00, 0xE8, 0xE8, 0xE8 },
{ 0x00, 0xE9, 0xE9, 0xE9 },
{ 0x00, 0xEA, 0xEA, 0xEA },
{ 0x00, 0xEB, 0xEB, 0xEB },
{ 0x00, 0xEC, 0xEC, 0xEC },
{ 0x00, 0xED, 0xED, 0xED },
{ 0x00, 0xEE, 0xEE, 0xEE },
{ 0x00, 0xEF, 0xEF, 0xEF },
{ 0x00, 0xF0, 0xF0, 0xF0 },
{ 0x00, 0xF1, 0xF1, 0xF1 },
{ 0x00, 0xF2, 0xF2, 0xF2 },
{ 0x00, 0xF3, 0xF3, 0xF3 },
{ 0x00, 0xF4, 0xF4, 0xF4 },
{ 0x00, 0xF5, 0xF5, 0xF5 },
{ 0x00, 0xF6, 0xF6, 0xF6 },
{ 0x00, 0xF7, 0xF7, 0xF7 },
{ 0x00, 0xF8, 0xF8, 0xF8 },
{ 0x00, 0xF9, 0xF9, 0xF9 },
{ 0x00, 0xFA, 0xFA, 0xFA },
{ 0x00, 0xFB, 0xFB, 0xFB },
{ 0x00, 0xFC, 0xFC, 0xFC },
{ 0x00, 0xFD, 0xFD, 0xFD },
{ 0x00, 0xFE, 0xFE, 0xFE },
{ 0x00, 0xFF, 0xFF, 0xFF }
};
extern const struct _PDCLIB_charcodec_t _PDCLIB_ascii_codec;
struct _PDCLIB_locale _PDCLIB_global_locale = {
._Codec = &_PDCLIB_ascii_codec,
._Conv = {
/* decimal_point */ (char *)".",
/* thousands_sep */ (char *)"",
/* grouping */ (char *)"",
/* mon_decimal_point */ (char *)"",
/* mon_thousands_sep */ (char *)"",
/* mon_grouping */ (char *)"",
/* positive_sign */ (char *)"",
/* negative_sign */ (char *)"",
/* currency_symbol */ (char *)"",
/* int_curr_symbol */ (char *)"",
/* frac_digits */ CHAR_MAX,
/* p_cs_precedes */ CHAR_MAX,
/* n_cs_precedes */ CHAR_MAX,
/* p_sep_by_space */ CHAR_MAX,
/* n_sep_by_space */ CHAR_MAX,
/* p_sign_posn */ CHAR_MAX,
/* n_sign_posn */ CHAR_MAX,
/* int_frac_digits */ CHAR_MAX,
/* int_p_cs_precedes */ CHAR_MAX,
/* int_n_cs_precedes */ CHAR_MAX,
/* int_p_sep_by_space */ CHAR_MAX,
/* int_n_sep_by_space */ CHAR_MAX,
/* int_p_sign_posn */ CHAR_MAX,
/* int_n_sign_posn */ CHAR_MAX,
},
._CType = &global_ctype[1],
._ErrnoStr = {
"Success",
"EPERM (operation not permitted)",
"ENOENT (no such file or directory)",
"ESRCH (no such process)",
"EINTR (interrupted)",
"EIO (io error)",
"ENXIO (no such device or address)",
"E2BIG (argument list too long)",
"ENOEXEC (executable format error)",
"EBADF (bad file descriptor)",
"ECHILD (no child process)",
"EAGAIN (resource unavailable try again)",
"ENOMEM (not enough memory)",
"EACCES (permission denied)",
"EFAULT (bad address)",
"Unknown error",
"EBUSY (device or resource busy)",
"EEXIST (file exists)",
"EXDEV (cross device link)",
"ENODEV (no such device)",
"ENOTDIR (not a directory)",
"EISDIR (is a directory)",
"EINVAL (invalid argument)",
"ENFILE (too many files open in system)",
"EMFILE (too many files open)",
"ENOTTY (inappropriate io control operation)",
"ETXTBSY (text file busy)",
"EFBIG (file too large)",
"ENOSPC (no space on device)",
"ESPIPE (invalid seek)",
"EROFS (read only file system)",
"EMLINK (too many links)",
"EPIPE (broken pipe)",
"EDOM (argument out of domain)",
"ERANGE (result out of range)",
"EDEADLK (resource deadlock would occur)",
"ENAMETOOLONG (filename too long)",
"ENOLCK (no lock available)",
"ENOSYS (function not supported)",
"ENOTEMPTY (directory not empty)",
"ELOOP (too many symbolic link levels)",
"Unknown error",
"ENOMSG (no message)",
"EIDRM (identifier removed)",
"Unknown error",
"Unknown error",
"Unknown error",
"Unknown error",
"Unknown error",
"Unknown error",
"Unknown error",
"Unknown error",
"Unknown error",
"Unknown error",
"Unknown error",
"Unknown error",
"Unknown error",
"Unknown error",
"Unknown error",
"Unknown error",
"ENOSTR (not a stream)",
"ENODATA (no message available)",
"ETIME (stream timeout)",
"ENOSR (no stream resources)",
"Unknown error",
"Unknown error",
"Unknown error",
"ENOLINK (no link)",
"Unknown error",
"Unknown error",
"Unknown error",
"EPROTO (protocol error)",
"Unknown error",
"Unknown error",
"EBADMSG (bad message)",
"EOVERFLOW (value too large)",
"Unknown error",
"Unknown error",
"Unknown error",
"Unknown error",
"Unknown error",
"Unknown error",
"Unknown error",
"Unknown error",
"EILSEQ (illegal byte sequence)",
"Unknown error",
"Unknown error",
"Unknown error",
"ENOTSOCK (not a socket)",
"EDESTADDRREQ (destination address required)",
"EMSGSIZE (message size)",
"EPROTOTYPE (wrong protocol type)",
"ENOPROTOOPT (no protocol option)",
"EPROTONOSUPPORT (protocol not supported)",
"Unknown error",
"ENOTSUP (not supported)",
"Unknown error",
"EAFNOSUPPORT (address family not supported)",
"EADDRINUSE (address in use)",
"EADDRNOTAVAIL (address not available)",
"ENETDOWN (network down)",
"ENETUNREACH (network unreachable)",
"ENETRESET (network reset)",
"ECONNABORTED (connection aborted)",
"ECONNRESET (connection reset)",
"ENOBUFS (no buffer space)",
"EISCONN (already connected)",
"ENOTCONN (not connected)",
"Unknown error",
"Unknown error",
"ETIMEDOUT (timed out)",
"ECONNREFUSED (connection refused)",
"Unknown error",
"EHOSTUNREACH (host unreachable)",
"EALREADY (connection already in progress)",
"EINPROGRESS (operation in progress)",
"Unknown error",
"Unknown error",
"Unknown error",
"Unknown error",
"Unknown error",
"Unknown error",
"Unknown error",
"Unknown error",
"Unknown error",
"ECANCELED (operation canceled)",
"Unknown error",
"Unknown error",
"Unknown error",
"Unknown error",
"EOWNERDEAD (owner dead)",
"ENOTRECOVERABLE (state not recoverable)",
},
};
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
/* Testing covered by several other testdrivers using stdin / stdout /
stderr.
*/
return TEST_RESULTS;
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,50 +0,0 @@
#include "_PDCLIB_glue.h"
#include <threads.h>
#undef WIN32
#undef _WIN32
#define DLMALLOC_EXPORT _PDCLIB_API
#define MALLOC_ALIGNMENT _PDCLIB_MALLOC_ALIGN
#define MSPACES 0
#define USE_LOCKS 0
#define USE_SPIN_LOCKS 0
#define USE_RECURSIVE_LOCKS 0
#undef NEED_GLOBAL_LOCK_INIT
#define FOOTERS 0
#undef USE_DL_PREFIX
#define MALLOC_INSPECT_ALL 0
#define ABORT abort()
#define PROCEED_ON_ERROR 0
#define DEBUG 0
#define ABORT_ON_ASSERT_FAILURE 1
#define MALLOC_FAILURE_ACTION errno = ENOMEM
#define HAVE_MORECORE 1
#define MORECORE _PDCLIB_sbrk
#define MORECORE_CONTIGUOUS 1
#define MORECORE_CANNOT_TRIM 1
#define NO_SEGMENT_TRAVERSAL 0
#define HAVE_MMAP 0
#define HAVE_MREMAP 0
#define USE_BUILTIN_FFS 0
#define malloc_getpagesize _PDCLIB_MALLOC_PAGESIZE
#define USE_DEV_RANDOM 0
#define NO_MALLINFO 1
#define MALLINFO_FIELD_TYPE size_t
#define NO_MALLOC_STATS 1
#define DEFAULT_GRANULARITY _PDCLIB_MALLOC_GRANULARITY
#define DEFAULT_TRIM_THRESHOLD _PDCLIB_MALLOC_TRIM_THRESHOLD
#define DEFAULT_MMAP_THREHOLD _PDCLIB_MALLOC_MMAP_THRESHOLD
#define MAX_RELEASE_CHECK_RATE _PDCLIB_MALLOC_RELEASE_CHECK_RATE
/* C standard says this is so */
#define REALLOC_ZERO_BYTES_FREES 1
#define LACKS_UNISTD_H
#define LACKS_FCNTL_H
#define LACKS_SYS_PARAM_H
#define LACKS_SYS_MMAN_H
#define LACKS_STRINGS_H
#define LACKS_SYS_TYPES_H
#define LACKS_SCHED_H
#include <stdlib.h>
#include <errno.h>

View File

@ -1,36 +0,0 @@
/* isalnum( int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <ctype.h>
#ifndef REGTEST
#include "_PDCLIB_locale.h"
int isalnum( int c )
{
return ( _PDCLIB_threadlocale()->_CType[c].flags & ( _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_DIGIT ) );
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
TESTCASE( isalnum( 'a' ) );
TESTCASE( isalnum( 'z' ) );
TESTCASE( isalnum( 'A' ) );
TESTCASE( isalnum( 'Z' ) );
TESTCASE( isalnum( '0' ) );
TESTCASE( isalnum( '9' ) );
TESTCASE( ! isalnum( ' ' ) );
TESTCASE( ! isalnum( '\n' ) );
TESTCASE( ! isalnum( '@' ) );
return TEST_RESULTS;
}
#endif

View File

@ -1,32 +0,0 @@
/* isalpha( int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <ctype.h>
#ifndef REGTEST
#include "_PDCLIB_locale.h"
int isalpha( int c )
{
return ( _PDCLIB_threadlocale()->_CType[c].flags & _PDCLIB_CTYPE_ALPHA );
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
TESTCASE( isalpha( 'a' ) );
TESTCASE( isalpha( 'z' ) );
TESTCASE( ! isalpha( ' ' ) );
TESTCASE( ! isalpha( '1' ) );
TESTCASE( ! isalpha( '@' ) );
return TEST_RESULTS;
}
#endif

View File

@ -1,6 +0,0 @@
#include <ctype.h>
int isascii(int c)
{
return (unsigned)c < 128;
}

View File

@ -1,33 +0,0 @@
/* isblank( int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <ctype.h>
#ifndef REGTEST
#include "_PDCLIB_locale.h"
int isblank( int c )
{
return ( _PDCLIB_threadlocale()->_CType[c].flags & _PDCLIB_CTYPE_BLANK );
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
TESTCASE( isblank( ' ' ) );
TESTCASE( isblank( '\t' ) );
TESTCASE( ! isblank( '\v' ) );
TESTCASE( ! isblank( '\r' ) );
TESTCASE( ! isblank( 'x' ) );
TESTCASE( ! isblank( '@' ) );
return TEST_RESULTS;
}
#endif

View File

@ -1,31 +0,0 @@
/* iscntrl( int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <ctype.h>
#ifndef REGTEST
#include "_PDCLIB_locale.h"
int iscntrl( int c )
{
return ( _PDCLIB_threadlocale()->_CType[c].flags & _PDCLIB_CTYPE_CNTRL );
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
TESTCASE( iscntrl( '\a' ) );
TESTCASE( iscntrl( '\b' ) );
TESTCASE( iscntrl( '\n' ) );
TESTCASE( ! iscntrl( ' ' ) );
return TEST_RESULTS;
}
#endif

View File

@ -1,32 +0,0 @@
/* isdigit( int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <ctype.h>
#ifndef REGTEST
#include "_PDCLIB_locale.h"
int isdigit( int c )
{
return ( _PDCLIB_threadlocale()->_CType[c].flags & _PDCLIB_CTYPE_DIGIT );
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
TESTCASE( isdigit( '0' ) );
TESTCASE( isdigit( '9' ) );
TESTCASE( ! isdigit( ' ' ) );
TESTCASE( ! isdigit( 'a' ) );
TESTCASE( ! isdigit( '@' ) );
return TEST_RESULTS;
}
#endif

View File

@ -1,35 +0,0 @@
/* isgraph( int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <ctype.h>
#ifndef REGTEST
#include "_PDCLIB_locale.h"
int isgraph( int c )
{
return ( _PDCLIB_threadlocale()->_CType[c].flags & _PDCLIB_CTYPE_GRAPH );
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
TESTCASE( isgraph( 'a' ) );
TESTCASE( isgraph( 'z' ) );
TESTCASE( isgraph( 'A' ) );
TESTCASE( isgraph( 'Z' ) );
TESTCASE( isgraph( '@' ) );
TESTCASE( ! isgraph( '\t' ) );
TESTCASE( ! isgraph( '\0' ) );
TESTCASE( ! isgraph( ' ' ) );
return TEST_RESULTS;
}
#endif

View File

@ -1,33 +0,0 @@
/* islower( int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <ctype.h>
#ifndef REGTEST
#include "_PDCLIB_locale.h"
int islower( int c )
{
return ( _PDCLIB_threadlocale()->_CType[c].flags & _PDCLIB_CTYPE_LOWER );
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
TESTCASE( islower( 'a' ) );
TESTCASE( islower( 'z' ) );
TESTCASE( ! islower( 'A' ) );
TESTCASE( ! islower( 'Z' ) );
TESTCASE( ! islower( ' ' ) );
TESTCASE( ! islower( '@' ) );
return TEST_RESULTS;
}
#endif

View File

@ -1,35 +0,0 @@
/* isprint( int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <ctype.h>
#ifndef REGTEST
#include "_PDCLIB_locale.h"
int isprint( int c )
{
return ( _PDCLIB_threadlocale()->_CType[c].flags & _PDCLIB_CTYPE_GRAPH ) || ( c == ' ' );
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
TESTCASE( isprint( 'a' ) );
TESTCASE( isprint( 'z' ) );
TESTCASE( isprint( 'A' ) );
TESTCASE( isprint( 'Z' ) );
TESTCASE( isprint( '@' ) );
TESTCASE( ! isprint( '\t' ) );
TESTCASE( ! isprint( '\0' ) );
TESTCASE( isprint( ' ' ) );
return TEST_RESULTS;
}
#endif

View File

@ -1,36 +0,0 @@
/* ispunct( int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <ctype.h>
#ifndef REGTEST
#include "_PDCLIB_locale.h"
int ispunct( int c )
{
return ( _PDCLIB_threadlocale()->_CType[c].flags & _PDCLIB_CTYPE_PUNCT );
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
TESTCASE( ! ispunct( 'a' ) );
TESTCASE( ! ispunct( 'z' ) );
TESTCASE( ! ispunct( 'A' ) );
TESTCASE( ! ispunct( 'Z' ) );
TESTCASE( ispunct( '@' ) );
TESTCASE( ispunct( '.' ) );
TESTCASE( ! ispunct( '\t' ) );
TESTCASE( ! ispunct( '\0' ) );
TESTCASE( ! ispunct( ' ' ) );
return TEST_RESULTS;
}
#endif

View File

@ -1,34 +0,0 @@
/* isspace( int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <ctype.h>
#ifndef REGTEST
#include "_PDCLIB_locale.h"
int isspace( int c )
{
return ( _PDCLIB_threadlocale()->_CType[c].flags & _PDCLIB_CTYPE_SPACE );
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
TESTCASE( isspace( ' ' ) );
TESTCASE( isspace( '\f' ) );
TESTCASE( isspace( '\n' ) );
TESTCASE( isspace( '\r' ) );
TESTCASE( isspace( '\t' ) );
TESTCASE( isspace( '\v' ) );
TESTCASE( ! isspace( 'a' ) );
return TEST_RESULTS;
}
#endif

View File

@ -1,33 +0,0 @@
/* isupper( int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <ctype.h>
#ifndef REGTEST
#include "_PDCLIB_locale.h"
int isupper( int c )
{
return ( _PDCLIB_threadlocale()->_CType[c].flags & _PDCLIB_CTYPE_UPPER );
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
TESTCASE( isupper( 'A' ) );
TESTCASE( isupper( 'Z' ) );
TESTCASE( ! isupper( 'a' ) );
TESTCASE( ! isupper( 'z' ) );
TESTCASE( ! isupper( ' ' ) );
TESTCASE( ! isupper( '@' ) );
return TEST_RESULTS;
}
#endif

View File

@ -1,37 +0,0 @@
/* isxdigit( int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <ctype.h>
#ifndef REGTEST
#include "_PDCLIB_locale.h"
int isxdigit( int c )
{
return ( _PDCLIB_threadlocale()->_CType[c].flags & _PDCLIB_CTYPE_XDIGT );
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
TESTCASE( isxdigit( '0' ) );
TESTCASE( isxdigit( '9' ) );
TESTCASE( isxdigit( 'a' ) );
TESTCASE( isxdigit( 'f' ) );
TESTCASE( ! isxdigit( 'g' ) );
TESTCASE( isxdigit( 'A' ) );
TESTCASE( isxdigit( 'F' ) );
TESTCASE( ! isxdigit( 'G' ) );
TESTCASE( ! isxdigit( '@' ) );
TESTCASE( ! isxdigit( ' ' ) );
return TEST_RESULTS;
}
#endif

View File

@ -1,32 +0,0 @@
/* tolower( int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <ctype.h>
#ifndef REGTEST
#include "_PDCLIB_locale.h"
int tolower( int c )
{
return _PDCLIB_threadlocale()->_CType[c].lower;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
TESTCASE( tolower( 'A' ) == 'a' );
TESTCASE( tolower( 'Z' ) == 'z' );
TESTCASE( tolower( 'a' ) == 'a' );
TESTCASE( tolower( 'z' ) == 'z' );
TESTCASE( tolower( '@' ) == '@' );
TESTCASE( tolower( '[' ) == '[' );
return TEST_RESULTS;
}
#endif

View File

@ -1,32 +0,0 @@
/* toupper( int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <ctype.h>
#ifndef REGTEST
#include "_PDCLIB_locale.h"
int toupper( int c )
{
return _PDCLIB_threadlocale()->_CType[c].upper;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
TESTCASE( toupper( 'a' ) == 'A' );
TESTCASE( toupper( 'z' ) == 'Z' );
TESTCASE( toupper( 'A' ) == 'A' );
TESTCASE( toupper( 'Z' ) == 'Z' );
TESTCASE( toupper( '@' ) == '@' );
TESTCASE( toupper( '[' ) == '[' );
return TEST_RESULTS;
}
#endif

View File

@ -1,37 +0,0 @@
/* _PDCLIB_errno
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <errno.h>
#ifndef REGTEST
#include <threads.h>
/* Temporary */
static int _PDCLIB_errno = 0;
int * _PDCLIB_errno_func()
{
return &_PDCLIB_errno;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
errno = 0;
TESTCASE( errno == 0 );
errno = EDOM;
TESTCASE( errno == EDOM );
errno = ERANGE;
TESTCASE( errno == ERANGE );
return TEST_RESULTS;
}
#endif

View File

@ -1,30 +0,0 @@
/* imaxabs( intmax_t )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <inttypes.h>
#ifndef REGTEST
intmax_t imaxabs( intmax_t j )
{
return ( j >= 0 ) ? j : -j;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
#include <limits.h>
int main( void )
{
TESTCASE( imaxabs( (intmax_t)0 ) == 0 );
TESTCASE( imaxabs( INTMAX_MAX ) == INTMAX_MAX );
TESTCASE( imaxabs( INTMAX_MIN + 1 ) == -( INTMAX_MIN + 1 ) );
return TEST_RESULTS;
}
#endif

View File

@ -1,38 +0,0 @@
/* lldiv( long long int, long long int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <inttypes.h>
#ifndef REGTEST
imaxdiv_t imaxdiv( intmax_t numer, intmax_t denom )
{
imaxdiv_t rc;
rc.quot = numer / denom;
rc.rem = numer % denom;
return rc;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
imaxdiv_t result;
result = imaxdiv( (intmax_t)5, (intmax_t)2 );
TESTCASE( result.quot == 2 && result.rem == 1 );
result = imaxdiv( (intmax_t)-5, (intmax_t)2 );
TESTCASE( result.quot == -2 && result.rem == -1 );
result = imaxdiv( (intmax_t)5, (intmax_t)-2 );
TESTCASE( result.quot == -2 && result.rem == 1 );
TESTCASE( sizeof( result.quot ) == sizeof( intmax_t ) );
TESTCASE( sizeof( result.rem ) == sizeof( intmax_t ) );
return TEST_RESULTS;
}
#endif

View File

@ -1,146 +0,0 @@
/* strtoimax( const char *, char * *, int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <limits.h>
#include <inttypes.h>
#ifndef REGTEST
#include <stddef.h>
intmax_t strtoimax( const char * _PDCLIB_restrict nptr, char ** _PDCLIB_restrict endptr, int base )
{
intmax_t rc;
char sign = '+';
const char * p = _PDCLIB_strtox_prelim( nptr, &sign, &base );
if ( base < 2 || base > 36 ) return 0;
if ( sign == '+' )
{
rc = (intmax_t)_PDCLIB_strtox_main( &p, (unsigned)base, (uintmax_t)INTMAX_MAX, (uintmax_t)( INTMAX_MAX / base ), (int)( INTMAX_MAX % base ), &sign );
}
else
{
rc = (intmax_t)_PDCLIB_strtox_main( &p, (unsigned)base, (uintmax_t)INTMAX_MIN, (uintmax_t)( INTMAX_MIN / -base ), (int)( -( INTMAX_MIN % base ) ), &sign );
}
if ( endptr != NULL ) *endptr = ( p != NULL ) ? (char *) p : (char *) nptr;
return ( sign == '+' ) ? rc : -rc;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
#include <errno.h>
int main( void )
{
char * endptr;
/* this, to base 36, overflows even a 256 bit integer */
char overflow[] = "-ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ_";
/* tricky border case */
char tricky[] = "+0xz";
errno = 0;
/* basic functionality */
TESTCASE( strtoimax( "123", NULL, 10 ) == 123 );
/* proper detecting of default base 10 */
TESTCASE( strtoimax( "456", NULL, 0 ) == 456 );
/* proper functioning to smaller base */
TESTCASE( strtoimax( "14", NULL, 8 ) == 12 );
/* proper autodetecting of octal */
TESTCASE( strtoimax( "016", NULL, 0 ) == 14 );
/* proper autodetecting of hexadecimal, lowercase 'x' */
TESTCASE( strtoimax( "0xFF", NULL, 0 ) == 255 );
/* proper autodetecting of hexadecimal, uppercase 'X' */
TESTCASE( strtoimax( "0Xa1", NULL, 0 ) == 161 );
/* proper handling of border case: 0x followed by non-hexdigit */
TESTCASE( strtoimax( tricky, &endptr, 0 ) == 0 );
TESTCASE( endptr == tricky + 2 );
/* proper handling of border case: 0 followed by non-octdigit */
TESTCASE( strtoimax( tricky, &endptr, 8 ) == 0 );
TESTCASE( endptr == tricky + 2 );
/* errno should still be 0 */
TESTCASE( errno == 0 );
/* overflowing subject sequence must still return proper endptr */
TESTCASE( strtoimax( overflow, &endptr, 36 ) == INTMAX_MIN );
TESTCASE( errno == ERANGE );
TESTCASE( ( endptr - overflow ) == 53 );
/* same for positive */
errno = 0;
TESTCASE( strtoimax( overflow + 1, &endptr, 36 ) == INTMAX_MAX );
TESTCASE( errno == ERANGE );
TESTCASE( ( endptr - overflow ) == 53 );
/* testing skipping of leading whitespace */
TESTCASE( strtoimax( " \n\v\t\f789", NULL, 0 ) == 789 );
/* testing conversion failure */
TESTCASE( strtoimax( overflow, &endptr, 10 ) == 0 );
TESTCASE( endptr == overflow );
endptr = NULL;
TESTCASE( strtoimax( overflow, &endptr, 0 ) == 0 );
TESTCASE( endptr == overflow );
/* These tests assume two-complement, but conversion should work for */
/* one-complement and signed magnitude just as well. Anyone having a */
/* platform to test this on? */
errno = 0;
#if INTMAX_MAX >> 62 == 1
/* testing "odd" overflow, i.e. base is not a power of two */
TESTCASE( strtoimax( "9223372036854775807", NULL, 0 ) == INTMAX_MAX );
TESTCASE( errno == 0 );
TESTCASE( strtoimax( "9223372036854775808", NULL, 0 ) == INTMAX_MAX );
TESTCASE( errno == ERANGE );
errno = 0;
TESTCASE( strtoimax( "-9223372036854775807", NULL, 0 ) == (INTMAX_MIN + 1) );
TESTCASE( errno == 0 );
TESTCASE( strtoimax( "-9223372036854775808", NULL, 0 ) == INTMAX_MIN );
TESTCASE( errno == 0 );
TESTCASE( strtoimax( "-9223372036854775809", NULL, 0 ) == INTMAX_MIN );
TESTCASE( errno == ERANGE );
/* testing "even" overflow, i.e. base is power of two */
errno = 0;
TESTCASE( strtoimax( "0x7fffffffffffffff", NULL, 0 ) == INTMAX_MAX );
TESTCASE( errno == 0 );
TESTCASE( strtoimax( "0x8000000000000000", NULL, 0 ) == INTMAX_MAX );
TESTCASE( errno == ERANGE );
errno = 0;
TESTCASE( strtoimax( "-0x7fffffffffffffff", NULL, 0 ) == (INTMAX_MIN + 1) );
TESTCASE( errno == 0 );
TESTCASE( strtoimax( "-0x8000000000000000", NULL, 0 ) == INTMAX_MIN );
TESTCASE( errno == 0 );
TESTCASE( strtoimax( "-0x8000000000000001", NULL, 0 ) == INTMAX_MIN );
TESTCASE( errno == ERANGE );
#elif LLONG_MAX >> 126 == 1
/* testing "odd" overflow, i.e. base is not a power of two */
TESTCASE( strtoimax( "170141183460469231731687303715884105728", NULL, 0 ) == INTMAX_MAX );
TESTCASE( errno == 0 );
TESTCASE( strtoimax( "170141183460469231731687303715884105729", NULL, 0 ) == INTMAX_MAX );
TESTCASE( errno == ERANGE );
errno = 0;
TESTCASE( strtoimax( "-170141183460469231731687303715884105728", NULL, 0 ) == (INTMAX_MIN + 1) );
TESTCASE( errno == 0 );
TESTCASE( strtoimax( "-170141183460469231731687303715884105729", NULL, 0 ) == INTMAX_MIN );
TESTCASE( errno == 0 );
TESTCASE( strtoimax( "-170141183460469231731687303715884105730", NULL, 0 ) == INTMAX_MIN );
TESTCASE( errno == ERANGE );
/* testing "even" overflow, i.e. base is power of two */
errno = 0;
TESTCASE( strtoimax( "0x7fffffffffffffffffffffffffffffff", NULL, 0 ) == INTMAX_MAX );
TESTCASE( errno == 0 );
TESTCASE( strtoimax( "0x80000000000000000000000000000000", NULL, 0 ) == INTMAX_MAX );
TESTCASE( errno == ERANGE );
errno = 0;
TESTCASE( strtoimax( "-0x7fffffffffffffffffffffffffffffff", NULL, 0 ) == (INTMAX_MIN + 1) );
TESTCASE( errno == 0 );
TESTCASE( strtoimax( "-0x80000000000000000000000000000000", NULL, 0 ) == INTMAX_MIN );
TESTCASE( errno == 0 );
TESTCASE( strtoimax( "-0x80000000000000000000000000000001", NULL, 0 ) == INTMAX_MIN );
TESTCASE( errno == ERANGE );
#else
#error Unsupported width of 'intmax_t' (neither 64 nor 128 bit).
#endif
return TEST_RESULTS;
}
#endif

View File

@ -1,109 +0,0 @@
/* strtoumax( const char *, char * *, int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <limits.h>
#include <inttypes.h>
#ifndef REGTEST
#include <stddef.h>
uintmax_t strtoumax( const char * _PDCLIB_restrict nptr, char ** _PDCLIB_restrict endptr, int base )
{
uintmax_t rc;
char sign = '+';
const char * p = _PDCLIB_strtox_prelim( nptr, &sign, &base );
if ( base < 2 || base > 36 ) return 0;
rc = _PDCLIB_strtox_main( &p, (unsigned)base, (uintmax_t)UINTMAX_MAX, (uintmax_t)( UINTMAX_MAX / base ), (int)( UINTMAX_MAX % base ), &sign );
if ( endptr != NULL ) *endptr = ( p != NULL ) ? (char *) p : (char *) nptr;
return ( sign == '+' ) ? rc : -rc;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
#include <errno.h>
int main( void )
{
char * endptr;
/* this, to base 36, overflows even a 256 bit integer */
char overflow[] = "-ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ_";
/* tricky border case */
char tricky[] = "+0xz";
errno = 0;
/* basic functionality */
TESTCASE( strtoumax( "123", NULL, 10 ) == 123 );
/* proper detecting of default base 10 */
TESTCASE( strtoumax( "456", NULL, 0 ) == 456 );
/* proper functioning to smaller base */
TESTCASE( strtoumax( "14", NULL, 8 ) == 12 );
/* proper autodetecting of octal */
TESTCASE( strtoumax( "016", NULL, 0 ) == 14 );
/* proper autodetecting of hexadecimal, lowercase 'x' */
TESTCASE( strtoumax( "0xFF", NULL, 0 ) == 255 );
/* proper autodetecting of hexadecimal, uppercase 'X' */
TESTCASE( strtoumax( "0Xa1", NULL, 0 ) == 161 );
/* proper handling of border case: 0x followed by non-hexdigit */
TESTCASE( strtoumax( tricky, &endptr, 0 ) == 0 );
TESTCASE( endptr == tricky + 2 );
/* proper handling of border case: 0 followed by non-octdigit */
TESTCASE( strtoumax( tricky, &endptr, 8 ) == 0 );
TESTCASE( endptr == tricky + 2 );
/* errno should still be 0 */
TESTCASE( errno == 0 );
/* overflowing subject sequence must still return proper endptr */
TESTCASE( strtoumax( overflow, &endptr, 36 ) == UINTMAX_MAX );
TESTCASE( errno == ERANGE );
TESTCASE( ( endptr - overflow ) == 53 );
/* same for positive */
errno = 0;
TESTCASE( strtoumax( overflow + 1, &endptr, 36 ) == UINTMAX_MAX );
TESTCASE( errno == ERANGE );
TESTCASE( ( endptr - overflow ) == 53 );
/* testing skipping of leading whitespace */
TESTCASE( strtoumax( " \n\v\t\f789", NULL, 0 ) == 789 );
/* testing conversion failure */
TESTCASE( strtoumax( overflow, &endptr, 10 ) == 0 );
TESTCASE( endptr == overflow );
endptr = NULL;
TESTCASE( strtoumax( overflow, &endptr, 0 ) == 0 );
TESTCASE( endptr == overflow );
errno = 0;
/* uintmax_t -> long long -> 64 bit */
#if UINTMAX_MAX >> 63 == 1
/* testing "odd" overflow, i.e. base is not power of two */
TESTCASE( strtoumax( "18446744073709551615", NULL, 0 ) == UINTMAX_MAX );
TESTCASE( errno == 0 );
TESTCASE( strtoumax( "18446744073709551616", NULL, 0 ) == UINTMAX_MAX );
TESTCASE( errno == ERANGE );
/* testing "even" overflow, i.e. base is power of two */
errno = 0;
TESTCASE( strtoumax( "0xFFFFFFFFFFFFFFFF", NULL, 0 ) == UINTMAX_MAX );
TESTCASE( errno == 0 );
TESTCASE( strtoumax( "0x10000000000000000", NULL, 0 ) == UINTMAX_MAX );
TESTCASE( errno == ERANGE );
/* uintmax_t -> long long -> 128 bit */
#elif UINTMAX_MAX >> 127 == 1
/* testing "odd" overflow, i.e. base is not power of two */
TESTCASE( strtoumax( "340282366920938463463374607431768211455", NULL, 0 ) == UINTMAX_MAX );
TESTCASE( errno == 0 );
TESTCASE( strtoumax( "340282366920938463463374607431768211456", NULL, 0 ) == UINTMAX_MAX );
TESTCASE( errno == ERANGE );
/* testing "even" everflow, i.e. base is power of two */
errno = 0;
TESTCASE( strtoumax( "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", NULL, 0 ) == UINTMAX_MAX );
TESTCASE( errno == 0 );
TESTCASE( strtoumax( "0x100000000000000000000000000000000", NULL, 0 ) == UINTMAX_MAX );
TESTCASE( errno == ERANGE );
#else
#error Unsupported width of 'uintmax_t' (neither 64 nor 128 bit).
#endif
return TEST_RESULTS;
}
#endif

View File

@ -1,194 +0,0 @@
#!/usr/bin/python
# -*- coding: ascii -*-
# Unicode Data Converter
#
# This file is part of the Public Domain C Library (PDCLib).
# Permission is granted to use, modify, and / or redistribute at will.
"""
Converts the character information provdied by Unicode in the UnicodeData.txt
file from the Unicode character database into a table for use by PDCLib.
Usage: Download the UnicodeData.txt file to the same directory as this script
and then run it. Both Python 2 and 3 are supported.
Download the data from
ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
We do some simple "run" compression, because characters in the Unicode Data file
tend to come in groups with the same properties.
"""
import os
# MUST BE KEPT SYNCHRONIZED WITH _PDCLIB_locale.h
BIT_ALPHA = 1
BIT_BLANK = 2
BIT_CNTRL = 4
BIT_GRAPH = 8
BIT_PUNCT = 16
BIT_SPACE = 32
BIT_LOWER = 64
BIT_UPPER = 128
BIT_DIGIT = 256
BIT_XDIGT = 512
# Category to bitfield mapping
categories = {
'Lu': BIT_ALPHA | BIT_GRAPH | BIT_UPPER, # Uppercase
'Ll': BIT_ALPHA | BIT_GRAPH | BIT_LOWER, # Lowercase
'Lt': BIT_ALPHA | BIT_GRAPH | BIT_UPPER, # Title case. Upper?
'Lm': BIT_ALPHA | BIT_GRAPH, # Modifier. Case?
'Lo': BIT_ALPHA | BIT_GRAPH, # "Other" letter (e.g. Ideograph)
'Nd': BIT_DIGIT | BIT_GRAPH, # Decimal digit
'Nl': BIT_GRAPH, # Letter-like numeric character
'No': BIT_GRAPH, # Other numeric
'Pc': BIT_PUNCT | BIT_GRAPH, # Connecting punctuation
'Pd': BIT_PUNCT | BIT_GRAPH, # Dash punctuation
'Ps': BIT_PUNCT | BIT_GRAPH, # Opening punctuation
'Pe': BIT_PUNCT | BIT_GRAPH, # Closing punctuation
'Pi': BIT_PUNCT | BIT_GRAPH, # Opening quote
'Pf': BIT_PUNCT | BIT_GRAPH, # Closing quote
'Po': BIT_PUNCT | BIT_GRAPH, # Other punctuation
'Sm': BIT_GRAPH, # Mathematical symbol
'Sc': BIT_GRAPH, # Currency symbol
'Sk': BIT_GRAPH, # Non-letterlike modifier symbol
'So': BIT_GRAPH, # Other symbol
'Zs': BIT_SPACE, # Non-zero-width space character
'Zl': BIT_SPACE, # Line separator
'Zp': BIT_SPACE, # Paragraph separator
'Cc': BIT_CNTRL, # C0/C1 control codes
}
# Characters with special properties
special = {
# Blank characters
0x0020: BIT_SPACE | BIT_BLANK, # space
0x0009: BIT_SPACE | BIT_BLANK, # tab
# Digits
0x0030: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,
0x0031: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,
0x0032: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,
0x0033: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,
0x0034: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,
0x0035: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,
0x0036: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,
0x0037: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,
0x0038: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,
0x0039: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,
# A-F (hex uppercase)
0x0041: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_UPPER,
0x0042: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_UPPER,
0x0043: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_UPPER,
0x0044: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_UPPER,
0x0045: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_UPPER,
0x0046: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_UPPER,
# a-f (hex lowercase)
0x0061: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_LOWER,
0x0062: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_LOWER,
0x0063: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_LOWER,
0x0064: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_LOWER,
0x0065: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_LOWER,
0x0066: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_LOWER,
}
class Group:
def __init__(self, start, flags, upper_delta, lower_delta):
self.start = start
self.flags = flags
self.upper_delta = upper_delta
self.lower_delta = lower_delta
self.chars = []
def add_char(self, num, label):
self.chars.append((num, label))
def write_to_file(self, f):
for char in self.chars:
f.write("// %x %s\n" % char)
f.write(" { 0x%X, \t0x%X, \t0x%X, \t%d, \t%d },\n" %
(self.start, len(self.chars), self.flags, self.lower_delta, self.upper_delta))
def next(self):
return self.start + len(self.chars)
groups = []
def add_char(num, upper, lower, bits, label):
upper_delta = upper - num
lower_delta = lower - num
if len(groups) != 0:
cur = groups[-1]
if num == cur.next() and cur.flags == bits and \
cur.upper_delta == upper_delta and \
cur.lower_delta == lower_delta:
cur.add_char(num, label)
return
g = Group(num, bits, upper_delta, lower_delta)
g.add_char(num, label)
groups.append(g)
in_file = open('UnicodeData.txt', 'r')
out_file = open('_PDCLIB_unicodedata.c', 'w')
try:
for line in in_file:
(num_hex, name, category, combining_class, bidi_class, decomposition,
numeric_type, numeric_digit, numeric_value, mirrored, u1name, iso_com,
upper_case_hex, lower_case_hex, title_case_hex) = line.split(";")
num = int(num_hex, 16)
upper_case = int(upper_case_hex, 16) if len(upper_case_hex) else num
lower_case = int(lower_case_hex, 16) if len(lower_case_hex) else num
bits = special.get(num, categories.get(category, 0))
if upper_case == 0 and lower_case == 0 and bits == 0:
continue
add_char(num, upper_case, lower_case, bits, name)
out_file.write("""
/* Unicode Character Information ** AUTOMATICALLY GENERATED FILE **
*
* This file is part of the PDCLib public domain C Library, but is automatically
* generated from the Unicode character data information file found at
* ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
*
* As a result, the licensing that applies to that file also applies to this
* file. The licensing which applies to the Unicode character data can be found
* in Exhibit 1 of the Unicode Terms of Use, found at
* http://www.unicode.org/copyright.html#Exhibit1
*/
#ifndef REGTEST
#include <_PDCLIB_locale.h>
const _PDCLIB_wcinfo_t _PDCLIB_wcinfo[] = {
// { value, \tlength, \tflags,\tlower,\tupper\t}, // name
""")
for g in groups:
g.write_to_file(out_file)
out_file.write('};\n\n')
out_file.write("""
const size_t _PDCLIB_wcinfo_size = sizeof(_PDCLIB_wcinfo) / sizeof(_PDCLIB_wcinfo[0]);
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
return TEST_RESULTS;
}
#endif
""")
except:
in_file.close()
out_file.close()
os.remove('_PDCLIB_unicodedata.c')
raise
else:
in_file.close()
out_file.close()

View File

@ -1,27 +0,0 @@
/* _PDCLIB_mb_cur_max( void )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <locale.h>
#ifndef REGTEST
#include "_PDCLIB_locale.h"
#include "_PDCLIB_encoding.h"
size_t _PDCLIB_mb_cur_max( void )
{
return _PDCLIB_threadlocale()->_Codec->__mb_max;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
TESTCASE( NO_TESTDRIVER );
return TEST_RESULTS;
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +0,0 @@
#include <_PDCLIB_locale.h>
locale_t _PDCLIB_locale_fake;

View File

@ -1,29 +0,0 @@
/* freelocale( locale_t )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <locale.h>
#ifndef REGTEST
#include "_PDCLIB_locale.h"
#include <assert.h>
void freelocale( locale_t newloc )
{
if( newloc != NULL ) {
assert( ! "Not implemented" );
}
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
TESTCASE( NO_TESTDRIVER );
return TEST_RESULTS;
}
#endif

View File

@ -1,26 +0,0 @@
/* localeconv( void )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <locale.h>
#ifndef REGTEST
#include "_PDCLIB_locale.h"
struct lconv * localeconv( void )
{
return &_PDCLIB_threadlocale()->_Conv;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
TESTCASE( NO_TESTDRIVER );
return TEST_RESULTS;
}
#endif

View File

@ -1,26 +0,0 @@
/* setlocale( int, const char * )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <locale.h>
#ifndef REGTEST
#include "_PDCLIB_locale.h"
char * setlocale( int category, const char * locale )
{
return NULL;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
TESTCASE( NO_TESTDRIVER );
return TEST_RESULTS;
}
#endif

View File

@ -1,36 +0,0 @@
/* uselocale( locale_t )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <locale.h>
#ifndef REGTEST
#include "_PDCLIB_locale.h"
#ifdef _PDCLIB_LOCALE_METHOD
locale_t uselocale( locale_t newloc )
{
locale_t oldloc = _PDCLIB_threadlocale();
if(newloc == LC_GLOBAL_LOCALE) {
_PDCLIB_setthreadlocale(NULL);
} else if(newloc != NULL) {
_PDCLIB_setthreadlocale(newloc);
}
return oldloc;
}
#endif
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
TESTCASE( NO_TESTDRIVER );
return TEST_RESULTS;
}
#endif

View File

@ -1,71 +0,0 @@
/* origin: FreeBSD /usr/src/lib/msun/src/k_cos.c */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
* __cos( x, y )
* kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164
* Input x is assumed to be bounded by ~pi/4 in magnitude.
* Input y is the tail of x.
*
* Algorithm
* 1. Since cos(-x) = cos(x), we need only to consider positive x.
* 2. if x < 2^-27 (hx<0x3e400000 0), return 1 with inexact if x!=0.
* 3. cos(x) is approximated by a polynomial of degree 14 on
* [0,pi/4]
* 4 14
* cos(x) ~ 1 - x*x/2 + C1*x + ... + C6*x
* where the remez error is
*
* | 2 4 6 8 10 12 14 | -58
* |cos(x)-(1-.5*x +C1*x +C2*x +C3*x +C4*x +C5*x +C6*x )| <= 2
* | |
*
* 4 6 8 10 12 14
* 4. let r = C1*x +C2*x +C3*x +C4*x +C5*x +C6*x , then
* cos(x) ~ 1 - x*x/2 + r
* since cos(x+y) ~ cos(x) - sin(x)*y
* ~ cos(x) - x*y,
* a correction term is necessary in cos(x) and hence
* cos(x+y) = 1 - (x*x/2 - (r - x*y))
* For better accuracy, rearrange to
* cos(x+y) ~ w + (tmp + (r-x*y))
* where w = 1 - x*x/2 and tmp is a tiny correction term
* (1 - x*x/2 == w + tmp exactly in infinite precision).
* The exactness of w + tmp in infinite precision depends on w
* and tmp having the same precision as x. If they have extra
* precision due to compiler bugs, then the extra precision is
* only good provided it is retained in all terms of the final
* expression for cos(). Retention happens in all cases tested
* under FreeBSD, so don't pessimize things by forcibly clipping
* any extra precision in w.
*/
#include "libm.h"
static const double
C1 = 4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */
C2 = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */
C3 = 2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */
C4 = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */
C5 = 2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */
C6 = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */
double __cos(double x, double y)
{
double_t hz,z,r,w;
z = x*x;
w = z*z;
r = z*(C1+z*(C2+z*C3)) + w*w*(C4+z*(C5+z*C6));
hz = 0.5*z;
w = 1.0-hz;
return w + (((1.0-w)-hz) + (z*r-x*y));
}

View File

@ -1,35 +0,0 @@
/* origin: FreeBSD /usr/src/lib/msun/src/k_cosf.c */
/*
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
* Debugged and optimized by Bruce D. Evans.
*/
/*
* ====================================================
* 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.
* ====================================================
*/
#include "libm.h"
/* |cos(x) - c(x)| < 2**-34.1 (~[-5.37e-11, 5.295e-11]). */
static const double
C0 = -0x1ffffffd0c5e81.0p-54, /* -0.499999997251031003120 */
C1 = 0x155553e1053a42.0p-57, /* 0.0416666233237390631894 */
C2 = -0x16c087e80f1e27.0p-62, /* -0.00138867637746099294692 */
C3 = 0x199342e0ee5069.0p-68; /* 0.0000243904487962774090654 */
float __cosdf(double x)
{
double_t r, w, z;
/* Try to optimize for parallel evaluation as in __tandf.c. */
z = x*x;
w = z*z;
r = C2+z*C3;
return ((1.0+z*C0) + w*C1) + (w*z)*r;
}

View File

@ -1,96 +0,0 @@
/* origin: FreeBSD /usr/src/lib/msun/ld80/k_cosl.c */
/* origin: FreeBSD /usr/src/lib/msun/ld128/k_cosl.c */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
* Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans.
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
#include "libm.h"
#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
#if LDBL_MANT_DIG == 64
/*
* ld80 version of __cos.c. See __cos.c for most comments.
*/
/*
* Domain [-0.7854, 0.7854], range ~[-2.43e-23, 2.425e-23]:
* |cos(x) - c(x)| < 2**-75.1
*
* The coefficients of c(x) were generated by a pari-gp script using
* a Remez algorithm that searches for the best higher coefficients
* after rounding leading coefficients to a specified precision.
*
* Simpler methods like Chebyshev or basic Remez barely suffice for
* cos() in 64-bit precision, because we want the coefficient of x^2
* to be precisely -0.5 so that multiplying by it is exact, and plain
* rounding of the coefficients of a good polynomial approximation only
* gives this up to about 64-bit precision. Plain rounding also gives
* a mediocre approximation for the coefficient of x^4, but a rounding
* error of 0.5 ulps for this coefficient would only contribute ~0.01
* ulps to the final error, so this is unimportant. Rounding errors in
* higher coefficients are even less important.
*
* In fact, coefficients above the x^4 one only need to have 53-bit
* precision, and this is more efficient. We get this optimization
* almost for free from the complications needed to search for the best
* higher coefficients.
*/
static const long double
C1 = 0.0416666666666666666136L; /* 0xaaaaaaaaaaaaaa9b.0p-68 */
static const double
C2 = -0.0013888888888888874, /* -0x16c16c16c16c10.0p-62 */
C3 = 0.000024801587301571716, /* 0x1a01a01a018e22.0p-68 */
C4 = -0.00000027557319215507120, /* -0x127e4fb7602f22.0p-74 */
C5 = 0.0000000020876754400407278, /* 0x11eed8caaeccf1.0p-81 */
C6 = -1.1470297442401303e-11, /* -0x19393412bd1529.0p-89 */
C7 = 4.7383039476436467e-14; /* 0x1aac9d9af5c43e.0p-97 */
#define POLY(z) (z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*(C6+z*C7)))))))
#elif LDBL_MANT_DIG == 113
/*
* ld128 version of __cos.c. See __cos.c for most comments.
*/
/*
* Domain [-0.7854, 0.7854], range ~[-1.80e-37, 1.79e-37]:
* |cos(x) - c(x))| < 2**-122.0
*
* 113-bit precision requires more care than 64-bit precision, since
* simple methods give a minimax polynomial with coefficient for x^2
* that is 1 ulp below 0.5, but we want it to be precisely 0.5. See
* above for more details.
*/
static const long double
C1 = 0.04166666666666666666666666666666658424671L,
C2 = -0.001388888888888888888888888888863490893732L,
C3 = 0.00002480158730158730158730158600795304914210L,
C4 = -0.2755731922398589065255474947078934284324e-6L,
C5 = 0.2087675698786809897659225313136400793948e-8L,
C6 = -0.1147074559772972315817149986812031204775e-10L,
C7 = 0.4779477332386808976875457937252120293400e-13L;
static const double
C8 = -0.1561920696721507929516718307820958119868e-15,
C9 = 0.4110317413744594971475941557607804508039e-18,
C10 = -0.8896592467191938803288521958313920156409e-21,
C11 = 0.1601061435794535138244346256065192782581e-23;
#define POLY(z) (z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*(C6+z*(C7+ \
z*(C8+z*(C9+z*(C10+z*C11)))))))))))
#endif
long double __cosl(long double x, long double y)
{
long double hz,z,r,w;
z = x*x;
r = POLY(z);
hz = 0.5*z;
w = 1.0-hz;
return w + (((1.0-w)-hz) + (z*r-x*y));
}
#endif

View File

@ -1,16 +0,0 @@
#include "libm.h"
/* k is such that k*ln2 has minimal relative error and x - kln2 > log(DBL_MIN) */
static const int k = 2043;
static const double kln2 = 0x1.62066151add8bp+10;
/* exp(x)/2 for x >= log(DBL_MAX), slightly better than 0.5*exp(x/2)*exp(x/2) */
double __expo2(double x)
{
double scale;
/* note that k is odd and scale*scale overflows */
INSERT_WORDS(scale, (uint32_t)(0x3ff + k/2) << 20, 0);
/* exp(x - k ln2) * 2**(k-1) */
return exp(x - kln2) * scale * scale;
}

View File

@ -1,16 +0,0 @@
#include "libm.h"
/* k is such that k*ln2 has minimal relative error and x - kln2 > log(FLT_MIN) */
static const int k = 235;
static const float kln2 = 0x1.45c778p+7f;
/* expf(x)/2 for x >= log(FLT_MAX), slightly better than 0.5f*expf(x/2)*expf(x/2) */
float __expo2f(float x)
{
float scale;
/* note that k is odd and scale*scale overflows */
SET_FLOAT_WORD(scale, (uint32_t)(0x7f + k/2) << 23);
/* exp(x - k ln2) * 2**(k-1) */
return expf(x - kln2) * scale * scale;
}

View File

@ -1,11 +0,0 @@
#include <math.h>
#include <stdint.h>
int __fpclassify(double x)
{
union {double f; uint64_t i;} u = {x};
int e = u.i>>52 & 0x7ff;
if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO;
if (e==0x7ff) return u.i<<12 ? FP_NAN : FP_INFINITE;
return FP_NORMAL;
}

View File

@ -1,11 +0,0 @@
#include <math.h>
#include <stdint.h>
int __fpclassifyf(float x)
{
union {float f; uint32_t i;} u = {x};
int e = u.i>>23 & 0xff;
if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO;
if (e==0xff) return u.i<<9 ? FP_NAN : FP_INFINITE;
return FP_NORMAL;
}

View File

@ -1,34 +0,0 @@
#include "libm.h"
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
int __fpclassifyl(long double x)
{
return __fpclassify(x);
}
#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
int __fpclassifyl(long double x)
{
union ldshape u = {x};
int e = u.i.se & 0x7fff;
int msb = u.i.m>>63;
if (!e && !msb)
return u.i.m ? FP_SUBNORMAL : FP_ZERO;
if (!msb)
return FP_NAN;
if (e == 0x7fff)
return u.i.m << 1 ? FP_NAN : FP_INFINITE;
return FP_NORMAL;
}
#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
int __fpclassifyl(long double x)
{
union ldshape u = {x};
int e = u.i.se & 0x7fff;
u.i.se = 0;
if (!e)
return u.i2.lo | u.i2.hi ? FP_SUBNORMAL : FP_ZERO;
if (e == 0x7fff)
return u.i2.lo | u.i2.hi ? FP_NAN : FP_INFINITE;
return FP_NORMAL;
}
#endif

View File

@ -1,63 +0,0 @@
#include <float.h>
#include "__invtrigl.h"
#if LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
static const long double
pS0 = 1.66666666666666666631e-01L,
pS1 = -4.16313987993683104320e-01L,
pS2 = 3.69068046323246813704e-01L,
pS3 = -1.36213932016738603108e-01L,
pS4 = 1.78324189708471965733e-02L,
pS5 = -2.19216428382605211588e-04L,
pS6 = -7.10526623669075243183e-06L,
qS1 = -2.94788392796209867269e+00L,
qS2 = 3.27309890266528636716e+00L,
qS3 = -1.68285799854822427013e+00L,
qS4 = 3.90699412641738801874e-01L,
qS5 = -3.14365703596053263322e-02L;
const long double pio2_hi = 1.57079632679489661926L;
const long double pio2_lo = -2.50827880633416601173e-20L;
/* used in asinl() and acosl() */
/* R(x^2) is a rational approximation of (asin(x)-x)/x^3 with Remez algorithm */
long double __invtrigl_R(long double z)
{
long double p, q;
p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*(pS5+z*pS6))))));
q = 1.0+z*(qS1+z*(qS2+z*(qS3+z*(qS4+z*qS5))));
return p/q;
}
#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
static const long double
pS0 = 1.66666666666666666666666666666700314e-01L,
pS1 = -7.32816946414566252574527475428622708e-01L,
pS2 = 1.34215708714992334609030036562143589e+00L,
pS3 = -1.32483151677116409805070261790752040e+00L,
pS4 = 7.61206183613632558824485341162121989e-01L,
pS5 = -2.56165783329023486777386833928147375e-01L,
pS6 = 4.80718586374448793411019434585413855e-02L,
pS7 = -4.42523267167024279410230886239774718e-03L,
pS8 = 1.44551535183911458253205638280410064e-04L,
pS9 = -2.10558957916600254061591040482706179e-07L,
qS1 = -4.84690167848739751544716485245697428e+00L,
qS2 = 9.96619113536172610135016921140206980e+00L,
qS3 = -1.13177895428973036660836798461641458e+01L,
qS4 = 7.74004374389488266169304117714658761e+00L,
qS5 = -3.25871986053534084709023539900339905e+00L,
qS6 = 8.27830318881232209752469022352928864e-01L,
qS7 = -1.18768052702942805423330715206348004e-01L,
qS8 = 8.32600764660522313269101537926539470e-03L,
qS9 = -1.99407384882605586705979504567947007e-04L;
const long double pio2_hi = 1.57079632679489661923132169163975140L;
const long double pio2_lo = 4.33590506506189051239852201302167613e-35L;
long double __invtrigl_R(long double z)
{
long double p, q;
p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*(pS5+z*(pS6+z*(pS7+z*(pS8+z*pS9)))))))));
q = 1.0+z*(qS1+z*(qS2+z*(qS3+z*(qS4+z*(qS5+z*(pS6+z*(pS7+z*(pS8+z*pS9))))))));
return p/q;
}
#endif

View File

@ -1,6 +0,0 @@
/* shared by acosl, asinl and atan2l */
#define pio2_hi __pio2_hi
#define pio2_lo __pio2_lo
extern const long double pio2_hi, pio2_lo;
long double __invtrigl_R(long double z);

View File

@ -1,93 +0,0 @@
/* origin: OpenBSD /usr/src/lib/libm/src/polevll.c */
/*
* Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* Evaluate polynomial
*
*
* SYNOPSIS:
*
* int N;
* long double x, y, coef[N+1], polevl[];
*
* y = polevll( x, coef, N );
*
*
* DESCRIPTION:
*
* Evaluates polynomial of degree N:
*
* 2 N
* y = C + C x + C x +...+ C x
* 0 1 2 N
*
* Coefficients are stored in reverse order:
*
* coef[0] = C , ..., coef[N] = C .
* N 0
*
* The function p1evll() assumes that coef[N] = 1.0 and is
* omitted from the array. Its calling arguments are
* otherwise the same as polevll().
*
*
* SPEED:
*
* In the interest of speed, there are no checks for out
* of bounds arithmetic. This routine is used by most of
* the functions in the library. Depending on available
* equipment features, the user may wish to rewrite the
* program in microcode or assembly language.
*
*/
#include "libm.h"
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
#else
/*
* Polynomial evaluator:
* P[0] x^n + P[1] x^(n-1) + ... + P[n]
*/
long double __polevll(long double x, const long double *P, int n)
{
long double y;
y = *P++;
do {
y = y * x + *P++;
} while (--n);
return y;
}
/*
* Polynomial evaluator:
* x^n + P[0] x^(n-1) + P[1] x^(n-2) + ... + P[n]
*/
long double __p1evll(long double x, const long double *P, int n)
{
long double y;
n -= 1;
y = x + *P++;
do {
y = y * x + *P++;
} while (--n);
return y;
}
#endif

View File

@ -1,177 +0,0 @@
/* origin: FreeBSD /usr/src/lib/msun/src/e_rem_pio2.c */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*
* Optimized by Bruce D. Evans.
*/
/* __rem_pio2(x,y)
*
* return the remainder of x rem pi/2 in y[0]+y[1]
* use __rem_pio2_large() for large x
*/
#include "libm.h"
#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
#define EPS DBL_EPSILON
#elif FLT_EVAL_METHOD==2
#define EPS LDBL_EPSILON
#endif
/*
* invpio2: 53 bits of 2/pi
* pio2_1: first 33 bit of pi/2
* pio2_1t: pi/2 - pio2_1
* pio2_2: second 33 bit of pi/2
* pio2_2t: pi/2 - (pio2_1+pio2_2)
* pio2_3: third 33 bit of pi/2
* pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3)
*/
static const double
toint = 1.5/EPS,
invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */
pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */
pio2_2 = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */
pio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */
pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */
pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */
/* caller must handle the case when reduction is not needed: |x| ~<= pi/4 */
int __rem_pio2(double x, double *y)
{
union {double f; uint64_t i;} u = {x};
double_t z,w,t,r,fn;
double tx[3],ty[2];
uint32_t ix;
int sign, n, ex, ey, i;
sign = u.i>>63;
ix = u.i>>32 & 0x7fffffff;
if (ix <= 0x400f6a7a) { /* |x| ~<= 5pi/4 */
if ((ix & 0xfffff) == 0x921fb) /* |x| ~= pi/2 or 2pi/2 */
goto medium; /* cancellation -- use medium case */
if (ix <= 0x4002d97c) { /* |x| ~<= 3pi/4 */
if (!sign) {
z = x - pio2_1; /* one round good to 85 bits */
y[0] = z - pio2_1t;
y[1] = (z-y[0]) - pio2_1t;
return 1;
} else {
z = x + pio2_1;
y[0] = z + pio2_1t;
y[1] = (z-y[0]) + pio2_1t;
return -1;
}
} else {
if (!sign) {
z = x - 2*pio2_1;
y[0] = z - 2*pio2_1t;
y[1] = (z-y[0]) - 2*pio2_1t;
return 2;
} else {
z = x + 2*pio2_1;
y[0] = z + 2*pio2_1t;
y[1] = (z-y[0]) + 2*pio2_1t;
return -2;
}
}
}
if (ix <= 0x401c463b) { /* |x| ~<= 9pi/4 */
if (ix <= 0x4015fdbc) { /* |x| ~<= 7pi/4 */
if (ix == 0x4012d97c) /* |x| ~= 3pi/2 */
goto medium;
if (!sign) {
z = x - 3*pio2_1;
y[0] = z - 3*pio2_1t;
y[1] = (z-y[0]) - 3*pio2_1t;
return 3;
} else {
z = x + 3*pio2_1;
y[0] = z + 3*pio2_1t;
y[1] = (z-y[0]) + 3*pio2_1t;
return -3;
}
} else {
if (ix == 0x401921fb) /* |x| ~= 4pi/2 */
goto medium;
if (!sign) {
z = x - 4*pio2_1;
y[0] = z - 4*pio2_1t;
y[1] = (z-y[0]) - 4*pio2_1t;
return 4;
} else {
z = x + 4*pio2_1;
y[0] = z + 4*pio2_1t;
y[1] = (z-y[0]) + 4*pio2_1t;
return -4;
}
}
}
if (ix < 0x413921fb) { /* |x| ~< 2^20*(pi/2), medium size */
medium:
/* rint(x/(pi/2)), Assume round-to-nearest. */
fn = (double_t)x*invpio2 + toint - toint;
n = (int32_t)fn;
r = x - fn*pio2_1;
w = fn*pio2_1t; /* 1st round, good to 85 bits */
y[0] = r - w;
u.f = y[0];
ey = u.i>>52 & 0x7ff;
ex = ix>>20;
if (ex - ey > 16) { /* 2nd round, good to 118 bits */
t = r;
w = fn*pio2_2;
r = t - w;
w = fn*pio2_2t - ((t-r)-w);
y[0] = r - w;
u.f = y[0];
ey = u.i>>52 & 0x7ff;
if (ex - ey > 49) { /* 3rd round, good to 151 bits, covers all cases */
t = r;
w = fn*pio2_3;
r = t - w;
w = fn*pio2_3t - ((t-r)-w);
y[0] = r - w;
}
}
y[1] = (r - y[0]) - w;
return n;
}
/*
* all other (large) arguments
*/
if (ix >= 0x7ff00000) { /* x is inf or NaN */
y[0] = y[1] = x - x;
return 0;
}
/* set z = scalbn(|x|,-ilogb(x)+23) */
u.f = x;
u.i &= (uint64_t)-1>>12;
u.i |= (uint64_t)(0x3ff + 23)<<52;
z = u.f;
for (i=0; i < 2; i++) {
tx[i] = (double)(int32_t)z;
z = (z-tx[i])*0x1p24;
}
tx[i] = z;
/* skip zero terms, first term is non-zero */
while (tx[i] == 0.0)
i--;
n = __rem_pio2_large(tx,ty,(int)(ix>>20)-(0x3ff+23),i+1,1);
if (sign) {
y[0] = -ty[0];
y[1] = -ty[1];
return -n;
}
y[0] = ty[0];
y[1] = ty[1];
return n;
}

View File

@ -1,442 +0,0 @@
/* origin: FreeBSD /usr/src/lib/msun/src/k_rem_pio2.c */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
* __rem_pio2_large(x,y,e0,nx,prec)
* double x[],y[]; int e0,nx,prec;
*
* __rem_pio2_large return the last three digits of N with
* y = x - N*pi/2
* so that |y| < pi/2.
*
* The method is to compute the integer (mod 8) and fraction parts of
* (2/pi)*x without doing the full multiplication. In general we
* skip the part of the product that are known to be a huge integer (
* more accurately, = 0 mod 8 ). Thus the number of operations are
* independent of the exponent of the input.
*
* (2/pi) is represented by an array of 24-bit integers in ipio2[].
*
* Input parameters:
* x[] The input value (must be positive) is broken into nx
* pieces of 24-bit integers in double precision format.
* x[i] will be the i-th 24 bit of x. The scaled exponent
* of x[0] is given in input parameter e0 (i.e., x[0]*2^e0
* match x's up to 24 bits.
*
* Example of breaking a double positive z into x[0]+x[1]+x[2]:
* e0 = ilogb(z)-23
* z = scalbn(z,-e0)
* for i = 0,1,2
* x[i] = floor(z)
* z = (z-x[i])*2**24
*
*
* y[] ouput result in an array of double precision numbers.
* The dimension of y[] is:
* 24-bit precision 1
* 53-bit precision 2
* 64-bit precision 2
* 113-bit precision 3
* The actual value is the sum of them. Thus for 113-bit
* precison, one may have to do something like:
*
* long double t,w,r_head, r_tail;
* t = (long double)y[2] + (long double)y[1];
* w = (long double)y[0];
* r_head = t+w;
* r_tail = w - (r_head - t);
*
* e0 The exponent of x[0]. Must be <= 16360 or you need to
* expand the ipio2 table.
*
* nx dimension of x[]
*
* prec an integer indicating the precision:
* 0 24 bits (single)
* 1 53 bits (double)
* 2 64 bits (extended)
* 3 113 bits (quad)
*
* External function:
* double scalbn(), floor();
*
*
* Here is the description of some local variables:
*
* jk jk+1 is the initial number of terms of ipio2[] needed
* in the computation. The minimum and recommended value
* for jk is 3,4,4,6 for single, double, extended, and quad.
* jk+1 must be 2 larger than you might expect so that our
* recomputation test works. (Up to 24 bits in the integer
* part (the 24 bits of it that we compute) and 23 bits in
* the fraction part may be lost to cancelation before we
* recompute.)
*
* jz local integer variable indicating the number of
* terms of ipio2[] used.
*
* jx nx - 1
*
* jv index for pointing to the suitable ipio2[] for the
* computation. In general, we want
* ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8
* is an integer. Thus
* e0-3-24*jv >= 0 or (e0-3)/24 >= jv
* Hence jv = max(0,(e0-3)/24).
*
* jp jp+1 is the number of terms in PIo2[] needed, jp = jk.
*
* q[] double array with integral value, representing the
* 24-bits chunk of the product of x and 2/pi.
*
* q0 the corresponding exponent of q[0]. Note that the
* exponent for q[i] would be q0-24*i.
*
* PIo2[] double precision array, obtained by cutting pi/2
* into 24 bits chunks.
*
* f[] ipio2[] in floating point
*
* iq[] integer array by breaking up q[] in 24-bits chunk.
*
* fq[] final product of x*(2/pi) in fq[0],..,fq[jk]
*
* ih integer. If >0 it indicates q[] is >= 0.5, hence
* it also indicates the *sign* of the result.
*
*/
/*
* Constants:
* The hexadecimal values are the intended ones for the following
* constants. The decimal values may be used, provided that the
* compiler will convert from decimal to binary accurately enough
* to produce the hexadecimal values shown.
*/
#include "libm.h"
static const int init_jk[] = {3,4,4,6}; /* initial value for jk */
/*
* Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi
*
* integer array, contains the (24*i)-th to (24*i+23)-th
* bit of 2/pi after binary point. The corresponding
* floating value is
*
* ipio2[i] * 2^(-24(i+1)).
*
* NB: This table must have at least (e0-3)/24 + jk terms.
* For quad precision (e0 <= 16360, jk = 6), this is 686.
*/
static const int32_t ipio2[] = {
0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62,
0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A,
0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129,
0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, 0x7026B4, 0x5F7E41,
0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8,
0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D, 0x367ECF,
0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5,
0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08,
0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3,
0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880,
0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B,
#if LDBL_MAX_EXP > 1024
0x47C419, 0xC367CD, 0xDCE809, 0x2A8359, 0xC4768B, 0x961CA6,
0xDDAF44, 0xD15719, 0x053EA5, 0xFF0705, 0x3F7E33, 0xE832C2,
0xDE4F98, 0x327DBB, 0xC33D26, 0xEF6B1E, 0x5EF89F, 0x3A1F35,
0xCAF27F, 0x1D87F1, 0x21907C, 0x7C246A, 0xFA6ED5, 0x772D30,
0x433B15, 0xC614B5, 0x9D19C3, 0xC2C4AD, 0x414D2C, 0x5D000C,
0x467D86, 0x2D71E3, 0x9AC69B, 0x006233, 0x7CD2B4, 0x97A7B4,
0xD55537, 0xF63ED7, 0x1810A3, 0xFC764D, 0x2A9D64, 0xABD770,
0xF87C63, 0x57B07A, 0xE71517, 0x5649C0, 0xD9D63B, 0x3884A7,
0xCB2324, 0x778AD6, 0x23545A, 0xB91F00, 0x1B0AF1, 0xDFCE19,
0xFF319F, 0x6A1E66, 0x615799, 0x47FBAC, 0xD87F7E, 0xB76522,
0x89E832, 0x60BFE6, 0xCDC4EF, 0x09366C, 0xD43F5D, 0xD7DE16,
0xDE3B58, 0x929BDE, 0x2822D2, 0xE88628, 0x4D58E2, 0x32CAC6,
0x16E308, 0xCB7DE0, 0x50C017, 0xA71DF3, 0x5BE018, 0x34132E,
0x621283, 0x014883, 0x5B8EF5, 0x7FB0AD, 0xF2E91E, 0x434A48,
0xD36710, 0xD8DDAA, 0x425FAE, 0xCE616A, 0xA4280A, 0xB499D3,
0xF2A606, 0x7F775C, 0x83C2A3, 0x883C61, 0x78738A, 0x5A8CAF,
0xBDD76F, 0x63A62D, 0xCBBFF4, 0xEF818D, 0x67C126, 0x45CA55,
0x36D9CA, 0xD2A828, 0x8D61C2, 0x77C912, 0x142604, 0x9B4612,
0xC459C4, 0x44C5C8, 0x91B24D, 0xF31700, 0xAD43D4, 0xE54929,
0x10D5FD, 0xFCBE00, 0xCC941E, 0xEECE70, 0xF53E13, 0x80F1EC,
0xC3E7B3, 0x28F8C7, 0x940593, 0x3E71C1, 0xB3092E, 0xF3450B,
0x9C1288, 0x7B20AB, 0x9FB52E, 0xC29247, 0x2F327B, 0x6D550C,
0x90A772, 0x1FE76B, 0x96CB31, 0x4A1679, 0xE27941, 0x89DFF4,
0x9794E8, 0x84E6E2, 0x973199, 0x6BED88, 0x365F5F, 0x0EFDBB,
0xB49A48, 0x6CA467, 0x427271, 0x325D8D, 0xB8159F, 0x09E5BC,
0x25318D, 0x3974F7, 0x1C0530, 0x010C0D, 0x68084B, 0x58EE2C,
0x90AA47, 0x02E774, 0x24D6BD, 0xA67DF7, 0x72486E, 0xEF169F,
0xA6948E, 0xF691B4, 0x5153D1, 0xF20ACF, 0x339820, 0x7E4BF5,
0x6863B2, 0x5F3EDD, 0x035D40, 0x7F8985, 0x295255, 0xC06437,
0x10D86D, 0x324832, 0x754C5B, 0xD4714E, 0x6E5445, 0xC1090B,
0x69F52A, 0xD56614, 0x9D0727, 0x50045D, 0xDB3BB4, 0xC576EA,
0x17F987, 0x7D6B49, 0xBA271D, 0x296996, 0xACCCC6, 0x5414AD,
0x6AE290, 0x89D988, 0x50722C, 0xBEA404, 0x940777, 0x7030F3,
0x27FC00, 0xA871EA, 0x49C266, 0x3DE064, 0x83DD97, 0x973FA3,
0xFD9443, 0x8C860D, 0xDE4131, 0x9D3992, 0x8C70DD, 0xE7B717,
0x3BDF08, 0x2B3715, 0xA0805C, 0x93805A, 0x921110, 0xD8E80F,
0xAF806C, 0x4BFFDB, 0x0F9038, 0x761859, 0x15A562, 0xBBCB61,
0xB989C7, 0xBD4010, 0x04F2D2, 0x277549, 0xF6B6EB, 0xBB22DB,
0xAA140A, 0x2F2689, 0x768364, 0x333B09, 0x1A940E, 0xAA3A51,
0xC2A31D, 0xAEEDAF, 0x12265C, 0x4DC26D, 0x9C7A2D, 0x9756C0,
0x833F03, 0xF6F009, 0x8C402B, 0x99316D, 0x07B439, 0x15200C,
0x5BC3D8, 0xC492F5, 0x4BADC6, 0xA5CA4E, 0xCD37A7, 0x36A9E6,
0x9492AB, 0x6842DD, 0xDE6319, 0xEF8C76, 0x528B68, 0x37DBFC,
0xABA1AE, 0x3115DF, 0xA1AE00, 0xDAFB0C, 0x664D64, 0xB705ED,
0x306529, 0xBF5657, 0x3AFF47, 0xB9F96A, 0xF3BE75, 0xDF9328,
0x3080AB, 0xF68C66, 0x15CB04, 0x0622FA, 0x1DE4D9, 0xA4B33D,
0x8F1B57, 0x09CD36, 0xE9424E, 0xA4BE13, 0xB52333, 0x1AAAF0,
0xA8654F, 0xA5C1D2, 0x0F3F0B, 0xCD785B, 0x76F923, 0x048B7B,
0x721789, 0x53A6C6, 0xE26E6F, 0x00EBEF, 0x584A9B, 0xB7DAC4,
0xBA66AA, 0xCFCF76, 0x1D02D1, 0x2DF1B1, 0xC1998C, 0x77ADC3,
0xDA4886, 0xA05DF7, 0xF480C6, 0x2FF0AC, 0x9AECDD, 0xBC5C3F,
0x6DDED0, 0x1FC790, 0xB6DB2A, 0x3A25A3, 0x9AAF00, 0x9353AD,
0x0457B6, 0xB42D29, 0x7E804B, 0xA707DA, 0x0EAA76, 0xA1597B,
0x2A1216, 0x2DB7DC, 0xFDE5FA, 0xFEDB89, 0xFDBE89, 0x6C76E4,
0xFCA906, 0x70803E, 0x156E85, 0xFF87FD, 0x073E28, 0x336761,
0x86182A, 0xEABD4D, 0xAFE7B3, 0x6E6D8F, 0x396795, 0x5BBF31,
0x48D784, 0x16DF30, 0x432DC7, 0x356125, 0xCE70C9, 0xB8CB30,
0xFD6CBF, 0xA200A4, 0xE46C05, 0xA0DD5A, 0x476F21, 0xD21262,
0x845CB9, 0x496170, 0xE0566B, 0x015299, 0x375550, 0xB7D51E,
0xC4F133, 0x5F6E13, 0xE4305D, 0xA92E85, 0xC3B21D, 0x3632A1,
0xA4B708, 0xD4B1EA, 0x21F716, 0xE4698F, 0x77FF27, 0x80030C,
0x2D408D, 0xA0CD4F, 0x99A520, 0xD3A2B3, 0x0A5D2F, 0x42F9B4,
0xCBDA11, 0xD0BE7D, 0xC1DB9B, 0xBD17AB, 0x81A2CA, 0x5C6A08,
0x17552E, 0x550027, 0xF0147F, 0x8607E1, 0x640B14, 0x8D4196,
0xDEBE87, 0x2AFDDA, 0xB6256B, 0x34897B, 0xFEF305, 0x9EBFB9,
0x4F6A68, 0xA82A4A, 0x5AC44F, 0xBCF82D, 0x985AD7, 0x95C7F4,
0x8D4D0D, 0xA63A20, 0x5F57A4, 0xB13F14, 0x953880, 0x0120CC,
0x86DD71, 0xB6DEC9, 0xF560BF, 0x11654D, 0x6B0701, 0xACB08C,
0xD0C0B2, 0x485551, 0x0EFB1E, 0xC37295, 0x3B06A3, 0x3540C0,
0x7BDC06, 0xCC45E0, 0xFA294E, 0xC8CAD6, 0x41F3E8, 0xDE647C,
0xD8649B, 0x31BED9, 0xC397A4, 0xD45877, 0xC5E369, 0x13DAF0,
0x3C3ABA, 0x461846, 0x5F7555, 0xF5BDD2, 0xC6926E, 0x5D2EAC,
0xED440E, 0x423E1C, 0x87C461, 0xE9FD29, 0xF3D6E7, 0xCA7C22,
0x35916F, 0xC5E008, 0x8DD7FF, 0xE26A6E, 0xC6FDB0, 0xC10893,
0x745D7C, 0xB2AD6B, 0x9D6ECD, 0x7B723E, 0x6A11C6, 0xA9CFF7,
0xDF7329, 0xBAC9B5, 0x5100B7, 0x0DB2E2, 0x24BA74, 0x607DE5,
0x8AD874, 0x2C150D, 0x0C1881, 0x94667E, 0x162901, 0x767A9F,
0xBEFDFD, 0xEF4556, 0x367ED9, 0x13D9EC, 0xB9BA8B, 0xFC97C4,
0x27A831, 0xC36EF1, 0x36C594, 0x56A8D8, 0xB5A8B4, 0x0ECCCF,
0x2D8912, 0x34576F, 0x89562C, 0xE3CE99, 0xB920D6, 0xAA5E6B,
0x9C2A3E, 0xCC5F11, 0x4A0BFD, 0xFBF4E1, 0x6D3B8E, 0x2C86E2,
0x84D4E9, 0xA9B4FC, 0xD1EEEF, 0xC9352E, 0x61392F, 0x442138,
0xC8D91B, 0x0AFC81, 0x6A4AFB, 0xD81C2F, 0x84B453, 0x8C994E,
0xCC2254, 0xDC552A, 0xD6C6C0, 0x96190B, 0xB8701A, 0x649569,
0x605A26, 0xEE523F, 0x0F117F, 0x11B5F4, 0xF5CBFC, 0x2DBC34,
0xEEBC34, 0xCC5DE8, 0x605EDD, 0x9B8E67, 0xEF3392, 0xB817C9,
0x9B5861, 0xBC57E1, 0xC68351, 0x103ED8, 0x4871DD, 0xDD1C2D,
0xA118AF, 0x462C21, 0xD7F359, 0x987AD9, 0xC0549E, 0xFA864F,
0xFC0656, 0xAE79E5, 0x362289, 0x22AD38, 0xDC9367, 0xAAE855,
0x382682, 0x9BE7CA, 0xA40D51, 0xB13399, 0x0ED7A9, 0x480569,
0xF0B265, 0xA7887F, 0x974C88, 0x36D1F9, 0xB39221, 0x4A827B,
0x21CF98, 0xDC9F40, 0x5547DC, 0x3A74E1, 0x42EB67, 0xDF9DFE,
0x5FD45E, 0xA4677B, 0x7AACBA, 0xA2F655, 0x23882B, 0x55BA41,
0x086E59, 0x862A21, 0x834739, 0xE6E389, 0xD49EE5, 0x40FB49,
0xE956FF, 0xCA0F1C, 0x8A59C5, 0x2BFA94, 0xC5C1D3, 0xCFC50F,
0xAE5ADB, 0x86C547, 0x624385, 0x3B8621, 0x94792C, 0x876110,
0x7B4C2A, 0x1A2C80, 0x12BF43, 0x902688, 0x893C78, 0xE4C4A8,
0x7BDBE5, 0xC23AC4, 0xEAF426, 0x8A67F7, 0xBF920D, 0x2BA365,
0xB1933D, 0x0B7CBD, 0xDC51A4, 0x63DD27, 0xDDE169, 0x19949A,
0x9529A8, 0x28CE68, 0xB4ED09, 0x209F44, 0xCA984E, 0x638270,
0x237C7E, 0x32B90F, 0x8EF5A7, 0xE75614, 0x08F121, 0x2A9DB5,
0x4D7E6F, 0x5119A5, 0xABF9B5, 0xD6DF82, 0x61DD96, 0x023616,
0x9F3AC4, 0xA1A283, 0x6DED72, 0x7A8D39, 0xA9B882, 0x5C326B,
0x5B2746, 0xED3400, 0x7700D2, 0x55F4FC, 0x4D5901, 0x8071E0,
#endif
};
static const double PIo2[] = {
1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */
7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */
5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */
3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */
1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */
1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */
2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */
2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */
};
int __rem_pio2_large(double *x, double *y, int e0, int nx, int prec)
{
int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;
double z,fw,f[20],fq[20],q[20];
/* initialize jk*/
jk = init_jk[prec];
jp = jk;
/* determine jx,jv,q0, note that 3>q0 */
jx = nx-1;
jv = (e0-3)/24; if(jv<0) jv=0;
q0 = e0-24*(jv+1);
/* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */
j = jv-jx; m = jx+jk;
for (i=0; i<=m; i++,j++)
f[i] = j<0 ? 0.0 : (double)ipio2[j];
/* 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;
}
jz = jk;
recompute:
/* distill q[] into iq[] reversingly */
for (i=0,j=jz,z=q[jz]; j>0; i++,j--) {
fw = (double)(int32_t)(0x1p-24*z);
iq[i] = (int32_t)(z - 0x1p24*fw);
z = q[j-1]+fw;
}
/* compute n */
z = scalbn(z,q0); /* actual value of z */
z -= 8.0*floor(z*0.125); /* trim off integer >= 8 */
n = (int32_t)z;
z -= (double)n;
ih = 0;
if (q0 > 0) { /* need iq[jz-1] to determine n */
i = iq[jz-1]>>(24-q0); n += i;
iq[jz-1] -= i<<(24-q0);
ih = iq[jz-1]>>(23-q0);
}
else if (q0 == 0) ih = iq[jz-1]>>23;
else if (z >= 0.5) ih = 2;
if (ih > 0) { /* q > 0.5 */
n += 1; carry = 0;
for (i=0; i<jz; i++) { /* compute 1-q */
j = iq[i];
if (carry == 0) {
if (j != 0) {
carry = 1;
iq[i] = 0x1000000 - j;
}
} else
iq[i] = 0xffffff - j;
}
if (q0 > 0) { /* rare case: chance is 1 in 12 */
switch(q0) {
case 1:
iq[jz-1] &= 0x7fffff; break;
case 2:
iq[jz-1] &= 0x3fffff; break;
}
}
if (ih == 2) {
z = 1.0 - z;
if (carry != 0)
z -= scalbn(1.0,q0);
}
}
/* check if recomputation is needed */
if (z == 0.0) {
j = 0;
for (i=jz-1; i>=jk; i--) j |= iq[i];
if (j == 0) { /* need recomputation */
for (k=1; iq[jk-k]==0; k++); /* k = no. of terms needed */
for (i=jz+1; i<=jz+k; i++) { /* add q[jz+1] to q[jz+k] */
f[jx+i] = (double)ipio2[jv+i];
for (j=0,fw=0.0; j<=jx; j++)
fw += x[j]*f[jx+i-j];
q[i] = fw;
}
jz += k;
goto recompute;
}
}
/* chop off zero terms */
if (z == 0.0) {
jz -= 1;
q0 -= 24;
while (iq[jz] == 0) {
jz--;
q0 -= 24;
}
} else { /* break z into 24-bit if necessary */
z = scalbn(z,-q0);
if (z >= 0x1p24) {
fw = (double)(int32_t)(0x1p-24*z);
iq[jz] = (int32_t)(z - 0x1p24*fw);
jz += 1;
q0 += 24;
iq[jz] = (int32_t)fw;
} else
iq[jz] = (int32_t)z;
}
/* convert integer "bit" chunk to floating-point value */
fw = scalbn(1.0,q0);
for (i=jz; i>=0; i--) {
q[i] = fw*(double)iq[i];
fw *= 0x1p-24;
}
/* compute PIo2[0,...,jp]*q[jz,...,0] */
for(i=jz; i>=0; i--) {
for (fw=0.0,k=0; k<=jp && k<=jz-i; k++)
fw += PIo2[k]*q[i+k];
fq[jz-i] = fw;
}
/* compress fq[] into y[] */
switch(prec) {
case 0:
fw = 0.0;
for (i=jz; i>=0; i--)
fw += fq[i];
y[0] = ih==0 ? fw : -fw;
break;
case 1:
case 2:
fw = 0.0;
for (i=jz; i>=0; i--)
fw += fq[i];
// TODO: drop excess precision here once double_t is used
fw = (double)fw;
y[0] = ih==0 ? fw : -fw;
fw = fq[0]-fw;
for (i=1; i<=jz; i++)
fw += fq[i];
y[1] = ih==0 ? fw : -fw;
break;
case 3: /* painful */
for (i=jz; i>0; i--) {
fw = fq[i-1]+fq[i];
fq[i] += fq[i-1]-fw;
fq[i-1] = fw;
}
for (i=jz; i>1; i--) {
fw = fq[i-1]+fq[i];
fq[i] += fq[i-1]-fw;
fq[i-1] = fw;
}
for (fw=0.0,i=jz; i>=2; i--)
fw += fq[i];
if (ih==0) {
y[0] = fq[0]; y[1] = fq[1]; y[2] = fw;
} else {
y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw;
}
}
return n&7;
}

View File

@ -1,75 +0,0 @@
/* origin: FreeBSD /usr/src/lib/msun/src/e_rem_pio2f.c */
/*
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
* Debugged and optimized by Bruce D. Evans.
*/
/*
* ====================================================
* 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.
* ====================================================
*/
/* __rem_pio2f(x,y)
*
* return the remainder of x rem pi/2 in *y
* use double precision for everything except passing x
* use __rem_pio2_large() for large x
*/
#include "libm.h"
#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
#define EPS DBL_EPSILON
#elif FLT_EVAL_METHOD==2
#define EPS LDBL_EPSILON
#endif
/*
* invpio2: 53 bits of 2/pi
* pio2_1: first 25 bits of pi/2
* pio2_1t: pi/2 - pio2_1
*/
static const double
toint = 1.5/EPS,
invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
pio2_1 = 1.57079631090164184570e+00, /* 0x3FF921FB, 0x50000000 */
pio2_1t = 1.58932547735281966916e-08; /* 0x3E5110b4, 0x611A6263 */
int __rem_pio2f(float x, double *y)
{
union {float f; uint32_t i;} u = {x};
double tx[1],ty[1];
double_t fn;
uint32_t ix;
int n, sign, e0;
ix = u.i & 0x7fffffff;
/* 25+53 bit pi is good enough for medium size */
if (ix < 0x4dc90fdb) { /* |x| ~< 2^28*(pi/2), medium size */
/* Use a specialized rint() to get fn. Assume round-to-nearest. */
fn = (double_t)x*invpio2 + toint - toint;
n = (int32_t)fn;
*y = x - fn*pio2_1 - fn*pio2_1t;
return n;
}
if(ix>=0x7f800000) { /* x is inf or NaN */
*y = x-x;
return 0;
}
/* scale x into [2^23, 2^24-1] */
sign = u.i>>31;
e0 = (ix>>23) - (0x7f+23); /* e0 = ilogb(|x|)-23, positive */
u.i = ix - (e0<<23);
tx[0] = u.f;
n = __rem_pio2_large(tx,ty,e0,1,0);
if (sign) {
*y = -ty[0];
return -n;
}
*y = ty[0];
return n;
}

View File

@ -1,141 +0,0 @@
/* origin: FreeBSD /usr/src/lib/msun/ld80/e_rem_pio2.c */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
* Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans.
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*
* Optimized by Bruce D. Evans.
*/
#include "libm.h"
#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
/* ld80 and ld128 version of __rem_pio2(x,y)
*
* return the remainder of x rem pi/2 in y[0]+y[1]
* use __rem_pio2_large() for large x
*/
static const long double toint = 1.5/LDBL_EPSILON;
#if LDBL_MANT_DIG == 64
/* u ~< 0x1p25*pi/2 */
#define SMALL(u) (((u.i.se & 0x7fffU)<<16 | u.i.m>>48) < ((0x3fff + 25)<<16 | 0x921f>>1 | 0x8000))
#define QUOBITS(x) ((uint32_t)(int32_t)x & 0x7fffffff)
#define ROUND1 22
#define ROUND2 61
#define NX 3
#define NY 2
/*
* invpio2: 64 bits of 2/pi
* pio2_1: first 39 bits of pi/2
* pio2_1t: pi/2 - pio2_1
* pio2_2: second 39 bits of pi/2
* pio2_2t: pi/2 - (pio2_1+pio2_2)
* pio2_3: third 39 bits of pi/2
* pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3)
*/
static const double
pio2_1 = 1.57079632679597125389e+00, /* 0x3FF921FB, 0x54444000 */
pio2_2 = -1.07463465549783099519e-12, /* -0x12e7b967674000.0p-92 */
pio2_3 = 6.36831716351370313614e-25; /* 0x18a2e037074000.0p-133 */
static const long double
invpio2 = 6.36619772367581343076e-01L, /* 0xa2f9836e4e44152a.0p-64 */
pio2_1t = -1.07463465549719416346e-12L, /* -0x973dcb3b399d747f.0p-103 */
pio2_2t = 6.36831716351095013979e-25L, /* 0xc51701b839a25205.0p-144 */
pio2_3t = -2.75299651904407171810e-37L; /* -0xbb5bf6c7ddd660ce.0p-185 */
#elif LDBL_MANT_DIG == 113
/* u ~< 0x1p45*pi/2 */
#define SMALL(u) (((u.i.se & 0x7fffU)<<16 | u.i.top) < ((0x3fff + 45)<<16 | 0x921f))
#define QUOBITS(x) ((uint32_t)(int64_t)x & 0x7fffffff)
#define ROUND1 51
#define ROUND2 119
#define NX 5
#define NY 3
static const long double
invpio2 = 6.3661977236758134307553505349005747e-01L, /* 0x145f306dc9c882a53f84eafa3ea6a.0p-113 */
pio2_1 = 1.5707963267948966192292994253909555e+00L, /* 0x1921fb54442d18469800000000000.0p-112 */
pio2_1t = 2.0222662487959507323996846200947577e-21L, /* 0x13198a2e03707344a4093822299f3.0p-181 */
pio2_2 = 2.0222662487959507323994779168837751e-21L, /* 0x13198a2e03707344a400000000000.0p-181 */
pio2_2t = 2.0670321098263988236496903051604844e-43L, /* 0x127044533e63a0105df531d89cd91.0p-254 */
pio2_3 = 2.0670321098263988236499468110329591e-43L, /* 0x127044533e63a0105e00000000000.0p-254 */
pio2_3t = -2.5650587247459238361625433492959285e-65L; /* -0x159c4ec64ddaeb5f78671cbfb2210.0p-327 */
#endif
int __rem_pio2l(long double x, long double *y)
{
union ldshape u,uz;
long double z,w,t,r,fn;
double tx[NX],ty[NY];
int ex,ey,n,i;
u.f = x;
ex = u.i.se & 0x7fff;
if (SMALL(u)) {
/* rint(x/(pi/2)), Assume round-to-nearest. */
fn = x*invpio2 + toint - toint;
n = QUOBITS(fn);
r = x-fn*pio2_1;
w = fn*pio2_1t; /* 1st round good to 102/180 bits (ld80/ld128) */
y[0] = r-w;
u.f = y[0];
ey = u.i.se & 0x7fff;
if (ex - ey > ROUND1) { /* 2nd iteration needed, good to 141/248 (ld80/ld128) */
t = r;
w = fn*pio2_2;
r = t-w;
w = fn*pio2_2t-((t-r)-w);
y[0] = r-w;
u.f = y[0];
ey = u.i.se & 0x7fff;
if (ex - ey > ROUND2) { /* 3rd iteration, good to 180/316 bits */
t = r; /* will cover all possible cases (not verified for ld128) */
w = fn*pio2_3;
r = t-w;
w = fn*pio2_3t-((t-r)-w);
y[0] = r-w;
}
}
y[1] = (r - y[0]) - w;
return n;
}
/*
* all other (large) arguments
*/
if (ex == 0x7fff) { /* x is inf or NaN */
y[0] = y[1] = x - x;
return 0;
}
/* set z = scalbn(|x|,-ilogb(x)+23) */
uz.f = x;
uz.i.se = 0x3fff + 23;
z = uz.f;
for (i=0; i < NX - 1; i++) {
tx[i] = (double)(int32_t)z;
z = (z-tx[i])*0x1p24;
}
tx[i] = z;
while (tx[i] == 0)
i--;
n = __rem_pio2_large(tx, ty, ex-0x3fff-23, i+1, NY);
w = ty[1];
if (NY == 3)
w += ty[2];
r = ty[0] + w;
/* TODO: for ld128 this does not follow the recommendation of the
comments of __rem_pio2_large which seem wrong if |ty[0]| > |ty[1]+ty[2]| */
w -= r - ty[0];
if (u.i.se >> 15) {
y[0] = -r;
y[1] = -w;
return -n;
}
y[0] = r;
y[1] = w;
return n;
}
#endif

View File

@ -1,13 +0,0 @@
#include "libm.h"
// FIXME: macro in math.h
int __signbit(double x)
{
union {
double d;
uint64_t i;
} y = { x };
return y.i>>63;
}

View File

@ -1,11 +0,0 @@
#include "libm.h"
// FIXME: macro in math.h
int __signbitf(float x)
{
union {
float f;
uint32_t i;
} y = { x };
return y.i>>31;
}

View File

@ -1,14 +0,0 @@
#include "libm.h"
#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
int __signbitl(long double x)
{
union ldshape u = {x};
return u.i.se >> 15;
}
#elif LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
int __signbitl(long double x)
{
return __signbit(x);
}
#endif

View File

@ -1,64 +0,0 @@
/* origin: FreeBSD /usr/src/lib/msun/src/k_sin.c */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/* __sin( x, y, iy)
* kernel sin function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854
* Input x is assumed to be bounded by ~pi/4 in magnitude.
* Input y is the tail of x.
* Input iy indicates whether y is 0. (if iy=0, y assume to be 0).
*
* Algorithm
* 1. Since sin(-x) = -sin(x), we need only to consider positive x.
* 2. Callers must return sin(-0) = -0 without calling here since our
* odd polynomial is not evaluated in a way that preserves -0.
* Callers may do the optimization sin(x) ~ x for tiny x.
* 3. sin(x) is approximated by a polynomial of degree 13 on
* [0,pi/4]
* 3 13
* sin(x) ~ x + S1*x + ... + S6*x
* where
*
* |sin(x) 2 4 6 8 10 12 | -58
* |----- - (1+S1*x +S2*x +S3*x +S4*x +S5*x +S6*x )| <= 2
* | x |
*
* 4. sin(x+y) = sin(x) + sin'(x')*y
* ~ sin(x) + (1-x*x/2)*y
* For better accuracy, let
* 3 2 2 2 2
* r = x *(S2+x *(S3+x *(S4+x *(S5+x *S6))))
* then 3 2
* sin(x) = x + (S1*x + (x *(r-y/2)+y))
*/
#include "libm.h"
static const double
S1 = -1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */
S2 = 8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */
S3 = -1.98412698298579493134e-04, /* 0xBF2A01A0, 0x19C161D5 */
S4 = 2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */
S5 = -2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */
S6 = 1.58969099521155010221e-10; /* 0x3DE5D93A, 0x5ACFD57C */
double __sin(double x, double y, int iy)
{
double_t z,r,v,w;
z = x*x;
w = z*z;
r = S2 + z*(S3 + z*S4) + z*w*(S5 + z*S6);
v = z*x;
if (iy == 0)
return x + v*(S1 + z*r);
else
return x - ((z*(0.5*y - v*r) - y) - v*S1);
}

View File

@ -1,36 +0,0 @@
/* origin: FreeBSD /usr/src/lib/msun/src/k_sinf.c */
/*
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
* Optimized by Bruce D. Evans.
*/
/*
* ====================================================
* 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.
* ====================================================
*/
#include "libm.h"
/* |sin(x)/x - s(x)| < 2**-37.5 (~[-4.89e-12, 4.824e-12]). */
static const double
S1 = -0x15555554cbac77.0p-55, /* -0.166666666416265235595 */
S2 = 0x111110896efbb2.0p-59, /* 0.0083333293858894631756 */
S3 = -0x1a00f9e2cae774.0p-65, /* -0.000198393348360966317347 */
S4 = 0x16cd878c3b46a7.0p-71; /* 0.0000027183114939898219064 */
float __sindf(double x)
{
double_t r, s, w, z;
/* Try to optimize for parallel evaluation as in __tandf.c. */
z = x*x;
w = z*z;
r = S3 + z*S4;
s = z*x;
return (x + s*(S1 + z*S2)) + s*w*r;
}

View File

@ -1,78 +0,0 @@
/* origin: FreeBSD /usr/src/lib/msun/ld80/k_sinl.c */
/* origin: FreeBSD /usr/src/lib/msun/ld128/k_sinl.c */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
* Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans.
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
#include "libm.h"
#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
#if LDBL_MANT_DIG == 64
/*
* ld80 version of __sin.c. See __sin.c for most comments.
*/
/*
* Domain [-0.7854, 0.7854], range ~[-1.89e-22, 1.915e-22]
* |sin(x)/x - s(x)| < 2**-72.1
*
* See __cosl.c for more details about the polynomial.
*/
static const long double
S1 = -0.166666666666666666671L; /* -0xaaaaaaaaaaaaaaab.0p-66 */
static const double
S2 = 0.0083333333333333332, /* 0x11111111111111.0p-59 */
S3 = -0.00019841269841269427, /* -0x1a01a01a019f81.0p-65 */
S4 = 0.0000027557319223597490, /* 0x171de3a55560f7.0p-71 */
S5 = -0.000000025052108218074604, /* -0x1ae64564f16cad.0p-78 */
S6 = 1.6059006598854211e-10, /* 0x161242b90243b5.0p-85 */
S7 = -7.6429779983024564e-13, /* -0x1ae42ebd1b2e00.0p-93 */
S8 = 2.6174587166648325e-15; /* 0x179372ea0b3f64.0p-101 */
#define POLY(z) (S2+z*(S3+z*(S4+z*(S5+z*(S6+z*(S7+z*S8))))))
#elif LDBL_MANT_DIG == 113
/*
* ld128 version of __sin.c. See __sin.c for most comments.
*/
/*
* Domain [-0.7854, 0.7854], range ~[-1.53e-37, 1.659e-37]
* |sin(x)/x - s(x)| < 2**-122.1
*
* See __cosl.c for more details about the polynomial.
*/
static const long double
S1 = -0.16666666666666666666666666666666666606732416116558L,
S2 = 0.0083333333333333333333333333333331135404851288270047L,
S3 = -0.00019841269841269841269841269839935785325638310428717L,
S4 = 0.27557319223985890652557316053039946268333231205686e-5L,
S5 = -0.25052108385441718775048214826384312253862930064745e-7L,
S6 = 0.16059043836821614596571832194524392581082444805729e-9L,
S7 = -0.76471637318198151807063387954939213287488216303768e-12L,
S8 = 0.28114572543451292625024967174638477283187397621303e-14L;
static const double
S9 = -0.82206352458348947812512122163446202498005154296863e-17,
S10 = 0.19572940011906109418080609928334380560135358385256e-19,
S11 = -0.38680813379701966970673724299207480965452616911420e-22,
S12 = 0.64038150078671872796678569586315881020659912139412e-25;
#define POLY(z) (S2+z*(S3+z*(S4+z*(S5+z*(S6+z*(S7+z*(S8+ \
z*(S9+z*(S10+z*(S11+z*S12))))))))))
#endif
long double __sinl(long double x, long double y, int iy)
{
long double z,r,v;
z = x*x;
v = z*x;
r = POLY(z);
if (iy == 0)
return x+v*(S1+z*r);
return x-((z*(0.5*y-v*r)-y)-v*S1);
}
#endif

View File

@ -1,110 +0,0 @@
/* origin: FreeBSD /usr/src/lib/msun/src/k_tan.c */
/*
* ====================================================
* Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
*
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/* __tan( x, y, k )
* kernel tan function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854
* Input x is assumed to be bounded by ~pi/4 in magnitude.
* Input y is the tail of x.
* Input odd indicates whether tan (if odd = 0) or -1/tan (if odd = 1) is returned.
*
* Algorithm
* 1. Since tan(-x) = -tan(x), we need only to consider positive x.
* 2. Callers must return tan(-0) = -0 without calling here since our
* odd polynomial is not evaluated in a way that preserves -0.
* Callers may do the optimization tan(x) ~ x for tiny x.
* 3. tan(x) is approximated by a odd polynomial of degree 27 on
* [0,0.67434]
* 3 27
* tan(x) ~ x + T1*x + ... + T13*x
* where
*
* |tan(x) 2 4 26 | -59.2
* |----- - (1+T1*x +T2*x +.... +T13*x )| <= 2
* | x |
*
* Note: tan(x+y) = tan(x) + tan'(x)*y
* ~ tan(x) + (1+x*x)*y
* Therefore, for better accuracy in computing tan(x+y), let
* 3 2 2 2 2
* r = x *(T2+x *(T3+x *(...+x *(T12+x *T13))))
* then
* 3 2
* tan(x+y) = x + (T1*x + (x *(r+y)+y))
*
* 4. For x in [0.67434,pi/4], let y = pi/4 - x, then
* tan(x) = tan(pi/4-y) = (1-tan(y))/(1+tan(y))
* = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y)))
*/
#include "libm.h"
static const double T[] = {
3.33333333333334091986e-01, /* 3FD55555, 55555563 */
1.33333333333201242699e-01, /* 3FC11111, 1110FE7A */
5.39682539762260521377e-02, /* 3FABA1BA, 1BB341FE */
2.18694882948595424599e-02, /* 3F9664F4, 8406D637 */
8.86323982359930005737e-03, /* 3F8226E3, E96E8493 */
3.59207910759131235356e-03, /* 3F6D6D22, C9560328 */
1.45620945432529025516e-03, /* 3F57DBC8, FEE08315 */
5.88041240820264096874e-04, /* 3F4344D8, F2F26501 */
2.46463134818469906812e-04, /* 3F3026F7, 1A8D1068 */
7.81794442939557092300e-05, /* 3F147E88, A03792A6 */
7.14072491382608190305e-05, /* 3F12B80F, 32F0A7E9 */
-1.85586374855275456654e-05, /* BEF375CB, DB605373 */
2.59073051863633712884e-05, /* 3EFB2A70, 74BF7AD4 */
},
pio4 = 7.85398163397448278999e-01, /* 3FE921FB, 54442D18 */
pio4lo = 3.06161699786838301793e-17; /* 3C81A626, 33145C07 */
double __tan(double x, double y, int odd)
{
double_t z, r, v, w, s, a;
double w0, a0;
uint32_t hx;
int big, sign;
GET_HIGH_WORD(hx,x);
big = (hx&0x7fffffff) >= 0x3FE59428; /* |x| >= 0.6744 */
if (big) {
sign = hx>>31;
if (sign) {
x = -x;
y = -y;
}
x = (pio4 - x) + (pio4lo - y);
y = 0.0;
}
z = x * x;
w = z * z;
/*
* Break x^5*(T[1]+x^2*T[2]+...) into
* x^5(T[1]+x^4*T[3]+...+x^20*T[11]) +
* x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12]))
*/
r = T[1] + w*(T[3] + w*(T[5] + w*(T[7] + w*(T[9] + w*T[11]))));
v = z*(T[2] + w*(T[4] + w*(T[6] + w*(T[8] + w*(T[10] + w*T[12])))));
s = z * x;
r = y + z*(s*(r + v) + y) + s*T[0];
w = x + r;
if (big) {
s = 1 - 2*odd;
v = s - 2.0 * (x + (r - w*w/(w + s)));
return sign ? -v : v;
}
if (!odd)
return w;
/* -1.0/(x+r) has up to 2ulp error, so compute it accurately */
w0 = w;
SET_LOW_WORD(w0, 0);
v = r - (w0 - x); /* w0+v = r+x */
a0 = a = -1.0 / w;
SET_LOW_WORD(a0, 0);
return a0 + a*(1.0 + a0*w0 + a0*v);
}

View File

@ -1,54 +0,0 @@
/* origin: FreeBSD /usr/src/lib/msun/src/k_tanf.c */
/*
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
* Optimized by Bruce D. Evans.
*/
/*
* ====================================================
* Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
*
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
#include "libm.h"
/* |tan(x)/x - t(x)| < 2**-25.5 (~[-2e-08, 2e-08]). */
static const double T[] = {
0x15554d3418c99f.0p-54, /* 0.333331395030791399758 */
0x1112fd38999f72.0p-55, /* 0.133392002712976742718 */
0x1b54c91d865afe.0p-57, /* 0.0533812378445670393523 */
0x191df3908c33ce.0p-58, /* 0.0245283181166547278873 */
0x185dadfcecf44e.0p-61, /* 0.00297435743359967304927 */
0x1362b9bf971bcd.0p-59, /* 0.00946564784943673166728 */
};
float __tandf(double x, int odd)
{
double_t z,r,w,s,t,u;
z = x*x;
/*
* Split up the polynomial into small independent terms to give
* opportunities for parallel evaluation. The chosen splitting is
* micro-optimized for Athlons (XP, X64). It costs 2 multiplications
* relative to Horner's method on sequential machines.
*
* We add the small terms from lowest degree up for efficiency on
* non-sequential machines (the lowest degree terms tend to be ready
* earlier). Apart from this, we don't care about order of
* operations, and don't need to to care since we have precision to
* spare. However, the chosen splitting is good for accuracy too,
* and would give results as accurate as Horner's method if the
* small terms were added from highest degree down.
*/
r = T[4] + z*T[5];
t = T[2] + z*T[3];
w = z*z;
s = z*x;
u = T[0] + z*T[1];
r = (x + s*u) + (s*w)*(t + w*r);
return odd ? -1.0/r : r;
}

View File

@ -1,143 +0,0 @@
/* origin: FreeBSD /usr/src/lib/msun/ld80/k_tanl.c */
/* origin: FreeBSD /usr/src/lib/msun/ld128/k_tanl.c */
/*
* ====================================================
* Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
* Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans.
*
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
#include "libm.h"
#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
#if LDBL_MANT_DIG == 64
/*
* ld80 version of __tan.c. See __tan.c for most comments.
*/
/*
* Domain [-0.67434, 0.67434], range ~[-2.25e-22, 1.921e-22]
* |tan(x)/x - t(x)| < 2**-71.9
*
* See __cosl.c for more details about the polynomial.
*/
static const long double
T3 = 0.333333333333333333180L, /* 0xaaaaaaaaaaaaaaa5.0p-65 */
T5 = 0.133333333333333372290L, /* 0x88888888888893c3.0p-66 */
T7 = 0.0539682539682504975744L, /* 0xdd0dd0dd0dc13ba2.0p-68 */
pio4 = 0.785398163397448309628L, /* 0xc90fdaa22168c235.0p-64 */
pio4lo = -1.25413940316708300586e-20L; /* -0xece675d1fc8f8cbb.0p-130 */
static const double
T9 = 0.021869488536312216, /* 0x1664f4882cc1c2.0p-58 */
T11 = 0.0088632355256619590, /* 0x1226e355c17612.0p-59 */
T13 = 0.0035921281113786528, /* 0x1d6d3d185d7ff8.0p-61 */
T15 = 0.0014558334756312418, /* 0x17da354aa3f96b.0p-62 */
T17 = 0.00059003538700862256, /* 0x13559358685b83.0p-63 */
T19 = 0.00023907843576635544, /* 0x1f56242026b5be.0p-65 */
T21 = 0.000097154625656538905, /* 0x1977efc26806f4.0p-66 */
T23 = 0.000038440165747303162, /* 0x14275a09b3ceac.0p-67 */
T25 = 0.000018082171885432524, /* 0x12f5e563e5487e.0p-68 */
T27 = 0.0000024196006108814377, /* 0x144c0d80cc6896.0p-71 */
T29 = 0.0000078293456938132840, /* 0x106b59141a6cb3.0p-69 */
T31 = -0.0000032609076735050182, /* -0x1b5abef3ba4b59.0p-71 */
T33 = 0.0000023261313142559411; /* 0x13835436c0c87f.0p-71 */
#define RPOLY(w) (T5 + w * (T9 + w * (T13 + w * (T17 + w * (T21 + \
w * (T25 + w * (T29 + w * T33)))))))
#define VPOLY(w) (T7 + w * (T11 + w * (T15 + w * (T19 + w * (T23 + \
w * (T27 + w * T31))))))
#elif LDBL_MANT_DIG == 113
/*
* ld128 version of __tan.c. See __tan.c for most comments.
*/
/*
* Domain [-0.67434, 0.67434], range ~[-3.37e-36, 1.982e-37]
* |tan(x)/x - t(x)| < 2**-117.8 (XXX should be ~1e-37)
*
* See __cosl.c for more details about the polynomial.
*/
static const long double
T3 = 0x1.5555555555555555555555555553p-2L,
T5 = 0x1.1111111111111111111111111eb5p-3L,
T7 = 0x1.ba1ba1ba1ba1ba1ba1ba1b694cd6p-5L,
T9 = 0x1.664f4882c10f9f32d6bbe09d8bcdp-6L,
T11 = 0x1.226e355e6c23c8f5b4f5762322eep-7L,
T13 = 0x1.d6d3d0e157ddfb5fed8e84e27b37p-9L,
T15 = 0x1.7da36452b75e2b5fce9ee7c2c92ep-10L,
T17 = 0x1.355824803674477dfcf726649efep-11L,
T19 = 0x1.f57d7734d1656e0aceb716f614c2p-13L,
T21 = 0x1.967e18afcb180ed942dfdc518d6cp-14L,
T23 = 0x1.497d8eea21e95bc7e2aa79b9f2cdp-15L,
T25 = 0x1.0b132d39f055c81be49eff7afd50p-16L,
T27 = 0x1.b0f72d33eff7bfa2fbc1059d90b6p-18L,
T29 = 0x1.5ef2daf21d1113df38d0fbc00267p-19L,
T31 = 0x1.1c77d6eac0234988cdaa04c96626p-20L,
T33 = 0x1.cd2a5a292b180e0bdd701057dfe3p-22L,
T35 = 0x1.75c7357d0298c01a31d0a6f7d518p-23L,
T37 = 0x1.2f3190f4718a9a520f98f50081fcp-24L,
pio4 = 0x1.921fb54442d18469898cc51701b8p-1L,
pio4lo = 0x1.cd129024e088a67cc74020bbea60p-116L;
static const double
T39 = 0.000000028443389121318352, /* 0x1e8a7592977938.0p-78 */
T41 = 0.000000011981013102001973, /* 0x19baa1b1223219.0p-79 */
T43 = 0.0000000038303578044958070, /* 0x107385dfb24529.0p-80 */
T45 = 0.0000000034664378216909893, /* 0x1dc6c702a05262.0p-81 */
T47 = -0.0000000015090641701997785, /* -0x19ecef3569ebb6.0p-82 */
T49 = 0.0000000029449552300483952, /* 0x194c0668da786a.0p-81 */
T51 = -0.0000000022006995706097711, /* -0x12e763b8845268.0p-81 */
T53 = 0.0000000015468200913196612, /* 0x1a92fc98c29554.0p-82 */
T55 = -0.00000000061311613386849674, /* -0x151106cbc779a9.0p-83 */
T57 = 1.4912469681508012e-10; /* 0x147edbdba6f43a.0p-85 */
#define RPOLY(w) (T5 + w * (T9 + w * (T13 + w * (T17 + w * (T21 + \
w * (T25 + w * (T29 + w * (T33 + w * (T37 + w * (T41 + \
w * (T45 + w * (T49 + w * (T53 + w * T57)))))))))))))
#define VPOLY(w) (T7 + w * (T11 + w * (T15 + w * (T19 + w * (T23 + \
w * (T27 + w * (T31 + w * (T35 + w * (T39 + w * (T43 + \
w * (T47 + w * (T51 + w * T55))))))))))))
#endif
long double __tanl(long double x, long double y, int odd) {
long double z, r, v, w, s, a, t;
int big, sign;
big = fabsl(x) >= 0.67434;
if (big) {
sign = 0;
if (x < 0) {
sign = 1;
x = -x;
y = -y;
}
x = (pio4 - x) + (pio4lo - y);
y = 0.0;
}
z = x * x;
w = z * z;
r = RPOLY(w);
v = z * VPOLY(w);
s = z * x;
r = y + z * (s * (r + v) + y) + T3 * s;
w = x + r;
if (big) {
s = 1 - 2*odd;
v = s - 2.0 * (x + (r - w * w / (w + s)));
return sign ? -v : v;
}
if (!odd)
return w;
/*
* if allow error up to 2 ulp, simply return
* -1.0 / (x+r) here
*/
/* compute -1.0 / (x+r) accurately */
z = w;
z = z + 0x1p32 - 0x1p32;
v = r - (z - x); /* z+v = r+x */
t = a = -1.0 / w; /* a = -1.0/w */
t = t + 0x1p32 - 0x1p32;
s = 1.0 + t * z;
return t + a * (s + t * v);
}
#endif

View File

@ -1,101 +0,0 @@
/* origin: FreeBSD /usr/src/lib/msun/src/e_acos.c */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/* acos(x)
* Method :
* acos(x) = pi/2 - asin(x)
* acos(-x) = pi/2 + asin(x)
* For |x|<=0.5
* acos(x) = pi/2 - (x + x*x^2*R(x^2)) (see asin.c)
* For x>0.5
* acos(x) = pi/2 - (pi/2 - 2asin(sqrt((1-x)/2)))
* = 2asin(sqrt((1-x)/2))
* = 2s + 2s*z*R(z) ...z=(1-x)/2, s=sqrt(z)
* = 2f + (2c + 2s*z*R(z))
* where f=hi part of s, and c = (z-f*f)/(s+f) is the correction term
* for f so that f+c ~ sqrt(z).
* For x<-0.5
* acos(x) = pi - 2asin(sqrt((1-|x|)/2))
* = pi - 0.5*(s+s*z*R(z)), where z=(1-|x|)/2,s=sqrt(z)
*
* Special cases:
* if x is NaN, return x itself;
* if |x|>1, return NaN with invalid signal.
*
* Function needed: sqrt
*/
#include "libm.h"
static const double
pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */
pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */
pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */
pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */
pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */
pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */
pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */
pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */
qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */
qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */
qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
static double R(double z)
{
double_t p, q;
p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
q = 1.0+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
return p/q;
}
double acos(double x)
{
double z,w,s,c,df;
uint32_t hx,ix;
GET_HIGH_WORD(hx, x);
ix = hx & 0x7fffffff;
/* |x| >= 1 or nan */
if (ix >= 0x3ff00000) {
uint32_t lx;
GET_LOW_WORD(lx,x);
if ((ix-0x3ff00000 | lx) == 0) {
/* acos(1)=0, acos(-1)=pi */
if (hx >> 31)
return 2*pio2_hi + 0x1p-120f;
return 0;
}
return 0/(x-x);
}
/* |x| < 0.5 */
if (ix < 0x3fe00000) {
if (ix <= 0x3c600000) /* |x| < 2**-57 */
return pio2_hi + 0x1p-120f;
return pio2_hi - (x - (pio2_lo-x*R(x*x)));
}
/* x < -0.5 */
if (hx >> 31) {
z = (1.0+x)*0.5;
s = sqrt(z);
w = R(z)*s-pio2_lo;
return 2*(pio2_hi - (s+w));
}
/* x > 0.5 */
z = (1.0-x)*0.5;
s = sqrt(z);
df = s;
SET_LOW_WORD(df,0);
c = (z-df*df)/(s+df);
w = R(z)*s+c;
return 2*(df+w);
}

View File

@ -1,71 +0,0 @@
/* origin: FreeBSD /usr/src/lib/msun/src/e_acosf.c */
/*
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/*
* ====================================================
* 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.
* ====================================================
*/
#include "libm.h"
static const float
pio2_hi = 1.5707962513e+00, /* 0x3fc90fda */
pio2_lo = 7.5497894159e-08, /* 0x33a22168 */
pS0 = 1.6666586697e-01,
pS1 = -4.2743422091e-02,
pS2 = -8.6563630030e-03,
qS1 = -7.0662963390e-01;
static float R(float z)
{
float_t p, q;
p = z*(pS0+z*(pS1+z*pS2));
q = 1.0f+z*qS1;
return p/q;
}
float acosf(float x)
{
float z,w,s,c,df;
uint32_t hx,ix;
GET_FLOAT_WORD(hx, x);
ix = hx & 0x7fffffff;
/* |x| >= 1 or nan */
if (ix >= 0x3f800000) {
if (ix == 0x3f800000) {
if (hx >> 31)
return 2*pio2_hi + 0x1p-120f;
return 0;
}
return 0/(x-x);
}
/* |x| < 0.5 */
if (ix < 0x3f000000) {
if (ix <= 0x32800000) /* |x| < 2**-26 */
return pio2_hi + 0x1p-120f;
return pio2_hi - (x - (pio2_lo-x*R(x*x)));
}
/* x < -0.5 */
if (hx >> 31) {
z = (1+x)*0.5f;
s = sqrtf(z);
w = R(z)*s-pio2_lo;
return 2*(pio2_hi - (s+w));
}
/* x > 0.5 */
z = (1-x)*0.5f;
s = sqrtf(z);
GET_FLOAT_WORD(hx,s);
SET_FLOAT_WORD(df,hx&0xfffff000);
c = (z-df*df)/(s+df);
w = R(z)*s+c;
return 2*(df+w);
}

View File

@ -1,24 +0,0 @@
#include "libm.h"
#if FLT_EVAL_METHOD==2
#undef sqrt
#define sqrt sqrtl
#endif
/* acosh(x) = log(x + sqrt(x*x-1)) */
double acosh(double x)
{
union {double f; uint64_t i;} u = {.f = x};
unsigned e = u.i >> 52 & 0x7ff;
/* x < 1 domain error is handled in the called functions */
if (e < 0x3ff + 1)
/* |x| < 2, up to 2ulp error in [1,1.125] */
return log1p(x-1 + sqrt((x-1)*(x-1)+2*(x-1)));
if (e < 0x3ff + 26)
/* |x| < 0x1p26 */
return log(2*x - 1/(x+sqrt(x*x-1)));
/* |x| >= 0x1p26 or nan */
return log(x) + 0.693147180559945309417232121458176568;
}

View File

@ -1,26 +0,0 @@
#include "libm.h"
#if FLT_EVAL_METHOD==2
#undef sqrtf
#define sqrtf sqrtl
#elif FLT_EVAL_METHOD==1
#undef sqrtf
#define sqrtf sqrt
#endif
/* acosh(x) = log(x + sqrt(x*x-1)) */
float acoshf(float x)
{
union {float f; uint32_t i;} u = {x};
uint32_t a = u.i & 0x7fffffff;
if (a < 0x3f800000+(1<<23))
/* |x| < 2, invalid if x < 1 or nan */
/* up to 2ulp error in [1,1.125] */
return log1pf(x-1 + sqrtf((x-1)*(x-1)+2*(x-1)));
if (a < 0x3f800000+(12<<23))
/* |x| < 0x1p12 */
return logf(2*x - 1/(x+sqrtf(x*x-1)));
/* x >= 0x1p12 */
return logf(x) + 0.693147180559945309417232121458176568f;
}

View File

@ -1,29 +0,0 @@
#include "libm.h"
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
long double acoshl(long double x)
{
return acosh(x);
}
#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
/* acosh(x) = log(x + sqrt(x*x-1)) */
long double acoshl(long double x)
{
union ldshape u = {x};
int e = u.i.se & 0x7fff;
if (e < 0x3fff + 1)
/* |x| < 2, invalid if x < 1 or nan */
return log1pl(x-1 + sqrtl((x-1)*(x-1)+2*(x-1)));
if (e < 0x3fff + 32)
/* |x| < 0x1p32 */
return logl(2*x - 1/(x+sqrtl(x*x-1)));
return logl(x) + 0.693147180559945309417232121458176568L;
}
#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
// TODO: broken implementation to make things compile
long double acoshl(long double x)
{
return acosh(x);
}
#endif

View File

@ -1,67 +0,0 @@
/* origin: FreeBSD /usr/src/lib/msun/src/e_acosl.c */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
* See comments in acos.c.
* Converted to long double by David Schultz <das@FreeBSD.ORG>.
*/
#include "libm.h"
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
long double acosl(long double x)
{
return acos(x);
}
#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
#include "__invtrigl.h"
#if LDBL_MANT_DIG == 64
#define CLEARBOTTOM(u) (u.i.m &= -1ULL << 32)
#elif LDBL_MANT_DIG == 113
#define CLEARBOTTOM(u) (u.i.lo = 0)
#endif
long double acosl(long double x)
{
union ldshape u = {x};
long double z, s, c, f;
uint16_t e = u.i.se & 0x7fff;
/* |x| >= 1 or nan */
if (e >= 0x3fff) {
if (x == 1)
return 0;
if (x == -1)
return 2*pio2_hi + 0x1p-120f;
return 0/(x-x);
}
/* |x| < 0.5 */
if (e < 0x3fff - 1) {
if (e < 0x3fff - LDBL_MANT_DIG - 1)
return pio2_hi + 0x1p-120f;
return pio2_hi - (__invtrigl_R(x*x)*x - pio2_lo + x);
}
/* x < -0.5 */
if (u.i.se >> 15) {
z = (1 + x)*0.5;
s = sqrtl(z);
return 2*(pio2_hi - (__invtrigl_R(z)*s - pio2_lo + s));
}
/* x > 0.5 */
z = (1 - x)*0.5;
s = sqrtl(z);
u.f = s;
CLEARBOTTOM(u);
f = u.f;
c = (z - f*f)/(s + f);
return 2*(__invtrigl_R(z)*s + c + f);
}
#endif

View File

@ -1,107 +0,0 @@
/* origin: FreeBSD /usr/src/lib/msun/src/e_asin.c */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/* asin(x)
* Method :
* Since asin(x) = x + x^3/6 + x^5*3/40 + x^7*15/336 + ...
* we approximate asin(x) on [0,0.5] by
* asin(x) = x + x*x^2*R(x^2)
* where
* R(x^2) is a rational approximation of (asin(x)-x)/x^3
* and its remez error is bounded by
* |(asin(x)-x)/x^3 - R(x^2)| < 2^(-58.75)
*
* For x in [0.5,1]
* asin(x) = pi/2-2*asin(sqrt((1-x)/2))
* Let y = (1-x), z = y/2, s := sqrt(z), and pio2_hi+pio2_lo=pi/2;
* then for x>0.98
* asin(x) = pi/2 - 2*(s+s*z*R(z))
* = pio2_hi - (2*(s+s*z*R(z)) - pio2_lo)
* For x<=0.98, let pio4_hi = pio2_hi/2, then
* f = hi part of s;
* c = sqrt(z) - f = (z-f*f)/(s+f) ...f+c=sqrt(z)
* and
* asin(x) = pi/2 - 2*(s+s*z*R(z))
* = pio4_hi+(pio4-2s)-(2s*z*R(z)-pio2_lo)
* = pio4_hi+(pio4-2f)-(2s*z*R(z)-(pio2_lo+2c))
*
* Special cases:
* if x is NaN, return x itself;
* if |x|>1, return NaN with invalid signal.
*
*/
#include "libm.h"
static const double
pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */
pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */
/* coefficients for R(x^2) */
pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */
pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */
pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */
pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */
pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */
pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */
qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */
qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */
qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
static double R(double z)
{
double_t p, q;
p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
q = 1.0+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
return p/q;
}
double asin(double x)
{
double z,r,s;
uint32_t hx,ix;
GET_HIGH_WORD(hx, x);
ix = hx & 0x7fffffff;
/* |x| >= 1 or nan */
if (ix >= 0x3ff00000) {
uint32_t lx;
GET_LOW_WORD(lx, x);
if ((ix-0x3ff00000 | lx) == 0)
/* asin(1) = +-pi/2 with inexact */
return x*pio2_hi + 0x1p-120f;
return 0/(x-x);
}
/* |x| < 0.5 */
if (ix < 0x3fe00000) {
/* if 0x1p-1022 <= |x| < 0x1p-26, avoid raising underflow */
if (ix < 0x3e500000 && ix >= 0x00100000)
return x;
return x + x*R(x*x);
}
/* 1 > |x| >= 0.5 */
z = (1 - fabs(x))*0.5;
s = sqrt(z);
r = R(z);
if (ix >= 0x3fef3333) { /* if |x| > 0.975 */
x = pio2_hi-(2*(s+s*r)-pio2_lo);
} else {
double f,c;
/* f+c = sqrt(z) */
f = s;
SET_LOW_WORD(f,0);
c = (z-f*f)/(s+f);
x = 0.5*pio2_hi - (2*s*r - (pio2_lo-2*c) - (0.5*pio2_hi-2*f));
}
if (hx >> 31)
return -x;
return x;
}

View File

@ -1,61 +0,0 @@
/* origin: FreeBSD /usr/src/lib/msun/src/e_asinf.c */
/*
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/*
* ====================================================
* 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.
* ====================================================
*/
#include "libm.h"
static const double
pio2 = 1.570796326794896558e+00;
static const float
/* coefficients for R(x^2) */
pS0 = 1.6666586697e-01,
pS1 = -4.2743422091e-02,
pS2 = -8.6563630030e-03,
qS1 = -7.0662963390e-01;
static float R(float z)
{
float_t p, q;
p = z*(pS0+z*(pS1+z*pS2));
q = 1.0f+z*qS1;
return p/q;
}
float asinf(float x)
{
double s;
float z;
uint32_t hx,ix;
GET_FLOAT_WORD(hx, x);
ix = hx & 0x7fffffff;
if (ix >= 0x3f800000) { /* |x| >= 1 */
if (ix == 0x3f800000) /* |x| == 1 */
return x*pio2 + 0x1p-120f; /* asin(+-1) = +-pi/2 with inexact */
return 0/(x-x); /* asin(|x|>1) is NaN */
}
if (ix < 0x3f000000) { /* |x| < 0.5 */
/* if 0x1p-126 <= |x| < 0x1p-12, avoid raising underflow */
if (ix < 0x39800000 && ix >= 0x00800000)
return x;
return x + x*R(x*x);
}
/* 1 > |x| >= 0.5 */
z = (1 - fabsf(x))*0.5f;
s = sqrt(z);
x = pio2 - 2*(s+s*R(z));
if (hx >> 31)
return -x;
return x;
}

View File

@ -1,28 +0,0 @@
#include "libm.h"
/* asinh(x) = sign(x)*log(|x|+sqrt(x*x+1)) ~= x - x^3/6 + o(x^5) */
double asinh(double x)
{
union {double f; uint64_t i;} u = {.f = x};
unsigned e = u.i >> 52 & 0x7ff;
unsigned s = u.i >> 63;
/* |x| */
u.i &= (uint64_t)-1/2;
x = u.f;
if (e >= 0x3ff + 26) {
/* |x| >= 0x1p26 or inf or nan */
x = log(x) + 0.693147180559945309417232121458176568;
} else if (e >= 0x3ff + 1) {
/* |x| >= 2 */
x = log(2*x + 1/(sqrt(x*x+1)+x));
} else if (e >= 0x3ff - 26) {
/* |x| >= 0x1p-26, up to 1.6ulp error in [0.125,0.5] */
x = log1p(x + x*x/(sqrt(x*x+1)+1));
} else {
/* |x| < 0x1p-26, raise inexact if x != 0 */
FORCE_EVAL(x + 0x1p120f);
}
return s ? -x : x;
}

View File

@ -1,28 +0,0 @@
#include "libm.h"
/* asinh(x) = sign(x)*log(|x|+sqrt(x*x+1)) ~= x - x^3/6 + o(x^5) */
float asinhf(float x)
{
union {float f; uint32_t i;} u = {.f = x};
uint32_t i = u.i & 0x7fffffff;
unsigned s = u.i >> 31;
/* |x| */
u.i = i;
x = u.f;
if (i >= 0x3f800000 + (12<<23)) {
/* |x| >= 0x1p12 or inf or nan */
x = logf(x) + 0.693147180559945309417232121458176568f;
} else if (i >= 0x3f800000 + (1<<23)) {
/* |x| >= 2 */
x = logf(2*x + 1/(sqrtf(x*x+1)+x));
} else if (i >= 0x3f800000 - (12<<23)) {
/* |x| >= 0x1p-12, up to 1.6ulp error in [0.125,0.5] */
x = log1pf(x + x*x/(sqrtf(x*x+1)+1));
} else {
/* |x| < 0x1p-12, raise inexact if x!=0 */
FORCE_EVAL(x + 0x1p120f);
}
return s ? -x : x;
}

View File

@ -1,41 +0,0 @@
#include "libm.h"
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
long double asinhl(long double x)
{
return asinh(x);
}
#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
/* asinh(x) = sign(x)*log(|x|+sqrt(x*x+1)) ~= x - x^3/6 + o(x^5) */
long double asinhl(long double x)
{
union ldshape u = {x};
unsigned e = u.i.se & 0x7fff;
unsigned s = u.i.se >> 15;
/* |x| */
u.i.se = e;
x = u.f;
if (e >= 0x3fff + 32) {
/* |x| >= 0x1p32 or inf or nan */
x = logl(x) + 0.693147180559945309417232121458176568L;
} else if (e >= 0x3fff + 1) {
/* |x| >= 2 */
x = logl(2*x + 1/(sqrtl(x*x+1)+x));
} else if (e >= 0x3fff - 32) {
/* |x| >= 0x1p-32 */
x = log1pl(x + x*x/(sqrtl(x*x+1)+1));
} else {
/* |x| < 0x1p-32, raise inexact if x!=0 */
FORCE_EVAL(x + 0x1p120f);
}
return s ? -x : x;
}
#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
// TODO: broken implementation to make things compile
long double asinhl(long double x)
{
return asinh(x);
}
#endif

View File

@ -1,71 +0,0 @@
/* origin: FreeBSD /usr/src/lib/msun/src/e_asinl.c */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
* See comments in asin.c.
* Converted to long double by David Schultz <das@FreeBSD.ORG>.
*/
#include "libm.h"
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
long double asinl(long double x)
{
return asin(x);
}
#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
#include "__invtrigl.h"
#if LDBL_MANT_DIG == 64
#define CLOSETO1(u) (u.i.m>>56 >= 0xf7)
#define CLEARBOTTOM(u) (u.i.m &= -1ULL << 32)
#elif LDBL_MANT_DIG == 113
#define CLOSETO1(u) (u.i.top >= 0xee00)
#define CLEARBOTTOM(u) (u.i.lo = 0)
#endif
long double asinl(long double x)
{
union ldshape u = {x};
long double z, r, s;
uint16_t e = u.i.se & 0x7fff;
int sign = u.i.se >> 15;
if (e >= 0x3fff) { /* |x| >= 1 or nan */
/* asin(+-1)=+-pi/2 with inexact */
if (x == 1 || x == -1)
return x*pio2_hi + 0x1p-120f;
return 0/(x-x);
}
if (e < 0x3fff - 1) { /* |x| < 0.5 */
if (e < 0x3fff - (LDBL_MANT_DIG+1)/2) {
/* return x with inexact if x!=0 */
FORCE_EVAL(x + 0x1p120f);
return x;
}
return x + x*__invtrigl_R(x*x);
}
/* 1 > |x| >= 0.5 */
z = (1.0 - fabsl(x))*0.5;
s = sqrtl(z);
r = __invtrigl_R(z);
if (CLOSETO1(u)) {
x = pio2_hi - (2*(s+s*r)-pio2_lo);
} else {
long double f, c;
u.f = s;
CLEARBOTTOM(u);
f = u.f;
c = (z - f*f)/(s + f);
x = 0.5*pio2_hi-(2*s*r - (pio2_lo-2*c) - (0.5*pio2_hi-2*f));
}
return sign ? -x : x;
}
#endif

View File

@ -1,116 +0,0 @@
/* origin: FreeBSD /usr/src/lib/msun/src/s_atan.c */
/*
* ====================================================
* 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.
* ====================================================
*/
/* atan(x)
* Method
* 1. Reduce x to positive by atan(x) = -atan(-x).
* 2. According to the integer k=4t+0.25 chopped, t=x, the argument
* is further reduced to one of the following intervals and the
* arctangent of t is evaluated by the corresponding formula:
*
* [0,7/16] atan(x) = t-t^3*(a1+t^2*(a2+...(a10+t^2*a11)...)
* [7/16,11/16] atan(x) = atan(1/2) + atan( (t-0.5)/(1+t/2) )
* [11/16.19/16] atan(x) = atan( 1 ) + atan( (t-1)/(1+t) )
* [19/16,39/16] atan(x) = atan(3/2) + atan( (t-1.5)/(1+1.5t) )
* [39/16,INF] atan(x) = atan(INF) + atan( -1/t )
*
* Constants:
* The hexadecimal values are the intended ones for the following
* constants. The decimal values may be used, provided that the
* compiler will convert from decimal to binary accurately enough
* to produce the hexadecimal values shown.
*/
#include "libm.h"
static const double atanhi[] = {
4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */
7.85398163397448278999e-01, /* atan(1.0)hi 0x3FE921FB, 0x54442D18 */
9.82793723247329054082e-01, /* atan(1.5)hi 0x3FEF730B, 0xD281F69B */
1.57079632679489655800e+00, /* atan(inf)hi 0x3FF921FB, 0x54442D18 */
};
static const double atanlo[] = {
2.26987774529616870924e-17, /* atan(0.5)lo 0x3C7A2B7F, 0x222F65E2 */
3.06161699786838301793e-17, /* atan(1.0)lo 0x3C81A626, 0x33145C07 */
1.39033110312309984516e-17, /* atan(1.5)lo 0x3C700788, 0x7AF0CBBD */
6.12323399573676603587e-17, /* atan(inf)lo 0x3C91A626, 0x33145C07 */
};
static const double aT[] = {
3.33333333333329318027e-01, /* 0x3FD55555, 0x5555550D */
-1.99999999998764832476e-01, /* 0xBFC99999, 0x9998EBC4 */
1.42857142725034663711e-01, /* 0x3FC24924, 0x920083FF */
-1.11111104054623557880e-01, /* 0xBFBC71C6, 0xFE231671 */
9.09088713343650656196e-02, /* 0x3FB745CD, 0xC54C206E */
-7.69187620504482999495e-02, /* 0xBFB3B0F2, 0xAF749A6D */
6.66107313738753120669e-02, /* 0x3FB10D66, 0xA0D03D51 */
-5.83357013379057348645e-02, /* 0xBFADDE2D, 0x52DEFD9A */
4.97687799461593236017e-02, /* 0x3FA97B4B, 0x24760DEB */
-3.65315727442169155270e-02, /* 0xBFA2B444, 0x2C6A6C2F */
1.62858201153657823623e-02, /* 0x3F90AD3A, 0xE322DA11 */
};
double atan(double x)
{
double_t w,s1,s2,z;
uint32_t ix,sign;
int id;
GET_HIGH_WORD(ix, x);
sign = ix >> 31;
ix &= 0x7fffffff;
if (ix >= 0x44100000) { /* if |x| >= 2^66 */
if (isnan(x))
return x;
z = atanhi[3] + 0x1p-120f;
return sign ? -z : z;
}
if (ix < 0x3fdc0000) { /* |x| < 0.4375 */
if (ix < 0x3e400000) { /* |x| < 2^-27 */
if (ix < 0x00100000)
/* raise underflow for subnormal x */
FORCE_EVAL((float)x);
return x;
}
id = -1;
} else {
x = fabs(x);
if (ix < 0x3ff30000) { /* |x| < 1.1875 */
if (ix < 0x3fe60000) { /* 7/16 <= |x| < 11/16 */
id = 0;
x = (2.0*x-1.0)/(2.0+x);
} else { /* 11/16 <= |x| < 19/16 */
id = 1;
x = (x-1.0)/(x+1.0);
}
} else {
if (ix < 0x40038000) { /* |x| < 2.4375 */
id = 2;
x = (x-1.5)/(1.0+1.5*x);
} else { /* 2.4375 <= |x| < 2^66 */
id = 3;
x = -1.0/x;
}
}
}
/* end of argument reduction */
z = x*x;
w = z*z;
/* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */
s1 = z*(aT[0]+w*(aT[2]+w*(aT[4]+w*(aT[6]+w*(aT[8]+w*aT[10])))));
s2 = w*(aT[1]+w*(aT[3]+w*(aT[5]+w*(aT[7]+w*aT[9]))));
if (id < 0)
return x - x*(s1+s2);
z = atanhi[id] - (x*(s1+s2) - atanlo[id] - x);
return sign ? -z : z;
}

Some files were not shown because too many files have changed in this diff Show More