From 98143415babcb626e66edb6baf6339d6fa45017c Mon Sep 17 00:00:00 2001 From: NishiOwO Date: Sat, 1 Nov 2025 04:25:22 +0000 Subject: [PATCH] curse git-svn-id: http://svn2.nishi.boats/svn/milsko/trunk@543 b9cfdab3-6d41-4d17-bbe4-086880011989 --- BorMakefile | 5 +- NTMakefile | 5 +- WatMakefile | 7 +- include/Mw/LowLevelMath.h | 6 +- mk/math.mk | 2 + src/math/default.c | 56 +++---- src/math/math.c | 54 +++---- src/math/math_internal.h | 3 + src/math/mmx.c | 2 + src/math/mmx_guard.c | 1 + src/math/nbsd_math.h | 87 +++++++++++ src/math/nbsd_pow.c | 303 ++++++++++++++++++++++++++++++++++++++ 12 files changed, 467 insertions(+), 64 deletions(-) create mode 100644 src/math/nbsd_math.h create mode 100644 src/math/nbsd_pow.c diff --git a/BorMakefile b/BorMakefile index 161e45c..22e9128 100644 --- a/BorMakefile +++ b/BorMakefile @@ -65,11 +65,12 @@ clean: del /f /q src\math\mmx.obj del /f /q src\math\default.obj del /f /q src\math\math.obj + del /f /q src\math\nbsd_pow.obj del /f /q src\backend\gdi.obj del /f /q src\Mw.dll -src\Mw.dll: src\default.obj src\lowlevel.obj src\color.obj src\directory.obj src\text.obj src\error.obj src\unicode.obj src\messagebox.obj src\string.obj src\filechooser.obj src\core.obj src\draw.obj external\stb_ds.obj external\stb_image.obj external\stb_truetype.obj src\icon\error.obj src\icon\info.obj src\icon\news.obj src\icon\note.obj src\icon\warning.obj src\icon\file.obj src\icon\directory.obj src\icon\back.obj src\icon\forward.obj src\icon\computer.obj src\icon\up.obj src\icon\search.obj src\icon\down.obj src\icon\left.obj src\icon\right.obj src\cursor\cross.obj src\cursor\default.obj src\cursor\text.obj src\cursor\hidden.obj src\widget\button.obj src\widget\frame.obj src\widget\window.obj src\widget\entry.obj src\widget\label.obj src\widget\opengl.obj src\widget\radiobox.obj src\widget\submenu.obj src\widget\menu.obj src\widget\image.obj src\widget\viewport.obj src\widget\listbox.obj src\widget\scrollbar.obj src\widget\checkbox.obj src\widget\numberentry.obj src\widget\progressbar.obj src\font\boldfont.obj src\font\boldttf.obj src\font\font.obj src\font\ttf.obj src\math\mmx_guard.obj src\math\mmx.obj src\math\default.obj src\math\math.obj src\backend\gdi.obj - $(LD) $(LDFLAGS) -e$@ src\default.obj src\lowlevel.obj src\color.obj src\directory.obj src\text.obj src\error.obj src\unicode.obj src\messagebox.obj src\string.obj src\filechooser.obj src\core.obj src\draw.obj external\stb_ds.obj external\stb_image.obj external\stb_truetype.obj src\icon\error.obj src\icon\info.obj src\icon\news.obj src\icon\note.obj src\icon\warning.obj src\icon\file.obj src\icon\directory.obj src\icon\back.obj src\icon\forward.obj src\icon\computer.obj src\icon\up.obj src\icon\search.obj src\icon\down.obj src\icon\left.obj src\icon\right.obj src\cursor\cross.obj src\cursor\default.obj src\cursor\text.obj src\cursor\hidden.obj src\widget\button.obj src\widget\frame.obj src\widget\window.obj src\widget\entry.obj src\widget\label.obj src\widget\opengl.obj src\widget\radiobox.obj src\widget\submenu.obj src\widget\menu.obj src\widget\image.obj src\widget\viewport.obj src\widget\listbox.obj src\widget\scrollbar.obj src\widget\checkbox.obj src\widget\numberentry.obj src\widget\progressbar.obj src\font\boldfont.obj src\font\boldttf.obj src\font\font.obj src\font\ttf.obj src\math\mmx_guard.obj src\math\mmx.obj src\math\default.obj src\math\math.obj src\backend\gdi.obj -lopengl32.lib -lgdi32.lib -luser32.lib +src\Mw.dll: src\default.obj src\lowlevel.obj src\color.obj src\directory.obj src\text.obj src\error.obj src\unicode.obj src\messagebox.obj src\string.obj src\filechooser.obj src\core.obj src\draw.obj external\stb_ds.obj external\stb_image.obj external\stb_truetype.obj src\icon\error.obj src\icon\info.obj src\icon\news.obj src\icon\note.obj src\icon\warning.obj src\icon\file.obj src\icon\directory.obj src\icon\back.obj src\icon\forward.obj src\icon\computer.obj src\icon\up.obj src\icon\search.obj src\icon\down.obj src\icon\left.obj src\icon\right.obj src\cursor\cross.obj src\cursor\default.obj src\cursor\text.obj src\cursor\hidden.obj src\widget\button.obj src\widget\frame.obj src\widget\window.obj src\widget\entry.obj src\widget\label.obj src\widget\opengl.obj src\widget\radiobox.obj src\widget\submenu.obj src\widget\menu.obj src\widget\image.obj src\widget\viewport.obj src\widget\listbox.obj src\widget\scrollbar.obj src\widget\checkbox.obj src\widget\numberentry.obj src\widget\progressbar.obj src\font\boldfont.obj src\font\boldttf.obj src\font\font.obj src\font\ttf.obj src\math\mmx_guard.obj src\math\mmx.obj src\math\default.obj src\math\math.obj src\math\nbsd_pow.obj src\backend\gdi.obj + $(LD) $(LDFLAGS) -e$@ src\default.obj src\lowlevel.obj src\color.obj src\directory.obj src\text.obj src\error.obj src\unicode.obj src\messagebox.obj src\string.obj src\filechooser.obj src\core.obj src\draw.obj external\stb_ds.obj external\stb_image.obj external\stb_truetype.obj src\icon\error.obj src\icon\info.obj src\icon\news.obj src\icon\note.obj src\icon\warning.obj src\icon\file.obj src\icon\directory.obj src\icon\back.obj src\icon\forward.obj src\icon\computer.obj src\icon\up.obj src\icon\search.obj src\icon\down.obj src\icon\left.obj src\icon\right.obj src\cursor\cross.obj src\cursor\default.obj src\cursor\text.obj src\cursor\hidden.obj src\widget\button.obj src\widget\frame.obj src\widget\window.obj src\widget\entry.obj src\widget\label.obj src\widget\opengl.obj src\widget\radiobox.obj src\widget\submenu.obj src\widget\menu.obj src\widget\image.obj src\widget\viewport.obj src\widget\listbox.obj src\widget\scrollbar.obj src\widget\checkbox.obj src\widget\numberentry.obj src\widget\progressbar.obj src\font\boldfont.obj src\font\boldttf.obj src\font\font.obj src\font\ttf.obj src\math\mmx_guard.obj src\math\mmx.obj src\math\default.obj src\math\math.obj src\math\nbsd_pow.obj src\backend\gdi.obj -lopengl32.lib -lgdi32.lib -luser32.lib implib src\Mw.lib src\Mw.dll .c.obj: diff --git a/NTMakefile b/NTMakefile index 7efa637..78cb5d8 100644 --- a/NTMakefile +++ b/NTMakefile @@ -65,11 +65,12 @@ clean: del /f /q src\math\mmx.obj del /f /q src\math\default.obj del /f /q src\math\math.obj + del /f /q src\math\nbsd_pow.obj del /f /q src\backend\gdi.obj del /f /q src\Mw.dll -src\Mw.dll: src\default.obj src\lowlevel.obj src\color.obj src\directory.obj src\text.obj src\error.obj src\unicode.obj src\messagebox.obj src\string.obj src\filechooser.obj src\core.obj src\draw.obj external\stb_ds.obj external\stb_image.obj external\stb_truetype.obj src\icon\error.obj src\icon\info.obj src\icon\news.obj src\icon\note.obj src\icon\warning.obj src\icon\file.obj src\icon\directory.obj src\icon\back.obj src\icon\forward.obj src\icon\computer.obj src\icon\up.obj src\icon\search.obj src\icon\down.obj src\icon\left.obj src\icon\right.obj src\cursor\cross.obj src\cursor\default.obj src\cursor\text.obj src\cursor\hidden.obj src\widget\button.obj src\widget\frame.obj src\widget\window.obj src\widget\entry.obj src\widget\label.obj src\widget\opengl.obj src\widget\radiobox.obj src\widget\submenu.obj src\widget\menu.obj src\widget\image.obj src\widget\viewport.obj src\widget\listbox.obj src\widget\scrollbar.obj src\widget\checkbox.obj src\widget\numberentry.obj src\widget\progressbar.obj src\font\boldfont.obj src\font\boldttf.obj src\font\font.obj src\font\ttf.obj src\math\mmx_guard.obj src\math\mmx.obj src\math\default.obj src\math\math.obj src\backend\gdi.obj - $(LD) $(LDFLAGS) /OUT:$@ src\default.obj src\lowlevel.obj src\color.obj src\directory.obj src\text.obj src\error.obj src\unicode.obj src\messagebox.obj src\string.obj src\filechooser.obj src\core.obj src\draw.obj external\stb_ds.obj external\stb_image.obj external\stb_truetype.obj src\icon\error.obj src\icon\info.obj src\icon\news.obj src\icon\note.obj src\icon\warning.obj src\icon\file.obj src\icon\directory.obj src\icon\back.obj src\icon\forward.obj src\icon\computer.obj src\icon\up.obj src\icon\search.obj src\icon\down.obj src\icon\left.obj src\icon\right.obj src\cursor\cross.obj src\cursor\default.obj src\cursor\text.obj src\cursor\hidden.obj src\widget\button.obj src\widget\frame.obj src\widget\window.obj src\widget\entry.obj src\widget\label.obj src\widget\opengl.obj src\widget\radiobox.obj src\widget\submenu.obj src\widget\menu.obj src\widget\image.obj src\widget\viewport.obj src\widget\listbox.obj src\widget\scrollbar.obj src\widget\checkbox.obj src\widget\numberentry.obj src\widget\progressbar.obj src\font\boldfont.obj src\font\boldttf.obj src\font\font.obj src\font\ttf.obj src\math\mmx_guard.obj src\math\mmx.obj src\math\default.obj src\math\math.obj src\backend\gdi.obj opengl32.lib gdi32.lib user32.lib +src\Mw.dll: src\default.obj src\lowlevel.obj src\color.obj src\directory.obj src\text.obj src\error.obj src\unicode.obj src\messagebox.obj src\string.obj src\filechooser.obj src\core.obj src\draw.obj external\stb_ds.obj external\stb_image.obj external\stb_truetype.obj src\icon\error.obj src\icon\info.obj src\icon\news.obj src\icon\note.obj src\icon\warning.obj src\icon\file.obj src\icon\directory.obj src\icon\back.obj src\icon\forward.obj src\icon\computer.obj src\icon\up.obj src\icon\search.obj src\icon\down.obj src\icon\left.obj src\icon\right.obj src\cursor\cross.obj src\cursor\default.obj src\cursor\text.obj src\cursor\hidden.obj src\widget\button.obj src\widget\frame.obj src\widget\window.obj src\widget\entry.obj src\widget\label.obj src\widget\opengl.obj src\widget\radiobox.obj src\widget\submenu.obj src\widget\menu.obj src\widget\image.obj src\widget\viewport.obj src\widget\listbox.obj src\widget\scrollbar.obj src\widget\checkbox.obj src\widget\numberentry.obj src\widget\progressbar.obj src\font\boldfont.obj src\font\boldttf.obj src\font\font.obj src\font\ttf.obj src\math\mmx_guard.obj src\math\mmx.obj src\math\default.obj src\math\math.obj src\math\nbsd_pow.obj src\backend\gdi.obj + $(LD) $(LDFLAGS) /OUT:$@ src\default.obj src\lowlevel.obj src\color.obj src\directory.obj src\text.obj src\error.obj src\unicode.obj src\messagebox.obj src\string.obj src\filechooser.obj src\core.obj src\draw.obj external\stb_ds.obj external\stb_image.obj external\stb_truetype.obj src\icon\error.obj src\icon\info.obj src\icon\news.obj src\icon\note.obj src\icon\warning.obj src\icon\file.obj src\icon\directory.obj src\icon\back.obj src\icon\forward.obj src\icon\computer.obj src\icon\up.obj src\icon\search.obj src\icon\down.obj src\icon\left.obj src\icon\right.obj src\cursor\cross.obj src\cursor\default.obj src\cursor\text.obj src\cursor\hidden.obj src\widget\button.obj src\widget\frame.obj src\widget\window.obj src\widget\entry.obj src\widget\label.obj src\widget\opengl.obj src\widget\radiobox.obj src\widget\submenu.obj src\widget\menu.obj src\widget\image.obj src\widget\viewport.obj src\widget\listbox.obj src\widget\scrollbar.obj src\widget\checkbox.obj src\widget\numberentry.obj src\widget\progressbar.obj src\font\boldfont.obj src\font\boldttf.obj src\font\font.obj src\font\ttf.obj src\math\mmx_guard.obj src\math\mmx.obj src\math\default.obj src\math\math.obj src\math\nbsd_pow.obj src\backend\gdi.obj opengl32.lib gdi32.lib user32.lib .c.obj: diff --git a/WatMakefile b/WatMakefile index d7479df..20f58ba 100644 --- a/WatMakefile +++ b/WatMakefile @@ -64,11 +64,12 @@ clean: .SYMBOLIC %erase src/math/mmx.obj %erase src/math/default.obj %erase src/math/math.obj + %erase src/math/nbsd_pow.obj %erase src/backend/gdi.obj %erase src/Mw.dll -src/Mw.dll: src/default.obj src/lowlevel.obj src/color.obj src/directory.obj src/text.obj src/error.obj src/unicode.obj src/messagebox.obj src/string.obj src/filechooser.obj src/core.obj src/draw.obj external/stb_ds.obj external/stb_image.obj external/stb_truetype.obj src/icon/error.obj src/icon/info.obj src/icon/news.obj src/icon/note.obj src/icon/warning.obj src/icon/file.obj src/icon/directory.obj src/icon/back.obj src/icon/forward.obj src/icon/computer.obj src/icon/up.obj src/icon/search.obj src/icon/down.obj src/icon/left.obj src/icon/right.obj src/cursor/cross.obj src/cursor/default.obj src/cursor/text.obj src/cursor/hidden.obj src/widget/button.obj src/widget/frame.obj src/widget/window.obj src/widget/entry.obj src/widget/label.obj src/widget/opengl.obj src/widget/radiobox.obj src/widget/submenu.obj src/widget/menu.obj src/widget/image.obj src/widget/viewport.obj src/widget/listbox.obj src/widget/scrollbar.obj src/widget/checkbox.obj src/widget/numberentry.obj src/widget/progressbar.obj src/font/boldfont.obj src/font/boldttf.obj src/font/font.obj src/font/ttf.obj src/math/mmx_guard.obj src/math/mmx.obj src/math/default.obj src/math/math.obj src/backend/gdi.obj - $(LD) $(LDFLAGS) option implib=src/Mw.lib name $@ file src/default.obj file src/lowlevel.obj file src/color.obj file src/directory.obj file src/text.obj file src/error.obj file src/unicode.obj file src/messagebox.obj file src/string.obj file src/filechooser.obj file src/core.obj file src/draw.obj file external/stb_ds.obj file external/stb_image.obj file external/stb_truetype.obj file src/icon/error.obj file src/icon/info.obj file src/icon/news.obj file src/icon/note.obj file src/icon/warning.obj file src/icon/file.obj file src/icon/directory.obj file src/icon/back.obj file src/icon/forward.obj file src/icon/computer.obj file src/icon/up.obj file src/icon/search.obj file src/icon/down.obj file src/icon/left.obj file src/icon/right.obj file src/cursor/cross.obj file src/cursor/default.obj file src/cursor/text.obj file src/cursor/hidden.obj file src/widget/button.obj file src/widget/frame.obj file src/widget/window.obj file src/widget/entry.obj file src/widget/label.obj file src/widget/opengl.obj file src/widget/radiobox.obj file src/widget/submenu.obj file src/widget/menu.obj file src/widget/image.obj file src/widget/viewport.obj file src/widget/listbox.obj file src/widget/scrollbar.obj file src/widget/checkbox.obj file src/widget/numberentry.obj file src/widget/progressbar.obj file src/font/boldfont.obj file src/font/boldttf.obj file src/font/font.obj file src/font/ttf.obj file src/math/mmx_guard.obj file src/math/mmx.obj file src/math/default.obj file src/math/math.obj file src/backend/gdi.obj library clib3r.lib library opengl32.lib library gdi32.lib library user32.lib +src/Mw.dll: src/default.obj src/lowlevel.obj src/color.obj src/directory.obj src/text.obj src/error.obj src/unicode.obj src/messagebox.obj src/string.obj src/filechooser.obj src/core.obj src/draw.obj external/stb_ds.obj external/stb_image.obj external/stb_truetype.obj src/icon/error.obj src/icon/info.obj src/icon/news.obj src/icon/note.obj src/icon/warning.obj src/icon/file.obj src/icon/directory.obj src/icon/back.obj src/icon/forward.obj src/icon/computer.obj src/icon/up.obj src/icon/search.obj src/icon/down.obj src/icon/left.obj src/icon/right.obj src/cursor/cross.obj src/cursor/default.obj src/cursor/text.obj src/cursor/hidden.obj src/widget/button.obj src/widget/frame.obj src/widget/window.obj src/widget/entry.obj src/widget/label.obj src/widget/opengl.obj src/widget/radiobox.obj src/widget/submenu.obj src/widget/menu.obj src/widget/image.obj src/widget/viewport.obj src/widget/listbox.obj src/widget/scrollbar.obj src/widget/checkbox.obj src/widget/numberentry.obj src/widget/progressbar.obj src/font/boldfont.obj src/font/boldttf.obj src/font/font.obj src/font/ttf.obj src/math/mmx_guard.obj src/math/mmx.obj src/math/default.obj src/math/math.obj src/math/nbsd_pow.obj src/backend/gdi.obj + $(LD) $(LDFLAGS) option implib=src/Mw.lib name $@ file src/default.obj file src/lowlevel.obj file src/color.obj file src/directory.obj file src/text.obj file src/error.obj file src/unicode.obj file src/messagebox.obj file src/string.obj file src/filechooser.obj file src/core.obj file src/draw.obj file external/stb_ds.obj file external/stb_image.obj file external/stb_truetype.obj file src/icon/error.obj file src/icon/info.obj file src/icon/news.obj file src/icon/note.obj file src/icon/warning.obj file src/icon/file.obj file src/icon/directory.obj file src/icon/back.obj file src/icon/forward.obj file src/icon/computer.obj file src/icon/up.obj file src/icon/search.obj file src/icon/down.obj file src/icon/left.obj file src/icon/right.obj file src/cursor/cross.obj file src/cursor/default.obj file src/cursor/text.obj file src/cursor/hidden.obj file src/widget/button.obj file src/widget/frame.obj file src/widget/window.obj file src/widget/entry.obj file src/widget/label.obj file src/widget/opengl.obj file src/widget/radiobox.obj file src/widget/submenu.obj file src/widget/menu.obj file src/widget/image.obj file src/widget/viewport.obj file src/widget/listbox.obj file src/widget/scrollbar.obj file src/widget/checkbox.obj file src/widget/numberentry.obj file src/widget/progressbar.obj file src/font/boldfont.obj file src/font/boldttf.obj file src/font/font.obj file src/font/ttf.obj file src/math/mmx_guard.obj file src/math/mmx.obj file src/math/default.obj file src/math/math.obj file src/math/nbsd_pow.obj file src/backend/gdi.obj library clib3r.lib library opengl32.lib library gdi32.lib library user32.lib @@ -188,5 +189,7 @@ src/math/default.obj: src/math/default.c $(CC) $(CFLAGS) -fo=$@ $< src/math/math.obj: src/math/math.c $(CC) $(CFLAGS) -fo=$@ $< +src/math/nbsd_pow.obj: src/math/nbsd_pow.c + $(CC) $(CFLAGS) -fo=$@ $< src/backend/gdi.obj: src/backend/gdi.c $(CC) $(CFLAGS) -fo=$@ $< diff --git a/include/Mw/LowLevelMath.h b/include/Mw/LowLevelMath.h index 651ca3f..af0d9e6 100644 --- a/include/Mw/LowLevelMath.h +++ b/include/Mw/LowLevelMath.h @@ -19,9 +19,9 @@ * @brief Generic vector type * @warning Do not try to instantiate this yourself, use the appropriate functions instead. */ + typedef struct _MwLLVec MwLLVec; -typedef enum _MwLLVecType MwLLVecType; typedef union _MwLLVecUnion MwLLVecUnion; // clang-format off @@ -48,11 +48,11 @@ enum _MwLLVecType { _MwLLVecType_Max, }; struct _MwLLVec { - MwLLVecType ty; + int ty; MwLLVecUnion un; }; -MwLLVec _MwLLVecCreateGeneric(MwLLVecType ty, ...); +MwLLVec _MwLLVecCreateGeneric(int ty, ...); #define MwLLVecU8x8(a, b, c, d, e, f, g, h) _MwLLVecCreateGeneric(_MwLLVecTypeU8x8, a, b, c, d, e, f, g, h) #define MwLLVecU16x4(a, b, c, d) _MwLLVecCreateGeneric(_MwLLVecTypeU16x4, a, b, c, d) diff --git a/mk/math.mk b/mk/math.mk index 4e009a5..d7f5c17 100644 --- a/mk/math.mk +++ b/mk/math.mk @@ -1 +1,3 @@ +# $Id$ L_OBJS += src/math/default.o src/math/math.o src/math/mmx_guard.o +L_OBJS += src/math/nbsd_pow.o diff --git a/src/math/default.c b/src/math/default.c index 1c98e15..cdf8dd9 100644 --- a/src/math/default.c +++ b/src/math/default.c @@ -34,14 +34,14 @@ static void default_multiply_u8(MwLLVec* a, MwLLVec* b, MwLLVec* out) { out->un.u8.h = a->un.u8.h * b->un.u8.h; }; static void default_reciprocal_u8(MwLLVec* a, MwLLVec* out) { - out->un.u8.a = powf(a->un.u8.a, -1); - out->un.u8.b = powf(a->un.u8.b, -1); - out->un.u8.c = powf(a->un.u8.c, -1); - out->un.u8.d = powf(a->un.u8.d, -1); - out->un.u8.e = powf(a->un.u8.e, -1); - out->un.u8.f = powf(a->un.u8.f, -1); - out->un.u8.g = powf(a->un.u8.g, -1); - out->un.u8.h = powf(a->un.u8.h, -1); + out->un.u8.a = nbsd_pow(a->un.u8.a, -1); + out->un.u8.b = nbsd_pow(a->un.u8.b, -1); + out->un.u8.c = nbsd_pow(a->un.u8.c, -1); + out->un.u8.d = nbsd_pow(a->un.u8.d, -1); + out->un.u8.e = nbsd_pow(a->un.u8.e, -1); + out->un.u8.f = nbsd_pow(a->un.u8.f, -1); + out->un.u8.g = nbsd_pow(a->un.u8.g, -1); + out->un.u8.h = nbsd_pow(a->un.u8.h, -1); }; static void default_squareRoot_u8(MwLLVec* a, MwLLVec* out) { out->un.u8.a = sqrt(a->un.u8.a); @@ -123,10 +123,10 @@ static void default_multiply_u16(MwLLVec* a, MwLLVec* b, MwLLVec* out) { out->un.u16.d = a->un.u16.d * b->un.u16.d; } static void default_reciprocal_u16(MwLLVec* a, MwLLVec* out) { - out->un.u16.a = powf(a->un.u16.a, -1); - out->un.u16.b = powf(a->un.u16.b, -1); - out->un.u16.c = powf(a->un.u16.c, -1); - out->un.u16.d = powf(a->un.u16.d, -1); + out->un.u16.a = nbsd_pow(a->un.u16.a, -1); + out->un.u16.b = nbsd_pow(a->un.u16.b, -1); + out->un.u16.c = nbsd_pow(a->un.u16.c, -1); + out->un.u16.d = nbsd_pow(a->un.u16.d, -1); }; static void default_squareRoot_u16(MwLLVec* a, MwLLVec* out) { out->un.u16.a = sqrt(a->un.u16.a); @@ -184,8 +184,8 @@ static void default_multiply_u32(MwLLVec* a, MwLLVec* b, MwLLVec* out) { out->un.u32.b = a->un.u32.b * b->un.u32.b; } static void default_reciprocal_u32(MwLLVec* a, MwLLVec* out) { - out->un.u32.a = powf(a->un.u32.a, -1); - out->un.u32.b = powf(a->un.u32.b, -1); + out->un.u32.a = nbsd_pow(a->un.u32.a, -1); + out->un.u32.b = nbsd_pow(a->un.u32.b, -1); }; static void default_squareRoot_u32(MwLLVec* a, MwLLVec* out) { out->un.u32.a = sqrt(a->un.u32.a); @@ -251,14 +251,14 @@ static void default_multiply_i8(MwLLVec* a, MwLLVec* b, MwLLVec* out) { out->un.i8.h = a->un.i8.h * b->un.i8.h; }; static void default_reciprocal_i8(MwLLVec* a, MwLLVec* out) { - out->un.i8.a = powf(a->un.i8.a, -1); - out->un.i8.b = powf(a->un.i8.b, -1); - out->un.i8.c = powf(a->un.i8.c, -1); - out->un.i8.d = powf(a->un.i8.d, -1); - out->un.i8.e = powf(a->un.i8.e, -1); - out->un.i8.f = powf(a->un.i8.f, -1); - out->un.i8.g = powf(a->un.i8.g, -1); - out->un.i8.h = powf(a->un.i8.h, -1); + out->un.i8.a = nbsd_pow(a->un.i8.a, -1); + out->un.i8.b = nbsd_pow(a->un.i8.b, -1); + out->un.i8.c = nbsd_pow(a->un.i8.c, -1); + out->un.i8.d = nbsd_pow(a->un.i8.d, -1); + out->un.i8.e = nbsd_pow(a->un.i8.e, -1); + out->un.i8.f = nbsd_pow(a->un.i8.f, -1); + out->un.i8.g = nbsd_pow(a->un.i8.g, -1); + out->un.i8.h = nbsd_pow(a->un.i8.h, -1); }; static void default_squareRoot_i8(MwLLVec* a, MwLLVec* out) { out->un.i8.a = sqrt(a->un.i8.a); @@ -321,10 +321,10 @@ static void default_multiply_i16(MwLLVec* a, MwLLVec* b, MwLLVec* out) { out->un.i16.d = a->un.i16.d * b->un.i16.d; } static void default_reciprocal_i16(MwLLVec* a, MwLLVec* out) { - out->un.i16.a = powf(a->un.i16.a, -1); - out->un.i16.b = powf(a->un.i16.b, -1); - out->un.i16.c = powf(a->un.i16.c, -1); - out->un.i16.d = powf(a->un.i16.d, -1); + out->un.i16.a = nbsd_pow(a->un.i16.a, -1); + out->un.i16.b = nbsd_pow(a->un.i16.b, -1); + out->un.i16.c = nbsd_pow(a->un.i16.c, -1); + out->un.i16.d = nbsd_pow(a->un.i16.d, -1); }; static void default_squareRoot_i16(MwLLVec* a, MwLLVec* out) { out->un.i16.a = sqrt(a->un.i16.a); @@ -370,8 +370,8 @@ static void default_multiply_i32(MwLLVec* a, MwLLVec* b, MwLLVec* out) { out->un.i32.b = a->un.i32.b * b->un.i32.b; } static void default_reciprocal_i32(MwLLVec* a, MwLLVec* out) { - out->un.i32.a = powf(a->un.i32.a, -1); - out->un.i32.b = powf(a->un.i32.b, -1); + out->un.i32.a = nbsd_pow(a->un.i32.a, -1); + out->un.i32.b = nbsd_pow(a->un.i32.b, -1); }; static void default_squareRoot_i32(MwLLVec* a, MwLLVec* out) { out->un.i32.a = sqrt(a->un.i32.a); diff --git a/src/math/math.c b/src/math/math.c index 30dc6c2..f898b26 100644 --- a/src/math/math.c +++ b/src/math/math.c @@ -3,7 +3,7 @@ #include "math_internal.h" -MwLLVec _MwLLVecCreateGeneric(MwLLVecType ty, ...) { +MwLLVec _MwLLVecCreateGeneric(int ty, ...) { MwLLVecUnion un; MwLLVec vec; va_list va; @@ -59,16 +59,16 @@ static MwBool hasMMX(void) { } static MwLLMathVTable** mwLLMultiTable; -static MwLLMathVTable* multiTableSetupAndGet(MwLLVecType ty); -static MwLLMathVTable* multiTableGet(MwLLVecType ty); +static MwLLMathVTable* multiTableSetupAndGet(int ty); +static MwLLMathVTable* multiTableGet(int ty); -static MwLLMathVTable* (*mwLLmathFunc)(MwLLVecType ty) = multiTableSetupAndGet; +static MwLLMathVTable* (*mwLLmathFunc)(int ty) = multiTableSetupAndGet; -static MwLLMathVTable* getMultiTable(MwLLVecType ty) { +static MwLLMathVTable* getMultiTable(int ty) { return mwLLmathFunc(ty); } -static MwLLMathVTable* multiTableSetupAndGet(MwLLVecType ty) { +static MwLLMathVTable* multiTableSetupAndGet(int ty) { mwLLMultiTable = default_multi_table(); #if defined(__i386__) || defined(__x86_64__) @@ -81,50 +81,50 @@ static MwLLMathVTable* multiTableSetupAndGet(MwLLVecType ty) { return mwLLMultiTable[ty]; } -static MwLLMathVTable* multiTableGet(MwLLVecType ty) { +static MwLLMathVTable* multiTableGet(int ty) { return mwLLMultiTable[ty]; } void MwLLMathAdd(MwLLVec* a, MwLLVec* b, MwLLVec* out) { assert(a->ty == b->ty && a->ty == out->ty && b->ty == out->ty); - return getMultiTable(a->ty)->Add(a, b, out); -}; + getMultiTable(a->ty)->Add(a, b, out); +} void MwLLMathSub(MwLLVec* a, MwLLVec* b, MwLLVec* out) { assert(a->ty == b->ty && a->ty == out->ty && b->ty == out->ty); - return getMultiTable(a->ty)->Sub(a, b, out); -}; + getMultiTable(a->ty)->Sub(a, b, out); +} void MwLLMathMultiply(MwLLVec* a, MwLLVec* b, MwLLVec* out) { assert(a->ty == b->ty && a->ty == out->ty && b->ty == out->ty); - return getMultiTable(a->ty)->Multiply(a, b, out); -}; + getMultiTable(a->ty)->Multiply(a, b, out); +} void MwLLMathReciprocal(MwLLVec* a, MwLLVec* out) { assert(a->ty == out->ty); - return getMultiTable(a->ty)->Reciprocal(a, out); -}; + getMultiTable(a->ty)->Reciprocal(a, out); +} void MwLLMathSquareRoot(MwLLVec* a, MwLLVec* out) { assert(a->ty == out->ty); - return getMultiTable(a->ty)->SquareRoot(a, out); -}; + getMultiTable(a->ty)->SquareRoot(a, out); +} void MwLLMathShiftRight(MwLLVec* a, MwLLVec* b, MwLLVec* out) { assert(a->ty == b->ty && a->ty == out->ty && b->ty == out->ty); - return getMultiTable(a->ty)->ShiftRight(a, b, out); -}; + getMultiTable(a->ty)->ShiftRight(a, b, out); +} void MwLLMathShiftLeft(MwLLVec* a, MwLLVec* b, MwLLVec* out) { assert(a->ty == b->ty && a->ty == out->ty && b->ty == out->ty); - return getMultiTable(a->ty)->ShiftLeft(a, b, out); -}; + getMultiTable(a->ty)->ShiftLeft(a, b, out); +} void MwLLMathEqual(MwLLVec* a, MwLLVec* b, MwLLVec* out) { assert(a->ty == b->ty && a->ty == out->ty && b->ty == out->ty); - return getMultiTable(a->ty)->Equal(a, b, out); -}; + getMultiTable(a->ty)->Equal(a, b, out); +} void MwLLMathGreaterThen(MwLLVec* a, MwLLVec* b, MwLLVec* out) { assert(a->ty == b->ty && a->ty == out->ty && b->ty == out->ty); - return getMultiTable(a->ty)->GreaterThen(a, b, out); -}; + getMultiTable(a->ty)->GreaterThen(a, b, out); +} void MwLLMathAnd(MwLLVec* a, MwLLVec* b, MwLLVec* out) { out->un.all = a->un.all & b->un.all; -}; +} void MwLLMathOr(MwLLVec* a, MwLLVec* b, MwLLVec* out) { out->un.all = a->un.all | b->un.all; -}; +} diff --git a/src/math/math_internal.h b/src/math/math_internal.h index d725a26..24930b6 100644 --- a/src/math/math_internal.h +++ b/src/math/math_internal.h @@ -5,6 +5,8 @@ #include +#include "nbsd_math.h" + struct _MwLLMathVTable { void (*Add)(MwLLVec* a, MwLLVec* b, MwLLVec* out); void (*Multiply)(MwLLVec* a, MwLLVec* b, MwLLVec* out); @@ -24,5 +26,6 @@ typedef struct _MwLLMathVTable MwLLMathVTable; MwLLMathVTable** default_multi_table(void); void mmx_apply(MwLLMathVTable**); +double nbsd_pow(double a, double b); #endif diff --git a/src/math/mmx.c b/src/math/mmx.c index bf88f61..874991e 100644 --- a/src/math/mmx.c +++ b/src/math/mmx.c @@ -1,4 +1,5 @@ /* $Id$ */ +#ifdef GUARD #include #include "math_internal.h" @@ -101,3 +102,4 @@ void mmx_apply(MwLLMathVTable** t) { t[_MwLLVecTypeI32x2]->ShiftLeft = mmx_shiftLeft_u32; t[_MwLLVecTypeI32x2]->ShiftRight = mmx_shiftRight_u32; } +#endif diff --git a/src/math/mmx_guard.c b/src/math/mmx_guard.c index be3832c..e2a1be1 100644 --- a/src/math/mmx_guard.c +++ b/src/math/mmx_guard.c @@ -1,5 +1,6 @@ /* $Id$ */ #if defined(__WATCOMC__) || defined(__i386__) || defined(__amd64__) +#define GUARD #include "mmx.c" #else void mmx_apply(MwLLMathVTable** t) { diff --git a/src/math/nbsd_math.h b/src/math/nbsd_math.h new file mode 100644 index 0000000..2e587f6 --- /dev/null +++ b/src/math/nbsd_math.h @@ -0,0 +1,87 @@ +/* + * ==================================================== + * 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. + * ==================================================== + */ + +/* + * from: @(#)fdlibm.h 5.1 93/09/24 + * $NetBSD: math_private.h,v 1.34 2024/07/17 12:00:13 riastradh Exp $ + */ + +/* $Id$ */ +#ifndef __NBSD_MATH__ +#define __NBSD_MATH__ + +#include + +typedef union _ieee_double_shape_type +{ + double value; + struct + { + MwU32 lsw; + MwU32 msw; + } parts; + struct + { + MwU64 w; + } xparts; +} ieee_double_shape_type; + +/* Get two 32-bit integers from a double. */ + +#define EXTRACT_WORDS(ix0,ix1,d) \ +do { \ + ieee_double_shape_type ew_u; \ + ew_u.value = (d); \ + (ix0) = ew_u.parts.msw; \ + (ix1) = ew_u.parts.lsw; \ +} while (0) + +/* Get the more significant 32-bit integer from a double. */ + +#define GET_HIGH_WORD(i,d) \ +do { \ + ieee_double_shape_type gh_u; \ + gh_u.value = (d); \ + (i) = gh_u.parts.msw; \ +} while (0) + +/* Get the less significant 32-bit integer from a double. */ + +#define GET_LOW_WORD(i,d) \ +do { \ + ieee_double_shape_type gl_u; \ + gl_u.value = (d); \ + (i) = gl_u.parts.lsw; \ +} while (0) + +/* Set the more significant 32 bits of a double from an integer. */ + +#define SET_HIGH_WORD(d,v) \ +do { \ + ieee_double_shape_type sh_u; \ + sh_u.value = (d); \ + sh_u.parts.msw = (v); \ + (d) = sh_u.value; \ +} while (0) + +/* Set the less significant 32 bits of a double from an integer. */ + +#define SET_LOW_WORD(d,v) \ +do { \ + ieee_double_shape_type sl_u; \ + sl_u.value = (d); \ + sl_u.parts.lsw = (v); \ + (d) = sl_u.value; \ +} while (0) + + + +#endif diff --git a/src/math/nbsd_pow.c b/src/math/nbsd_pow.c new file mode 100644 index 0000000..291a477 --- /dev/null +++ b/src/math/nbsd_pow.c @@ -0,0 +1,303 @@ +/* @(#)e_pow.c 1.5 04/04/22 SMI */ +/* + * ==================================================== + * Copyright (C) 2004 by 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 +#include "math_internal.h" + +/* __ieee754_pow(x,y) return x**y + * + * n + * Method: Let x = 2 * (1+f) + * 1. Compute and return log2(x) in two pieces: + * log2(x) = w1 + w2, + * where w1 has 53-24 = 29 bit trailing zeros. + * 2. Perform y*log2(x) = n+y' by simulating multi-precision + * arithmetic, where |y'|<=0.5. + * 3. Return x**y = 2**n*exp(y'*log2) + * + * Special cases: + * 1. (anything) ** 0 is 1 + * 2. (anything) ** 1 is itself + * 3. (anything) ** NAN is NAN except 1 ** NAN = 1 + * 4. NAN ** (anything except 0) is NAN + * 5. +-(|x| > 1) ** +INF is +INF + * 6. +-(|x| > 1) ** -INF is +0 + * 7. +-(|x| < 1) ** +INF is +0 + * 8. +-(|x| < 1) ** -INF is +INF + * 9. +-1 ** +-INF is 1 + * 10. +0 ** (+anything except 0, NAN) is +0 + * 11. -0 ** (+anything except 0, NAN, odd integer) is +0 + * 12. +0 ** (-anything except 0, NAN) is +INF + * 13. -0 ** (-anything except 0, NAN, odd integer) is +INF + * 14. -0 ** (odd integer) = -( +0 ** (odd integer) ) + * 15. +INF ** (+anything except 0,NAN) is +INF + * 16. +INF ** (-anything except 0,NAN) is +0 + * 17. -INF ** (anything) = -0 ** (-anything) + * 18. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer) + * 19. (-anything except 0 and inf) ** (non-integer) is NAN + * + * Accuracy: + * pow(x,y) returns x**y nearly rounded. In particular + * pow(integer,integer) + * always returns the correct integer provided it is + * representable. + * + * 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. + */ + +static const double +bp[] = {1.0, 1.5,}, +dp_h[] = { 0.0, 5.84962487220764160156e-01,}, /* 0x3FE2B803, 0x40000000 */ +dp_l[] = { 0.0, 1.35003920212974897128e-08,}, /* 0x3E4CFDEB, 0x43CFD006 */ +zero = 0.0, +one = 1.0, +two = 2.0, +two53 = 9007199254740992.0, /* 0x43400000, 0x00000000 */ +hugev = 1.0e300, +tinyv = 1.0e-300, + /* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */ +L1 = 5.99999999999994648725e-01, /* 0x3FE33333, 0x33333303 */ +L2 = 4.28571428578550184252e-01, /* 0x3FDB6DB6, 0xDB6FABFF */ +L3 = 3.33333329818377432918e-01, /* 0x3FD55555, 0x518F264D */ +L4 = 2.72728123808534006489e-01, /* 0x3FD17460, 0xA91D4101 */ +L5 = 2.30660745775561754067e-01, /* 0x3FCD864A, 0x93C9DB65 */ +L6 = 2.06975017800338417784e-01, /* 0x3FCA7E28, 0x4A454EEF */ +P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */ +P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */ +P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */ +P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */ +P5 = 4.13813679705723846039e-08, /* 0x3E663769, 0x72BEA4D0 */ +lg2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */ +lg2_h = 6.93147182464599609375e-01, /* 0x3FE62E43, 0x00000000 */ +lg2_l = -1.90465429995776804525e-09, /* 0xBE205C61, 0x0CA86C39 */ +ovt = 8.0085662595372944372e-0017, /* -(1024-log2(ovfl+.5ulp)) */ +cp = 9.61796693925975554329e-01, /* 0x3FEEC709, 0xDC3A03FD =2/(3ln2) */ +cp_h = 9.61796700954437255859e-01, /* 0x3FEEC709, 0xE0000000 =(float)cp */ +cp_l = -7.02846165095275826516e-09, /* 0xBE3E2FE0, 0x145B01F5 =tail of cp_h*/ +ivln2 = 1.44269504088896338700e+00, /* 0x3FF71547, 0x652B82FE =1/ln2 */ +ivln2_h = 1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/ +ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/ + +double +nbsd_pow(double x, double y) +{ + double z,ax,z_h,z_l,p_h,p_l; + double yy1,t1,t2,r,s,t,u,v,w; + MwI32 i,j,k,yisint,n; + MwI32 hx,hy,ix,iy; + MwU32 lx,ly; + + EXTRACT_WORDS(hx,lx,x); + EXTRACT_WORDS(hy,ly,y); + ix = hx&0x7fffffff; iy = hy&0x7fffffff; + + /* y==zero: x**0 = 1 */ + if((iy|ly)==0) return one; + + /* x==1: 1**y = 1, even if y is NaN */ + if (hx==0x3ff00000 && lx == 0) return one; + + /* y!=zero: result is NaN if either arg is NaN */ + if(ix > 0x7ff00000 || ((ix==0x7ff00000)&&(lx!=0)) || + iy > 0x7ff00000 || ((iy==0x7ff00000)&&(ly!=0))) + return (x+0.0)+(y+0.0); + + /* determine if y is an odd int when x < 0 + * yisint = 0 ... y is not an integer + * yisint = 1 ... y is an odd int + * yisint = 2 ... y is an even int + */ + yisint = 0; + if(hx<0) { + if(iy>=0x43400000) yisint = 2; /* even integer y */ + else if(iy>=0x3ff00000) { + k = (iy>>20)-0x3ff; /* exponent */ + if(k>20) { + j = ly>>(52-k); + if((uint32_t)(j<<(52-k))==ly) yisint = 2-(j&1); + } else if(ly==0) { + j = iy>>(20-k); + if((j<<(20-k))==iy) yisint = 2-(j&1); + } + } + } + + /* special value of y */ + if(ly==0) { + if (iy==0x7ff00000) { /* y is +-inf */ + if(((ix-0x3ff00000)|lx)==0) + return one; /* (-1)**+-inf is 1 */ + else if (ix >= 0x3ff00000)/* (|x|>1)**+-inf = inf,0 */ + return (hy>=0)? y: zero; + else /* (|x|<1)**-,+inf = inf,0 */ + return (hy<0)?-y: zero; + } + if(iy==0x3ff00000) { /* y is +-1 */ + if(hy<0) return one/x; else return x; + } + if(hy==0x40000000) return x*x; /* y is 2 */ + if(hy==0x3fe00000) { /* y is 0.5 */ + if(hx>=0) /* x >= +0 */ + return sqrt(x); + } + } + + ax = fabs(x); + /* special value of x */ + if(lx==0) { + if(ix==0x7ff00000||ix==0||ix==0x3ff00000){ + z = ax; /*x is +-0,+-inf,+-1*/ + if(hy<0) z = one/z; /* z = (1/|x|) */ + if(hx<0) { + if(((ix-0x3ff00000)|yisint)==0) { + z = (z-z)/(z-z); /* (-1)**non-int is NaN */ + } else if(yisint==1) + z = -z; /* (x<0)**odd = -(|x|**odd) */ + } + return z; + } + } + + /* CYGNUS LOCAL + fdlibm-5.3 fix: This used to be + n = (hx>>31)+1; + but ANSI C says a right shift of a signed negative quantity is + implementation defined. */ + n = ((MwU32)hx>>31)-1; + + /* (x<0)**(non-int) is NaN */ + if((n|yisint)==0) return (x-x)/(x-x); + + s = one; /* s (sign of result -ve**odd) = -1 else = 1 */ + if((n|(yisint-1))==0) s = -one;/* (-ve)**(odd int) */ + + /* |y| is hugev */ + if(iy>0x41e00000) { /* if |y| > 2**31 */ + if(iy>0x43f00000){ /* if |y| > 2**64, must o/uflow */ + if(ix<=0x3fefffff) return (hy<0)? hugev*hugev:tinyv*tinyv; + if(ix>=0x3ff00000) return (hy>0)? hugev*hugev:tinyv*tinyv; + } + /* over/underflow if x is not close to one */ + if(ix<0x3fefffff) return (hy<0)? s*hugev*hugev:s*tinyv*tinyv; + if(ix>0x3ff00000) return (hy>0)? s*hugev*hugev:s*tinyv*tinyv; + /* now |1-x| is tinyv <= 2**-20, suffice to compute + log(x) by x-x^2/2+x^3/3-x^4/4 */ + t = ax-one; /* t has 20 trailing zeros */ + w = (t*t)*(0.5-t*(0.3333333333333333333333-t*0.25)); + u = ivln2_h*t; /* ivln2_h has 21 sig. bits */ + v = t*ivln2_l-w*ivln2; + t1 = u+v; + SET_LOW_WORD(t1,0); + t2 = v-(t1-u); + } else { + double ss,s2,s_h,s_l,t_h,t_l; + n = 0; + /* take care subnormal number */ + if(ix<0x00100000) + {ax *= two53; n -= 53; GET_HIGH_WORD(ix,ax); } + n += ((ix)>>20)-0x3ff; + j = ix&0x000fffff; + /* determine interval */ + ix = j|0x3ff00000; /* normalize ix */ + if(j<=0x3988E) k=0; /* |x|>1)|0x20000000)+0x00080000+(k<<18)); + t_l = ax - (t_h-bp[k]); + s_l = v*((u-s_h*t_h)-s_h*t_l); + /* compute log(ax) */ + s2 = ss*ss; + r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6))))); + r += s_l*(s_h+ss); + s2 = s_h*s_h; + t_h = 3.0+s2+r; + SET_LOW_WORD(t_h,0); + t_l = r-((t_h-3.0)-s2); + /* u+v = ss*(1+...) */ + u = s_h*t_h; + v = s_l*t_h+t_l*ss; + /* 2/(3log2)*(ss+...) */ + p_h = u+v; + SET_LOW_WORD(p_h,0); + p_l = v-(p_h-u); + z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */ + z_l = cp_l*p_h+p_l*cp+dp_l[k]; + /* log2(ax) = (ss+..)*2/(3*log2) = n + dp_h + z_h + z_l */ + t = (double)n; + t1 = (((z_h+z_l)+dp_h[k])+t); + SET_LOW_WORD(t1,0); + t2 = z_l-(((t1-t)-dp_h[k])-z_h); + } + + /* split up y into yy1+y2 and compute (yy1+y2)*(t1+t2) */ + yy1 = y; + SET_LOW_WORD(yy1,0); + p_l = (y-yy1)*t1+y*t2; + p_h = yy1*t1; + z = p_l+p_h; + EXTRACT_WORDS(j,i,z); + if (j>=0x40900000) { /* z >= 1024 */ + if(((j-0x40900000)|i)!=0) /* if z > 1024 */ + return s*hugev*hugev; /* overflow */ + else { + if(p_l+ovt>z-p_h) return s*hugev*hugev; /* overflow */ + } + } else if((j&0x7fffffff)>=0x4090cc00 ) { /* z <= -1075 */ + if(((j-0xc090cc00)|i)!=0) /* z < -1075 */ + return s*tinyv*tinyv; /* underflow */ + else { + if(p_l<=z-p_h) return s*tinyv*tinyv; /* underflow */ + } + } + /* + * compute 2**(p_h+p_l) + */ + i = j&0x7fffffff; + k = (i>>20)-0x3ff; + n = 0; + if(i>0x3fe00000) { /* if |z| > 0.5, set n = [z+0.5] */ + n = j+(0x00100000>>(k+1)); + k = ((n&0x7fffffff)>>20)-0x3ff; /* new k for n */ + t = zero; + SET_HIGH_WORD(t,n&~(0x000fffff>>k)); + n = ((n&0x000fffff)|0x00100000)>>(20-k); + if(j<0) n = -n; + p_h -= t; + } + t = p_l+p_h; + SET_LOW_WORD(t,0); + u = t*lg2_h; + v = (p_l-(t-p_h))*lg2+t*lg2_l; + z = u+v; + w = v-(z-u); + t = z*z; + t1 = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5)))); + r = (z*t1)/(t1-two)-(w+z*w); + z = one-(r-z); + GET_HIGH_WORD(j,z); + j += (n<<20); + if((j>>20)<=0) z = scalbn(z,n); /* subnormal output */ + else SET_HIGH_WORD(z,j); + return s*z; +}