diff --git a/mk/linux/Jamfile b/mk/linux/Jamfile index 73606ef1c..df54eee5d 100644 --- a/mk/linux/Jamfile +++ b/mk/linux/Jamfile @@ -7,6 +7,24 @@ Package license.txt readme.txt ; #### Library #### SubDir TOP shared_lib sources ; +LIB_STREFLOP_DIRS = + streflop/libm/flt-32 + streflop/libm/headers +; + +LIB_STREFLOP_INCLUDE_DIRS = ../include/$(LIB_STREFLOP_DIRS) ; + +for i in $(LIB_STREFLOP_DIRS) { + LIB_STREFLOP_SOURCES += [ Wildcard $(i) : *.c *.cpp *.h ] ; +} + +Library strefloplib : $(LIB_STREFLOP_SOURCES) ; +ExternalLibs strefloplib : SDL GL GLU XERCES VORBIS VORBISFILE OGG OPENAL LUA JPEG PNG ; +IncludeDir strefloplib : $(LIB_STREFLOP_INCLUDE_DIRS) ; + +#### Library #### +SubDir TOP shared_lib sources ; + LIB_DIRS = platform/sdl platform/posix @@ -18,14 +36,18 @@ LIB_DIRS = xml glew lua + streflop + streflop/libm_flt32_source ; + LIB_INCLUDE_DIRS = ../include/$(LIB_DIRS) ; for i in $(LIB_DIRS) { LIB_SOURCES += [ Wildcard $(i) : *.c *.cpp *.h ] ; } -Library glestlib : $(LIB_SOURCES) ; +Library glestlib : $(LIB_SOURCES) ; +LinkWith glestlib : strefloplib ; ExternalLibs glestlib : SDL GL GLU XERCES VORBIS VORBISFILE OGG OPENAL LUA JPEG PNG ; IncludeDir glestlib : $(LIB_INCLUDE_DIRS) ; @@ -54,7 +76,7 @@ for i in $(GLEST_DIRS) { } Application glest.bin : $(GLEST_SOURCES) ; -LinkWith glest.bin : glestlib ; +LinkWith glest.bin : glestlib strefloplib ; ExternalLibs glest.bin : SDL GL GLU XERCES VORBIS VORBISFILE OGG OPENAL LUA JPEG PNG ; IncludeDir glest.bin : ../shared_lib/include/$(LIB_INCLUDE_DIRS) $(GLEST_DIRS) ; @@ -68,7 +90,7 @@ if $(WX_AVAILABLE) = "yes" { } Application glest_editor : $(GLEST_MAP_SOURCES) ; - LinkWith glest_editor : glestlib ; + LinkWith glest_editor : glestlib strefloplib ; ExternalLibs glest_editor : SDL GL GLU XERCES VORBIS VORBISFILE OGG OPENAL WX ; IncludeDir glest_editor : ../shared_lib/include/$(LIB_INCLUDE_DIRS) $(GLEST_MAP_DIRS) ; } @@ -83,7 +105,7 @@ if $(WX_AVAILABLE) = "yes" { } Application glest_g3dviewer : $(GLEST_VIEWER_SOURCES) ; - LinkWith glest_g3dviewer : glestlib ; + LinkWith glest_g3dviewer : glestlib strefloplib ; ExternalLibs glest_g3dviewer : SDL GL GLU WX ; IncludeDir glest_g3dviewer : ../shared_lib/include/$(LIB_INCLUDE_DIRS) $(GLEST_VIEWER_DIRS) ; } @@ -97,7 +119,7 @@ if $(WX_AVAILABLE) = "yes" { } Application glest_configurator : $(GLEST_CONFIG_SOURCES) ; - LinkWith glest_configurator : glestlib ; + LinkWith glest_configurator : glestlib strefloplib ; ExternalLibs glest_configurator : SDL GL GLU XERCES WX ; IncludeDir glest_configurator : ../shared_lib/include/$(LIB_INCLUDE_DIRS) $(GLEST_CONFIG_DIRS) ; diff --git a/mk/linux/Jamrules b/mk/linux/Jamrules new file mode 100644 index 000000000..f467a9c6a --- /dev/null +++ b/mk/linux/Jamrules @@ -0,0 +1,45 @@ +if ! $(top_builddir) +{ + top_builddir = $(TOP) ; +} +top_srcdir = $(TOP) ; + +JAMCONFIG ?= $(top_builddir)/Jamconfig ; +include $(JAMCONFIG) ; +if ! $(JAMCONFIG_READ) +{ + EXIT "Couldn't find config. Please run 'configure' first." ; +} + +if $(USE_STLPORT_DEBUG) +{ + CPPFLAGS += -I/usr/include/stlport ; + CPPFLAGS += -D_STLP_DEBUG=1 -D_STLP_DEBUG_UNINITIALIZED=1 ; + CPPFLAGS += -D_STLP_SHRED_BYTE=0xA3 ; + LIBS += -lstlport_gcc_debug ; +} + +# if using streflop then add some special compiler defines +if $(USE_STREFLOP) +{ + CPPFLAGS += -mfpmath=sse -msse ; +} + +COMPILER_CFLAGS += -Wall -W -Wno-unused -Wno-sign-compare ; +COMPILER_CFLAGS_optimize += -O3 -DNDEBUG ; +COMPILER_CXXFLAGS_optimize += -O3 -DNDEBUG ; +COMPILER_LIBS_optimize += ; +COMPILER_CFLAGS_debug += -DDEBUG -g3 ; +COMPILER_CXXFLAGS_debug += -DDEBUG -g3 ; +COMPILER_LIBS_debug += -g3 ; +COMPILER_CFLAGS_profile += -O3 -fno-inline -pg ; +COMPILER_CXXFLAGS_profile += -O3 -fno-inline -g3 -pg ; +COMPILER_LIBS_profile += -pg ; + +LINK = $(CXX) ; + +# Include build rules +include $(TOP)/mk/jam/build.jam ; + +# Include Dirs +IncludeDir $(top_builddir) ; # for config.h diff --git a/mk/linux/configure.ac b/mk/linux/configure.ac index 2a06d7887..ec7d32a6f 100644 --- a/mk/linux/configure.ac +++ b/mk/linux/configure.ac @@ -20,6 +20,12 @@ AC_C_BIGENDIAN() # stupid autoconf is adding default -g -O2 flags when we don't want this :-/ test ".$CXXFLAGS" = "." && CXXFLAGS=" " +# here we define required defines for streflop +AC_DEFINE([USE_STREFLOP], [], [Define if streflop should be used]) +AC_DEFINE([STREFLOP_SSE], [], [Define type of streflop to use]) +AC_DEFINE([LIBM_COMPILING_FLT32], [], [Define which libm compile type should be used]) +# end + #---------------------------------------------------------------------------- # Check for build variant (debug, profile, optimize) #---------------------------------------------------------------------------- diff --git a/source/glest_game/game/game_camera.cpp b/source/glest_game/game/game_camera.cpp index 398cc1443..e556604c3 100644 --- a/source/glest_game/game/game_camera.cpp +++ b/source/glest_game/game/game_camera.cpp @@ -144,12 +144,12 @@ void GameCamera::update(){ Quad2i GameCamera::computeVisibleQuad() const{ /* //maxRenderDistance - float flatDist = maxRenderDistance * -cos(degToRad(vAng + fov / 2.f)); - Vec3f p1(flatDist * sin(degToRad(hAng + fov / 2.f)), maxRenderDistance * sin(degToRad(vAng + fov / 2.f)), flatDist * -cos(degToRad(hAng + fov / 2.f))); - Vec3f p2(flatDist * sin(degToRad(hAng - fov / 2.f)), maxRenderDistance * sin(degToRad(vAng + fov / 2.f)), flatDist * -cos(degToRad(hAng - fov / 2.f))); + float flatDist = maxRenderDistance * -streflop::cos(degToRad(vAng + fov / 2.f)); + Vec3f p1(flatDist * sin(degToRad(hAng + fov / 2.f)), maxRenderDistance * sin(degToRad(vAng + fov / 2.f)), flatDist * -streflop::cos(degToRad(hAng + fov / 2.f))); + Vec3f p2(flatDist * sin(degToRad(hAng - fov / 2.f)), maxRenderDistance * sin(degToRad(vAng + fov / 2.f)), flatDist * -streflop::cos(degToRad(hAng - fov / 2.f))); flatDist = maxRenderDistance * -cos(degToRad(vAng - fov / 2.f)); - Vec3f p3(flatDist * sin(degToRad(hAng + fov / 2.f)), maxRenderDistance * sin(degToRad(vAng - fov / 2.f)), flatDist * -cos(degToRad(hAng + fov / 2.f))); - Vec3f p4(flatDist * sin(degToRad(hAng - fov / 2.f)), maxRenderDistance * sin(degToRad(vAng - fov / 2.f)), flatDist * -cos(degToRad(hAng - fov / 2.f))); + Vec3f p3(flatDist * sin(degToRad(hAng + fov / 2.f)), maxRenderDistance * sin(degToRad(vAng - fov / 2.f)), flatDist * -streflop::cos(degToRad(hAng + fov / 2.f))); + Vec3f p4(flatDist * sin(degToRad(hAng - fov / 2.f)), maxRenderDistance * sin(degToRad(vAng - fov / 2.f)), flatDist * -streflop::cos(degToRad(hAng - fov / 2.f))); // find the floor if(-p1.y > pos.y) { p1 = p1 * pos.y / abs(p1.y); @@ -182,9 +182,9 @@ Quad2i GameCamera::computeVisibleQuad() const{ float farDist = 90.f * (pos.y > 20.f ? pos.y / 15.f : 1.f); float fov = Config::getInstance().getFloat("CameraFov","45"); - Vec2f v(sinf(degToRad(180 - hAng)), cosf(degToRad(180 - hAng))); - Vec2f v1(sinf(degToRad(180 - hAng - fov)), cosf(degToRad(180 - hAng - fov))); - Vec2f v2(sinf(degToRad(180 - hAng + fov)), cosf(degToRad(180 - hAng + fov))); + Vec2f v(streflop::sinf(degToRad(180 - hAng)), streflop::cosf(degToRad(180 - hAng))); + Vec2f v1(streflop::sinf(degToRad(180 - hAng - fov)), streflop::cosf(degToRad(180 - hAng - fov))); + Vec2f v2(streflop::sinf(degToRad(180 - hAng + fov)), streflop::cosf(degToRad(180 - hAng + fov))); v.normalize(); v1.normalize(); v2.normalize(); @@ -246,8 +246,8 @@ void GameCamera::transitionVH(float v, float h) { } void GameCamera::zoom(float dist) { - float flatDist = dist * cosf(degToRad(vAng)); - Vec3f offset(flatDist * sinf(degToRad(hAng)), dist * sinf(degToRad(vAng)), flatDist * -cosf(degToRad(hAng))); + float flatDist = dist * streflop::cosf(degToRad(vAng)); + Vec3f offset(flatDist * streflop::sinf(degToRad(hAng)), dist * streflop::sinf(degToRad(vAng)), flatDist * -streflop::cosf(degToRad(hAng))); destPos += offset; } @@ -308,7 +308,7 @@ void GameCamera::clampAng() { //move camera forwad but never change heightFactor void GameCamera::moveForwardH(float d, float response) { - Vec3f offset(sinf(degToRad(hAng)) * d, 0.f, -cosf(degToRad(hAng)) * d); + Vec3f offset(streflop::sinf(degToRad(hAng)) * d, 0.f, -streflop::cosf(degToRad(hAng)) * d); destPos += offset; pos.x += offset.x * response; pos.z += offset.z * response; @@ -316,7 +316,7 @@ void GameCamera::moveForwardH(float d, float response) { //move camera to a side but never change heightFactor void GameCamera::moveSideH(float d, float response){ - Vec3f offset(sinf(degToRad(hAng+90)) * d, 0.f, -cosf(degToRad(hAng+90)) * d); + Vec3f offset(streflop::sinf(degToRad(hAng+90)) * d, 0.f, -streflop::cosf(degToRad(hAng+90)) * d); destPos += offset; pos.x += (destPos.x - pos.x) * response; pos.z += (destPos.z - pos.z) * response; diff --git a/source/glest_game/game/script_manager.cpp b/source/glest_game/game/script_manager.cpp index b013dd229..51da2fecf 100644 --- a/source/glest_game/game/script_manager.cpp +++ b/source/glest_game/game/script_manager.cpp @@ -71,8 +71,6 @@ void ScriptManager::init(World* world, GameCamera *gameCamera){ luaScript.registerFunction(getLastDeadUnitId, "lastDeadUnit"); luaScript.registerFunction(getUnitCount, "unitCount"); luaScript.registerFunction(getUnitCountOfType, "unitCountOfType"); - luaScript.registerFunction(unfogMap, "unfogMap"); - //load code for(int i= 0; igetScriptCount(); ++i){ @@ -397,14 +395,4 @@ int ScriptManager::getUnitCountOfType(LuaHandle* luaHandle){ return luaArguments.getReturnCount(); } -void ScriptManager::unfogMap() { - world->setFogOfWar(false); -} - -int ScriptManager::unfogMap(LuaHandle* luaHandle){ - LuaArguments luaArguments(luaHandle); - thisScriptManager->unfogMap(); - return luaArguments.getReturnCount(); -} - }}//end namespace diff --git a/source/glest_game/game/script_manager.h b/source/glest_game/game/script_manager.h index 4bb044659..eabfb34fa 100644 --- a/source/glest_game/game/script_manager.h +++ b/source/glest_game/game/script_manager.h @@ -136,7 +136,6 @@ private: void disableAi(int factionIndex); void setPlayerAsWinner(int factionIndex); void endGame(); - void unfogMap(); //wrappers, queries Vec2i getStartLocation(int factionIndex); @@ -163,7 +162,6 @@ private: static int disableAi(LuaHandle* luaHandle); static int setPlayerAsWinner(LuaHandle* luaHandle); static int endGame(LuaHandle* luaHandle); - static int unfogMap(LuaHandle* luaHandle); //callbacks, queries static int getStartLocation(LuaHandle* luaHandle); diff --git a/source/glest_game/graphics/renderer.cpp b/source/glest_game/graphics/renderer.cpp index e165b179e..2f484f14c 100644 --- a/source/glest_game/graphics/renderer.cpp +++ b/source/glest_game/graphics/renderer.cpp @@ -24,6 +24,8 @@ #include "opengl.h" #include "faction.h" #include "factory_repository.h" +#include + #include "leak_dumper.h" using namespace Shared::Graphics; @@ -1775,13 +1777,13 @@ void Renderer::renderMinimap(){ glColor4f(1.f, 1.f, 1.f, 0.0f); glVertex2i( - mx + x + static_cast(20*sin(ang-pi/5)), - my + mh - (y-static_cast(20*cos(ang-pi/5)))); + mx + x + static_cast(20*streflop::sin(ang-pi/5)), + my + mh - (y-static_cast(20*streflop::cos(ang-pi/5)))); glColor4f(1.f, 1.f, 1.f, 0.0f); glVertex2i( - mx + x + static_cast(20*sin(ang+pi/5)), - my + mh - (y-static_cast(20*cos(ang+pi/5)))); + mx + x + static_cast(20*streflop::sin(ang+pi/5)), + my + mh - (y-static_cast(20*streflop::cos(ang+pi/5)))); glEnd(); glPopAttrib(); @@ -2393,12 +2395,12 @@ float Renderer::computeMoonAngle(float time){ Vec4f Renderer::computeSunPos(float time){ float ang= computeSunAngle(time); - return Vec4f(-cos(ang)*sunDist, sin(ang)*sunDist, 0.f, 0.f); + return Vec4f(-streflop::cos(ang)*sunDist, streflop::sin(ang)*sunDist, 0.f, 0.f); } Vec4f Renderer::computeMoonPos(float time){ float ang= computeMoonAngle(time); - return Vec4f(-cos(ang)*moonDist, sin(ang)*moonDist, 0.f, 0.f); + return Vec4f(-streflop::cos(ang)*moonDist, streflop::sin(ang)*moonDist, 0.f, 0.f); } Vec3f Renderer::computeLightColor(float time){ diff --git a/source/glest_game/gui/gui.h b/source/glest_game/gui/gui.h index 235bdb9f4..1ee95a700 100644 --- a/source/glest_game/gui/gui.h +++ b/source/glest_game/gui/gui.h @@ -21,7 +21,7 @@ #include "random.h" #include -using Shared::Util::Random; +//using Shared::Util::Random; namespace Glest{ namespace Game{ @@ -102,7 +102,7 @@ public: private: //External objects - Random random; + Shared::Util::Random random; const Commander *commander; const World *world; GameCamera *gameCamera; diff --git a/source/glest_game/main/main.cpp b/source/glest_game/main/main.cpp index 32dfae2ac..a0fe90c52 100644 --- a/source/glest_game/main/main.cpp +++ b/source/glest_game/main/main.cpp @@ -8,6 +8,10 @@ // License, or (at your option) any later version // ============================================================== +#ifdef USE_STREFLOP + #include "streflop.h" +#endif + #include "main.h" #include @@ -260,6 +264,13 @@ void MainWindow::setProgram(Program *program) { SystemFlags debugger; int glestMain(int argc, char** argv){ +#ifdef STREFLOP_H + streflop_init(); + printf("%s, STREFLOP enabled.\n",getNetworkVersionString().c_str()); +#else + printf("%s, STREFLOP disabled.\n",getNetworkVersionString().c_str()); +#endif + SystemFlags::enableNetworkDebugInfo = true; SystemFlags::enableDebugText = true; SystemFlags::enablePerformanceDebugInfo = false; diff --git a/source/glest_game/menu/main_menu.h b/source/glest_game/menu/main_menu.h index a438ab942..7008461af 100644 --- a/source/glest_game/menu/main_menu.h +++ b/source/glest_game/menu/main_menu.h @@ -46,6 +46,8 @@ struct ScenarioInfo bool defaultVictoryConditions; string desc; + + bool fogOfWar; }; class MenuState; diff --git a/source/glest_game/menu/menu_background.h b/source/glest_game/menu/menu_background.h new file mode 100644 index 000000000..2edbbcd0b --- /dev/null +++ b/source/glest_game/menu/menu_background.h @@ -0,0 +1,104 @@ +// ============================================================== +// This file is part of Glest (www.glest.org) +// +// Copyright (C) 2001-2008 Martio Figueroa +// +// You can redistribute this code and/or modify it under +// the terms of the GNU General Public License as published +// by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version +// ============================================================== + +#ifndef _GLEST_GAME_MENUBACKGROUND_H_ +#define _GLEST_GAME_MENUBACKGROUND_H_ + +#include "particle.h" +#include "camera.h" +#include "vec.h" +#include "texture.h" +#include "model.h" +#include "random.h" + +using Shared::Graphics::RainParticleSystem; +using Shared::Graphics::FireParticleSystem; +using Shared::Graphics::Camera; +using Shared::Graphics::Vec3f; +using Shared::Graphics::Vec2f; +using Shared::Graphics::Texture2D; +using Shared::Graphics::Model; +//using Shared::Util::Random; + +namespace Glest{ namespace Game{ + +// =========================================================== +// class MenuBackground +// +/// Holds the data to display the 3D environment +/// in the MenuState +// =========================================================== + +class MenuBackground{ +public: + static const int meshSize= 32; + static const int raindropCount= 1000; + static const int characterCount= 5; + +private: + Model *mainModel; + + //water + bool water; + float waterHeight; + Texture2D *waterTexture; + + //fog + bool fog; + float fogDensity; + + //rain + bool rain; + Vec2f raindropPos[raindropCount]; + float raindropStates[raindropCount]; + + //camera + Camera camera; + Camera lastCamera; + const Camera *targetCamera; + float t; + + //misc + Shared::Util::Random random; + Model *characterModels[characterCount]; + float anim; + float fade; + Vec3f aboutPosition; + +public: + MenuBackground(); + + bool getWater() const {return water;} + float getWaterHeight() const {return waterHeight;} + bool getFog() const {return fog;} + float getFogDensity() const {return fogDensity;} + bool getRain() const {return rain;} + Texture2D *getWaterTexture() const {return waterTexture;} + const Camera *getCamera() const {return &camera;} + const Model *getCharacterModel(int i) const {return characterModels[i];} + const Model *getMainModel() const {return mainModel;} + float getFade() const {return fade;} + Vec2f getRaindropPos(int i) const {return raindropPos[i];} + float getRaindropState(int i) const {return raindropStates[i];} + float getAnim() const {return anim;} + const Vec3f &getAboutPosition() const {return aboutPosition;} + + void setTargetCamera(const Camera *targetCamera); + void update(); + +private: + Vec2f computeRaindropPos(); +}; + +}} //end namespace + +#endif + diff --git a/source/glest_game/menu/menu_state_scenario.cpp b/source/glest_game/menu/menu_state_scenario.cpp index b897ca77d..967ba3fdb 100644 --- a/source/glest_game/menu/menu_state_scenario.cpp +++ b/source/glest_game/menu/menu_state_scenario.cpp @@ -198,6 +198,13 @@ void MenuStateScenario::loadScenarioInfo(string file, ScenarioInfo *scenarioInfo scenarioInfo->desc+= lang.get("Map") + ": " + formatString(scenarioInfo->mapName) + "\n"; scenarioInfo->desc+= lang.get("Tileset") + ": " + formatString(scenarioInfo->tilesetName) + "\n"; scenarioInfo->desc+= lang.get("TechTree") + ": " + formatString(scenarioInfo->techTreeName) + "\n"; + + if(scenarioNode->hasChild("fog-of-war") == true) { + scenarioInfo->fogOfWar = scenarioNode->getChild("fog-of-war")->getAttribute("value")->getBoolValue(); + } + else { + scenarioInfo->fogOfWar = true; + } } void MenuStateScenario::loadGameSettings(const ScenarioInfo *scenarioInfo, GameSettings *gameSettings){ @@ -229,6 +236,7 @@ void MenuStateScenario::loadGameSettings(const ScenarioInfo *scenarioInfo, GameS } gameSettings->setFactionCount(factionCount); + gameSettings->setFogOfWar(scenarioInfo->fogOfWar); } ControlType MenuStateScenario::strToControllerType(const string &str){ diff --git a/source/glest_game/sound/sound_container.h b/source/glest_game/sound/sound_container.h new file mode 100644 index 000000000..5f5cd3478 --- /dev/null +++ b/source/glest_game/sound/sound_container.h @@ -0,0 +1,53 @@ +// ============================================================== +// This file is part of Glest (www.glest.org) +// +// Copyright (C) 2001-2008 Martio Figueroa +// +// You can redistribute this code and/or modify it under +// the terms of the GNU General Public License as published +// by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version +// ============================================================== + +#ifndef _GLEST_GAME_SOUNDCONTAINER_H_ +#define _GLEST_GAME_SOUNDCONTAINER_H_ + +#include + +#include "sound.h" +#include "random.h" + +using std::vector; +//using Shared::Util::Random; +using Shared::Sound::StaticSound; + +namespace Glest{ namespace Game{ + +// ===================================================== +// class SoundContainer +// +/// Holds a list of sounds that are usually played at random +// ===================================================== + +class SoundContainer{ +public: + typedef vector Sounds; + +private: + Sounds sounds; + mutable Shared::Util::Random random; + mutable int lastSound; + +public: + SoundContainer(); + + void resize(int size) {sounds.resize(size);} + StaticSound *&operator[](int i) {return sounds[i];} + + const Sounds &getSounds() const {return sounds;} + StaticSound *getRandSound() const; +}; + +}}//end namespace + +#endif diff --git a/source/glest_game/type_instances/object.cpp b/source/glest_game/type_instances/object.cpp new file mode 100644 index 000000000..0825a0555 --- /dev/null +++ b/source/glest_game/type_instances/object.cpp @@ -0,0 +1,64 @@ +// ============================================================== +// This file is part of Glest (www.glest.org) +// +// Copyright (C) 2001-2008 Martio Figueroa +// +// You can redistribute this code and/or modify it under +// the terms of the GNU General Public License as published +// by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version +// ============================================================== + +#include "object.h" + +#include "faction_type.h" +#include "tech_tree.h" +#include "resource.h" +#include "upgrade.h" +#include "object_type.h" +#include "resource.h" +#include "util.h" +#include "random.h" +#include "leak_dumper.h" + +using namespace Shared::Util; + +namespace Glest{ namespace Game{ + + +// ===================================================== +// class Object +// ===================================================== + +Object::Object(ObjectType *objectType, const Vec3f &pos){ + Shared::Util::Random random; + + random.init(static_cast(pos.x*pos.z)); + + this->objectType= objectType; + resource= NULL; + this->pos= pos + Vec3f(random.randRange(-0.6f, 0.6f), 0.0f, random.randRange(-0.6f, 0.6f)); + rotation= random.randRange(0.f, 360.f); + if(objectType!=NULL){ + variation = random.randRange(0, objectType->getModelCount()-1); + } +} + +Object::~Object(){ + delete resource; +} + +const Model *Object::getModel() const{ + return objectType==NULL? resource->getType()->getModel(): objectType->getModel(variation); +} + +bool Object::getWalkable() const{ + return objectType==NULL? false: objectType->getWalkable(); +} + +void Object::setResource(const ResourceType *resourceType, const Vec2i &pos){ + resource= new Resource(); + resource->init(resourceType, pos); +} + +}}//end namespace diff --git a/source/glest_game/type_instances/unit.cpp b/source/glest_game/type_instances/unit.cpp index 67b8b3faa..d14c02ffb 100644 --- a/source/glest_game/type_instances/unit.cpp +++ b/source/glest_game/type_instances/unit.cpp @@ -24,6 +24,8 @@ #include "core_data.h" #include "renderer.h" #include "leak_dumper.h" +#include + #include "socket.h" using namespace Shared::Graphics; @@ -244,7 +246,7 @@ float Unit::getVerticalRotation() const{ /*if(type->getProperty(UnitType::pRotatedClimb) && currSkill->getClass()==scMove){ float heightDiff= map->getCell(pos)->getHeight() - map->getCell(targetPos)->getHeight(); float dist= pos.dist(targetPos); - return radToDeg(atan2(heightDiff, dist)); + return radToDeg(streflop::atan2(heightDiff, dist)); }*/ return 0.f; } @@ -403,7 +405,7 @@ void Unit::setTargetPos(const Vec2i &targetPos){ Vec2i relPos= targetPos - pos; Vec2f relPosf= Vec2f(relPos.x, relPos.y); - targetRotation= radToDeg(atan2(relPosf.x, relPosf.y)); + targetRotation= radToDeg(streflop::atan2(relPosf.x, relPosf.y)); targetRef= NULL; this->targetPos= targetPos; @@ -979,7 +981,7 @@ void Unit::updateTarget(){ targetPos= target->getCellPos(); Vec2i relPos= targetPos - pos; Vec2f relPosf= Vec2f(relPos.x, relPos.y); - targetRotation= radToDeg(atan2(relPosf.x, relPosf.y)); + targetRotation= radToDeg(streflop::atan2(relPosf.x, relPosf.y)); //update target vec targetVec= target->getCurrVector(); diff --git a/source/glest_game/world/map.cpp b/source/glest_game/world/map.cpp index 9f866b967..eb9476753 100644 --- a/source/glest_game/world/map.cpp +++ b/source/glest_game/world/map.cpp @@ -663,7 +663,7 @@ bool PosCircularIterator::next(){ if(pos.y>center.y+radius) return false; } - while(floor(pos.dist(center)) >= (radius+1) || !map->isInside(pos)); + while(streflop::floor(pos.dist(center)) >= (radius+1) || !map->isInside(pos)); //while(!(pos.dist(center) <= radius && map->isInside(pos))); return true; diff --git a/source/glest_game/world/tileset.cpp b/source/glest_game/world/tileset.cpp index fcff4e9b7..6947f8747 100644 --- a/source/glest_game/world/tileset.cpp +++ b/source/glest_game/world/tileset.cpp @@ -1,7 +1,7 @@ // ============================================================== // This file is part of Glest (www.glest.org) // -// Copyright (C) 2001-2008 Martiņo Figueroa +// Copyright (C) 2001-2008 Martio Figueroa // // You can redistribute this code and/or modify it under // the terms of the GNU General Public License as published @@ -195,7 +195,7 @@ void Tileset::load(const string &dir, Checksum *checksum){ const XmlNode *weatherNode= parametersNode->getChild("weather"); float sunnyProb= weatherNode->getAttribute("sun")->getFloatValue(0.f, 1.f); float rainyProb= weatherNode->getAttribute("rain")->getFloatValue(0.f, 1.f) + sunnyProb; - float rnd= fabs(random.randRange(-1.f, 1.f)); + float rnd= streflop::fabs(random.randRange(-1.f, 1.f)); if(rndisInside(i, j) && floor(floatCenter.dist(Vec2f(i, j))) <= (range+1)){ + if(map->isInside(i, j) && streflop::floor(floatCenter.dist(Vec2f(i, j))) <= (range+1)){ //all fields for(int k=0; k + +#include "vec.h" + +namespace Shared{ namespace Graphics{ + +const float pi= 3.1415926f; +const float sqrt2= 1.41421356f; +const float zero= 1e-6f; +const float infinity= 1e6f; + +// ===================================================== +// class Rect +// ===================================================== + +// 0 +-+ +// | | +// +-+ 1 + +template +class Rect2{ +public: + Vec2 p[2]; +public: + Rect2(){ + }; + + Rect2(const Vec2 &p0, const Vec2 &p1){ + this->p[0]= p0; + this->p[1]= p1; + } + + Rect2(T p0x, T p0y, T p1x, T p1y){ + p[0].x= p0x; + p[0].y= p0y; + p[1].x= p1x; + p[1].y= p1y; + } + + Rect2 operator*(T scalar){ + return Rect2( + p[0]*scalar, + p[1]*scalar); + } + + Rect2 operator/(T scalar){ + return Rect2( + p[0]/scalar, + p[1]/scalar); + } + + bool isInside(const Vec2 &p) const{ + return + p.x>=this->p[0].x && + p.y>=this->p[0].y && + p.xp[1].x && + p.yp[1].y; + } + + void clamp(T minX, T minY,T maxX, T maxY){ + for(int i=0; i<2; ++i){ + if(p[i].xmaxX){ + p[i].x= maxX; + } + if(p[i].y>maxY){ + p[i].y= maxY; + } + } + } +}; + +typedef Rect2 Rect2i; +typedef Rect2 Rect2c; +typedef Rect2 Rect2f; +typedef Rect2 Rect2d; + +// ===================================================== +// class Quad +// ===================================================== + +// 0 +-+ 2 +// | | +// 1 +-+ 3 + +template +class Quad2{ +public: + Vec2 p[4]; +public: + Quad2(){ + }; + + Quad2(const Vec2 &p0, const Vec2 &p1, const Vec2 &p2, const Vec2 &p3){ + this->p[0]= p0; + this->p[1]= p1; + this->p[2]= p2; + this->p[3]= p3; + } + + explicit Quad2(const Rect2 &rect){ + this->p[0]= rect.p[0]; + this->p[1]= Vec2(rect.p[0].x, rect.p[1].y); + this->p[2]= rect.p[1]; + this->p[3]= Vec2(rect.p[1].x, rect.p[0].y); + } + + Quad2 operator*(T scalar){ + return Quad2( + p[0]*scalar, + p[1]*scalar, + p[2]*scalar, + p[3]*scalar); + } + + Quad2 operator/(T scalar){ + return Quad2( + p[0]/scalar, + p[1]/scalar, + p[2]/scalar, + p[3]/scalar); + } + + Rect2 computeBoundingRect() const{ + return Rect2i( + min(p[0].x, p[1].x), + min(p[0].y, p[2].y), + max(p[2].x, p[3].x), + max(p[1].y, p[3].y)); + } + + bool isInside(const Vec2 &pt) const{ + + if(!computeBoundingRect().isInside(pt)) + return false; + + bool left[4]; + + left[0]= (pt.y - p[0].y)*(p[1].x - p[0].x) - (pt.x - p[0].x)*(p[1].y - p[0].y) < 0; + left[1]= (pt.y - p[1].y)*(p[3].x - p[1].x) - (pt.x - p[1].x)*(p[3].y - p[1].y) < 0; + left[2]= (pt.y - p[3].y)*(p[2].x - p[3].x) - (pt.x - p[3].x)*(p[2].y - p[3].y) < 0; + left[3]= (pt.y - p[2].y)*(p[0].x - p[2].x) - (pt.x - p[2].x)*(p[0].y - p[2].y) < 0; + + return left[0] && left[1] && left[2] && left[3]; + } + + void clamp(T minX, T minY, T maxX, T maxY){ + for(int i=0; i<4; ++i){ + if(p[i].xmaxX){ + p[i].x= maxX; + } + if(p[i].y>maxY){ + p[i].y= maxY; + } + } + } + + float area(){ + Vec2i v0= p[3]-p[0]; + Vec2i v1= p[1]-p[2]; + + return 0.5f * ((v0.x * v1.y) - (v0.y * v1.x)); + } +}; + +typedef Quad2 Quad2i; +typedef Quad2 Quad2c; +typedef Quad2 Quad2f; +typedef Quad2 Quad2d; + +// ===================================================== +// Misc +// ===================================================== + +inline int next2Power(int n){ + int i; + for (i=1; i +inline T degToRad(T deg){ + return (deg*2*pi)/360; +} + +template +inline T radToDeg(T rad){ + return (rad*360)/(2*pi); +} + +}}//end namespace + +#endif diff --git a/source/shared_lib/include/graphics/matrix.h b/source/shared_lib/include/graphics/matrix.h new file mode 100644 index 000000000..3048cb2f8 --- /dev/null +++ b/source/shared_lib/include/graphics/matrix.h @@ -0,0 +1,162 @@ +// ============================================================== +// This file is part of Glest Shared Library (www.glest.org) +// +// Copyright (C) 2001-2008 Martio Figueroa +// +// You can redistribute this code and/or modify it under +// the terms of the GNU General Public License as published +// by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version +// ============================================================== + +#ifndef _SHARED_GRAPHICS_MATRIX_H_ +#define _SHARED_GRAPHICS_MATRIX_H_ + +//#include + +#include "vec.h" + +namespace Shared{ namespace Graphics{ + +// ===================================================== +// class Matrix3 +// ===================================================== + +template +class Matrix3{ +private: + T data[9]; +public: + Matrix3(){}; + + Matrix3(T *p){ + for(int i=0; i<9; ++i){ + data[i]= p[i]; + } + } + + T *ptr(){ + return data; + } + + const T *ptr() const{ + return data; + } + + T &operator[](int i){ + return data[i]; + } + + T &operator()(int i, int j){ + return data[i*3+j]; + } + + Vec3 operator * (const Vec3 &v) const{ + Vec3 rv; + + return Vec3f( + data[0]*v.x + data[1]*v.y + data[2]*v.z, + data[3]*v.x + data[4]*v.y + data[5]*v.z, + data[6]*v.x + data[7]*v.y + data[8]*v.z); + } + + Matrix3 operator * (const Matrix3 &m) const{ + Matrix3 rm; + + for(int i=0; i<3; ++i){ + for(int j=0; j<3; ++j){ + T acum= 0.0f; + for(int k=0; k<3; ++k){ + acum+= data[i*3+k]*m[k*3+j]; + } + rm[i*3+j]= acum; + } + } + return rm; + } + + void traspose(){ + for(int i=0; i<3; ++i){ + for(int j=0; j<3; ++j){ + T tmp= data[j*3+i]; + data[j*3+i]= data[i*3+j]; + data[i*3+j]= tmp; + } + } + } +}; + +typedef Matrix3 Matrix3f; +typedef Matrix3 Matrix3d; + +// ===================================================== +// class Matrix4 +// ===================================================== + +template +class Matrix4{ +private: + T data[16]; +public: + Matrix4(){}; + + Matrix4(T *p){ + for(int i=0; i<16; ++i){ + data[i]= p[i]; + } + } + + T *ptr(){ + return data; + } + + const T *ptr() const{ + return data; + } + + T &operator[](int i){ + return data[i]; + } + + const T &operator[](int i) const{ + return data[i]; + } + + T &operator()(int i, int j){ + return data[i*4+j]; + } + + Vec4 operator * (const Vec4 &v) const{ + Vec4 rv; + + return Vec4f( + data[0]*v.x + data[1]*v.y + data[2]*v.z + data[3]*v.w, + data[4]*v.x + data[5]*v.y + data[6]*v.z + data[7]*v.w, + data[8]*v.x + data[9]*v.y + data[10]*v.z + data[11]*v.w, + data[12]*v.x + data[13]*v.y + data[14]*v.z + data[15]*v.w); + } + + Matrix4 operator * (const Matrix4 &m) const{ + Matrix4 rm; + + for(int i=0; i<4; ++i){ + for(int j=0; j<4; ++j){ + T acum= 0.0f; + for(int k=0; k<4; ++k){ + acum+= data[i*4+k]*m[k*4+j]; + } + rm[i*4+j]= acum; + } + } + return rm; + } + +}; + +typedef Matrix4 Matrix4f; +typedef Matrix4 Matrix4d; + + +}} //enmd namespace + +#endif diff --git a/source/shared_lib/include/graphics/particle.h b/source/shared_lib/include/graphics/particle.h index f68b6a0c1..f779a2c92 100644 --- a/source/shared_lib/include/graphics/particle.h +++ b/source/shared_lib/include/graphics/particle.h @@ -21,7 +21,7 @@ #include "random.h" using std::list; -using Shared::Util::Random; +//using Shared::Util::Random; namespace Shared{ namespace Graphics{ @@ -95,7 +95,7 @@ protected: protected: Particle *particles; - Random random; + Shared::Util::Random random; BlendMode blendMode; State state; diff --git a/source/shared_lib/include/graphics/vec.h b/source/shared_lib/include/graphics/vec.h new file mode 100644 index 000000000..6f35a5605 --- /dev/null +++ b/source/shared_lib/include/graphics/vec.h @@ -0,0 +1,444 @@ +// ============================================================== +// This file is part of Glest Shared Library (www.glest.org) +// +// Copyright (C) 2001-2008 Martio Figueroa +// +// You can redistribute this code and/or modify it under +// the terms of the GNU General Public License as published +// by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version +// ============================================================== + + +#ifndef _SHARED_GRAPHICS_VEC_H_ +#define _SHARED_GRAPHICS_VEC_H_ + +#include "streflop_cond.h" +//#include + +namespace Shared{ namespace Graphics{ + +template class Vec2; +template class Vec3; +template class Vec4; + +// ===================================================== +// class Vec2 +// ===================================================== + +template +class Vec2{ +public: + T x; + T y; +public: + Vec2(){ + }; + + explicit Vec2(T *p){ + this->x= p[0]; + this->y= p[1]; + } + + explicit Vec2(T xy){ + this->x= xy; + this->y= xy; + } + + template + explicit Vec2(const Vec2 &v){ + this->x= v.x; + this->y= v.y; + } + + Vec2(T x, T y){ + this->x= x; + this->y= y; + } + + T *ptr(){ + return reinterpret_cast(this); + } + + const T *ptr() const{ + return reinterpret_cast(this); + } + + bool operator ==(const Vec2 &v) const{ + return x==v.x && y==v.y; + } + + bool operator !=(const Vec2 &v) const{ + return x!=v.x || y!=v.y; + } + + Vec2 operator +(const Vec2 &v) const{ + return Vec2(x+v.x, y+v.y); + } + + Vec2 operator -(const Vec2 &v) const{ + return Vec2(x-v.x, y-v.y); + } + + Vec2 operator -() const{ + return Vec2(-x, -y); + } + + Vec2 operator *(const Vec2 &v) const{ + return Vec2(x*v.x, y*v.y); + } + + Vec2 operator *(T s) const{ + return Vec2(x*s, y*s); + } + + Vec2 operator /(const Vec2 &v) const{ + return Vec2(x/v.x, y/v.y); + } + + Vec2 operator /(T s) const{ + return Vec2(x/s, y/s); + } + + Vec2 operator +=(const Vec2 &v){ + x+=v.x; + y+=v.y; + return *this; + } + + Vec2 operator -=(const Vec2 &v){ + x-=v.x; + y-=v.y; + return *this; + } + + Vec2 lerp(T t, const Vec2 &v) const{ + return *this + (v - *this)*t; + } + + T dot(const Vec2 &v) const{ + return x*v.x+y*v.y; + } + + float dist(const Vec2 &v) const{ + return Vec2(v-*this).length(); + } + + float length() const{ + return static_cast(streflop::sqrt(static_cast(x*x + y*y))); + } + + void normalize(){ + T m= length(); + x/= m; + y/= m; + } +}; + +typedef Vec2 Vec2i; +typedef Vec2 Vec2b; +typedef Vec2 Vec2c; +typedef Vec2 Vec2f; +typedef Vec2 Vec2d; + +// ===================================================== +// class Vec3 +// ===================================================== + +template +class Vec3{ +public: + T x; + T y; + T z; + +public: + Vec3(){ + }; + + explicit Vec3(T *p){ + this->x= p[0]; + this->y= p[1]; + this->z= p[2]; + } + + explicit Vec3(T xyz){ + this->x= xyz; + this->y= xyz; + this->z= xyz; + } + + template + explicit Vec3(const Vec3 &v){ + this->x= v.x; + this->y= v.y; + this->z= v.z; + } + + Vec3(T x, T y, T z){ + this->x= x; + this->y= y; + this->z= z; + } + + explicit Vec3(Vec4 v){ + this->x= v.x; + this->y= v.y; + this->z= v.z; + } + + T *ptr(){ + return reinterpret_cast(this); + } + + const T *ptr() const{ + return reinterpret_cast(this); + } + + bool operator ==(const Vec3 &v) const{ + return x==v.x && y==v.y && z==v.z; + } + + bool operator !=(const Vec3 &v) const{ + return x!=v.x || y!=v.y || z!=v.z; + } + + Vec3 operator +(const Vec3 &v) const{ + return Vec3(x+v.x, y+v.y, z+v.z); + } + + Vec3 operator -(const Vec3 &v) const{ + return Vec3(x-v.x, y-v.y, z-v.z); + } + + Vec3 operator -() const{ + return Vec3(-x, -y, -z); + } + + Vec3 operator *(const Vec3 &v) const{ + return Vec3(x*v.x, y*v.y, z*v.z); + } + + Vec3 operator *(T s) const{ + return Vec3(x*s, y*s, z*s); + } + + Vec3 operator /(const Vec3 &v) const{ + return Vec3(x/v.x, y/v.y, z/v.z); + } + + Vec3 operator /(T s) const{ + return Vec3(x/s, y/s, z/s); + } + + Vec3 operator +=(const Vec3 &v){ + x+=v.x; + y+=v.y; + z+=v.z; + return *this; + } + + Vec3 operator -=(const Vec3 &v){ + x-=v.x; + y-=v.y; + z-=v.z; + return *this; + } + + Vec3 lerp(T t, const Vec3 &v) const{ + return *this + (v - *this) * t; + } + + T dot(const Vec3 &v) const{ + return x*v.x + y*v.y + z*v.z; + } + + float dist(const Vec3 &v) const{ + return Vec3(v-*this).length(); + } + + float length() const{ + return static_cast(streflop::sqrt(x*x + y*y + z*z)); + } + + void normalize(){ + T m= length(); + x/= m; + y/= m; + z/= m; + } + + Vec3 getNormalized() const{ + T m= length(); + return Vec3(x/m, y/m, z/m); + } + + Vec3 cross(const Vec3 &v) const{ + return Vec3( + this->y*v.z-this->z*v.y, + this->z*v.x-this->x*v.z, + this->x*v.y-this->y*v.x); + } + + Vec3 normal(const Vec3 &p1, const Vec3 &p2) const{ + Vec3 rv; + rv= (p2-*this).cross(p1-*this); + rv.normalize(); + return rv; + } + + Vec3 normal(const Vec3 &p1, const Vec3 &p2, const Vec3 &p3, const Vec3 &p4) const{ + Vec3 rv; + + rv= this->normal(p1, p2); + rv= rv + this->normal(p2, p3); + rv= rv + this->normal(p3, p4); + rv= rv + this->normal(p4, p1); + rv.normalize(); + return rv; + } + +}; + +typedef Vec3 Vec3i; +typedef Vec3 Vec3b; +typedef Vec3 Vec3c; +typedef Vec3 Vec3f; +typedef Vec3 Vec3d; + +// ===================================================== +// class Vec4 +// ===================================================== + +template +class Vec4{ +public: + T x; + T y; + T z; + T w; +public: + Vec4(){ + }; + + explicit Vec4(T *p){ + this->x= p[0]; + this->y= p[1]; + this->z= p[2]; + this->w= p[3]; + } + + explicit Vec4(T xyzw){ + this->x= xyzw; + this->y= xyzw; + this->z= xyzw; + this->w= xyzw; + } + + template + explicit Vec4(const Vec4 &v){ + this->x= v.x; + this->y= v.y; + this->z= v.z; + this->w= v.w; + } + + Vec4(T x, T y, T z, T w){ + this->x= x; + this->y= y; + this->z= z; + this->w= w; + } + + Vec4(Vec3 v, T w){ + this->x= v.x; + this->y= v.y; + this->z= v.z; + this->w= w; + } + + explicit Vec4(Vec3 v){ + this->x= v.x; + this->y= v.y; + this->z= v.z; + this->w= 1; + } + + T *ptr(){ + return reinterpret_cast(this); + } + + const T *ptr() const{ + return reinterpret_cast(this); + } + + bool operator ==(const Vec4 &v) const{ + return x==v.x && y==v.y && z==v.z && w==v.w; + } + + bool operator !=(const Vec4 &v) const{ + return x!=v.x || y!=v.y || z!=v.z || w!=v.w; + } + + Vec4 operator +(const Vec4 &v) const{ + return Vec4(x+v.x, y+v.y, z+v.z, w+v.w); + } + + Vec4 operator -(const Vec4 &v) const{ + return Vec4(x-v.x, y-v.y, z-v.z, w-v.w); + } + + Vec4 operator -() const{ + return Vec4(-x, -y, -z, -w); + } + + Vec4 operator *(const Vec4 &v) const{ + return Vec4(x*v.x, y*v.y, z*v.z, w*v.w); + } + + Vec4 operator *(T s) const{ + return Vec4(x*s, y*s, z*s, w*s); + } + + Vec4 operator /(const Vec4 &v) const{ + return Vec4(x/v.x, y/v.y, z/v.z, w/v.w); + } + + Vec4 operator /(T s) const{ + return Vec4(x/s, y/s, z/s, w/s); + } + + Vec4 operator +=(const Vec4 &v){ + x+=v.x; + y+=v.y; + z+=v.z; + w+=w.z; + return *this; + } + + Vec4 operator -=(const Vec4 &v){ + x-=v.x; + y-=v.y; + z-=v.z; + w-=w.z; + return *this; + } + + Vec4 lerp(T t, const Vec4 &v) const{ + return *this + (v - *this) *t; + } + + T dot(const Vec4 &v) const{ + return x*v.x + y*v.y + z*v.z + w*v.w; + } +}; + +typedef Vec4 Vec4i; +typedef Vec4 Vec4b; +typedef Vec4 Vec4c; +typedef Vec4 Vec4f; +typedef Vec4 Vec4d; + +}} //enmd namespace + +#endif diff --git a/source/shared_lib/include/streflop/CMakeLists.txt b/source/shared_lib/include/streflop/CMakeLists.txt new file mode 100644 index 000000000..54e969f35 --- /dev/null +++ b/source/shared_lib/include/streflop/CMakeLists.txt @@ -0,0 +1,16 @@ +AUX_SOURCE_DIRECTORY(libm/flt-32 libm_flt32_source) + +SET(cxxflags "-w -O3 -I${CMAKE_CURRENT_SOURCE_DIR}/libm/headers") +if (NOT $ENV{CXX} MATCHES "icpc") + SET(cxxflags "${cxxflags} -mfpmath=sse -msse") +endif (NOT $ENV{CXX} MATCHES "icpc") +SET_SOURCE_FILES_PROPERTIES(${libm_flt32_source} PROPERTIES COMPILE_FLAGS "-DLIBM_COMPILING_FLT32 ${cxxflags}") + +ADD_LIBRARY(streflop STATIC EXCLUDE_FROM_ALL + SMath.cpp + Random.cpp + streflopC.cpp + ${libm_flt32_source} +) +set_target_properties(streflop PROPERTIES COMPILE_FLAGS "${PIC_FLAG}") +#TODO do not use -fPIC for streflop (decreases performance) diff --git a/source/shared_lib/include/streflop/FPUSettings.h b/source/shared_lib/include/streflop/FPUSettings.h new file mode 100644 index 000000000..013be871e --- /dev/null +++ b/source/shared_lib/include/streflop/FPUSettings.h @@ -0,0 +1,533 @@ +/* + streflop: STandalone REproducible FLOating-Point + Nicolas Brodu, 2006 + Code released according to the GNU Lesser General Public License + + Heavily relies on GNU Libm, itself depending on netlib fplibm, GNU MP, and IBM MP lib. + Uses SoftFloat too. + + Please read the history and copyright information in the documentation provided with the source code +*/ + +/* + For reference, the layout of the MXCSR register: + FZ:RC:RC:PM:UM:OM:ZM:DM:IM:Rsvd:PE:UE:OE:ZE:DE:IE + 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + + And the layout of the 387 FPU control word register: + Rsvd:Rsvd:Rsvd:X:RC:RC:PC:PC:Rsvd:Rsvd:PM:UM:OM:ZM:DM:IM + 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + + Where: + Rsvd - Reserved + FZ - Flush to Zero + RC - Rounding Control + PM - Precision Mask + UM - Underflow Mask + OM - Overflow Mask + ZM - Zerodivide Mask + DM - Denormal Mask + IM - Invalid Mask + PE - Precision Exception + UE - Underflow Exception + OE - Overflow Exception + ZE - Zerodivide Exception + DE - Denormal Exception + IE - Invalid Exception + X - Infinity control (unused on 387 and higher) + PC - Precision Control + + Source: Intel Architecture Software Development Manual, Volume 1, Basic Architecture +*/ + +// Included by the main streflop include file +// module broken apart for logical code separation +#ifndef STREFLOP_FPU_H +#define STREFLOP_FPU_H + +// Can safely make the symbols from softfloat visible to user program, protected in namespace +#if defined(STREFLOP_SOFT) +#include "softfloat/softfloat.h" +#endif + +namespace streflop { + +// We do not use libm, so let's copy a few flags and C99 functions +// Give warning in case these flags would be defined already, this is indication +// of potential confusion! + +#if defined(FE_INVALID) || defined(FE_DENORMAL) || defined(FE_DIVBYZERO) || defined(FE_OVERFLOW) || defined(FE_UNDERFLOW) || defined(FE_INEXACT) || defined(FE_DOWNWARD) || defined(FE_TONEAREST) || defined(FE_TOWARDZERO) || defined(FE_UPWARD) + +#warning STREFLOP: FE_XXX flags were already defined and will be redefined! Check you do not use the system libm. +#undef FE_INVALID +#undef FE_DENORMAL +#undef FE_DIVBYZERO +#undef FE_OVERFLOW +#undef FE_UNDERFLOW +#undef FE_INEXACT +#undef FE_INEXACT +#undef FE_ALL_EXCEPT +#undef FE_DOWNWARD +#undef FE_TONEAREST +#undef FE_TOWARDZERO +#undef FE_UPWARD +#endif // defined(FE_INVALID) || ... + + +// Flags for FPU exceptions +enum FPU_Exceptions { + + // Invalid operation. If not signaling, gives NaN instead + FE_INVALID = 0x0001, + #define FE_INVALID FE_INVALID + + // Extension: for x86 and SSE + // Denormal operand. If not signaling, use denormal arithmetic as usual + FE_DENORMAL = 0x0002, + #define FE_DENORMAL FE_DENORMAL + + // Division by zero. If not signaling, uses +/- infinity + FE_DIVBYZERO = 0x0004, + #define FE_DIVBYZERO FE_DIVBYZERO + + // Overflow. If not signaling, round to nearest (including infinity) according to rounding mode + FE_OVERFLOW = 0x0008, + #define FE_OVERFLOW FE_OVERFLOW + + // Underflow. If not signaling, use 0 instead + FE_UNDERFLOW = 0x0010, + #define FE_UNDERFLOW FE_UNDERFLOW + + // Rounding was not exact (ex: sqrt(2) is never exact) or when overflow causes rounding + FE_INEXACT = 0x0020, + #define FE_INEXACT FE_INEXACT + + // Combination of all the above + FE_ALL_EXCEPT = 0x003F + #define FE_ALL_EXCEPT FE_ALL_EXCEPT +}; + +// Flags for FPU rounding modes +enum FPU_RoundMode { + FE_TONEAREST = 0x0000, + #define FE_TONEAREST FE_TONEAREST + + FE_DOWNWARD = 0x0400, + #define FE_DOWNWARD FE_DOWNWARD + + FE_UPWARD = 0x0800, + #define FE_UPWARD FE_UPWARD + + FE_TOWARDZERO = 0x0C00 + #define FE_TOWARDZERO FE_TOWARDZERO +}; + +/* Note: SSE control word, bits 0..15 +0->5: Run-time status flags +6: DAZ (denormals are zero, i.e. don't use denormals if bit is 1) +7->12: Exception flags, same meaning as for the x87 ones +13,14: Rounding flags, same meaning as for the x87 ones +15: Flush to zero (FTZ) for automatic handling of underflow (default is NO) +*/ + +// plan for portability +#if defined(_MSC_VER) +#define STREFLOP_FSTCW(cw) do { short tmp; __asm { fstcw tmp }; (cw) = tmp; } while (0) +#define STREFLOP_FLDCW(cw) do { short tmp = (cw); __asm { fclex }; __asm { fldcw tmp }; } while (0) +#define STREFLOP_STMXCSR(cw) do { int tmp; __asm { stmxcsr tmp }; (cw) = tmp; } while (0) +#define STREFLOP_LDMXCSR(cw) do { int tmp = (cw); __asm { ldmxcsr tmp }; } while (0) +#else // defined(_MSC_VER) +#define STREFLOP_FSTCW(cw) do { asm volatile ("fstcw %0" : "=m" (cw) : ); } while (0) +#define STREFLOP_FLDCW(cw) do { asm volatile ("fclex \n fldcw %0" : : "m" (cw)); } while (0) +#define STREFLOP_STMXCSR(cw) do { asm volatile ("stmxcsr %0" : "=m" (cw) : ); } while (0) +#define STREFLOP_LDMXCSR(cw) do { asm volatile ("ldmxcsr %0" : : "m" (cw) ); } while (0) +#endif // defined(_MSC_VER) + +// Subset of all C99 functions + +#if defined(STREFLOP_X87) + +/// Raise exception for these flags +inline int feraiseexcept(FPU_Exceptions excepts) { + unsigned short fpu_mode; + STREFLOP_FSTCW(fpu_mode); + fpu_mode &= ~( excepts ); // generate error for selection + STREFLOP_FLDCW(fpu_mode); + return 0; +} + +/// Clear exceptions for these flags +inline int feclearexcept(int excepts) { + unsigned short fpu_mode; + STREFLOP_FSTCW(fpu_mode); + fpu_mode |= excepts; + STREFLOP_FLDCW(fpu_mode); + return 0; +} + +/// Get current rounding mode +inline int fegetround() { + unsigned short fpu_mode; + STREFLOP_FSTCW(fpu_mode); + return fpu_mode & 0x0C00; +} + +/// Set a new rounding mode +inline int fesetround(FPU_RoundMode roundMode) { + unsigned short fpu_mode; + STREFLOP_FSTCW(fpu_mode); + fpu_mode &= 0xF3FF; // clear current mode + fpu_mode |= roundMode; // sets new mode + STREFLOP_FLDCW(fpu_mode); + return 0; +} + +typedef short int fenv_t; + +/// Default env. Defined in Math.cpp to be 0, and initalized on first use to the permanent holder +extern fenv_t FE_DFL_ENV; + +/// Get FP env into the given structure +inline int fegetenv(fenv_t *envp) { + // check that default env exists, otherwise save it now + if (!FE_DFL_ENV) STREFLOP_FSTCW(FE_DFL_ENV); + // Now store env into argument + STREFLOP_FSTCW(*envp); + return 0; +} + +/// Sets FP env from the given structure +inline int fesetenv(const fenv_t *envp) { + // check that default env exists, otherwise save it now + if (!FE_DFL_ENV) STREFLOP_FSTCW(FE_DFL_ENV); + // Now overwrite current env by argument + STREFLOP_FLDCW(*envp); + return 0; +} + +/// get env and clear exceptions +inline int feholdexcept(fenv_t *envp) { + fegetenv(envp); + feclearexcept(FE_ALL_EXCEPT); + return 0; +} + + +template inline void streflop_init() { + struct X {}; + X Unknown_numeric_type; + // unknown types do not compile + T error = Unknown_numeric_type; +} + +/// Initialize the FPU for the different types +/// this may also be called to switch between code sections using +/// different precisions +template<> inline void streflop_init() { + unsigned short fpu_mode; + STREFLOP_FSTCW(fpu_mode); + fpu_mode &= 0xFCFF; // 32 bits internal operations + STREFLOP_FLDCW(fpu_mode); + + // Enable signaling nans if compiled with this option. +#if defined(__SUPPORT_SNAN__) && !defined(USE_GML) + feraiseexcept(streflop::FPU_Exceptions(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW)); +#endif +} + +template<> inline void streflop_init() { + unsigned short fpu_mode; + STREFLOP_FSTCW(fpu_mode); + fpu_mode &= 0xFCFF; + fpu_mode |= 0x0200; // 64 bits internal operations + STREFLOP_FLDCW(fpu_mode); + +#if defined(__SUPPORT_SNAN__) && !defined(USE_GML) + feraiseexcept(streflop::FPU_Exceptions(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW)); +#endif +} + +#if defined(Extended) +template<> inline void streflop_init() { + unsigned short fpu_mode; + STREFLOP_FSTCW(fpu_mode); + fpu_mode &= 0xFCFF; + fpu_mode |= 0x0300; // 80 bits internal operations + STREFLOP_FLDCW(fpu_mode); + +#if defined(__SUPPORT_SNAN__) && !defined(USE_GML) + feraiseexcept(streflop::FPU_Exceptions(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW)); +#endif +} +#endif // defined(Extended) + +#elif defined(STREFLOP_SSE) + +/// Raise exception for these flags +inline int feraiseexcept(FPU_Exceptions excepts) { + // Just in case the compiler would store a value on the st(x) registers + unsigned short x87_mode; + STREFLOP_FSTCW(x87_mode); + x87_mode &= ~( excepts ); // generate error for selection + STREFLOP_FLDCW(x87_mode); + + int sse_mode; + STREFLOP_STMXCSR(sse_mode); + sse_mode &= ~( excepts << 7 ); // generate error for selection + STREFLOP_LDMXCSR(sse_mode); + + return 0; +} + +/// Clear exceptions for these flags +inline int feclearexcept(int excepts) { + // Just in case the compiler would store a value on the st(x) registers + unsigned short x87_mode; + STREFLOP_FSTCW(x87_mode); + x87_mode |= excepts; + STREFLOP_FLDCW(x87_mode); + + int sse_mode; + STREFLOP_STMXCSR(sse_mode); + sse_mode |= excepts << 7; + STREFLOP_LDMXCSR(sse_mode); + + return 0; +} + +/// Get current rounding mode +inline int fegetround() { + int sse_mode; + STREFLOP_STMXCSR(sse_mode); + return (sse_mode>>3) & 0x00000C00; +} + +/// Set a new rounding mode +inline int fesetround(FPU_RoundMode roundMode) { + int sse_mode; + STREFLOP_STMXCSR(sse_mode); + sse_mode &= 0xFFFF9FFF; // clear current mode + sse_mode |= roundMode<<3; // sets new mode + STREFLOP_LDMXCSR(sse_mode); + return 0; +} + +/// stores both x87 and SSE words +struct fenv_t { + int sse_mode; + short int x87_mode; +}; + +/// Default env. Defined in Math.cpp, structs are initialized to 0 +extern fenv_t FE_DFL_ENV; + +/// Get FP env into the given structure +inline int fegetenv(fenv_t *envp) { + // check that default env exists, otherwise save it now + if (!FE_DFL_ENV.x87_mode) STREFLOP_FSTCW(FE_DFL_ENV.x87_mode); + // Now store env into argument + STREFLOP_FSTCW(envp->x87_mode); + + // For SSE + if (!FE_DFL_ENV.sse_mode) STREFLOP_STMXCSR(FE_DFL_ENV.sse_mode); + // Now store env into argument + STREFLOP_STMXCSR(envp->sse_mode); + return 0; +} + +/// Sets FP env from the given structure +inline int fesetenv(const fenv_t *envp) { + // check that default env exists, otherwise save it now + if (!FE_DFL_ENV.x87_mode) STREFLOP_FSTCW(FE_DFL_ENV.x87_mode); + // Now overwrite current env by argument + STREFLOP_FLDCW(envp->x87_mode); + + // For SSE + if (!FE_DFL_ENV.sse_mode) STREFLOP_STMXCSR(FE_DFL_ENV.sse_mode); + // Now overwrite current env by argument + STREFLOP_LDMXCSR(envp->sse_mode); + return 0; +} + +/// get env and clear exceptions +inline int feholdexcept(fenv_t *envp) { + fegetenv(envp); + feclearexcept(FE_ALL_EXCEPT); + return 0; +} + + +template inline void streflop_init() { + // Do nothing by default, or for unknown types +} + +/// Initialize the FPU for the different types +/// this may also be called to switch between code sections using +/// different precisions +template<> inline void streflop_init() { + // Just in case the compiler would store a value on the st(x) registers + unsigned short x87_mode; + STREFLOP_FSTCW(x87_mode); + x87_mode &= 0xFCFF; // 32 bits internal operations + STREFLOP_FLDCW(x87_mode); + + int sse_mode; + STREFLOP_STMXCSR(sse_mode); +#if defined(STREFLOP_NO_DENORMALS) + sse_mode |= 0x8040; // set DAZ and FTZ +#else + sse_mode &= 0xFFFF7FBF; // clear DAZ and FTZ +#endif + STREFLOP_LDMXCSR(sse_mode); +} + +template<> inline void streflop_init() { + // Just in case the compiler would store a value on the st(x) registers + unsigned short x87_mode; + STREFLOP_FSTCW(x87_mode); + x87_mode &= 0xFCFF; + x87_mode |= 0x0200; // 64 bits internal operations + STREFLOP_FLDCW(x87_mode); + + int sse_mode; + STREFLOP_STMXCSR(sse_mode); +#if defined(STREFLOP_NO_DENORMALS) + sse_mode |= 0x8040; // set DAZ and FTZ +#else + sse_mode &= 0xFFFF7FBF; // clear DAZ and FTZ +#endif + STREFLOP_LDMXCSR(sse_mode); +} + +#if defined(Extended) +template<> inline void streflop_init() { + // Just in case the compiler would store a value on the st(x) registers + unsigned short x87_mode; + STREFLOP_FSTCW(x87_mode); + x87_mode &= 0xFCFF; + x87_mode |= 0x0300; // 80 bits internal operations + STREFLOP_FLDCW(x87_mode); + + int sse_mode; + STREFLOP_STMXCSR(sse_mode); +#if defined(STREFLOP_NO_DENORMALS) + sse_mode |= 0x8040; // set DAZ and FTZ +#else + sse_mode &= 0xFFFF7FBF; // clear DAZ and FTZ +#endif + STREFLOP_LDMXCSR(sse_mode); +} +#endif // defined(Extended) + + +#elif defined(STREFLOP_SOFT) +/// Raise exception for these flags +inline int feraiseexcept(FPU_Exceptions excepts) { + // Use positive logic + SoftFloat::float_exception_realtraps |= excepts; + return 0; +} + +/// Clear exceptions for these flags +inline int feclearexcept(int excepts) { + // Use positive logic + SoftFloat::float_exception_realtraps &= ~( excepts ); + return 0; +} + +/// Get current rounding mode +inline int fegetround() { + // see softfloat.h for the definition + switch (SoftFloat::float_rounding_mode) { + case SoftFloat::float_round_down: return FE_DOWNWARD; + case SoftFloat::float_round_up: return FE_UPWARD; + case SoftFloat::float_round_to_zero: return FE_TOWARDZERO; + default:; // is also initial mode + } + // case SoftFloat::float_round_nearest_even: + return FE_TONEAREST; +} + +/// Set a new rounding mode +inline int fesetround(FPU_RoundMode roundMode) { + // see softfloat.h for the definition + switch (roundMode) { + case FE_DOWNWARD: SoftFloat::float_rounding_mode = SoftFloat::float_round_down; return 0; + case FE_UPWARD: SoftFloat::float_rounding_mode = SoftFloat::float_round_up; return 0; + case FE_TOWARDZERO: SoftFloat::float_rounding_mode = SoftFloat::float_round_to_zero; return 0; + case FE_TONEAREST: SoftFloat::float_rounding_mode = SoftFloat::float_round_nearest_even; return 0; + } + // Error, invalid mode + return 1; +} + +/// SoftFloat environment comprises non-volatile state variables +struct fenv_t { + char tininess; + char rounding_mode; + int exception_realtraps; +}; + +/// Default env. Defined in Math.cpp, initialized to some invalid value for detection +extern fenv_t FE_DFL_ENV; + +/// Get FP env into the given structure +inline int fegetenv(fenv_t *envp) { + // check that default env exists, otherwise save it now + if (FE_DFL_ENV.tininess==42) { + // First use: save default environment now + FE_DFL_ENV.tininess = SoftFloat::float_detect_tininess; + FE_DFL_ENV.rounding_mode = SoftFloat::float_rounding_mode; + FE_DFL_ENV.exception_realtraps = SoftFloat::float_exception_realtraps; + } + // Now get the current env in the given argument + envp->tininess = SoftFloat::float_detect_tininess; + envp->rounding_mode = SoftFloat::float_rounding_mode; + envp->exception_realtraps = SoftFloat::float_exception_realtraps; + return 0; +} + +/// Sets FP env from the given structure +inline int fesetenv(const fenv_t *envp) { + // check that default env exists, otherwise save it now + if (FE_DFL_ENV.tininess==42) { + // First use: save default environment now + FE_DFL_ENV.tininess = SoftFloat::float_detect_tininess; + FE_DFL_ENV.rounding_mode = SoftFloat::float_rounding_mode; + FE_DFL_ENV.exception_realtraps = SoftFloat::float_exception_realtraps; + } + // Now get the current env in the given argument + SoftFloat::float_detect_tininess = envp->tininess; + SoftFloat::float_rounding_mode = envp->rounding_mode; + SoftFloat::float_exception_realtraps = envp->exception_realtraps; + return 0; +} + +/// get env and clear exceptions +inline int feholdexcept(fenv_t *envp) { + fegetenv(envp); + feclearexcept(FE_ALL_EXCEPT); + return 0; +} + +template inline void streflop_init() { + // Do nothing by default, or for unknown types +} + +/// Initialize the FPU for the different types +/// this may also be called to switch between code sections using +/// different precisions +template<> inline void streflop_init() { +} +template<> inline void streflop_init() { +} +template<> inline void streflop_init() { +} + +#else // defined(STREFLOP_X87) +#error STREFLOP: Invalid combination or unknown FPU type. +#endif // defined(STREFLOP_X87) + +} + +#endif // STREFLOP_FPU_H diff --git a/source/shared_lib/include/streflop/IntegerTypes.h b/source/shared_lib/include/streflop/IntegerTypes.h new file mode 100644 index 000000000..943df14df --- /dev/null +++ b/source/shared_lib/include/streflop/IntegerTypes.h @@ -0,0 +1,139 @@ +/* + streflop: STandalone REproducible FLOating-Point + Nicolas Brodu, 2006 + Code released according to the GNU Lesser General Public License + + Heavily relies on GNU Libm, itself depending on netlib fplibm, GNU MP, and IBM MP lib. + Uses SoftFloat too. + + Please read the history and copyright information in the documentation provided with the source code +*/ + +#ifndef STREFLOP_INTEGER_TYPES_H +#define STREFLOP_INTEGER_TYPES_H + +// Given that: +// - C++ template metaprogramming is Turing complete +// - types are variables and integers are constants +// - sizeof(type) is known by the C++ compiler and a constant +// - sizeof(char) is 1 by definition, even if char != 8 bits +// Then: It is possible to derive the sized ints at compile time in C++, unlike C +// Note: This is NOT the same as the int32_t, etc from C99, in case char != 8 bits +// For this reason, redefine the macro below if this is not the case for you +// Note2: Even if char != 8 bits, it's still possible to define ints in terms of number of char! +#define STREFLOP_INTEGER_TYPES_CHAR_BITS 8 + +// Avoid conflict with system types, if any +namespace streflop { + +// Template meta-programming: this is the "program" which variables are types and constants are int template arguments +// Algorithm: provide an expected size, and recursively increase the integer types till the size match +template struct SizedTypeMaker { +}; + +// start by long long to provide the recursion terminal condition + +// false : the expected_size does not exist: do not define a type, there will be a compilation error +template struct SizedTypeMaker { + // Error: Integer type with expected size does not exist +}; + +// true: end recursion by defining the correct type to be long long +template struct SizedTypeMaker { + typedef long long final_type; +}; + +// false : recurse by increasing the integer type till it reaches the expected size +template struct SizedTypeMaker { + typedef typename SizedTypeMaker::final_type final_type; +}; + +// true: end recursion by defining the correct type to be long +template struct SizedTypeMaker { + typedef long final_type; +}; + +// false : recurse by increasing the integer type till it reaches the expected size +template struct SizedTypeMaker { + typedef typename SizedTypeMaker::final_type final_type; +}; + +// true: end recursion by defining the correct type to be int +template struct SizedTypeMaker { + typedef int final_type; +}; + +// false : recurse by increasing the integer type till it reaches the expected size +template struct SizedTypeMaker { + typedef typename SizedTypeMaker::final_type final_type; +}; + +// true: end recursion by defining the correct type to be short +template struct SizedTypeMaker { + typedef short final_type; +}; + + +// Do it again for unsigned types + +// false : the expected_size does not exist: do not define a type, there will be a compilation error +template struct SizedTypeMaker { + // Error: Integer type with expected size does not exist +}; + +// true: end recursion by defining the correct type to be long long +template struct SizedTypeMaker { + typedef unsigned long long final_type; +}; + +// false : recurse by increasing the integer type till it reaches the expected size +template struct SizedTypeMaker { + typedef typename SizedTypeMaker::final_type final_type; +}; + +// true: end recursion by defining the correct type to be long +template struct SizedTypeMaker { + typedef unsigned long final_type; +}; + +// false : recurse by increasing the integer type till it reaches the expected size +template struct SizedTypeMaker { + typedef typename SizedTypeMaker::final_type final_type; +}; + +// true: end recursion by defining the correct type to be int +template struct SizedTypeMaker { + typedef unsigned int final_type; +}; + +// false : recurse by increasing the integer type till it reaches the expected size +template struct SizedTypeMaker { + typedef typename SizedTypeMaker::final_type final_type; +}; + +// true: end recursion by defining the correct type to be short +template struct SizedTypeMaker { + typedef unsigned short final_type; +}; + +// Utility to get an int type with the selected size IN BITS +template struct SizedInteger { + typedef typename SizedTypeMaker::final_type Type; +}; +template struct SizedUnsignedInteger { + typedef typename SizedTypeMaker::final_type Type; +}; + +// Specialize for size = STREFLOP_INTEGER_TYPES_CHAR_BITS + +template<> struct SizedInteger { + typedef char Type; +}; + +template<> struct SizedUnsignedInteger { + typedef unsigned char Type; +}; + +} + +#endif diff --git a/source/shared_lib/include/streflop/LGPL.txt b/source/shared_lib/include/streflop/LGPL.txt new file mode 100644 index 000000000..cf9b6b997 --- /dev/null +++ b/source/shared_lib/include/streflop/LGPL.txt @@ -0,0 +1,510 @@ + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations +below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. +^L + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it +becomes a de-facto standard. To achieve this, non-free programs must +be allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. +^L + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control +compilation and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. +^L + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. +^L + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at least + three years, to give the same user the materials specified in + Subsection 6a, above, for a charge no more than the cost of + performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. +^L + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. +^L + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply, and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License +may add an explicit geographical distribution limitation excluding those +countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. +^L + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS +^L + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms +of the ordinary General Public License). + + To apply these terms, attach the following notices to the library. +It is safest to attach them to the start of each source file to most +effectively convey the exclusion of warranty; and each file should +have at least the "copyright" line and a pointer to where the full +notice is found. + + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or +your school, if any, to sign a "copyright disclaimer" for the library, +if necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James + Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/source/shared_lib/include/streflop/README.txt b/source/shared_lib/include/streflop/README.txt new file mode 100644 index 000000000..9b7b27a42 --- /dev/null +++ b/source/shared_lib/include/streflop/README.txt @@ -0,0 +1,205 @@ +STandalone REproducible FLOating-Point library +Version 0.2, june 2006. +Nicolas Brodu. See also the acknowledgments below. + + +For a quick setup guide, see the "usage" sections below. + + + +Presentation: + +Floating-point computations are strongly dependent on the FPU hardware implementation, the compiler and its optimizations, and the system mathematical library (libm). Experiments are usually reproducible only on the same machine with the same system library and the same compiler using the same options. Even then, the C++ standard does NOT guarantee reproducible results. Example: + + double x = 1.0; x /= 10.0; + double y = x; + ... + if (y == x) { + // THIS IS NOT ALWAYS TRUE! + } + +A related but more general problem is random number generation, often necessary for experiment reproducibility: + + set_random_seed(42); + double x = random_number(); + +May not return the same x across different FPUs / systems / compilers / etc. + + + +These problems are related to: + +- Some FPU (like x87 on Linux) keep by default an internal precision (80 bits) larger than the type size in memory. In the first example, if x is on the stack but y in a register, the comparison will fail. Worse, whether x and/or y is on the stack or register depends on what you put in the ... section. This problem can be solved by restricting the internal FPU precision to the type size in memory. Unfortunately, on x87, some operations like the transcendental functions are always computed on 80 bits... + +- How well your FPU implements the IEEE754 standard, and in particular, denormal number operations. The provided arithmetic_test code reproducibly gives different results between SSE and x87. This problem is NOT generally solved by restricting the internal precision to the type size in memory. There may be relations however, in particular a denormal float may be a normal double, so the precision matters. + +- How your compiler interacts with your system math library (libm) especially with optimization flags. In particular, gcc-3.4 and gcc-4.0 series may give different results on the same system with the same library. This problem is partially solved by changing the compiler options. + +- Even then, the IEEE754 standard has some loopholes concerning NaN types. In particular, when serializing results, binary files may differ. This problem is solved by comparing numerical values and not bit patterns. + + + +More points to consider: + +- SSE has an option to accelerate computations by approximating denormals by 0. For some applications this is plain wrong, but for other applications like real-time DSP, denormals are a real pain and this is just what's needed (reports have been made that a denormal multiply may take as much as 30 times a normal multiply). Due to the default round-to-nearest mode, the denormals tend NOT to cancel to 0 and may instead accumulate. Deactivating denormals is built-in the core SSE FPU, but unfortunately that's not reproducible on x87. In that case, it's possible to check for denormal conditions after each operation (including assignment) and then flush to zero, thanks to a wrapper type, for reproducibility (but at the expense of performance on x87). + +- No external dependency. The more dependencies, the more chances of a version mismatch. This library should be standalone, providing the whole libm features without resorting to system specific includes or other packages. This way, it can be included in a project as is, with minimal specialization (and risk of misconfiguration). + + + +Proposed solution: + +- Provide Simple, Double and Extended types that match the native types (float, double, long double), but that additionally take care of the FPU internal precision and denormal handling. These types may be simple aliases or C++ wrappers, depending on the FPU and configuration. Note: Extended is the 80-bit type defined by x87. + +- Reimplement the libm as a standalone code that uses these types. Note: For extended support, see below. + +- As a bonus, provide a random number generator so as to make standalone experiments reproducible. + +- Compare with a software floating-point reference implementation. + + + +Usage (programming): + +- Include "streflop.h" in place of , and link with streflop.a instead of libm. All streflop functions are protected by a namespace, so if another part of your program uses libm there is no risk of confusion at link time. However, including the correct file matters. + +- Use the streflop namespace, and the Simple, Double and Extended types as needed, instead of float, double, long double. The streflop types may actually be aliases to the C++ types, or wrapper classes that redefine the operators transparently. + +- You should also call streflop_init with FloatType=Simple,Double,Extended before using that type. You should use only this type (ex: Simple) until the next call to streflop_init. That is, separate your code in blocks using one type at a time. In the simplest case, use streflop_init for your chosen type at the beginning of your program and stick to that type later on. These init functions are necessary to set the correct FPU flags. See also the notes below. + +- You may have a look at arithmeticTest.cpp and randomTest.cpp for examples. + + + +Usage (standalone build): + +- Edit Makefile.common to configure which FPU/denormal setup you choose, by defining one of STREFLOP_SSE, STREFLOP_X87, STREFLOP_SOFT, and optionally STREFLOP_NO_DENORMALS. See the configurations grid below. + +- If you're using the software floating-point implementation on a big-endian machine, change the System.h file accordingly. If your target system size has a char type larger than 8 bits, then check Integer.h. In both cases you're on your own (this is untested). + +- Check the notes below before changing the compiler options. + + + +Usage (including in a project): + +- Copy the whole streflop source somewhere in your project, for example as a "streflop" subdirectory. + +- Check the steps for the standalone build. Potentially automate the choices using your build system, like autoconf. + +- Call "make -C streflop" somewhere in you own build process, or integrate the streflop build in your build system. + +- See the programming usage above. Don't forget to "-Istreflop" and "-Lstreflop -lstreflop.a" when compiling and linking. + + + +Configurations grid: + + | SSE | x87 | Soft | +------------+---------+-----------+----------+ +denormals | Simple *| Simple *| Simple | + | Double *| Double *| Double | + | | Extended *| Extended | +------------+---------+-----------+----------+ +no denormal | Simple *| Simple | + | Double *| Double | + | | Extended | +------------+---------+-----------+ + +One cell in this grid must be selected at configure time. All types within that cell are then available at compile and run time. +Types marked * are aliases to the native float/double/long double, with support by FPU flags. +The other types are wrapper classes that behave like the native types. + + +Apart for the bit representation of NaN values: + +- "Denormals SSE / Denormals Soft" with the same precision should give the same results. + +- "No denormal SSE / No denormal x87" with the same precision should give the same results. + +- "Denormals x87 extended / Denormals Soft extended" should give the same results. + +- "Denormals SSE / Denormals x87" with the same precision may differ but only for some unfrequent occurences involving denormal numbers. + +- All other configurations give different results. + + + +Comparison criteria: + +- Best performance is achieved by "no denormal/SSE simple". What matters most for performance is wrapper/native, the size, then denormals or not (unless using lots of denormals, in which case "no denormals" may matter more than size or wrapper). + +- Best precision is achieved by "denormals extended" modes. What matters most for precision is the the size, then denormal or not. + +- Best IEEE754 conformance is achieved by "Soft" modes (and equivalent results above with SSE/x87). Conformance is achieved only for denormals. + + + +Notes: + +- Beware of too aggressive optimization options! In particular, since this code relies on reinterpret_cast and unions, the compiler must not assume strict aliasing. For g++ optimization levels 2 and 3, this assumption is unfortunately the default. Similarly, the compiler should not assume that NaN can be ignored, or that the FPU has a constant rounding mode. Ex: -O3 -fno-strict-aliasing -frounding-math -fsignaling-nans. + +- You should also set correct FPU options, like -mfpmath=sse -msse -msse2. The -msse2 is important, there are cases where g++ refuses to use SSE (and silently falls back to x87) when using -msse and not -msse2. This also means you cannot reliably use this library with gcc on systems where only sse (but not sse2) is present, like some athlon-xp cores. + +- The system libm will almost surely produce different numerical results depending on your FPU, compiler and options, etc. The rationale is, using this library will increase the reproducibility of your experiments compared to using the system libm. If you want guaranteed (but slower) reproducible results across all machine configurations, without caring for denormals or whatever else, then use a multiprecision software library like GNU MP. If you want to use the hardware FPU in a controlled environment that can retain some reproducibility, then use this library. If it does not fit your needs, then improve it: After all, this is free software :) + +- The following C99 trap and rounding mode functions are implemented, even for the software floating-point implementation: fe(get|set)round, fe(get|set)env, and feholdexcept. You may call them to change rounding modes and to trap special conditions. These functions are expected to work correctly, insofar as the FPU works as intended*, but they have not been extensively tested. +* in particular, reports have been made that the x87 FPU denormal trap sometimes fails. + +- Really beware of aggressive optimization! Separate your code into INDEPENDENT BLOCKS. I mean it. This code is wrong: + streflop_init(); + Simple s = (1.0/4294967295.0); + displayHex(cout, s) << endl; + streflop_init(); + Double d = (1.0/4294967295.0); + displayHex(cout, d) << endl; +THIS NOT WORK CORRECTLY in -O3, but will do fine in -O0. This is because the compiler "optimizes" the constant computation only once for both lines in -O3, which is plain wrong since the precision is different. The only way to ensure this does not happen is to separate your code in logical units: +void func1() { + streflop_init(); + Simple s = (1.0/4294967295.0); + displayHex(cout, s) << endl; +} +void func2() { + streflop_init(); + Double d = (1.0/4294967295.0); + displayHex(cout, d) << endl; +} +Even then, you'd better be careful with interprocedural optimization options. If possible, put func1 and func2 in 2 separate compilation units. + + + +BUGS and discrepancies: + +- Do what you want with this library, but at your own risks, and according to the LGPL (see the LGPL.txt file). + +- There is the possibility of unknown bugs. And this is based on GNU libm 2.4, so any potential bug in that version are almost surely present in streflop too. + +- Extended support is INCOMPLETE. Proper functions are missing, in particular the trigonometric functions. The ldbl-96 implementation of the libm does not contain a generic implementation for these files. Since strelop enforces strict separation of Extended and Double functions, these functions were instead implemented by temporarily switching to Double using streflop_init, calling the function and storing the result on the stack, switching back to streflop_init, then converting the result to an Extended number. + + + +Acknowledgments: + +- This code heavily relies on GNU Libm, itself depending on Sun's netlib fplibm, GNU MP, and IBM's multi-precision library. + +- This code uses the SoftFloat library for the software floating-point implementation. + +- The random number generator is the Mersene Twister, created by Takuji Nishimura and Makoto Matsumoto, and adapted to C++ for this project. Please read the (BSD-like) license in Random.cpp if you intend to make binary packages of this library (and according to LGPL). + +- Please read the history and copyright information in the accompanying README.txt files in the libm and softfloat directories, as well as the LGPL.txt file in this directory. + +- Thanks to Tobi Vollebregt for feedback, Win32 reports, and patches. + + + +How you can help: + +- Test the library and report potential bugs. + +- Port the library to new FPU and operating systems. + +- Help extend the GNU libm first, and only then import that work in this project. + + + +Nicolas Brodu, june 2006. diff --git a/source/shared_lib/include/streflop/Random.h b/source/shared_lib/include/streflop/Random.h new file mode 100644 index 000000000..fee7acd77 --- /dev/null +++ b/source/shared_lib/include/streflop/Random.h @@ -0,0 +1,245 @@ +/* + streflop: STandalone REproducible FLOating-Point + Nicolas Brodu, 2006 + Code released according to the GNU Lesser General Public License + + Heavily relies on GNU Libm, itself depending on netlib fplibm, GNU MP, and IBM MP lib. + Uses SoftFloat too. + + Please read the history and copyright information in the documentation provided with the source code +*/ + +#ifndef RANDOM_H +#define RANDOM_H + +// Need sized integer types, which are now system-independent thanks to template metaprogramming +#include "IntegerTypes.h" + +namespace streflop { + +/** Random state holder object + Declare one of this per thread, and use it as context to the random functions + Object is properly set by the RandomInit functions + This allows it to remain POD type +*/ +struct RandomState { +#if !defined(STREFLOP_RANDOM_GEN_SIZE) +#define STREFLOP_RANDOM_GEN_SIZE 32 +#endif + // state vector + SizedUnsignedInteger::Type mt[19968/STREFLOP_RANDOM_GEN_SIZE]; + int mti; + // random seed that was used for initialization + SizedUnsignedInteger<32>::Type seed; +} +#ifdef __GNUC__ +__attribute__ ((aligned (64))) // align state vector on cache line size +#endif +; + +/// Default random state holder +extern RandomState DefaultRandomState; + +/** Initialize the random number generator with the given seed. + + By default, the seed is taken from system time and printed out + so the experiment is reproducible by inputing the same seed again. + + You can set here a previous seed to reproduce it. + + This interface allows independance from the actual RNG used, + and/or system functions. + + The RNG used is the Mersenne twister implementation by the + original authors Takuji Nishimura and Makoto Matsumoto. + + See also Random.cpp for more information. +*/ +SizedUnsignedInteger<32>::Type RandomInit(RandomState& state = DefaultRandomState); +SizedUnsignedInteger<32>::Type RandomInit(SizedUnsignedInteger<32>::Type seed, RandomState& state = DefaultRandomState); + +/// Returns the random seed that was used for the initialization +/// Defaults to 0 if the RNG is not yet initialized +SizedUnsignedInteger<32>::Type RandomSeed(RandomState& state = DefaultRandomState); + +/** Returns a random number from a uniform distribution. + + All integer types are supported, as well as Simple, Double, and Extended + + The Random(min, max) template takes as argument: + - bool: whether or not including the min bound + - bool: whether or not including the max bound + - type: to generate a number from that type, and decide on min/max bounds + Example: Double x = Random(7.0, 18.0) + This will return a Double number between 7.0 (included) and 18.0 (excluded) + This works for both float and integer types. + + Aliases are named like RandomXY with X,Y = E,I for bounds Excluded,Included. + Example: RandomEI(min,max) will return a number between min (excluded) and max (included). + + The Random() template returns a number of the given type chosen uniformly between + all representable numbers of that type. + - For integer types, this means what you expect: any int, char, whatever on the whole range + - For float types, just recall that there are as many representable floats in each range + 2^x - 2^(x+1), this is what floating-point means + + Notes: + - If min > max then the result is undefined. + - If you ask for an empty interval (like RandomEE with min==max) then the result is undefined. + - If a NaN value is passed to the float functions, NaN is returned. + - By order of performance, for float types, IE is fastest, then EI, then EE, then II. For integer + types, it happens that the order is II, IE and EI ex-aequo, and EE, but the difference is much + less pronounced than for the float types. Use IE preferably for floats, II for ints. + + The floating-point functions always compute a random number with the maximum digits of precision, + taking care of bounds. That is, it uses the 1-2 interval as this is a power-of-two bounded interval, + so each representable number in that interval (matching a distinct bit pattern) is given exactly + the same weight. This is really a truly uniform distribution, unlike the 0-1 range (see note below). + That 1-2 interval is then converted to the min-max range, hopefully resulting in the loss of as + few random bits as possible. See also the additional functions below for better performance. + + Note: Getting numbers in the 0-1 interval may be tricky. Half the 2^X exponents are in that range as + well as denormal numbers. This could result in an horrible loss of bits when scaling from one exponent + to another. Fortunately, the numbers in 1-2 are generated with maximum precision, and then subtracting 1.0 + to get a number in 0-1 keeps that precision because all the numbers obtained this way are still perfectly + representable. Moreover, the minimum exponent reached this way is still far above the denormals range. + + Note3: The random number generator MUST be initialized for this function to work correctly. + + Note4: These functions are thread-safe if you use one RandomState object per thread (or if you + synchronize the access to a shared state object, of course). +*/ + +template a_type Random(a_type min, a_type max, RandomState& state = DefaultRandomState); +// function that returns a random number on the whole possible range +template a_type Random(RandomState& state = DefaultRandomState); +// Alias that can be useful too +template inline a_type RandomIE(a_type min, a_type max, RandomState& state = DefaultRandomState) {return Random(min, max, state);} +template inline a_type RandomEI(a_type min, a_type max, RandomState& state = DefaultRandomState) {return Random(min, max, state);} +template inline a_type RandomEE(a_type min, a_type max, RandomState& state = DefaultRandomState) {return Random(min, max, state);} +template inline a_type RandomII(a_type min, a_type max, RandomState& state = DefaultRandomState) {return Random(min, max, state);} +#define STREFLOP_RANDOM_MAKE_REAL(a_type) \ +template<> a_type Random(RandomState& state); \ +template<> a_type Random(a_type min, a_type max, RandomState& state); \ +template<> a_type Random(a_type min, a_type max, RandomState& state); \ +template<> a_type Random(a_type min, a_type max, RandomState& state); \ +template<> a_type Random(a_type min, a_type max, RandomState& state); + +STREFLOP_RANDOM_MAKE_REAL(char) +STREFLOP_RANDOM_MAKE_REAL(unsigned char) +STREFLOP_RANDOM_MAKE_REAL(short) +STREFLOP_RANDOM_MAKE_REAL(unsigned short) +STREFLOP_RANDOM_MAKE_REAL(int) +STREFLOP_RANDOM_MAKE_REAL(unsigned int) +STREFLOP_RANDOM_MAKE_REAL(long) +STREFLOP_RANDOM_MAKE_REAL(unsigned long) +STREFLOP_RANDOM_MAKE_REAL(long long) +STREFLOP_RANDOM_MAKE_REAL(unsigned long long) + + +/** Additional and faster functions for real numbers + These return a number in the 1..2 range, the base for all the other random functions +*/ +template a_type Random12(RandomState& state = DefaultRandomState); +// Alias that can be useful too +template inline a_type Random12IE(RandomState& state = DefaultRandomState) {return Random12(state);} +template inline a_type Random12EI(RandomState& state = DefaultRandomState) {return Random12(state);} +template inline a_type Random12EE(RandomState& state = DefaultRandomState) {return Random12(state);} +template inline a_type Random12II(RandomState& state = DefaultRandomState) {return Random12(state);} + +/** Additional and faster functions for real numbers + + These return a number in the 0..1 range by subtracting one to the 1..2 function + This avoids a multiplication for the min...max scaling + + Provided for convenience only, use the 1..2 range as the base random function +*/ +template inline a_type Random01(RandomState& state = DefaultRandomState) { + return Random12(state) - a_type(1.0); +} +// Alias that can be useful too +template inline a_type Random01IE(RandomState& state = DefaultRandomState) {return Random01(state);} +template inline a_type Random01EI(RandomState& state = DefaultRandomState) {return Random01(state);} +template inline a_type Random01EE(RandomState& state = DefaultRandomState) {return Random01(state);} +template inline a_type Random01II(RandomState& state = DefaultRandomState) {return Random01(state);} + +/// Define all 12 and 01 functions only for real types +/// use the 12 function to generate the other + +#define STREFLOP_RANDOM_MAKE_REAL_FLOAT_TYPES(a_type) \ +template<> a_type Random12(RandomState& state); \ +template<> a_type Random12(RandomState& state); \ +template<> a_type Random12(RandomState& state); \ +template<> a_type Random12(RandomState& state); \ +template<> a_type Random(RandomState& state); \ +template<> inline a_type Random(a_type min, a_type max, RandomState& state) { \ + a_type range = max - min;\ + return Random12(DefaultRandomState) * range - range + min;\ +} \ +template<> inline a_type Random(a_type min, a_type max, RandomState& state) { \ + a_type range = max - min;\ + return Random12(DefaultRandomState) * range - range + min;\ +} \ +template<> inline a_type Random(a_type min, a_type max, RandomState& state) { \ + a_type range = max - min;\ + return Random12(DefaultRandomState) * range - range + min;\ +} \ +template<> inline a_type Random(a_type min, a_type max, RandomState& state) { \ + a_type range = max - min;\ + return Random12(DefaultRandomState) * range - range + min;\ +} + + +STREFLOP_RANDOM_MAKE_REAL_FLOAT_TYPES(Simple) +STREFLOP_RANDOM_MAKE_REAL_FLOAT_TYPES(Double) + +#if defined(Extended) +STREFLOP_RANDOM_MAKE_REAL_FLOAT_TYPES(Extended) +#endif + + +/** + Utility to get a number from a Normal distribution + The no argument version returns a distribution with mean 0, variance 1. + The 2 argument version takes the desired mean standard deviation. + Both are only defined over the floating-point types + + This uses the common polar-coordinate method to transform between uniform and normal + Step 1: generate a pair of numbers in the -1,1 x -1,1 square + Step 2: loop over to step 1 until it is also in the unit circle + Step 3: Convert using the property property (U1, U2) = (X,Y) * sqrt( -2 * log(D) / D) + with D = X*X+Y*Y the squared distance and log(D) the natural logarithm function + Step 4: Choose U1 or U2, they are independent (keep the other for the next call) + Step 5 (optional): Scale and translate U to a given mean, std_dev + + There may be better numerical methods, but I'm too lazy to implement them. + Any suggestion/contribution is welcome! + + In particular, it seems quite horrendous to do computations close to the 0, in the 0-1 range, + where there may be denormals and the lot, to scale and translate later on. It would be better + to compute everything in another float interval (ex: 2 to 4 centered on 3 for the same square + has a uniform representable range of floats), and only then convert to the given mean/std_dev + at the last moment. + + Note: An optional argument "secondary" may be specified, and in that case, a second number + indepedent from the first will be returned at negligible cost (in other words, by default, half the values + are thrown away) +*/ +template a_type NRandom(a_type mean, a_type std_dev, a_type *secondary = 0, RandomState& state = DefaultRandomState); +template<> Simple NRandom(Simple mean, Simple std_dev, Simple *secondary, RandomState& state); +template<> Double NRandom(Double mean, Double std_dev, Double *secondary, RandomState& state); +#if defined(Extended) +template<> Extended NRandom(Extended mean, Extended std_dev, Extended *secondary, RandomState& state); +#endif +/// Simplified versions +template a_type NRandom(a_type *secondary = 0, RandomState& state = DefaultRandomState); +template<> Simple NRandom(Simple *secondary, RandomState& state); +template<> Double NRandom(Double *secondary, RandomState& state); +#if defined(Extended) +template<> Extended NRandom(Extended *secondary, RandomState& state); +#endif + +} + +#endif + diff --git a/source/shared_lib/include/streflop/SMath.h b/source/shared_lib/include/streflop/SMath.h new file mode 100644 index 000000000..7da7e55b3 --- /dev/null +++ b/source/shared_lib/include/streflop/SMath.h @@ -0,0 +1,721 @@ +/* + streflop: STandalone REproducible FLOating-Point + Nicolas Brodu, 2006 + Code released according to the GNU Lesser General Public License + + Heavily relies on GNU Libm, itself depending on netlib fplibm, GNU MP, + and IBM MP lib. + Uses SoftFloat too. + + Please read the history and copyright information in the documentation + provided with the source code +*/ + +// Included by the main streflop include file +// module broken apart for logical code separation +#ifndef STREFLOP_MATH_H +#define STREFLOP_MATH_H + +// just in case, should already be included +#include "streflop.h" + +// Names from the libm conversion +namespace streflop_libm { +using streflop::Simple; +using streflop::Double; +#ifdef Extended +using streflop::Extended; +#endif + + extern Simple __ieee754_sqrtf(Simple x); + extern Simple __cbrtf(Simple x); + extern Simple __ieee754_hypotf(Simple x, Simple y); + extern Simple __ieee754_expf(Simple x); + extern Simple __ieee754_logf(Simple x); + extern Simple __ieee754_log2f(Simple x); + extern Simple __ieee754_exp2f(Simple x); + extern Simple __ieee754_log10f(Simple x); + extern Simple __ieee754_powf(Simple x, Simple y); + extern Simple __sinf(Simple x); + extern Simple __cosf(Simple x); + extern Simple __tanhf(Simple x); + extern Simple __tanf(Simple x); + extern Simple __ieee754_acosf(Simple x); + extern Simple __ieee754_asinf(Simple x); + extern Simple __atanf(Simple x); + extern Simple __ieee754_atan2f(Simple x, Simple y); + extern Simple __ieee754_coshf(Simple x); + extern Simple __ieee754_sinhf(Simple x); + extern Simple __ieee754_acoshf(Simple x); + extern Simple __asinhf(Simple x); + extern Simple __ieee754_atanhf(Simple x); + extern Simple __fabsf(Simple x); + extern Simple __floorf(Simple x); + extern Simple __ceilf(Simple x); + extern Simple __truncf(Simple x); + extern Simple __ieee754_fmodf(Simple x, Simple y); + extern Simple __ieee754_remainderf(Simple x, Simple y); + extern Simple __remquof(Simple x, Simple y, int *quo); + extern Simple __rintf(Simple x); + extern long int __lrintf(Simple x); + extern long long int __llrintf(Simple x); + extern Simple __roundf(Simple x); + extern long int __lroundf(Simple x); + extern long long int __llroundf(Simple x); + extern Simple __nearbyintf(Simple x); + extern Simple __frexpf(Simple x, int *exp); + extern Simple __ldexpf(Simple value, int exp); + extern Simple __logbf(Simple x); + extern int __ilogbf(Simple x); + extern Simple __copysignf(Simple x); + extern int __signbitf(Simple x); + extern Simple __nextafterf(Simple x, Simple y); + extern Simple __expm1f(Simple x); + extern Simple __log1pf(Simple x); + extern Simple __erff(Simple x); + extern Simple __ieee754_j0f(Simple x); + extern Simple __ieee754_j1f(Simple x); + extern Simple __ieee754_jnf(int n, Simple x); + extern Simple __ieee754_y0f(Simple x); + extern Simple __ieee754_y1f(Simple x); + extern Simple __ieee754_ynf(int n, Simple x); + extern Simple __scalbnf(Simple x, int n); + extern Simple __scalblnf(Simple x, long int n); + extern int __fpclassifyf(Simple x); + extern int __isnanf(Simple x); + extern int __isinff(Simple x); + extern Double __ieee754_sqrt(Double x); + extern Double __cbrt(Double x); + extern Double __ieee754_hypot(Double x, Double y); + extern Double __ieee754_exp(Double x); + extern Double __ieee754_log(Double x); + extern Double __ieee754_log2(Double x); + extern Double __ieee754_exp2(Double x); + extern Double __ieee754_log10(Double x); + extern Double __ieee754_pow(Double x, Double y); + extern Double __sin(Double x); + extern Double __cos(Double x); + extern Double tan(Double x); + extern Double __ieee754_acos(Double x); + extern Double __ieee754_asin(Double x); + extern Double atan(Double x); + extern Double __ieee754_atan2(Double x, Double y); + extern Double __ieee754_cosh(Double x); + extern Double __ieee754_sinh(Double x); + extern Double __tanh(Double x); + extern Double __ieee754_acosh(Double x); + extern Double __asinh(Double x); + extern Double __ieee754_atanh(Double x); + extern Double __fabs(Double x); + extern Double __floor(Double x); + extern Double __ceil(Double x); + extern Double __trunc(Double x); + extern Double __ieee754_fmod(Double x, Double y); + extern Double __ieee754_remainder(Double x, Double y); + extern Double __remquo(Double x, Double y, int *quo); + extern Double __rint(Double x); + extern long int __lrint(Double x); + extern long long int __llrint(Double x); + extern Double __round(Double x); + extern long int __lround(Double x); + extern long long int __llround(Double x); + extern Double __nearbyint(Double x); + extern Double __frexp(Double x, int *exp); + extern Double __ldexp(Double value, int exp); + extern Double __logb(Double x); + extern int __ilogb(Double x); + extern Double __copysign(Double x); + extern int __signbit(Double x); + extern Double __nextafter(Double x, Double y); + extern Double __expm1(Double x); + extern Double __log1p(Double x); + extern Double __erf(Double x); + extern Double __ieee754_j0(Double x); + extern Double __ieee754_j1(Double x); + extern Double __ieee754_jn(int n, Double x); + extern Double __ieee754_y0(Double x); + extern Double __ieee754_y1(Double x); + extern Double __ieee754_yn(int n, Double x); + extern Double __scalbn(Double x, int n); + extern Double __scalbln(Double x, long int n); + extern int __fpclassify(Double x); + extern int __isnanl(Double x); + extern int __isinf(Double x); +#ifdef Extended + extern Extended __ieee754_sqrtl(Extended x); + extern Extended __cbrtl(Extended x); + extern Extended __ieee754_hypotl(Extended x, Extended y); + extern Extended __ieee754_expl(Extended x); + extern Extended __ieee754_logl(Extended x); + extern Extended __sinl(Extended x); + extern Extended __cosl(Extended x); + extern Extended __tanl(Extended x); + extern Extended __ieee754_asinl(Extended x); + extern Extended __atanl(Extended x); + extern Extended __ieee754_atan2l(Extended x, Extended y); + extern Extended __ieee754_coshl(Extended x); + extern Extended __ieee754_sinhl(Extended x); + extern Extended __tanhl(Extended x); + extern Extended __ieee754_acoshl(Extended x); + extern Extended __asinhl(Extended x); + extern Extended __ieee754_atanhl(Extended x); + extern Extended __fabsl(Extended x); + extern Extended __floorl(Extended x); + extern Extended __ceill(Extended x); + extern Extended __truncl(Extended x); + extern Extended __ieee754_fmodl(Extended x, Extended y); + extern Extended __ieee754_remainderl(Extended x, Extended y); + extern Extended __remquol(Extended x, Extended y, int *quo); + extern Extended __rintl(Extended x); + extern long int __lrintl(Extended x); + extern long long int __llrintl(Extended x); + extern Extended __roundl(Extended x); + extern long int __lroundl(Extended x); + extern long long int __llroundl(Extended x); + extern Extended __nearbyintl(Extended x); + extern Extended __frexpl(Extended x, int *exp); + extern Extended __ldexpl(Extended value, int exp); + extern Extended __logbl(Extended x); + extern int __ilogbl(Extended x); + extern Extended __copysignl(Extended x); + extern int __signbitl(Extended x); + extern Extended __nextafterl(Extended x, Extended y); + extern Extended __expm1l(Extended x); + extern Extended __log1pl(Extended x); + extern Extended __erfl(Extended x); + extern Extended __ieee754_j0l(Extended x); + extern Extended __ieee754_j1l(Extended x); + extern Extended __ieee754_jnl(int n, Extended x); + extern Extended __ieee754_y0l(Extended x); + extern Extended __ieee754_y1l(Extended x); + extern Extended __ieee754_ynl(int n, Extended x); + extern Extended __scalbnl(Extended x, int n); + extern Extended __scalblnl(Extended x, long int n); + extern int __fpclassifyl(Extended x); + extern int __isnanl(Extended x); + extern int __isinfl(Extended x); +#endif // Extended +} + + +// Wrappers in our own namespace +namespace streflop { + +// Stolen from math.h. All floating-point numbers can be put in one of these categories. +enum +{ + STREFLOP_FP_NAN = 0, + STREFLOP_FP_INFINITE = 1, + STREFLOP_FP_ZERO = 2, + STREFLOP_FP_SUBNORMAL = 3, + STREFLOP_FP_NORMAL = 4 +}; + + +// Simple and double are present in all configurations + + inline Simple sqrt(Simple x) {return streflop_libm::__ieee754_sqrtf(x);} + inline Simple cbrt(Simple x) {return streflop_libm::__cbrtf(x);} + inline Simple hypot(Simple x, Simple y) {return streflop_libm::__ieee754_hypotf(x,y);} + + inline Simple exp(Simple x) {return streflop_libm::__ieee754_expf(x);} + inline Simple log(Simple x) {return streflop_libm::__ieee754_logf(x);} + inline Simple log2(Simple x) {return streflop_libm::__ieee754_log2f(x);} + inline Simple exp2(Simple x) {return streflop_libm::__ieee754_exp2f(x);} + inline Simple log10(Simple x) {return streflop_libm::__ieee754_log10f(x);} + inline Simple pow(Simple x, Simple y) {return streflop_libm::__ieee754_powf(x,y);} + + inline Simple sin(Simple x) {return streflop_libm::__sinf(x);} + inline Simple cos(Simple x) {return streflop_libm::__cosf(x);} + inline Simple tan(Simple x) {return streflop_libm::__tanf(x);} + inline Simple acos(Simple x) {return streflop_libm::__ieee754_acosf(x);} + inline Simple asin(Simple x) {return streflop_libm::__ieee754_asinf(x);} + inline Simple atan(Simple x) {return streflop_libm::__atanf(x);} + inline Simple atan2(Simple x, Simple y) {return streflop_libm::__ieee754_atan2f(x,y);} + + inline Simple cosh(Simple x) {return streflop_libm::__ieee754_coshf(x);} + inline Simple sinh(Simple x) {return streflop_libm::__ieee754_sinhf(x);} + inline Simple tanh(Simple x) {return streflop_libm::__tanhf(x);} + inline Simple acosh(Simple x) {return streflop_libm::__ieee754_acoshf(x);} + inline Simple asinh(Simple x) {return streflop_libm::__asinhf(x);} + inline Simple atanh(Simple x) {return streflop_libm::__ieee754_atanhf(x);} + + inline Simple fabs(Simple x) {return streflop_libm::__fabsf(x);} + inline Simple floor(Simple x) {return streflop_libm::__floorf(x);} + inline Simple ceil(Simple x) {return streflop_libm::__ceilf(x);} + inline Simple trunc(Simple x) {return streflop_libm::__truncf(x);} + inline Simple fmod(Simple x, Simple y) {return streflop_libm::__ieee754_fmodf(x,y);} + inline Simple remainder(Simple x, Simple y) {return streflop_libm::__ieee754_remainderf(x,y);} + inline Simple remquo(Simple x, Simple y, int *quo) {return streflop_libm::__remquof(x,y,quo);} + inline Simple rint(Simple x) {return streflop_libm::__rintf(x);} + inline long int lrint(Simple x) {return streflop_libm::__lrintf(x);} + inline long long int llrint(Simple x) {return streflop_libm::__llrintf(x);} + inline Simple round(Simple x) {return streflop_libm::__roundf(x);} + inline long int lround(Simple x) {return streflop_libm::__lroundf(x);} + inline long long int llround(Simple x) {return streflop_libm::__llroundf(x);} + inline Simple nearbyint(Simple x) {return streflop_libm::__nearbyintf(x);} + + inline Simple frexp(Simple x, int *exp) {return streflop_libm::__frexpf(x,exp);} + inline Simple ldexp(Simple value, int exp) {return streflop_libm::__ldexpf(value,exp);} + inline Simple logb(Simple x) {return streflop_libm::__logbf(x);} + inline int ilogb(Simple x) {return streflop_libm::__ilogbf(x);} + inline Simple copysign(Simple x) {return streflop_libm::__copysignf(x);} +#undef signbit + inline int signbit (Simple x) {return streflop_libm::__signbitf(x);} + inline Simple nextafter(Simple x, Simple y) {return streflop_libm::__nextafterf(x,y);} + + inline Simple expm1(Simple x) {return streflop_libm::__expm1f(x);} + inline Simple log1p(Simple x) {return streflop_libm::__log1pf(x);} + inline Simple erf(Simple x) {return streflop_libm::__erff(x);} + inline Simple j0(Simple x) {return streflop_libm::__ieee754_j0f(x);} + inline Simple j1(Simple x) {return streflop_libm::__ieee754_j1f(x);} + inline Simple jn(int n, Simple x) {return streflop_libm::__ieee754_jnf(n,x);} + inline Simple y0(Simple x) {return streflop_libm::__ieee754_y0f(x);} + inline Simple y1(Simple x) {return streflop_libm::__ieee754_y1f(x);} + inline Simple yn(int n, Simple x) {return streflop_libm::__ieee754_ynf(n,x);} + inline Simple scalbn(Simple x, int n) {return streflop_libm::__scalbnf(x,n);} + inline Simple scalbln(Simple x, long int n) {return streflop_libm::__scalblnf(x,n);} + +#undef fpclassify + inline int fpclassify(Simple x) {return streflop_libm::__fpclassifyf(x);} +#undef isnan + inline int isnan(Simple x) {return streflop_libm::__isnanf(x);} +#undef isinf + inline int isinf(Simple x) {return streflop_libm::__isinff(x);} +#undef isfinite + inline int isfinite(Simple x) {return !(isnan(x) || isinf(x));} + + // Stolen from math.h and inlined instead of macroized. + // Return nonzero value if X is neither zero, subnormal, Inf, nor NaN. */ +#undef isnormal + inline int isnormal(Simple x) {return fpclassify(x) == STREFLOP_FP_NORMAL;} + + // Constants user may set + extern const Simple SimplePositiveInfinity; + extern const Simple SimpleNegativeInfinity; + // Non-signaling NaN used for returning such results + // Standard lets a large room for implementing different kinds of NaN + // These NaN can be used for custom purposes + // Threated as an integer, the bit pattern here may be incremented to get at least 2^20 different NaN custom numbers! + // Note that when switching the left-most bit to 1, you can get another bunch of negative NaNs, whatever this mean. + extern const Simple SimpleNaN; + + /** Generic C99 "macros" for unordered comparison + Defined as inlined for each type, thanks to C++ overloading + */ +#if defined isunordered +#undef isunordered +#endif // defined isunordered + inline bool isunordered(Simple x, Simple y) { + return (fpclassify(x) == STREFLOP_FP_NAN) || (fpclassify(y) == STREFLOP_FP_NAN); + } +#if defined isgreater +#undef isgreater +#endif // defined isgreater + inline bool isgreater(Simple x, Simple y) { + return (!isunordered(x,y)) && (x > y); + } +#if defined isgreaterequal +#undef isgreaterequal +#endif // defined isgreaterequal + inline bool isgreaterequal(Simple x, Simple y) { + return (!isunordered(x,y)) && (x >= y); + } +#if defined isless +#undef isless +#endif // defined isless + inline bool isless(Simple x, Simple y) { + return (!isunordered(x,y)) && (x < y); + } +#if defined islessequal +#undef islessequal +#endif // defined islessequal + inline bool islessequal(Simple x, Simple y) { + return (!isunordered(x,y)) && (x <= y); + } +#if defined islessgreater +#undef islessgreater +#endif // defined islessgreater + inline bool islessgreater(Simple x, Simple y) { + return (!isunordered(x,y)) && ((x < y) || (x > y)); + } + + +// Add xxxf alias to ease porting existing code to streflop +// Additionally, using xxxf(number) avoids potential confusion + + inline Simple sqrtf(Simple x) {return sqrt(x);} + inline Simple cbrtf(Simple x) {return cbrt(x);} + inline Simple hypotf(Simple x, Simple y) {return hypot(x, y);} + + inline Simple expf(Simple x) {return exp(x);} + inline Simple logf(Simple x) {return log(x);} + inline Simple log2f(Simple x) {return log2(x);} + inline Simple exp2f(Simple x) {return exp2(x);} + inline Simple log10f(Simple x) {return log10(x);} + inline Simple powf(Simple x, Simple y) {return pow(x, y);} + + inline Simple sinf(Simple x) {return sin(x);} + inline Simple cosf(Simple x) {return cos(x);} + inline Simple tanf(Simple x) {return tan(x);} + inline Simple acosf(Simple x) {return acos(x);} + inline Simple asinf(Simple x) {return asin(x);} + inline Simple atanf(Simple x) {return atan(x);} + inline Simple atan2f(Simple x, Simple y) {return atan2(x, y);} + + inline Simple coshf(Simple x) {return cosh(x);} + inline Simple sinhf(Simple x) {return sinh(x);} + inline Simple tanhf(Simple x) {return tanh(x);} + inline Simple acoshf(Simple x) {return acosh(x);} + inline Simple asinhf(Simple x) {return asinh(x);} + inline Simple atanhf(Simple x) {return atanh(x);} + + inline Simple fabsf(Simple x) {return fabs(x);} + inline Simple floorf(Simple x) {return floor(x);} + inline Simple ceilf(Simple x) {return ceil(x);} + inline Simple truncf(Simple x) {return trunc(x);} + inline Simple fmodf(Simple x, Simple y) {return fmod(x,y);} + inline Simple remainderf(Simple x, Simple y) {return remainder(x,y);} + inline Simple remquof(Simple x, Simple y, int *quo) {return remquo(x, y, quo);} + inline Simple rintf(Simple x) {return rint(x);} + inline long int lrintf(Simple x) {return lrint(x);} + inline long long int llrintf(Simple x) {return llrint(x);} + inline Simple roundf(Simple x) {return round(x);} + inline long int lroundf(Simple x) {return lround(x);} + inline long long int llroundf(Simple x) {return llround(x);} + inline Simple nearbyintf(Simple x) {return nearbyint(x);} + + inline Simple frexpf(Simple x, int *exp) {return frexp(x, exp);} + inline Simple ldexpf(Simple value, int exp) {return ldexp(value,exp);} + inline Simple logbf(Simple x) {return logb(x);} + inline int ilogbf(Simple x) {return ilogb(x);} + inline Simple copysignf(Simple x) {return copysign(x);} + inline int signbitf(Simple x) {return signbit(x);} + inline Simple nextafterf(Simple x, Simple y) {return nextafter(x, y);} + + inline Simple expm1f(Simple x) {return expm1(x);} + inline Simple log1pf(Simple x) {return log1p(x);} + inline Simple erff(Simple x) {return erf(x);} + inline Simple j0f(Simple x) {return j0(x);} + inline Simple j1f(Simple x) {return j1(x);} + inline Simple jnf(int n, Simple x) {return jn(n, x);} + inline Simple y0f(Simple x) {return y0(x);} + inline Simple y1f(Simple x) {return y1(x);} + inline Simple ynf(int n, Simple x) {return yn(n, x);} + inline Simple scalbnf(Simple x, int n) {return scalbn(x, n);} + inline Simple scalblnf(Simple x, long int n) {return scalbln(x, n);} + + inline int fpclassifyf(Simple x) {return fpclassify(x);} + inline int isnanf(Simple x) {return isnan(x);} + inline int isinff(Simple x) {return isinf(x);} + inline int isfinitef(Simple x) {return isfinite(x);} + inline int isnormalf(Simple x) {return isnormal(x);} + + inline bool isunorderedf(Simple x, Simple y) {return isunordered(x, y);} + inline bool isgreaterf(Simple x, Simple y) {return isgreater(x, y);} + inline bool isgreaterequalf(Simple x, Simple y) {return isgreaterequalf(x, y);} + inline bool islessf(Simple x, Simple y) {return isless(x, y);} + inline bool islessequalf(Simple x, Simple y) {return islessequal(x, y);} + inline bool islessgreaterf(Simple x, Simple y) {return islessgreater(x, y);} + + +// Declare Double functions +// Simple and double are present in all configurations + + inline Double sqrt(Double x) {return streflop_libm::__ieee754_sqrt(x);} + inline Double cbrt(Double x) {return streflop_libm::__cbrt(x);} + inline Double hypot(Double x, Double y) {return streflop_libm::__ieee754_hypot(x,y);} + + inline Double exp(Double x) {return streflop_libm::__ieee754_exp(x);} + inline Double log(Double x) {return streflop_libm::__ieee754_log(x);} + inline Double log2(Double x) {return streflop_libm::__ieee754_log2(x);} + inline Double exp2(Double x) {return streflop_libm::__ieee754_exp2(x);} + inline Double log10(Double x) {return streflop_libm::__ieee754_log10(x);} + inline Double pow(Double x, Double y) {return streflop_libm::__ieee754_pow(x,y);} + + inline Double sin(Double x) {return streflop_libm::__sin(x);} + inline Double cos(Double x) {return streflop_libm::__cos(x);} + inline Double tan(Double x) {return streflop_libm::tan(x);} + inline Double acos(Double x) {return streflop_libm::__ieee754_acos(x);} + inline Double asin(Double x) {return streflop_libm::__ieee754_asin(x);} + inline Double atan(Double x) {return streflop_libm::atan(x);} + inline Double atan2(Double x, Double y) {return streflop_libm::__ieee754_atan2(x,y);} + + inline Double cosh(Double x) {return streflop_libm::__ieee754_cosh(x);} + inline Double sinh(Double x) {return streflop_libm::__ieee754_sinh(x);} + inline Double tanh(Double x) {return streflop_libm::__tanh(x);} + inline Double acosh(Double x) {return streflop_libm::__ieee754_acosh(x);} + inline Double asinh(Double x) {return streflop_libm::__asinh(x);} + inline Double atanh(Double x) {return streflop_libm::__ieee754_atanh(x);} + + inline Double fabs(Double x) {return streflop_libm::__fabs(x);} + inline Double floor(Double x) {return streflop_libm::__floor(x);} + inline Double ceil(Double x) {return streflop_libm::__ceil(x);} + inline Double trunc(Double x) {return streflop_libm::__trunc(x);} + inline Double fmod(Double x, Double y) {return streflop_libm::__ieee754_fmod(x,y);} + inline Double remainder(Double x, Double y) {return streflop_libm::__ieee754_remainder(x,y);} + inline Double remquo(Double x, Double y, int *quo) {return streflop_libm::__remquo(x,y,quo);} + inline Double rint(Double x) {return streflop_libm::__rint(x);} + inline long int lrint(Double x) {return streflop_libm::__lrint(x);} + inline long long int llrint(Double x) {return streflop_libm::__llrint(x);} + inline Double round(Double x) {return streflop_libm::__round(x);} + inline long int lround(Double x) {return streflop_libm::__lround(x);} + inline long long int llround(Double x) {return streflop_libm::__llround(x);} + inline Double nearbyint(Double x) {return streflop_libm::__nearbyint(x);} + + inline Double frexp(Double x, int *exp) {return streflop_libm::__frexp(x, exp);} + inline Double ldexp(Double value, int exp) {return streflop_libm::__ldexp(value,exp);} + inline Double logb(Double x) {return streflop_libm::__logb(x);} + inline int ilogb(Double x) {return streflop_libm::__ilogb(x);} + inline Double copysign(Double x) {return streflop_libm::__copysign(x);} + inline int signbit(Double x) {return streflop_libm::__signbit(x);} + inline Double nextafter(Double x, Double y) {return streflop_libm::__nextafter(x,y);} + + inline Double expm1(Double x) {return streflop_libm::__expm1(x);} + inline Double log1p(Double x) {return streflop_libm::__log1p(x);} + inline Double erf(Double x) {return streflop_libm::__erf(x);} + inline Double j0(Double x) {return streflop_libm::__ieee754_j0(x);} + inline Double j1(Double x) {return streflop_libm::__ieee754_j1(x);} + inline Double jn(int n, Double x) {return streflop_libm::__ieee754_jn(n,x);} + inline Double y0(Double x) {return streflop_libm::__ieee754_y0(x);} + inline Double y1(Double x) {return streflop_libm::__ieee754_y1(x);} + inline Double yn(int n, Double x) {return streflop_libm::__ieee754_yn(n,x);} + inline Double scalbn(Double x, int n) {return streflop_libm::__scalbn(x,n);} + inline Double scalbln(Double x, long int n) {return streflop_libm::__scalbln(x,n);} + + inline int fpclassify(Double x) {return streflop_libm::__fpclassify(x);} + inline int isnan(Double x) {return streflop_libm::__isnanl(x);} + inline int isinf(Double x) {return streflop_libm::__isinf(x);} + inline int isfinite(Double x) {return !(isnan(x) || isinf(x));} + + // Stolen from math.h and inlined instead of macroized. + // Return nonzero value if X is neither zero, subnormal, Inf, nor NaN. */ + inline int isnormal(Double x) {return fpclassify(x) == STREFLOP_FP_NORMAL;} + + // Constants user may set + extern const Double DoublePositiveInfinity; + extern const Double DoubleNegativeInfinity; + // Non-signaling NaN used for returning such results + // Standard lets a large room for implementing different kinds of NaN + // These NaN can be used for custom purposes + // Threated as an integer, the bit pattern here may be incremented to get at least 2^20 different NaN custom numbers! + // Note that when switching the left-most bit to 1, you can get another bunch of negative NaNs, whatever this mean. + extern const Double DoubleNaN; + + /** Generic C99 "macros" for unordered comparison + Defined as inlined for each type, thanks to C++ overloading + */ + inline bool isunordered(Double x, Double y) { + return (fpclassify(x) == STREFLOP_FP_NAN) || (fpclassify (y) == STREFLOP_FP_NAN); + } + inline bool isgreater(Double x, Double y) { + return (!isunordered(x,y)) && (x > y); + } + inline bool isgreaterequal(Double x, Double y) { + return (!isunordered(x,y)) && (x >= y); + } + inline bool isless(Double x, Double y) { + return (!isunordered(x,y)) && (x < y); + } + inline bool islessequal(Double x, Double y) { + return (!isunordered(x,y)) && (x <= y); + } + inline bool islessgreater(Double x, Double y) { + return (!isunordered(x,y)) && ((x < y) || (x > y)); + } + +// Extended are not always available +#ifdef Extended + + inline Extended cbrt(Extended x) {return streflop_libm::__cbrtl(x);} + inline Extended hypot(Extended x, Extended y) {return streflop_libm::__ieee754_hypotl(x,y);} + + +// Missing from libm: temporarily switch to Double and execute the Double version, +// then switch back to Extended and return the result + inline Extended sqrt(Extended x) {streflop_init(); Double res = sqrt(Double(x)); streflop_init(); return Extended(res);} + + inline Extended exp(Extended x) {streflop_init(); Double res = exp(Double(x)); streflop_init(); return Extended(res);} + inline Extended log(Extended x) {streflop_init(); Double res = log(Double(x)); streflop_init(); return Extended(res);} + inline Extended log2(Extended x) {streflop_init(); Double res = log2(Double(x)); streflop_init(); return Extended(res);} + inline Extended exp2(Extended x) {streflop_init(); Double res = exp2(Double(x)); streflop_init(); return Extended(res);} + inline Extended log10(Extended x) {streflop_init(); Double res = log10(Double(x)); streflop_init(); return Extended(res);} + inline Extended pow(Extended x, Extended y) {streflop_init(); Double res = pow(Double(x), Double(y)); streflop_init(); return Extended(res);} + inline Extended sin(Extended x) {streflop_init(); Double res = sin(Double(x)); streflop_init(); return Extended(res);} + inline Extended cos(Extended x) {streflop_init(); Double res = cos(Double(x)); streflop_init(); return Extended(res);} + inline Extended tan(Extended x) {streflop_init(); Double res = tan(Double(x)); streflop_init(); return Extended(res);} + inline Extended acos(Extended x) {streflop_init(); Double res = acos(Double(x)); streflop_init(); return Extended(res);} + inline Extended asin(Extended x) {streflop_init(); Double res = asin(Double(x)); streflop_init(); return Extended(res);} + inline Extended atan(Extended x) {streflop_init(); Double res = atan(Double(x)); streflop_init(); return Extended(res);} + inline Extended atan2(Extended x, Extended y) {streflop_init(); Double res = atan2(Double(x), Double(y)); streflop_init(); return Extended(res);} + + inline Extended cosh(Extended x) {streflop_init(); Double res = cosh(Double(x)); streflop_init(); return Extended(res);} + inline Extended sinh(Extended x) {streflop_init(); Double res = sinh(Double(x)); streflop_init(); return Extended(res);} + inline Extended tanh(Extended x) {streflop_init(); Double res = tanh(Double(x)); streflop_init(); return Extended(res);} + inline Extended acosh(Extended x) {streflop_init(); Double res = acosh(Double(x)); streflop_init(); return Extended(res);} + inline Extended asinh(Extended x) {streflop_init(); Double res = asinh(Double(x)); streflop_init(); return Extended(res);} + inline Extended atanh(Extended x) {streflop_init(); Double res = atanh(Double(x)); streflop_init(); return Extended(res);} + + + inline Extended expm1(Extended x) {streflop_init(); Double res = expm1(Double(x)); streflop_init(); return Extended(res);} + inline Extended log1p(Extended x) {streflop_init(); Double res = log1p(Double(x)); streflop_init(); return Extended(res);} + inline Extended erf(Extended x) {streflop_init(); Double res = erf(Double(x)); streflop_init(); return Extended(res);} + inline Extended j0(Extended x) {streflop_init(); Double res = j0(Double(x)); streflop_init(); return Extended(res);} + inline Extended j1(Extended x) {streflop_init(); Double res = j1(Double(x)); streflop_init(); return Extended(res);} + inline Extended jn(int n, Extended x) {streflop_init(); Double res = jn(n,Double(x)); streflop_init(); return Extended(res);} + inline Extended y0(Extended x) {streflop_init(); Double res = y0(Double(x)); streflop_init(); return Extended(res);} + inline Extended y1(Extended x) {streflop_init(); Double res = y1(Double(x)); streflop_init(); return Extended(res);} + inline Extended yn(int n, Extended x) {streflop_init(); Double res = yn(n,Double(x)); streflop_init(); return Extended(res);} + inline Extended scalbn(Extended x, int n) {streflop_init(); Double res = scalbn(Double(x),n); streflop_init(); return Extended(res);} + inline Extended scalbln(Extended x, long int n) {streflop_init(); Double res = scalbln(Double(x),n); streflop_init(); return Extended(res);} + + + + inline Extended fabs(Extended x) {return streflop_libm::__fabsl(x);} + inline Extended floor(Extended x) {return streflop_libm::__floorl(x);} + inline Extended ceil(Extended x) {return streflop_libm::__ceill(x);} + inline Extended trunc(Extended x) {return streflop_libm::__truncl(x);} + inline Extended fmod(Extended x, Extended y) {return streflop_libm::__ieee754_fmodl(x,y);} + inline Extended remainder(Extended x, Extended y) {return streflop_libm::__ieee754_remainderl(x,y);} + inline Extended remquo(Extended x, Extended y, int *quo) {return streflop_libm::__remquol(x,y,quo);} + inline Extended rint(Extended x) {return streflop_libm::__rintl(x);} + inline long int lrint(Extended x) {return streflop_libm::__lrintl(x);} + inline long long int llrint(Extended x) {return streflop_libm::__llrintl(x);} + inline Extended round(Extended x) {return streflop_libm::__roundl(x);} + inline long int lround(Extended x) {return streflop_libm::__lroundl(x);} + inline long long int llround(Extended x) {return streflop_libm::__llroundl(x);} + inline Extended nearbyint(Extended x) {return streflop_libm::__nearbyintl(x);} + + inline Extended frexp(Extended x, int *exp) {return streflop_libm::__frexpl(x,exp);} + inline Extended ldexp(Extended value, int exp) {return streflop_libm::__ldexpl(value,exp);} + inline Extended logb(Extended x) {return streflop_libm::__logbl(x);} + inline int ilogb(Extended x) {return streflop_libm::__ilogbl(x);} + inline Extended copysign(Extended x) {return streflop_libm::__copysignl(x);} + inline int signbit (Extended x) {return streflop_libm::__signbitl(x);} + inline Extended nextafter(Extended x, Extended y) {return streflop_libm::__nextafterl(x,y);} + + inline int fpclassify(Extended x) {return streflop_libm::__fpclassifyl(x);} + inline int isnan(Extended x) {return streflop_libm::__isnanl(x);} + inline int isinf(Extended x) {return streflop_libm::__isinfl(x);} + inline int isfinite(Extended x) {return !(isnan(x) || isinf(x));} + + // Stolen from math.h and inlined instead of macroized. + // Return nonzero value if X is neither zero, subnormal, Inf, nor NaN. */ + inline int isnormal(Extended x) {return fpclassify(x) == STREFLOP_FP_NORMAL;} + + // Constants user may set + extern const Extended ExtendedPositiveInfinity; + extern const Extended ExtendedNegativeInfinity; + // Non-signaling NaN used for returning such results + // Standard lets a large room for implementing different kinds of NaN + // These NaN can be used for custom purposes + // Threated as an integer, the bit pattern here may be incremented to get at least 2^20 different NaN custom numbers! + // Note that when switching the left-most bit to 1, you can get another bunch of negative NaNs, whatever this mean. + extern const Extended ExtendedNaN; + + /** Generic C99 "macros" for unordered comparison + Defined as inlined for each type, thanks to C++ overloading + */ + inline bool isunordered(Extended x, Extended y) { + return (fpclassify(x) == STREFLOP_FP_NAN) || (fpclassify (y) == STREFLOP_FP_NAN); + } + inline bool isgreater(Extended x, Extended y) { + return (!isunordered(x,y)) && (x > y); + } + inline bool isgreaterequal(Extended x, Extended y) { + return (!isunordered(x,y)) && (x >= y); + } + inline bool isless(Extended x, Extended y) { + return (!isunordered(x,y)) && (x < y); + } + inline bool islessequal(Extended x, Extended y) { + return (!isunordered(x,y)) && (x <= y); + } + inline bool islessgreater(Extended x, Extended y) { + return (!isunordered(x,y)) && ((x < y) || (x > y)); + } + + +// Add xxxl alias to ease porting existing code to streflop +// Additionally, using xxxl(number) avoids potential confusion + + inline Extended sqrtl(Extended x) {return sqrt(x);} + inline Extended cbrtl(Extended x) {return cbrt(x);} + inline Extended hypotl(Extended x, Extended y) {return hypot(x, y);} + + inline Extended expl(Extended x) {return exp(x);} + inline Extended logl(Extended x) {return log(x);} + inline Extended log2l(Extended x) {return log2(x);} + inline Extended exp2l(Extended x) {return exp2(x);} + inline Extended log10l(Extended x) {return log10(x);} + inline Extended powl(Extended x, Extended y) {return pow(x, y);} + + inline Extended sinl(Extended x) {return sin(x);} + inline Extended cosl(Extended x) {return cos(x);} + inline Extended tanl(Extended x) {return tan(x);} + inline Extended acosl(Extended x) {return acos(x);} + inline Extended asinl(Extended x) {return asin(x);} + inline Extended atanl(Extended x) {return atan(x);} + inline Extended atan2l(Extended x, Extended y) {return atan2(x, y);} + + inline Extended coshl(Extended x) {return cosh(x);} + inline Extended sinhl(Extended x) {return sinh(x);} + inline Extended tanhl(Extended x) {return tanh(x);} + inline Extended acoshl(Extended x) {return acosh(x);} + inline Extended asinhl(Extended x) {return asinh(x);} + inline Extended atanhl(Extended x) {return atanh(x);} + + inline Extended fabsl(Extended x) {return fabs(x);} + inline Extended floorl(Extended x) {return floor(x);} + inline Extended ceill(Extended x) {return ceil(x);} + inline Extended truncl(Extended x) {return trunc(x);} + inline Extended fmodl(Extended x, Extended y) {return fmod(x,y);} + inline Extended remainderl(Extended x, Extended y) {return remainder(x,y);} + inline Extended remquol(Extended x, Extended y, int *quo) {return remquo(x, y, quo);} + inline Extended rintl(Extended x) {return rint(x);} + inline long int lrintl(Extended x) {return lrint(x);} + inline long long int llrintl(Extended x) {return llrint(x);} + inline Extended roundl(Extended x) {return round(x);} + inline long int lroundl(Extended x) {return lround(x);} + inline long long int llroundl(Extended x) {return llround(x);} + inline Extended nearbyintl(Extended x) {return nearbyint(x);} + + inline Extended frexpl(Extended x, int *exp) {return frexp(x, exp);} + inline Extended ldexpl(Extended value, int exp) {return ldexp(value,exp);} + inline Extended logbl(Extended x) {return logb(x);} + inline int ilogbl(Extended x) {return ilogb(x);} + inline Extended copysignl(Extended x) {return copysign(x);} + inline int signbitl(Extended x) {return signbit(x);} + inline Extended nextafterl(Extended x, Extended y) {return nextafter(x, y);} + + inline Extended expm1l(Extended x) {return expm1(x);} + inline Extended log1pl(Extended x) {return log1p(x);} + inline Extended erfl(Extended x) {return erf(x);} + inline Extended j0l(Extended x) {return j0(x);} + inline Extended j1l(Extended x) {return j1(x);} + inline Extended jnl(int n, Extended x) {return jn(n, x);} + inline Extended y0l(Extended x) {return y0(x);} + inline Extended y1l(Extended x) {return y1(x);} + inline Extended ynl(int n, Extended x) {return yn(n, x);} + inline Extended scalbnl(Extended x, int n) {return scalbn(x, n);} + inline Extended scalblnl(Extended x, long int n) {return scalbln(x, n);} + + inline int fpclassifyl(Extended x) {return fpclassify(x);} + inline int isnanl(Extended x) {return isnan(x);} + inline int isinfl(Extended x) {return isinf(x);} + inline int isfinitel(Extended x) {return isfinite(x);} + inline int isnormall(Extended x) {return isnormal(x);} + + inline bool isunorderedl(Extended x, Extended y) {return isunordered(x, y);} + inline bool isgreaterl(Extended x, Extended y) {return isgreater(x, y);} + inline bool isgreaterequall(Extended x, Extended y) {return isgreaterequall(x, y);} + inline bool islessl(Extended x, Extended y) {return isless(x, y);} + inline bool islessequall(Extended x, Extended y) {return islessequal(x, y);} + inline bool islessgreaterl(Extended x, Extended y) {return islessgreater(x, y);} + + +#endif // Extended + +} // namespace streflop + +#endif // STREFLOP_MATH_H diff --git a/source/shared_lib/include/streflop/System.h b/source/shared_lib/include/streflop/System.h new file mode 100644 index 000000000..542d3f441 --- /dev/null +++ b/source/shared_lib/include/streflop/System.h @@ -0,0 +1,82 @@ +/* + streflop: STandalone REproducible FLOating-Point + Nicolas Brodu, 2006 + Code released according to the GNU Lesser General Public License + + Heavily relies on GNU Libm, itself depending on netlib fplibm, GNU MP, and IBM MP lib. + Uses SoftFloat too. + + Please read the history and copyright information in the documentation provided with the source code +*/ + + +#ifndef STREFLOP_SYSTEM_H +#define STREFLOP_SYSTEM_H + +#if defined(STREFLOP_SSE) || defined(STREFLOP_X87) +// SSE or X87 machines are little-endian +#define __BYTE_ORDER 1234 +#define __FLOAT_WORD_ORDER 1234 + +// Softfloat or other unknown FPU. TODO: Try some header autodetect? +#else + +#define __BYTE_ORDER 1234 +#define __FLOAT_WORD_ORDER 1234 +/* +#include + +#if !defined(__FLOAT_WORD_ORDER) || !defined(__BYTE_ORDER) +#undef __FLOAT_WORD_ORDER +#undef __BYTE_ORDER + +#if defined(_LITTLE_ENDIAN) || defined(__LITTLE_ENDIAN) || defined(LITTLE_ENDIAN) +// avoid conflicting defs +#undef _LITTLE_ENDIAN +#undef LITTLE_ENDIAN +#undef __LITTLE_ENDIAN +#undef __BYTE_ORDER +#define __BYTE_ORDER 1234 +#define __FLOAT_WORD_ORDER 1234 + +#elif defined(_BIG_ENDIAN) || defined(__BIG_ENDIAN) || defined(BIG_ENDIAN) +// avoid conflicting defs +#undef _BIG_ENDIAN +#undef BIG_ENDIAN +#undef __BIG_ENDIAN +#undef __BYTE_ORDER +#define __BYTE_ORDER 4321 +#define __FLOAT_WORD_ORDER 4321 + +#else +// Unfortunately, the endianity for the compilation target cannot be deduced at compile time +// => preprocessor #define is necessary, possibly with heuristics +#error Could not detect endianity. +#endif + +#endif +*/ +#endif + + +#include "IntegerTypes.h" + +// Avoid conflict with system types, if any +namespace streflop { + +// Use the assumption above for char +typedef char int8_t; +typedef unsigned char uint8_t; + +// Now "run" the meta-program to define the types +// Entry point is (unsigned) short, then all types above are tried till the size match +typedef SizedInteger<16>::Type int16_t; +typedef SizedUnsignedInteger<16>::Type uint16_t; +typedef SizedInteger<32>::Type int32_t; +typedef SizedUnsignedInteger<32>::Type uint32_t; +typedef SizedInteger<64>::Type int64_t; +typedef SizedUnsignedInteger<64>::Type uint64_t; + +} + +#endif diff --git a/source/shared_lib/include/streflop/VERSION.txt b/source/shared_lib/include/streflop/VERSION.txt new file mode 100644 index 000000000..3b04cfb60 --- /dev/null +++ b/source/shared_lib/include/streflop/VERSION.txt @@ -0,0 +1 @@ +0.2 diff --git a/source/shared_lib/include/streflop/X87DenormalSquasher.h b/source/shared_lib/include/streflop/X87DenormalSquasher.h new file mode 100644 index 000000000..d2199f0fd --- /dev/null +++ b/source/shared_lib/include/streflop/X87DenormalSquasher.h @@ -0,0 +1,196 @@ +/* + streflop: STandalone REproducible FLOating-Point + Nicolas Brodu, 2006 + Code released according to the GNU Lesser General Public License + + Heavily relies on GNU Libm, itself depending on netlib fplibm, GNU MP, and IBM MP lib. + Uses SoftFloat too. + + Please read the history and copyright information in the documentation provided with the source code +*/ + +#ifndef X87DenormalSquasher_H +#define X87DenormalSquasher_H + +/// This file should be included from within a streflop namespace + +template inline void X87DenormalSquashFunction(ValueType& value) { + struct X {}; + X Unknown_numeric_type; + // unknown types do not compile + value = Unknown_numeric_type; +} + +// Use cmov instruction to avoid branching? +// Pro: branching may be costly, though the branching predictor may compensate when there are few denormals +// Con: cmov forces an unconditional writeback to the mem just after read, which may be worse than the branch + +template<> inline void X87DenormalSquashFunction(float& value) { + if ((reinterpret_cast(&value)[0] & 0x7F800000) == 0) value = 0.0f; +} + +template<> inline void X87DenormalSquashFunction(double& value) { + if ((reinterpret_cast(&value)[1] & 0x7FF00000) == 0) value = 0.0; +} + +template<> inline void X87DenormalSquashFunction(long double& value) { + if ((reinterpret_cast(&value)[4] & 0x7FFF) == 0) value = 0.0L; +} + +/// Wrapper class for the denormal squashing of X87 +/// The goal is to be able to use this file for normal arithmetic operations +/// as if this was a native float or double, thanks to C++ operator overloading. +/// In particular, the GNU libm may be compiled this way, though no effort was made +/// to optimize out the denormal parts (and squashing denormals is non-IEEE compliant anyway) + +template struct X87DenormalSquasher { + +// Define value + ValueType value; + + /// Uninitialized object + inline X87DenormalSquasher() {} + + /// Copy and conversion from other precisions + inline X87DenormalSquasher(const X87DenormalSquasher& f) : value(f.value) {X87DenormalSquashFunction(value);} + inline X87DenormalSquasher(const X87DenormalSquasher& f) : value(f.value) {X87DenormalSquashFunction(value);} + inline X87DenormalSquasher(const X87DenormalSquasher& f) : value(f.value) {X87DenormalSquashFunction(value);} + inline X87DenormalSquasher& operator=(const X87DenormalSquasher& f) {value = f.value; X87DenormalSquashFunction(value); return *this;} // self-ref OK + inline X87DenormalSquasher& operator=(const X87DenormalSquasher& f) {value = f.value; X87DenormalSquashFunction(value); return *this;} // self-ref OK + inline X87DenormalSquasher& operator=(const X87DenormalSquasher& f) {value = f.value; X87DenormalSquashFunction(value); return *this;} // self-ref OK + + /// Destructor + inline ~X87DenormalSquasher() {} + + /// Now the real fun, arithmetic operator overloading + inline X87DenormalSquasher& operator+=(const X87DenormalSquasher& f) {value += f.value; X87DenormalSquashFunction(value); return *this;} + inline X87DenormalSquasher& operator-=(const X87DenormalSquasher& f) {value -= f.value; X87DenormalSquashFunction(value); return *this;} + inline X87DenormalSquasher& operator*=(const X87DenormalSquasher& f) {value *= f.value; X87DenormalSquashFunction(value); return *this;} + inline X87DenormalSquasher& operator/=(const X87DenormalSquasher& f) {value /= f.value; X87DenormalSquashFunction(value); return *this;} + inline bool operator==(const X87DenormalSquasher& f) const {return value == f.value;} + inline bool operator!=(const X87DenormalSquasher& f) const {return value != f.value;} + inline bool operator<(const X87DenormalSquasher& f) const {return value < f.value;} + inline bool operator<=(const X87DenormalSquasher& f) const {return value <= f.value;} + inline bool operator>(const X87DenormalSquasher& f) const {return value > f.value;} + inline bool operator>=(const X87DenormalSquasher& f) const {return value >= f.value;} + +#define STREFLOP_X87DENORMAL_NATIVE_FLOAT_OPS(native_type) \ + inline X87DenormalSquasher(const native_type f) {value = f; X87DenormalSquashFunction(value);} \ + inline X87DenormalSquasher& operator=(const native_type f) {value = f; X87DenormalSquashFunction(value); return *this;} \ + inline operator native_type() const {return static_cast(value);} \ + inline X87DenormalSquasher& operator+=(const native_type f) {return operator+=(X87DenormalSquasher(f));} \ + inline X87DenormalSquasher& operator-=(const native_type f) {return operator-=(X87DenormalSquasher(f));} \ + inline X87DenormalSquasher& operator*=(const native_type f) {return operator*=(X87DenormalSquasher(f));} \ + inline X87DenormalSquasher& operator/=(const native_type f) {return operator/=(X87DenormalSquasher(f));} \ + inline bool operator==(const native_type f) const {return operator==(X87DenormalSquasher(f));} \ + inline bool operator!=(const native_type f) const {return operator!=(X87DenormalSquasher(f));} \ + inline bool operator<(const native_type f) const {return operator<(X87DenormalSquasher(f));} \ + inline bool operator<=(const native_type f) const {return operator<=(X87DenormalSquasher(f));} \ + inline bool operator>(const native_type f) const {return operator>(X87DenormalSquasher(f));} \ + inline bool operator>=(const native_type f) const {return operator>=(X87DenormalSquasher(f));} + +#define STREFLOP_X87DENORMAL_NATIVE_INT_OPS(native_type) \ + inline X87DenormalSquasher(const native_type x) {value = x;} \ + inline X87DenormalSquasher& operator=(const native_type x) {value = x; return *this;} \ + inline operator native_type() const {return static_cast(value);} \ + inline X87DenormalSquasher& operator+=(const native_type f) {value += f; X87DenormalSquashFunction(value); return *this;} \ + inline X87DenormalSquasher& operator-=(const native_type f) {value -= f; X87DenormalSquashFunction(value); return *this;} \ + inline X87DenormalSquasher& operator*=(const native_type f) {value *= f; X87DenormalSquashFunction(value); return *this;} \ + inline X87DenormalSquasher& operator/=(const native_type f) {value /= f; X87DenormalSquashFunction(value); return *this;} \ + inline bool operator==(const native_type f) const {return value == f;} \ + inline bool operator!=(const native_type f) const {return value != f;} \ + inline bool operator<(const native_type f) const {return value < f;} \ + inline bool operator<=(const native_type f) const {return value <= f;} \ + inline bool operator>(const native_type f) const {return value > f;} \ + inline bool operator>=(const native_type f) const {return value >= f;} + +STREFLOP_X87DENORMAL_NATIVE_FLOAT_OPS(float) +STREFLOP_X87DENORMAL_NATIVE_FLOAT_OPS(double) +STREFLOP_X87DENORMAL_NATIVE_FLOAT_OPS(long double) + +STREFLOP_X87DENORMAL_NATIVE_INT_OPS(char) +STREFLOP_X87DENORMAL_NATIVE_INT_OPS(unsigned char) +STREFLOP_X87DENORMAL_NATIVE_INT_OPS(short) +STREFLOP_X87DENORMAL_NATIVE_INT_OPS(unsigned short) +STREFLOP_X87DENORMAL_NATIVE_INT_OPS(int) +STREFLOP_X87DENORMAL_NATIVE_INT_OPS(unsigned int) +STREFLOP_X87DENORMAL_NATIVE_INT_OPS(long) +STREFLOP_X87DENORMAL_NATIVE_INT_OPS(unsigned long) +STREFLOP_X87DENORMAL_NATIVE_INT_OPS(long long) +STREFLOP_X87DENORMAL_NATIVE_INT_OPS(unsigned long long) + +}; + +/// binary operators +template inline X87DenormalSquasher operator+(const X87DenormalSquasher& f1, const X87DenormalSquasher& f2) {return X87DenormalSquasher(f1.value + f2.value);} +template inline X87DenormalSquasher operator-(const X87DenormalSquasher& f1, const X87DenormalSquasher& f2) {return X87DenormalSquasher(f1.value - f2.value);} +template inline X87DenormalSquasher operator*(const X87DenormalSquasher& f1, const X87DenormalSquasher& f2) {return X87DenormalSquasher(f1.value * f2.value);} +template inline X87DenormalSquasher operator/(const X87DenormalSquasher& f1, const X87DenormalSquasher& f2) {return X87DenormalSquasher(f1.value / f2.value);} + +#define STREFLOP_X87DENORMAL_FLOAT_BINARY(native_type) \ +template inline X87DenormalSquasher operator+(const X87DenormalSquasher& f1, const native_type f2) {return f1 + X87DenormalSquasher(f2);} \ +template inline X87DenormalSquasher operator-(const X87DenormalSquasher& f1, const native_type f2) {return f1 - X87DenormalSquasher(f2);} \ +template inline X87DenormalSquasher operator*(const X87DenormalSquasher& f1, const native_type f2) {return f1 * X87DenormalSquasher(f2);} \ +template inline X87DenormalSquasher operator/(const X87DenormalSquasher& f1, const native_type f2) {return f1 / X87DenormalSquasher(f2);} \ +template inline X87DenormalSquasher operator+(const native_type f1, const X87DenormalSquasher& f2) {return X87DenormalSquasher(f1) + f2;} \ +template inline X87DenormalSquasher operator-(const native_type f1, const X87DenormalSquasher& f2) {return X87DenormalSquasher(f1) - f2;} \ +template inline X87DenormalSquasher operator*(const native_type f1, const X87DenormalSquasher& f2) {return X87DenormalSquasher(f1) * f2;} \ +template inline X87DenormalSquasher operator/(const native_type f1, const X87DenormalSquasher& f2) {return X87DenormalSquasher(f1) / f2;} \ +template inline bool operator==(const native_type value, const X87DenormalSquasher& f) {return X87DenormalSquasher(value) == f;} \ +template inline bool operator!=(const native_type value, const X87DenormalSquasher& f) {return X87DenormalSquasher(value) != f;} \ +template inline bool operator<(const native_type value, const X87DenormalSquasher& f) {return X87DenormalSquasher(value) < f;} \ +template inline bool operator<=(const native_type value, const X87DenormalSquasher& f) {return X87DenormalSquasher(value) <= f;} \ +template inline bool operator>(const native_type value, const X87DenormalSquasher& f) {return X87DenormalSquasher(value) > f;} \ +template inline bool operator>=(const native_type value, const X87DenormalSquasher& f) {return X87DenormalSquasher(value) >= f;} + +#define STREFLOP_X87DENORMAL_INT_BINARY(native_type) \ +template inline X87DenormalSquasher operator+(const X87DenormalSquasher& f1, const native_type f2) {return X87DenormalSquasher(f1.value + f2);} \ +template inline X87DenormalSquasher operator-(const X87DenormalSquasher& f1, const native_type f2) {return X87DenormalSquasher(f1.value - f2);} \ +template inline X87DenormalSquasher operator*(const X87DenormalSquasher& f1, const native_type f2) {return X87DenormalSquasher(f1.value * f2);} \ +template inline X87DenormalSquasher operator/(const X87DenormalSquasher& f1, const native_type f2) {return X87DenormalSquasher(f1.value / f2);} \ +template inline X87DenormalSquasher operator+(const native_type f1, const X87DenormalSquasher& f2) {return X87DenormalSquasher(f1 + f2.value);} \ +template inline X87DenormalSquasher operator-(const native_type f1, const X87DenormalSquasher& f2) {return X87DenormalSquasher(f1 - f2.value);} \ +template inline X87DenormalSquasher operator*(const native_type f1, const X87DenormalSquasher& f2) {return X87DenormalSquasher(f1 * f2.value);} \ +template inline X87DenormalSquasher operator/(const native_type f1, const X87DenormalSquasher& f2) {return X87DenormalSquasher(f1 / f2.value);} \ +template inline bool operator==(const native_type value, const X87DenormalSquasher& f) {return value == f.value;} \ +template inline bool operator!=(const native_type value, const X87DenormalSquasher& f) {return value != f.value;} \ +template inline bool operator<(const native_type value, const X87DenormalSquasher& f) {return value < f.value;} \ +template inline bool operator<=(const native_type value, const X87DenormalSquasher& f) {return value <= f.value;} \ +template inline bool operator>(const native_type value, const X87DenormalSquasher& f) {return value > f.value;} \ +template inline bool operator>=(const native_type value, const X87DenormalSquasher& f) {return value >= f.value;} + +STREFLOP_X87DENORMAL_FLOAT_BINARY(float) +STREFLOP_X87DENORMAL_FLOAT_BINARY(double) +STREFLOP_X87DENORMAL_FLOAT_BINARY(long double) + +STREFLOP_X87DENORMAL_INT_BINARY(char) +STREFLOP_X87DENORMAL_INT_BINARY(unsigned char) +STREFLOP_X87DENORMAL_INT_BINARY(short) +STREFLOP_X87DENORMAL_INT_BINARY(unsigned short) +STREFLOP_X87DENORMAL_INT_BINARY(int) +STREFLOP_X87DENORMAL_INT_BINARY(unsigned int) +STREFLOP_X87DENORMAL_INT_BINARY(long) +STREFLOP_X87DENORMAL_INT_BINARY(unsigned long) +STREFLOP_X87DENORMAL_INT_BINARY(long long) +STREFLOP_X87DENORMAL_INT_BINARY(unsigned long long) + +/// Unary operators +template inline X87DenormalSquasher operator-(const X87DenormalSquasher& f) {return X87DenormalSquasher(-f.value);} +template inline X87DenormalSquasher operator+(const X87DenormalSquasher& f) {return X87DenormalSquasher(+f.value);} + +/* +/// Stream operators for output +/// Warning! The SYSTEM operators are used to the normal floats and therefore +/// this function may not be reliable (they may depend on system rounding mode, etc.) +/// Still useful for debug output and to report results with a few significant digits +template inline std::ostream& operator<<(std::ostream& out, const X87DenormalSquasher& f) { + out << f.value; + return out; +} +template inline std::istream& operator>>(std::istream& in, X87DenormalSquasher& f) { + in >> f.value; + return in; +} +*/ + +#endif diff --git a/source/shared_lib/include/streflop/libm/README.txt b/source/shared_lib/include/streflop/libm/README.txt new file mode 100644 index 000000000..d460dcb21 --- /dev/null +++ b/source/shared_lib/include/streflop/libm/README.txt @@ -0,0 +1,19 @@ +This directory contains (in addition to this file): + +- flt-32/ dbl-64/ ldbl-96/ headers/: These subdirectories are imported from the GNU libm automatically. Do not modify them manually. You may safely erase them and run the import.pl script again. The "clean-import" make target does just that. + +- import.pl: A perl script that takes as argument the location of a valid glibc-2.4 source directory. It will create the aforementioned subdirectories and convert the original libm files. The conversion mainly concerns removing external dependencies, and making the c files and constructs compilable with the streflop wrapper types. See the import.pl script itself for the full list of modifications. + +- Makefile: Instructions for compiling the subdirectories with the make command. You you re-use this as the basis for other build systems (like CMake, scons, etc.). + +- streflop_libm_bridge.h: Contains the definitions and other macros that are necessary to compile libm, in a streflop framework. These declarations were either done by external files, or by other parts of the glibc that were not imported. + +- e_expf.c: The float exp in e_expf.c uses doubles internally since revision 1.2 in the libm-ieee754 CVS attic! This is the slower, but purely float version, that is rolled back from the CVS attic. + +- w_expf.c: A wrapper to expf that replaces the libm wrapper by a wraper to the float only version. + +- (after compilation): flt-target dbl-target ldbl-target temporary files for the make process + +The original GNU libm is released under the GNU LGPL license, and so are these modifications. See the LGPL.txt in the parent streflop main directory. See also the comments at the beginning of each file for particular information, especially the Sun Microsystems disclaimer. + +If you import a version of glibc other than 2.4, please check the information there (in particular their LICENSES file) for potential inclusion of new files in the libm subdirectories that are used here. diff --git a/source/shared_lib/include/streflop/libm/flt-32/Makefile b/source/shared_lib/include/streflop/libm/flt-32/Makefile new file mode 100644 index 000000000..f4bfb6592 --- /dev/null +++ b/source/shared_lib/include/streflop/libm/flt-32/Makefile @@ -0,0 +1,5 @@ +# Makefile automatically generated by import.pl +include ../../Makefile.common +CPPFLAGS += -I../headers -DLIBM_COMPILING_FLT32=1 +all: e_acosf.o e_acoshf.o e_asinf.o e_atan2f.o e_atanhf.o e_coshf.o e_exp2f.o e_expf.o e_fmodf.o e_gammaf_r.o e_hypotf.o e_j0f.o e_j1f.o e_jnf.o e_lgammaf_r.o e_log10f.o e_log2f.o e_logf.o e_powf.o e_rem_pio2f.o e_remainderf.o e_sinhf.o e_sqrtf.o k_cosf.o k_rem_pio2f.o k_sinf.o k_tanf.o s_asinhf.o s_atanf.o s_cbrtf.o s_ceilf.o s_copysignf.o s_cosf.o s_erff.o s_expm1f.o s_fabsf.o s_finitef.o s_floorf.o s_fpclassifyf.o s_frexpf.o s_ilogbf.o s_isinff.o s_isnanf.o s_ldexpf.o s_llrintf.o s_llroundf.o s_log1pf.o s_logbf.o s_lrintf.o s_lroundf.o s_modff.o s_nearbyintf.o s_nextafterf.o s_remquof.o s_rintf.o s_roundf.o s_scalblnf.o s_scalbnf.o s_signbitf.o s_sincosf.o s_sinf.o s_tanf.o s_tanhf.o s_truncf.o w_expf.o + echo 'flt-32 done!' diff --git a/source/shared_lib/include/streflop/libm/flt-32/t_exp2f.h b/source/shared_lib/include/streflop/libm/flt-32/t_exp2f.h new file mode 100644 index 000000000..f2b552051 --- /dev/null +++ b/source/shared_lib/include/streflop/libm/flt-32/t_exp2f.h @@ -0,0 +1,355 @@ +/* See the import.pl script for potential modifications */ +/* Accurate tables for exp2f(). + Copyright (C) 1998 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Geoffrey Keating + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1f of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* This table has the property that, for all integers -128 <= i <= 127, + exp(i/256.0f + __exp2f_deltatable[i-128]) == __exp2f_atable[i+128] + r + for some -2^-35 < r < 2^-35 (abs(r) < 2^-36 if i <= 0); and that + __exp2f_deltatable[i+128] == t * 2^-30 + for integer t so that abs(t) <= 43447 * 2^0. */ + +#define W30 (9.31322575e-10f) +static const Simple __exp2f_deltatable[256] = { + -810*W30, 283*W30, -1514*W30, 1304*W30, + -1148*W30, -98*W30, -744*W30, -156*W30, + -419*W30, -155*W30, 474*W30, 167*W30, + -1984*W30, -826*W30, 692*W30, 781*W30, + -578*W30, -411*W30, -129*W30, -1500*W30, + 654*W30, -141*W30, -816*W30, -53*W30, + 148*W30, 493*W30, -2214*W30, 760*W30, + 260*W30, 750*W30, -1300*W30, 1424*W30, + -1445*W30, -339*W30, -680*W30, -349*W30, + -922*W30, 531*W30, 193*W30, -2892*W30, + 290*W30, -2145*W30, -276*W30, 485*W30, + -695*W30, 215*W30, -7093*W30, 412*W30, + -4596*W30, 367*W30, 592*W30, -615*W30, + -97*W30, -1066*W30, 972*W30, -226*W30, + -625*W30, -374*W30, -5647*W30, -180*W30, + 20349*W30, -447*W30, 111*W30, -4164*W30, + -87*W30, -21*W30, -251*W30, 66*W30, + -517*W30, 2093*W30, -263*W30, 182*W30, + -601*W30, 475*W30, -483*W30, -1251*W30, + -373*W30, 1471*W30, -92*W30, -215*W30, + -97*W30, -190*W30, 0*W30, -290*W30, + -2647*W30, 1940*W30, -582*W30, 28*W30, + 833*W30, 1493*W30, 34*W30, 321*W30, + 3327*W30, -35*W30, 177*W30, -135*W30, + -796*W30, -428*W30, 129*W30, 9332*W30, + -12*W30, -69*W30, -1743*W30, 6508*W30, + -60*W30, 359*W30, 43447*W30, 15*W30, + -23*W30, -305*W30, -375*W30, -652*W30, + 667*W30, 269*W30, -1575*W30, 185*W30, + -329*W30, 200*W30, 6002*W30, 163*W30, + -647*W30, 19*W30, -603*W30, -755*W30, + 742*W30, -438*W30, 3587*W30, 2560*W30, + 0*W30, -520*W30, -241*W30, -299*W30, + -1270*W30, -991*W30, -1138*W30, 255*W30, + -1192*W30, 1722*W30, 1023*W30, 3700*W30, + -1388*W30, -1551*W30, -2549*W30, 27*W30, + 282*W30, 673*W30, 113*W30, 1561*W30, + 72*W30, 873*W30, 87*W30, -395*W30, + -433*W30, 629*W30, 3440*W30, -284*W30, + -592*W30, -103*W30, -46*W30, -3844*W30, + 1712*W30, 303*W30, 1555*W30, -631*W30, + -1400*W30, -961*W30, -854*W30, -276*W30, + 407*W30, 833*W30, -345*W30, -1501*W30, + 121*W30, -1581*W30, 400*W30, 150*W30, + 1224*W30, -139*W30, -563*W30, 879*W30, + 933*W30, 2939*W30, 788*W30, 211*W30, + 530*W30, -192*W30, 706*W30, -13347*W30, + 1065*W30, 3*W30, 111*W30, -208*W30, + -360*W30, -532*W30, -291*W30, 483*W30, + 987*W30, -33*W30, -1373*W30, -166*W30, + -1174*W30, -3955*W30, 1601*W30, -280*W30, + 1405*W30, 600*W30, -1659*W30, -23*W30, + 390*W30, 449*W30, 570*W30, -13143*W30, + -9*W30, -1646*W30, 1201*W30, 294*W30, + 2181*W30, -1173*W30, 1388*W30, -4504*W30, + 190*W30, -2304*W30, 211*W30, 239*W30, + 48*W30, -817*W30, 1018*W30, 1828*W30, + -663*W30, 1408*W30, 408*W30, -36*W30, + 1295*W30, -230*W30, 1341*W30, 9*W30, + 40*W30, 705*W30, 186*W30, 376*W30, + 557*W30, 5866*W30, 363*W30, -1558*W30, + 718*W30, 669*W30, 1369*W30, -2972*W30, + -468*W30, -121*W30, -219*W30, 667*W30, + 29954*W30, 366*W30, 48*W30, -203*W30 +}; + +namespace streflop_libm { +static const Simple __exp2f_atable[256] /* __attribute__((mode(SF))) */ = { + 0.707106411447f, /* 0x0.b504ecfff */ + 0.709024071690f, /* 0x0.b58299fff */ + 0.710945606239f, /* 0x0.b60088000 */ + 0.712874472142f, /* 0x0.b67ef1000 */ + 0.714806139464f, /* 0x0.b6fd88fff */ + 0.716744661340f, /* 0x0.b77c94000 */ + 0.718687653549f, /* 0x0.b7fbea000 */ + 0.720636486992f, /* 0x0.b87ba1fff */ + 0.722590208040f, /* 0x0.b8fbabfff */ + 0.724549472323f, /* 0x0.b97c12fff */ + 0.726514220228f, /* 0x0.b9fcd5fff */ + 0.728483855735f, /* 0x0.ba7deb000 */ + 0.730457961549f, /* 0x0.baff4afff */ + 0.732438981522f, /* 0x0.bb811efff */ + 0.734425544748f, /* 0x0.bc0350000 */ + 0.736416816713f, /* 0x0.bc85d0000 */ + 0.738412797450f, /* 0x0.bd089efff */ + 0.740414917465f, /* 0x0.bd8bd4fff */ + 0.742422521111f, /* 0x0.be0f66fff */ + 0.744434773914f, /* 0x0.be9346fff */ + 0.746454179287f, /* 0x0.bf179f000 */ + 0.748477637755f, /* 0x0.bf9c3afff */ + 0.750506639473f, /* 0x0.c02133fff */ + 0.752541840064f, /* 0x0.c0a694fff */ + 0.754582285889f, /* 0x0.c12c4e000 */ + 0.756628334525f, /* 0x0.c1b265000 */ + 0.758678436269f, /* 0x0.c238bffff */ + 0.760736882681f, /* 0x0.c2bfa6fff */ + 0.762799203401f, /* 0x0.c346cf000 */ + 0.764867603790f, /* 0x0.c3ce5d000 */ + 0.766940355298f, /* 0x0.c45633fff */ + 0.769021093841f, /* 0x0.c4de90fff */ + 0.771104693409f, /* 0x0.c5671dfff */ + 0.773195922364f, /* 0x0.c5f02afff */ + 0.775292098512f, /* 0x0.c6798afff */ + 0.777394294745f, /* 0x0.c70350000 */ + 0.779501736166f, /* 0x0.c78d6d000 */ + 0.781615912910f, /* 0x0.c817fafff */ + 0.783734917628f, /* 0x0.c8a2d9fff */ + 0.785858273516f, /* 0x0.c92e02000 */ + 0.787990570071f, /* 0x0.c9b9c0000 */ + 0.790125787245f, /* 0x0.ca45aefff */ + 0.792268991467f, /* 0x0.cad223fff */ + 0.794417440881f, /* 0x0.cb5ef0fff */ + 0.796570718287f, /* 0x0.cbec0efff */ + 0.798730909811f, /* 0x0.cc79a0fff */ + 0.800892710672f, /* 0x0.cd074dfff */ + 0.803068041795f, /* 0x0.cd95ddfff */ + 0.805242776881f, /* 0x0.ce2464000 */ + 0.807428598393f, /* 0x0.ceb3a3fff */ + 0.809617877002f, /* 0x0.cf431dfff */ + 0.811812341211f, /* 0x0.cfd2eefff */ + 0.814013659956f, /* 0x0.d06333000 */ + 0.816220164311f, /* 0x0.d0f3ce000 */ + 0.818434238424f, /* 0x0.d184e7fff */ + 0.820652604094f, /* 0x0.d21649fff */ + 0.822877407074f, /* 0x0.d2a818000 */ + 0.825108587751f, /* 0x0.d33a51000 */ + 0.827342867839f, /* 0x0.d3ccbdfff */ + 0.829588949684f, /* 0x0.d45ff1000 */ + 0.831849217401f, /* 0x0.d4f411fff */ + 0.834093391880f, /* 0x0.d58724fff */ + 0.836355149750f, /* 0x0.d61b5f000 */ + 0.838620424257f, /* 0x0.d6afd3fff */ + 0.840896368027f, /* 0x0.d744fc000 */ + 0.843176305293f, /* 0x0.d7da66fff */ + 0.845462262643f, /* 0x0.d87037000 */ + 0.847754716864f, /* 0x0.d90673fff */ + 0.850052893157f, /* 0x0.d99d10fff */ + 0.852359056469f, /* 0x0.da3433fff */ + 0.854668736446f, /* 0x0.dacb91fff */ + 0.856986224651f, /* 0x0.db6373000 */ + 0.859309315673f, /* 0x0.dbfbb1fff */ + 0.861639738080f, /* 0x0.dc946bfff */ + 0.863975346095f, /* 0x0.dd2d7d000 */ + 0.866317391394f, /* 0x0.ddc6f9fff */ + 0.868666708472f, /* 0x0.de60f1000 */ + 0.871022939695f, /* 0x0.defb5c000 */ + 0.873383641229f, /* 0x0.df9611fff */ + 0.875751554968f, /* 0x0.e03141000 */ + 0.878126025200f, /* 0x0.e0ccde000 */ + 0.880506813521f, /* 0x0.e168e4fff */ + 0.882894217966f, /* 0x0.e2055afff */ + 0.885287821299f, /* 0x0.e2a239000 */ + 0.887686729423f, /* 0x0.e33f6ffff */ + 0.890096127973f, /* 0x0.e3dd56fff */ + 0.892507970338f, /* 0x0.e47b67000 */ + 0.894928157336f, /* 0x0.e51a03000 */ + 0.897355020043f, /* 0x0.e5b90efff */ + 0.899788379682f, /* 0x0.e65888000 */ + 0.902227103705f, /* 0x0.e6f85afff */ + 0.904673457151f, /* 0x0.e798ae000 */ + 0.907128036008f, /* 0x0.e8398afff */ + 0.909585535528f, /* 0x0.e8da99000 */ + 0.912051796915f, /* 0x0.e97c3a000 */ + 0.914524436003f, /* 0x0.ea1e46000 */ + 0.917003571999f, /* 0x0.eac0bf000 */ + 0.919490039339f, /* 0x0.eb63b2fff */ + 0.921983361257f, /* 0x0.ec071a000 */ + 0.924488604054f, /* 0x0.ecab48fff */ + 0.926989555360f, /* 0x0.ed4f30000 */ + 0.929502844812f, /* 0x0.edf3e6000 */ + 0.932021975503f, /* 0x0.ee98fdfff */ + 0.934553921208f, /* 0x0.ef3eecfff */ + 0.937083780759f, /* 0x0.efe4b8fff */ + 0.939624726786f, /* 0x0.f08b3f000 */ + 0.942198514924f, /* 0x0.f133ebfff */ + 0.944726586343f, /* 0x0.f1d99a000 */ + 0.947287976728f, /* 0x0.f28176fff */ + 0.949856162070f, /* 0x0.f329c5fff */ + 0.952431440345f, /* 0x0.f3d28bfff */ + 0.955013573175f, /* 0x0.f47bc5000 */ + 0.957603693021f, /* 0x0.f52584000 */ + 0.960199773321f, /* 0x0.f5cfa7000 */ + 0.962801992906f, /* 0x0.f67a31000 */ + 0.965413510788f, /* 0x0.f72556fff */ + 0.968030691152f, /* 0x0.f7d0dc000 */ + 0.970655620084f, /* 0x0.f87ce2fff */ + 0.973290979849f, /* 0x0.f92998fff */ + 0.975926160805f, /* 0x0.f9d64bfff */ + 0.978571653370f, /* 0x0.fa83ac000 */ + 0.981225252139f, /* 0x0.fb3193fff */ + 0.983885228626f, /* 0x0.fbdfe6fff */ + 0.986552715296f, /* 0x0.fc8eb7fff */ + 0.989228487027f, /* 0x0.fd3e14000 */ + 0.991909801964f, /* 0x0.fdedcd000 */ + 0.994601726545f, /* 0x0.fe9e38000 */ + 0.997297704209f, /* 0x0.ff4ee6fff */ + 1.000000000000f, /* 0x1.000000000f */ + 1.002710938457f, /* 0x1.00b1aa000 */ + 1.005429744692f, /* 0x1.0163d7ffe */ + 1.008155703526f, /* 0x1.02167dffe */ + 1.010888457284f, /* 0x1.02c995fff */ + 1.013629436498f, /* 0x1.037d38000 */ + 1.016377568250f, /* 0x1.043152000f */ + 1.019134163841f, /* 0x1.04e5f9ffe */ + 1.021896362316f, /* 0x1.059b00000 */ + 1.024668931945f, /* 0x1.0650b3ffe */ + 1.027446627635f, /* 0x1.0706be001 */ + 1.030234098408f, /* 0x1.07bd6bffe */ + 1.033023953416f, /* 0x1.087441ffe */ + 1.035824656494f, /* 0x1.092bce000 */ + 1.038632392900f, /* 0x1.09e3d0001 */ + 1.041450142840f, /* 0x1.0a9c79ffe */ + 1.044273972530f, /* 0x1.0b558a001 */ + 1.047105550795f, /* 0x1.0c0f1c001 */ + 1.049944162390f, /* 0x1.0cc924001 */ + 1.052791833895f, /* 0x1.0d83c4001 */ + 1.055645227426f, /* 0x1.0e3ec3fff */ + 1.058507919326f, /* 0x1.0efa60001 */ + 1.061377286898f, /* 0x1.0fb66bfff */ + 1.064254641510f, /* 0x1.1072fdffe */ + 1.067140102389f, /* 0x1.113018000f */ + 1.070034146304f, /* 0x1.11edc1fff */ + 1.072937250162f, /* 0x1.12ac04001 */ + 1.075843691823f, /* 0x1.136a7dfff */ + 1.078760385496f, /* 0x1.1429a3ffe */ + 1.081685543070f, /* 0x1.14e958000f */ + 1.084618330005f, /* 0x1.15a98c000 */ + 1.087556362176f, /* 0x1.166a18001 */ + 1.090508937863f, /* 0x1.172b98001 */ + 1.093464612954f, /* 0x1.17ed4bfff */ + 1.096430182434f, /* 0x1.18afa5ffe */ + 1.099401354802f, /* 0x1.19725e000f */ + 1.102381587017f, /* 0x1.1a35adfff */ + 1.105370759965f, /* 0x1.1af994000 */ + 1.108367800686f, /* 0x1.1bbdfdffe */ + 1.111373305331f, /* 0x1.1c82f6000 */ + 1.114387035385f, /* 0x1.1d4878001 */ + 1.117408752440f, /* 0x1.1e0e7ffff */ + 1.120437502874f, /* 0x1.1ed4fe000 */ + 1.123474478729f, /* 0x1.1f9c06000 */ + 1.126521706601f, /* 0x1.2063ba001 */ + 1.129574775716f, /* 0x1.212bd0001 */ + 1.132638812065f, /* 0x1.21f49e000 */ + 1.135709524130f, /* 0x1.22bddbffe */ + 1.138789534565f, /* 0x1.2387b5fff */ + 1.141876101508f, /* 0x1.2451fe000 */ + 1.144971728301f, /* 0x1.251cddffe */ + 1.148077130296f, /* 0x1.25e861ffe */ + 1.151189923305f, /* 0x1.26b462001 */ + 1.154312610610f, /* 0x1.278107ffe */ + 1.157440662410f, /* 0x1.284e08001f */ + 1.160578370109f, /* 0x1.291baa001 */ + 1.163725256932f, /* 0x1.29e9e6000 */ + 1.166879892324f, /* 0x1.2ab8a3ffe */ + 1.170044302935f, /* 0x1.2b8805fff */ + 1.173205971694f, /* 0x1.2c5739ffe */ + 1.176397800428f, /* 0x1.2d2867ffe */ + 1.179586529747f, /* 0x1.2df962001 */ + 1.182784795737f, /* 0x1.2ecafbffe */ + 1.185991406414f, /* 0x1.2f9d21ffe */ + 1.189206838636f, /* 0x1.306fdc001 */ + 1.192430973067f, /* 0x1.314328000f */ + 1.195664167430f, /* 0x1.32170c001 */ + 1.198906540890f, /* 0x1.32eb8a001 */ + 1.202157497408f, /* 0x1.33c098000 */ + 1.205416083326f, /* 0x1.349625fff */ + 1.208683252332f, /* 0x1.356c43fff */ + 1.211961269402f, /* 0x1.364318001f */ + 1.215246438983f, /* 0x1.371a64000 */ + 1.218539118740f, /* 0x1.37f22dffe */ + 1.221847295770f, /* 0x1.38cafc000 */ + 1.225158572187f, /* 0x1.39a3fdfff */ + 1.228481650325f, /* 0x1.3a7dc5ffe */ + 1.231811761846f, /* 0x1.3b5803fff */ + 1.235149741144f, /* 0x1.3c32c5ffe */ + 1.238499879811f, /* 0x1.3d0e53ffe */ + 1.241858124726f, /* 0x1.3dea69fff */ + 1.245225191102f, /* 0x1.3ec713fff */ + 1.248601436624f, /* 0x1.3fa458000 */ + 1.251975655584f, /* 0x1.40817a001 */ + 1.255380749731f, /* 0x1.4160a2001 */ + 1.258783102010f, /* 0x1.423f9bffe */ + 1.262198328973f, /* 0x1.431f6e000 */ + 1.265619754780f, /* 0x1.43ffa7fff */ + 1.269052743928f, /* 0x1.44e0a4001 */ + 1.272490739830f, /* 0x1.45c1f4000 */ + 1.275942921659f, /* 0x1.46a432001 */ + 1.279397487615f, /* 0x1.478697ffe */ + 1.282870173427f, /* 0x1.486a2dffe */ + 1.286346316319f, /* 0x1.494dfdffe */ + 1.289836049094f, /* 0x1.4a32b2001 */ + 1.293333172770f, /* 0x1.4b17e1ffe */ + 1.296839594835f, /* 0x1.4bfdadfff */ + 1.300354957560f, /* 0x1.4ce40fffe */ + 1.303882122055f, /* 0x1.4dcb38001 */ + 1.307417988757f, /* 0x1.4eb2f1ffe */ + 1.310960650439f, /* 0x1.4f9b1dfff */ + 1.314516782746f, /* 0x1.50842bfff */ + 1.318079948424f, /* 0x1.516daffff */ + 1.321653246888f, /* 0x1.5257de000 */ + 1.325237751030f, /* 0x1.5342c8001 */ + 1.328829526907f, /* 0x1.542e2c000 */ + 1.332433700535f, /* 0x1.551a5fffe */ + 1.336045145966f, /* 0x1.56070dffe */ + 1.339667558645f, /* 0x1.56f473ffe */ + 1.343300342533f, /* 0x1.57e287ffe */ + 1.346941947961f, /* 0x1.58d130001 */ + 1.350594043714f, /* 0x1.59c087ffe */ + 1.354256033883f, /* 0x1.5ab085fff */ + 1.357932448365f, /* 0x1.5ba175ffe */ + 1.361609339707f, /* 0x1.5c926dfff */ + 1.365299344044f, /* 0x1.5d8441ffe */ + 1.369003057507f, /* 0x1.5e76fc001 */ + 1.372714757920f, /* 0x1.5f6a3c000 */ + 1.376437187179f, /* 0x1.605e2fffe */ + 1.380165219333f, /* 0x1.615282001f */ + 1.383909463864f, /* 0x1.6247e3ffe */ + 1.387661933907f, /* 0x1.633dd0000 */ + 1.391424179060f, /* 0x1.64345fffe */ + 1.395197510706f, /* 0x1.652ba9fff */ + 1.399006724329f, /* 0x1.66254dffe */ + 1.402773022651f, /* 0x1.671c22000 */ + 1.406576037403f, /* 0x1.68155dfff */ + 1.410389423392f, /* 0x1.690f48001 */ +}; +} diff --git a/source/shared_lib/include/streflop/libm/headers/SMath.h b/source/shared_lib/include/streflop/libm/headers/SMath.h new file mode 100644 index 000000000..4a7531b4f --- /dev/null +++ b/source/shared_lib/include/streflop/libm/headers/SMath.h @@ -0,0 +1,7 @@ +/* Copied from math.h in same directory */ + +/* This file is stub automatically generated by import.pl */ + +// Include bridge, just in case math_private is not included +#include "../streflop_libm_bridge.h" + diff --git a/source/shared_lib/include/streflop/libm/headers/endian.h b/source/shared_lib/include/streflop/libm/headers/endian.h new file mode 100644 index 000000000..04734e5c8 --- /dev/null +++ b/source/shared_lib/include/streflop/libm/headers/endian.h @@ -0,0 +1,77 @@ +/* See the import.pl script for potential modifications */ +/* Copyright (C) 1992, 1996, 1997, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _ENDIAN_H +#define _ENDIAN_H 1 + +#include "features.h" + +/* Definitions for byte order, according to significance of bytes, + from low addresses to high addresses. The value is what you get by + putting '4' in the most significant byte, '3' in the second most + significant byte, '2' in the second least significant byte, and '1' + in the least significant byte, and then writing down one digit for + each byte, starting with the byte at the lowest address at the left, + and proceeding to the byte with the highest address at the right. */ + +#define __LITTLE_ENDIAN 1234 +#define __BIG_ENDIAN 4321 +#define __PDP_ENDIAN 3412 + +/* This file defines `__BYTE_ORDER' for the particular machine. */ +#include "../streflop_libm_bridge.h" + +/* Some machines may need to use a different endianness for floating point + values. */ +#ifndef __FLOAT_WORD_ORDER +# define __FLOAT_WORD_ORDER __BYTE_ORDER +#endif + +#ifdef __USE_BSD +# define LITTLE_ENDIAN __LITTLE_ENDIAN +# define BIG_ENDIAN __BIG_ENDIAN +# define PDP_ENDIAN __PDP_ENDIAN +# define BYTE_ORDER __BYTE_ORDER +#endif + +#if __BYTE_ORDER == __LITTLE_ENDIAN +# define __LONG_LONG_PAIR(HI, LO) LO, HI +#elif __BYTE_ORDER == __BIG_ENDIAN +# define __LONG_LONG_PAIR(HI, LO) HI, LO +#endif + +#endif /* endian.h */ +//#include + +#if 1 +//#if defined _LIBC && !defined _ISOMAC +# if __FLOAT_WORD_ORDER == __BIG_ENDIAN +# define BIG_ENDI 1 +# undef LITTLE_ENDI +# define HIGH_HALF 0 +# define LOW_HALF 1 +# else +# if __FLOAT_WORD_ORDER == __LITTLE_ENDIAN +# undef BIG_ENDI +# define LITTLE_ENDI 1 +# define HIGH_HALF 1 +# define LOW_HALF 0 +# endif +# endif +#endif diff --git a/source/shared_lib/include/streflop/libm/headers/features.h b/source/shared_lib/include/streflop/libm/headers/features.h new file mode 100644 index 000000000..9e3292f05 --- /dev/null +++ b/source/shared_lib/include/streflop/libm/headers/features.h @@ -0,0 +1,350 @@ +/* See the import.pl script for potential modifications */ +/* Copyright (C) 1991,1992,1993,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _FEATURES_H +#define _FEATURES_H 1 + +/* These are defined by the user (or the compiler) + to specify the desired environment: + + __STRICT_ANSI__ ISO Standard C. + _ISOC99_SOURCE Extensions to ISO C89 from ISO C99. + _POSIX_SOURCE IEEE Std 1003.1. + _POSIX_C_SOURCE If ==1, like _POSIX_SOURCE; if >=2 add IEEE Std 1003.2; + if >=199309L, add IEEE Std 1003.1b-1993; + if >=199506L, add IEEE Std 1003.1c-1995; + if >=200112L, all of IEEE 1003.1-2004 + _XOPEN_SOURCE Includes POSIX and XPG things. Set to 500 if + Single Unix conformance is wanted, to 600 for the + upcoming sixth revision. + _XOPEN_SOURCE_EXTENDED XPG things and X/Open Unix extensions. + _LARGEFILE_SOURCE Some more functions for correct standard I/O. + _LARGEFILE64_SOURCE Additional functionality from LFS for large files. + _FILE_OFFSET_BITS=N Select default filesystem interface. + _BSD_SOURCE ISO C, POSIX, and 4.3BSD things. + _SVID_SOURCE ISO C, POSIX, and SVID things. + _ATFILE_SOURCE Additional *at interfaces. + _GNU_SOURCE All of the above, plus GNU extensions. + _REENTRANT Select additionally reentrant object. + _THREAD_SAFE Same as _REENTRANT, often used by other systems. + _FORTIFY_SOURCE If set to numeric value > 0 additional security + measures are defined, according to level. + + The `-ansi' switch to the GNU C compiler defines __STRICT_ANSI__. + If none of these are defined, the default is to have _SVID_SOURCE, + _BSD_SOURCE, and _POSIX_SOURCE set to one and _POSIX_C_SOURCE set to + 199506L. If more than one of these are defined, they accumulate. + For example __STRICT_ANSI__, _POSIX_SOURCE and _POSIX_C_SOURCE + together give you ISO C, 1003.1, and 1003.2, but nothing else. + + These are defined by this file and are used by the + header files to decide what to declare or define: + + __USE_ISOC99 Define ISO C99 things. + __USE_POSIX Define IEEE Std 1003.1 things. + __USE_POSIX2 Define IEEE Std 1003.2 things. + __USE_POSIX199309 Define IEEE Std 1003.1, and .1b things. + __USE_POSIX199506 Define IEEE Std 1003.1, .1b, .1c and .1i things. + __USE_XOPEN Define XPG things. + __USE_XOPEN_EXTENDED Define X/Open Unix things. + __USE_UNIX98 Define Single Unix V2 things. + __USE_XOPEN2K Define XPG6 things. + __USE_LARGEFILE Define correct standard I/O things. + __USE_LARGEFILE64 Define LFS things with separate names. + __USE_FILE_OFFSET64 Define 64bit interface as default. + __USE_BSD Define 4.3BSD things. + __USE_SVID Define SVID things. + __USE_MISC Define things common to BSD and System V Unix. + __USE_ATFILE Define *at interfaces and AT_* constants for them. + __USE_GNU Define GNU extensions. + __USE_REENTRANT Define reentrant/thread-safe *_r functions. + __USE_FORTIFY_LEVEL Additional security measures used, according to level. + __FAVOR_BSD Favor 4.3BSD things in cases of conflict. + + The macros `__GNU_LIBRARY__', `__GLIBC__', and `__GLIBC_MINOR__' are + defined by this file unconditionally. `__GNU_LIBRARY__' is provided + only for compatibility. All new code should use the other symbols + to test for features. + + All macros listed above as possibly being defined by this file are + explicitly undefined if they are not explicitly defined. + Feature-test macros that are not defined by the user or compiler + but are implied by the other feature-test macros defined (or by the + lack of any definitions) are defined by the file. */ + + +/* Undefine everything, so we get a clean slate. */ +#undef __USE_ISOC99 +#undef __USE_POSIX +#undef __USE_POSIX2 +#undef __USE_POSIX199309 +#undef __USE_POSIX199506 +#undef __USE_XOPEN +#undef __USE_XOPEN_EXTENDED +#undef __USE_UNIX98 +#undef __USE_XOPEN2K +#undef __USE_LARGEFILE +#undef __USE_LARGEFILE64 +#undef __USE_FILE_OFFSET64 +#undef __USE_BSD +#undef __USE_SVID +#undef __USE_MISC +#undef __USE_ATFILE +#undef __USE_GNU +#undef __USE_REENTRANT +#undef __USE_FORTIFY_LEVEL +#undef __FAVOR_BSD +#undef __KERNEL_STRICT_NAMES + +/* Suppress kernel-name space pollution unless user expressedly asks + for it. */ +#ifndef _LOOSE_KERNEL_NAMES +# define __KERNEL_STRICT_NAMES +#endif + +/* Always use ISO C things. */ +#define __USE_ANSI 1 + +/* Convenience macros to test the versions of glibc and gcc. + Use them like this: + #if __GNUC_PREREQ (2,8) + ... code requiring gcc 2.8 or later ... + #endif + Note - they won't work for gcc1 or glibc1, since the _MINOR macros + were not defined then. */ +#if defined __GNUC__ && defined __GNUC_MINOR__ +# define __GNUC_PREREQ(maj, min) \ + ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) +#else +# define __GNUC_PREREQ(maj, min) 0 +#endif + + +/* If _BSD_SOURCE was defined by the user, favor BSD over POSIX. */ +#if defined _BSD_SOURCE && \ + !(defined _POSIX_SOURCE || defined _POSIX_C_SOURCE || \ + defined _XOPEN_SOURCE || defined _XOPEN_SOURCE_EXTENDED || \ + defined _GNU_SOURCE || defined _SVID_SOURCE) +# define __FAVOR_BSD 1 +#endif + +/* If _GNU_SOURCE was defined by the user, turn on all the other features. */ +#ifdef _GNU_SOURCE +# undef _ISOC99_SOURCE +# define _ISOC99_SOURCE 1 +# undef _POSIX_SOURCE +# define _POSIX_SOURCE 1 +# undef _POSIX_C_SOURCE +# define _POSIX_C_SOURCE 199506L +# undef _XOPEN_SOURCE +# define _XOPEN_SOURCE 600 +# undef _XOPEN_SOURCE_EXTENDED +# define _XOPEN_SOURCE_EXTENDED 1 +# undef _LARGEFILE64_SOURCE +# define _LARGEFILE64_SOURCE 1 +# undef _BSD_SOURCE +# define _BSD_SOURCE 1 +# undef _SVID_SOURCE +# define _SVID_SOURCE 1 +# undef _ATFILE_SOURCE +# define _ATFILE_SOURCE 1 +#endif + +/* If nothing (other than _GNU_SOURCE) is defined, + define _BSD_SOURCE and _SVID_SOURCE. */ +#if (!defined __STRICT_ANSI__ && !defined _ISOC99_SOURCE && \ + !defined _POSIX_SOURCE && !defined _POSIX_C_SOURCE && \ + !defined _XOPEN_SOURCE && !defined _XOPEN_SOURCE_EXTENDED && \ + !defined _BSD_SOURCE && !defined _SVID_SOURCE) +# define _BSD_SOURCE 1 +# define _SVID_SOURCE 1 +#endif + +/* This is to enable the ISO C99 extension. Also recognize the old macro + which was used prior to the standard acceptance. This macro will + eventually go away and the features enabled by default once the ISO C99 + standard is widely adopted. */ +#if (defined _ISOC99_SOURCE || defined _ISOC9X_SOURCE \ + || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)) +# define __USE_ISOC99 1 +#endif + +/* If none of the ANSI/POSIX macros are defined, use POSIX.1 and POSIX.2 + (and IEEE Std 1003.1b-1993 unless _XOPEN_SOURCE is defined). */ +#if ((!defined __STRICT_ANSI__ || (_XOPEN_SOURCE - 0) >= 500) && \ + !defined _POSIX_SOURCE && !defined _POSIX_C_SOURCE) +# define _POSIX_SOURCE 1 +# if defined _XOPEN_SOURCE && (_XOPEN_SOURCE - 0) < 500 +# define _POSIX_C_SOURCE 2 +# elif defined _XOPEN_SOURCE && (_XOPEN_SOURCE - 0) < 600 +# define _POSIX_C_SOURCE 199506L +# else +# define _POSIX_C_SOURCE 200112L +# endif +#endif + +#if defined _POSIX_SOURCE || _POSIX_C_SOURCE >= 1 || defined _XOPEN_SOURCE +# define __USE_POSIX 1 +#endif + +#if defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 2 || defined _XOPEN_SOURCE +# define __USE_POSIX2 1 +#endif + +#if (_POSIX_C_SOURCE - 0) >= 199309L +# define __USE_POSIX199309 1 +#endif + +#if (_POSIX_C_SOURCE - 0) >= 199506L +# define __USE_POSIX199506 1 +#endif + +#if (_POSIX_C_SOURCE - 0) >= 200112L +# define __USE_XOPEN2K 1 +#endif + +#ifdef _XOPEN_SOURCE +# define __USE_XOPEN 1 +# if (_XOPEN_SOURCE - 0) >= 500 +# define __USE_XOPEN_EXTENDED 1 +# define __USE_UNIX98 1 +# undef _LARGEFILE_SOURCE +# define _LARGEFILE_SOURCE 1 +# if (_XOPEN_SOURCE - 0) >= 600 +# define __USE_XOPEN2K 1 +# undef __USE_ISOC99 +# define __USE_ISOC99 1 +# endif +# else +# ifdef _XOPEN_SOURCE_EXTENDED +# define __USE_XOPEN_EXTENDED 1 +# endif +# endif +#endif + +#ifdef _LARGEFILE_SOURCE +# define __USE_LARGEFILE 1 +#endif + +#ifdef _LARGEFILE64_SOURCE +# define __USE_LARGEFILE64 1 +#endif + +#if defined _FILE_OFFSET_BITS && _FILE_OFFSET_BITS == 64 +# define __USE_FILE_OFFSET64 1 +#endif + +#if defined _BSD_SOURCE || defined _SVID_SOURCE +# define __USE_MISC 1 +#endif + +#ifdef _BSD_SOURCE +# define __USE_BSD 1 +#endif + +#ifdef _SVID_SOURCE +# define __USE_SVID 1 +#endif + +#ifdef _ATFILE_SOURCE +# define __USE_ATFILE 1 +#endif + +#ifdef _GNU_SOURCE +# define __USE_GNU 1 +#endif + +#if defined _REENTRANT || defined _THREAD_SAFE +# define __USE_REENTRANT 1 +#endif + +#if defined _FORTIFY_SOURCE && _FORTIFY_SOURCE > 0 \ + && __GNUC_PREREQ (4, 1) && defined __OPTIMIZE__ && __OPTIMIZE__ > 0 +# if _FORTIFY_SOURCE > 1 +# define __USE_FORTIFY_LEVEL 2 +# else +# define __USE_FORTIFY_LEVEL 1 +# endif +#else +# define __USE_FORTIFY_LEVEL 0 +#endif + +/* We do support the IEC 559 math functionality, real and complex. */ +#define __STDC_IEC_559__ 1 +#define __STDC_IEC_559_COMPLEX__ 1 + +/* wchar_t uses ISO 10646-1 (2nd ed., published 2000-09-15) / Unicode 3.1. */ +#define __STDC_ISO_10646__ 200009L + +/* This macro indicates that the installed library is the GNU C Library. + For historic reasons the value now is 6 and this will stay from now + on. The use of this variable is deprecated. Use __GLIBC__ and + __GLIBC_MINOR__ now (see below) when you want to test for a specific + GNU C library version and use the values in to get + the sonames of the shared libraries. */ +#undef __GNU_LIBRARY__ +#define __GNU_LIBRARY__ 6 + +/* Major and minor version number of the GNU C library package. Use + these macros to test for features in specific releases. */ +#define __GLIBC__ 2 +#define __GLIBC_MINOR__ 4 + +#define __GLIBC_PREREQ(maj, min) \ + ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= ((maj) << 16) + (min)) + +/* Decide whether a compiler supports the long long datatypes. */ +#if defined __GNUC__ \ + || (defined __PGI && defined __i386__ ) \ + || (defined __INTEL_COMPILER && (defined __i386__ || defined __ia64__)) \ + || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) +# define __GLIBC_HAVE_LONG_LONG 1 +#endif + +/* This is here only because every header file already includes this one. */ +#ifndef __ASSEMBLER__ +# ifndef _SYS_CDEFS_H +//# include +# endif + +/* If we don't have __REDIRECT, prototypes will be missing if + __USE_FILE_OFFSET64 but not __USE_LARGEFILE[64]. */ +# if defined __USE_FILE_OFFSET64 && !defined __REDIRECT +# define __USE_LARGEFILE 1 +# define __USE_LARGEFILE64 1 +# endif + +#endif /* !ASSEMBLER */ + +/* Decide whether we can define 'extern inline' functions in headers. */ +#if __GNUC_PREREQ (2, 7) && defined __OPTIMIZE__ \ + && !defined __OPTIMIZE_SIZE__ && !defined __NO_INLINE__ +# define __USE_EXTERN_INLINES 1 +#endif + + +/* This is here only because every header file already includes this one. + Get the definitions of all the appropriate `__stub_FUNCTION' symbols. + contains `#define __stub_FUNCTION' when FUNCTION is a stub + that will always return failure (and set errno to ENOSYS). */ +//#include + + +#endif /* features.h */ diff --git a/source/shared_lib/include/streflop/libm/headers/ieee754.h b/source/shared_lib/include/streflop/libm/headers/ieee754.h new file mode 100644 index 000000000..6ea7378d2 --- /dev/null +++ b/source/shared_lib/include/streflop/libm/headers/ieee754.h @@ -0,0 +1,223 @@ +/* See the import.pl script for potential modifications */ +/* Copyright (C) 1992, 1995, 1996, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _IEEE754_H + +#define _IEEE754_H 1 +#include "../streflop_libm_bridge.h" + +#include "features.h" + +#include "endian.h" + +//__BEGIN_DECLS + +#if defined(LIBM_COMPILING_FLT32) +union ieee754_float + { +int storage[sizeof(float)/sizeof(int)]; +inline Simple& f() {return SIMPLE_FROM_INT_PTR(&storage[0]);} +inline const Simple& f() const {return CONST_SIMPLE_FROM_INT_PTR(&storage[0]);} + + + /* This is the IEEE 754 single-precision format. */ + struct + { +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned int negative:1; + unsigned int exponent:8; + unsigned int mantissa:23; +#endif /* Big endian. */ +#if __BYTE_ORDER == __LITTLE_ENDIAN + unsigned int mantissa:23; + unsigned int exponent:8; + unsigned int negative:1; +#endif /* Little endian. */ + } ieee; + + /* This format makes it easier to see if a NaN is a signalling NaN. */ + struct + { +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned int negative:1; + unsigned int exponent:8; + unsigned int quiet_nan:1; + unsigned int mantissa:22; +#endif /* Big endian. */ +#if __BYTE_ORDER == __LITTLE_ENDIAN + unsigned int mantissa:22; + unsigned int quiet_nan:1; + unsigned int exponent:8; + unsigned int negative:1; +#endif /* Little endian. */ + } ieee_nan; + }; + +#define IEEE754_FLOAT_BIAS 0x7f /* Added to exponent. */ + +#endif + + +#if defined(LIBM_COMPILING_DBL64) +union ieee754_double + { +int storage[sizeof(double)/sizeof(int)]; +inline Double& d() {return DOUBLE_FROM_INT_PTR(&storage[0]);} +inline const Double& d() const {return CONST_DOUBLE_FROM_INT_PTR(&storage[0]);} + + + /* This is the IEEE 754 double-precision format. */ + struct + { +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned int negative:1; + unsigned int exponent:11; + /* Together these comprise the mantissa. */ + unsigned int mantissa0:20; + unsigned int mantissa1:32; +#endif /* Big endian. */ +#if __BYTE_ORDER == __LITTLE_ENDIAN +# if __FLOAT_WORD_ORDER == BIG_ENDIAN + unsigned int mantissa0:20; + unsigned int exponent:11; + unsigned int negative:1; + unsigned int mantissa1:32; +# else + /* Together these comprise the mantissa. */ + unsigned int mantissa1:32; + unsigned int mantissa0:20; + unsigned int exponent:11; + unsigned int negative:1; +# endif +#endif /* Little endian. */ + } ieee; + + /* This format makes it easier to see if a NaN is a signalling NaN. */ + struct + { +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned int negative:1; + unsigned int exponent:11; + unsigned int quiet_nan:1; + /* Together these comprise the mantissa. */ + unsigned int mantissa0:19; + unsigned int mantissa1:32; +#else +# if __FLOAT_WORD_ORDER == BIG_ENDIAN + unsigned int mantissa0:19; + unsigned int quiet_nan:1; + unsigned int exponent:11; + unsigned int negative:1; + unsigned int mantissa1:32; +# else + /* Together these comprise the mantissa. */ + unsigned int mantissa1:32; + unsigned int mantissa0:19; + unsigned int quiet_nan:1; + unsigned int exponent:11; + unsigned int negative:1; +# endif +#endif + } ieee_nan; + }; + +#define IEEE754_DOUBLE_BIAS 0x3ff /* Added to exponent. */ + +#endif + + +#if defined(LIBM_COMPILING_LDBL96) +#if defined(Extended) +union ieee854_long_double + { +int storage[sizeof(long double)/sizeof(int)]; +inline Extended& d() {return EXTENDED_FROM_INT_PTR(&storage[0]);} +inline const Extended& d() const {return CONST_EXTENDED_FROM_INT_PTR(&storage[0]);} + + + /* This is the IEEE 854 double-extended-precision format. */ + struct + { +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned int negative:1; + unsigned int exponent:15; + unsigned int empty:16; + unsigned int mantissa0:32; + unsigned int mantissa1:32; +#endif +#if __BYTE_ORDER == __LITTLE_ENDIAN +# if __FLOAT_WORD_ORDER == BIG_ENDIAN + unsigned int exponent:15; + unsigned int negative:1; + unsigned int empty:16; + unsigned int mantissa0:32; + unsigned int mantissa1:32; +# else + unsigned int mantissa1:32; + unsigned int mantissa0:32; + unsigned int exponent:15; + unsigned int negative:1; + unsigned int empty:16; +# endif +#endif + } ieee; + + /* This is for NaNs in the IEEE 854 double-extended-precision format. */ + struct + { +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned int negative:1; + unsigned int exponent:15; + unsigned int empty:16; + unsigned int one:1; + unsigned int quiet_nan:1; + unsigned int mantissa0:30; + unsigned int mantissa1:32; +#endif +#if __BYTE_ORDER == __LITTLE_ENDIAN +# if __FLOAT_WORD_ORDER == BIG_ENDIAN + unsigned int exponent:15; + unsigned int negative:1; + unsigned int empty:16; + unsigned int mantissa0:30; + unsigned int quiet_nan:1; + unsigned int one:1; + unsigned int mantissa1:32; +# else + unsigned int mantissa1:32; + unsigned int mantissa0:30; + unsigned int quiet_nan:1; + unsigned int one:1; + unsigned int exponent:15; + unsigned int negative:1; + unsigned int empty:16; +# endif +#endif + } ieee_nan; + }; + +#define IEEE854_LONG_DOUBLE_BIAS 0x3fff + +#endif + +#endif + +//__END_DECLS + +#endif /* ieee754.h */ diff --git a/source/shared_lib/include/streflop/libm/headers/math.h b/source/shared_lib/include/streflop/libm/headers/math.h new file mode 100644 index 000000000..edc4f9d34 --- /dev/null +++ b/source/shared_lib/include/streflop/libm/headers/math.h @@ -0,0 +1,5 @@ +/* This file is stub automatically generated by import.pl */ + +// Include bridge, just in case math_private is not included +#include "../streflop_libm_bridge.h" + diff --git a/source/shared_lib/include/streflop/libm/headers/math_private.h b/source/shared_lib/include/streflop/libm/headers/math_private.h new file mode 100644 index 000000000..e12b7d275 --- /dev/null +++ b/source/shared_lib/include/streflop/libm/headers/math_private.h @@ -0,0 +1,285 @@ +/* See the import.pl script for potential modifications */ +/* + * ==================================================== + * 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 + */ + +#ifndef _MATH_PRIVATE_H_ +#define _MATH_PRIVATE_H_ + +/* import.pl: Skipped the macro definitions, keep only the declarations, converted to use streflop types (aliases or wrappers) */ +#include "../streflop_libm_bridge.h" + +namespace streflop_libm { + +#ifdef LIBM_COMPILING_FLT32 +#define __sqrtf __ieee754_sqrtf +#define fabsf __fabsf +#define copysignf __copysignf +extern Simple __log1pf(Simple x); +extern Simple __fabsf(Simple x); +extern Simple __atanf(Simple x); +extern Simple __expm1f(Simple x); +extern int __isinff(Simple x); +extern Simple __rintf(Simple x); +extern Simple __cosf(Simple x); +extern void __sincosf (Simple x, Simple *sinx, Simple *cosx); +extern Simple __floorf(Simple x); +extern Simple __scalbnf (Simple x, int n); +extern Simple __frexpf(Simple x, int *eptr); +extern Simple __ldexpf(Simple value, int exp); +extern int __finitef(Simple x); +#endif + +#ifdef LIBM_COMPILING_DBL64 +#define __sqrt __ieee754_sqrt +#define fabs __fabs +#define copysign __copysign +extern Double __log1p(Double x); +extern Double __fabs(Double x); +extern Double atan(Double x); +extern Double __expm1(Double x); +extern int __isinf(Double x); +extern Double __rint(Double x); +extern Double __cos(Double x); +extern void __sincos (Double x, Double *sinx, Double *cosx); +extern Double __floor(Double x); +extern Double __scalbn(Double x, int n); +extern Double __frexp(Double x, int *eptr); +extern Double __ldexp(Double value, int exp); +extern int __finite(Double x); +#endif + +#ifdef LIBM_COMPILING_LDBL96 +#if defined(Extended) +#define fabsl __fabsl +extern Extended __cosl(Extended x); +extern Extended __sinl(Extended x); +extern Extended __fabsl(Extended x); +#endif +#endif + +#ifdef LIBM_COMPILING_DBL64 +extern Double __ieee754_sqrt (Double); +extern Double __ieee754_acos (Double); +extern Double __ieee754_acosh (Double); +extern Double __ieee754_log (Double); +extern Double __ieee754_atanh (Double); +extern Double __ieee754_asin (Double); +extern Double __ieee754_atan2 (Double,Double); +extern Double __ieee754_exp (Double); +extern Double __ieee754_exp2 (Double); +extern Double __ieee754_exp10 (Double); +extern Double __ieee754_cosh (Double); +extern Double __ieee754_fmod (Double,Double); +extern Double __ieee754_pow (Double,Double); +extern Double __ieee754_lgamma_r (Double,int *); +extern Double __ieee754_gamma_r (Double,int *); +extern Double __ieee754_lgamma (Double); +extern Double __ieee754_gamma (Double); +extern Double __ieee754_log10 (Double); +extern Double __ieee754_log2 (Double); +extern Double __ieee754_sinh (Double); +extern Double __ieee754_hypot (Double,Double); +extern Double __ieee754_j0 (Double); +extern Double __ieee754_j1 (Double); +extern Double __ieee754_y0 (Double); +extern Double __ieee754_y1 (Double); +extern Double __ieee754_jn (int,Double); +extern Double __ieee754_yn (int,Double); +extern Double __ieee754_remainder (Double,Double); +extern int32_t __ieee754_rem_pio2 (Double,Double*); +extern Double __ieee754_scalb (Double,Double); +#endif + +/* fdlibm kernel function */ +#ifdef LIBM_COMPILING_DBL64 +extern Double __kernel_standard (Double,Double,int); +extern Double __kernel_sin (Double,Double,int); +extern Double __kernel_cos (Double,Double); +extern Double __kernel_tan (Double,Double,int); +extern int __kernel_rem_pio2 (Double*,Double*,int,int,int, const int32_t*); +#endif + +/* internal functions. */ +#ifdef LIBM_COMPILING_DBL64 +extern Double __copysign (Double x, Double __y); +#endif + +#if 0 +#ifdef LIBM_COMPILING_DBL64 +extern inline Double __copysign (Double x, Double y) +{ return __builtin_copysign (x, y); } +#endif +#endif + +/* ieee style elementary Simple functions */ +#ifdef LIBM_COMPILING_FLT32 +extern Simple __ieee754_sqrtf (Simple); +extern Simple __ieee754_acosf (Simple); +extern Simple __ieee754_acoshf (Simple); +extern Simple __ieee754_logf (Simple); +extern Simple __ieee754_atanhf (Simple); +extern Simple __ieee754_asinf (Simple); +extern Simple __ieee754_atan2f (Simple,Simple); +extern Simple __ieee754_expf (Simple); +extern Simple __ieee754_exp2f (Simple); +extern Simple __ieee754_exp10f (Simple); +extern Simple __ieee754_coshf (Simple); +extern Simple __ieee754_fmodf (Simple,Simple); +extern Simple __ieee754_powf (Simple,Simple); +extern Simple __ieee754_lgammaf_r (Simple,int *); +extern Simple __ieee754_gammaf_r (Simple,int *); +extern Simple __ieee754_lgammaf (Simple); +extern Simple __ieee754_gammaf (Simple); +extern Simple __ieee754_log10f (Simple); +extern Simple __ieee754_log2f (Simple); +extern Simple __ieee754_sinhf (Simple); +extern Simple __ieee754_hypotf (Simple,Simple); +extern Simple __ieee754_j0f (Simple); +extern Simple __ieee754_j1f (Simple); +extern Simple __ieee754_y0f (Simple); +extern Simple __ieee754_y1f (Simple); +extern Simple __ieee754_jnf (int,Simple); +extern Simple __ieee754_ynf (int,Simple); +extern Simple __ieee754_remainderf (Simple,Simple); +extern int32_t __ieee754_rem_pio2f (Simple,Simple*); +extern Simple __ieee754_scalbf (Simple,Simple); +#endif + + +/* Simple versions of fdlibm kernel functions */ +#ifdef LIBM_COMPILING_FLT32 +extern Simple __kernel_sinf (Simple,Simple,int); +extern Simple __kernel_cosf (Simple,Simple); +extern Simple __kernel_tanf (Simple,Simple,int); +extern int __kernel_rem_pio2f (Simple*,Simple*,int,int,int, const int32_t*); +#endif + +/* internal functions. */ +#ifdef LIBM_COMPILING_FLT32 +extern Simple __copysignf (Simple x, Simple __y); +#endif + +#if 0 +#ifdef LIBM_COMPILING_FLT32 +extern inline Simple __copysignf (Simple x, Simple y) +{ return __builtin_copysignf (x, y); } +#endif +#endif + +#if defined(Extended) +/* ieee style elementary Extended functions */ +#ifdef LIBM_COMPILING_LDBL96 +extern Extended __ieee754_sqrtl (Extended); +extern Extended __ieee754_acosl (Extended); +extern Extended __ieee754_acoshl (Extended); +extern Extended __ieee754_logl (Extended); +extern Extended __ieee754_atanhl (Extended); +extern Extended __ieee754_asinl (Extended); +extern Extended __ieee754_atan2l (Extended,Extended); +extern Extended __ieee754_expl (Extended); +extern Extended __ieee754_exp2l (Extended); +extern Extended __ieee754_exp10l (Extended); +extern Extended __ieee754_coshl (Extended); +extern Extended __ieee754_fmodl (Extended,Extended); +extern Extended __ieee754_powl (Extended,Extended); +extern Extended __ieee754_lgammal_r (Extended,int *); +extern Extended __ieee754_gammal_r (Extended,int *); +extern Extended __ieee754_lgammal (Extended); +extern Extended __ieee754_gammal (Extended); +extern Extended __ieee754_log10l (Extended); +extern Extended __ieee754_log2l (Extended); +extern Extended __ieee754_sinhl (Extended); +extern Extended __ieee754_hypotl (Extended,Extended); +extern Extended __ieee754_j0l (Extended); +extern Extended __ieee754_j1l (Extended); +extern Extended __ieee754_y0l (Extended); +extern Extended __ieee754_y1l (Extended); +extern Extended __ieee754_jnl (int,Extended); +extern Extended __ieee754_ynl (int,Extended); +extern Extended __ieee754_remainderl (Extended,Extended); +extern int __ieee754_rem_pio2l (Extended,Extended*); +extern Extended __ieee754_scalbl (Extended,Extended); +#endif + +/* Extended versions of fdlibm kernel functions */ +#ifdef LIBM_COMPILING_LDBL96 +extern Extended __kernel_sinl (Extended,Extended,int); +extern Extended __kernel_cosl (Extended,Extended); +extern Extended __kernel_tanl (Extended,Extended,int); +extern void __kernel_sincosl (Extended,Extended, + Extended *,Extended *, int); +extern int __kernel_rem_pio2l (Extended*,Extended*,int,int, + int,const int*); +#endif + +#ifndef NO_LONG_DOUBLE +/* prototypes required to compile the ldbl-96 support without warnings */ +#ifdef LIBM_COMPILING_LDBL96 +extern int __finitel (Extended); +extern int __ilogbl (Extended); +extern int __isinfl (Extended); +extern int __isnanl (Extended); +extern Extended __atanl (Extended); +extern Extended __copysignl (Extended, Extended); +extern Extended __expm1l (Extended); +extern Extended __floorl (Extended); +extern Extended __frexpl (Extended, int *); +extern Extended __ldexpl (Extended, int); +extern Extended __log1pl (Extended); +extern Extended __nanl (const char *); +extern Extended __rintl (Extended); +extern Extended __scalbnl (Extended, int); +extern Extended __sqrtl (Extended x); +extern Extended fabsl (Extended x); +extern void __sincosl (Extended, Extended *, Extended *); +extern Extended __logbl (Extended x); +extern Extended __significandl (Extended x); +#endif + +#if 0 +#ifdef LIBM_COMPILING_LDBL96 +extern inline Extended __copysignl (Extended x, Extended y) +{ return __builtin_copysignl (x, y); } +#endif +#endif + +#endif + +#endif + +/* Prototypes for functions of the IBM Accurate Mathematical Library. */ +#ifdef LIBM_COMPILING_DBL64 +extern Double __exp1 (Double __x, Double __xx, Double __error); +extern Double __sin (Double __x); +extern Double __cos (Double __x); +extern int __branred (Double __x, Double *__a, Double *__aa); +extern void __doasin (Double __x, Double __dx, Double __v[]); +extern void __dubsin (Double __x, Double __dx, Double __v[]); +extern void __dubcos (Double __x, Double __dx, Double __v[]); +extern Double __halfulp (Double __x, Double __y); +extern Double __sin32 (Double __x, Double __res, Double __res1); +extern Double __cos32 (Double __x, Double __res, Double __res1); +extern Double __mpsin (Double __x, Double __dx); +extern Double __mpcos (Double __x, Double __dx); +extern Double __mpsin1 (Double __x); +extern Double __mpcos1 (Double __x); +extern Double __slowexp (Double __x); +extern Double __slowpow (Double __x, Double __y, Double __z); +extern void __docos (Double __x, Double __dx, Double __v[]); +#endif + +} + +#endif /* _MATH_PRIVATE_H_ */ diff --git a/source/shared_lib/include/streflop/libm/headers/wchar.h b/source/shared_lib/include/streflop/libm/headers/wchar.h new file mode 100644 index 000000000..ef1f56363 --- /dev/null +++ b/source/shared_lib/include/streflop/libm/headers/wchar.h @@ -0,0 +1,26 @@ +/* wchar_t type related definitions. + Copyright (C) 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _BITS_WCHAR_H +#define _BITS_WCHAR_H 1 + +#define __WCHAR_MIN (-2147483647 - 1) +#define __WCHAR_MAX (2147483647) + +#endif /* bits/wchar.h */ diff --git a/source/shared_lib/include/streflop/libm/import.pl b/source/shared_lib/include/streflop/libm/import.pl new file mode 100755 index 000000000..cb71762a1 --- /dev/null +++ b/source/shared_lib/include/streflop/libm/import.pl @@ -0,0 +1,536 @@ +#!/usr/bin/perl + +# streflop: STandalone REproducible FLOating-Point + +# This script imports the GNU libm files and convert them in such a way they can be compiled with streflop types. + +# Code released according to the GNU Lesser General Public License +# Nicolas Brodu, 2006 + +# Please read the history and copyright information in the accompanying documentation + +if ($#ARGV==-1) { +print <> headers/endian.h"); + +# remove some routines we don't need +if (-r "ldbl-96/printf_fphex.c") {unlink "ldbl-96/printf_fphex.c";} +if (-r "ldbl-96/strtold_l.c") {unlink "ldbl-96/strtold_l.c";} +if (-r "flt-32/mpn2flt.c") {unlink "flt-32/mpn2flt.c";} +if (-r "dbl-64/mpn2dbl.c") {unlink "dbl-64/mpn2dbl.c";} +if (-r "dbl-64/dbl2mpn.c") {unlink "dbl-64/dbl2mpn.c";} +if (-r "dbl-64/t_exp.c") {unlink "dbl-64/t_exp.c";} +if (-r "ldbl-96/mpn2ldbl.c") {unlink "ldbl-96/mpn2ldbl.c";} +if (-r "ldbl-96/ldbl2mpn.c") {unlink "ldbl-96/ldbl2mpn.c";} +if (-r "ldbl-96/s_nexttoward.c") {unlink "ldbl-96/s_nexttoward.c";} +if (-r "ldbl-96/s_nexttowardf.c") {unlink "ldbl-96/s_nexttowardf.c";} +if (-r "ldbl-96/math_ldbl.h") {unlink "ldbl-96/math_ldbl.h";} + +# The float exp in e_expf.c uses doubles internally since revision 1.2 in the libm-ieee754 CVS attic! +# Roll back to the slower, but purely float version, and also overwrite the wrapper by a wraper to the float only version +system("cp -f w_expf.c e_expf.c flt-32"); + +# convert .c => .cpp for clarity +@filelist = glob("flt-32/*.c dbl-64/*.c ldbl-96/*.c"); +foreach $f (@filelist) { + $g = $f; + $g =~ s/\.c$/.cpp/; + rename $f, $g; +} + +# create dummy math.h stub +open(FILE, ">headers/math.h"); +print FILE <) { + # replace double by float, OK in these files + s/double/float/g; + $content.=$_; + } + close FILE; + open(FILE,">$f"); + print FILE $content; + close FILE; +} + +# These files in the dbl directory wrongly use float, long double and float functions +foreach $f ("dbl-64/e_lgamma_r.cpp", "dbl-64/t_exp2.h", "dbl-64/s_llrint.cpp") { + open(FILE,"<$f"); + $content = ""; + while() { + s/fabsf/fabs/g; + s/float/double/g; + s/long double/double/g; + $content.=$_; + } + close FILE; + open(FILE,">$f"); + print FILE $content; + close FILE; +} + +# These files in the ldbl directory wrongly use lower precision types +foreach $f ("ldbl-96/e_lgammal_r.cpp", "ldbl-96/s_cbrtl.cpp", "ldbl-96/s_logbl.cpp", "ldbl-96/s_ldexpl.cpp") { + open(FILE,"<$f"); + $content = ""; + while() { + # do the substitution now + s/long double/Extended/g; + s/\(double\) i;/(long double) i;/g; + s/double (_|v)/long double $1/g; + s/const double factor/const long double factor/g; + s/fabs(?!l)/fabsl$1/g; + s/ldexp(?!l)/ldexpl$1/g; + s/__finite\(/__finitel\(/g; + s/__scalbn\(/__scalbnl\(/g; + $content.=$_; + } + close FILE; + open(FILE,">$f"); + print FILE $content; + close FILE; +} + + +# DOUBLE_FROM_INT_PTR(x) could simply be *reinterpret_cast(x) +# for basic types, but may use a dedicated factory for Object wrappers +# BaseType is either the same as FloatType for plain old float/double, or it is +# the float/double type when FloatType is an Object wrapper +$xdaccessor= + "inline Double& d() {return DOUBLE_FROM_INT_PTR(&i[0]);}\n" +."inline Double& x() {return DOUBLE_FROM_INT_PTR(&i[0]);}\n" +."inline Double& d(int idx) {return DOUBLE_FROM_INT_PTR(&i[idx*(sizeof(double)/sizeof(i))]);}\n" +."inline Double& x(int idx) {return DOUBLE_FROM_INT_PTR(&i[idx*(sizeof(double)/sizeof(i))]);}\n" +."inline const Double& d() const {return CONST_DOUBLE_FROM_INT_PTR(&i[0]);}\n" +."inline const Double& x() const {return CONST_DOUBLE_FROM_INT_PTR(&i[0]);}\n" +."inline const Double& d(int idx) const {return CONST_DOUBLE_FROM_INT_PTR(&i[idx*(sizeof(double)/sizeof(i))]);}\n" +."inline const Double& x(int idx) const {return CONST_DOUBLE_FROM_INT_PTR(&i[idx*(sizeof(double)/sizeof(i))]);}\n" +; + +@filelist = glob("flt-32/* dbl-64/* ldbl-96/*"); + +foreach $f (@filelist) { + + open(FILE,"<$f"); + $content = ""; + $opened_namespace = 0; + while() { + # remove all system-wide includes + if (/.*?#include(.*?)(.*)/#$1include$2\"$3\"$4/g; + # fp environment is now handled directly by streflop (and FPUSettings.h) + s/fenv\.h/..\/streflop_libm_bridge.h/g; + # integer types handled by the bridge + s/inttypes\.h/..\/streflop_libm_bridge.h/g; + # get rid of stdlib too + s/stdlib\.h/..\/streflop_libm_bridge.h/g; + # and limits.h + s/limits\.h/..\/streflop_libm_bridge.h/g; + # float.h too + s/float\.h/..\/streflop_libm_bridge.h/g; + # errno.h falls back to system, remove it + s/errno\.h/..\/streflop_libm_bridge.h/g; + # replace all occurences of problematic union fields with objects + # by proper C++ accessors + s/\b(\.d(?!\[)\b|\.d\[(.*?)\])/.d($2)/g; + s/\b(\.x(?!\[)\b|\.x\[(.*?)\])/.x($2)/g; + s/\b(\.f(?!\[)\b|\.f\[(.*?)\])/.f($2)/g; # ieee754.h + s/\b(->d(?!\[)\b|->d\[(.*?)\])/->d($2)/g; + s/\b(->x(?!\[)\b|->x\[(.*?)\])/->x($2)/g; + s/\b(->f(?!\[)\b|->f\[(.*?)\])/->f($2)/g; # ieee754.h + # Some more occurences from arrays of such unions/structs + s/\]\.d\b/].d()/g; + # named field C construct is invalid (C++ would initialize first union member) + # and we replace unions by struct + accessor anyway + s/{ *?.i *?= *?{/{{/g; + # volatile declaration of static const global variables poses problem with the wrapper types + s/volatile //g; + # Now substitute the base types by their Simple/Double/Extended aliases or wrapper + s/long double/Extended/g; # before double + s/\bdouble\b/Double/g; + s/\bfloat\b/Simple/g; + # Replace problematic int += double + s/E(X|Y|Z)(.*?=.*?)ONE/E${1}${2}1/g; + # problematic ?: operator with different types. This simple check catches all problematic occurences +# if (/\?(.*?(\b0\.|\.0).*?:.*?|.*?:.*?(\b0\.|\.0).*?);/) { +# print "$f => ?$1;\n"; +# } + if (/\?(.*?):(.*?)\b(0\.0|10\.0|1\.0)\b/) { + my $type = ""; + if ($f =~ /flt-32/) {$type = "Simple";} + if ($f =~ /dbl-64/) {$type = "Double";} + if ($f =~ /ldbl-96/) {$type = "Extended";} + s/\?(.*?):(.*?)\b(0\.0|10\.0|1\.0)\b/?$1:$2$type($3)/g; + } + my $type = ""; + my $flit = ""; + if ($f =~ /flt-32/) {$type = "Simple"; $flit = "f";} + if ($f =~ /dbl-64/) {$type = "Double"; $flit = "";} + if ($f =~ /ldbl-96/) {$type = "Extended"; $flit = "l";} + # replace problematic mixed-type ?: operators where an int and a float are used as arguments, incompatible with wrappers + if (/\?(.*?)\b(0\.0|1\.0)\b(.*?):(.*?)/) { + s/\?(.*?)\b(0\.0|1\.0)\b(.*?):(.*?)/?$1$type($2)$3:$4/g; + } + # These special cases are OK because no other ?: pattern use them in the 3 subdirs + s/\?0:/?Double(0.0):/; + s/:0;/:Double(0.0);/; + # protect the new symbol names by namespace to avoid any conflict with system libm + if (((/#ifdef __STDC__/) || (/.*? (__|mcr|ss32)[a-z,A-Z,_,0-9]*?\(.*?{$/) || (/Double (atan2Mp|atanMp|slow|tanMp|__exp1|__ieee754_remainder|__ieee754_sqrt)/) || (/^(Simple|Double|Extended|void|int)$/) || ((/^#ifdef BIG_ENDI$/) && ($f =~ /(uatan|mpa2|mpexp|atnat|sincos32)/)) || (/^#define MM 5$/) || (/^void __mp(log|sqrt|exp|atan)\(/) || (/^int __(b|mp)ranred\(/)) && ($opened_namespace == 0)) { + $_ = "namespace streflop_libm {\n".$_; + $opened_namespace = 1; + } + + # Prevent type promotion for native aliases + # Ex: promotion would cause computations like y = 0.5 * x to be done in double for x,y float, then cast back to float + # We want the whole computation done in float, not temporary switching to double. + # In some case the FPU internal precision is enough to mask the problem, but for SSE for example, the float/double + # are using different instructions and the problem cannot be ignored (in these cases, there are differences from + # soft float implementation) + # Cannot replace by s/blah/$type($1)/g; because of static order initialization fiasco with wrapper types + # So use next best option to use litteral type specification + # => this solves the problem for native types + # => wrappers are OK thanks to the redefinitions of the operators + s/\b((\d+\.\d*|\d*\.\d+)((e|E)[-+]?\d+)?)(f|F|l|L)?\b/$1$flit/g; + $content.=$_; + } + close FILE; + # multi-line spanning regexp + $content =~ s/union ?{(.*?);.*?Double.*?}/struct {\n$xdaccessor$1;}/sg; + # close opened namespace + if ($opened_namespace==1) { + $content .= "}\n"; + } + open(FILE,">$f"); + print FILE $importNotice; + print FILE $content; + close FILE; +} + + +# ieee754.h union+accessor +open(FILE,") { + # Comment out decls sections + if (/.*?__.*?_DECLS.*/) {$_="//".$_;} + # Convert all includes to local files + s/^([ \t]*)#include([ \t]*)<(.*)>(.*)/#$1include$2\"$3\"$4/g; + # insert our own bridge + if (/^#define _IEEE754_H.*/) { + $_.="#include \"../streflop_libm_bridge.h\"\n\n"; + } + # Protect the Simple section by a #define + if (/.*?ieee754_float.*?/) { + $_ = "#if defined(LIBM_COMPILING_FLT32)\n".$_; + } + if (/.*?IEEE754_FLOAT_BIAS.*?/) { + $_ = $_."\n#endif\n"; + } + # Protect the Double section by a #define + if (/.*?ieee754_double.*?/) { + $_ = "#if defined(LIBM_COMPILING_DBL64)\n".$_; + } + if (/.*?IEEE754_DOUBLE_BIAS.*?/) { + $_ = $_."\n#endif\n"; + } + # Protect the Extended section by a #define + if (/.*?ieee854_long_double.*?/) { + $_ = "#if defined(Extended)\n".$_; + $_ = "#if defined(LIBM_COMPILING_LDBL96)\n".$_; + } + if (/.*?IEEE854_LONG_DOUBLE_BIAS.*?/) { + $_ = $_."\n#endif\n"; + $_ = $_."\n#endif\n"; + } + $content.=$_; +} +$ieeeAccessorSimple= + "inline Simple& f() {return SIMPLE_FROM_INT_PTR(&storage[0]);}\n" +."inline const Simple& f() const {return CONST_SIMPLE_FROM_INT_PTR(&storage[0]);}\n"; +$ieeeAccessorDouble= + "inline Double& d() {return DOUBLE_FROM_INT_PTR(&storage[0]);}\n" +."inline const Double& d() const {return CONST_DOUBLE_FROM_INT_PTR(&storage[0]);}\n"; +$ieeeAccessorExtended= + "inline Extended& d() {return EXTENDED_FROM_INT_PTR(&storage[0]);}\n" +."inline const Extended& d() const {return CONST_EXTENDED_FROM_INT_PTR(&storage[0]);}\n"; + +# multi-line spanning regexp +$content =~ s/union(.*?ieee854_long_double.*?){.*?;/union$1\{\nint storage[sizeof(long double)\/sizeof(int)];\n$ieeeAccessorExtended/sg; +$content =~ s/union(.*?ieee754_double.*?){.*?;/union$1\{\nint storage[sizeof(double)\/sizeof(int)];\n$ieeeAccessorDouble/sg; +$content =~ s/union(.*?ieee754_float.*?){.*?;/union$1\{\nint storage[sizeof(float)\/sizeof(int)];\n$ieeeAccessorSimple/sg; +close FILE; +open(FILE,">headers/ieee754.h"); +print FILE $importNotice; +print FILE $content; +close FILE; + +# math_private.h needs a special treatement to define the macros for the wrapper objects +# The macros will be defined separately +open(FILE,") { + # keep initial lines with header information and #define file protection + # skip all lines defining macros and unions + if (/^#define _MATH_PRIVATE_H_.*/) { + push @convert,$_; + push @convert,"\n/* import.pl: Skipped the macro definitions, keep only the declarations, converted to use streflop types (aliases or wrappers) */\n#include \"../streflop_libm_bridge.h\"\n\nnamespace streflop_libm {\n\n"; + # ensure strict separation of precision mode, each one does not have access to the other names + push @convert,"#ifdef LIBM_COMPILING_FLT32\n"; + # define wrappers as the libm would do in IEEE754 mode + push @convert,"#define __sqrtf __ieee754_sqrtf\n"; + push @convert,"#define fabsf __fabsf\n"; + push @convert,"#define copysignf __copysignf\n"; + # add missing defines + push @convert,"extern Simple __log1pf(Simple x);\n"; + push @convert,"extern Simple __fabsf(Simple x);\n"; + push @convert,"extern Simple __atanf(Simple x);\n"; + push @convert,"extern Simple __expm1f(Simple x);\n"; + push @convert,"extern int __isinff(Simple x);\n"; + push @convert,"extern Simple __rintf(Simple x);\n"; + push @convert,"extern Simple __cosf(Simple x);\n"; + push @convert,"extern void __sincosf (Simple x, Simple *sinx, Simple *cosx);\n"; + push @convert,"extern Simple __floorf(Simple x);\n"; + push @convert,"extern Simple __scalbnf (Simple x, int n);\n"; + push @convert,"extern Simple __frexpf(Simple x, int *eptr);\n"; + push @convert,"extern Simple __ldexpf(Simple value, int exp);\n"; + push @convert,"extern int __finitef(Simple x);\n"; + push @convert,"#endif\n\n"; + push @convert,"#ifdef LIBM_COMPILING_DBL64\n"; + push @convert,"#define __sqrt __ieee754_sqrt\n"; + push @convert,"#define fabs __fabs\n"; + push @convert,"#define copysign __copysign\n"; + push @convert,"extern Double __log1p(Double x);\n"; + push @convert,"extern Double __fabs(Double x);\n"; + push @convert,"extern Double atan(Double x);\n"; + push @convert,"extern Double __expm1(Double x);\n"; + push @convert,"extern int __isinf(Double x);\n"; + push @convert,"extern Double __rint(Double x);\n"; + push @convert,"extern Double __cos(Double x);\n"; + push @convert,"extern void __sincos (Double x, Double *sinx, Double *cosx);\n"; + push @convert,"extern Double __floor(Double x);\n"; + push @convert,"extern Double __scalbn(Double x, int n);\n"; + push @convert,"extern Double __frexp(Double x, int *eptr);\n"; + push @convert,"extern Double __ldexp(Double value, int exp);\n"; + push @convert,"extern int __finite(Double x);\n"; + push @convert,"#endif\n\n"; + push @convert,"#ifdef LIBM_COMPILING_LDBL96\n"; + push @convert,"#if defined(Extended)\n"; + push @convert,"#define fabsl __fabsl\n"; + push @convert,"extern Extended __cosl(Extended x);\n"; + push @convert,"extern Extended __sinl(Extended x);\n"; + push @convert,"extern Extended __fabsl(Extended x);\n"; + push @convert,"#endif\n"; + push @convert,"#endif\n"; + push @convert,"\n"; + $flag = 0; + } + if (/^extern(.*)/) { + $flag = 1; + } + if ($flag==0) {next MPRIV_LOOP;} + + + + # Now substitute the base types by their Simple/Double/Extended aliases or wrapper + s/\blong double\b/Extended/g; # before double + s/\bdouble\b/Double/g; + s/\bfloat\b/Simple/g; + # Protect the Extended section by a #define + if (/.*?elementary Extended functions.*?/) { + $_ = "#if defined(Extended)\n".$_; + } + if (/.*?functions of the IBM.*?/) { + $_ = "#endif\n\n".$_; + } + # remove the inline aliases + s/__GNUC_PREREQ \(.*?\)/0/; + # end namespace protection + if (/^#endif.*_MATH_PRIVATE_H_/) { + $_ = "}\n\n".$_; + } + + # now insert protection for symbols separation + if (/^extern(.*)/) { + $remline = $1; + if ($remline =~ /Extended/) { + if ($precisionMode ne "Extended") { + if ($precisionMode ne "none") {$_ = "#endif\n".$_;} + $_ = "#ifdef LIBM_COMPILING_LDBL96\n".$_; + $precisionMode = "Extended"; + } + } + elsif ($remline =~ /Double/) { + if ($precisionMode ne "Double") { + if ($precisionMode ne "none") {$_ = "#endif\n".$_;} + $_ = "#ifdef LIBM_COMPILING_DBL64\n".$_; + $precisionMode = "Double"; + } + } + elsif ($remline =~ /Simple/) { + if ($precisionMode ne "Simple") { + if ($precisionMode ne "none") {$_ = "#endif\n".$_;} + $_ = "#ifdef LIBM_COMPILING_FLT32\n".$_; + $precisionMode = "Simple"; + } + } + } else { + $line = $_; + chomp $line; + if (($line =~ /^(\s)*$/) && ($precisionMode ne "none")) { + $_ = "#endif\n".$_; + $precisionMode = "none"; + } + } + + push @convert,$_; +} +close FILE; +open(FILE,">headers/math_private.h"); +print FILE $importNotice; +print FILE @convert; +close FILE; + +# features.h is nearly ready, just do not include more external defs +open(FILE,") { + # commment out external includes + s,(.*?#.*?include.*),//$1,; + push @convert,$_; +} +close FILE; +open(FILE,">headers/features.h"); +print FILE $importNotice; +print FILE @convert; +close FILE; + +# headers/endian.h +open(FILE,") { + # change machine specific bits/endian by streflop configuration + if (//) { + s,,\"../streflop_libm_bridge.h\",; + #keep features.h, but locally + } elsif (//) { + s,,"features.h",; + } else { + # commment out all other external includes + s,(.*?#.*?include.*),//$1,; + } + #unconditional definition of endian things + if (/defined _LIBC/) { + $_ = "#if 1\n//".$_; + } + push @convert,$_; +} +close FILE; +open(FILE,">headers/endian.h"); +print FILE $importNotice; +print FILE @convert; +close FILE; + + +# include the bridge from mpa.h +open(FILE,") { + # special case + s/->d\(\)/->mantissa/g; + $content.=$_; +} +close FILE; +$mpAccessor= + "inline Double& d(int idx) {return mantissa[idx];}\n" +."inline const Double& d(int idx) const {return mantissa[idx];}\n"; +# multi-line spanning regexp +$content =~ s/Double d\[(.*?)\].*?} mp_no/Double mantissa[$1];\n$mpAccessor} mp_no/sg; +open(FILE,">dbl-64/mpa.h"); +print FILE $content."}\n"; # also close namespace +close FILE; + +# Generate specific Makefiles +$parentMakefile=""; +foreach $dir ("flt-32", "dbl-64", "ldbl-96") { + @objFiles = glob("$dir/*.cpp"); + $parentObjects = "$dir-objects ="; + foreach $f (@objFiles) { + $f =~ s/\.cpp$/.o/; + $parentObjects .= " libm/$f"; + $f =~ s/^$dir\///; + } + open(FILE, ">$dir/Makefile"); + my $DIR = uc($dir); + $DIR =~ s/\-//; + print FILE "# Makefile automatically generated by import.pl\n" + ."include ../../Makefile.common\n" + ."CPPFLAGS += -I../headers -DLIBM_COMPILING_$DIR=1\n" + ."all: @objFiles\n" + ."\techo '$dir done!'\n"; + close FILE; + $parentMakefile .= $parentObjects."\n\n"; +} + +# generate Makefile rule in parent directory +@projectFiles = glob("flt-32/* dbl-64/* ldbl-96/* headers/*"); +foreach $f (@projectFiles) {$f = " libm/$f";} +open(FILE, ">../Makefile.libm_objects"); +print FILE "# Makefile automatically generated by libm/import.pl. Do not edit.\n\n" + .$parentMakefile + ."\nlibm-src ="; +print FILE @projectFiles; +print FILE "\n"; +close FILE; diff --git a/source/shared_lib/include/streflop/libm/streflop_libm_bridge.h b/source/shared_lib/include/streflop/libm/streflop_libm_bridge.h new file mode 100644 index 000000000..989685734 --- /dev/null +++ b/source/shared_lib/include/streflop/libm/streflop_libm_bridge.h @@ -0,0 +1,438 @@ +/* + This file acts as a bridge between the libm files and streflop. + It replaces the missing type definitions and macros that were defined + by the external files that were included by the libm, so it is now + standalone. + + In addition, this allows to wrap the basic types for compiling + the libm, ex, with SoftFloat. + + This file is NOT included by the streflop main files, and thus NOT + included by the user programs. + It is included by the libm converted files to produce the streflop binary, + that will be linked by the user program instead of the system libm. + + Nicolas Brodu, 2006 + Code released according to the GNU Lesser General Public License +*/ + +#ifndef STREFLOP_LIBM_BRIDGE +#define STREFLOP_LIBM_BRIDGE + +// prevent inclusion of the main Math.h file +// => the function symbol are not defined when compiling libm +// => this adds a level of protection, a function inadvertantly using a wrong precision function is detected +#define STREFLOP_MATH_H + +// First define our custom types +#include "../streflop.h" + +// Export type definitions, etc. +using namespace streflop; + +// for int32_t, etc. Assume WORDSIZE is defined by the Makefile.common +#include "../System.h" +#undef __USE_ISOC99 +#undef __USE_POSIX +#undef __USE_POSIX2 +#undef __USE_POSIX199309 +#undef __USE_POSIX199506 +#undef __USE_XOPEN +#undef __USE_XOPEN_EXTENDED +#undef __USE_UNIX98 +#undef __USE_XOPEN2K +#undef __USE_LARGEFILE +#undef __USE_LARGEFILE64 +#undef __USE_FILE_OFFSET64 +#undef __USE_BSD +#undef __USE_SVID +#undef __USE_MISC +#undef __USE_GNU +#undef __USE_REENTRANT +#undef __USE_FORTIFY_LEVEL +#undef __FAVOR_BSD +#undef __KERNEL_STRICT_NAMES + +#undef weak_alias +#undef strong_alias +#undef hidden_def +#undef libm_hidden_def +#undef INTDEF +#define weak_alias(x,y) +#define strong_alias(x,y) +#define hidden_def(x) +#define libm_hidden_def(x) +#define INTDEF(x) +#define __set_errno(x) do {} while (0) + +#define _IEEE_LIBM 1 + +// u_int32_t is not C99 compliant +typedef streflop::uint32_t u_int32_t; + +///////////////////////////////////////////////////////////////////////////// +// Common definitions +///////////////////////////////////////////////////////////////////////////// + +// is not included, define only these constants that are needed to compile libm +#define FLT_MIN_EXP (-128) +#define FLT_MAX_EXP 127 +#define FLT_MANT_DIG 24 +#define DBL_MIN_EXP (-1024) +#define DBL_MAX_EXP 1023 +#define DBL_MANT_DIG 53 +#define LDBL_MANT_DIG 64 + +#define HUGE_VALF SimplePositiveInfinity +#define HUGE_VAL DoublePositiveInfinity +#define HUGE_VALL ExtendedPositiveInfinity + +#define INT_MAX ((-1)>>1) + +// Stolen from bits/mathdef.h +#define FP_ILOGB0 (-2147483647) +#define FP_ILOGBNAN 2147483647 + +namespace streflop_libm { + +// No template, only allow this for int types (could use traits, but it's simpler this way) +inline char abs(char x) {return x < 0 ? -x : x;} +inline short abs(short x) {return x < 0 ? -x : x;} +inline int abs(int x) {return x < 0 ? -x : x;} +inline long abs(long x) {return x < 0 ? -x : x;} +inline long long abs(long long x) {return x < 0 ? -x : x;} + +inline char MIN(char x, char y) {return x y); + } + inline bool isgreaterequal(Simple x, Simple y) { + return (!isunordered(x,y)) && (x >= y); + } + inline bool isless(Simple x, Simple y) { + return (!isunordered(x,y)) && (x < y); + } + inline bool islessequal(Simple x, Simple y) { + return (!isunordered(x,y)) && (x <= y); + } + inline bool islessgreater(Simple x, Simple y) { + return (!isunordered(x,y)) && ((x < y) || (x > y)); + } + extern const Simple SimplePositiveInfinity; + extern const Simple SimpleNegativeInfinity; + extern const Simple SimpleNaN; +#endif + +#ifdef LIBM_COMPILING_DBL64 + extern int __fpclassify(Double x); + extern int __isnanl(Double x); + extern int __isinf(Double x); + inline int fpclassify(Double x) {return streflop_libm::__fpclassify(x);} + inline int isnan(Double x) {return streflop_libm::__isnanl(x);} + inline int isinf(Double x) {return streflop_libm::__isinf(x);} + inline int isfinite(Double x) {return !(isnan(x) || isinf(x));} + inline int isnormal(Double x) {return fpclassify(x) == FP_NORMAL;} + inline bool isunordered(Double x, Double y) { + return (fpclassify(x) == FP_NAN) || (fpclassify (y) == FP_NAN); + } + inline bool isgreater(Double x, Double y) { + return (!isunordered(x,y)) && (x > y); + } + inline bool isgreaterequal(Double x, Double y) { + return (!isunordered(x,y)) && (x >= y); + } + inline bool isless(Double x, Double y) { + return (!isunordered(x,y)) && (x < y); + } + inline bool islessequal(Double x, Double y) { + return (!isunordered(x,y)) && (x <= y); + } + inline bool islessgreater(Double x, Double y) { + return (!isunordered(x,y)) && ((x < y) || (x > y)); + } + extern const Double DoublePositiveInfinity; + extern const Double DoubleNegativeInfinity; + extern const Double DoubleNaN; +#endif + +#ifdef LIBM_COMPILING_LDBL96 +#ifdef Extended + extern int __fpclassifyl(Extended x); + extern int __isnanl(Extended x); + extern int __isinfl(Extended x); + inline int fpclassify(Extended x) {return streflop_libm::__fpclassifyl(x);} + inline int isnan(Extended x) {return streflop_libm::__isnanl(x);} + inline int isinf(Extended x) {return streflop_libm::__isinfl(x);} + inline int isfinite(Extended x) {return !(isnan(x) || isinf(x));} + inline int isnormal(Extended x) {return fpclassify(x) == FP_NORMAL;} + inline bool isunordered(Extended x, Extended y) { + return (fpclassify(x) == FP_NAN) || (fpclassify (y) == FP_NAN); + } + inline bool isgreater(Extended x, Extended y) { + return (!isunordered(x,y)) && (x > y); + } + inline bool isgreaterequal(Extended x, Extended y) { + return (!isunordered(x,y)) && (x >= y); + } + inline bool isless(Extended x, Extended y) { + return (!isunordered(x,y)) && (x < y); + } + inline bool islessequal(Extended x, Extended y) { + return (!isunordered(x,y)) && (x <= y); + } + inline bool islessgreater(Extended x, Extended y) { + return (!isunordered(x,y)) && ((x < y) || (x > y)); + } + extern const Extended ExtendedPositiveInfinity; + extern const Extended ExtendedNegativeInfinity; + extern const Extended ExtendedNaN; +#endif +#endif + + +} + + +// eval method is 0 for x87, sse, soft, that is float_t has size float and double_t has size double +#define FLT_EVAL_METHOD 0 + + + +// Endianity checking +#if __FLOAT_WORD_ORDER == 1234 +#define LOW_WORD_IDX 0 +#define HIGH_WORD_IDX 1 +#elif __FLOAT_WORD_ORDER == 4321 +#define LOW_WORD_IDX 1 +#define HIGH_WORD_IDX 0 +#else +#error unknown byte order +#endif + + +#ifdef Extended + +// little endian +#if __FLOAT_WORD_ORDER == 1234 + +/// Little endian is fine, always the same offsets whatever the memory model +template struct ExtendedConverter { + // Sign and exponent + static inline SizedUnsignedInteger<16>::Type* sexpPtr(Extended* e) { + return reinterpret_cast::Type*>(reinterpret_cast(e)+8); + } + // Mantissa + static inline SizedUnsignedInteger<32>::Type* mPtr(Extended* e) { + return reinterpret_cast::Type*>(e); + } +}; + +// Big endian +#elif __FLOAT_WORD_ORDER == 4321 +/// Extended is softfloat +template<> struct ExtendedConverter<10> { + // Sign and exponent + static inline SizedUnsignedInteger<16>::Type* sexpPtr(Extended* e) { + return reinterpret_cast::Type*>(e); + } + // Mantissa + static inline SizedUnsignedInteger<32>::Type* mPtr(Extended* e) { + return reinterpret_cast::Type*>(reinterpret_cast(e)+2); + } +}; + +/// Default gcc model for x87 - 32 bits (or with -m96bit-long-double) +template<> struct ExtendedConverter<12> { + // Sign and exponent + static inline SizedUnsignedInteger<16>::Type* sexpPtr(Extended* e) { + return reinterpret_cast::Type*>(reinterpret_cast(e)+2); + } + // Mantissa + static inline SizedUnsignedInteger<32>::Type* mPtr(Extended* e) { + return reinterpret_cast::Type*>(reinterpret_cast(e)+4); + } +}; + +/// Default gcc model for x87 - 64 bits (or with -m128bit-long-double) +template<> struct ExtendedConverter<16> { + // Sign and exponent + static inline SizedUnsignedInteger<16>::Type* sexpPtr(Extended* e) { + return reinterpret_cast::Type*>(reinterpret_cast(e)+6); + } + // Mantissa + static inline SizedUnsignedInteger<32>::Type* mPtr(Extended* e) { + return reinterpret_cast::Type*>(reinterpret_cast(e)+8); + } +}; +#else +#error unknown byte order +#endif + +#endif + + +// Simple +#ifdef LIBM_COMPILING_FLT32 + +// SSE is best case, always plain types +// X87 uses a wrapper for no denormals case +// First member of struct guaranted aligned at mem location => OK +// Idem for SoftFloat wrapper, though endianity has to be checked explicitly +#define SIMPLE_FROM_INT_PTR(x) *reinterpret_cast(x) +#define CONST_SIMPLE_FROM_INT_PTR(x) *reinterpret_cast(x) + + +#define GET_FLOAT_WORD(i,d) \ +do { \ + Simple f = (d); \ + (i) = *reinterpret_cast(&f); \ +} while (0) + + +/* Set a float from a 32 bit int. */ +#define SET_FLOAT_WORD(d,i) \ +do { \ + int ii = (i); \ + (d) = *reinterpret_cast(&ii); \ +} while (0) + +#endif + +// Double + +#ifdef LIBM_COMPILING_DBL64 + +#define DOUBLE_FROM_INT_PTR(x) *reinterpret_cast(x) +#define CONST_DOUBLE_FROM_INT_PTR(x) *reinterpret_cast(x) + +#define EXTRACT_WORDS(ix0,ix1,d) \ +do { \ + Double f = (d); \ + (ix0) = reinterpret_cast(&f)[HIGH_WORD_IDX]; \ + (ix1) = reinterpret_cast(&f)[LOW_WORD_IDX]; \ +} while (0) + +#define GET_HIGH_WORD(i,d) \ +do { \ + Double f = (d); \ + (i) = reinterpret_cast(&f)[HIGH_WORD_IDX]; \ +} while (0) + +#define GET_LOW_WORD(i,d) \ +do { \ + Double f = (d); \ + (i) = reinterpret_cast(&f)[LOW_WORD_IDX]; \ +} while (0) + +#define INSERT_WORDS(d,ix0,ix1) \ +do { \ + Double f; \ + reinterpret_cast(&f)[HIGH_WORD_IDX] = (ix0); \ + reinterpret_cast(&f)[LOW_WORD_IDX] = (ix1); \ + (d) = f; \ +} while (0) + +#define SET_HIGH_WORD(d,v) \ +do { \ + Double f = (d); \ + reinterpret_cast(&f)[HIGH_WORD_IDX] = (v); \ + (d) = f; \ +} while (0) + +#define SET_LOW_WORD(d,v) \ +do { \ + Double f = (d); \ + reinterpret_cast(&f)[LOW_WORD_IDX] = (v); \ + (d) = f; \ +} while (0) + +#endif + +// Extended +#ifdef LIBM_COMPILING_LDBL96 + +#define EXTENDED_FROM_INT_PTR(x) *reinterpret_cast(x) +#define CONST_EXTENDED_FROM_INT_PTR(x) *reinterpret_cast(x) + +#define GET_LDOUBLE_WORDS(exp,ix0,ix1,d) \ +do { \ + Extended f = (d); \ + (exp) = *ExtendedConverter::sexpPtr(&f); \ + (ix0) = ExtendedConverter::mPtr(&f)[HIGH_WORD_IDX]; \ + (ix1) = ExtendedConverter::mPtr(&f)[LOW_WORD_IDX]; \ +} while (0) + +#define SET_LDOUBLE_WORDS(d,exp,ix0,ix1) \ +do { \ + Extended f; \ + *ExtendedConverter::sexpPtr(&f) = (exp); \ + ExtendedConverter::mPtr(&f)[HIGH_WORD_IDX] = (ix0); \ + ExtendedConverter::mPtr(&f)[LOW_WORD_IDX] = (ix1); \ + (d) = f; \ +} while (0) + +#define GET_LDOUBLE_MSW(v,d) \ +do { \ + Extended f = (d); \ + (v) = ExtendedConverter::mPtr(&f)[HIGH_WORD_IDX]; \ +} while (0) + +#define SET_LDOUBLE_MSW(d,v) \ +do { \ + Extended f = (d); \ + ExtendedConverter::mPtr(&f)[HIGH_WORD_IDX] = (v); \ + (d) = f; \ +} while (0) + +#define GET_LDOUBLE_EXP(exp,d) \ +do { \ + Extended f = (d); \ + (exp) = *ExtendedConverter::sexpPtr(&f); \ +} while (0) + +#define SET_LDOUBLE_EXP(d,exp) \ +do { \ + Extended f = (d); \ + *ExtendedConverter::sexpPtr(&f) = (exp); \ + (d) = f; \ +} while (0) + +#endif + + +#ifdef _MSC_VER +// Even if MSVC != STDC, we still need to define it, +// otherwise MSVC chokes on the K&R style function headers. +# define __STDC__ +#endif + + +#endif diff --git a/source/shared_lib/include/streflop/streflop.h b/source/shared_lib/include/streflop/streflop.h new file mode 100644 index 000000000..b5f819732 --- /dev/null +++ b/source/shared_lib/include/streflop/streflop.h @@ -0,0 +1,99 @@ +/* + streflop: STandalone REproducible FLOating-Point + Nicolas Brodu, 2006 + Code released according to the GNU Lesser General Public License + + Heavily relies on GNU Libm, itself depending on netlib fplibm, GNU MP, and IBM MP lib. + Uses SoftFloat too. + + Please read the history and copyright information in the documentation provided with the source code +*/ + +#ifndef STREFLOP_H +#define STREFLOP_H + +// protect against bad defines +#if defined(STREFLOP_SSE) && defined(STREFLOP_X87) +#error You have to define exactly one of STREFLOP_SSE STREFLOP_X87 STREFLOP_SOFT, but you defined both STREFLOP_SSE and STREFLOP_X87 +#elif defined(STREFLOP_SSE) && defined(STREFLOP_SOFT) +#error You have to define exactly one of STREFLOP_SSE STREFLOP_X87 STREFLOP_SOFT, but you defined both STREFLOP_SSE and STREFLOP_SOFT +#elif defined(STREFLOP_X87) && defined(STREFLOP_SOFT) +#error You have to define exactly one of STREFLOP_SSE STREFLOP_X87 STREFLOP_SOFT, but you defined both STREFLOP_X87 and STREFLOP_SOFT +#elif !defined(STREFLOP_SSE) && !defined(STREFLOP_X87) && !defined(STREFLOP_SOFT) +#error You have to define exactly one of STREFLOP_SSE STREFLOP_X87 STREFLOP_SOFT, but you defined none +#endif + +// First, define the numerical types +namespace streflop { + +// Handle the 6 cells of the configuration array. See README.txt +#if defined(STREFLOP_SSE) + + // SSE always uses native types, denormals are handled by FPU flags + typedef float Simple; + typedef double Double; + #undef Extended + +#elif defined(STREFLOP_X87) + + // X87 uses a wrapper for no denormals case +#if defined(STREFLOP_NO_DENORMALS) +#include "X87DenormalSquasher.h" + typedef X87DenormalSquasher Simple; + typedef X87DenormalSquasher Double; + typedef X87DenormalSquasher Extended; + #define Extended Extended + +#else + // Use FPU flags for x87 with denormals + typedef float Simple; + typedef double Double; + typedef long double Extended; + #define Extended Extended +#endif + +#elif defined(STREFLOP_SOFT) && !defined(STREFLOP_NO_DENORMALS) + // Use SoftFloat wrapper +#include "SoftFloatWrapper.h" + typedef SoftFloatWrapper<32> Simple; + typedef SoftFloatWrapper<64> Double; + typedef SoftFloatWrapper<96> Extended; + #define Extended Extended + +#else + +#error STREFLOP: Invalid combination or unknown FPU type. + +#endif + +} + +#if defined(STREFLOP_SSE) && defined(_MSC_VER) + // MSVC will not compile without the long double variants defined, so we either have to declare Extended: + // typedef long double Extended; + // #define Extended Extended + // or write some wrapper macros: + #define atan2l(a, b) atan2((double)a, (double)b) + #define cosl(a) cos((double)a) + #define expl(a) exp((double)a) + #define ldexpl(a, b) ldexp((double)a, (double)b) + #define logl(a) log((double)a) + #define powl(a,b) pow((double)a, (double)b) + #define sinl(a) sin((double)a) + #define sqrtl(a) sqrt((double)a) + #define tanl(a) tan((double)a) + #define frexpl(a, b) frexp((double)a, b) + // The wrappers are possibly the better choice for sync reasons. +#endif + +// Include the FPU settings file, so the user can initialize the library +#include "FPUSettings.h" + +// Now that types are defined, include the Math.h file for the prototypes +#include "SMath.h" + +// And now that math functions are defined, include the random numbers +#include "Random.h" + +#endif + diff --git a/source/shared_lib/include/streflop/streflopC.h b/source/shared_lib/include/streflop/streflopC.h new file mode 100644 index 000000000..0af9edd22 --- /dev/null +++ b/source/shared_lib/include/streflop/streflopC.h @@ -0,0 +1,29 @@ +/* Copyright (C) 2009 Tobi Vollebregt */ + +/* + Serves as a C compatible interface to the most basic streflop functions. +*/ + +#ifndef STREFLOP_C_H +#define STREFLOP_C_H + +#ifdef __cplusplus +extern "C" { +#endif + +/// Initializes the FPU to single precision +void streflop_init_Simple(); + +/// Initializes the FPU to double precision +void streflop_init_Double(); + +#if defined(Extended) +/// Initializes the FPU to extended precision +void streflop_init_Extended(); +#endif // defined(Extended) + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // STREFLOP_C_H diff --git a/source/shared_lib/include/streflop/streflop_cond.h b/source/shared_lib/include/streflop/streflop_cond.h new file mode 100644 index 000000000..d6e55c79a --- /dev/null +++ b/source/shared_lib/include/streflop/streflop_cond.h @@ -0,0 +1,65 @@ +/* Copyright (C) 2008 Tobi Vollebregt */ + +/* Conditionally include streflop depending on STREFLOP_* #defines: + If one of those is present, #include "streflop.h", otherwise #include + + When faced with ambiguous call errors with e.g. fabs, use math::function. + Add it to math namespace if it doesn't exist there yet. */ + +#ifndef STREFLOP_COND_H +#define STREFLOP_COND_H + +#if defined(STREFLOP_X87) || defined(STREFLOP_SSE) || defined(STREFLOP_SOFT) +#include "streflop.h" +using namespace streflop; + +namespace math { + using namespace streflop; +} +#else +#include +namespace math { + using std::fabs; + // using std::sqrt; + using std::sin; + using std::cos; + + using std::sinh; + using std::cosh; + using std::tan; + using std::tanh; + using std::asin; + using std::acos; + using std::atan; + using std::atan2; + using std::ceil; + using std::floor; + using std::fmod; + using std::pow; + using std::log; + using std::log10; + using std::exp; + using std::frexp; + using std::ldexp; +// the following are C99 functions -> not supported by VS C +#if !defined(_MSC_VER) || _MSC_VER < 1500 + using std::isnan; + using std::isinf; + using std::isfinite; +#elif __cplusplus + template inline bool isnan(T value) { + return value != value; + } + // requires include + template inline bool isinf(T value) { + return std::numeric_limits::has_infinity && value == std::numeric_limits::infinity(); + } + // requires include + template inline bool isfinite(T value) { + return !isinf(value); + } +#endif +} +#endif + +#endif // STREFLOP_COND_H diff --git a/source/shared_lib/sources/graphics/particle.cpp b/source/shared_lib/sources/graphics/particle.cpp index d78a18187..461df1fe3 100644 --- a/source/shared_lib/sources/graphics/particle.cpp +++ b/source/shared_lib/sources/graphics/particle.cpp @@ -9,6 +9,7 @@ // License, or (at your option) any later version // ============================================================== +#include "streflop_cond.h" #include "particle.h" #include @@ -262,12 +263,12 @@ void FireParticleSystem::initParticle(Particle *p, int particleIndex){ ParticleSystem::initParticle(p, particleIndex); float ang= random.randRange(-2.0f*pi, 2.0f*pi); - float mod= fabsf(random.randRange(-radius, radius)); + float mod= streflop::fabsf(random.randRange(-radius, radius)); - float x= sinf(ang)*mod; - float y= cosf(ang)*mod; + float x= streflop::sinf(ang)*mod; + float y= streflop::cosf(ang)*mod; - float radRatio= sqrtf(sqrtf(mod/radius)); + float radRatio= streflop::sqrtf(streflop::sqrtf(mod/radius)); p->color= colorNoEnergy*0.5f + colorNoEnergy*0.5f*radRatio; p->energy= static_cast(maxParticleEnergy*radRatio) + random.randRange(-varParticleEnergy, varParticleEnergy); @@ -300,9 +301,9 @@ void FireParticleSystem::setRadius(float radius){ } void FireParticleSystem::setWind(float windAngle, float windSpeed){ - this->windSpeed.x= sinf(degToRad(windAngle))*windSpeed; + this->windSpeed.x= streflop::sinf(degToRad(windAngle))*windSpeed; this->windSpeed.y= 0.0f; - this->windSpeed.z= cosf(degToRad(windAngle))*windSpeed; + this->windSpeed.z= streflop::cosf(degToRad(windAngle))*windSpeed; } @@ -365,12 +366,12 @@ void UnitParticleSystem::initParticle(Particle *p, int particleIndex){ ParticleSystem::initParticle(p, particleIndex); float ang= random.randRange(-2.0f*pi, 2.0f*pi); - float mod= fabsf(random.randRange(-radius, radius)); + float mod= streflop::fabsf(random.randRange(-radius, radius)); - float x= sinf(ang)*mod; - float y= cosf(ang)*mod; + float x= streflop::sinf(ang)*mod; + float y= streflop::cosf(ang)*mod; - float radRatio= sqrtf(sqrtf(mod/radius)); + float radRatio= streflop::sqrtf(streflop::sqrtf(mod/radius)); //p->color= color*0.5f + color*0.5f*radRatio; p->color=color; @@ -392,9 +393,9 @@ void UnitParticleSystem::initParticle(Particle *p, int particleIndex){ else {// rotate it according to rotation float rad=degToRad(rotation); - p->pos= Vec3f(pos.x+x+offset.z*sinf(rad)+offset.x*cosf(rad), pos.y+random.randRange(-radius/2, radius/2)+offset.y, pos.z+y+(offset.z*cosf(rad)-offset.x*sinf(rad))); + p->pos= Vec3f(pos.x+x+offset.z*streflop::sinf(rad)+offset.x*streflop::cosf(rad), pos.y+random.randRange(-radius/2, radius/2)+offset.y, pos.z+y+(offset.z*streflop::cosf(rad)-offset.x*streflop::sinf(rad))); if(relativeDirection){ - p->speed=Vec3f(p->speed.z*sinf(rad)+p->speed.x*cosf(rad),p->speed.y,(p->speed.z*cosf(rad)-p->speed.x*sinf(rad))); + p->speed=Vec3f(p->speed.z*streflop::sinf(rad)+p->speed.x*streflop::cosf(rad),p->speed.y,(p->speed.z*streflop::cosf(rad)-p->speed.x*streflop::sinf(rad))); } } } @@ -448,9 +449,9 @@ void UnitParticleSystem::setRadius(float radius){ } void UnitParticleSystem::setWind(float windAngle, float windSpeed){ - this->windSpeed.x= sinf(degToRad(windAngle))*windSpeed; + this->windSpeed.x= streflop::sinf(degToRad(windAngle))*windSpeed; this->windSpeed.y= 0.0f; - this->windSpeed.z= cosf(degToRad(windAngle))*windSpeed; + this->windSpeed.z= streflop::cosf(degToRad(windAngle))*windSpeed; } @@ -498,9 +499,9 @@ void RainParticleSystem::setRadius(float radius){ } void RainParticleSystem::setWind(float windAngle, float windSpeed){ - this->windSpeed.x= sinf(degToRad(windAngle))*windSpeed; + this->windSpeed.x= streflop::sinf(degToRad(windAngle))*windSpeed; this->windSpeed.y= 0.0f; - this->windSpeed.z= cosf(degToRad(windAngle))*windSpeed; + this->windSpeed.z= streflop::cosf(degToRad(windAngle))*windSpeed; } // =========================================================================== @@ -542,9 +543,9 @@ void SnowParticleSystem::setRadius(float radius){ } void SnowParticleSystem::setWind(float windAngle, float windSpeed){ - this->windSpeed.x= sinf(degToRad(windAngle))*windSpeed; + this->windSpeed.x= streflop::sinf(degToRad(windAngle))*windSpeed; this->windSpeed.y= 0.0f; - this->windSpeed.z= cosf(degToRad(windAngle))*windSpeed; + this->windSpeed.z= streflop::cosf(degToRad(windAngle))*windSpeed; } // =========================================================================== @@ -654,8 +655,8 @@ void ProjectileParticleSystem::update(){ case tSpiral: { pos= flatPos; - pos+= xVector * cos(t*trajectoryFrequency*targetVector.length())*trajectoryScale; - pos+= yVector * sin(t*trajectoryFrequency*targetVector.length())*trajectoryScale; + pos+= xVector * streflop::cos(t*trajectoryFrequency*targetVector.length())*trajectoryScale; + pos+= yVector * streflop::sin(t*trajectoryFrequency*targetVector.length())*trajectoryScale; } break; diff --git a/source/shared_lib/sources/graphics/pixmap.cpp b/source/shared_lib/sources/graphics/pixmap.cpp index a6a74fa99..b564e6e71 100644 --- a/source/shared_lib/sources/graphics/pixmap.cpp +++ b/source/shared_lib/sources/graphics/pixmap.cpp @@ -1,7 +1,7 @@ // ============================================================== // This file is part of Glest Shared Library (www.glest.org) // -// Copyright (C) 2001-2008 Martiņo Figueroa +// Copyright (C) 2001-2008 Martio Figueroa // // You can redistribute this code and/or modify it under // the terms of the GNU General Public License as published @@ -9,6 +9,7 @@ // License, or (at your option) any later version // ============================================================== +#include "streflop_cond.h" #include "pixmap.h" #include @@ -654,11 +655,11 @@ void Pixmap2D::splat(const Pixmap2D *leftUp, const Pixmap2D *rightUp, const Pixm float distRd= splatDist(Vec2i(i, j), Vec2i(w, h)); const float powFactor= 2.0f; - distLu= pow(distLu, powFactor); - distRu= pow(distRu, powFactor); - distLd= pow(distLd, powFactor); - distRd= pow(distRd, powFactor); - avg= pow(avg, powFactor); + distLu= streflop::pow(distLu, powFactor); + distRu= streflop::pow(distRu, powFactor); + distLd= streflop::pow(distLd, powFactor); + distRd= streflop::pow(distRd, powFactor); + avg= streflop::pow(avg, powFactor); float lu= distLu>avg? 0: ((avg-distLu))*random.randRange(0.5f, 1.0f); float ru= distRu>avg? 0: ((avg-distRu))*random.randRange(0.5f, 1.0f); diff --git a/source/shared_lib/sources/graphics/quaternion.cpp b/source/shared_lib/sources/graphics/quaternion.cpp new file mode 100644 index 000000000..a68bec8a9 --- /dev/null +++ b/source/shared_lib/sources/graphics/quaternion.cpp @@ -0,0 +1,211 @@ +// ============================================================== +// This file is part of Glest Shared Library (www.glest.org) +// +// Copyright (C) 2001-2008 Martio Figueroa +// +// You can redistribute this code and/or modify it under +// the terms of the GNU General Public License as published +// by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version +// ============================================================== + +#include "streflop_cond.h" +#include "quaternion.h" + +#include "leak_dumper.h" + +namespace Shared{ namespace Graphics{ + +// ===================================================== +// class AxisAngle +// ===================================================== + +AxisAngle::AxisAngle(const Vec3f &axis, float angle){ + this->axis= axis; + this->angle= angle; +} + +// ===================================================== +// class EulerAngles +// ===================================================== + +EulerAngles::EulerAngles(float x, float y, float z){ + this->x= x; + this->y= y; + this->z= z; +} + +// ===================================================== +// class Quaternion +// ===================================================== + +Quaternion::Quaternion(){ + setMultIdentity(); +} + +Quaternion::Quaternion(float w, const Vec3f &v){ + this->w= w; + this->v= v; +} + +Quaternion::Quaternion(const EulerAngles &eulerAngles){ + setEuler(eulerAngles); +} + +Quaternion::Quaternion(const AxisAngle &axisAngle){ + setAxisAngle(axisAngle); +} + +void Quaternion::setMultIdentity(){ + w= 1.0f; + v= Vec3f(0.0f); +} + +void Quaternion::setAddIdentity(){ + w= 0.0f; + v= Vec3f(0.0f); +} + +void Quaternion::setAxisAngle(const AxisAngle &axisAngle){ + w= streflop::cosf(axisAngle.angle/2.0f); + v.x= axisAngle.axis.x * streflop::sinf(axisAngle.angle/2.0f); + v.y= axisAngle.axis.y * streflop::sinf(axisAngle.angle/2.0f); + v.z= axisAngle.axis.z * streflop::sinf(axisAngle.angle/2.0f); +} + +void Quaternion::setEuler(const EulerAngles &eulerAngles){ + Quaternion qx, qy, qz, qr; + + qx.w= streflop::cosf(eulerAngles.x/2.0f); + qx.v= Vec3f(streflop::sinf(eulerAngles.x/2.0f), 0.0f, 0.0f); + + qy.w= streflop::cosf(eulerAngles.y/2.0f); + qy.v= Vec3f(0.0f, streflop::sinf(eulerAngles.y/2.0f), 0.0f); + + qz.w= streflop::cosf(eulerAngles.z/2.0f); + qz.v= Vec3f(0.0f, 0.0f, streflop::sinf(eulerAngles.z/2.0f)); + + qr= qx*qy*qz; + + w= qr.w; + v= qr.v; +} + +float Quaternion::length(){ + return streflop::sqrt(w*w+v.x*v.x+v.y*v.y+v.z*v.z); +} + +Quaternion Quaternion::conjugate(){ + return Quaternion(w, -v); +} + +void Quaternion::normalize(){ + float il= 1.f/length(); + w*= il; + v= v*il; +} + +Quaternion Quaternion::operator + (const Quaternion &q) const{ + return Quaternion(w +q.w, v+q.v); +} +Quaternion Quaternion::operator * (const Quaternion &q) const{ + return Quaternion( + w*q.w - v.x*q.v.x - v.y*q.v.y - v.z*q.v.z, + Vec3f( + w*q.v.x + v.x*q.w + v.y*q.v.z - v.z*q.v.y, + w*q.v.y + v.y*q.w + v.z*q.v.x - v.x*q.v.z, + w*q.v.z + v.z*q.w + v.x*q.v.y - v.y*q.v.x)); +} + +void Quaternion::operator += (const Quaternion &q){ + *this= *this + q; +} + +void Quaternion::operator *= (const Quaternion &q){ + *this= *this * q; +} + +Quaternion Quaternion::lerp(float t, const Quaternion &q) const{ + return Quaternion( + w * (1.0f-t) + q.w * t, + v * (1.0f-t) + q.v * t); +} + +Matrix3f Quaternion::toMatrix3() const{ + Matrix3f rm; + + //row1 + rm[0]= 1.0f - 2*v.y*v.y - 2*v.z*v.z; + rm[3]= 2*v.x*v.y - 2*w*v.z; + rm[6]= 2*v.x*v.z + 2*w*v.y; + + //row2 + rm[1]= 2*v.x*v.y + 2*w*v.z; + rm[4]= 1.0f - 2*v.x*v.x - 2*v.z*v.z; + rm[7]= 2*v.y*v.z - 2*w*v.x; + + //row3 + rm[2]= 2*v.x*v.z - 2*w*v.y; + rm[5]= 2*v.y*v.z + 2*w*v.x; + rm[8]= 1.0f - 2*v.x*v.x - 2*v.y*v.y; + + return rm; +} + +Matrix4f Quaternion::toMatrix4() const{ + Matrix4f rm; + + //row1 + rm[0]= 1.0f - 2*v.y*v.y - 2*v.z*v.z; + rm[4]= 2*v.x*v.y - 2*w*v.z; + rm[8]= 2*v.x*v.z + 2*w*v.y; + rm[12]= 0.0f; + + //row2 + rm[1]= 2*v.x*v.y + 2*w*v.z; + rm[5]= 1.0f - 2*v.x*v.x - 2*v.z*v.z; + rm[9]= 2*v.y*v.z - 2*w*v.x; + rm[13]= 0.0f; + + //row3 + rm[2]= 2*v.x*v.z - 2*w*v.y; + rm[6]= 2*v.y*v.z + 2*w*v.x; + rm[10]= 1.0f - 2*v.x*v.x - 2*v.y*v.y; + rm[14]= 0.0f; + + //row4 + rm[3]= 0.0f; + rm[7]= 0.0f; + rm[11]= 0.0f; + rm[15]= 1.0f; + + return rm; +} + +AxisAngle Quaternion::toAxisAngle() const{ + float scale= 1.0f/(v.x*v.x + v.y*v.y + v.z*v.z); + return AxisAngle(v*scale, 2*streflop::acosf(w)); +} + +Vec3f Quaternion::getLocalXAxis() const{ + return Vec3f( + 1.0f - 2*v.y*v.y - 2*v.z*v.z, + 2*v.x*v.y + 2*w*v.z, + 2*v.x*v.z - 2*w*v.y); +} + +Vec3f Quaternion::getLocalYAxis() const{ + return Vec3f( + 2*v.x*v.y - 2*w*v.z, + 1.0f - 2*v.x*v.x - 2*v.z*v.z, + 2*v.y*v.z + 2*w*v.x); +} + +Vec3f Quaternion::getLocalZAxis() const{ + return Vec3f( + 2*v.x*v.z + 2*w*v.y, + 2*v.y*v.z - 2*w*v.x, + 1.0f - 2*v.x*v.x - 2*v.y*v.y); +} + +}}//end namespace diff --git a/source/shared_lib/sources/sound/ds8/sound_player_ds8.cpp b/source/shared_lib/sources/sound/ds8/sound_player_ds8.cpp index ebee9de9b..7916c6bb3 100644 --- a/source/shared_lib/sources/sound/ds8/sound_player_ds8.cpp +++ b/source/shared_lib/sources/sound/ds8/sound_player_ds8.cpp @@ -1,7 +1,7 @@ // ============================================================== // This file is part of Glest Shared Library (www.glest.org) // -// Copyright (C) 2001-2008 Martiņo Figueroa +// Copyright (C) 2001-2008 Martio Figueroa // // You can redistribute this code and/or modify it under // the terms of the GNU General Public License as published @@ -12,7 +12,8 @@ #include "sound_player_ds8.h" #include -#include +//#include +//#include "streflop.h" #include "util.h" #include "leak_dumper.h" diff --git a/source/shared_lib/sources/streflop/CMakeLists.txt b/source/shared_lib/sources/streflop/CMakeLists.txt new file mode 100644 index 000000000..54e969f35 --- /dev/null +++ b/source/shared_lib/sources/streflop/CMakeLists.txt @@ -0,0 +1,16 @@ +AUX_SOURCE_DIRECTORY(libm/flt-32 libm_flt32_source) + +SET(cxxflags "-w -O3 -I${CMAKE_CURRENT_SOURCE_DIR}/libm/headers") +if (NOT $ENV{CXX} MATCHES "icpc") + SET(cxxflags "${cxxflags} -mfpmath=sse -msse") +endif (NOT $ENV{CXX} MATCHES "icpc") +SET_SOURCE_FILES_PROPERTIES(${libm_flt32_source} PROPERTIES COMPILE_FLAGS "-DLIBM_COMPILING_FLT32 ${cxxflags}") + +ADD_LIBRARY(streflop STATIC EXCLUDE_FROM_ALL + SMath.cpp + Random.cpp + streflopC.cpp + ${libm_flt32_source} +) +set_target_properties(streflop PROPERTIES COMPILE_FLAGS "${PIC_FLAG}") +#TODO do not use -fPIC for streflop (decreases performance) diff --git a/source/shared_lib/sources/streflop/LGPL.txt b/source/shared_lib/sources/streflop/LGPL.txt new file mode 100644 index 000000000..cf9b6b997 --- /dev/null +++ b/source/shared_lib/sources/streflop/LGPL.txt @@ -0,0 +1,510 @@ + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations +below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. +^L + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it +becomes a de-facto standard. To achieve this, non-free programs must +be allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. +^L + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control +compilation and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. +^L + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. +^L + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at least + three years, to give the same user the materials specified in + Subsection 6a, above, for a charge no more than the cost of + performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. +^L + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. +^L + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply, and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License +may add an explicit geographical distribution limitation excluding those +countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. +^L + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS +^L + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms +of the ordinary General Public License). + + To apply these terms, attach the following notices to the library. +It is safest to attach them to the start of each source file to most +effectively convey the exclusion of warranty; and each file should +have at least the "copyright" line and a pointer to where the full +notice is found. + + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or +your school, if any, to sign a "copyright disclaimer" for the library, +if necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James + Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/source/shared_lib/sources/streflop/README.txt b/source/shared_lib/sources/streflop/README.txt new file mode 100644 index 000000000..9b7b27a42 --- /dev/null +++ b/source/shared_lib/sources/streflop/README.txt @@ -0,0 +1,205 @@ +STandalone REproducible FLOating-Point library +Version 0.2, june 2006. +Nicolas Brodu. See also the acknowledgments below. + + +For a quick setup guide, see the "usage" sections below. + + + +Presentation: + +Floating-point computations are strongly dependent on the FPU hardware implementation, the compiler and its optimizations, and the system mathematical library (libm). Experiments are usually reproducible only on the same machine with the same system library and the same compiler using the same options. Even then, the C++ standard does NOT guarantee reproducible results. Example: + + double x = 1.0; x /= 10.0; + double y = x; + ... + if (y == x) { + // THIS IS NOT ALWAYS TRUE! + } + +A related but more general problem is random number generation, often necessary for experiment reproducibility: + + set_random_seed(42); + double x = random_number(); + +May not return the same x across different FPUs / systems / compilers / etc. + + + +These problems are related to: + +- Some FPU (like x87 on Linux) keep by default an internal precision (80 bits) larger than the type size in memory. In the first example, if x is on the stack but y in a register, the comparison will fail. Worse, whether x and/or y is on the stack or register depends on what you put in the ... section. This problem can be solved by restricting the internal FPU precision to the type size in memory. Unfortunately, on x87, some operations like the transcendental functions are always computed on 80 bits... + +- How well your FPU implements the IEEE754 standard, and in particular, denormal number operations. The provided arithmetic_test code reproducibly gives different results between SSE and x87. This problem is NOT generally solved by restricting the internal precision to the type size in memory. There may be relations however, in particular a denormal float may be a normal double, so the precision matters. + +- How your compiler interacts with your system math library (libm) especially with optimization flags. In particular, gcc-3.4 and gcc-4.0 series may give different results on the same system with the same library. This problem is partially solved by changing the compiler options. + +- Even then, the IEEE754 standard has some loopholes concerning NaN types. In particular, when serializing results, binary files may differ. This problem is solved by comparing numerical values and not bit patterns. + + + +More points to consider: + +- SSE has an option to accelerate computations by approximating denormals by 0. For some applications this is plain wrong, but for other applications like real-time DSP, denormals are a real pain and this is just what's needed (reports have been made that a denormal multiply may take as much as 30 times a normal multiply). Due to the default round-to-nearest mode, the denormals tend NOT to cancel to 0 and may instead accumulate. Deactivating denormals is built-in the core SSE FPU, but unfortunately that's not reproducible on x87. In that case, it's possible to check for denormal conditions after each operation (including assignment) and then flush to zero, thanks to a wrapper type, for reproducibility (but at the expense of performance on x87). + +- No external dependency. The more dependencies, the more chances of a version mismatch. This library should be standalone, providing the whole libm features without resorting to system specific includes or other packages. This way, it can be included in a project as is, with minimal specialization (and risk of misconfiguration). + + + +Proposed solution: + +- Provide Simple, Double and Extended types that match the native types (float, double, long double), but that additionally take care of the FPU internal precision and denormal handling. These types may be simple aliases or C++ wrappers, depending on the FPU and configuration. Note: Extended is the 80-bit type defined by x87. + +- Reimplement the libm as a standalone code that uses these types. Note: For extended support, see below. + +- As a bonus, provide a random number generator so as to make standalone experiments reproducible. + +- Compare with a software floating-point reference implementation. + + + +Usage (programming): + +- Include "streflop.h" in place of , and link with streflop.a instead of libm. All streflop functions are protected by a namespace, so if another part of your program uses libm there is no risk of confusion at link time. However, including the correct file matters. + +- Use the streflop namespace, and the Simple, Double and Extended types as needed, instead of float, double, long double. The streflop types may actually be aliases to the C++ types, or wrapper classes that redefine the operators transparently. + +- You should also call streflop_init with FloatType=Simple,Double,Extended before using that type. You should use only this type (ex: Simple) until the next call to streflop_init. That is, separate your code in blocks using one type at a time. In the simplest case, use streflop_init for your chosen type at the beginning of your program and stick to that type later on. These init functions are necessary to set the correct FPU flags. See also the notes below. + +- You may have a look at arithmeticTest.cpp and randomTest.cpp for examples. + + + +Usage (standalone build): + +- Edit Makefile.common to configure which FPU/denormal setup you choose, by defining one of STREFLOP_SSE, STREFLOP_X87, STREFLOP_SOFT, and optionally STREFLOP_NO_DENORMALS. See the configurations grid below. + +- If you're using the software floating-point implementation on a big-endian machine, change the System.h file accordingly. If your target system size has a char type larger than 8 bits, then check Integer.h. In both cases you're on your own (this is untested). + +- Check the notes below before changing the compiler options. + + + +Usage (including in a project): + +- Copy the whole streflop source somewhere in your project, for example as a "streflop" subdirectory. + +- Check the steps for the standalone build. Potentially automate the choices using your build system, like autoconf. + +- Call "make -C streflop" somewhere in you own build process, or integrate the streflop build in your build system. + +- See the programming usage above. Don't forget to "-Istreflop" and "-Lstreflop -lstreflop.a" when compiling and linking. + + + +Configurations grid: + + | SSE | x87 | Soft | +------------+---------+-----------+----------+ +denormals | Simple *| Simple *| Simple | + | Double *| Double *| Double | + | | Extended *| Extended | +------------+---------+-----------+----------+ +no denormal | Simple *| Simple | + | Double *| Double | + | | Extended | +------------+---------+-----------+ + +One cell in this grid must be selected at configure time. All types within that cell are then available at compile and run time. +Types marked * are aliases to the native float/double/long double, with support by FPU flags. +The other types are wrapper classes that behave like the native types. + + +Apart for the bit representation of NaN values: + +- "Denormals SSE / Denormals Soft" with the same precision should give the same results. + +- "No denormal SSE / No denormal x87" with the same precision should give the same results. + +- "Denormals x87 extended / Denormals Soft extended" should give the same results. + +- "Denormals SSE / Denormals x87" with the same precision may differ but only for some unfrequent occurences involving denormal numbers. + +- All other configurations give different results. + + + +Comparison criteria: + +- Best performance is achieved by "no denormal/SSE simple". What matters most for performance is wrapper/native, the size, then denormals or not (unless using lots of denormals, in which case "no denormals" may matter more than size or wrapper). + +- Best precision is achieved by "denormals extended" modes. What matters most for precision is the the size, then denormal or not. + +- Best IEEE754 conformance is achieved by "Soft" modes (and equivalent results above with SSE/x87). Conformance is achieved only for denormals. + + + +Notes: + +- Beware of too aggressive optimization options! In particular, since this code relies on reinterpret_cast and unions, the compiler must not assume strict aliasing. For g++ optimization levels 2 and 3, this assumption is unfortunately the default. Similarly, the compiler should not assume that NaN can be ignored, or that the FPU has a constant rounding mode. Ex: -O3 -fno-strict-aliasing -frounding-math -fsignaling-nans. + +- You should also set correct FPU options, like -mfpmath=sse -msse -msse2. The -msse2 is important, there are cases where g++ refuses to use SSE (and silently falls back to x87) when using -msse and not -msse2. This also means you cannot reliably use this library with gcc on systems where only sse (but not sse2) is present, like some athlon-xp cores. + +- The system libm will almost surely produce different numerical results depending on your FPU, compiler and options, etc. The rationale is, using this library will increase the reproducibility of your experiments compared to using the system libm. If you want guaranteed (but slower) reproducible results across all machine configurations, without caring for denormals or whatever else, then use a multiprecision software library like GNU MP. If you want to use the hardware FPU in a controlled environment that can retain some reproducibility, then use this library. If it does not fit your needs, then improve it: After all, this is free software :) + +- The following C99 trap and rounding mode functions are implemented, even for the software floating-point implementation: fe(get|set)round, fe(get|set)env, and feholdexcept. You may call them to change rounding modes and to trap special conditions. These functions are expected to work correctly, insofar as the FPU works as intended*, but they have not been extensively tested. +* in particular, reports have been made that the x87 FPU denormal trap sometimes fails. + +- Really beware of aggressive optimization! Separate your code into INDEPENDENT BLOCKS. I mean it. This code is wrong: + streflop_init(); + Simple s = (1.0/4294967295.0); + displayHex(cout, s) << endl; + streflop_init(); + Double d = (1.0/4294967295.0); + displayHex(cout, d) << endl; +THIS NOT WORK CORRECTLY in -O3, but will do fine in -O0. This is because the compiler "optimizes" the constant computation only once for both lines in -O3, which is plain wrong since the precision is different. The only way to ensure this does not happen is to separate your code in logical units: +void func1() { + streflop_init(); + Simple s = (1.0/4294967295.0); + displayHex(cout, s) << endl; +} +void func2() { + streflop_init(); + Double d = (1.0/4294967295.0); + displayHex(cout, d) << endl; +} +Even then, you'd better be careful with interprocedural optimization options. If possible, put func1 and func2 in 2 separate compilation units. + + + +BUGS and discrepancies: + +- Do what you want with this library, but at your own risks, and according to the LGPL (see the LGPL.txt file). + +- There is the possibility of unknown bugs. And this is based on GNU libm 2.4, so any potential bug in that version are almost surely present in streflop too. + +- Extended support is INCOMPLETE. Proper functions are missing, in particular the trigonometric functions. The ldbl-96 implementation of the libm does not contain a generic implementation for these files. Since strelop enforces strict separation of Extended and Double functions, these functions were instead implemented by temporarily switching to Double using streflop_init, calling the function and storing the result on the stack, switching back to streflop_init, then converting the result to an Extended number. + + + +Acknowledgments: + +- This code heavily relies on GNU Libm, itself depending on Sun's netlib fplibm, GNU MP, and IBM's multi-precision library. + +- This code uses the SoftFloat library for the software floating-point implementation. + +- The random number generator is the Mersene Twister, created by Takuji Nishimura and Makoto Matsumoto, and adapted to C++ for this project. Please read the (BSD-like) license in Random.cpp if you intend to make binary packages of this library (and according to LGPL). + +- Please read the history and copyright information in the accompanying README.txt files in the libm and softfloat directories, as well as the LGPL.txt file in this directory. + +- Thanks to Tobi Vollebregt for feedback, Win32 reports, and patches. + + + +How you can help: + +- Test the library and report potential bugs. + +- Port the library to new FPU and operating systems. + +- Help extend the GNU libm first, and only then import that work in this project. + + + +Nicolas Brodu, june 2006. diff --git a/source/shared_lib/sources/streflop/Random.cpp b/source/shared_lib/sources/streflop/Random.cpp new file mode 100644 index 000000000..3c08ebef0 --- /dev/null +++ b/source/shared_lib/sources/streflop/Random.cpp @@ -0,0 +1,984 @@ +/* + streflop: STandalone REproducible FLOating-Point + Nicolas Brodu, 2006 + Code released according to the GNU Lesser General Public License + + Heavily relies on GNU Libm, itself depending on netlib fplibm, GNU MP, and IBM MP lib. + Uses SoftFloat too. + + Please read the history and copyright information in the documentation provided with the source code +*/ + +// Include time(0) function to get a seed based on system time +#include +#include +using namespace std; +#include "streflop.h" + +// Include endian-specific code +#undef __BYTE_ORDER +#undef __FLOAT_WORD_ORDER +#include "System.h" + +namespace streflop { + +////////////////////////////////////////////////////////////////////// +// Code stolen and adapted from mt19937ar.c +////////////////////////////////////////////////////////////////////// + +/* + A C-program for MT19937, with initialization improved 2002/1/26. + Coded by Takuji Nishimura and Makoto Matsumoto. + + Before using, initialize the state by using init_genrand(seed) + or init_by_array(init_key, key_length). + + Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, + All rights reserved. + Copyright (C) 2005, Mutsuo Saito, + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The names of its contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + Any feedback is very welcome. + http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html + email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) +*/ + +#if STREFLOP_RANDOM_GEN_SIZE == 32 + +/* Period parameters */ +#define N 624 +#define M 397 +#define MATRIX_A 0x9908b0dfUL /* constant vector a */ +#define UPPER_MASK 0x80000000UL /* most significant w-r bits */ +#define LOWER_MASK 0x7fffffffUL /* least significant r bits */ + +/* initializes mt[N] with a seed */ +inline void init_genrand(SizedUnsignedInteger<32>::Type s, RandomState& state) +{ + state.seed = s; + state.mt[0]= s; // & 0xffffffffUL; // NB060508: unnecessary with the use of sized types + for (state.mti=1; state.mti> 30)) + state.mti); + /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ + /* In the previous versions, MSBs of the seed affect */ + /* only MSBs of the array mt[]. */ + /* 2002/01/09 modified by Makoto Matsumoto */ + //mt[mti] &= 0xffffffffUL; // NB060508: unnecessary with the use of sized types + /* for >32 bit machines */ + } +} + +/* generates a random number on [0,0xffffffff]-interval */ +inline SizedUnsignedInteger<32>::Type genrand_int(RandomState& state) +{ + SizedUnsignedInteger<32>::Type y; + static SizedUnsignedInteger<32>::Type mag01[2]={0x0UL, MATRIX_A}; + /* mag01[x] = x * MATRIX_A for x=0,1 */ + + if (state.mti >= N) { /* generate N words at one time */ + int kk; + + //if (state.mti == N+1) /* if init_genrand() has not been called, */ + //init_genrand(5489UL, state); /* a default initial seed is used */ + + for (kk=0;kk> 1) ^ mag01[y & 0x1UL]; + } + for (;kk> 1) ^ mag01[y & 0x1UL]; + } + y = (state.mt[N-1]&UPPER_MASK)|(state.mt[0]&LOWER_MASK); + state.mt[N-1] = state.mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL]; + + state.mti = 0; + } + + y = state.mt[state.mti++]; + + /* Tempering */ + y ^= (y >> 11); + y ^= (y << 7) & 0x9d2c5680UL; + y ^= (y << 15) & 0xefc60000UL; + y ^= (y >> 18); + + return y; +} + +#else + +////////////////////////////////////////////////////////////////////// +// End of code adapted from mt19937ar.c +// Now adapt code from the 64-bit version in mt19937-64.c +////////////////////////////////////////////////////////////////////// + +/* + A C-program for MT19937-64 (2004/9/29 version). + Coded by Takuji Nishimura and Makoto Matsumoto. + + This is a 64-bit version of Mersenne Twister pseudorandom number + generator. + + Before using, initialize the state by using init_genrand64(seed) + or init_by_array64(init_key, key_length). + + Copyright (C) 2004, Makoto Matsumoto and Takuji Nishimura, + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The names of its contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + References: + T. Nishimura, ``Tables of 64-bit Mersenne Twisters'' + ACM Transactions on Modeling and + Computer Simulation 10. (2000) 348--357. + M. Matsumoto and T. Nishimura, + ``Mersenne Twister: a 623-dimensionally equidistributed + uniform pseudorandom number generator'' + ACM Transactions on Modeling and + Computer Simulation 8. (Jan. 1998) 3--30. + + Any feedback is very welcome. + http://www.math.hiroshima-u.ac.jp/~m-mat/MT/emt.html + email: m-mat @ math.sci.hiroshima-u.ac.jp (remove spaces) +*/ + +#define NN 312 +#define MM 156 +#define MATRIX_A 0xB5026F5AA96619E9ULL +#define UM 0xFFFFFFFF80000000ULL /* Most significant 33 bits */ +#define LM 0x7FFFFFFFULL /* Least significant 31 bits */ + +/* initializes mt[NN] with a seed */ +inline void init_genrand(SizedUnsignedInteger<64>::Type seed, RandomState& state) +{ + state.seed = seed; + state.mt[0] = seed; + for (state.mti=1; state.mti::Type(6364136223846793005ULL) * (state.mt[state.mti-1] ^ (state.mt[state.mti-1] >> 62)) + state.mti); +} + +/* generates a random number on [0, 2^64-1]-interval */ +inline SizedUnsignedInteger<64>::Type genrand_int(RandomState& state) +{ + int i; + SizedUnsignedInteger<64>::Type x; + static SizedUnsignedInteger<64>::Type mag01[2]={0ULL, MATRIX_A}; + + if (state.mti >= NN) { /* generate NN words at one time */ + + /* if init_genrand64() has not been called, */ + /* a default initial seed is used */ + //if (state.mti == NN+1) + //init_genrand64(5489ULL, state); + + for (i=0;i>1) ^ mag01[(int)(x&1ULL)]; + } + for (;i>1) ^ mag01[(int)(x&1ULL)]; + } + x = (state.mt[NN-1]&UM)|(state.mt[0]&LM); + state.mt[NN-1] = state.mt[MM-1] ^ (x>>1) ^ mag01[(int)(x&1ULL)]; + + state.mti = 0; + } + + x = state.mt[state.mti++]; + + x ^= (x >> 29) & 0x5555555555555555ULL; + x ^= (x << 17) & 0x71D67FFFEDA60000ULL; + x ^= (x << 37) & 0xFFF7EEE000000000ULL; + x ^= (x >> 43); + + return x; +} +#endif + +////////////////////////////////////////////////////////////////////// +// End of code adapted from mt19937-64.c +////////////////////////////////////////////////////////////////////// + +// Bit getter utilities +template struct Accessor { + typedef typename SizedUnsignedInteger::Type Type; + static inline Type getRandomInt(RandomState& state) { + return static_cast(genrand_int(state)); + } +}; + +// Specialize for 32 bits generator case +#if STREFLOP_RANDOM_GEN_SIZE == 32 +template<> struct Accessor<64> { + typedef SizedUnsignedInteger<64>::Type Type; + static inline Type getRandomInt(RandomState& state) { + return static_cast(genrand_int(state)) | (static_cast(genrand_int(state)) << 32); + } +}; +#endif + + +// This code inspired from a trick found in Richard J. Wagner's Mersene class and the optimization +// by Magnus Jonsson, also found at http://aggregate.org. +// The trick consists in: +// - draw random numbers in as close as possible as the target +// - reject these which are out of range +// The goal is to avoid operator % + +template struct RandomIntRestrictor { +}; + +// for 8-bits +template<> struct RandomIntRestrictor<8> { + typedef SizedUnsignedInteger<8>::Type Type; + + static inline Type getRestrictedRandomInt(Type n, RandomState& state) + { + // First propagate leading 1 to all other bits + Type mask = n; + mask |= mask >> 1; + mask |= mask >> 2; + mask |= mask >> 4; + + // Draw only that number of bits, until a number is in the desired range [0,n] + // Worse case is number of loops proba decreasing in 1/2^nloops + Type ret; + do { + ret = Accessor<8>::getRandomInt(state) & mask; + } while( ret > n ); + + return ret; + } +}; + +// for 16-bits +template<> struct RandomIntRestrictor<16> { + typedef SizedUnsignedInteger<16>::Type Type; + + static inline Type getRestrictedRandomInt(Type n, RandomState& state) + { + // First propagate leading 1 to all other bits + Type mask = n; + mask |= mask >> 1; + mask |= mask >> 2; + mask |= mask >> 4; + mask |= mask >> 8; + + // Draw only that number of bits, until a number is in the desired range [0,n] + // Worse case is number of loops proba decreasing in 1/2^nloops + Type ret; + do { + ret = Accessor<16>::getRandomInt(state) & mask; + } while( ret > n ); + + return ret; + } +}; + +// for 32-bits +template<> struct RandomIntRestrictor<32> { + typedef SizedUnsignedInteger<32>::Type Type; + + static inline Type getRestrictedRandomInt(Type n, RandomState& state) + { + // First propagate leading 1 to all other bits + Type mask = n; + mask |= mask >> 1; + mask |= mask >> 2; + mask |= mask >> 4; + mask |= mask >> 8; + mask |= mask >> 16; + + // Draw only that number of bits, until a number is in the desired range [0,n] + // Worse case is number of loops proba decreasing in 1/2^nloops + Type ret; + do { + ret = Accessor<32>::getRandomInt(state) & mask; + } while( ret > n ); + + return ret; + } +}; + +// for 64-bits +template<> struct RandomIntRestrictor<64> { + typedef SizedUnsignedInteger<64>::Type Type; + + static inline Type getRestrictedRandomInt(Type n, RandomState& state) + { + // First propagate leading 1 to all other bits + Type mask = n; + mask |= mask >> 1; + mask |= mask >> 2; + mask |= mask >> 4; + mask |= mask >> 8; + mask |= mask >> 16; + mask |= mask >> 32; + + // Draw only that number of bits, until a number is in the desired range [0,n] + // Worse case is number of loops proba descreasing in 1/2^nloops + Type ret; + do { + ret = Accessor<64>::getRandomInt(state) & mask; + } while( ret > n ); + + return ret; + } +}; + + +// Now implement the Random functions + +/* range checker. + But why should clean caller code be slowed down by checks? + => caller code should provide good arguments, or be fixed + +/// Common function that will be used for all random integer types +template struct RandomSwitcher { + // random selection + static inline an_int_type getMinMaxRandom(an_int_type min, an_int_type max, RandomState& state) { + // Works in both signed and unsigned arithmetic + if (max<=min) { + if (max==min) return min; // easy + return RandomSwitcher::getMinMaxRandom(max, min, state); + } + + // now max > min + an_int_type range = max - min + 1; + + // overflow, asking the whole range of integers + if (range==0) return getRandomBits(sizeof(an_int_type)*STREFLOP_INTEGER_TYPES_CHAR_BITS, state); + + // range >= 2, num_bounds <= 2, OK to subtract 2 - num_bounds + range -= 2-num_bounds; + // ask the impossible, like RandomEE(3,4) + if (range == 0) return min; + + // This gives the number of possible integers to choose from (at least 1) + // Now generate the number + an_int_type ret = min + min_excluded + static_cast(RandomIntRestrictor< sizeof(an_int_type)*STREFLOP_INTEGER_TYPES_CHAR_BITS >::getRestrictedRandomInt(range,state)); + return ret; + } +}; +*/ + +#define SPECIALIZE_RANDOM_FOR_TYPE(a_type,use_signed) \ +template<> a_type Random(RandomState& state) { \ + return Accessor::getRandomInt(state); \ +} \ +template<> a_type Random(a_type min, a_type max, RandomState& state) { \ + return static_cast(RandomIntRestrictor< sizeof(a_type)*STREFLOP_INTEGER_TYPES_CHAR_BITS >::getRestrictedRandomInt(max-min,state)) + min; \ +} \ +template<> a_type Random(a_type min, a_type max, RandomState& state) { \ + return static_cast(RandomIntRestrictor< sizeof(a_type)*STREFLOP_INTEGER_TYPES_CHAR_BITS >::getRestrictedRandomInt(max-min-1,state)) + min; \ +} \ +template<> a_type Random(a_type min, a_type max, RandomState& state) { \ + return max - static_cast(RandomIntRestrictor< sizeof(a_type)*STREFLOP_INTEGER_TYPES_CHAR_BITS >::getRestrictedRandomInt(max-min-1,state)); \ +} \ +template<> a_type Random(a_type min, a_type max, RandomState& state) { \ + return static_cast(RandomIntRestrictor< sizeof(a_type)*STREFLOP_INTEGER_TYPES_CHAR_BITS >::getRestrictedRandomInt(max-min-2,state)) + min + 1; \ +} +SPECIALIZE_RANDOM_FOR_TYPE(char,true) +SPECIALIZE_RANDOM_FOR_TYPE(unsigned char,false) +SPECIALIZE_RANDOM_FOR_TYPE(short,true) +SPECIALIZE_RANDOM_FOR_TYPE(unsigned short,false) +SPECIALIZE_RANDOM_FOR_TYPE(int,true) +SPECIALIZE_RANDOM_FOR_TYPE(unsigned int,false) +SPECIALIZE_RANDOM_FOR_TYPE(long,true) +SPECIALIZE_RANDOM_FOR_TYPE(unsigned long,false) +SPECIALIZE_RANDOM_FOR_TYPE(long long,true) +SPECIALIZE_RANDOM_FOR_TYPE(unsigned long long,false) + + +// Random for float types is even more dependent on size + + +/* + +EXPERIMENTAL: + + The ULP_Random functions use a uniform distribution in the ULP space. + This means, each possibly representable float is given exactly the same weight for the + random choice. This is an exponential scale where there are as many numbers between + successive powers of 2 (i.e as many numbers between 1 and 2 as there are between 1024 and 2048). + This effectively corresponds to the maximum machine precision, but it is unfortunately + not what one means by "uniform" in the traditional sense of the term (it is uniform in terms + of bit patterns, so for the computer!) + + Algorithm: treat floats as binary pattern, thanks to IEEE754 ordered property + => this gives a "range" like max-min for the integers, where the unit is ulp + => this gives the maximum precision for floats, because a random number is chosen between exactly how many + numbers can be represented with that float format in that range + + +#define SPECIALIZE_RANDOM_FOR_SIMPLE_ULP(X,Y) \ +Simple ULP_Random ## X ## Y(Simple min, Simple max) { \ + \ + // Convert to signed integer for quick test of bit sign \ + SizedInteger<32>::Type imin = *reinterpret_cast::Type*>(&min); \ + SizedInteger<32>::Type imax = *reinterpret_cast::Type*>(&max); \ + \ + // Infinity is a perfectly fine number, with a bit pattern contiguous to the min and max floats \ + // This makes sense if excluding bounds: RandomEE(-inf,+inf) returns a possible float at random \ + \ + // Rule out NaNs \ + if (imin&0x7fffffff > 0x7f800000) return SimpleNaN; \ + if (imax&0x7fffffff > 0x7f800000) return SimpleNaN; \ + \ + // Convert to 2-complement representation \ + if (imin<0) imin = 0x80000000 - imin; \ + if (imax<0) imax = 0x80000000 - imax; \ + \ + // Now magically get an integer at random in that range \ + // This gives EXACTLY one choice per representable float \ + // It is non-uniform in the float space, but uniform in the bit-pattern space \ + SizedInteger<32>::Type iret = Random ## X ## Y(imin,imax); \ + \ + // convert back to 2-complement to IEEE754 \ + if (iret<0) iret = 0x80000000 - iret; \ + \ + // cast to float \ + return *reinterpret_cast(&iret); \ +} +SPECIALIZE_RANDOM_FOR_SIMPLE_ULP(E,I) +SPECIALIZE_RANDOM_FOR_SIMPLE_ULP(E,E) +SPECIALIZE_RANDOM_FOR_SIMPLE_ULP(I,E) +SPECIALIZE_RANDOM_FOR_SIMPLE_ULP(I,I) +*/ + + +// Return a random float +template<> Simple Random(RandomState& state) { + // Generate bits + SizedUnsignedInteger<32>::Type ret = Accessor<32>::getRandomInt(state); + + // Discard NaNs and Inf, ignore sign + while ((ret & 0x7fffffff) >= 0x7f800000) ret = Accessor<32>::getRandomInt(state); + + // cast to float + return *reinterpret_cast(&ret); +} + +// Random in 1..2 - ideal IE case +template<> Simple Random12(RandomState& state) { + + // Get uniform number between 1 and 2 at max precision + + // Generate bits + SizedUnsignedInteger<32>::Type r12 = Accessor<32>::getRandomInt(state); + + // Simple precision keeps only 23 bits + r12 &= 0x007FFFFF; + + // Insert exponent so it's in the [1.0-2.0) range + r12 |= 0x3F800000; + + return *reinterpret_cast(&r12); +} + +// Random in 1..2 - near ideal EI case +template<> Simple Random12(RandomState& state) { + + // Get uniform number between 1 and 2 at max precision + + // Generate bits + SizedUnsignedInteger<32>::Type r12 = Accessor<32>::getRandomInt(state); + + // Simple precision keeps only 23 bits + r12 &= 0x007FFFFF; + + // Insert exponent so it's in the [1.0-2.0) range + r12 |= 0x3F800000; + + // Bitwise add 1 so it's in the (1.0-2.0] range + r12 += 1; + + return *reinterpret_cast(&r12); +} + +// Random in 1..2 - need to include both bounds +template<> Simple Random12(RandomState& state) { + + // Get uniform number between 1 and 2 at max precision + + // Generate bits + SizedUnsignedInteger<32>::Type r12 = Accessor<32>::getRandomInt(state); + + // Keep 2^23 + 1 possibilities, discard others + // Note: %= operator is nicely converted into reciprocal multiply and shift by compiler + r12 %= 0x00800001; + // Choose to avoid % operator by having about 1/2 chance of rejection. Not faster. +// while ((r12 &= 0x00FFFFFF) > 0x00800000) r12 = Accessor<32>::getRandomInt(state); + +/* could also use multiply by reciprocal and then find remainder. For div by 0x00800001: +; dividend: register other than EAX or memory location +MOV EAX, 0FFFFFE01h +MUL dividend +SHR EDX, 23 +; quotient now in EDX +*/ + + // bitwise add exponent so it's in the [1.0-2.0] range + r12 += 0x3F800000; + + return *reinterpret_cast(&r12); +} + +// Random in 1..2 - need to exclude both bounds +template<> Simple Random12(RandomState& state) { + + // Get uniform number between 1 and 2 at max precision + + // Generate bits + SizedUnsignedInteger<32>::Type r12 = Accessor<32>::getRandomInt(state); + + // Keep 2^23 - 1 possibilities + //r12 %= 0x007FFFFF; + // Choose to avoid % operator by having very small chance of rejection + // Could we find a branchless version for % by 2^N-1 ? + while ((r12 &= 0x007FFFFF) == 0x007FFFFF) r12 = Accessor<32>::getRandomInt(state); + + // bitwise add exponent so it's in the (1.0-2.0) range + r12 += 0x3F800001; + + return *reinterpret_cast(&r12); +} + + +///////// Double versions /////////// + +// Return a random float +template<> Double Random(RandomState& state) { + // Generate bits + SizedUnsignedInteger<64>::Type ret = Accessor<64>::getRandomInt(state); + + // Discard NaNs and Inf, ignore sign + while ((ret & 0x7fffffffffffffffULL) >= 0x7ff0000000000000ULL) ret = Accessor<64>::getRandomInt(state); + + // cast to Double + return *reinterpret_cast(&ret); +} + + +// Random in a 1..2 - ideal IE case +template<> Double Random12(RandomState& state) { + + // Get uniform number between 1 and 2 at max precision + + // Generate bits + SizedUnsignedInteger<64>::Type r12 = Accessor<64>::getRandomInt(state); + + // Double precision keeps only 52 bits + r12 &= 0x000FFFFFFFFFFFFFULL; + + // Insert exponent so it's in the [1.0-2.0) range + r12 |= 0x3FF0000000000000ULL; + + // scale from 1-2 interval to the desired interval + return *reinterpret_cast(&r12); +} + +// Random in a 1..2 - near ideal EI case +template<> Double Random12(RandomState& state) { + + // Get uniform number between 1 and 2 at max precision + + // Generate bits + SizedUnsignedInteger<64>::Type r12 = Accessor<64>::getRandomInt(state); + + // Double precision keeps only 52 bits + r12 &= 0x000FFFFFFFFFFFFFULL; + + // Insert exponent so it's in the [1.0-2.0) range + r12 |= 0x3FF0000000000000ULL; + + // Bitwise add 1 so it's in the (1.0-2.0] range + r12 += 1; + + // scale from 1-2 interval to the desired interval + return *reinterpret_cast(&r12); +} + +// Random in a 1..2 - need to include both bounds +template<> Double Random12(RandomState& state) { + + // Get uniform number between 1 and 2 at max precision + + // Generate bits + SizedUnsignedInteger<64>::Type r12 = Accessor<64>::getRandomInt(state); + + // Keep 2^52 + 1 possibilities + // See comment in Simple version + // allow %= only for 64-bit register machines +#if STREFLOP_RANDOM_GEN_SIZE == 64 + r12 %= 0x0010000000000001ULL; +#else + // Choose to avoid % operator by having about 1/2 chance of rejection. Is this faster? + while ((r12 &= 0x001FFFFFFFFFFFFFULL) > 0x0010000000000000ULL) r12 = Accessor<64>::getRandomInt(state); +#endif + + // bitwise add exponent so it's in the [1.0-2.0] range + r12 += 0x3FF0000000000000ULL; + + return *reinterpret_cast(&r12); +} + +// Random in a 1..2 - need to exclude both bounds +template<> Double Random12(RandomState& state) { + + // Get uniform number between 1 and 2 at max precision + + // Generate bits + SizedUnsignedInteger<64>::Type r12 = Accessor<64>::getRandomInt(state); + + // Keep 2^52 - 1 possibilities + // See comment in Simple version + // r12 %= 0x000FFFFFFFFFFFFFULL; + // Choose to avoid % operator by having very small chance of rejection + while ((r12 &= 0x000FFFFFFFFFFFFFULL) == 0x000FFFFFFFFFFFFFULL) r12 = Accessor<64>::getRandomInt(state); + + // bitwise add exponent so it's in the (1.0-2.0) range + r12 += 0x3FF0000000000001ULL; + + return *reinterpret_cast(&r12); +} + + +#ifdef Extended + +// little endian +#if __FLOAT_WORD_ORDER == 1234 + +/// Little endian is fine, always the same offsets whatever the memory model +template struct ExtendedConverter { + // Sign and exponent + static inline SizedUnsignedInteger<16>::Type* sexpPtr(Extended* e) { + return reinterpret_cast::Type*>(reinterpret_cast(e)+8); + } + // Mantissa + static inline SizedUnsignedInteger<64>::Type* mPtr(Extended* e) { + return reinterpret_cast::Type*>(e); + } +}; + +// Big endian +#elif __FLOAT_WORD_ORDER == 4321 +template struct ExtendedConverter { +} + +/// Extended is softfloat +template<> struct ExtendedConverter<10> { + // Sign and exponent + static inline SizedUnsignedInteger<16>::Type* sexpPtr(Extended* e) { + return reinterpret_cast::Type*>(e); + } + // Mantissa + static inline SizedUnsignedInteger<64>::Type* mPtr(Extended* e) { + return reinterpret_cast::Type*>(reinterpret_cast(e)+2); + } +}; + +/// Default gcc model for x87 - 32 bits (or with -m96bit-long-double) +template<> struct ExtendedConverter<12> { + // Sign and exponent + static inline SizedUnsignedInteger<16>::Type* sexpPtr(Extended* e) { + return reinterpret_cast::Type*>(reinterpret_cast(e)+2); + } + // Mantissa + static inline SizedUnsignedInteger<64>::Type* mPtr(Extended* e) { + return reinterpret_cast::Type*>(reinterpret_cast(e)+4); + } +}; + +/// Default gcc model for x87 - 64 bits (or with -m128bit-long-double) +template<> struct ExtendedConverter<16> { + // Sign and exponent + static inline SizedUnsignedInteger<16>::Type* sexpPtr(Extended* e) { + return reinterpret_cast::Type*>(reinterpret_cast(e)+6); + } + // Mantissa + static inline SizedUnsignedInteger<64>::Type* mPtr(Extended* e) { + return reinterpret_cast::Type*>(reinterpret_cast(e)+8); + } +}; +#else +#error unknown byte order +#endif + + +// Return a random float +template<> Extended Random(RandomState& state) { + // Work directly on Extended bits + Extended ret; + + // Generate 63 bits for the mantissa + *ExtendedConverter::mPtr(&ret) = Accessor<64>::getRandomInt(state); + + // Generate 16 bits for the exponent + *ExtendedConverter::sexpPtr(&ret) = Accessor<16>::getRandomInt(state); + + // Discard NaNs and Inf, ignore sign + while ((*ExtendedConverter::sexpPtr(&ret) & 0x7fff) == 0x7fff) + *ExtendedConverter::sexpPtr(&ret) = Accessor<16>::getRandomInt(state); + + // x87 extended format oddity: the first mantissa bit (always 1 for normal numbers) is visible, not hidden! + if ((*ExtendedConverter::sexpPtr(&ret) & 0x7fff) != 0) + *ExtendedConverter::mPtr(&ret) |= 0x8000000000000000ULL; + + return ret; +} + + +// Random in 1..2 - ideal IE case +template<> Extended Random12(RandomState& state) { + + // Get uniform number between 1 and 2 at max precision + + // Work directly on Extended bits + Extended r12; + + // Generate 63 bits for the mantissa + *ExtendedConverter::mPtr(&r12) = Accessor<64>::getRandomInt(state); + + // x87 extended format oddity: the first mantissa bit (always 1 for normal numbers) is visible, not hidden! + // Since in this case this is a number between 1 and 2, this bit has to be set explicitly + *ExtendedConverter::mPtr(&r12) |= 0x8000000000000000ULL; + + // Set exponent so it's in the [1.0-2.0) range + *ExtendedConverter::sexpPtr(&r12) = 0x3FFF; + + // scale from 1-2 interval to the desired interval + return r12; +} + +// Random in 1..2 - near ideal EI case +template<> Extended Random12(RandomState& state) { + + // Get uniform number between 1 and 2 at max precision + + // Work directly on Extended bits + Extended r12; + + // Generate 63 bits for the mantissa + *ExtendedConverter::mPtr(&r12) = Accessor<64>::getRandomInt(state); + + // x87 extended format oddity: the first mantissa bit (always 1 for normal numbers) is visible, not hidden! + // Since in this case this is a number between 1 and 2, this bit has to be set explicitly + *ExtendedConverter::mPtr(&r12) |= 0x8000000000000000LL; + + // Set exponent so it's in the (1.0-2.0] range + // Replace 1.0 by 2.0 + if (*ExtendedConverter::mPtr(&r12) == 0x8000000000000000LL) + *ExtendedConverter::sexpPtr(&r12) = 0x4000; + else + *ExtendedConverter::sexpPtr(&r12) = 0x3FFF; + + return r12; +} + +// Random in 1..2 - need to include both bounds +template<> Extended Random12(RandomState& state) { + + // Get uniform number between 1 and 2 at max precision + + // Work directly on Extended bits + Extended r12; + + // Generate 64 bits for the mantissa + do { + *ExtendedConverter::mPtr(&r12) = Accessor<64>::getRandomInt(state); + } + // Include both bounds : repeat the random get till it's in the desired range + // Keep the possibility for 2.0 in addition to all [1.0-2.0) + while (*ExtendedConverter::mPtr(&r12) > 0x8000000000000000LL); + + // Set exponent so it's in the [1.0-2.0] range + // Check if 2.0 was selected + if (*ExtendedConverter::mPtr(&r12) == 0x8000000000000000LL) + *ExtendedConverter::sexpPtr(&r12) = 0x4000; + // otherwise, set the correct mantissa bit and the correct exponent + else { + // x87 extended format oddity: the first mantissa bit (always 1 for normal numbers) is visible, not hidden! + // Since in this case this is a number between 1 and 2, this bit has to be set explicitly + *ExtendedConverter::mPtr(&r12) |= 0x8000000000000000LL; + *ExtendedConverter::sexpPtr(&r12) = 0x3FFF; + } + + return r12; +} + +// Random in 1..2 - need to exclude both bounds +template<> Extended Random12(RandomState& state) { + + // Get uniform number between 1 and 2 at max precision + + // Work directly on Extended bits + Extended r12; + + // Generate 63 bits for the mantissa + do { + *ExtendedConverter::mPtr(&r12) = Accessor<64>::getRandomInt(state); + // x87 extended format oddity: the first mantissa bit (always 1 for normal numbers) is visible, not hidden! + // Since in this case this is a number between 1 and 2, this bit has to be set explicitly + *ExtendedConverter::mPtr(&r12) |= 0x8000000000000000LL; + } + // Exclude both bounds : repeat the random get till it's in the desired range + // Remove the possibility for 1.0 compared to all [1.0-2.0) + while (*ExtendedConverter::mPtr(&r12) == 0x8000000000000000LL); + + // Set exponent so it's in the (1.0-2.0) range + *ExtendedConverter::sexpPtr(&r12) = 0x3FFF; + + // scale from 1-2 interval to the desired interval + return r12; +} + +#endif + +// This is a way to hide the implementation from the header +// And also to ensure there is only one template instanciation, instead of duplicating +// the code in all object files +template static inline FloatType NRandom_Generic(FloatType *secondary, RandomState& state) { + + FloatType x, y, d; + // Generate a point strictly inside the unit circle + do { + // Use IE as this is the most convenient for the generation, + // any will do since the bounds are rejected anyway by unit circle strict comparison + x = RandomIE(FloatType(-1.0), FloatType(1.0), state); + y = RandomIE(FloatType(-1.0), FloatType(1.0), state); + d = x*x + y*y; + } while (d>=FloatType(1.0)); + // Convert from x/y to uniform + FloatType conv = sqrt( FloatType(-2.0) * log(d) / d ); + // Use one result as secondary independent variable, if user wishes + if (secondary) *secondary = x * conv; + // return the other + return y * conv; +} + +// Specialize for the Float types declared in the header +template<> Simple NRandom(Simple *secondary, RandomState& state) { + return NRandom_Generic(secondary,state); +} + +/* +template<> Double NRandom(Double *secondary, RandomState& state) { + return NRandom_Generic(secondary,state); +} +#if defined(Extended) +template<> Extended NRandom(Extended *secondary, RandomState& state) { + return NRandom_Generic(secondary,state); +} +#endif +*/ + +// May save one mul +template static inline FloatType NRandom_Generic(FloatType mean, FloatType std_dev, FloatType *secondary, RandomState& state) { + + FloatType x, y, d; + // Generate a point strictly inside the unit circle + do { + // Use IE as this is the most convenient for the generation, + // any will do since the bounds are rejected anyway by unit circle strict comparison + x = RandomIE(FloatType(-1.0), FloatType(1.0), state); + y = RandomIE(FloatType(-1.0), FloatType(1.0), state); + d = x*x + y*y; + } while (d>=FloatType(1.0)); + // Convert from x/y to uniform + FloatType conv = sqrt( FloatType(-2.0) * log(d) / d ) * std_dev; + // Use one result as secondary independent variable, if user wishes + if (secondary) *secondary = x * conv + mean; + // return the other + return y * conv + mean; +} + +// Specialize for the Float types declared in the header +template<> Simple NRandom(Simple mean, Simple std_dev, Simple *secondary, RandomState& state) { + return NRandom_Generic(mean, std_dev, secondary,state); +} + +/* +template<> Double NRandom(Double mean, Double std_dev, Double *secondary, RandomState& state) { + return NRandom_Generic(mean, std_dev, secondary,state); +} +#if defined(Extended) +template<> Extended NRandom(Extended mean, Extended std_dev, Extended *secondary, RandomState& state) { + return NRandom_Generic(mean, std_dev, secondary,state); +} +#endif +*/ + +SizedUnsignedInteger<32>::Type RandomInit(RandomState& state) { + return RandomInit(SizedUnsignedInteger<32>::Type(time(0))); +} + +SizedUnsignedInteger<32>::Type RandomInit(SizedUnsignedInteger<32>::Type seed, RandomState& state) { + init_genrand(seed,state); + return state.seed; +} + +SizedUnsignedInteger<32>::Type RandomSeed(RandomState& state) { + return state.seed; +} + +// Default state holder, so single threaded applications don't bother setting up an object +RandomState DefaultRandomState; + +} // end streflop namespace diff --git a/source/shared_lib/sources/streflop/SMath.cpp b/source/shared_lib/sources/streflop/SMath.cpp new file mode 100644 index 000000000..749d61396 --- /dev/null +++ b/source/shared_lib/sources/streflop/SMath.cpp @@ -0,0 +1,44 @@ +// Includes Math.h in turn +#include "streflop.h" + +namespace streflop { + + // Constants + + const Simple SimpleZero(0.0f); + const Simple SimplePositiveInfinity = Simple(1.0f) / SimpleZero; + const Simple SimpleNegativeInfinity = Simple(-1.0f) / SimpleZero; + // TODO: non-signaling version + const Simple SimpleNaN = SimplePositiveInfinity + SimpleNegativeInfinity; + + const Double DoubleZero(0.0f); + const Double DoublePositiveInfinity = Double(1.0f) / DoubleZero; + const Double DoubleNegativeInfinity = Double(-1.0f) / DoubleZero; + // TODO: non-signaling version + const Double DoubleNaN = DoublePositiveInfinity + DoubleNegativeInfinity; + +// Extended are not always available +#ifdef Extended + + const Extended ExtendedZero(0.0f); + const Extended ExtendedPositiveInfinity = Extended(1.0f) / ExtendedZero; + const Extended ExtendedNegativeInfinity = Extended(-1.0f) / ExtendedZero; + // TODO: non-signaling version + const Extended ExtendedNaN = ExtendedPositiveInfinity + ExtendedNegativeInfinity; + +#endif + + + + // Default environment. Initalized to 0, and really set on first access +#if defined(STREFLOP_X87) + fenv_t FE_DFL_ENV = 0; +#elif defined(STREFLOP_SSE) + fenv_t FE_DFL_ENV = {0,0}; +#elif defined(STREFLOP_SOFT) + fenv_t FE_DFL_ENV = {42,0,0}; +#else +#error STREFLOP: Invalid combination or unknown FPU type. +#endif + +} diff --git a/source/shared_lib/sources/streflop/VERSION.txt b/source/shared_lib/sources/streflop/VERSION.txt new file mode 100644 index 000000000..3b04cfb60 --- /dev/null +++ b/source/shared_lib/sources/streflop/VERSION.txt @@ -0,0 +1 @@ +0.2 diff --git a/source/shared_lib/sources/streflop/libm/README.txt b/source/shared_lib/sources/streflop/libm/README.txt new file mode 100644 index 000000000..d460dcb21 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/README.txt @@ -0,0 +1,19 @@ +This directory contains (in addition to this file): + +- flt-32/ dbl-64/ ldbl-96/ headers/: These subdirectories are imported from the GNU libm automatically. Do not modify them manually. You may safely erase them and run the import.pl script again. The "clean-import" make target does just that. + +- import.pl: A perl script that takes as argument the location of a valid glibc-2.4 source directory. It will create the aforementioned subdirectories and convert the original libm files. The conversion mainly concerns removing external dependencies, and making the c files and constructs compilable with the streflop wrapper types. See the import.pl script itself for the full list of modifications. + +- Makefile: Instructions for compiling the subdirectories with the make command. You you re-use this as the basis for other build systems (like CMake, scons, etc.). + +- streflop_libm_bridge.h: Contains the definitions and other macros that are necessary to compile libm, in a streflop framework. These declarations were either done by external files, or by other parts of the glibc that were not imported. + +- e_expf.c: The float exp in e_expf.c uses doubles internally since revision 1.2 in the libm-ieee754 CVS attic! This is the slower, but purely float version, that is rolled back from the CVS attic. + +- w_expf.c: A wrapper to expf that replaces the libm wrapper by a wraper to the float only version. + +- (after compilation): flt-target dbl-target ldbl-target temporary files for the make process + +The original GNU libm is released under the GNU LGPL license, and so are these modifications. See the LGPL.txt in the parent streflop main directory. See also the comments at the beginning of each file for particular information, especially the Sun Microsystems disclaimer. + +If you import a version of glibc other than 2.4, please check the information there (in particular their LICENSES file) for potential inclusion of new files in the libm subdirectories that are used here. diff --git a/source/shared_lib/sources/streflop/libm/e_expf.c b/source/shared_lib/sources/streflop/libm/e_expf.c new file mode 100644 index 000000000..9816f9b11 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/e_expf.c @@ -0,0 +1,104 @@ +/* e_expf.c -- float version of e_exp.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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_expf.c,v 1.6 1996/04/08 15:43:43 phil Exp $"; +#endif + +#include "math.h" +#include "math_private.h" + +static const float huge = 1.0e+30f; + +#ifdef __STDC__ +static const float +#else +static float +#endif +one = 1.0f, +halF[2] = {0.5f,-0.5f,}, +twom100 = 7.8886090522e-31f, /* 2**-100=0x0d800000 */ +o_threshold= 8.8721679688e+01f, /* 0x42b17180 */ +u_threshold= -1.0397208405e+02f, /* 0xc2cff1b5 */ +ln2HI[2] ={ 6.9313812256e-01f, /* 0x3f317180 */ + -6.9313812256e-01f,}, /* 0xbf317180 */ +ln2LO[2] ={ 9.0580006145e-06f, /* 0x3717f7d1 */ + -9.0580006145e-06f,}, /* 0xb717f7d1 */ +invln2 = 1.4426950216e+00f, /* 0x3fb8aa3b */ +P1 = 1.6666667163e-01f, /* 0x3e2aaaab */ +P2 = -2.7777778450e-03f, /* 0xbb360b61 */ +P3 = 6.6137559770e-05f, /* 0x388ab355 */ +P4 = -1.6533901999e-06f, /* 0xb5ddea0e */ +P5 = 4.1381369442e-08f; /* 0x3331bb4c */ + +#ifdef __STDC__ + float __ieee754_expf(float x) /* default IEEE double exp */ +#else + float __ieee754_expf(x) /* default IEEE double exp */ + float x; +#endif +{ + float y,hi,lo,c,t; + int32_t k,xsb; + u_int32_t hx; + + GET_FLOAT_WORD(hx,x); + xsb = (hx>>31)&1; /* sign bit of x */ + hx &= 0x7fffffff; /* high word of |x| */ + + /* filter out non-finite argument */ + if(hx >= 0x42b17218) { /* if |x|>=88.721... */ + if(hx>0x7f800000) + return x+x; /* NaN */ + if(hx==0x7f800000) + return (xsb==0)? x:0.0f; /* exp(+-inf)={inf,0} */ + if(x > o_threshold) return huge*huge; /* overflow */ + if(x < u_threshold) return twom100*twom100; /* underflow */ + } + + /* argument reduction */ + if(hx > 0x3eb17218) { /* if |x| > 0.5 ln2 */ + if(hx < 0x3F851592) { /* and |x| < 1.5 ln2 */ + hi = x-ln2HI[xsb]; lo=ln2LO[xsb]; k = 1-xsb-xsb; + } else { + k = invln2*x+halF[xsb]; + t = k; + hi = x - t*ln2HI[0]; /* t*ln2HI is exact here */ + lo = t*ln2LO[0]; + } + x = hi - lo; + } + else if(hx < 0x31800000) { /* when |x|<2**-28 */ + if(huge+x>one) return one+x;/* trigger inexact */ + } + else k = 0; + + /* x is now in primary range */ + t = x*x; + c = x - t*(P1+t*(P2+t*(P3+t*(P4+t*P5)))); + if(k==0) return one-((x*c)/(c-(float)2.0f)-x); + else y = one-((lo-(x*c)/((float)2.0f-c))-hi); + if(k >= -125) { + u_int32_t hy; + GET_FLOAT_WORD(hy,y); + SET_FLOAT_WORD(y,hy+(k<<23)); /* add k to y's exponent */ + return y; + } else { + u_int32_t hy; + GET_FLOAT_WORD(hy,y); + SET_FLOAT_WORD(y,hy+((k+100)<<23)); /* add k to y's exponent */ + return y*twom100; + } +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/Makefile b/source/shared_lib/sources/streflop/libm/flt-32/Makefile new file mode 100644 index 000000000..f4bfb6592 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/Makefile @@ -0,0 +1,5 @@ +# Makefile automatically generated by import.pl +include ../../Makefile.common +CPPFLAGS += -I../headers -DLIBM_COMPILING_FLT32=1 +all: e_acosf.o e_acoshf.o e_asinf.o e_atan2f.o e_atanhf.o e_coshf.o e_exp2f.o e_expf.o e_fmodf.o e_gammaf_r.o e_hypotf.o e_j0f.o e_j1f.o e_jnf.o e_lgammaf_r.o e_log10f.o e_log2f.o e_logf.o e_powf.o e_rem_pio2f.o e_remainderf.o e_sinhf.o e_sqrtf.o k_cosf.o k_rem_pio2f.o k_sinf.o k_tanf.o s_asinhf.o s_atanf.o s_cbrtf.o s_ceilf.o s_copysignf.o s_cosf.o s_erff.o s_expm1f.o s_fabsf.o s_finitef.o s_floorf.o s_fpclassifyf.o s_frexpf.o s_ilogbf.o s_isinff.o s_isnanf.o s_ldexpf.o s_llrintf.o s_llroundf.o s_log1pf.o s_logbf.o s_lrintf.o s_lroundf.o s_modff.o s_nearbyintf.o s_nextafterf.o s_remquof.o s_rintf.o s_roundf.o s_scalblnf.o s_scalbnf.o s_signbitf.o s_sincosf.o s_sinf.o s_tanf.o s_tanhf.o s_truncf.o w_expf.o + echo 'flt-32 done!' diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_acosf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_acosf.cpp new file mode 100644 index 000000000..ca498a464 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_acosf.cpp @@ -0,0 +1,92 @@ +/* See the import.pl script for potential modifications */ +/* e_acosf.c -- Simple version of e_acos.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_acosf.c,v 1.5f 1995/05/12 04:57:16 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple +#else +static Simple +#endif +one = 1.0000000000e+00f, /* 0x3F800000 */ +pi = 3.1415925026e+00f, /* 0x40490fda */ +pio2_hi = 1.5707962513e+00f, /* 0x3fc90fda */ +pio2_lo = 7.5497894159e-08f, /* 0x33a22168 */ +pS0 = 1.6666667163e-01f, /* 0x3e2aaaab */ +pS1 = -3.2556581497e-01f, /* 0xbea6b090 */ +pS2 = 2.0121252537e-01f, /* 0x3e4e0aa8 */ +pS3 = -4.0055535734e-02f, /* 0xbd241146 */ +pS4 = 7.9153501429e-04f, /* 0x3a4f7f04 */ +pS5 = 3.4793309169e-05f, /* 0x3811ef08 */ +qS1 = -2.4033949375e+00f, /* 0xc019d139 */ +qS2 = 2.0209457874e+00f, /* 0x4001572d */ +qS3 = -6.8828397989e-01f, /* 0xbf303361 */ +qS4 = 7.7038154006e-02f; /* 0x3d9dc62e */ + +#ifdef __STDC__ + Simple __ieee754_acosf(Simple x) +#else + Simple __ieee754_acosf(x) + Simple x; +#endif +{ + Simple z,p,q,r,w,s,c,df; + int32_t hx,ix; + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix==0x3f800000) { /* |x|==1 */ + if(hx>0) return 0.0f; /* acos(1) = 0 */ + else return pi+(Simple)2.0f*pio2_lo; /* acos(-1)= pi */ + } else if(ix>0x3f800000) { /* |x| >= 1 */ + return (x-x)/(x-x); /* acos(|x|>1) is NaN */ + } + if(ix<0x3f000000) { /* |x| < 0.5f */ + if(ix<=0x23000000) return pio2_hi+pio2_lo;/*if|x|<2**-57*/ + z = x*x; + p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); + q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); + r = p/q; + return pio2_hi - (x - (pio2_lo-x*r)); + } else if (hx<0) { /* x < -0.5f */ + z = (one+x)*(Simple)0.5f; + p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); + q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); + s = __ieee754_sqrtf(z); + r = p/q; + w = r*s-pio2_lo; + return pi - (Simple)2.0f*(s+w); + } else { /* x > 0.5f */ + int32_t idf; + z = (one-x)*(Simple)0.5f; + s = __ieee754_sqrtf(z); + df = s; + GET_FLOAT_WORD(idf,df); + SET_FLOAT_WORD(df,idf&0xfffff000); + c = (z-df*df)/(s+df); + p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); + q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); + r = p/q; + w = r*s+c; + return (Simple)2.0f*(df+w); + } +} +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_acoshf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_acoshf.cpp new file mode 100644 index 000000000..a5914596b --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_acoshf.cpp @@ -0,0 +1,60 @@ +/* See the import.pl script for potential modifications */ +/* e_acoshf.c -- Simple version of e_acosh.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_acoshf.c,v 1.5f 1995/05/12 04:57:20 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple +#else +static Simple +#endif +one = 1.0f, +ln2 = 6.9314718246e-01f; /* 0x3f317218 */ + +#ifdef __STDC__ + Simple __ieee754_acoshf(Simple x) +#else + Simple __ieee754_acoshf(x) + Simple x; +#endif +{ + Simple t; + int32_t hx; + GET_FLOAT_WORD(hx,x); + if(hx<0x3f800000) { /* x < 1 */ + return (x-x)/(x-x); + } else if(hx >=0x4d800000) { /* x > 2**28 */ + if(hx >=0x7f800000) { /* x is inf of NaN */ + return x+x; + } else + return __ieee754_logf(x)+ln2; /* acosh(huge)=log(2x) */ + } else if (hx==0x3f800000) { + return 0.0f; /* acosh(1) = 0 */ + } else if (hx > 0x40000000) { /* 2**28 > x > 2 */ + t=x*x; + return __ieee754_logf((Simple)2.0f*x-one/(x+__ieee754_sqrtf(t-one))); + } else { /* 1 + and are incorporated herein by permission of the author. The author + reserves the right to distribute this material elsewhere under different + copying permissions. These modifications are distributed here under + the following terms: + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1f of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_asinf.c,v 1.5f 1995/05/12 04:57:25 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple +#else +static Simple +#endif +one = 1.0000000000e+00f, /* 0x3F800000 */ +huge = 1.000e+30f, + +pio2_hi = 1.57079637050628662109375f, +pio2_lo = -4.37113900018624283e-8f, +pio4_hi = 0.785398185253143310546875f, + +/* asin x = x + x^3 p(x^2) + -0.5f <= x <= 0.5f; + Peak relative error 4.8e-9f */ +p0 = 1.666675248e-1f, +p1 = 7.495297643e-2f, +p2 = 4.547037598e-2f, +p3 = 2.417951451e-2f, +p4 = 4.216630880e-2f; + +#ifdef __STDC__ + Simple __ieee754_asinf(Simple x) +#else + Simple __ieee754_asinf(x) + Simple x; +#endif +{ + Simple t,w,p,q,c,r,s; + int32_t hx,ix; + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix==0x3f800000) { + /* asin(1)=+-pi/2 with inexact */ + return x*pio2_hi+x*pio2_lo; + } else if(ix> 0x3f800000) { /* |x|>= 1 */ + return (x-x)/(x-x); /* asin(|x|>1) is NaN */ + } else if (ix<0x3f000000) { /* |x|<0.5f */ + if(ix<0x32000000) { /* if |x| < 2**-27 */ + if(huge+x>one) return x;/* return x with inexact if x!=0*/ + } else { + t = x*x; + w = t * (p0 + t * (p1 + t * (p2 + t * (p3 + t * p4)))); + return x+x*w; + } + } + /* 1> |x|>= 0.5f */ + w = one-fabsf(x); + t = w*0.5f; + p = t * (p0 + t * (p1 + t * (p2 + t * (p3 + t * p4)))); + s = __ieee754_sqrtf(t); + if(ix>=0x3F79999A) { /* if |x| > 0.975f */ + t = pio2_hi-(2.0f*(s+s*p)-pio2_lo); + } else { + int32_t iw; + w = s; + GET_FLOAT_WORD(iw,w); + SET_FLOAT_WORD(w,iw&0xfffff000); + c = (t-w*w)/(s+w); + r = p; + p = 2.0f*s*r-(pio2_lo-2.0f*c); + q = pio4_hi-2.0f*w; + t = pio4_hi-(p-q); + } + if(hx>0) return t; else return -t; +} +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_atan2f.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_atan2f.cpp new file mode 100644 index 000000000..6b69a7237 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_atan2f.cpp @@ -0,0 +1,108 @@ +/* See the import.pl script for potential modifications */ +/* e_atan2f.c -- Simple version of e_atan2.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_atan2f.c,v 1.4f 1995/05/10 20:44:53 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple +#else +static Simple +#endif +tiny = 1.0e-30f, +zero = 0.0f, +pi_o_4 = 7.8539818525e-01f, /* 0x3f490fdb */ +pi_o_2 = 1.5707963705e+00f, /* 0x3fc90fdb */ +pi = 3.1415927410e+00f, /* 0x40490fdb */ +pi_lo = -8.7422776573e-08f; /* 0xb3bbbd2e */ + +#ifdef __STDC__ + Simple __ieee754_atan2f(Simple y, Simple x) +#else + Simple __ieee754_atan2f(y,x) + Simple y,x; +#endif +{ + Simple z; + int32_t k,m,hx,hy,ix,iy; + + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + GET_FLOAT_WORD(hy,y); + iy = hy&0x7fffffff; + if((ix>0x7f800000)|| + (iy>0x7f800000)) /* x or y is NaN */ + return x+y; + if(hx==0x3f800000) return __atanf(y); /* x=1.0f */ + m = ((hy>>31)&1)|((hx>>30)&2); /* 2*sign(x)+sign(y) */ + + /* when y = 0 */ + if(iy==0) { + switch(m) { + case 0: + case 1: return y; /* atan(+-0,+anything)=+-0 */ + case 2: return pi+tiny;/* atan(+0,-anything) = pi */ + case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */ + } + } + /* when x = 0 */ + if(ix==0) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny; + + /* when x is INF */ + if(ix==0x7f800000) { + if(iy==0x7f800000) { + switch(m) { + case 0: return pi_o_4+tiny;/* atan(+INF,+INF) */ + case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */ + case 2: return (Simple)3.0f*pi_o_4+tiny;/*atan(+INF,-INF)*/ + case 3: return (Simple)-3.0f*pi_o_4-tiny;/*atan(-INF,-INF)*/ + } + } else { + switch(m) { + case 0: return zero ; /* atan(+...,+INF) */ + case 1: return -zero ; /* atan(-...,+INF) */ + case 2: return pi+tiny ; /* atan(+...,-INF) */ + case 3: return -pi-tiny ; /* atan(-...,-INF) */ + } + } + } + /* when y is INF */ + if(iy==0x7f800000) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny; + + /* compute y/x */ + k = (iy-ix)>>23; + if(k > 60) z=pi_o_2+(Simple)0.5f*pi_lo; /* |y/x| > 2**60 */ + else if(hx<0&&k<-60) z=0.0f; /* |y|/x < -2**60 */ + else z=__atanf(fabsf(y/x)); /* safe to do y/x */ + switch (m) { + case 0: return z ; /* atan(+,+) */ + case 1: { + u_int32_t zh; + GET_FLOAT_WORD(zh,z); + SET_FLOAT_WORD(z,zh ^ 0x80000000); + } + return z ; /* atan(-,+) */ + case 2: return pi-(z-pi_lo);/* atan(+,-) */ + default: /* case 3 */ + return (z-pi_lo)-pi;/* atan(-,-) */ + } +} +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_atanhf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_atanhf.cpp new file mode 100644 index 000000000..88474a899 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_atanhf.cpp @@ -0,0 +1,61 @@ +/* See the import.pl script for potential modifications */ +/* e_atanhf.c -- Simple version of e_atanh.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_atanhf.c,v 1.4f 1995/05/10 20:44:56 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple one = 1.0f, huge = 1e30f; +#else +static Simple one = 1.0f, huge = 1e30f; +#endif + +#ifdef __STDC__ +static const Simple zero = 0.0f; +#else +static Simple zero = 0.0f; +#endif + +#ifdef __STDC__ + Simple __ieee754_atanhf(Simple x) +#else + Simple __ieee754_atanhf(x) + Simple x; +#endif +{ + Simple t; + int32_t hx,ix; + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if (ix>0x3f800000) /* |x|>1 */ + return (x-x)/(x-x); + if(ix==0x3f800000) + return x/zero; + if(ix<0x31800000&&(huge+x)>zero) return x; /* x<2**-28 */ + SET_FLOAT_WORD(x,ix); + if(ix<0x3f000000) { /* x < 0.5f */ + t = x+x; + t = (Simple)0.5f*__log1pf(t+t*x/(one-x)); + } else + t = (Simple)0.5f*__log1pf((x+x)/(one-x)); + if(hx>=0) return t; else return -t; +} +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_coshf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_coshf.cpp new file mode 100644 index 000000000..02502acf8 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_coshf.cpp @@ -0,0 +1,75 @@ +/* See the import.pl script for potential modifications */ +/* e_coshf.c -- Simple version of e_cosh.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_coshf.c,v 1.6f 1996/04/08 15:43:41 phil Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple huge = 1.0e30f; +static const Simple one = 1.0f, half=0.5f; +#else +static Simple one = 1.0f, half=0.5f, huge = 1.0e30f; +#endif + +#ifdef __STDC__ + Simple __ieee754_coshf(Simple x) +#else + Simple __ieee754_coshf(x) + Simple x; +#endif +{ + Simple t,w; + int32_t ix; + + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; + + /* x is INF or NaN */ + if(ix>=0x7f800000) return x*x; + + /* |x| in [0,0.5f*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */ + if(ix<0x3eb17218) { + t = __expm1f(fabsf(x)); + w = one+t; + if (ix<0x24000000) return w; /* cosh(tiny) = 1 */ + return one+(t*t)/(w+w); + } + + /* |x| in [0.5f*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */ + if (ix < 0x41b00000) { + t = __ieee754_expf(fabsf(x)); + return half*t+half/t; + } + + /* |x| in [22, log(maxdouble)] return half*exp(|x|) */ + if (ix < 0x42b17180) return half*__ieee754_expf(fabsf(x)); + + /* |x| in [log(maxdouble), overflowthresold] */ + if (ix<=0x42b2d4fc) { + w = __ieee754_expf(half*fabsf(x)); + t = half*w; + return t*w; + } + + /* |x| > overflowthresold, cosh(x) overflow */ + return huge*huge; +} +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_exp2f.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_exp2f.cpp new file mode 100644 index 000000000..8432cdca7 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_exp2f.cpp @@ -0,0 +1,131 @@ +/* See the import.pl script for potential modifications */ +/* Single-precision floating point 2^x. + Copyright (C) 1997,1998,2000,2001,2005,2006 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Geoffrey Keating + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1f of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* The basic design here is from + Shmuel Gal and Boris Bachelis, "An Accurate Elementary Mathematical + Library for the IEEE Floating Point Standard", ACM Trans. Math. Soft., + 17 (1), March 1991, pp. 26-45. + It has been slightly modified to compute 2^x instead of e^x, and for + single-precision. + */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif +#include "../streflop_libm_bridge.h" +#include "../streflop_libm_bridge.h" +#include "ieee754.h" +#include "SMath.h" +#include "../streflop_libm_bridge.h" +#include "../streflop_libm_bridge.h" +#include "math_private.h" + +#include "t_exp2f.h" + +static const Simple TWOM100 = 7.88860905e-31f; +static const Simple TWO127 = 1.7014118346e+38f; + +namespace streflop_libm { +Simple +__ieee754_exp2f (Simple x) +{ + static const Simple himark = (Simple) FLT_MAX_EXP; + static const Simple lomark = (Simple) (FLT_MIN_EXP - FLT_MANT_DIG - 1); + + /* Check for usual case. */ + if (isless (x, himark) && isgreaterequal (x, lomark)) + { + static const Simple THREEp14 = 49152.0f; + int tval, unsafe; + Simple rx, x22, result; + union ieee754_float ex2_u, scale_u; + fenv_t oldenv; + + feholdexcept (&oldenv); +#ifdef FE_TONEAREST + /* If we don't have this, it's too bad. */ + fesetround (FE_TONEAREST); +#endif + + /* 1. Argument reduction. + Choose integers ex, -128 <= t < 128, and some real + -1/512 <= x1 <= 1/512 so that + x = ex + t/512 + x1. + + First, calculate rx = ex + t/256. */ + rx = x + THREEp14; + rx -= THREEp14; + x -= rx; /* Compute x=x1. */ + /* Compute tval = (ex*256 + t)+128. + Now, t = (tval mod 256)-128 and ex=tval/256 [that's mod, NOT %; and + /-round-to-nearest not the usual c integer /]. */ + tval = (int) (rx * 256.0f + 128.0f); + + /* 2. Adjust for accurate table entry. + Find e so that + x = ex + t/256 + e + x2 + where -7e-4 < e < 7e-4, and + (Simple)(2^(t/256+e)) + is accurate to one part in 2^-64. */ + + /* 'tval & 255' is the same as 'tval%256' except that it's always + positive. + Compute x = x2. */ + x -= __exp2f_deltatable[tval & 255]; + + /* 3. Compute ex2 = 2^(t/255+e+ex). */ + ex2_u.f() = __exp2f_atable[tval & 255]; + tval >>= 8; + unsafe = abs(tval) >= -FLT_MIN_EXP - 1; + ex2_u.ieee.exponent += tval >> unsafe; + scale_u.f() = 1.0f; + scale_u.ieee.exponent += tval - (tval >> unsafe); + + /* 4. Approximate 2^x2 - 1, using a second-degree polynomial, + with maximum error in [-2^-9 - 2^-14, 2^-9 + 2^-14] + less than 1.3e-10f. */ + + x22 = (.24022656679f * x + .69314736128f) * ex2_u.f(); + + /* 5. Return (2^x2-1) * 2^(t/512+e+ex) + 2^(t/512+e+ex). */ + fesetenv (&oldenv); + + result = x22 * x + ex2_u.f(); + + if (!unsafe) + return result; + else + return result * scale_u.f(); + } + /* Exceptional cases: */ + else if (isless (x, himark)) + { + if (__isinff (x)) + /* e^-inf == 0, with no error. */ + return 0; + else + /* Underflow */ + return TWOM100 * TWOM100; + } + else + /* Return x, if x is a NaN or Inf; or overflow, otherwise. */ + return TWO127*x; +} +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_expf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_expf.cpp new file mode 100644 index 000000000..1204263f3 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_expf.cpp @@ -0,0 +1,107 @@ +/* See the import.pl script for potential modifications */ +/* e_expf.c -- Simple version of e_exp.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_expf.c,v 1.6f 1996/04/08 15:43:43 phil Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +static const Simple huge = 1.0e+30f; + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple +#else +static Simple +#endif +one = 1.0f, +halF[2] = {0.5f,-0.5f,}, +twom100 = 7.8886090522e-31f, /* 2**-100=0x0d800000 */ +o_threshold= 8.8721679688e+01f, /* 0x42b17180 */ +u_threshold= -1.0397208405e+02f, /* 0xc2cff1b5 */ +ln2HI[2] ={ 6.9313812256e-01f, /* 0x3f317180 */ + -6.9313812256e-01f,}, /* 0xbf317180 */ +ln2LO[2] ={ 9.0580006145e-06f, /* 0x3717f7d1 */ + -9.0580006145e-06f,}, /* 0xb717f7d1 */ +invln2 = 1.4426950216e+00f, /* 0x3fb8aa3b */ +P1 = 1.6666667163e-01f, /* 0x3e2aaaab */ +P2 = -2.7777778450e-03f, /* 0xbb360b61 */ +P3 = 6.6137559770e-05f, /* 0x388ab355 */ +P4 = -1.6533901999e-06f, /* 0xb5ddea0e */ +P5 = 4.1381369442e-08f; /* 0x3331bb4c */ + +#ifdef __STDC__ + Simple __ieee754_expf(Simple x) /* default IEEE Double exp */ +#else + Simple __ieee754_expf(x) /* default IEEE Double exp */ + Simple x; +#endif +{ + Simple y,hi,lo,c,t; + int32_t k,xsb; + u_int32_t hx; + + GET_FLOAT_WORD(hx,x); + xsb = (hx>>31)&1; /* sign bit of x */ + hx &= 0x7fffffff; /* high word of |x| */ + + /* filter out non-finite argument */ + if(hx >= 0x42b17218) { /* if |x|>=88.721f... */ + if(hx>0x7f800000) + return x+x; /* NaN */ + if(hx==0x7f800000) + return (xsb==0)? x:Simple(0.0f); /* exp(+-inf)={inf,0} */ + if(x > o_threshold) return huge*huge; /* overflow */ + if(x < u_threshold) return twom100*twom100; /* underflow */ + } + + /* argument reduction */ + if(hx > 0x3eb17218) { /* if |x| > 0.5f ln2 */ + if(hx < 0x3F851592) { /* and |x| < 1.5f ln2 */ + hi = x-ln2HI[xsb]; lo=ln2LO[xsb]; k = 1-xsb-xsb; + } else { + k = invln2*x+halF[xsb]; + t = k; + hi = x - t*ln2HI[0]; /* t*ln2HI is exact here */ + lo = t*ln2LO[0]; + } + x = hi - lo; + } + else if(hx < 0x31800000) { /* when |x|<2**-28 */ + if(huge+x>one) return one+x;/* trigger inexact */ + } + else k = 0; + + /* x is now in primary range */ + t = x*x; + c = x - t*(P1+t*(P2+t*(P3+t*(P4+t*P5)))); + if(k==0) return one-((x*c)/(c-(Simple)2.0f)-x); + else y = one-((lo-(x*c)/((Simple)2.0f-c))-hi); + if(k >= -125) { + u_int32_t hy; + GET_FLOAT_WORD(hy,y); + SET_FLOAT_WORD(y,hy+(k<<23)); /* add k to y's exponent */ + return y; + } else { + u_int32_t hy; + GET_FLOAT_WORD(hy,y); + SET_FLOAT_WORD(y,hy+((k+100)<<23)); /* add k to y's exponent */ + return y*twom100; + } +} +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_fmodf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_fmodf.cpp new file mode 100644 index 000000000..b17437575 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_fmodf.cpp @@ -0,0 +1,116 @@ +/* See the import.pl script for potential modifications */ +/* e_fmodf.c -- Simple version of e_fmod.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_fmodf.c,v 1.4f 1995/05/10 20:45:10 jtc Exp $"; +#endif + +/* + * __ieee754_fmodf(x,y) + * Return x mod y in exact arithmetic + * Method: shift and subtract + */ + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple one = 1.0f, Zero[] = {0.0f, -0.0f,}; +#else +static Simple one = 1.0f, Zero[] = {0.0f, -0.0f,}; +#endif + +#ifdef __STDC__ + Simple __ieee754_fmodf(Simple x, Simple y) +#else + Simple __ieee754_fmodf(x,y) + Simple x,y ; +#endif +{ + int32_t n,hx,hy,hz,ix,iy,sx,i; + + GET_FLOAT_WORD(hx,x); + GET_FLOAT_WORD(hy,y); + sx = hx&0x80000000; /* sign of x */ + hx ^=sx; /* |x| */ + hy &= 0x7fffffff; /* |y| */ + + /* purge off exception values */ + if(hy==0||(hx>=0x7f800000)|| /* y=0,or x not finite */ + (hy>0x7f800000)) /* or y is NaN */ + return (x*y)/(x*y); + if(hx>31]; /* |x|=|y| return x*0*/ + + /* determine ix = ilogb(x) */ + if(hx<0x00800000) { /* subnormal x */ + for (ix = -126,i=(hx<<8); i>0; i<<=1) ix -=1; + } else ix = (hx>>23)-127; + + /* determine iy = ilogb(y) */ + if(hy<0x00800000) { /* subnormal y */ + for (iy = -126,i=(hy<<8); i>=0; i<<=1) iy -=1; + } else iy = (hy>>23)-127; + + /* set up {hx,lx}, {hy,ly} and align y to x */ + if(ix >= -126) + hx = 0x00800000|(0x007fffff&hx); + else { /* subnormal x, shift x to normal */ + n = -126-ix; + hx = hx<= -126) + hy = 0x00800000|(0x007fffff&hy); + else { /* subnormal y, shift y to normal */ + n = -126-iy; + hy = hy<>31]; + hx = hz+hz; + } + } + hz=hx-hy; + if(hz>=0) {hx=hz;} + + /* convert back to floating value and restore the sign */ + if(hx==0) /* return sign(x)*0 */ + return Zero[(u_int32_t)sx>>31]; + while(hx<0x00800000) { /* normalize x */ + hx = hx+hx; + iy -= 1; + } + if(iy>= -126) { /* normalize output */ + hx = ((hx-0x00800000)|((iy+127)<<23)); + SET_FLOAT_WORD(x,hx|sx); + } else { /* subnormal output */ + n = -126 - iy; + hx >>= n; + SET_FLOAT_WORD(x,hx|sx); + x *= one; /* create necessary signal */ + } + return x; /* exact output */ +} +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_gammaf_r.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_gammaf_r.cpp new file mode 100644 index 000000000..685c0d794 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_gammaf_r.cpp @@ -0,0 +1,59 @@ +/* See the import.pl script for potential modifications */ +/* Implementation of gamma function according to ISO C. + Copyright (C) 1997, 1999, 2001, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1f of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "SMath.h" +#include "math_private.h" + + +namespace streflop_libm { +Simple +__ieee754_gammaf_r (Simple x, int *signgamp) +{ + /* We don't have a real gamma implementation now. We'll use lgamma + and the exp function. But due to the required boundary + conditions we must check some values separately. */ + int32_t hx; + + GET_FLOAT_WORD (hx, x); + + if ((hx & 0x7fffffff) == 0) + { + /* Return value for x == 0 is Inf with divide by zero exception. */ + *signgamp = 0; + return 1.0f / x; + } + if (hx < 0 && (u_int32_t) hx < 0xff800000 && __rintf (x) == x) + { + /* Return value for integer x < 0 is NaN with invalid exception. */ + *signgamp = 0; + return (x - x) / (x - x); + } + if (hx == 0xff800000) + { + /* x == -Inf. According to ISO this is NaN. */ + *signgamp = 0; + return x - x; + } + + /* XXX FIXME. */ + return __ieee754_expf (__ieee754_lgammaf_r (x, signgamp)); +} +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_hypotf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_hypotf.cpp new file mode 100644 index 000000000..47c96ce56 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_hypotf.cpp @@ -0,0 +1,90 @@ +/* See the import.pl script for potential modifications */ +/* e_hypotf.c -- Simple version of e_hypot.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_hypotf.c,v 1.5f 1995/05/12 04:57:30 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ + Simple __ieee754_hypotf(Simple x, Simple y) +#else + Simple __ieee754_hypotf(x,y) + Simple x, y; +#endif +{ + Simple a,b,t1,t2,y1,y2,w; + int32_t j,k,ha,hb; + + GET_FLOAT_WORD(ha,x); + ha &= 0x7fffffff; + GET_FLOAT_WORD(hb,y); + hb &= 0x7fffffff; + if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;} + SET_FLOAT_WORD(a,ha); /* a <- |a| */ + SET_FLOAT_WORD(b,hb); /* b <- |b| */ + if((ha-hb)>0xf000000) {return a+b;} /* x/y > 2**30 */ + k=0; + if(ha > 0x58800000) { /* a>2**50 */ + if(ha >= 0x7f800000) { /* Inf or NaN */ + w = a+b; /* for sNaN */ + if(ha == 0x7f800000) w = a; + if(hb == 0x7f800000) w = b; + return w; + } + /* scale a and b by 2**-60 */ + ha -= 0x1e000000; hb -= 0x1e000000; k += 60; + SET_FLOAT_WORD(a,ha); + SET_FLOAT_WORD(b,hb); + } + if(hb < 0x26800000) { /* b < 2**-50 */ + if(hb <= 0x007fffff) { /* subnormal b or 0 */ + if(hb==0) return a; + SET_FLOAT_WORD(t1,0x7e800000); /* t1=2^126 */ + b *= t1; + a *= t1; + k -= 126; + } else { /* scale a and b by 2^60 */ + ha += 0x1e000000; /* a *= 2^60 */ + hb += 0x1e000000; /* b *= 2^60 */ + k -= 60; + SET_FLOAT_WORD(a,ha); + SET_FLOAT_WORD(b,hb); + } + } + /* medium size a and b */ + w = a-b; + if (w>b) { + SET_FLOAT_WORD(t1,ha&0xfffff000); + t2 = a-t1; + w = __ieee754_sqrtf(t1*t1-(b*(-b)-t2*(a+t1))); + } else { + a = a+a; + SET_FLOAT_WORD(y1,hb&0xfffff000); + y2 = b - y1; + SET_FLOAT_WORD(t1,ha+0x00800000); + t2 = a - t1; + w = __ieee754_sqrtf(t1*y1-(w*(-w)-(t1*y2+t2*b))); + } + if(k!=0) { + SET_FLOAT_WORD(t1,0x3f800000+(k<<23)); + return t1*w; + } else return w; +} +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_j0f.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_j0f.cpp new file mode 100644 index 000000000..7551062db --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_j0f.cpp @@ -0,0 +1,445 @@ +/* See the import.pl script for potential modifications */ +/* e_j0f.c -- Simple version of e_j0.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_j0f.c,v 1.4f 1995/05/10 20:45:25 jtc Exp $"; +#endif + +#include "math.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ +static Simple pzerof(Simple), qzerof(Simple); +#else +static Simple pzerof(), qzerof(); +#endif + +#ifdef __STDC__ +static const Simple +#else +static Simple +#endif +huge = 1e30f, +one = 1.0f, +invsqrtpi= 5.6418961287e-01f, /* 0x3f106ebb */ +tpi = 6.3661974669e-01f, /* 0x3f22f983 */ + /* R0/S0 on [0, 2.00f] */ +R02 = 1.5625000000e-02f, /* 0x3c800000 */ +R03 = -1.8997929874e-04f, /* 0xb947352e */ +R04 = 1.8295404516e-06f, /* 0x35f58e88 */ +R05 = -4.6183270541e-09f, /* 0xb19eaf3c */ +S01 = 1.5619102865e-02f, /* 0x3c7fe744 */ +S02 = 1.1692678527e-04f, /* 0x38f53697 */ +S03 = 5.1354652442e-07f, /* 0x3509daa6 */ +S04 = 1.1661400734e-09f; /* 0x30a045e8 */ + +#ifdef __STDC__ +static const Simple zero = 0.0f; +#else +static Simple zero = 0.0f; +#endif + +#ifdef __STDC__ + Simple __ieee754_j0f(Simple x) +#else + Simple __ieee754_j0f(x) + Simple x; +#endif +{ + Simple z, s,c,ss,cc,r,u,v; + int32_t hx,ix; + + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x7f800000) return one/(x*x); + x = fabsf(x); + if(ix >= 0x40000000) { /* |x| >= 2.0f */ + __sincosf (x, &s, &c); + ss = s-c; + cc = s+c; + if(ix<0x7f000000) { /* make sure x+x not overflow */ + z = -__cosf(x+x); + if ((s*c)0x48000000) z = (invsqrtpi*cc)/__ieee754_sqrtf(x); + else { + u = pzerof(x); v = qzerof(x); + z = invsqrtpi*(u*cc-v*ss)/__ieee754_sqrtf(x); + } + return z; + } + if(ix<0x39000000) { /* |x| < 2**-13 */ + if(huge+x>one) { /* raise inexact if x != 0 */ + if(ix<0x32000000) return one; /* |x|<2**-27 */ + else return one - (Simple)0.25f*x*x; + } + } + z = x*x; + r = z*(R02+z*(R03+z*(R04+z*R05))); + s = one+z*(S01+z*(S02+z*(S03+z*S04))); + if(ix < 0x3F800000) { /* |x| < 1.00f */ + return one + z*((Simple)-0.25f+(r/s)); + } else { + u = (Simple)0.5f*x; + return((one+u)*(one-u)+z*(r/s)); + } +} + +#ifdef __STDC__ +static const Simple +#else +static Simple +#endif +u00 = -7.3804296553e-02f, /* 0xbd9726b5 */ +u01 = 1.7666645348e-01f, /* 0x3e34e80d */ +u02 = -1.3818567619e-02f, /* 0xbc626746 */ +u03 = 3.4745343146e-04f, /* 0x39b62a69 */ +u04 = -3.8140706238e-06f, /* 0xb67ff53c */ +u05 = 1.9559013964e-08f, /* 0x32a802ba */ +u06 = -3.9820518410e-11f, /* 0xae2f21eb */ +v01 = 1.2730483897e-02f, /* 0x3c509385 */ +v02 = 7.6006865129e-05f, /* 0x389f65e0 */ +v03 = 2.5915085189e-07f, /* 0x348b216c */ +v04 = 4.4111031494e-10f; /* 0x2ff280c2 */ + +#ifdef __STDC__ + Simple __ieee754_y0f(Simple x) +#else + Simple __ieee754_y0f(x) + Simple x; +#endif +{ + Simple z, s,c,ss,cc,u,v; + int32_t hx,ix; + + GET_FLOAT_WORD(hx,x); + ix = 0x7fffffff&hx; + /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0, y0(0) is -inf. */ + if(ix>=0x7f800000) return one/(x+x*x); + if(ix==0) return -HUGE_VALF+x; /* -inf and overflow exception. */ + if(hx<0) return zero/(zero*x); + if(ix >= 0x40000000) { /* |x| >= 2.0f */ + /* y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x0)+q0(x)*cos(x0)) + * where x0 = x-pi/4 + * Better formula: + * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4) + * = 1/sqrt(2) * (sin(x) + cos(x)) + * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) + * = 1/sqrt(2) * (sin(x) - cos(x)) + * To avoid cancellation, use + * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) + * to compute the worse one. + */ + __sincosf (x, &s, &c); + ss = s-c; + cc = s+c; + /* + * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x) + * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x) + */ + if(ix<0x7f000000) { /* make sure x+x not overflow */ + z = -__cosf(x+x); + if ((s*c)0x48000000) z = (invsqrtpi*ss)/__ieee754_sqrtf(x); + else { + u = pzerof(x); v = qzerof(x); + z = invsqrtpi*(u*ss+v*cc)/__ieee754_sqrtf(x); + } + return z; + } + if(ix<=0x32000000) { /* x < 2**-27 */ + return(u00 + tpi*__ieee754_logf(x)); + } + z = x*x; + u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06))))); + v = one+z*(v01+z*(v02+z*(v03+z*v04))); + return(u/v + tpi*(__ieee754_j0f(x)*__ieee754_logf(x))); +} + +/* The asymptotic expansions of pzero is + * 1 - 9/128 s^2 + 11025/98304 s^4 - ..., where s = 1/x. + * For x >= 2, We approximate pzero by + * pzero(x) = 1 + (R/S) + * where R = pR0 + pR1*s^2 + pR2*s^4 + ... + pR5*s^10 + * S = 1 + pS0*s^2 + ... + pS4*s^10 + * and + * | pzero(x)-1-R/S | <= 2 ** ( -60.26f) + */ +#ifdef __STDC__ +static const Simple pR8[6] = { /* for x in [inf, 8]=1/[0,0.125f] */ +#else +static Simple pR8[6] = { /* for x in [inf, 8]=1/[0,0.125f] */ +#endif + 0.0000000000e+00f, /* 0x00000000 */ + -7.0312500000e-02f, /* 0xbd900000 */ + -8.0816707611e+00f, /* 0xc1014e86 */ + -2.5706311035e+02f, /* 0xc3808814 */ + -2.4852163086e+03f, /* 0xc51b5376 */ + -5.2530439453e+03f, /* 0xc5a4285a */ +}; +#ifdef __STDC__ +static const Simple pS8[5] = { +#else +static Simple pS8[5] = { +#endif + 1.1653436279e+02f, /* 0x42e91198 */ + 3.8337448730e+03f, /* 0x456f9beb */ + 4.0597855469e+04f, /* 0x471e95db */ + 1.1675296875e+05f, /* 0x47e4087c */ + 4.7627726562e+04f, /* 0x473a0bba */ +}; +#ifdef __STDC__ +static const Simple pR5[6] = { /* for x in [8,4.5454f]=1/[0.125f,0.22001f] */ +#else +static Simple pR5[6] = { /* for x in [8,4.5454f]=1/[0.125f,0.22001f] */ +#endif + -1.1412546255e-11f, /* 0xad48c58a */ + -7.0312492549e-02f, /* 0xbd8fffff */ + -4.1596107483e+00f, /* 0xc0851b88 */ + -6.7674766541e+01f, /* 0xc287597b */ + -3.3123129272e+02f, /* 0xc3a59d9b */ + -3.4643338013e+02f, /* 0xc3ad3779 */ +}; +#ifdef __STDC__ +static const Simple pS5[5] = { +#else +static Simple pS5[5] = { +#endif + 6.0753936768e+01f, /* 0x42730408 */ + 1.0512523193e+03f, /* 0x44836813 */ + 5.9789707031e+03f, /* 0x45bad7c4 */ + 9.6254453125e+03f, /* 0x461665c8 */ + 2.4060581055e+03f, /* 0x451660ee */ +}; + +#ifdef __STDC__ +static const Simple pR3[6] = {/* for x in [4.547f,2.8571f]=1/[0.2199f,0.35001f] */ +#else +static Simple pR3[6] = {/* for x in [4.547f,2.8571f]=1/[0.2199f,0.35001f] */ +#endif + -2.5470459075e-09f, /* 0xb12f081b */ + -7.0311963558e-02f, /* 0xbd8fffb8 */ + -2.4090321064e+00f, /* 0xc01a2d95 */ + -2.1965976715e+01f, /* 0xc1afba52 */ + -5.8079170227e+01f, /* 0xc2685112 */ + -3.1447946548e+01f, /* 0xc1fb9565 */ +}; +#ifdef __STDC__ +static const Simple pS3[5] = { +#else +static Simple pS3[5] = { +#endif + 3.5856033325e+01f, /* 0x420f6c94 */ + 3.6151397705e+02f, /* 0x43b4c1ca */ + 1.1936077881e+03f, /* 0x44953373 */ + 1.1279968262e+03f, /* 0x448cffe6 */ + 1.7358093262e+02f, /* 0x432d94b8 */ +}; + +#ifdef __STDC__ +static const Simple pR2[6] = {/* for x in [2.8570f,2]=1/[0.3499f,0.5f] */ +#else +static Simple pR2[6] = {/* for x in [2.8570f,2]=1/[0.3499f,0.5f] */ +#endif + -8.8753431271e-08f, /* 0xb3be98b7 */ + -7.0303097367e-02f, /* 0xbd8ffb12 */ + -1.4507384300e+00f, /* 0xbfb9b1cc */ + -7.6356959343e+00f, /* 0xc0f4579f */ + -1.1193166733e+01f, /* 0xc1331736 */ + -3.2336456776e+00f, /* 0xc04ef40d */ +}; +#ifdef __STDC__ +static const Simple pS2[5] = { +#else +static Simple pS2[5] = { +#endif + 2.2220300674e+01f, /* 0x41b1c32d */ + 1.3620678711e+02f, /* 0x430834f0 */ + 2.7047027588e+02f, /* 0x43873c32 */ + 1.5387539673e+02f, /* 0x4319e01a */ + 1.4657617569e+01f, /* 0x416a859a */ +}; + +#ifdef __STDC__ + static Simple pzerof(Simple x) +#else + static Simple pzerof(x) + Simple x; +#endif +{ +#ifdef __STDC__ + const Simple *p,*q; +#else + Simple *p,*q; +#endif + Simple z,r,s; + int32_t ix; + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; + if(ix>=0x41000000) {p = pR8; q= pS8;} + else if(ix>=0x40f71c58){p = pR5; q= pS5;} + else if(ix>=0x4036db68){p = pR3; q= pS3;} + else if(ix>=0x40000000){p = pR2; q= pS2;} + z = one/(x*x); + r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); + s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4])))); + return one+ r/s; +} + + +/* For x >= 8, the asymptotic expansions of qzero is + * -1/8 s + 75/1024 s^3 - ..., where s = 1/x. + * We approximate pzero by + * qzero(x) = s*(-1.25f + (R/S)) + * where R = qR0 + qR1*s^2 + qR2*s^4 + ... + qR5*s^10 + * S = 1 + qS0*s^2 + ... + qS5*s^12 + * and + * | qzero(x)/s +1.25f-R/S | <= 2 ** ( -61.22f) + */ +#ifdef __STDC__ +static const Simple qR8[6] = { /* for x in [inf, 8]=1/[0,0.125f] */ +#else +static Simple qR8[6] = { /* for x in [inf, 8]=1/[0,0.125f] */ +#endif + 0.0000000000e+00f, /* 0x00000000 */ + 7.3242187500e-02f, /* 0x3d960000 */ + 1.1768206596e+01f, /* 0x413c4a93 */ + 5.5767340088e+02f, /* 0x440b6b19 */ + 8.8591972656e+03f, /* 0x460a6cca */ + 3.7014625000e+04f, /* 0x471096a0 */ +}; +#ifdef __STDC__ +static const Simple qS8[6] = { +#else +static Simple qS8[6] = { +#endif + 1.6377603149e+02f, /* 0x4323c6aa */ + 8.0983447266e+03f, /* 0x45fd12c2 */ + 1.4253829688e+05f, /* 0x480b3293 */ + 8.0330925000e+05f, /* 0x49441ed4 */ + 8.4050156250e+05f, /* 0x494d3359 */ + -3.4389928125e+05f, /* 0xc8a7eb69 */ +}; + +#ifdef __STDC__ +static const Simple qR5[6] = { /* for x in [8,4.5454f]=1/[0.125f,0.22001f] */ +#else +static Simple qR5[6] = { /* for x in [8,4.5454f]=1/[0.125f,0.22001f] */ +#endif + 1.8408595828e-11f, /* 0x2da1ec79 */ + 7.3242180049e-02f, /* 0x3d95ffff */ + 5.8356351852e+00f, /* 0x40babd86 */ + 1.3511157227e+02f, /* 0x43071c90 */ + 1.0272437744e+03f, /* 0x448067cd */ + 1.9899779053e+03f, /* 0x44f8bf4b */ +}; +#ifdef __STDC__ +static const Simple qS5[6] = { +#else +static Simple qS5[6] = { +#endif + 8.2776611328e+01f, /* 0x42a58da0 */ + 2.0778142090e+03f, /* 0x4501dd07 */ + 1.8847289062e+04f, /* 0x46933e94 */ + 5.6751113281e+04f, /* 0x475daf1d */ + 3.5976753906e+04f, /* 0x470c88c1 */ + -5.3543427734e+03f, /* 0xc5a752be */ +}; + +#ifdef __STDC__ +static const Simple qR3[6] = {/* for x in [4.547f,2.8571f]=1/[0.2199f,0.35001f] */ +#else +static Simple qR3[6] = {/* for x in [4.547f,2.8571f]=1/[0.2199f,0.35001f] */ +#endif + 4.3774099900e-09f, /* 0x3196681b */ + 7.3241114616e-02f, /* 0x3d95ff70 */ + 3.3442313671e+00f, /* 0x405607e3 */ + 4.2621845245e+01f, /* 0x422a7cc5 */ + 1.7080809021e+02f, /* 0x432acedf */ + 1.6673394775e+02f, /* 0x4326bbe4 */ +}; +#ifdef __STDC__ +static const Simple qS3[6] = { +#else +static Simple qS3[6] = { +#endif + 4.8758872986e+01f, /* 0x42430916 */ + 7.0968920898e+02f, /* 0x44316c1c */ + 3.7041481934e+03f, /* 0x4567825f */ + 6.4604252930e+03f, /* 0x45c9e367 */ + 2.5163337402e+03f, /* 0x451d4557 */ + -1.4924745178e+02f, /* 0xc3153f59 */ +}; + +#ifdef __STDC__ +static const Simple qR2[6] = {/* for x in [2.8570f,2]=1/[0.3499f,0.5f] */ +#else +static Simple qR2[6] = {/* for x in [2.8570f,2]=1/[0.3499f,0.5f] */ +#endif + 1.5044444979e-07f, /* 0x342189db */ + 7.3223426938e-02f, /* 0x3d95f62a */ + 1.9981917143e+00f, /* 0x3fffc4bf */ + 1.4495602608e+01f, /* 0x4167edfd */ + 3.1666231155e+01f, /* 0x41fd5471 */ + 1.6252708435e+01f, /* 0x4182058c */ +}; +#ifdef __STDC__ +static const Simple qS2[6] = { +#else +static Simple qS2[6] = { +#endif + 3.0365585327e+01f, /* 0x41f2ecb8 */ + 2.6934811401e+02f, /* 0x4386ac8f */ + 8.4478375244e+02f, /* 0x44533229 */ + 8.8293585205e+02f, /* 0x445cbbe5 */ + 2.1266638184e+02f, /* 0x4354aa98 */ + -5.3109550476e+00f, /* 0xc0a9f358 */ +}; + +#ifdef __STDC__ + static Simple qzerof(Simple x) +#else + static Simple qzerof(x) + Simple x; +#endif +{ +#ifdef __STDC__ + const Simple *p,*q; +#else + Simple *p,*q; +#endif + Simple s,r,z; + int32_t ix; + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; + if(ix>=0x41000000) {p = qR8; q= qS8;} + else if(ix>=0x40f71c58){p = qR5; q= qS5;} + else if(ix>=0x4036db68){p = qR3; q= qS3;} + else if(ix>=0x40000000){p = qR2; q= qS2;} + z = one/(x*x); + r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); + s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5]))))); + return (-(Simple).125f + r/s)/x; +} +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_j1f.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_j1f.cpp new file mode 100644 index 000000000..321a54751 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_j1f.cpp @@ -0,0 +1,445 @@ +/* See the import.pl script for potential modifications */ +/* e_j1f.c -- Simple version of e_j1.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_j1f.c,v 1.4f 1995/05/10 20:45:31 jtc Exp $"; +#endif + +#include "math.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ +static Simple ponef(Simple), qonef(Simple); +#else +static Simple ponef(), qonef(); +#endif + +#ifdef __STDC__ +static const Simple +#else +static Simple +#endif +huge = 1e30f, +one = 1.0f, +invsqrtpi= 5.6418961287e-01f, /* 0x3f106ebb */ +tpi = 6.3661974669e-01f, /* 0x3f22f983 */ + /* R0/S0 on [0,2] */ +r00 = -6.2500000000e-02f, /* 0xbd800000 */ +r01 = 1.4070566976e-03f, /* 0x3ab86cfd */ +r02 = -1.5995563444e-05f, /* 0xb7862e36 */ +r03 = 4.9672799207e-08f, /* 0x335557d2 */ +s01 = 1.9153760746e-02f, /* 0x3c9ce859 */ +s02 = 1.8594678841e-04f, /* 0x3942fab6 */ +s03 = 1.1771846857e-06f, /* 0x359dffc2 */ +s04 = 5.0463624390e-09f, /* 0x31ad6446 */ +s05 = 1.2354227016e-11f; /* 0x2d59567e */ + +#ifdef __STDC__ +static const Simple zero = 0.0f; +#else +static Simple zero = 0.0f; +#endif + +#ifdef __STDC__ + Simple __ieee754_j1f(Simple x) +#else + Simple __ieee754_j1f(x) + Simple x; +#endif +{ + Simple z, s,c,ss,cc,r,u,v,y; + int32_t hx,ix; + + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x7f800000) return one/x; + y = fabsf(x); + if(ix >= 0x40000000) { /* |x| >= 2.0f */ + __sincosf (y, &s, &c); + ss = -s-c; + cc = s-c; + if(ix<0x7f000000) { /* make sure y+y not overflow */ + z = __cosf(y+y); + if ((s*c)>zero) cc = z/ss; + else ss = z/cc; + } + /* + * j1(x) = 1/sqrt(pi) * (P(1,x)*cc - Q(1,x)*ss) / sqrt(x) + * y1(x) = 1/sqrt(pi) * (P(1,x)*ss + Q(1,x)*cc) / sqrt(x) + */ + if(ix>0x48000000) z = (invsqrtpi*cc)/__ieee754_sqrtf(y); + else { + u = ponef(y); v = qonef(y); + z = invsqrtpi*(u*cc-v*ss)/__ieee754_sqrtf(y); + } + if(hx<0) return -z; + else return z; + } + if(ix<0x32000000) { /* |x|<2**-27 */ + if(huge+x>one) return (Simple)0.5f*x;/* inexact if x!=0 necessary */ + } + z = x*x; + r = z*(r00+z*(r01+z*(r02+z*r03))); + s = one+z*(s01+z*(s02+z*(s03+z*(s04+z*s05)))); + r *= x; + return(x*(Simple)0.5f+r/s); +} + +#ifdef __STDC__ +static const Simple U0[5] = { +#else +static Simple U0[5] = { +#endif + -1.9605709612e-01f, /* 0xbe48c331 */ + 5.0443872809e-02f, /* 0x3d4e9e3c */ + -1.9125689287e-03f, /* 0xbafaaf2a */ + 2.3525259166e-05f, /* 0x37c5581c */ + -9.1909917899e-08f, /* 0xb3c56003 */ +}; +#ifdef __STDC__ +static const Simple V0[5] = { +#else +static Simple V0[5] = { +#endif + 1.9916731864e-02f, /* 0x3ca3286a */ + 2.0255257550e-04f, /* 0x3954644b */ + 1.3560879779e-06f, /* 0x35b602d4 */ + 6.2274145840e-09f, /* 0x31d5f8eb */ + 1.6655924903e-11f, /* 0x2d9281cf */ +}; + +#ifdef __STDC__ + Simple __ieee754_y1f(Simple x) +#else + Simple __ieee754_y1f(x) + Simple x; +#endif +{ + Simple z, s,c,ss,cc,u,v; + int32_t hx,ix; + + GET_FLOAT_WORD(hx,x); + ix = 0x7fffffff&hx; + /* if Y1(NaN) is NaN, Y1(-inf) is NaN, Y1(inf) is 0 */ + if(ix>=0x7f800000) return one/(x+x*x); + if(ix==0) return -HUGE_VALF+x; /* -inf and overflow exception. */ + if(hx<0) return zero/(zero*x); + if(ix >= 0x40000000) { /* |x| >= 2.0f */ + __sincosf (x, &s, &c); + ss = -s-c; + cc = s-c; + if(ix<0x7f000000) { /* make sure x+x not overflow */ + z = __cosf(x+x); + if ((s*c)>zero) cc = z/ss; + else ss = z/cc; + } + /* y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x0)+q1(x)*cos(x0)) + * where x0 = x-3pi/4 + * Better formula: + * cos(x0) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4) + * = 1/sqrt(2) * (sin(x) - cos(x)) + * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) + * = -1/sqrt(2) * (cos(x) + sin(x)) + * To avoid cancellation, use + * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) + * to compute the worse one. + */ + if(ix>0x48000000) z = (invsqrtpi*ss)/__ieee754_sqrtf(x); + else { + u = ponef(x); v = qonef(x); + z = invsqrtpi*(u*ss+v*cc)/__ieee754_sqrtf(x); + } + return z; + } + if(ix<=0x24800000) { /* x < 2**-54 */ + return(-tpi/x); + } + z = x*x; + u = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4]))); + v = one+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4])))); + return(x*(u/v) + tpi*(__ieee754_j1f(x)*__ieee754_logf(x)-one/x)); +} + +/* For x >= 8, the asymptotic expansions of pone is + * 1 + 15/128 s^2 - 4725/2^15 s^4 - ..., where s = 1/x. + * We approximate pone by + * pone(x) = 1 + (R/S) + * where R = pr0 + pr1*s^2 + pr2*s^4 + ... + pr5*s^10 + * S = 1 + ps0*s^2 + ... + ps4*s^10 + * and + * | pone(x)-1-R/S | <= 2 ** ( -60.06f) + */ + +#ifdef __STDC__ +static const Simple pr8[6] = { /* for x in [inf, 8]=1/[0,0.125f] */ +#else +static Simple pr8[6] = { /* for x in [inf, 8]=1/[0,0.125f] */ +#endif + 0.0000000000e+00f, /* 0x00000000 */ + 1.1718750000e-01f, /* 0x3df00000 */ + 1.3239480972e+01f, /* 0x4153d4ea */ + 4.1205184937e+02f, /* 0x43ce06a3 */ + 3.8747453613e+03f, /* 0x45722bed */ + 7.9144794922e+03f, /* 0x45f753d6 */ +}; +#ifdef __STDC__ +static const Simple ps8[5] = { +#else +static Simple ps8[5] = { +#endif + 1.1420736694e+02f, /* 0x42e46a2c */ + 3.6509309082e+03f, /* 0x45642ee5 */ + 3.6956207031e+04f, /* 0x47105c35 */ + 9.7602796875e+04f, /* 0x47bea166 */ + 3.0804271484e+04f, /* 0x46f0a88b */ +}; + +#ifdef __STDC__ +static const Simple pr5[6] = { /* for x in [8,4.5454f]=1/[0.125f,0.22001f] */ +#else +static Simple pr5[6] = { /* for x in [8,4.5454f]=1/[0.125f,0.22001f] */ +#endif + 1.3199052094e-11f, /* 0x2d68333f */ + 1.1718749255e-01f, /* 0x3defffff */ + 6.8027510643e+00f, /* 0x40d9b023 */ + 1.0830818176e+02f, /* 0x42d89dca */ + 5.1763616943e+02f, /* 0x440168b7 */ + 5.2871520996e+02f, /* 0x44042dc6 */ +}; +#ifdef __STDC__ +static const Simple ps5[5] = { +#else +static Simple ps5[5] = { +#endif + 5.9280597687e+01f, /* 0x426d1f55 */ + 9.9140142822e+02f, /* 0x4477d9b1 */ + 5.3532670898e+03f, /* 0x45a74a23 */ + 7.8446904297e+03f, /* 0x45f52586 */ + 1.5040468750e+03f, /* 0x44bc0180 */ +}; + +#ifdef __STDC__ +static const Simple pr3[6] = { +#else +static Simple pr3[6] = {/* for x in [4.547f,2.8571f]=1/[0.2199f,0.35001f] */ +#endif + 3.0250391081e-09f, /* 0x314fe10d */ + 1.1718686670e-01f, /* 0x3defffab */ + 3.9329774380e+00f, /* 0x407bb5e7 */ + 3.5119403839e+01f, /* 0x420c7a45 */ + 9.1055007935e+01f, /* 0x42b61c2a */ + 4.8559066772e+01f, /* 0x42423c7c */ +}; +#ifdef __STDC__ +static const Simple ps3[5] = { +#else +static Simple ps3[5] = { +#endif + 3.4791309357e+01f, /* 0x420b2a4d */ + 3.3676245117e+02f, /* 0x43a86198 */ + 1.0468714600e+03f, /* 0x4482dbe3 */ + 8.9081134033e+02f, /* 0x445eb3ed */ + 1.0378793335e+02f, /* 0x42cf936c */ +}; + +#ifdef __STDC__ +static const Simple pr2[6] = {/* for x in [2.8570f,2]=1/[0.3499f,0.5f] */ +#else +static Simple pr2[6] = {/* for x in [2.8570f,2]=1/[0.3499f,0.5f] */ +#endif + 1.0771083225e-07f, /* 0x33e74ea8 */ + 1.1717621982e-01f, /* 0x3deffa16 */ + 2.3685150146e+00f, /* 0x401795c0 */ + 1.2242610931e+01f, /* 0x4143e1bc */ + 1.7693971634e+01f, /* 0x418d8d41 */ + 5.0735230446e+00f, /* 0x40a25a4d */ +}; +#ifdef __STDC__ +static const Simple ps2[5] = { +#else +static Simple ps2[5] = { +#endif + 2.1436485291e+01f, /* 0x41ab7dec */ + 1.2529022980e+02f, /* 0x42fa9499 */ + 2.3227647400e+02f, /* 0x436846c7 */ + 1.1767937469e+02f, /* 0x42eb5bd7 */ + 8.3646392822e+00f, /* 0x4105d590 */ +}; + +#ifdef __STDC__ + static Simple ponef(Simple x) +#else + static Simple ponef(x) + Simple x; +#endif +{ +#ifdef __STDC__ + const Simple *p,*q; +#else + Simple *p,*q; +#endif + Simple z,r,s; + int32_t ix; + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; + if(ix>=0x41000000) {p = pr8; q= ps8;} + else if(ix>=0x40f71c58){p = pr5; q= ps5;} + else if(ix>=0x4036db68){p = pr3; q= ps3;} + else if(ix>=0x40000000){p = pr2; q= ps2;} + z = one/(x*x); + r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); + s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4])))); + return one+ r/s; +} + + +/* For x >= 8, the asymptotic expansions of qone is + * 3/8 s - 105/1024 s^3 - ..., where s = 1/x. + * We approximate pone by + * qone(x) = s*(0.375f + (R/S)) + * where R = qr1*s^2 + qr2*s^4 + ... + qr5*s^10 + * S = 1 + qs1*s^2 + ... + qs6*s^12 + * and + * | qone(x)/s -0.375f-R/S | <= 2 ** ( -61.13f) + */ + +#ifdef __STDC__ +static const Simple qr8[6] = { /* for x in [inf, 8]=1/[0,0.125f] */ +#else +static Simple qr8[6] = { /* for x in [inf, 8]=1/[0,0.125f] */ +#endif + 0.0000000000e+00f, /* 0x00000000 */ + -1.0253906250e-01f, /* 0xbdd20000 */ + -1.6271753311e+01f, /* 0xc1822c8d */ + -7.5960174561e+02f, /* 0xc43de683 */ + -1.1849806641e+04f, /* 0xc639273a */ + -4.8438511719e+04f, /* 0xc73d3683 */ +}; +#ifdef __STDC__ +static const Simple qs8[6] = { +#else +static Simple qs8[6] = { +#endif + 1.6139537048e+02f, /* 0x43216537 */ + 7.8253862305e+03f, /* 0x45f48b17 */ + 1.3387534375e+05f, /* 0x4802bcd6 */ + 7.1965775000e+05f, /* 0x492fb29c */ + 6.6660125000e+05f, /* 0x4922be94 */ + -2.9449025000e+05f, /* 0xc88fcb48 */ +}; + +#ifdef __STDC__ +static const Simple qr5[6] = { /* for x in [8,4.5454f]=1/[0.125f,0.22001f] */ +#else +static Simple qr5[6] = { /* for x in [8,4.5454f]=1/[0.125f,0.22001f] */ +#endif + -2.0897993405e-11f, /* 0xadb7d219 */ + -1.0253904760e-01f, /* 0xbdd1fffe */ + -8.0564479828e+00f, /* 0xc100e736 */ + -1.8366960144e+02f, /* 0xc337ab6b */ + -1.3731937256e+03f, /* 0xc4aba633 */ + -2.6124443359e+03f, /* 0xc523471c */ +}; +#ifdef __STDC__ +static const Simple qs5[6] = { +#else +static Simple qs5[6] = { +#endif + 8.1276550293e+01f, /* 0x42a28d98 */ + 1.9917987061e+03f, /* 0x44f8f98f */ + 1.7468484375e+04f, /* 0x468878f8 */ + 4.9851425781e+04f, /* 0x4742bb6d */ + 2.7948074219e+04f, /* 0x46da5826 */ + -4.7191835938e+03f, /* 0xc5937978 */ +}; + +#ifdef __STDC__ +static const Simple qr3[6] = { +#else +static Simple qr3[6] = {/* for x in [4.547f,2.8571f]=1/[0.2199f,0.35001f] */ +#endif + -5.0783124372e-09f, /* 0xb1ae7d4f */ + -1.0253783315e-01f, /* 0xbdd1ff5b */ + -4.6101160049e+00f, /* 0xc0938612 */ + -5.7847221375e+01f, /* 0xc267638e */ + -2.2824453735e+02f, /* 0xc3643e9a */ + -2.1921012878e+02f, /* 0xc35b35cb */ +}; +#ifdef __STDC__ +static const Simple qs3[6] = { +#else +static Simple qs3[6] = { +#endif + 4.7665153503e+01f, /* 0x423ea91e */ + 6.7386511230e+02f, /* 0x4428775e */ + 3.3801528320e+03f, /* 0x45534272 */ + 5.5477290039e+03f, /* 0x45ad5dd5 */ + 1.9031191406e+03f, /* 0x44ede3d0 */ + -1.3520118713e+02f, /* 0xc3073381 */ +}; + +#ifdef __STDC__ +static const Simple qr2[6] = {/* for x in [2.8570f,2]=1/[0.3499f,0.5f] */ +#else +static Simple qr2[6] = {/* for x in [2.8570f,2]=1/[0.3499f,0.5f] */ +#endif + -1.7838172539e-07f, /* 0xb43f8932 */ + -1.0251704603e-01f, /* 0xbdd1f475 */ + -2.7522056103e+00f, /* 0xc0302423 */ + -1.9663616180e+01f, /* 0xc19d4f16 */ + -4.2325313568e+01f, /* 0xc2294d1f */ + -2.1371921539e+01f, /* 0xc1aaf9b2 */ +}; +#ifdef __STDC__ +static const Simple qs2[6] = { +#else +static Simple qs2[6] = { +#endif + 2.9533363342e+01f, /* 0x41ec4454 */ + 2.5298155212e+02f, /* 0x437cfb47 */ + 7.5750280762e+02f, /* 0x443d602e */ + 7.3939318848e+02f, /* 0x4438d92a */ + 1.5594900513e+02f, /* 0x431bf2f2 */ + -4.9594988823e+00f, /* 0xc09eb437 */ +}; + +#ifdef __STDC__ + static Simple qonef(Simple x) +#else + static Simple qonef(x) + Simple x; +#endif +{ +#ifdef __STDC__ + const Simple *p,*q; +#else + Simple *p,*q; +#endif + Simple s,r,z; + int32_t ix; + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; + if(ix>=0x40200000) {p = qr8; q= qs8;} + else if(ix>=0x40f71c58){p = qr5; q= qs5;} + else if(ix>=0x4036db68){p = qr3; q= qs3;} + else if(ix>=0x40000000){p = qr2; q= qs2;} + z = one/(x*x); + r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); + s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5]))))); + return ((Simple).375f + r/s)/x; +} +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_jnf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_jnf.cpp new file mode 100644 index 000000000..6a61c98b8 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_jnf.cpp @@ -0,0 +1,215 @@ +/* See the import.pl script for potential modifications */ +/* e_jnf.c -- Simple version of e_jn.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_jnf.c,v 1.5f 1995/05/10 20:45:37 jtc Exp $"; +#endif + +#include "math.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple +#else +static Simple +#endif +two = 2.0000000000e+00f, /* 0x40000000 */ +one = 1.0000000000e+00f; /* 0x3F800000 */ + +#ifdef __STDC__ +static const Simple zero = 0.0000000000e+00f; +#else +static Simple zero = 0.0000000000e+00f; +#endif + +#ifdef __STDC__ + Simple __ieee754_jnf(int n, Simple x) +#else + Simple __ieee754_jnf(n,x) + int n; Simple x; +#endif +{ + int32_t i,hx,ix, sgn; + Simple a, b, temp, di; + Simple z, w; + + /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x) + * Thus, J(-n,x) = J(n,-x) + */ + GET_FLOAT_WORD(hx,x); + ix = 0x7fffffff&hx; + /* if J(n,NaN) is NaN */ + if(ix>0x7f800000) return x+x; + if(n<0){ + n = -n; + x = -x; + hx ^= 0x80000000; + } + if(n==0) return(__ieee754_j0f(x)); + if(n==1) return(__ieee754_j1f(x)); + sgn = (n&1)&(hx>>31); /* even n -- 0, odd n -- sign(x) */ + x = fabsf(x); + if(ix==0||ix>=0x7f800000) /* if x is 0 or inf */ + b = zero; + else if((Simple)n<=x) { + /* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */ + a = __ieee754_j0f(x); + b = __ieee754_j1f(x); + for(i=1;i33) /* underflow */ + b = zero; + else { + temp = x*(Simple)0.5f; b = temp; + for (a=one,i=2;i<=n;i++) { + a *= (Simple)i; /* a = n! */ + b *= temp; /* b = (x/2)^n */ + } + b = b/a; + } + } else { + /* use backward recurrence */ + /* x x^2 x^2 + * J(n,x)/J(n-1,x) = ---- ------ ------ ..... + * 2n - 2(n+1) - 2(n+2) + * + * 1 1 1 + * (for large x) = ---- ------ ------ ..... + * 2n 2(n+1) 2(n+2) + * -- - ------ - ------ - + * x x x + * + * Let w = 2n/x and h=2/x, then the above quotient + * is equal to the continued fraction: + * 1 + * = ----------------------- + * 1 + * w - ----------------- + * 1 + * w+h - --------- + * w+2h - ... + * + * To determine how many terms needed, let + * Q(0) = w, Q(1) = w(w+h) - 1, + * Q(k) = (w+k*h)*Q(k-1) - Q(k-2), + * When Q(k) > 1e4 good for single + * When Q(k) > 1e9 good for Double + * When Q(k) > 1e17 good for quadruple + */ + /* determine k */ + Simple t,v; + Simple q0,q1,h,tmp; int32_t k,m; + w = (n+n)/(Simple)x; h = (Simple)2.0f/(Simple)x; + q0 = w; z = w+h; q1 = w*z - (Simple)1.0f; k=1; + while(q1<(Simple)1.0e9f) { + k += 1; z += h; + tmp = z*q1 - q0; + q0 = q1; + q1 = tmp; + } + m = n+n; + for(t=zero, i = 2*(n+k); i>=m; i -= 2) t = one/(i/x-t); + a = t; + b = one; + /* estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n) + * Hence, if n*(log(2n/x)) > ... + * single 8.8722839355e+01f + * Double 7.09782712893383973096e+02f + * Extended 1.1356523406294143949491931077970765006170e+04f + * then recurrent value may overflow and the result is + * likely underflow to zero + */ + tmp = n; + v = two/x; + tmp = tmp*__ieee754_logf(fabsf(v*tmp)); + if(tmp<(Simple)8.8721679688e+01f) { + for(i=n-1,di=(Simple)(i+i);i>0;i--){ + temp = b; + b *= di; + b = b/x - a; + a = temp; + di -= two; + } + } else { + for(i=n-1,di=(Simple)(i+i);i>0;i--){ + temp = b; + b *= di; + b = b/x - a; + a = temp; + di -= two; + /* scale b to avoid spurious overflow */ + if(b>(Simple)1e10f) { + a /= b; + t /= b; + b = one; + } + } + } + b = (t*__ieee754_j0f(x)/b); + } + } + if(sgn==1) return -b; else return b; +} + +#ifdef __STDC__ + Simple __ieee754_ynf(int n, Simple x) +#else + Simple __ieee754_ynf(n,x) + int n; Simple x; +#endif +{ + int32_t i,hx,ix; + u_int32_t ib; + int32_t sign; + Simple a, b, temp; + + GET_FLOAT_WORD(hx,x); + ix = 0x7fffffff&hx; + /* if Y(n,NaN) is NaN */ + if(ix>0x7f800000) return x+x; + if(ix==0) return -HUGE_VALF+x; /* -inf and overflow exception. */ + if(hx<0) return zero/(zero*x); + sign = 1; + if(n<0){ + n = -n; + sign = 1 - ((n&1)<<1); + } + if(n==0) return(__ieee754_y0f(x)); + if(n==1) return(sign*__ieee754_y1f(x)); + if(ix==0x7f800000) return zero; + + a = __ieee754_y0f(x); + b = __ieee754_y1f(x); + /* quit if b is -inf */ + GET_FLOAT_WORD(ib,b); + for(i=1;i0) return b; else return -b; +} +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_lgammaf_r.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_lgammaf_r.cpp new file mode 100644 index 000000000..b9f7d3d89 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_lgammaf_r.cpp @@ -0,0 +1,251 @@ +/* See the import.pl script for potential modifications */ +/* e_lgammaf_r.c -- Simple version of e_lgamma_r.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_lgammaf_r.c,v 1.3f 1995/05/10 20:45:47 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple +#else +static Simple +#endif +two23= 8.3886080000e+06f, /* 0x4b000000 */ +half= 5.0000000000e-01f, /* 0x3f000000 */ +one = 1.0000000000e+00f, /* 0x3f800000 */ +pi = 3.1415927410e+00f, /* 0x40490fdb */ +a0 = 7.7215664089e-02f, /* 0x3d9e233f */ +a1 = 3.2246702909e-01f, /* 0x3ea51a66 */ +a2 = 6.7352302372e-02f, /* 0x3d89f001 */ +a3 = 2.0580807701e-02f, /* 0x3ca89915 */ +a4 = 7.3855509982e-03f, /* 0x3bf2027e */ +a5 = 2.8905137442e-03f, /* 0x3b3d6ec6 */ +a6 = 1.1927076848e-03f, /* 0x3a9c54a1 */ +a7 = 5.1006977446e-04f, /* 0x3a05b634 */ +a8 = 2.2086278477e-04f, /* 0x39679767 */ +a9 = 1.0801156895e-04f, /* 0x38e28445 */ +a10 = 2.5214456400e-05f, /* 0x37d383a2 */ +a11 = 4.4864096708e-05f, /* 0x383c2c75 */ +tc = 1.4616321325e+00f, /* 0x3fbb16c3 */ +tf = -1.2148628384e-01f, /* 0xbdf8cdcd */ +/* tt = -(tail of tf) */ +tt = 6.6971006518e-09f, /* 0x31e61c52 */ +t0 = 4.8383611441e-01f, /* 0x3ef7b95e */ +t1 = -1.4758771658e-01f, /* 0xbe17213c */ +t2 = 6.4624942839e-02f, /* 0x3d845a15 */ +t3 = -3.2788541168e-02f, /* 0xbd064d47 */ +t4 = 1.7970675603e-02f, /* 0x3c93373d */ +t5 = -1.0314224288e-02f, /* 0xbc28fcfe */ +t6 = 6.1005386524e-03f, /* 0x3bc7e707 */ +t7 = -3.6845202558e-03f, /* 0xbb7177fe */ +t8 = 2.2596477065e-03f, /* 0x3b141699 */ +t9 = -1.4034647029e-03f, /* 0xbab7f476 */ +t10 = 8.8108185446e-04f, /* 0x3a66f867 */ +t11 = -5.3859531181e-04f, /* 0xba0d3085 */ +t12 = 3.1563205994e-04f, /* 0x39a57b6b */ +t13 = -3.1275415677e-04f, /* 0xb9a3f927 */ +t14 = 3.3552918467e-04f, /* 0x39afe9f7 */ +u0 = -7.7215664089e-02f, /* 0xbd9e233f */ +u1 = 6.3282704353e-01f, /* 0x3f2200f4 */ +u2 = 1.4549225569e+00f, /* 0x3fba3ae7 */ +u3 = 9.7771751881e-01f, /* 0x3f7a4bb2 */ +u4 = 2.2896373272e-01f, /* 0x3e6a7578 */ +u5 = 1.3381091878e-02f, /* 0x3c5b3c5e */ +v1 = 2.4559779167e+00f, /* 0x401d2ebe */ +v2 = 2.1284897327e+00f, /* 0x4008392d */ +v3 = 7.6928514242e-01f, /* 0x3f44efdf */ +v4 = 1.0422264785e-01f, /* 0x3dd572af */ +v5 = 3.2170924824e-03f, /* 0x3b52d5db */ +s0 = -7.7215664089e-02f, /* 0xbd9e233f */ +s1 = 2.1498242021e-01f, /* 0x3e5c245a */ +s2 = 3.2577878237e-01f, /* 0x3ea6cc7a */ +s3 = 1.4635047317e-01f, /* 0x3e15dce6 */ +s4 = 2.6642270386e-02f, /* 0x3cda40e4 */ +s5 = 1.8402845599e-03f, /* 0x3af135b4 */ +s6 = 3.1947532989e-05f, /* 0x3805ff67 */ +r1 = 1.3920053244e+00f, /* 0x3fb22d3b */ +r2 = 7.2193557024e-01f, /* 0x3f38d0c5 */ +r3 = 1.7193385959e-01f, /* 0x3e300f6e */ +r4 = 1.8645919859e-02f, /* 0x3c98bf54 */ +r5 = 7.7794247773e-04f, /* 0x3a4beed6 */ +r6 = 7.3266842264e-06f, /* 0x36f5d7bd */ +w0 = 4.1893854737e-01f, /* 0x3ed67f1d */ +w1 = 8.3333335817e-02f, /* 0x3daaaaab */ +w2 = -2.7777778450e-03f, /* 0xbb360b61 */ +w3 = 7.9365057172e-04f, /* 0x3a500cfd */ +w4 = -5.9518753551e-04f, /* 0xba1c065c */ +w5 = 8.3633989561e-04f, /* 0x3a5b3dd2 */ +w6 = -1.6309292987e-03f; /* 0xbad5c4e8 */ + +#ifdef __STDC__ +static const Simple zero= 0.0000000000e+00f; +#else +static Simple zero= 0.0000000000e+00f; +#endif + +#ifdef __STDC__ + static Simple sin_pif(Simple x) +#else + static Simple sin_pif(x) + Simple x; +#endif +{ + Simple y,z; + int n,ix; + + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; + + if(ix<0x3e800000) return __kernel_sinf(pi*x,zero,0); + y = -x; /* x is assume negative */ + + /* + * argument reduction, make sure inexact flag not raised if input + * is an integer + */ + z = __floorf(y); + if(z!=y) { /* inexact anyway */ + y *= (Simple)0.5f; + y = (Simple)2.0f*(y - __floorf(y)); /* y = |x| mod 2.0f */ + n = (int) (y*(Simple)4.0f); + } else { + if(ix>=0x4b800000) { + y = zero; n = 0; /* y must be even */ + } else { + if(ix<0x4b000000) z = y+two23; /* exact */ + GET_FLOAT_WORD(n,z); + n &= 1; + y = n; + n<<= 2; + } + } + switch (n) { + case 0: y = __kernel_sinf(pi*y,zero,0); break; + case 1: + case 2: y = __kernel_cosf(pi*((Simple)0.5f-y),zero); break; + case 3: + case 4: y = __kernel_sinf(pi*(one-y),zero,0); break; + case 5: + case 6: y = -__kernel_cosf(pi*(y-(Simple)1.5f),zero); break; + default: y = __kernel_sinf(pi*(y-(Simple)2.0f),zero,0); break; + } + return -y; +} + + +#ifdef __STDC__ + Simple __ieee754_lgammaf_r(Simple x, int *signgamp) +#else + Simple __ieee754_lgammaf_r(x,signgamp) + Simple x; int *signgamp; +#endif +{ + Simple t,y,z,nadj,p,p1,p2,p3,q,r,w; + int i,hx,ix; + + GET_FLOAT_WORD(hx,x); + + /* purge off +-inf, NaN, +-0, and negative arguments */ + *signgamp = 1; + ix = hx&0x7fffffff; + if(ix>=0x7f800000) return x*x; + if(ix==0) return one/fabsf(x); + if(ix<0x1c800000) { /* |x|<2**-70, return -log(|x|) */ + if(hx<0) { + *signgamp = -1; + return -__ieee754_logf(-x); + } else return -__ieee754_logf(x); + } + if(hx<0) { + if(ix>=0x4b000000) /* |x|>=2**23, must be -integer */ + return x/zero; + t = sin_pif(x); + if(t==zero) return one/fabsf(t); /* -integer */ + nadj = __ieee754_logf(pi/fabsf(t*x)); + if(t=0x3f3b4a20) {y = one-x; i= 0;} + else if(ix>=0x3e6d3308) {y= x-(tc-one); i=1;} + else {y = x; i=2;} + } else { + r = zero; + if(ix>=0x3fdda618) {y=(Simple)2.0f-x;i=0;} /* [1.7316f,2] */ + else if(ix>=0x3F9da620) {y=x-tc;i=1;} /* [1.23f,1.73f] */ + else {y=x-one;i=2;} + } + switch(i) { + case 0: + z = y*y; + p1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*a10)))); + p2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*a11))))); + p = y*p1+p2; + r += (p-(Simple)0.5f*y); break; + case 1: + z = y*y; + w = z*y; + p1 = t0+w*(t3+w*(t6+w*(t9 +w*t12))); /* parallel comp */ + p2 = t1+w*(t4+w*(t7+w*(t10+w*t13))); + p3 = t2+w*(t5+w*(t8+w*(t11+w*t14))); + p = z*p1-(tt-w*(p2+y*p3)); + r += (tf + p); break; + case 2: + p1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*u5))))); + p2 = one+y*(v1+y*(v2+y*(v3+y*(v4+y*v5)))); + r += (-(Simple)0.5f*y + p1/p2); + } + } + else if(ix<0x41000000) { /* x < 8.0f */ + i = (int)x; + t = zero; + y = x-(Simple)i; + p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6)))))); + q = one+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6))))); + r = half*y+p/q; + z = one; /* lgamma(1+s) = log(s) + lgamma(s) */ + switch(i) { + case 7: z *= (y+(Simple)6.0f); /* FALLTHRU */ + case 6: z *= (y+(Simple)5.0f); /* FALLTHRU */ + case 5: z *= (y+(Simple)4.0f); /* FALLTHRU */ + case 4: z *= (y+(Simple)3.0f); /* FALLTHRU */ + case 3: z *= (y+(Simple)2.0f); /* FALLTHRU */ + r += __ieee754_logf(z); break; + } + /* 8.0f <= x < 2**58 */ + } else if (ix < 0x5c800000) { + t = __ieee754_logf(x); + z = one/x; + y = z*z; + w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6))))); + r = (x-half)*(t-one)+w; + } else + /* 2**58 <= x <= inf */ + r = x*(__ieee754_logf(x)-one); + if(hx<0) r = nadj - r; + return r; +} +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_log10f.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_log10f.cpp new file mode 100644 index 000000000..6f1ba56a8 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_log10f.cpp @@ -0,0 +1,70 @@ +/* See the import.pl script for potential modifications */ +/* e_log10f.c -- Simple version of e_log10.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_log10f.c,v 1.5f 1995/05/10 20:45:53 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple +#else +static Simple +#endif +two25 = 3.3554432000e+07f, /* 0x4c000000 */ +ivln10 = 4.3429449201e-01f, /* 0x3ede5bd9 */ +log10_2hi = 3.0102920532e-01f, /* 0x3e9a2080 */ +log10_2lo = 7.9034151668e-07f; /* 0x355427db */ + +#ifdef __STDC__ +static const Simple zero = 0.0f; +#else +static Simple zero = 0.0f; +#endif + +#ifdef __STDC__ + Simple __ieee754_log10f(Simple x) +#else + Simple __ieee754_log10f(x) + Simple x; +#endif +{ + Simple y,z; + int32_t i,k,hx; + + GET_FLOAT_WORD(hx,x); + + k=0; + if (hx < 0x00800000) { /* x < 2**-126 */ + if ((hx&0x7fffffff)==0) + return -two25/(x-x); /* log(+-0)=-inf */ + if (hx<0) return (x-x)/(x-x); /* log(-#) = NaN */ + k -= 25; x *= two25; /* subnormal number, scale up x */ + GET_FLOAT_WORD(hx,x); + } + if (hx >= 0x7f800000) return x+x; + k += (hx>>23)-127; + i = ((u_int32_t)k&0x80000000)>>31; + hx = (hx&0x007fffff)|((0x7f-i)<<23); + y = (Simple)(k+i); + SET_FLOAT_WORD(x,hx); + z = y*log10_2lo + ivln10*__ieee754_logf(x); + return z+y*log10_2hi; +} +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_log2f.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_log2f.cpp new file mode 100644 index 000000000..26ad51963 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_log2f.cpp @@ -0,0 +1,93 @@ +/* See the import.pl script for potential modifications */ +/* e_logf.c -- Simple version of e_log.c. + * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + * adapted for log2 by Ulrich Drepper + */ + +/* + * ==================================================== + * 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 "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple +#else +static Simple +#endif +ln2 = 0.69314718055994530942f, +two25 = 3.355443200e+07f, /* 0x4c000000 */ +Lg1 = 6.6666668653e-01f, /* 3F2AAAAB */ +Lg2 = 4.0000000596e-01f, /* 3ECCCCCD */ +Lg3 = 2.8571429849e-01f, /* 3E924925 */ +Lg4 = 2.2222198546e-01f, /* 3E638E29 */ +Lg5 = 1.8183572590e-01f, /* 3E3A3325 */ +Lg6 = 1.5313838422e-01f, /* 3E1CD04F */ +Lg7 = 1.4798198640e-01f; /* 3E178897 */ + +#ifdef __STDC__ +static const Simple zero = 0.0f; +#else +static Simple zero = 0.0f; +#endif + +#ifdef __STDC__ + Simple __ieee754_log2f(Simple x) +#else + Simple __ieee754_log2f(x) + Simple x; +#endif +{ + Simple hfsq,f,s,z,R,w,t1,t2,dk; + int32_t k,ix,i,j; + + GET_FLOAT_WORD(ix,x); + + k=0; + if (ix < 0x00800000) { /* x < 2**-126 */ + if ((ix&0x7fffffff)==0) + return -two25/(x-x); /* log(+-0)=-inf */ + if (ix<0) return (x-x)/(x-x); /* log(-#) = NaN */ + k -= 25; x *= two25; /* subnormal number, scale up x */ + GET_FLOAT_WORD(ix,x); + } + if (ix >= 0x7f800000) return x+x; + k += (ix>>23)-127; + ix &= 0x007fffff; + i = (ix+(0x95f64<<3))&0x800000; + SET_FLOAT_WORD(x,ix|(i^0x3f800000)); /* normalize x or x/2 */ + k += (i>>23); + dk = (Simple)k; + f = x-(Simple)1.0f; + if((0x007fffff&(15+ix))<16) { /* |f| < 2**-20 */ + if(f==zero) return dk; + R = f*f*((Simple)0.5f-(Simple)0.33333333333333333f*f); + return dk-(R-f)/ln2; + } + s = f/((Simple)2.0f+f); + z = s*s; + i = ix-(0x6147a<<3); + w = z*z; + j = (0x6b851<<3)-ix; + t1= w*(Lg2+w*(Lg4+w*Lg6)); + t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); + i |= j; + R = t2+t1; + if(i>0) { + hfsq=(Simple)0.5f*f*f; + return dk-((hfsq-(s*(hfsq+R)))-f)/ln2; + } else { + return dk-((s*(f-R))-f)/ln2; + } +} +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_logf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_logf.cpp new file mode 100644 index 000000000..727d87690 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_logf.cpp @@ -0,0 +1,102 @@ +/* See the import.pl script for potential modifications */ +/* e_logf.c -- Simple version of e_log.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_logf.c,v 1.4f 1995/05/10 20:45:54 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple +#else +static Simple +#endif +ln2_hi = 6.9313812256e-01f, /* 0x3f317180 */ +ln2_lo = 9.0580006145e-06f, /* 0x3717f7d1 */ +two25 = 3.355443200e+07f, /* 0x4c000000 */ +Lg1 = 6.6666668653e-01f, /* 3F2AAAAB */ +Lg2 = 4.0000000596e-01f, /* 3ECCCCCD */ +Lg3 = 2.8571429849e-01f, /* 3E924925 */ +Lg4 = 2.2222198546e-01f, /* 3E638E29 */ +Lg5 = 1.8183572590e-01f, /* 3E3A3325 */ +Lg6 = 1.5313838422e-01f, /* 3E1CD04F */ +Lg7 = 1.4798198640e-01f; /* 3E178897 */ + +#ifdef __STDC__ +static const Simple zero = 0.0f; +#else +static Simple zero = 0.0f; +#endif + +#ifdef __STDC__ + Simple __ieee754_logf(Simple x) +#else + Simple __ieee754_logf(x) + Simple x; +#endif +{ + Simple hfsq,f,s,z,R,w,t1,t2,dk; + int32_t k,ix,i,j; + + GET_FLOAT_WORD(ix,x); + + k=0; + if (ix < 0x00800000) { /* x < 2**-126 */ + if ((ix&0x7fffffff)==0) + return -two25/(x-x); /* log(+-0)=-inf */ + if (ix<0) return (x-x)/(x-x); /* log(-#) = NaN */ + k -= 25; x *= two25; /* subnormal number, scale up x */ + GET_FLOAT_WORD(ix,x); + } + if (ix >= 0x7f800000) return x+x; + k += (ix>>23)-127; + ix &= 0x007fffff; + i = (ix+(0x95f64<<3))&0x800000; + SET_FLOAT_WORD(x,ix|(i^0x3f800000)); /* normalize x or x/2 */ + k += (i>>23); + f = x-(Simple)1.0f; + if((0x007fffff&(15+ix))<16) { /* |f| < 2**-20 */ + if(f==zero) { + if(k==0) return zero; else {dk=(Simple)k; + return dk*ln2_hi+dk*ln2_lo;} + } + R = f*f*((Simple)0.5f-(Simple)0.33333333333333333f*f); + if(k==0) return f-R; else {dk=(Simple)k; + return dk*ln2_hi-((R-dk*ln2_lo)-f);} + } + s = f/((Simple)2.0f+f); + dk = (Simple)k; + z = s*s; + i = ix-(0x6147a<<3); + w = z*z; + j = (0x6b851<<3)-ix; + t1= w*(Lg2+w*(Lg4+w*Lg6)); + t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); + i |= j; + R = t2+t1; + if(i>0) { + hfsq=(Simple)0.5f*f*f; + if(k==0) return f-(hfsq-s*(hfsq+R)); else + return dk*ln2_hi-((hfsq-(s*(hfsq+R)+dk*ln2_lo))-f); + } else { + if(k==0) return f-s*(f-R); else + return dk*ln2_hi-((s*(f-R)-dk*ln2_lo)-f); + } +} +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_powf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_powf.cpp new file mode 100644 index 000000000..f2cdddc31 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_powf.cpp @@ -0,0 +1,260 @@ +/* See the import.pl script for potential modifications */ +/* e_powf.c -- Simple version of e_pow.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_powf.c,v 1.7f 1996/04/08 15:43:44 phil Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +static const Simple huge = 1.0e+30f, tiny = 1.0e-30f; + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple +#else +static Simple +#endif +bp[] = {1.0f, 1.5f,}, +dp_h[] = { 0.0f, 5.84960938e-01f,}, /* 0x3f15c000 */ +dp_l[] = { 0.0f, 1.56322085e-06f,}, /* 0x35d1cfdc */ +zero = 0.0f, +one = 1.0f, +two = 2.0f, +two24 = 16777216.0f, /* 0x4b800000 */ + /* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */ +L1 = 6.0000002384e-01f, /* 0x3f19999a */ +L2 = 4.2857143283e-01f, /* 0x3edb6db7 */ +L3 = 3.3333334327e-01f, /* 0x3eaaaaab */ +L4 = 2.7272811532e-01f, /* 0x3e8ba305 */ +L5 = 2.3066075146e-01f, /* 0x3e6c3255 */ +L6 = 2.0697501302e-01f, /* 0x3e53f142 */ +P1 = 1.6666667163e-01f, /* 0x3e2aaaab */ +P2 = -2.7777778450e-03f, /* 0xbb360b61 */ +P3 = 6.6137559770e-05f, /* 0x388ab355 */ +P4 = -1.6533901999e-06f, /* 0xb5ddea0e */ +P5 = 4.1381369442e-08f, /* 0x3331bb4c */ +lg2 = 6.9314718246e-01f, /* 0x3f317218 */ +lg2_h = 6.93145752e-01f, /* 0x3f317200 */ +lg2_l = 1.42860654e-06f, /* 0x35bfbe8c */ +ovt = 4.2995665694e-08f, /* -(128-log2(ovfl+.5ulp)) */ +cp = 9.6179670095e-01f, /* 0x3f76384f =2/(3ln2) */ +cp_h = 9.6179199219e-01f, /* 0x3f763800 =head of cp */ +cp_l = 4.7017383622e-06f, /* 0x369dc3a0 =tail of cp_h */ +ivln2 = 1.4426950216e+00f, /* 0x3fb8aa3b =1/ln2 */ +ivln2_h = 1.4426879883e+00f, /* 0x3fb8aa00 =16b 1/ln2*/ +ivln2_l = 7.0526075433e-06f; /* 0x36eca570 =1/ln2 tail*/ + +#ifdef __STDC__ + Simple __ieee754_powf(Simple x, Simple y) +#else + Simple __ieee754_powf(x,y) + Simple x, y; +#endif +{ + Simple z,ax,z_h,z_l,p_h,p_l; + Simple y1,t1,t2,r,s,t,u,v,w; + int32_t i,j,k,yisint,n; + int32_t hx,hy,ix,iy,is; + + GET_FLOAT_WORD(hx,x); + GET_FLOAT_WORD(hy,y); + ix = hx&0x7fffffff; iy = hy&0x7fffffff; + + /* y==zero: x**0 = 1 */ + if(iy==0) return one; + + /* x==+-1 */ + if(x == 1.0f) return one; + if(x == -1.0f && isinf(y)) return one; + + /* +-NaN return x+y */ + if(ix > 0x7f800000 || + iy > 0x7f800000) + return x+y; + + /* 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>=0x4b800000) yisint = 2; /* even integer y */ + else if(iy>=0x3f800000) { + k = (iy>>23)-0x7f; /* exponent */ + j = iy>>(23-k); + if((j<<(23-k))==iy) yisint = 2-(j&1); + } + } + + /* special value of y */ + if (iy==0x7f800000) { /* y is +-inf */ + if (ix==0x3f800000) + return y - y; /* inf**+-1 is NaN */ + else if (ix > 0x3f800000)/* (|x|>1)**+-inf = inf,0 */ + return (hy>=0)? y: zero; + else /* (|x|<1)**-,+inf = inf,0 */ + return (hy<0)?-y: zero; + } + if(iy==0x3f800000) { /* y is +-1 */ + if(hy<0) return one/x; else return x; + } + if(hy==0x40000000) return x*x; /* y is 2 */ + if(hy==0x3f000000) { /* y is 0.5f */ + if(hx>=0) /* x >= +0 */ + return __ieee754_sqrtf(x); + } + + ax = fabsf(x); + /* special value of x */ + if(ix==0x7f800000||ix==0||ix==0x3f800000){ + z = ax; /*x is +-0,+-inf,+-1*/ + if(hy<0) z = one/z; /* z = (1/|x|) */ + if(hx<0) { + if(((ix-0x3f800000)|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; + } + + /* (x<0)**(non-int) is NaN */ + if(((((u_int32_t)hx>>31)-1)|yisint)==0) return (x-x)/(x-x); + + /* |y| is huge */ + if(iy>0x4d000000) { /* if |y| > 2**27 */ + /* over/underflow if x is not close to one */ + if(ix<0x3f7ffff8) return (hy<0)? huge*huge:tiny*tiny; + if(ix>0x3f800007) return (hy>0)? huge*huge:tiny*tiny; + /* now |1-x| is tiny <= 2**-20, suffice to compute + log(x) by x-x^2/2+x^3/3-x^4/4 */ + t = x-1; /* t has 20 trailing zeros */ + w = (t*t)*((Simple)0.5f-t*((Simple)0.333333333333f-t*(Simple)0.25f)); + u = ivln2_h*t; /* ivln2_h has 16 sig. bits */ + v = t*ivln2_l-w*ivln2; + t1 = u+v; + GET_FLOAT_WORD(is,t1); + SET_FLOAT_WORD(t1,is&0xfffff000); + t2 = v-(t1-u); + } else { + Simple s2,s_h,s_l,t_h,t_l; + n = 0; + /* take care subnormal number */ + if(ix<0x00800000) + {ax *= two24; n -= 24; GET_FLOAT_WORD(ix,ax); } + n += ((ix)>>23)-0x7f; + j = ix&0x007fffff; + /* determine interval */ + ix = j|0x3f800000; /* normalize ix */ + if(j<=0x1cc471) k=0; /* |x|>1)|0x20000000)+0x0040000+(k<<21)); + t_l = ax - (t_h-bp[k]); + s_l = v*((u-s_h*t_h)-s_h*t_l); + /* compute log(ax) */ + s2 = s*s; + r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6))))); + r += s_l*(s_h+s); + s2 = s_h*s_h; + t_h = (Simple)3.0f+s2+r; + GET_FLOAT_WORD(is,t_h); + SET_FLOAT_WORD(t_h,is&0xfffff000); + t_l = r-((t_h-(Simple)3.0f)-s2); + /* u+v = s*(1+...) */ + u = s_h*t_h; + v = s_l*t_h+t_l*s; + /* 2/(3log2)*(s+...) */ + p_h = u+v; + GET_FLOAT_WORD(is,p_h); + SET_FLOAT_WORD(p_h,is&0xfffff000); + 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) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */ + t = (Simple)n; + t1 = (((z_h+z_l)+dp_h[k])+t); + GET_FLOAT_WORD(is,t1); + SET_FLOAT_WORD(t1,is&0xfffff000); + t2 = z_l-(((t1-t)-dp_h[k])-z_h); + } + + s = one; /* s (sign of result -ve**odd) = -1 else = 1 */ + if(((((u_int32_t)hx>>31)-1)|(yisint-1))==0) + s = -one; /* (-ve)**(odd int) */ + + /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */ + GET_FLOAT_WORD(is,y); + SET_FLOAT_WORD(y1,is&0xfffff000); + p_l = (y-y1)*t1+y*t2; + p_h = y1*t1; + z = p_l+p_h; + GET_FLOAT_WORD(j,z); + if (j>0x43000000) /* if z > 128 */ + return s*huge*huge; /* overflow */ + else if (j==0x43000000) { /* if z == 128 */ + if(p_l+ovt>z-p_h) return s*huge*huge; /* overflow */ + } + else if ((j&0x7fffffff)>0x43160000) /* z <= -150 */ + return s*tiny*tiny; /* underflow */ + else if ((u_int32_t) j==0xc3160000){ /* z == -150 */ + if(p_l<=z-p_h) return s*tiny*tiny; /* underflow */ + } + /* + * compute 2**(p_h+p_l) + */ + i = j&0x7fffffff; + k = (i>>23)-0x7f; + n = 0; + if(i>0x3f000000) { /* if |z| > 0.5f, set n = [z+0.5f] */ + n = j+(0x00800000>>(k+1)); + k = ((n&0x7fffffff)>>23)-0x7f; /* new k for n */ + SET_FLOAT_WORD(t,n&~(0x007fffff>>k)); + n = ((n&0x007fffff)|0x00800000)>>(23-k); + if(j<0) n = -n; + p_h -= t; + } + t = p_l+p_h; + GET_FLOAT_WORD(is,t); + SET_FLOAT_WORD(t,is&0xfffff000); + 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_FLOAT_WORD(j,z); + j += (n<<23); + if((j>>23)<=0) z = __scalbnf(z,n); /* subnormal output */ + else SET_FLOAT_WORD(z,j); + return s*z; +} +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_rem_pio2f.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_rem_pio2f.cpp new file mode 100644 index 000000000..030cfcce8 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_rem_pio2f.cpp @@ -0,0 +1,199 @@ +/* See the import.pl script for potential modifications */ +/* e_rem_pio2f.c -- Simple version of e_rem_pio2.c + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_rem_pio2f.c,v 1.5f 1995/05/10 20:46:03 jtc Exp $"; +#endif + +/* __ieee754_rem_pio2f(x,y) + * + * return the remainder of x rem pi/2 in y[0]+y[1] + * use __kernel_rem_pio2f() + */ + +#include "SMath.h" +#include "math_private.h" + +/* + * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi + */ +namespace streflop_libm { +#ifdef __STDC__ +static const int32_t two_over_pi[] = { +#else +static int32_t two_over_pi[] = { +#endif +0xA2, 0xF9, 0x83, 0x6E, 0x4E, 0x44, 0x15, 0x29, 0xFC, +0x27, 0x57, 0xD1, 0xF5, 0x34, 0xDD, 0xC0, 0xDB, 0x62, +0x95, 0x99, 0x3C, 0x43, 0x90, 0x41, 0xFE, 0x51, 0x63, +0xAB, 0xDE, 0xBB, 0xC5, 0x61, 0xB7, 0x24, 0x6E, 0x3A, +0x42, 0x4D, 0xD2, 0xE0, 0x06, 0x49, 0x2E, 0xEA, 0x09, +0xD1, 0x92, 0x1C, 0xFE, 0x1D, 0xEB, 0x1C, 0xB1, 0x29, +0xA7, 0x3E, 0xE8, 0x82, 0x35, 0xF5, 0x2E, 0xBB, 0x44, +0x84, 0xE9, 0x9C, 0x70, 0x26, 0xB4, 0x5F, 0x7E, 0x41, +0x39, 0x91, 0xD6, 0x39, 0x83, 0x53, 0x39, 0xF4, 0x9C, +0x84, 0x5F, 0x8B, 0xBD, 0xF9, 0x28, 0x3B, 0x1F, 0xF8, +0x97, 0xFF, 0xDE, 0x05, 0x98, 0x0F, 0xEF, 0x2F, 0x11, +0x8B, 0x5A, 0x0A, 0x6D, 0x1F, 0x6D, 0x36, 0x7E, 0xCF, +0x27, 0xCB, 0x09, 0xB7, 0x4F, 0x46, 0x3F, 0x66, 0x9E, +0x5F, 0xEA, 0x2D, 0x75, 0x27, 0xBA, 0xC7, 0xEB, 0xE5, +0xF1, 0x7B, 0x3D, 0x07, 0x39, 0xF7, 0x8A, 0x52, 0x92, +0xEA, 0x6B, 0xFB, 0x5F, 0xB1, 0x1F, 0x8D, 0x5D, 0x08, +0x56, 0x03, 0x30, 0x46, 0xFC, 0x7B, 0x6B, 0xAB, 0xF0, +0xCF, 0xBC, 0x20, 0x9A, 0xF4, 0x36, 0x1D, 0xA9, 0xE3, +0x91, 0x61, 0x5E, 0xE6, 0x1B, 0x08, 0x65, 0x99, 0x85, +0x5F, 0x14, 0xA0, 0x68, 0x40, 0x8D, 0xFF, 0xD8, 0x80, +0x4D, 0x73, 0x27, 0x31, 0x06, 0x06, 0x15, 0x56, 0xCA, +0x73, 0xA8, 0xC9, 0x60, 0xE2, 0x7B, 0xC0, 0x8C, 0x6B, +}; + +/* This array is like the one in e_rem_pio2.c, but the numbers are + single precision and the last 8 bits are forced to 0. */ +#ifdef __STDC__ +static const int32_t npio2_hw[] = { +#else +static int32_t npio2_hw[] = { +#endif +0x3fc90f00, 0x40490f00, 0x4096cb00, 0x40c90f00, 0x40fb5300, 0x4116cb00, +0x412fed00, 0x41490f00, 0x41623100, 0x417b5300, 0x418a3a00, 0x4196cb00, +0x41a35c00, 0x41afed00, 0x41bc7e00, 0x41c90f00, 0x41d5a000, 0x41e23100, +0x41eec200, 0x41fb5300, 0x4203f200, 0x420a3a00, 0x42108300, 0x4216cb00, +0x421d1400, 0x42235c00, 0x4229a500, 0x422fed00, 0x42363600, 0x423c7e00, +0x4242c700, 0x42490f00 +}; + +/* + * invpio2: 24 bits of 2/pi + * pio2_1: first 17 bit of pi/2 + * pio2_1t: pi/2 - pio2_1 + * pio2_2: second 17 bit of pi/2 + * pio2_2t: pi/2 - (pio2_1+pio2_2) + * pio2_3: third 17 bit of pi/2 + * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3) + */ + +#ifdef __STDC__ +static const Simple +#else +static Simple +#endif +zero = 0.0000000000e+00f, /* 0x00000000 */ +half = 5.0000000000e-01f, /* 0x3f000000 */ +two8 = 2.5600000000e+02f, /* 0x43800000 */ +invpio2 = 6.3661980629e-01f, /* 0x3f22f984 */ +pio2_1 = 1.5707855225e+00f, /* 0x3fc90f80 */ +pio2_1t = 1.0804334124e-05f, /* 0x37354443 */ +pio2_2 = 1.0804273188e-05f, /* 0x37354400 */ +pio2_2t = 6.0770999344e-11f, /* 0x2e85a308 */ +pio2_3 = 6.0770943833e-11f, /* 0x2e85a300 */ +pio2_3t = 6.1232342629e-17f; /* 0x248d3132 */ + +#ifdef __STDC__ + int32_t __ieee754_rem_pio2f(Simple x, Simple *y) +#else + int32_t __ieee754_rem_pio2f(x,y) + Simple x,y[]; +#endif +{ + Simple z,w,t,r,fn; + Simple tx[3]; + int32_t e0,i,j,nx,n,ix,hx; + + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix<=0x3f490fd8) /* |x| ~<= pi/4 , no need for reduction */ + {y[0] = x; y[1] = 0; return 0;} + if(ix<0x4016cbe4) { /* |x| < 3pi/4, special case with n=+-1 */ + if(hx>0) { + z = x - pio2_1; + if((ix&0xfffffff0)!=0x3fc90fd0) { /* 24+24 bit pi OK */ + y[0] = z - pio2_1t; + y[1] = (z-y[0])-pio2_1t; + } else { /* near pi/2, use 24+24+24 bit pi */ + z -= pio2_2; + y[0] = z - pio2_2t; + y[1] = (z-y[0])-pio2_2t; + } + return 1; + } else { /* negative x */ + z = x + pio2_1; + if((ix&0xfffffff0)!=0x3fc90fd0) { /* 24+24 bit pi OK */ + y[0] = z + pio2_1t; + y[1] = (z-y[0])+pio2_1t; + } else { /* near pi/2, use 24+24+24 bit pi */ + z += pio2_2; + y[0] = z + pio2_2t; + y[1] = (z-y[0])+pio2_2t; + } + return -1; + } + } + if(ix<=0x43490f80) { /* |x| ~<= 2^7*(pi/2), medium size */ + t = fabsf(x); + n = (int32_t) (t*invpio2+half); + fn = (Simple)n; + r = t-fn*pio2_1; + w = fn*pio2_1t; /* 1st round good to 40 bit */ + if(n<32&&(int32_t)(ix&0xffffff00)!=npio2_hw[n-1]) { + y[0] = r-w; /* quick check no cancellation */ + } else { + u_int32_t high; + j = ix>>23; + y[0] = r-w; + GET_FLOAT_WORD(high,y[0]); + i = j-((high>>23)&0xff); + if(i>8) { /* 2nd iteration needed, good to 57 */ + t = r; + w = fn*pio2_2; + r = t-w; + w = fn*pio2_2t-((t-r)-w); + y[0] = r-w; + GET_FLOAT_WORD(high,y[0]); + i = j-((high>>23)&0xff); + if(i>25) { /* 3rd iteration need, 74 bits acc */ + t = r; /* will cover all possible cases */ + w = fn*pio2_3; + r = t-w; + w = fn*pio2_3t-((t-r)-w); + y[0] = r-w; + } + } + } + y[1] = (r-y[0])-w; + if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;} + else return n; + } + /* + * all other (large) arguments + */ + if(ix>=0x7f800000) { /* x is inf or NaN */ + y[0]=y[1]=x-x; return 0; + } + /* set z = scalbn(|x|,ilogb(x)-7) */ + e0 = (ix>>23)-134; /* e0 = ilogb(z)-7; */ + SET_FLOAT_WORD(z, ix - ((int32_t)(e0<<23))); + for(i=0;i<2;i++) { + tx[i] = (Simple)((int32_t)(z)); + z = (z-tx[i])*two8; + } + tx[2] = z; + nx = 3; + while(tx[nx-1]==zero) nx--; /* skip zero term */ + n = __kernel_rem_pio2f(tx,y,e0,nx,2,two_over_pi); + if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;} + return n; +} +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_remainderf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_remainderf.cpp new file mode 100644 index 000000000..c47001007 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_remainderf.cpp @@ -0,0 +1,76 @@ +/* See the import.pl script for potential modifications */ +/* e_remainderf.c -- Simple version of e_remainder.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_remainderf.c,v 1.4f 1995/05/10 20:46:08 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple zero = 0.0f; +#else +static Simple zero = 0.0f; +#endif + + +#ifdef __STDC__ + Simple __ieee754_remainderf(Simple x, Simple p) +#else + Simple __ieee754_remainderf(x,p) + Simple x,p; +#endif +{ + int32_t hx,hp; + u_int32_t sx; + Simple p_half; + + GET_FLOAT_WORD(hx,x); + GET_FLOAT_WORD(hp,p); + sx = hx&0x80000000; + hp &= 0x7fffffff; + hx &= 0x7fffffff; + + /* purge off exception values */ + if(hp==0) return (x*p)/(x*p); /* p = 0 */ + if((hx>=0x7f800000)|| /* x not finite */ + ((hp>0x7f800000))) /* p is NaN */ + return (x*p)/(x*p); + + + if (hp<=0x7effffff) x = __ieee754_fmodf(x,p+p); /* now x < 2p */ + if ((hx-hp)==0) return zero*x; + x = fabsf(x); + p = fabsf(p); + if (hp<0x01000000) { + if(x+x>p) { + x-=p; + if(x+x>=p) x -= p; + } + } else { + p_half = (Simple)0.5f*p; + if(x>p_half) { + x-=p; + if(x>=p_half) x -= p; + } + } + GET_FLOAT_WORD(hx,x); + SET_FLOAT_WORD(x,hx^sx); + return x; +} +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_sinhf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_sinhf.cpp new file mode 100644 index 000000000..b2adf65e1 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_sinhf.cpp @@ -0,0 +1,71 @@ +/* See the import.pl script for potential modifications */ +/* e_sinhf.c -- Simple version of e_sinh.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_sinhf.c,v 1.4f 1995/05/10 20:46:15 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple one = 1.0f, shuge = 1.0e37f; +#else +static Simple one = 1.0f, shuge = 1.0e37f; +#endif + +#ifdef __STDC__ + Simple __ieee754_sinhf(Simple x) +#else + Simple __ieee754_sinhf(x) + Simple x; +#endif +{ + Simple t,w,h; + int32_t ix,jx; + + GET_FLOAT_WORD(jx,x); + ix = jx&0x7fffffff; + + /* x is INF or NaN */ + if(ix>=0x7f800000) return x+x; + + h = 0.5f; + if (jx<0) h = -h; + /* |x| in [0,22], return sign(x)*0.5f*(E+E/(E+1))) */ + if (ix < 0x41b00000) { /* |x|<22 */ + if (ix<0x31800000) /* |x|<2**-28 */ + if(shuge+x>one) return x;/* sinh(tiny) = tiny with inexact */ + t = __expm1f(fabsf(x)); + if(ix<0x3f800000) return h*((Simple)2.0f*t-t*t/(t+one)); + return h*(t+t/(t+one)); + } + + /* |x| in [22, log(maxdouble)] return 0.5f*exp(|x|) */ + if (ix < 0x42b17180) return h*__ieee754_expf(fabsf(x)); + + /* |x| in [log(maxdouble), overflowthresold] */ + if (ix<=0x42b2d4fc) { + w = __ieee754_expf((Simple)0.5f*fabsf(x)); + t = h*w; + return t*w; + } + + /* |x| > overflowthresold, sinh(x) overflow */ + return x*shuge; +} +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_sqrtf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_sqrtf.cpp new file mode 100644 index 000000000..bb267c284 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_sqrtf.cpp @@ -0,0 +1,100 @@ +/* See the import.pl script for potential modifications */ +/* e_sqrtf.c -- Simple version of e_sqrt.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_sqrtf.c,v 1.4f 1995/05/10 20:46:19 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple one = 1.0f, tiny=1.0e-30f; +#else +static Simple one = 1.0f, tiny=1.0e-30f; +#endif + +#ifdef __STDC__ + Simple __ieee754_sqrtf(Simple x) +#else + Simple __ieee754_sqrtf(x) + Simple x; +#endif +{ + Simple z; + int32_t sign = (int)0x80000000; + int32_t ix,s,q,m,t,i; + u_int32_t r; + + GET_FLOAT_WORD(ix,x); + + /* take care of Inf and NaN */ + if((ix&0x7f800000)==0x7f800000) { + return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf + sqrt(-inf)=sNaN */ + } + /* take care of zero */ + if(ix<=0) { + if((ix&(~sign))==0) return x;/* sqrt(+-0) = +-0 */ + else if(ix<0) + return (x-x)/(x-x); /* sqrt(-ve) = sNaN */ + } + /* normalize x */ + m = (ix>>23); + if(m==0) { /* subnormal x */ + for(i=0;(ix&0x00800000)==0;i++) ix<<=1; + m -= i-1; + } + m -= 127; /* unbias exponent */ + ix = (ix&0x007fffff)|0x00800000; + if(m&1) /* odd m, Double x to make it even */ + ix += ix; + m >>= 1; /* m = [m/2] */ + + /* generate sqrt(x) bit by bit */ + ix += ix; + q = s = 0; /* q = sqrt(x) */ + r = 0x01000000; /* r = moving bit from right to left */ + + while(r!=0) { + t = s+r; + if(t<=ix) { + s = t+r; + ix -= t; + q += r; + } + ix += ix; + r>>=1; + } + + /* use floating add to find out rounding direction */ + if(ix!=0) { + z = one-tiny; /* trigger inexact flag */ + if (z>=one) { + z = one+tiny; + if (z>one) + q += 2; + else + q += (q&1); + } + } + ix = (q>>1)+0x3f000000; + ix += (m <<23); + SET_FLOAT_WORD(z,ix); + return z; +} +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/k_cosf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/k_cosf.cpp new file mode 100644 index 000000000..96607705d --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/k_cosf.cpp @@ -0,0 +1,67 @@ +/* See the import.pl script for potential modifications */ +/* k_cosf.c -- Simple version of k_cos.c + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: k_cosf.c,v 1.4f 1995/05/10 20:46:23 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple +#else +static Simple +#endif +one = 1.0000000000e+00f, /* 0x3f800000 */ +C1 = 4.1666667908e-02f, /* 0x3d2aaaab */ +C2 = -1.3888889225e-03f, /* 0xbab60b61 */ +C3 = 2.4801587642e-05f, /* 0x37d00d01 */ +C4 = -2.7557314297e-07f, /* 0xb493f27c */ +C5 = 2.0875723372e-09f, /* 0x310f74f6 */ +C6 = -1.1359647598e-11f; /* 0xad47d74e */ + +#ifdef __STDC__ + Simple __kernel_cosf(Simple x, Simple y) +#else + Simple __kernel_cosf(x, y) + Simple x,y; +#endif +{ + Simple a,hz,z,r,qx; + int32_t ix; + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; /* ix = |x|'s high word*/ + if(ix<0x32000000) { /* if x < 2**27 */ + if(((int)x)==0) return one; /* generate inexact */ + } + z = x*x; + r = z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*C6))))); + if(ix < 0x3e99999a) /* if |x| < 0.3f */ + return one - ((Simple)0.5f*z - (z*r - x*y)); + else { + if(ix > 0x3f480000) { /* x > 0.78125f */ + qx = (Simple)0.28125f; + } else { + SET_FLOAT_WORD(qx,ix-0x01000000); /* x/4 */ + } + hz = (Simple)0.5f*z-qx; + a = one-qx; + return a - (hz - (z*r-x*y)); + } +} +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/k_rem_pio2f.cpp b/source/shared_lib/sources/streflop/libm/flt-32/k_rem_pio2f.cpp new file mode 100644 index 000000000..73583bad7 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/k_rem_pio2f.cpp @@ -0,0 +1,216 @@ +/* See the import.pl script for potential modifications */ +/* k_rem_pio2f.c -- Simple version of k_rem_pio2.c + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: k_rem_pio2f.c,v 1.4f 1995/05/10 20:46:28 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +/* In the Simple version, the input parameter x contains 8 bit + integers, not 24 bit integers. 113 bit precision is not supported. */ + +namespace streflop_libm { +#ifdef __STDC__ +static const int init_jk[] = {4,7,9}; /* initial value for jk */ +#else +static int init_jk[] = {4,7,9}; +#endif + +#ifdef __STDC__ +static const Simple PIo2[] = { +#else +static Simple PIo2[] = { +#endif + 1.5703125000e+00f, /* 0x3fc90000 */ + 4.5776367188e-04f, /* 0x39f00000 */ + 2.5987625122e-05f, /* 0x37da0000 */ + 7.5437128544e-08f, /* 0x33a20000 */ + 6.0026650317e-11f, /* 0x2e840000 */ + 7.3896444519e-13f, /* 0x2b500000 */ + 5.3845816694e-15f, /* 0x27c20000 */ + 5.6378512969e-18f, /* 0x22d00000 */ + 8.3009228831e-20f, /* 0x1fc40000 */ + 3.2756352257e-22f, /* 0x1bc60000 */ + 6.3331015649e-25f, /* 0x17440000 */ +}; + +#ifdef __STDC__ +static const Simple +#else +static Simple +#endif +zero = 0.0f, +one = 1.0f, +two8 = 2.5600000000e+02f, /* 0x43800000 */ +twon8 = 3.9062500000e-03f; /* 0x3b800000 */ + +#ifdef __STDC__ + int __kernel_rem_pio2f(Simple *x, Simple *y, int e0, int nx, int prec, const int32_t *ipio2) +#else + int __kernel_rem_pio2f(x,y,e0,nx,prec,ipio2) + Simple x[], y[]; int e0,nx,prec; int32_t ipio2[]; +#endif +{ + int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih; + Simple 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)/8; if(jv<0) jv=0; + q0 = e0-8*(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)? zero : (Simple) ipio2[j]; + + /* compute q[0],q[1],...q[jk] */ + for (i=0;i<=jk;i++) { + for(j=0,fw=0.0f;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 = (Simple)((int32_t)(twon8* z)); + iq[i] = (int32_t)(z-two8*fw); + z = q[j-1]+fw; + } + + /* compute n */ + z = __scalbnf(z,q0); /* actual value of z */ + z -= (Simple)8.0f*__floorf(z*(Simple)0.125f); /* trim off integer >= 8 */ + n = (int32_t) z; + z -= (Simple)n; + ih = 0; + if(q0>0) { /* need iq[jz-1] to determine n */ + i = (iq[jz-1]>>(8-q0)); n += i; + iq[jz-1] -= i<<(8-q0); + ih = iq[jz-1]>>(7-q0); + } + else if(q0==0) ih = iq[jz-1]>>8; + else if(z>=(Simple)0.5f) ih=2; + + if(ih>0) { /* q > 0.5f */ + n += 1; carry = 0; + for(i=0;i0) { /* rare case: chance is 1 in 12 */ + switch(q0) { + case 1: + iq[jz-1] &= 0x7f; break; + case 2: + iq[jz-1] &= 0x3f; break; + } + } + if(ih==2) { + z = one - z; + if(carry!=0) z -= __scalbnf(one,q0); + } + } + + /* check if recomputation is needed */ + if(z==zero) { + 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] = (Simple) ipio2[jv+i]; + for(j=0,fw=0.0f;j<=jx;j++) fw += x[j]*f[jx+i-j]; + q[i] = fw; + } + jz += k; + goto recompute; + } + } + + /* chop off zero terms */ + if(z==(Simple)0.0f) { + jz -= 1; q0 -= 8; + while(iq[jz]==0) { jz--; q0-=8;} + } else { /* break z into 8-bit if necessary */ + z = __scalbnf(z,-q0); + if(z>=two8) { + fw = (Simple)((int32_t)(twon8*z)); + iq[jz] = (int32_t)(z-two8*fw); + jz += 1; q0 += 8; + iq[jz] = (int32_t) fw; + } else iq[jz] = (int32_t) z ; + } + + /* convert integer "bit" chunk to floating-point value */ + fw = __scalbnf(one,q0); + for(i=jz;i>=0;i--) { + q[i] = fw*(Simple)iq[i]; fw*=twon8; + } + + /* compute PIo2[0,...,jp]*q[jz,...,0] */ + for(i=jz;i>=0;i--) { + for(fw=0.0f,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.0f; + for (i=jz;i>=0;i--) fw += fq[i]; + y[0] = (ih==0)? fw: -fw; + break; + case 1: + case 2: + fw = 0.0f; + for (i=jz;i>=0;i--) fw += fq[i]; + 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.0f,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; +} +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/k_sinf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/k_sinf.cpp new file mode 100644 index 000000000..ed4d2be33 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/k_sinf.cpp @@ -0,0 +1,57 @@ +/* See the import.pl script for potential modifications */ +/* k_sinf.c -- Simple version of k_sin.c + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: k_sinf.c,v 1.4f 1995/05/10 20:46:33 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple +#else +static Simple +#endif +half = 5.0000000000e-01f,/* 0x3f000000 */ +S1 = -1.6666667163e-01f, /* 0xbe2aaaab */ +S2 = 8.3333337680e-03f, /* 0x3c088889 */ +S3 = -1.9841270114e-04f, /* 0xb9500d01 */ +S4 = 2.7557314297e-06f, /* 0x3638ef1b */ +S5 = -2.5050759689e-08f, /* 0xb2d72f34 */ +S6 = 1.5896910177e-10f; /* 0x2f2ec9d3 */ + +#ifdef __STDC__ + Simple __kernel_sinf(Simple x, Simple y, int iy) +#else + Simple __kernel_sinf(x, y, iy) + Simple x,y; int iy; /* iy=0 if y is zero */ +#endif +{ + Simple z,r,v; + int32_t ix; + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; /* high word of x */ + if(ix<0x32000000) /* |x| < 2**-27 */ + {if((int)x==0) return x;} /* generate inexact */ + z = x*x; + v = z*x; + r = S2+z*(S3+z*(S4+z*(S5+z*S6))); + if(iy==0) return x+v*(S1+z*r); + else return x-((z*(half*y-v*r)-y)-v*S1); +} +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/k_tanf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/k_tanf.cpp new file mode 100644 index 000000000..dec923d0b --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/k_tanf.cpp @@ -0,0 +1,104 @@ +/* See the import.pl script for potential modifications */ +/* k_tanf.c -- Simple version of k_tan.c + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: k_tanf.c,v 1.4f 1995/05/10 20:46:39 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" +namespace streflop_libm { +#ifdef __STDC__ +static const Simple +#else +static Simple +#endif +one = 1.0000000000e+00f, /* 0x3f800000 */ +pio4 = 7.8539812565e-01f, /* 0x3f490fda */ +pio4lo= 3.7748947079e-08f, /* 0x33222168 */ +T[] = { + 3.3333334327e-01f, /* 0x3eaaaaab */ + 1.3333334029e-01f, /* 0x3e088889 */ + 5.3968254477e-02f, /* 0x3d5d0dd1 */ + 2.1869488060e-02f, /* 0x3cb327a4 */ + 8.8632395491e-03f, /* 0x3c11371f */ + 3.5920790397e-03f, /* 0x3b6b6916 */ + 1.4562094584e-03f, /* 0x3abede48 */ + 5.8804126456e-04f, /* 0x3a1a26c8 */ + 2.4646313977e-04f, /* 0x398137b9 */ + 7.8179444245e-05f, /* 0x38a3f445 */ + 7.1407252108e-05f, /* 0x3895c07a */ + -1.8558637748e-05f, /* 0xb79bae5f */ + 2.5907305826e-05f, /* 0x37d95384 */ +}; + +#ifdef __STDC__ + Simple __kernel_tanf(Simple x, Simple y, int iy) +#else + Simple __kernel_tanf(x, y, iy) + Simple x,y; int iy; +#endif +{ + Simple z,r,v,w,s; + int32_t ix,hx; + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; /* high word of |x| */ + if(ix<0x31800000) /* x < 2**-28 */ + {if((int)x==0) { /* generate inexact */ + if((ix|(iy+1))==0) return one/fabsf(x); + else return (iy==1)? x: -one/x; + } + } + if(ix>=0x3f2ca140) { /* |x|>=0.6744f */ + if(hx<0) {x = -x; y = -y;} + z = pio4-x; + w = pio4lo-y; + x = z+w; y = 0.0f; + } + 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); + r += T[0]*s; + w = x+r; + if(ix>=0x3f2ca140) { + v = (Simple)iy; + return (Simple)(1-((hx>>30)&2))*(v-(Simple)2.0f*(x-(w*w/(w+v)-r))); + } + if(iy==1) return w; + else { /* if allow error up to 2 ulp, + simply return -1.0f/(x+r) here */ + /* compute -1.0f/(x+r) accurately */ + Simple a,t; + int32_t i; + z = w; + GET_FLOAT_WORD(i,z); + SET_FLOAT_WORD(z,i&0xfffff000); + v = r-(z - x); /* z+v = r+x */ + t = a = -(Simple)1.0f/w; /* a = -1.0f/w */ + GET_FLOAT_WORD(i,t); + SET_FLOAT_WORD(t,i&0xfffff000); + s = (Simple)1.0f+t*z; + return t+a*(s+t*v); + } +} +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_asinhf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_asinhf.cpp new file mode 100644 index 000000000..91fcec9d7 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_asinhf.cpp @@ -0,0 +1,61 @@ +/* See the import.pl script for potential modifications */ +/* s_asinhf.c -- Simple version of s_asinh.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_asinhf.c,v 1.5f 1995/05/12 04:57:39 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple +#else +static Simple +#endif +one = 1.0000000000e+00f, /* 0x3F800000 */ +ln2 = 6.9314718246e-01f, /* 0x3f317218 */ +huge= 1.0000000000e+30f; + +#ifdef __STDC__ + Simple __asinhf(Simple x) +#else + Simple __asinhf(x) + Simple x; +#endif +{ + Simple t,w; + int32_t hx,ix; + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x7f800000) return x+x; /* x is inf or NaN */ + if(ix< 0x38000000) { /* |x|<2**-14 */ + if(huge+x>one) return x; /* return x inexact except 0 */ + } + if(ix>0x47000000) { /* |x| > 2**14 */ + w = __ieee754_logf(fabsf(x))+ln2; + } else if (ix>0x40000000) { /* 2**14 > |x| > 2.0f */ + t = fabsf(x); + w = __ieee754_logf((Simple)2.0f*t+one/(__ieee754_sqrtf(x*x+one)+t)); + } else { /* 2.0f > |x| > 2**-14 */ + t = x*x; + w =__log1pf(fabsf(x)+t/(one+__ieee754_sqrtf(one+t))); + } + if(hx>0) return w; else return -w; +} +weak_alias (__asinhf, asinhf) +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_atanf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_atanf.cpp new file mode 100644 index 000000000..e8416dd91 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_atanf.cpp @@ -0,0 +1,123 @@ +/* See the import.pl script for potential modifications */ +/* s_atanf.c -- Simple version of s_atan.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_atanf.c,v 1.4f 1995/05/10 20:46:47 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple atanhi[] = { +#else +static Simple atanhi[] = { +#endif + 4.6364760399e-01f, /* atan(0.5f)hi 0x3eed6338 */ + 7.8539812565e-01f, /* atan(1.0f)hi 0x3f490fda */ + 9.8279368877e-01f, /* atan(1.5f)hi 0x3f7b985e */ + 1.5707962513e+00f, /* atan(inf)hi 0x3fc90fda */ +}; + +#ifdef __STDC__ +static const Simple atanlo[] = { +#else +static Simple atanlo[] = { +#endif + 5.0121582440e-09f, /* atan(0.5f)lo 0x31ac3769 */ + 3.7748947079e-08f, /* atan(1.0f)lo 0x33222168 */ + 3.4473217170e-08f, /* atan(1.5f)lo 0x33140fb4 */ + 7.5497894159e-08f, /* atan(inf)lo 0x33a22168 */ +}; + +#ifdef __STDC__ +static const Simple aT[] = { +#else +static Simple aT[] = { +#endif + 3.3333334327e-01f, /* 0x3eaaaaaa */ + -2.0000000298e-01f, /* 0xbe4ccccd */ + 1.4285714924e-01f, /* 0x3e124925 */ + -1.1111110449e-01f, /* 0xbde38e38 */ + 9.0908870101e-02f, /* 0x3dba2e6e */ + -7.6918758452e-02f, /* 0xbd9d8795 */ + 6.6610731184e-02f, /* 0x3d886b35 */ + -5.8335702866e-02f, /* 0xbd6ef16b */ + 4.9768779427e-02f, /* 0x3d4bda59 */ + -3.6531571299e-02f, /* 0xbd15a221 */ + 1.6285819933e-02f, /* 0x3c8569d7 */ +}; + +#ifdef __STDC__ + static const Simple +#else + static Simple +#endif +one = 1.0f, +huge = 1.0e30f; + +#ifdef __STDC__ + Simple __atanf(Simple x) +#else + Simple __atanf(x) + Simple x; +#endif +{ + Simple w,s1,s2,z; + int32_t ix,hx,id; + + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x50800000) { /* if |x| >= 2^34 */ + if(ix>0x7f800000) + return x+x; /* NaN */ + if(hx>0) return atanhi[3]+atanlo[3]; + else return -atanhi[3]-atanlo[3]; + } if (ix < 0x3ee00000) { /* |x| < 0.4375f */ + if (ix < 0x31000000) { /* |x| < 2^-29 */ + if(huge+x>one) return x; /* raise inexact */ + } + id = -1; + } else { + x = fabsf(x); + if (ix < 0x3f980000) { /* |x| < 1.1875f */ + if (ix < 0x3f300000) { /* 7/16 <=|x|<11/16 */ + id = 0; x = ((Simple)2.0f*x-one)/((Simple)2.0f+x); + } else { /* 11/16<=|x|< 19/16 */ + id = 1; x = (x-one)/(x+one); + } + } else { + if (ix < 0x401c0000) { /* |x| < 2.4375f */ + id = 2; x = (x-(Simple)1.5f)/(one+(Simple)1.5f*x); + } else { /* 2.4375f <= |x| < 2^66 */ + id = 3; x = -(Simple)1.0f/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); + else { + z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x); + return (hx<0)? -z:z; + } +} +weak_alias (__atanf, atanf) +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_cbrtf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_cbrtf.cpp new file mode 100644 index 000000000..db8d7d202 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_cbrtf.cpp @@ -0,0 +1,67 @@ +/* See the import.pl script for potential modifications */ +/* Compute cubic root of Simple value. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Dirk Alboth and + Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1f of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "SMath.h" +#include "math_private.h" + + +#define CBRT2 1.2599210498948731648f /* 2^(1/3) */ +#define SQR_CBRT2 1.5874010519681994748f /* 2^(2/3) */ + +static const Simple factor[5] = +{ + 1.0f / SQR_CBRT2, + 1.0f / CBRT2, + 1.0f, + CBRT2, + SQR_CBRT2 +}; + + +namespace streflop_libm { +Simple +__cbrtf (Simple x) +{ + Simple xm, ym, u, t2; + int xe; + + /* Reduce X. XM now is an range 1.0f to 0.5f. */ + xm = __frexpf (fabsf (x), &xe); + + /* If X is not finite or is null return it (with raising exceptions + if necessary. + Note: *Our* version of `frexp' sets XE to zero if the argument is + Inf or NaN. This is not portable but faster. */ + if (xe == 0 && fpclassify (x) <= FP_ZERO) + return x + x; + + u = (0.492659620528969547f + (0.697570460207922770f + - 0.191502161678719066f * xm) * xm); + + t2 = u * u * u; + + ym = u * (t2 + 2.0f * xm) / (2.0f * t2 + xm) * factor[2 + xe % 3]; + + return __ldexpf (x > 0.0f ? ym : -ym, xe / 3); +} +weak_alias (__cbrtf, cbrtf) +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_ceilf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_ceilf.cpp new file mode 100644 index 000000000..bb4c0649d --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_ceilf.cpp @@ -0,0 +1,65 @@ +/* See the import.pl script for potential modifications */ +/* s_ceilf.c -- Simple version of s_ceil.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_ceilf.c,v 1.4f 1995/05/10 20:46:55 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple huge = 1.0e30f; +#else +static Simple huge = 1.0e30f; +#endif + +#ifdef __STDC__ + Simple __ceilf(Simple x) +#else + Simple __ceilf(x) + Simple x; +#endif +{ + int32_t i0,j0; + u_int32_t i; + + GET_FLOAT_WORD(i0,x); + j0 = ((i0>>23)&0xff)-0x7f; + if(j0<23) { + if(j0<0) { /* raise inexact if x != 0 */ + if(huge+x>(Simple)0.0f) {/* return 0*sign(x) if |x|<1 */ + if(i0<0) {i0=0x80000000;} + else if(i0!=0) { i0=0x3f800000;} + } + } else { + i = (0x007fffff)>>j0; + if((i0&i)==0) return x; /* x is integral */ + if(huge+x>(Simple)0.0f) { /* raise inexact flag */ + if(i0>0) i0 += (0x00800000)>>j0; + i0 &= (~i); + } + } + } else { + if(j0==0x80) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } + SET_FLOAT_WORD(x,i0); + return x; +} +weak_alias (__ceilf, ceilf) +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_copysignf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_copysignf.cpp new file mode 100644 index 000000000..c09a2ec56 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_copysignf.cpp @@ -0,0 +1,45 @@ +/* See the import.pl script for potential modifications */ +/* s_copysignf.c -- Simple version of s_copysign.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_copysignf.c,v 1.4f 1995/05/10 20:46:59 jtc Exp $"; +#endif + +/* + * copysignf(Simple x, Simple y) + * copysignf(x,y) returns a value with the magnitude of x and + * with the sign bit of y. + */ + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ + Simple __copysignf(Simple x, Simple y) +#else + Simple __copysignf(x,y) + Simple x,y; +#endif +{ + u_int32_t ix,iy; + GET_FLOAT_WORD(ix,x); + GET_FLOAT_WORD(iy,y); + SET_FLOAT_WORD(x,(ix&0x7fffffff)|(iy&0x80000000)); + return x; +} +weak_alias (__copysignf, copysignf) +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_cosf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_cosf.cpp new file mode 100644 index 000000000..2ca15fba4 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_cosf.cpp @@ -0,0 +1,63 @@ +/* See the import.pl script for potential modifications */ +/* s_cosf.c -- Simple version of s_cos.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_cosf.c,v 1.4f 1995/05/10 20:47:03 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple one=1.0f; +#else +static Simple one=1.0f; +#endif + +#ifdef __STDC__ + Simple __cosf(Simple x) +#else + Simple __cosf(x) + Simple x; +#endif +{ + Simple y[2],z=0.0f; + int32_t n,ix; + + GET_FLOAT_WORD(ix,x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if(ix <= 0x3f490fd8) return __kernel_cosf(x,z); + + /* cos(Inf or NaN) is NaN */ + else if (ix>=0x7f800000) return x-x; + + /* argument reduction needed */ + else { + n = __ieee754_rem_pio2f(x,y); + switch(n&3) { + case 0: return __kernel_cosf(y[0],y[1]); + case 1: return -__kernel_sinf(y[0],y[1],1); + case 2: return -__kernel_cosf(y[0],y[1]); + default: + return __kernel_sinf(y[0],y[1],1); + } + } +} +weak_alias (__cosf, cosf) +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_erff.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_erff.cpp new file mode 100644 index 000000000..c28d4865e --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_erff.cpp @@ -0,0 +1,228 @@ +/* See the import.pl script for potential modifications */ +/* s_erff.c -- Simple version of s_erf.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_erff.c,v 1.4f 1995/05/10 20:47:07 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple +#else +static Simple +#endif +tiny = 1e-30f, +half= 5.0000000000e-01f, /* 0x3F000000 */ +one = 1.0000000000e+00f, /* 0x3F800000 */ +two = 2.0000000000e+00f, /* 0x40000000 */ + /* c = (subfloat)0.84506291151f */ +erx = 8.4506291151e-01f, /* 0x3f58560b */ +/* + * Coefficients for approximation to erf on [0,0.84375] + */ +efx = 1.2837916613e-01f, /* 0x3e0375d4 */ +efx8= 1.0270333290e+00f, /* 0x3f8375d4 */ +pp0 = 1.2837916613e-01f, /* 0x3e0375d4 */ +pp1 = -3.2504209876e-01f, /* 0xbea66beb */ +pp2 = -2.8481749818e-02f, /* 0xbce9528f */ +pp3 = -5.7702702470e-03f, /* 0xbbbd1489 */ +pp4 = -2.3763017452e-05f, /* 0xb7c756b1 */ +qq1 = 3.9791721106e-01f, /* 0x3ecbbbce */ +qq2 = 6.5022252500e-02f, /* 0x3d852a63 */ +qq3 = 5.0813062117e-03f, /* 0x3ba68116 */ +qq4 = 1.3249473704e-04f, /* 0x390aee49 */ +qq5 = -3.9602282413e-06f, /* 0xb684e21a */ +/* + * Coefficients for approximation to erf in [0.84375f,1.25f] + */ +pa0 = -2.3621185683e-03f, /* 0xbb1acdc6 */ +pa1 = 4.1485610604e-01f, /* 0x3ed46805 */ +pa2 = -3.7220788002e-01f, /* 0xbebe9208 */ +pa3 = 3.1834661961e-01f, /* 0x3ea2fe54 */ +pa4 = -1.1089469492e-01f, /* 0xbde31cc2 */ +pa5 = 3.5478305072e-02f, /* 0x3d1151b3 */ +pa6 = -2.1663755178e-03f, /* 0xbb0df9c0 */ +qa1 = 1.0642088205e-01f, /* 0x3dd9f331 */ +qa2 = 5.4039794207e-01f, /* 0x3f0a5785 */ +qa3 = 7.1828655899e-02f, /* 0x3d931ae7 */ +qa4 = 1.2617121637e-01f, /* 0x3e013307 */ +qa5 = 1.3637083583e-02f, /* 0x3c5f6e13 */ +qa6 = 1.1984500103e-02f, /* 0x3c445aa3 */ +/* + * Coefficients for approximation to erfc in [1.25f,1/0.35f] + */ +ra0 = -9.8649440333e-03f, /* 0xbc21a093 */ +ra1 = -6.9385856390e-01f, /* 0xbf31a0b7 */ +ra2 = -1.0558626175e+01f, /* 0xc128f022 */ +ra3 = -6.2375331879e+01f, /* 0xc2798057 */ +ra4 = -1.6239666748e+02f, /* 0xc322658c */ +ra5 = -1.8460508728e+02f, /* 0xc3389ae7 */ +ra6 = -8.1287437439e+01f, /* 0xc2a2932b */ +ra7 = -9.8143291473e+00f, /* 0xc11d077e */ +sa1 = 1.9651271820e+01f, /* 0x419d35ce */ +sa2 = 1.3765776062e+02f, /* 0x4309a863 */ +sa3 = 4.3456588745e+02f, /* 0x43d9486f */ +sa4 = 6.4538726807e+02f, /* 0x442158c9 */ +sa5 = 4.2900814819e+02f, /* 0x43d6810b */ +sa6 = 1.0863500214e+02f, /* 0x42d9451f */ +sa7 = 6.5702495575e+00f, /* 0x40d23f7c */ +sa8 = -6.0424413532e-02f, /* 0xbd777f97 */ +/* + * Coefficients for approximation to erfc in [1/.35f,28] + */ +rb0 = -9.8649431020e-03f, /* 0xbc21a092 */ +rb1 = -7.9928326607e-01f, /* 0xbf4c9dd4 */ +rb2 = -1.7757955551e+01f, /* 0xc18e104b */ +rb3 = -1.6063638306e+02f, /* 0xc320a2ea */ +rb4 = -6.3756646729e+02f, /* 0xc41f6441 */ +rb5 = -1.0250950928e+03f, /* 0xc480230b */ +rb6 = -4.8351919556e+02f, /* 0xc3f1c275 */ +sb1 = 3.0338060379e+01f, /* 0x41f2b459 */ +sb2 = 3.2579251099e+02f, /* 0x43a2e571 */ +sb3 = 1.5367296143e+03f, /* 0x44c01759 */ +sb4 = 3.1998581543e+03f, /* 0x4547fdbb */ +sb5 = 2.5530502930e+03f, /* 0x451f90ce */ +sb6 = 4.7452853394e+02f, /* 0x43ed43a7 */ +sb7 = -2.2440952301e+01f; /* 0xc1b38712 */ + +#ifdef __STDC__ + Simple __erff(Simple x) +#else + Simple __erff(x) + Simple x; +#endif +{ + int32_t hx,ix,i; + Simple R,S,P,Q,s,y,z,r; + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x7f800000) { /* erf(nan)=nan */ + i = ((u_int32_t)hx>>31)<<1; + return (Simple)(1-i)+one/x; /* erf(+-inf)=+-1 */ + } + + if(ix < 0x3f580000) { /* |x|<0.84375f */ + if(ix < 0x31800000) { /* |x|<2**-28 */ + if (ix < 0x04000000) + /*avoid underflow */ + return (Simple)0.125f*((Simple)8.0f*x+efx8*x); + return x + efx*x; + } + z = x*x; + r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4))); + s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5)))); + y = r/s; + return x + x*y; + } + if(ix < 0x3fa00000) { /* 0.84375f <= |x| < 1.25f */ + s = fabsf(x)-one; + P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6))))); + Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6))))); + if(hx>=0) return erx + P/Q; else return -erx - P/Q; + } + if (ix >= 0x40c00000) { /* inf>|x|>=6 */ + if(hx>=0) return one-tiny; else return tiny-one; + } + x = fabsf(x); + s = one/(x*x); + if(ix< 0x4036DB6E) { /* |x| < 1/0.35f */ + R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*( + ra5+s*(ra6+s*ra7)))))); + S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*( + sa5+s*(sa6+s*(sa7+s*sa8))))))); + } else { /* |x| >= 1/0.35f */ + R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*( + rb5+s*rb6))))); + S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*( + sb5+s*(sb6+s*sb7)))))); + } + GET_FLOAT_WORD(ix,x); + SET_FLOAT_WORD(z,ix&0xfffff000); + r = __ieee754_expf(-z*z-(Simple)0.5625f)*__ieee754_expf((z-x)*(z+x)+R/S); + if(hx>=0) return one-r/x; else return r/x-one; +} +weak_alias (__erff, erff) + +#ifdef __STDC__ + Simple __erfcf(Simple x) +#else + Simple __erfcf(x) + Simple x; +#endif +{ + int32_t hx,ix; + Simple R,S,P,Q,s,y,z,r; + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x7f800000) { /* erfc(nan)=nan */ + /* erfc(+-inf)=0,2 */ + return (Simple)(((u_int32_t)hx>>31)<<1)+one/x; + } + + if(ix < 0x3f580000) { /* |x|<0.84375f */ + if(ix < 0x23800000) /* |x|<2**-56 */ + return one-x; + z = x*x; + r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4))); + s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5)))); + y = r/s; + if(hx < 0x3e800000) { /* x<1/4 */ + return one-(x+x*y); + } else { + r = x*y; + r += (x-half); + return half - r ; + } + } + if(ix < 0x3fa00000) { /* 0.84375f <= |x| < 1.25f */ + s = fabsf(x)-one; + P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6))))); + Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6))))); + if(hx>=0) { + z = one-erx; return z - P/Q; + } else { + z = erx+P/Q; return one+z; + } + } + if (ix < 0x41e00000) { /* |x|<28 */ + x = fabsf(x); + s = one/(x*x); + if(ix< 0x4036DB6D) { /* |x| < 1/.35f ~ 2.857143f*/ + R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*( + ra5+s*(ra6+s*ra7)))))); + S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*( + sa5+s*(sa6+s*(sa7+s*sa8))))))); + } else { /* |x| >= 1/.35f ~ 2.857143f */ + if(hx<0&&ix>=0x40c00000) return two-tiny;/* x < -6 */ + R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*( + rb5+s*rb6))))); + S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*( + sb5+s*(sb6+s*sb7)))))); + } + GET_FLOAT_WORD(ix,x); + SET_FLOAT_WORD(z,ix&0xfffff000); + r = __ieee754_expf(-z*z-(Simple)0.5625f)* + __ieee754_expf((z-x)*(z+x)+R/S); + if(hx>0) return r/x; else return two-r/x; + } else { + if(hx>0) return tiny*tiny; else return two-tiny; + } +} +weak_alias (__erfcf, erfcf) +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_expm1f.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_expm1f.cpp new file mode 100644 index 000000000..8ec4d4a54 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_expm1f.cpp @@ -0,0 +1,139 @@ +/* See the import.pl script for potential modifications */ +/* s_expm1f.c -- Simple version of s_expm1.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_expm1f.c,v 1.5f 1995/05/10 20:47:11 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +static const Simple huge = 1.0e+30f; +static const Simple tiny = 1.0e-30f; + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple +#else +static Simple +#endif +one = 1.0f, +o_threshold = 8.8721679688e+01f,/* 0x42b17180 */ +ln2_hi = 6.9313812256e-01f,/* 0x3f317180 */ +ln2_lo = 9.0580006145e-06f,/* 0x3717f7d1 */ +invln2 = 1.4426950216e+00f,/* 0x3fb8aa3b */ + /* scaled coefficients related to expm1 */ +Q1 = -3.3333335072e-02f, /* 0xbd088889 */ +Q2 = 1.5873016091e-03f, /* 0x3ad00d01 */ +Q3 = -7.9365076090e-05f, /* 0xb8a670cd */ +Q4 = 4.0082177293e-06f, /* 0x36867e54 */ +Q5 = -2.0109921195e-07f; /* 0xb457edbb */ + +#ifdef __STDC__ + Simple __expm1f(Simple x) +#else + Simple __expm1f(x) + Simple x; +#endif +{ + Simple y,hi,lo,c,t,e,hxs,hfx,r1; + int32_t k,xsb; + u_int32_t hx; + + GET_FLOAT_WORD(hx,x); + xsb = hx&0x80000000; /* sign bit of x */ + if(xsb==0) y=x; else y= -x; /* y = |x| */ + hx &= 0x7fffffff; /* high word of |x| */ + + /* filter out huge and non-finite argument */ + if(hx >= 0x4195b844) { /* if |x|>=27*ln2 */ + if(hx >= 0x42b17218) { /* if |x|>=88.721f... */ + if(hx>0x7f800000) + return x+x; /* NaN */ + if(hx==0x7f800000) + return (xsb==0)? x:-Simple(1.0f);/* exp(+-inf)={inf,-1} */ + if(x > o_threshold) return huge*huge; /* overflow */ + } + if(xsb!=0) { /* x < -27*ln2, return -1.0f with inexact */ + if(x+tiny<(Simple)0.0f) /* raise inexact */ + return tiny-one; /* return -1 */ + } + } + + /* argument reduction */ + if(hx > 0x3eb17218) { /* if |x| > 0.5f ln2 */ + if(hx < 0x3F851592) { /* and |x| < 1.5f ln2 */ + if(xsb==0) + {hi = x - ln2_hi; lo = ln2_lo; k = 1;} + else + {hi = x + ln2_hi; lo = -ln2_lo; k = -1;} + } else { + k = invln2*x+((xsb==0)?(Simple)0.5f:(Simple)-0.5f); + t = k; + hi = x - t*ln2_hi; /* t*ln2_hi is exact here */ + lo = t*ln2_lo; + } + x = hi - lo; + c = (hi-x)-lo; + } + else if(hx < 0x33000000) { /* when |x|<2**-25, return x */ + t = huge+x; /* return x with inexact flags when x!=0 */ + return x - (t-(huge+x)); + } + else k = 0; + + /* x is now in primary range */ + hfx = (Simple)0.5f*x; + hxs = x*hfx; + r1 = one+hxs*(Q1+hxs*(Q2+hxs*(Q3+hxs*(Q4+hxs*Q5)))); + t = (Simple)3.0f-r1*hfx; + e = hxs*((r1-t)/((Simple)6.0f - x*t)); + if(k==0) return x - (x*e-hxs); /* c is 0 */ + else { + e = (x*(e-c)-c); + e -= hxs; + if(k== -1) return (Simple)0.5f*(x-e)-(Simple)0.5f; + if(k==1) { + if(x < (Simple)-0.25f) return -(Simple)2.0f*(e-(x+(Simple)0.5f)); + else return one+(Simple)2.0f*(x-e); + } + if (k <= -2 || k>56) { /* suffice to return exp(x)-1 */ + int32_t i; + y = one-(e-x); + GET_FLOAT_WORD(i,y); + SET_FLOAT_WORD(y,i+(k<<23)); /* add k to y's exponent */ + return y-one; + } + t = one; + if(k<23) { + int32_t i; + SET_FLOAT_WORD(t,0x3f800000 - (0x1000000>>k)); /* t=1-2^-k */ + y = t-(e-x); + GET_FLOAT_WORD(i,y); + SET_FLOAT_WORD(y,i+(k<<23)); /* add k to y's exponent */ + } else { + int32_t i; + SET_FLOAT_WORD(t,((0x7f-k)<<23)); /* 2^-k */ + y = x-(e+t); + y += one; + GET_FLOAT_WORD(i,y); + SET_FLOAT_WORD(y,i+(k<<23)); /* add k to y's exponent */ + } + } + return y; +} +weak_alias (__expm1f, expm1f) +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_fabsf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_fabsf.cpp new file mode 100644 index 000000000..2d3942ecc --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_fabsf.cpp @@ -0,0 +1,42 @@ +/* See the import.pl script for potential modifications */ +/* s_fabsf.c -- Simple version of s_fabs.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_fabsf.c,v 1.4f 1995/05/10 20:47:15 jtc Exp $"; +#endif + +/* + * fabsf(x) returns the absolute value of x. + */ + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ + Simple __fabsf(Simple x) +#else + Simple __fabsf(x) + Simple x; +#endif +{ + u_int32_t ix; + GET_FLOAT_WORD(ix,x); + SET_FLOAT_WORD(x,ix&0x7fffffff); + return x; +} +weak_alias (__fabsf, fabsf) +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_finitef.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_finitef.cpp new file mode 100644 index 000000000..300372dee --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_finitef.cpp @@ -0,0 +1,43 @@ +/* See the import.pl script for potential modifications */ +/* s_finitef.c -- Simple version of s_finite.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_finitef.c,v 1.4f 1995/05/10 20:47:18 jtc Exp $"; +#endif + +/* + * finitef(x) returns 1 is x is finite, else 0; + * no branching! + */ + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ + int __finitef(Simple x) +#else + int __finitef(x) + Simple x; +#endif +{ + int32_t ix; + GET_FLOAT_WORD(ix,x); + return (int)((u_int32_t)((ix&0x7fffffff)-0x7f800000)>>31); +} +hidden_def (__finitef) +weak_alias (__finitef, finitef) +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_floorf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_floorf.cpp new file mode 100644 index 000000000..42a87d46c --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_floorf.cpp @@ -0,0 +1,74 @@ +/* See the import.pl script for potential modifications */ +/* s_floorf.c -- Simple version of s_floor.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_floorf.c,v 1.4f 1995/05/10 20:47:22 jtc Exp $"; +#endif + +/* + * floorf(x) + * Return x rounded toward -inf to integral value + * Method: + * Bit twiddling. + * Exception: + * Inexact flag raised if x not equal to floorf(x). + */ + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple huge = 1.0e30f; +#else +static Simple huge = 1.0e30f; +#endif + +#ifdef __STDC__ + Simple __floorf(Simple x) +#else + Simple __floorf(x) + Simple x; +#endif +{ + int32_t i0,j0; + u_int32_t i; + GET_FLOAT_WORD(i0,x); + j0 = ((i0>>23)&0xff)-0x7f; + if(j0<23) { + if(j0<0) { /* raise inexact if x != 0 */ + if(huge+x>(Simple)0.0f) {/* return 0*sign(x) if |x|<1 */ + if(i0>=0) {i0=0;} + else if((i0&0x7fffffff)!=0) + { i0=0xbf800000;} + } + } else { + i = (0x007fffff)>>j0; + if((i0&i)==0) return x; /* x is integral */ + if(huge+x>(Simple)0.0f) { /* raise inexact flag */ + if(i0<0) i0 += (0x00800000)>>j0; + i0 &= (~i); + } + } + } else { + if(j0==0x80) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } + SET_FLOAT_WORD(x,i0); + return x; +} +weak_alias (__floorf, floorf) +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_fpclassifyf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_fpclassifyf.cpp new file mode 100644 index 000000000..ed23e8985 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_fpclassifyf.cpp @@ -0,0 +1,46 @@ +/* See the import.pl script for potential modifications */ +/* Return classification value corresponding to argument. + Copyright (C) 1997, 2000, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1f of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "SMath.h" + +#include "math_private.h" + + +namespace streflop_libm { +int +__fpclassifyf (Simple x) +{ + u_int32_t wx; + int retval = FP_NORMAL; + + GET_FLOAT_WORD (wx, x); + wx &= 0x7fffffff; + if (wx == 0) + retval = FP_ZERO; + else if (wx < 0x800000) + retval = FP_SUBNORMAL; + else if (wx >= 0x7f800000) + retval = wx > 0x7f800000 ? FP_NAN : FP_INFINITE; + + return retval; +} +libm_hidden_def (__fpclassifyf) +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_frexpf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_frexpf.cpp new file mode 100644 index 000000000..a416f605f --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_frexpf.cpp @@ -0,0 +1,56 @@ +/* See the import.pl script for potential modifications */ +/* s_frexpf.c -- Simple version of s_frexp.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_frexpf.c,v 1.5f 1995/05/10 20:47:26 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple +#else +static Simple +#endif +two25 = 3.3554432000e+07f; /* 0x4c000000 */ + +#ifdef __STDC__ + Simple __frexpf(Simple x, int *eptr) +#else + Simple __frexpf(x, eptr) + Simple x; int *eptr; +#endif +{ + int32_t hx,ix; + GET_FLOAT_WORD(hx,x); + ix = 0x7fffffff&hx; + *eptr = 0; + if(ix>=0x7f800000||(ix==0)) return x; /* 0,inf,nan */ + if (ix<0x00800000) { /* subnormal */ + x *= two25; + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + *eptr = -25; + } + *eptr += (ix>>23)-126; + hx = (hx&0x807fffff)|0x3f000000; + SET_FLOAT_WORD(x,hx); + return x; +} +weak_alias (__frexpf, frexpf) +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_ilogbf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_ilogbf.cpp new file mode 100644 index 000000000..b0b31cdc5 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_ilogbf.cpp @@ -0,0 +1,53 @@ +/* See the import.pl script for potential modifications */ +/* s_ilogbf.c -- Simple version of s_ilogb.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_ilogbf.c,v 1.4f 1995/05/10 20:47:31 jtc Exp $"; +#endif + +#include "../streflop_libm_bridge.h" +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ + int __ilogbf(Simple x) +#else + int __ilogbf(x) + Simple x; +#endif +{ + int32_t hx,ix; + + GET_FLOAT_WORD(hx,x); + hx &= 0x7fffffff; + if(hx<0x00800000) { + if(hx==0) + return FP_ILOGB0; /* ilogb(0) = FP_ILOGB0 */ + else /* subnormal x */ + for (ix = -126,hx<<=8; hx>0; hx<<=1) ix -=1; + return ix; + } + else if (hx<0x7f800000) return (hx>>23)-127; + else if (FP_ILOGBNAN != INT_MAX) { + /* ISO C99 requires ilogbf(+-Inf) == INT_MAX. */ + if (hx==0x7f800000) + return INT_MAX; + } + return FP_ILOGBNAN; +} +weak_alias (__ilogbf, ilogbf) +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_isinff.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_isinff.cpp new file mode 100644 index 000000000..520db800e --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_isinff.cpp @@ -0,0 +1,32 @@ +/* See the import.pl script for potential modifications */ +/* + * Written by J.T. Conklin . + * Public domain. + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_isinff.c,v 1.3f 1995/05/11 23:20:21 jtc Exp $"; +#endif + +/* + * isinff(x) returns 1 if x is inf, -1 if x is -inf, else 0; + * no branching! + */ + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +int +__isinff (Simple x) +{ + int32_t ix,t; + GET_FLOAT_WORD(ix,x); + t = ix & 0x7fffffff; + t ^= 0x7f800000; + t |= -t; + return ~(t >> 31) & (ix >> 30); +} +hidden_def (__isinff) +weak_alias (__isinff, isinff) +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_isnanf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_isnanf.cpp new file mode 100644 index 000000000..ee94414ce --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_isnanf.cpp @@ -0,0 +1,45 @@ +/* See the import.pl script for potential modifications */ +/* s_isnanf.c -- Simple version of s_isnan.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_isnanf.c,v 1.4f 1995/05/10 20:47:38 jtc Exp $"; +#endif + +/* + * isnanf(x) returns 1 is x is nan, else 0; + * no branching! + */ + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ + int __isnanf(Simple x) +#else + int __isnanf(x) + Simple x; +#endif +{ + int32_t ix; + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; + ix = 0x7f800000 - ix; + return (int)(((u_int32_t)(ix))>>31); +} +hidden_def (__isnanf) +weak_alias (__isnanf, isnanf) +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_ldexpf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_ldexpf.cpp new file mode 100644 index 000000000..378ea7957 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_ldexpf.cpp @@ -0,0 +1,40 @@ +/* See the import.pl script for potential modifications */ +/* s_ldexpf.c -- Simple version of s_ldexp.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_ldexpf.c,v 1.3f 1995/05/10 20:47:42 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" +#include "../streflop_libm_bridge.h" + +namespace streflop_libm { +#ifdef __STDC__ + Simple __ldexpf(Simple value, int exp) +#else + Simple __ldexpf(value, exp) + Simple value; int exp; +#endif +{ + if(!__finitef(value)||value==(Simple)0.0f) return value; + value = __scalbnf(value,exp); + if(!__finitef(value)||value==(Simple)0.0f) __set_errno (ERANGE); + return value; +} +INTDEF(__ldexpf) +weak_alias (__ldexpf, ldexpf) +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_llrintf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_llrintf.cpp new file mode 100644 index 000000000..e35eb6833 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_llrintf.cpp @@ -0,0 +1,79 @@ +/* See the import.pl script for potential modifications */ +/* Round argument to nearest integral value according to current rounding + direction. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1f of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "SMath.h" + +#include "math_private.h" + +static const Simple two23[2] = +{ + 8.3886080000e+06f, /* 0x4B000000 */ + -8.3886080000e+06f, /* 0xCB000000 */ +}; + + +long long int +__llrintf (Simple x) +{ + int32_t j0; + u_int32_t i0; + Simple w; + Simple t; + long long int result; + int sx; + + GET_FLOAT_WORD (i0, x); + + sx = i0 >> 31; + j0 = ((i0 >> 23) & 0xff) - 0x7f; + i0 &= 0x7fffff; + i0 |= 0x800000; + + if (j0 < (int32_t) (sizeof (long long int) * 8) - 1) + { + if (j0 < -1) + return 0; + else if (j0 >= 23) + result = (long long int) i0 << (j0 - 23); + else + { + w = two23[sx] + x; + t = w - two23[sx]; + GET_FLOAT_WORD (i0, t); + j0 = ((i0 >> 23) & 0xff) - 0x7f; + i0 &= 0x7fffff; + i0 |= 0x800000; + + result = i0 >> (23 - j0); + } + } + else + { + /* The number is too large. It is left implementation defined + what happens. */ + return (long long int) x; + } + + return sx ? -result : result; +} + +weak_alias (__llrintf, llrintf) diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_llroundf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_llroundf.cpp new file mode 100644 index 000000000..64491470a --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_llroundf.cpp @@ -0,0 +1,64 @@ +/* See the import.pl script for potential modifications */ +/* Round Simple value to long long int. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1f of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "SMath.h" + +#include "math_private.h" + + +long long int +__llroundf (Simple x) +{ + int32_t j0; + u_int32_t i; + long long int result; + int sign; + + GET_FLOAT_WORD (i, x); + j0 = ((i >> 23) & 0xff) - 0x7f; + sign = (i & 0x80000000) != 0 ? -1 : 1; + i &= 0x7fffff; + i |= 0x800000; + + if (j0 < (int32_t) (8 * sizeof (long long int)) - 1) + { + if (j0 < 0) + return j0 < -1 ? 0 : sign; + else if (j0 >= 23) + result = (long long int) i << (j0 - 23); + else + { + i += 0x400000 >> j0; + + result = i >> (23 - j0); + } + } + else + { + /* The number is too large. It is left implementation defined + what happens. */ + return (long long int) x; + } + + return sign * result; +} + +weak_alias (__llroundf, llroundf) diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_log1pf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_log1pf.cpp new file mode 100644 index 000000000..0837d0998 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_log1pf.cpp @@ -0,0 +1,118 @@ +/* See the import.pl script for potential modifications */ +/* s_log1pf.c -- Simple version of s_log1p.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_log1pf.c,v 1.4f 1995/05/10 20:47:48 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple +#else +static Simple +#endif +ln2_hi = 6.9313812256e-01f, /* 0x3f317180 */ +ln2_lo = 9.0580006145e-06f, /* 0x3717f7d1 */ +two25 = 3.355443200e+07f, /* 0x4c000000 */ +Lp1 = 6.6666668653e-01f, /* 3F2AAAAB */ +Lp2 = 4.0000000596e-01f, /* 3ECCCCCD */ +Lp3 = 2.8571429849e-01f, /* 3E924925 */ +Lp4 = 2.2222198546e-01f, /* 3E638E29 */ +Lp5 = 1.8183572590e-01f, /* 3E3A3325 */ +Lp6 = 1.5313838422e-01f, /* 3E1CD04F */ +Lp7 = 1.4798198640e-01f; /* 3E178897 */ + +#ifdef __STDC__ +static const Simple zero = 0.0f; +#else +static Simple zero = 0.0f; +#endif + +#ifdef __STDC__ + Simple __log1pf(Simple x) +#else + Simple __log1pf(x) + Simple x; +#endif +{ + Simple hfsq,f,c,s,z,R,u; + int32_t k,hx,hu,ax; + + GET_FLOAT_WORD(hx,x); + ax = hx&0x7fffffff; + + k = 1; + if (hx < 0x3ed413d7) { /* x < 0.41422f */ + if(ax>=0x3f800000) { /* x <= -1.0f */ + if(x==(Simple)-1.0f) return -two25/(x-x); /* log1p(-1)=+inf */ + else return (x-x)/(x-x); /* log1p(x<-1)=NaN */ + } + if(ax<0x31000000) { /* |x| < 2**-29 */ + if(two25+x>zero /* raise inexact */ + &&ax<0x24800000) /* |x| < 2**-54 */ + return x; + else + return x - x*x*(Simple)0.5f; + } + if(hx>0||hx<=((int32_t)0xbe95f61f)) { + k=0;f=x;hu=1;} /* -0.2929f= 0x7f800000) return x+x; + if(k!=0) { + if(hx<0x5a000000) { + u = (Simple)1.0f+x; + GET_FLOAT_WORD(hu,u); + k = (hu>>23)-127; + /* correction term */ + c = (k>0)? (Simple)Simple(1.0f)-(u-x):x-(u-(Simple)Simple(1.0f)); + c /= u; + } else { + u = x; + GET_FLOAT_WORD(hu,u); + k = (hu>>23)-127; + c = 0; + } + hu &= 0x007fffff; + if(hu<0x3504f7) { + SET_FLOAT_WORD(u,hu|0x3f800000);/* normalize u */ + } else { + k += 1; + SET_FLOAT_WORD(u,hu|0x3f000000); /* normalize u/2 */ + hu = (0x00800000-hu)>>2; + } + f = u-(Simple)1.0f; + } + hfsq=(Simple)0.5f*f*f; + if(hu==0) { /* |f| < 2**-20 */ + if(f==zero) { + if(k==0) return zero; + else {c += k*ln2_lo; return k*ln2_hi+c;} + } + R = hfsq*((Simple)1.0f-(Simple)0.66666666666666666f*f); + if(k==0) return f-R; else + return k*ln2_hi-((R-(k*ln2_lo+c))-f); + } + s = f/((Simple)2.0f+f); + z = s*s; + R = z*(Lp1+z*(Lp2+z*(Lp3+z*(Lp4+z*(Lp5+z*(Lp6+z*Lp7)))))); + if(k==0) return f-(hfsq-s*(hfsq+R)); else + return k*ln2_hi-((hfsq-(s*(hfsq+R)+(k*ln2_lo+c)))-f); +} +weak_alias (__log1pf, log1pf) +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_logbf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_logbf.cpp new file mode 100644 index 000000000..21756c02e --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_logbf.cpp @@ -0,0 +1,43 @@ +/* See the import.pl script for potential modifications */ +/* s_logbf.c -- Simple version of s_logb.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_logbf.c,v 1.4f 1995/05/10 20:47:51 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ + Simple __logbf(Simple x) +#else + Simple __logbf(x) + Simple x; +#endif +{ + int32_t ix; + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; /* high |x| */ + if(ix==0) return (Simple)-1.0f/fabsf(x); + if(ix>=0x7f800000) return x*x; + if((ix>>=23)==0) /* IEEE 754 logb */ + return -126.0f; + else + return (Simple) (ix-127); +} +weak_alias (__logbf, logbf) +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_lrintf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_lrintf.cpp new file mode 100644 index 000000000..9bad5f47d --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_lrintf.cpp @@ -0,0 +1,79 @@ +/* See the import.pl script for potential modifications */ +/* Round argument to nearest integral value according to current rounding + direction. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1f of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "SMath.h" + +#include "math_private.h" + +static const Simple two23[2] = +{ + 8.3886080000e+06f, /* 0x4B000000 */ + -8.3886080000e+06f, /* 0xCB000000 */ +}; + + +long int +__lrintf (Simple x) +{ + int32_t j0; + u_int32_t i0; + Simple w; + Simple t; + long int result; + int sx; + + GET_FLOAT_WORD (i0, x); + + sx = i0 >> 31; + j0 = ((i0 >> 23) & 0xff) - 0x7f; + i0 &= 0x7fffff; + i0 |= 0x800000; + + if (j0 < (int32_t) (sizeof (long int) * 8) - 1) + { + if (j0 < -1) + return 0; + else if (j0 >= 23) + result = (long int) i0 << (j0 - 23); + else + { + w = two23[sx] + x; + t = w - two23[sx]; + GET_FLOAT_WORD (i0, t); + j0 = ((i0 >> 23) & 0xff) - 0x7f; + i0 &= 0x7fffff; + i0 |= 0x800000; + + result = i0 >> (23 - j0); + } + } + else + { + /* The number is too large. It is left implementation defined + what happens. */ + return (long int) x; + } + + return sx ? -result : result; +} + +weak_alias (__lrintf, lrintf) diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_lroundf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_lroundf.cpp new file mode 100644 index 000000000..01b20dd8d --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_lroundf.cpp @@ -0,0 +1,64 @@ +/* See the import.pl script for potential modifications */ +/* Round Simple value to long int. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1f of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "SMath.h" + +#include "math_private.h" + + +long int +__lroundf (Simple x) +{ + int32_t j0; + u_int32_t i; + long int result; + int sign; + + GET_FLOAT_WORD (i, x); + j0 = ((i >> 23) & 0xff) - 0x7f; + sign = (i & 0x80000000) != 0 ? -1 : 1; + i &= 0x7fffff; + i |= 0x800000; + + if (j0 < (int32_t) (8 * sizeof (long int)) - 1) + { + if (j0 < 0) + return j0 < -1 ? 0 : sign; + else if (j0 >= 23) + result = (long int) i << (j0 - 23); + else + { + i += 0x400000 >> j0; + + result = i >> (23 - j0); + } + } + else + { + /* The number is too large. It is left implementation defined + what happens. */ + return (long int) x; + } + + return sign * result; +} + +weak_alias (__lroundf, lroundf) diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_modff.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_modff.cpp new file mode 100644 index 000000000..aef83849d --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_modff.cpp @@ -0,0 +1,69 @@ +/* See the import.pl script for potential modifications */ +/* s_modff.c -- Simple version of s_modf.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_modff.c,v 1.4f 1995/05/10 20:47:56 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple one = 1.0f; +#else +static Simple one = 1.0f; +#endif + +#ifdef __STDC__ + Simple __modff(Simple x, Simple *iptr) +#else + Simple __modff(x, iptr) + Simple x,*iptr; +#endif +{ + int32_t i0,j0; + u_int32_t i; + GET_FLOAT_WORD(i0,x); + j0 = ((i0>>23)&0xff)-0x7f; /* exponent of x */ + if(j0<23) { /* integer part in x */ + if(j0<0) { /* |x|<1 */ + SET_FLOAT_WORD(*iptr,i0&0x80000000); /* *iptr = +-0 */ + return x; + } else { + i = (0x007fffff)>>j0; + if((i0&i)==0) { /* x is integral */ + u_int32_t ix; + *iptr = x; + GET_FLOAT_WORD(ix,x); + SET_FLOAT_WORD(x,ix&0x80000000); /* return +-0 */ + return x; + } else { + SET_FLOAT_WORD(*iptr,i0&(~i)); + return x - *iptr; + } + } + } else { /* no fraction part */ + *iptr = x*one; + /* We must handle NaNs separately. */ + if (j0 == 0x80 && (i0 & 0x7fffff)) + return x*one; + SET_FLOAT_WORD(x,i0&0x80000000); /* return +-0 */ + return x; + } +} +weak_alias (__modff, modff) +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_nearbyintf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_nearbyintf.cpp new file mode 100644 index 000000000..426ecaba6 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_nearbyintf.cpp @@ -0,0 +1,80 @@ +/* See the import.pl script for potential modifications */ +/* s_rintf.c -- Simple version of s_rint.c. + * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ +/* Adapted for use as nearbyint by Ulrich Drepper . */ + +/* + * ==================================================== + * 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 "../streflop_libm_bridge.h" +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple +#else +static Simple +#endif +TWO23[2]={ + 8.3886080000e+06f, /* 0x4b000000 */ + -8.3886080000e+06f, /* 0xcb000000 */ +}; + +#ifdef __STDC__ + Simple __nearbyintf(Simple x) +#else + Simple __nearbyintf(x) + Simple x; +#endif +{ + fenv_t env; + int32_t i0,j0,sx; + u_int32_t i,i1; + Simple w,t; + GET_FLOAT_WORD(i0,x); + sx = (i0>>31)&1; + j0 = ((i0>>23)&0xff)-0x7f; + if(j0<23) { + if(j0<0) { + if((i0&0x7fffffff)==0) return x; + i1 = (i0&0x07fffff); + i0 &= 0xfff00000; + i0 |= ((i1|-i1)>>9)&0x400000; + SET_FLOAT_WORD(x,i0); + feholdexcept (&env); + w = TWO23[sx]+x; + t = w-TWO23[sx]; + fesetenv (&env); + GET_FLOAT_WORD(i0,t); + SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31)); + return t; + } else { + i = (0x007fffff)>>j0; + if((i0&i)==0) return x; /* x is integral */ + i>>=1; + if((i0&i)!=0) i0 = (i0&(~i))|((0x100000)>>j0); + } + } else { + if(j0==0x80) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } + SET_FLOAT_WORD(x,i0); + feholdexcept (&env); + w = TWO23[sx]+x; + t = w-TWO23[sx]; + fesetenv (&env); + return t; +} +weak_alias (__nearbyintf, nearbyintf) +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_nextafterf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_nextafterf.cpp new file mode 100644 index 000000000..96d47e780 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_nextafterf.cpp @@ -0,0 +1,82 @@ +/* See the import.pl script for potential modifications */ +/* s_nextafterf.c -- Simple version of s_nextafter.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_nextafterf.c,v 1.4f 1995/05/10 20:48:01 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" +#include "../streflop_libm_bridge.h" + +namespace streflop_libm { +#ifdef __STDC__ + Simple __nextafterf(Simple x, Simple y) +#else + Simple __nextafterf(x,y) + Simple x,y; +#endif +{ + int32_t hx,hy,ix,iy; + + GET_FLOAT_WORD(hx,x); + GET_FLOAT_WORD(hy,y); + ix = hx&0x7fffffff; /* |x| */ + iy = hy&0x7fffffff; /* |y| */ + + if((ix>0x7f800000) || /* x is nan */ + (iy>0x7f800000)) /* y is nan */ + return x+y; + if(x==y) return y; /* x=y, return y */ + if(ix==0) { /* x == 0 */ + SET_FLOAT_WORD(x,(hy&0x80000000)|1);/* return +-minsubnormal */ + y = x*x; + if(y==x) return y; else return x; /* raise underflow flag */ + } + if(hx>=0) { /* x > 0 */ + if(hx>hy) { /* x > y, x -= ulp */ + hx -= 1; + } else { /* x < y, x += ulp */ + hx += 1; + } + } else { /* x < 0 */ + if(hy>=0||hx>hy){ /* x < y, x -= ulp */ + hx -= 1; + } else { /* x > y, x += ulp */ + hx += 1; + } + } + hy = hx&0x7f800000; + if(hy>=0x7f800000) { + x = x+x; /* overflow */ +#if FLT_EVAL_METHOD != 0 + if (FLT_EVAL_METHOD != 0) + asm ("" : "=m"(x) : "m"(x)); +#endif + return x; /* overflow */ + } + if(hy<0x00800000) { /* underflow */ + y = x*x; + if(y!=x) { /* raise underflow flag */ + SET_FLOAT_WORD(y,hx); + return y; + } + } + SET_FLOAT_WORD(x,hx); + return x; +} +weak_alias (__nextafterf, nextafterf) +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_remquof.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_remquof.cpp new file mode 100644 index 000000000..448421035 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_remquof.cpp @@ -0,0 +1,111 @@ +/* See the import.pl script for potential modifications */ +/* Compute remainder and a congruent to the quotient. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1f of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "SMath.h" + +#include "math_private.h" + + +static const Simple zero = 0.0f; + + +namespace streflop_libm { +Simple +__remquof (Simple x, Simple y, int *quo) +{ + int32_t hx,hy; + u_int32_t sx; + int cquo, qs; + + GET_FLOAT_WORD (hx, x); + GET_FLOAT_WORD (hy, y); + sx = hx & 0x80000000; + qs = sx ^ (hy & 0x80000000); + hy &= 0x7fffffff; + hx &= 0x7fffffff; + + /* Purge off exception values. */ + if (hy == 0) + return (x * y) / (x * y); /* y = 0 */ + if ((hx >= 0x7f800000) /* x not finite */ + || (hy > 0x7f800000)) /* y is NaN */ + return (x * y) / (x * y); + + if (hy <= 0x7dffffff) + x = __ieee754_fmodf (x, 8 * y); /* now x < 8y */ + + if ((hx - hy) == 0) + { + *quo = qs ? -1 : 1; + return zero * x; + } + + x = fabsf (x); + y = fabsf (y); + cquo = 0; + + if (x >= 4 * y) + { + x -= 4 * y; + cquo += 4; + } + if (x >= 2 * y) + { + x -= 2 * y; + cquo += 2; + } + + if (hy < 0x01000000) + { + if (x + x > y) + { + x -= y; + ++cquo; + if (x + x >= y) + { + x -= y; + ++cquo; + } + } + } + else + { + Simple y_half = 0.5f * y; + if (x > y_half) + { + x -= y; + ++cquo; + if (x >= y_half) + { + x -= y; + ++cquo; + } + } + } + + *quo = qs ? -cquo : cquo; + + if (sx) + x = -x; + return x; +} +weak_alias (__remquof, remquof) +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_rintf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_rintf.cpp new file mode 100644 index 000000000..dcd98e158 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_rintf.cpp @@ -0,0 +1,75 @@ +/* See the import.pl script for potential modifications */ +/* s_rintf.c -- Simple version of s_rint.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_rintf.c,v 1.4f 1995/05/10 20:48:06 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple +#else +static Simple +#endif +TWO23[2]={ + 8.3886080000e+06f, /* 0x4b000000 */ + -8.3886080000e+06f, /* 0xcb000000 */ +}; + +#ifdef __STDC__ + Simple __rintf(Simple x) +#else + Simple __rintf(x) + Simple x; +#endif +{ + int32_t i0,j0,sx; + u_int32_t i,i1; + Simple w,t; + GET_FLOAT_WORD(i0,x); + sx = (i0>>31)&1; + j0 = ((i0>>23)&0xff)-0x7f; + if(j0<23) { + if(j0<0) { + if((i0&0x7fffffff)==0) return x; + i1 = (i0&0x07fffff); + i0 &= 0xfff00000; + i0 |= ((i1|-i1)>>9)&0x400000; + SET_FLOAT_WORD(x,i0); + w = TWO23[sx]+x; + t = w-TWO23[sx]; + GET_FLOAT_WORD(i0,t); + SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31)); + return t; + } else { + i = (0x007fffff)>>j0; + if((i0&i)==0) return x; /* x is integral */ + i>>=1; + if((i0&i)!=0) i0 = (i0&(~i))|((0x100000)>>j0); + } + } else { + if(j0==0x80) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } + SET_FLOAT_WORD(x,i0); + w = TWO23[sx]+x; + return w-TWO23[sx]; +} +weak_alias (__rintf, rintf) +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_roundf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_roundf.cpp new file mode 100644 index 000000000..159d69f1b --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_roundf.cpp @@ -0,0 +1,76 @@ +/* See the import.pl script for potential modifications */ +/* Round Simple to integer away from zero. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1f of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "SMath.h" + +#include "math_private.h" + + +static const Simple huge = 1.0e30f; + + +namespace streflop_libm { +Simple +__roundf (Simple x) +{ + int32_t i0, j0; + + GET_FLOAT_WORD (i0, x); + j0 = ((i0 >> 23) & 0xff) - 0x7f; + if (j0 < 23) + { + if (j0 < 0) + { + if (huge + x > 0.0f) + { + i0 &= 0x80000000; + if (j0 == -1) + i0 |= 0x3f800000; + } + } + else + { + u_int32_t i = 0x007fffff >> j0; + if ((i0 & i) == 0) + /* X is integral. */ + return x; + if (huge + x > 0.0f) + { + /* Raise inexact if x != 0. */ + i0 += 0x00400000 >> j0; + i0 &= ~i; + } + } + } + else + { + if (j0 == 0x80) + /* Inf or NaN. */ + return x + x; + else + return x; + } + + SET_FLOAT_WORD (x, i0); + return x; +} +weak_alias (__roundf, roundf) +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_scalblnf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_scalblnf.cpp new file mode 100644 index 000000000..22d37d227 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_scalblnf.cpp @@ -0,0 +1,66 @@ +/* See the import.pl script for potential modifications */ +/* s_scalbnf.c -- Simple version of s_scalbn.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_scalbnf.c,v 1.4f 1995/05/10 20:48:10 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple +#else +static Simple +#endif +two25 = 3.355443200e+07f, /* 0x4c000000 */ +twom25 = 2.9802322388e-08f, /* 0x33000000 */ +huge = 1.0e+30f, +tiny = 1.0e-30f; + +#ifdef __STDC__ + Simple __scalblnf (Simple x, long int n) +#else + Simple __scalblnf (x,n) + Simple x; long int n; +#endif +{ + int32_t k,ix; + GET_FLOAT_WORD(ix,x); + k = (ix&0x7f800000)>>23; /* extract exponent */ + if (k==0) { /* 0 or subnormal x */ + if ((ix&0x7fffffff)==0) return x; /* +-0 */ + x *= two25; + GET_FLOAT_WORD(ix,x); + k = ((ix&0x7f800000)>>23) - 25; + } + if (k==0xff) return x+x; /* NaN or Inf */ + k = k+n; + if (n> 50000 || k > 0xfe) + return huge*copysignf(huge,x); /* overflow */ + if (n< -50000) + return tiny*copysignf(tiny,x); /*underflow*/ + if (k > 0) /* normal result */ + {SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); return x;} + if (k <= -25) + return tiny*copysignf(tiny,x); /*underflow*/ + k += 25; /* subnormal result */ + SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); + return x*twom25; +} +weak_alias (__scalblnf, scalblnf) +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_scalbnf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_scalbnf.cpp new file mode 100644 index 000000000..fd4d3efa7 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_scalbnf.cpp @@ -0,0 +1,66 @@ +/* See the import.pl script for potential modifications */ +/* s_scalbnf.c -- Simple version of s_scalbn.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_scalbnf.c,v 1.4f 1995/05/10 20:48:10 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple +#else +static Simple +#endif +two25 = 3.355443200e+07f, /* 0x4c000000 */ +twom25 = 2.9802322388e-08f, /* 0x33000000 */ +huge = 1.0e+30f, +tiny = 1.0e-30f; + +#ifdef __STDC__ + Simple __scalbnf (Simple x, int n) +#else + Simple __scalbnf (x,n) + Simple x; int n; +#endif +{ + int32_t k,ix; + GET_FLOAT_WORD(ix,x); + k = (ix&0x7f800000)>>23; /* extract exponent */ + if (k==0) { /* 0 or subnormal x */ + if ((ix&0x7fffffff)==0) return x; /* +-0 */ + x *= two25; + GET_FLOAT_WORD(ix,x); + k = ((ix&0x7f800000)>>23) - 25; + } + if (k==0xff) return x+x; /* NaN or Inf */ + k = k+n; + if (n> 50000 || k > 0xfe) + return huge*__copysignf(huge,x); /* overflow */ + if (n< -50000) + return tiny*__copysignf(tiny,x); /*underflow*/ + if (k > 0) /* normal result */ + {SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); return x;} + if (k <= -25) + return tiny*__copysignf(tiny,x); /*underflow*/ + k += 25; /* subnormal result */ + SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); + return x*twom25; +} +weak_alias (__scalbnf, scalbnf) +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_signbitf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_signbitf.cpp new file mode 100644 index 000000000..f2cbd901e --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_signbitf.cpp @@ -0,0 +1,35 @@ +/* See the import.pl script for potential modifications */ +/* Return nonzero value if number is negative. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1f of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "SMath.h" + +#include "math_private.h" + +namespace streflop_libm { +int +__signbitf (Simple x) +{ + int32_t hx; + + GET_FLOAT_WORD (hx, x); + return hx & 0x80000000; +} +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_sincosf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_sincosf.cpp new file mode 100644 index 000000000..02e78f7de --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_sincosf.cpp @@ -0,0 +1,77 @@ +/* See the import.pl script for potential modifications */ +/* Compute sine and cosine of argument. + Copyright (C) 1997, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1f of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "SMath.h" + +#include "math_private.h" + + +namespace streflop_libm { +void +__sincosf (Simple x, Simple *sinx, Simple *cosx) +{ + int32_t ix; + + /* High word of x. */ + GET_FLOAT_WORD (ix, x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if (ix <= 0x3f490fd8) + { + *sinx = __kernel_sinf (x, 0.0f, 0); + *cosx = __kernel_cosf (x, 0.0f); + } + else if (ix>=0x7f800000) + { + /* sin(Inf or NaN) is NaN */ + *sinx = *cosx = x - x; + } + else + { + /* Argument reduction needed. */ + Simple y[2]; + int n; + + n = __ieee754_rem_pio2f (x, y); + switch (n & 3) + { + case 0: + *sinx = __kernel_sinf (y[0], y[1], 1); + *cosx = __kernel_cosf (y[0], y[1]); + break; + case 1: + *sinx = __kernel_cosf (y[0], y[1]); + *cosx = -__kernel_sinf (y[0], y[1], 1); + break; + case 2: + *sinx = -__kernel_sinf (y[0], y[1], 1); + *cosx = -__kernel_cosf (y[0], y[1]); + break; + default: + *sinx = -__kernel_cosf (y[0], y[1]); + *cosx = __kernel_sinf (y[0], y[1], 1); + break; + } + } +} +weak_alias (__sincosf, sincosf) +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_sinf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_sinf.cpp new file mode 100644 index 000000000..1fdf78369 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_sinf.cpp @@ -0,0 +1,57 @@ +/* See the import.pl script for potential modifications */ +/* s_sinf.c -- Simple version of s_sin.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_sinf.c,v 1.4f 1995/05/10 20:48:16 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ + Simple __sinf(Simple x) +#else + Simple __sinf(x) + Simple x; +#endif +{ + Simple y[2],z=0.0f; + int32_t n, ix; + + GET_FLOAT_WORD(ix,x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if(ix <= 0x3f490fd8) return __kernel_sinf(x,z,0); + + /* sin(Inf or NaN) is NaN */ + else if (ix>=0x7f800000) return x-x; + + /* argument reduction needed */ + else { + n = __ieee754_rem_pio2f(x,y); + switch(n&3) { + case 0: return __kernel_sinf(y[0],y[1],1); + case 1: return __kernel_cosf(y[0],y[1]); + case 2: return -__kernel_sinf(y[0],y[1],1); + default: + return -__kernel_cosf(y[0],y[1]); + } + } +} +weak_alias (__sinf, sinf) +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_tanf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_tanf.cpp new file mode 100644 index 000000000..6de3015cd --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_tanf.cpp @@ -0,0 +1,52 @@ +/* See the import.pl script for potential modifications */ +/* s_tanf.c -- Simple version of s_tan.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_tanf.c,v 1.4f 1995/05/10 20:48:20 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ + Simple __tanf(Simple x) +#else + Simple __tanf(x) + Simple x; +#endif +{ + Simple y[2],z=0.0f; + int32_t n, ix; + + GET_FLOAT_WORD(ix,x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if(ix <= 0x3f490fda) return __kernel_tanf(x,z,1); + + /* tan(Inf or NaN) is NaN */ + else if (ix>=0x7f800000) return x-x; /* NaN */ + + /* argument reduction needed */ + else { + n = __ieee754_rem_pio2f(x,y); + return __kernel_tanf(y[0],y[1],1-((n&1)<<1)); /* 1 -- n even + -1 -- n odd */ + } +} +weak_alias (__tanf, tanf) +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_tanhf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_tanhf.cpp new file mode 100644 index 000000000..8000ea01e --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_tanhf.cpp @@ -0,0 +1,70 @@ +/* See the import.pl script for potential modifications */ +/* s_tanhf.c -- Simple version of s_tanh.c. + * Conversion to Simple 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. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_tanhf.c,v 1.4f 1995/05/10 20:48:24 jtc Exp $"; +#endif + +#include "SMath.h" +#include "math_private.h" + +namespace streflop_libm { +#ifdef __STDC__ +static const Simple one=1.0f, two=2.0f, tiny = 1.0e-30f; +#else +static Simple one=1.0f, two=2.0f, tiny = 1.0e-30f; +#endif + +#ifdef __STDC__ + Simple __tanhf(Simple x) +#else + Simple __tanhf(x) + Simple x; +#endif +{ + Simple t,z; + int32_t jx,ix; + + GET_FLOAT_WORD(jx,x); + ix = jx&0x7fffffff; + + /* x is INF or NaN */ + if(ix>=0x7f800000) { + if (jx>=0) return one/x+one; /* tanh(+-inf)=+-1 */ + else return one/x-one; /* tanh(NaN) = NaN */ + } + + /* |x| < 22 */ + if (ix < 0x41b00000) { /* |x|<22 */ + if (ix == 0) + return x; /* x == +-0 */ + if (ix<0x24000000) /* |x|<2**-55 */ + return x*(one+x); /* tanh(small) = small */ + if (ix>=0x3f800000) { /* |x|>=1 */ + t = __expm1f(two*fabsf(x)); + z = one - two/(t+two); + } else { + t = __expm1f(-two*fabsf(x)); + z= -t/(t+two); + } + /* |x| > 22, return +-1 */ + } else { + z = one - tiny; /* raised inexact flag */ + } + return (jx>=0)? z: -z; +} +weak_alias (__tanhf, tanhf) +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_truncf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_truncf.cpp new file mode 100644 index 000000000..97aa01f5c --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_truncf.cpp @@ -0,0 +1,55 @@ +/* See the import.pl script for potential modifications */ +/* Truncate argument to nearest integral value not larger than the argument. + Copyright (C) 1997, 1998 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1f of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "SMath.h" + +#include "math_private.h" + + +namespace streflop_libm { +Simple +__truncf (Simple x) +{ + int32_t i0, j0; + int sx; + + GET_FLOAT_WORD (i0, x); + sx = i0 & 0x80000000; + j0 = ((i0 >> 23) & 0xff) - 0x7f; + if (j0 < 23) + { + if (j0 < 0) + /* The magnitude of the number is < 1 so the result is +-0. */ + SET_FLOAT_WORD (x, sx); + else + SET_FLOAT_WORD (x, sx | (i0 & ~(0x007fffff >> j0))); + } + else + { + if (j0 == 0x80) + /* x is inf or NaN. */ + return x + x; + } + + return x; +} +weak_alias (__truncf, truncf) +} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/w_expf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/w_expf.cpp new file mode 100644 index 000000000..dea0363a2 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/flt-32/w_expf.cpp @@ -0,0 +1,13 @@ +/* See the import.pl script for potential modifications */ +/* The original libm wrapper may call the Double implementation + and declares Double constants. + This wrapper purely wraps the Simple version +*/ + +#include "math_private.h" + +namespace streflop_libm { +Simple __expf(Simple x) { + return __ieee754_expf(x); +} +} diff --git a/source/shared_lib/sources/streflop/libm/import.pl b/source/shared_lib/sources/streflop/libm/import.pl new file mode 100755 index 000000000..cb71762a1 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/import.pl @@ -0,0 +1,536 @@ +#!/usr/bin/perl + +# streflop: STandalone REproducible FLOating-Point + +# This script imports the GNU libm files and convert them in such a way they can be compiled with streflop types. + +# Code released according to the GNU Lesser General Public License +# Nicolas Brodu, 2006 + +# Please read the history and copyright information in the accompanying documentation + +if ($#ARGV==-1) { +print <> headers/endian.h"); + +# remove some routines we don't need +if (-r "ldbl-96/printf_fphex.c") {unlink "ldbl-96/printf_fphex.c";} +if (-r "ldbl-96/strtold_l.c") {unlink "ldbl-96/strtold_l.c";} +if (-r "flt-32/mpn2flt.c") {unlink "flt-32/mpn2flt.c";} +if (-r "dbl-64/mpn2dbl.c") {unlink "dbl-64/mpn2dbl.c";} +if (-r "dbl-64/dbl2mpn.c") {unlink "dbl-64/dbl2mpn.c";} +if (-r "dbl-64/t_exp.c") {unlink "dbl-64/t_exp.c";} +if (-r "ldbl-96/mpn2ldbl.c") {unlink "ldbl-96/mpn2ldbl.c";} +if (-r "ldbl-96/ldbl2mpn.c") {unlink "ldbl-96/ldbl2mpn.c";} +if (-r "ldbl-96/s_nexttoward.c") {unlink "ldbl-96/s_nexttoward.c";} +if (-r "ldbl-96/s_nexttowardf.c") {unlink "ldbl-96/s_nexttowardf.c";} +if (-r "ldbl-96/math_ldbl.h") {unlink "ldbl-96/math_ldbl.h";} + +# The float exp in e_expf.c uses doubles internally since revision 1.2 in the libm-ieee754 CVS attic! +# Roll back to the slower, but purely float version, and also overwrite the wrapper by a wraper to the float only version +system("cp -f w_expf.c e_expf.c flt-32"); + +# convert .c => .cpp for clarity +@filelist = glob("flt-32/*.c dbl-64/*.c ldbl-96/*.c"); +foreach $f (@filelist) { + $g = $f; + $g =~ s/\.c$/.cpp/; + rename $f, $g; +} + +# create dummy math.h stub +open(FILE, ">headers/math.h"); +print FILE <) { + # replace double by float, OK in these files + s/double/float/g; + $content.=$_; + } + close FILE; + open(FILE,">$f"); + print FILE $content; + close FILE; +} + +# These files in the dbl directory wrongly use float, long double and float functions +foreach $f ("dbl-64/e_lgamma_r.cpp", "dbl-64/t_exp2.h", "dbl-64/s_llrint.cpp") { + open(FILE,"<$f"); + $content = ""; + while() { + s/fabsf/fabs/g; + s/float/double/g; + s/long double/double/g; + $content.=$_; + } + close FILE; + open(FILE,">$f"); + print FILE $content; + close FILE; +} + +# These files in the ldbl directory wrongly use lower precision types +foreach $f ("ldbl-96/e_lgammal_r.cpp", "ldbl-96/s_cbrtl.cpp", "ldbl-96/s_logbl.cpp", "ldbl-96/s_ldexpl.cpp") { + open(FILE,"<$f"); + $content = ""; + while() { + # do the substitution now + s/long double/Extended/g; + s/\(double\) i;/(long double) i;/g; + s/double (_|v)/long double $1/g; + s/const double factor/const long double factor/g; + s/fabs(?!l)/fabsl$1/g; + s/ldexp(?!l)/ldexpl$1/g; + s/__finite\(/__finitel\(/g; + s/__scalbn\(/__scalbnl\(/g; + $content.=$_; + } + close FILE; + open(FILE,">$f"); + print FILE $content; + close FILE; +} + + +# DOUBLE_FROM_INT_PTR(x) could simply be *reinterpret_cast(x) +# for basic types, but may use a dedicated factory for Object wrappers +# BaseType is either the same as FloatType for plain old float/double, or it is +# the float/double type when FloatType is an Object wrapper +$xdaccessor= + "inline Double& d() {return DOUBLE_FROM_INT_PTR(&i[0]);}\n" +."inline Double& x() {return DOUBLE_FROM_INT_PTR(&i[0]);}\n" +."inline Double& d(int idx) {return DOUBLE_FROM_INT_PTR(&i[idx*(sizeof(double)/sizeof(i))]);}\n" +."inline Double& x(int idx) {return DOUBLE_FROM_INT_PTR(&i[idx*(sizeof(double)/sizeof(i))]);}\n" +."inline const Double& d() const {return CONST_DOUBLE_FROM_INT_PTR(&i[0]);}\n" +."inline const Double& x() const {return CONST_DOUBLE_FROM_INT_PTR(&i[0]);}\n" +."inline const Double& d(int idx) const {return CONST_DOUBLE_FROM_INT_PTR(&i[idx*(sizeof(double)/sizeof(i))]);}\n" +."inline const Double& x(int idx) const {return CONST_DOUBLE_FROM_INT_PTR(&i[idx*(sizeof(double)/sizeof(i))]);}\n" +; + +@filelist = glob("flt-32/* dbl-64/* ldbl-96/*"); + +foreach $f (@filelist) { + + open(FILE,"<$f"); + $content = ""; + $opened_namespace = 0; + while() { + # remove all system-wide includes + if (/.*?#include(.*?)(.*)/#$1include$2\"$3\"$4/g; + # fp environment is now handled directly by streflop (and FPUSettings.h) + s/fenv\.h/..\/streflop_libm_bridge.h/g; + # integer types handled by the bridge + s/inttypes\.h/..\/streflop_libm_bridge.h/g; + # get rid of stdlib too + s/stdlib\.h/..\/streflop_libm_bridge.h/g; + # and limits.h + s/limits\.h/..\/streflop_libm_bridge.h/g; + # float.h too + s/float\.h/..\/streflop_libm_bridge.h/g; + # errno.h falls back to system, remove it + s/errno\.h/..\/streflop_libm_bridge.h/g; + # replace all occurences of problematic union fields with objects + # by proper C++ accessors + s/\b(\.d(?!\[)\b|\.d\[(.*?)\])/.d($2)/g; + s/\b(\.x(?!\[)\b|\.x\[(.*?)\])/.x($2)/g; + s/\b(\.f(?!\[)\b|\.f\[(.*?)\])/.f($2)/g; # ieee754.h + s/\b(->d(?!\[)\b|->d\[(.*?)\])/->d($2)/g; + s/\b(->x(?!\[)\b|->x\[(.*?)\])/->x($2)/g; + s/\b(->f(?!\[)\b|->f\[(.*?)\])/->f($2)/g; # ieee754.h + # Some more occurences from arrays of such unions/structs + s/\]\.d\b/].d()/g; + # named field C construct is invalid (C++ would initialize first union member) + # and we replace unions by struct + accessor anyway + s/{ *?.i *?= *?{/{{/g; + # volatile declaration of static const global variables poses problem with the wrapper types + s/volatile //g; + # Now substitute the base types by their Simple/Double/Extended aliases or wrapper + s/long double/Extended/g; # before double + s/\bdouble\b/Double/g; + s/\bfloat\b/Simple/g; + # Replace problematic int += double + s/E(X|Y|Z)(.*?=.*?)ONE/E${1}${2}1/g; + # problematic ?: operator with different types. This simple check catches all problematic occurences +# if (/\?(.*?(\b0\.|\.0).*?:.*?|.*?:.*?(\b0\.|\.0).*?);/) { +# print "$f => ?$1;\n"; +# } + if (/\?(.*?):(.*?)\b(0\.0|10\.0|1\.0)\b/) { + my $type = ""; + if ($f =~ /flt-32/) {$type = "Simple";} + if ($f =~ /dbl-64/) {$type = "Double";} + if ($f =~ /ldbl-96/) {$type = "Extended";} + s/\?(.*?):(.*?)\b(0\.0|10\.0|1\.0)\b/?$1:$2$type($3)/g; + } + my $type = ""; + my $flit = ""; + if ($f =~ /flt-32/) {$type = "Simple"; $flit = "f";} + if ($f =~ /dbl-64/) {$type = "Double"; $flit = "";} + if ($f =~ /ldbl-96/) {$type = "Extended"; $flit = "l";} + # replace problematic mixed-type ?: operators where an int and a float are used as arguments, incompatible with wrappers + if (/\?(.*?)\b(0\.0|1\.0)\b(.*?):(.*?)/) { + s/\?(.*?)\b(0\.0|1\.0)\b(.*?):(.*?)/?$1$type($2)$3:$4/g; + } + # These special cases are OK because no other ?: pattern use them in the 3 subdirs + s/\?0:/?Double(0.0):/; + s/:0;/:Double(0.0);/; + # protect the new symbol names by namespace to avoid any conflict with system libm + if (((/#ifdef __STDC__/) || (/.*? (__|mcr|ss32)[a-z,A-Z,_,0-9]*?\(.*?{$/) || (/Double (atan2Mp|atanMp|slow|tanMp|__exp1|__ieee754_remainder|__ieee754_sqrt)/) || (/^(Simple|Double|Extended|void|int)$/) || ((/^#ifdef BIG_ENDI$/) && ($f =~ /(uatan|mpa2|mpexp|atnat|sincos32)/)) || (/^#define MM 5$/) || (/^void __mp(log|sqrt|exp|atan)\(/) || (/^int __(b|mp)ranred\(/)) && ($opened_namespace == 0)) { + $_ = "namespace streflop_libm {\n".$_; + $opened_namespace = 1; + } + + # Prevent type promotion for native aliases + # Ex: promotion would cause computations like y = 0.5 * x to be done in double for x,y float, then cast back to float + # We want the whole computation done in float, not temporary switching to double. + # In some case the FPU internal precision is enough to mask the problem, but for SSE for example, the float/double + # are using different instructions and the problem cannot be ignored (in these cases, there are differences from + # soft float implementation) + # Cannot replace by s/blah/$type($1)/g; because of static order initialization fiasco with wrapper types + # So use next best option to use litteral type specification + # => this solves the problem for native types + # => wrappers are OK thanks to the redefinitions of the operators + s/\b((\d+\.\d*|\d*\.\d+)((e|E)[-+]?\d+)?)(f|F|l|L)?\b/$1$flit/g; + $content.=$_; + } + close FILE; + # multi-line spanning regexp + $content =~ s/union ?{(.*?);.*?Double.*?}/struct {\n$xdaccessor$1;}/sg; + # close opened namespace + if ($opened_namespace==1) { + $content .= "}\n"; + } + open(FILE,">$f"); + print FILE $importNotice; + print FILE $content; + close FILE; +} + + +# ieee754.h union+accessor +open(FILE,") { + # Comment out decls sections + if (/.*?__.*?_DECLS.*/) {$_="//".$_;} + # Convert all includes to local files + s/^([ \t]*)#include([ \t]*)<(.*)>(.*)/#$1include$2\"$3\"$4/g; + # insert our own bridge + if (/^#define _IEEE754_H.*/) { + $_.="#include \"../streflop_libm_bridge.h\"\n\n"; + } + # Protect the Simple section by a #define + if (/.*?ieee754_float.*?/) { + $_ = "#if defined(LIBM_COMPILING_FLT32)\n".$_; + } + if (/.*?IEEE754_FLOAT_BIAS.*?/) { + $_ = $_."\n#endif\n"; + } + # Protect the Double section by a #define + if (/.*?ieee754_double.*?/) { + $_ = "#if defined(LIBM_COMPILING_DBL64)\n".$_; + } + if (/.*?IEEE754_DOUBLE_BIAS.*?/) { + $_ = $_."\n#endif\n"; + } + # Protect the Extended section by a #define + if (/.*?ieee854_long_double.*?/) { + $_ = "#if defined(Extended)\n".$_; + $_ = "#if defined(LIBM_COMPILING_LDBL96)\n".$_; + } + if (/.*?IEEE854_LONG_DOUBLE_BIAS.*?/) { + $_ = $_."\n#endif\n"; + $_ = $_."\n#endif\n"; + } + $content.=$_; +} +$ieeeAccessorSimple= + "inline Simple& f() {return SIMPLE_FROM_INT_PTR(&storage[0]);}\n" +."inline const Simple& f() const {return CONST_SIMPLE_FROM_INT_PTR(&storage[0]);}\n"; +$ieeeAccessorDouble= + "inline Double& d() {return DOUBLE_FROM_INT_PTR(&storage[0]);}\n" +."inline const Double& d() const {return CONST_DOUBLE_FROM_INT_PTR(&storage[0]);}\n"; +$ieeeAccessorExtended= + "inline Extended& d() {return EXTENDED_FROM_INT_PTR(&storage[0]);}\n" +."inline const Extended& d() const {return CONST_EXTENDED_FROM_INT_PTR(&storage[0]);}\n"; + +# multi-line spanning regexp +$content =~ s/union(.*?ieee854_long_double.*?){.*?;/union$1\{\nint storage[sizeof(long double)\/sizeof(int)];\n$ieeeAccessorExtended/sg; +$content =~ s/union(.*?ieee754_double.*?){.*?;/union$1\{\nint storage[sizeof(double)\/sizeof(int)];\n$ieeeAccessorDouble/sg; +$content =~ s/union(.*?ieee754_float.*?){.*?;/union$1\{\nint storage[sizeof(float)\/sizeof(int)];\n$ieeeAccessorSimple/sg; +close FILE; +open(FILE,">headers/ieee754.h"); +print FILE $importNotice; +print FILE $content; +close FILE; + +# math_private.h needs a special treatement to define the macros for the wrapper objects +# The macros will be defined separately +open(FILE,") { + # keep initial lines with header information and #define file protection + # skip all lines defining macros and unions + if (/^#define _MATH_PRIVATE_H_.*/) { + push @convert,$_; + push @convert,"\n/* import.pl: Skipped the macro definitions, keep only the declarations, converted to use streflop types (aliases or wrappers) */\n#include \"../streflop_libm_bridge.h\"\n\nnamespace streflop_libm {\n\n"; + # ensure strict separation of precision mode, each one does not have access to the other names + push @convert,"#ifdef LIBM_COMPILING_FLT32\n"; + # define wrappers as the libm would do in IEEE754 mode + push @convert,"#define __sqrtf __ieee754_sqrtf\n"; + push @convert,"#define fabsf __fabsf\n"; + push @convert,"#define copysignf __copysignf\n"; + # add missing defines + push @convert,"extern Simple __log1pf(Simple x);\n"; + push @convert,"extern Simple __fabsf(Simple x);\n"; + push @convert,"extern Simple __atanf(Simple x);\n"; + push @convert,"extern Simple __expm1f(Simple x);\n"; + push @convert,"extern int __isinff(Simple x);\n"; + push @convert,"extern Simple __rintf(Simple x);\n"; + push @convert,"extern Simple __cosf(Simple x);\n"; + push @convert,"extern void __sincosf (Simple x, Simple *sinx, Simple *cosx);\n"; + push @convert,"extern Simple __floorf(Simple x);\n"; + push @convert,"extern Simple __scalbnf (Simple x, int n);\n"; + push @convert,"extern Simple __frexpf(Simple x, int *eptr);\n"; + push @convert,"extern Simple __ldexpf(Simple value, int exp);\n"; + push @convert,"extern int __finitef(Simple x);\n"; + push @convert,"#endif\n\n"; + push @convert,"#ifdef LIBM_COMPILING_DBL64\n"; + push @convert,"#define __sqrt __ieee754_sqrt\n"; + push @convert,"#define fabs __fabs\n"; + push @convert,"#define copysign __copysign\n"; + push @convert,"extern Double __log1p(Double x);\n"; + push @convert,"extern Double __fabs(Double x);\n"; + push @convert,"extern Double atan(Double x);\n"; + push @convert,"extern Double __expm1(Double x);\n"; + push @convert,"extern int __isinf(Double x);\n"; + push @convert,"extern Double __rint(Double x);\n"; + push @convert,"extern Double __cos(Double x);\n"; + push @convert,"extern void __sincos (Double x, Double *sinx, Double *cosx);\n"; + push @convert,"extern Double __floor(Double x);\n"; + push @convert,"extern Double __scalbn(Double x, int n);\n"; + push @convert,"extern Double __frexp(Double x, int *eptr);\n"; + push @convert,"extern Double __ldexp(Double value, int exp);\n"; + push @convert,"extern int __finite(Double x);\n"; + push @convert,"#endif\n\n"; + push @convert,"#ifdef LIBM_COMPILING_LDBL96\n"; + push @convert,"#if defined(Extended)\n"; + push @convert,"#define fabsl __fabsl\n"; + push @convert,"extern Extended __cosl(Extended x);\n"; + push @convert,"extern Extended __sinl(Extended x);\n"; + push @convert,"extern Extended __fabsl(Extended x);\n"; + push @convert,"#endif\n"; + push @convert,"#endif\n"; + push @convert,"\n"; + $flag = 0; + } + if (/^extern(.*)/) { + $flag = 1; + } + if ($flag==0) {next MPRIV_LOOP;} + + + + # Now substitute the base types by their Simple/Double/Extended aliases or wrapper + s/\blong double\b/Extended/g; # before double + s/\bdouble\b/Double/g; + s/\bfloat\b/Simple/g; + # Protect the Extended section by a #define + if (/.*?elementary Extended functions.*?/) { + $_ = "#if defined(Extended)\n".$_; + } + if (/.*?functions of the IBM.*?/) { + $_ = "#endif\n\n".$_; + } + # remove the inline aliases + s/__GNUC_PREREQ \(.*?\)/0/; + # end namespace protection + if (/^#endif.*_MATH_PRIVATE_H_/) { + $_ = "}\n\n".$_; + } + + # now insert protection for symbols separation + if (/^extern(.*)/) { + $remline = $1; + if ($remline =~ /Extended/) { + if ($precisionMode ne "Extended") { + if ($precisionMode ne "none") {$_ = "#endif\n".$_;} + $_ = "#ifdef LIBM_COMPILING_LDBL96\n".$_; + $precisionMode = "Extended"; + } + } + elsif ($remline =~ /Double/) { + if ($precisionMode ne "Double") { + if ($precisionMode ne "none") {$_ = "#endif\n".$_;} + $_ = "#ifdef LIBM_COMPILING_DBL64\n".$_; + $precisionMode = "Double"; + } + } + elsif ($remline =~ /Simple/) { + if ($precisionMode ne "Simple") { + if ($precisionMode ne "none") {$_ = "#endif\n".$_;} + $_ = "#ifdef LIBM_COMPILING_FLT32\n".$_; + $precisionMode = "Simple"; + } + } + } else { + $line = $_; + chomp $line; + if (($line =~ /^(\s)*$/) && ($precisionMode ne "none")) { + $_ = "#endif\n".$_; + $precisionMode = "none"; + } + } + + push @convert,$_; +} +close FILE; +open(FILE,">headers/math_private.h"); +print FILE $importNotice; +print FILE @convert; +close FILE; + +# features.h is nearly ready, just do not include more external defs +open(FILE,") { + # commment out external includes + s,(.*?#.*?include.*),//$1,; + push @convert,$_; +} +close FILE; +open(FILE,">headers/features.h"); +print FILE $importNotice; +print FILE @convert; +close FILE; + +# headers/endian.h +open(FILE,") { + # change machine specific bits/endian by streflop configuration + if (//) { + s,,\"../streflop_libm_bridge.h\",; + #keep features.h, but locally + } elsif (//) { + s,,"features.h",; + } else { + # commment out all other external includes + s,(.*?#.*?include.*),//$1,; + } + #unconditional definition of endian things + if (/defined _LIBC/) { + $_ = "#if 1\n//".$_; + } + push @convert,$_; +} +close FILE; +open(FILE,">headers/endian.h"); +print FILE $importNotice; +print FILE @convert; +close FILE; + + +# include the bridge from mpa.h +open(FILE,") { + # special case + s/->d\(\)/->mantissa/g; + $content.=$_; +} +close FILE; +$mpAccessor= + "inline Double& d(int idx) {return mantissa[idx];}\n" +."inline const Double& d(int idx) const {return mantissa[idx];}\n"; +# multi-line spanning regexp +$content =~ s/Double d\[(.*?)\].*?} mp_no/Double mantissa[$1];\n$mpAccessor} mp_no/sg; +open(FILE,">dbl-64/mpa.h"); +print FILE $content."}\n"; # also close namespace +close FILE; + +# Generate specific Makefiles +$parentMakefile=""; +foreach $dir ("flt-32", "dbl-64", "ldbl-96") { + @objFiles = glob("$dir/*.cpp"); + $parentObjects = "$dir-objects ="; + foreach $f (@objFiles) { + $f =~ s/\.cpp$/.o/; + $parentObjects .= " libm/$f"; + $f =~ s/^$dir\///; + } + open(FILE, ">$dir/Makefile"); + my $DIR = uc($dir); + $DIR =~ s/\-//; + print FILE "# Makefile automatically generated by import.pl\n" + ."include ../../Makefile.common\n" + ."CPPFLAGS += -I../headers -DLIBM_COMPILING_$DIR=1\n" + ."all: @objFiles\n" + ."\techo '$dir done!'\n"; + close FILE; + $parentMakefile .= $parentObjects."\n\n"; +} + +# generate Makefile rule in parent directory +@projectFiles = glob("flt-32/* dbl-64/* ldbl-96/* headers/*"); +foreach $f (@projectFiles) {$f = " libm/$f";} +open(FILE, ">../Makefile.libm_objects"); +print FILE "# Makefile automatically generated by libm/import.pl. Do not edit.\n\n" + .$parentMakefile + ."\nlibm-src ="; +print FILE @projectFiles; +print FILE "\n"; +close FILE; diff --git a/source/shared_lib/sources/streflop/libm/w_expf.c b/source/shared_lib/sources/streflop/libm/w_expf.c new file mode 100644 index 000000000..a1cc988d6 --- /dev/null +++ b/source/shared_lib/sources/streflop/libm/w_expf.c @@ -0,0 +1,10 @@ +/* The original libm wrapper may call the double implementation + and declares double constants. + This wrapper purely wraps the float version +*/ + +#include "math_private.h" + +float __expf(float x) { + return __ieee754_expf(x); +} diff --git a/source/shared_lib/sources/streflop/streflopC.cpp b/source/shared_lib/sources/streflop/streflopC.cpp new file mode 100644 index 000000000..032b6c8fb --- /dev/null +++ b/source/shared_lib/sources/streflop/streflopC.cpp @@ -0,0 +1,27 @@ +/* Copyright (C) 2009 Tobi Vollebregt */ + +#include "streflopC.h" + +#include "streflop_cond.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void streflop_init_Simple() { + streflop_init(); +} + +void streflop_init_Double() { + streflop_init(); +} + +#if defined(Extended) +void streflop_init_Extended() { + streflop_init(); +} +#endif // defined(Extended) + +#ifdef __cplusplus +} // extern "C" +#endif