From bb06162a599315ba697cb3df4f11c3c94e037327 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B2=88=E8=BE=BE?= Date: Tue, 28 Dec 2021 22:18:05 +0800 Subject: [PATCH] Use JEAIII itoa --- CMakeLists.txt | 3 + src/Kernel/Types/string.cpp | 20 +++++ src/Plugins/Jeaiii/itoa_jeaiii.cpp | 132 +++++++++++++++++++++++++++++ src/Plugins/Jeaiii/itoa_jeaiii.hpp | 21 +++++ src/System/config.h.cmake | 2 + 5 files changed, 178 insertions(+) create mode 100644 src/Plugins/Jeaiii/itoa_jeaiii.cpp create mode 100644 src/Plugins/Jeaiii/itoa_jeaiii.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f9bd3ab5a..f8e8ec44d2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -359,6 +359,8 @@ else (WIN32) option (USE_STACK_TRACE "Use stack trace" ON) endif (WIN32) +option (USE_JEAIII "Use JEAIII itoa" ON) + set (CONFIG_STD_SETENV "#define STD_SETENV") set (tm_orig ${TEXMACS_SOURCE_DIR}) set (CONFIG_HOST_OS "linux-gnu") # TODO: should not be hard-coded @@ -479,6 +481,7 @@ file (GLOB_RECURSE TeXmacs_Std_Plugins_SRCS "${TEXMACS_SOURCE_DIR}/src/Plugins/Cairo/*.cpp" "${TEXMACS_SOURCE_DIR}/src/Plugins/Database/*.cpp" "${TEXMACS_SOURCE_DIR}/src/Plugins/Freetype/*.cpp" + "${TEXMACS_SOURCE_DIR}/src/Plugins/Jeaiii/*.cpp" "${TEXMACS_SOURCE_DIR}/src/Plugins/Pdf/*.cpp" "${TEXMACS_SOURCE_DIR}/src/Plugins/Pdf/*.c" "${TEXMACS_SOURCE_DIR}/src/Plugins/Ghostscript/*.cpp" diff --git a/src/Kernel/Types/string.cpp b/src/Kernel/Types/string.cpp index a9fe595445..455121535c 100644 --- a/src/Kernel/Types/string.cpp +++ b/src/Kernel/Types/string.cpp @@ -15,6 +15,10 @@ #include #include +#ifdef USE_JEAIII +#include "Jeaiii/itoa_jeaiii.hpp" +#endif + /****************************************************************************** * Low level routines and constructors ******************************************************************************/ @@ -286,7 +290,11 @@ as_string_bool (bool f) { string as_string (int i) { char buf[64]; +#ifdef USE_JEAIII + i32toa_jeaiii (i, buf); +#else sprintf (buf, "%i", i); +#endif // sprintf (buf, "%i\0", i); return string (buf); } @@ -294,7 +302,11 @@ as_string (int i) { string as_string (unsigned int i) { char buf[64]; +#ifdef USE_JEAIII + u32toa_jeaiii (i, buf); +#else sprintf (buf, "%u", i); +#endif // sprintf (buf, "%u\0", i); return string (buf); } @@ -302,7 +314,11 @@ as_string (unsigned int i) { string as_string (long int i) { char buf[64]; +#ifdef USE_JEAIII + i64toa_jeaiii (i, buf); +#else sprintf (buf, "%li", i); +#endif // sprintf (buf, "%li\0", i); return string (buf); } @@ -322,7 +338,11 @@ as_string (long long int i) { string as_string (unsigned long int i) { char buf[64]; +#ifdef USE_JEAIII + u64toa_jeaiii (i, buf); +#else sprintf (buf, "%lu", i); +#endif // sprintf (buf, "%lu\0", i); return string (buf); } diff --git a/src/Plugins/Jeaiii/itoa_jeaiii.cpp b/src/Plugins/Jeaiii/itoa_jeaiii.cpp new file mode 100644 index 0000000000..e499006722 --- /dev/null +++ b/src/Plugins/Jeaiii/itoa_jeaiii.cpp @@ -0,0 +1,132 @@ +/* +MIT License +Copyright (c) 2017 James Edward Anhalt III - https://github.com/jeaiii/itoa +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "itoa_jeaiii.hpp" + +// form a 4.32 fixed point number: t = u * 2^32 / 10^log10(u) +// use as much precision as possible when needed (log10(u) >= 5) +// so shift up then down afterwards by log10(u) * log2(10) ~= 53/16 +// need to round up before and or after in some cases +// once we have the fixed point number we can read off the digit in the upper 32 bits +// and multiply the lower 32 bits by 10 to get the next digit and so on +// we can do 2 digits at a time by multiplying by 100 each time + +// TODO: +// x64 optimized verison (no need to line up on 32bit boundary, so can multiply by 5 instead of 10 using lea instruction) +// full 64 bit LG() +// try splitting the number into chucks that can be processed independently +// try odd digit first +// try writing 4 chars at a time + +#if 0 +// 1 char at a time + +#define W(N, I) b[N] = char(I) + '0' +#define A(N) t = (uint64_t(1) << (32 + N / 5 * N * 53 / 16)) / uint32_t(1e##N) + 1 - N / 9, t *= u, t >>= N / 5 * N * 53 / 16, t += N / 5 * 4, W(0, t >> 32) +#define D(N) t = uint64_t(10) * uint32_t(t), W(N, t >> 32) + +#define L0 W(0, u) +#define L1 A(1), D(1) +#define L2 A(2), D(1), D(2) +#define L3 A(3), D(1), D(2), D(3) +#define L4 A(4), D(1), D(2), D(3), D(4) +#define L5 A(5), D(1), D(2), D(3), D(4), D(5) +#define L6 A(6), D(1), D(2), D(3), D(4), D(5), D(6) +#define L7 A(7), D(1), D(2), D(3), D(4), D(5), D(6), D(7) +#define L8 A(8), D(1), D(2), D(3), D(4), D(5), D(6), D(7), D(8) +#define L9 A(9), D(1), D(2), D(3), D(4), D(5), D(6), D(7), D(8), D(9) + +#else +// 2 chars at a time + +struct pair { char t, o; }; +#define P(T) T, '0', T, '1', T, '2', T, '3', T, '4', T, '5', T, '6', T, '7', T, '8', T, '9' +static const pair s_pairs[] = { P('0'), P('1'), P('2'), P('3'), P('4'), P('5'), P('6'), P('7'), P('8'), P('9') }; + +#define W(N, I) *(pair*)&b[N] = s_pairs[I] +#define A(N) t = (uint64_t(1) << (32 + N / 5 * N * 53 / 16)) / uint32_t(1e##N) + 1 + N/6 - N/8, t *= u, t >>= N / 5 * N * 53 / 16, t += N / 6 * 4, W(0, t >> 32) +#define S(N) b[N] = char(uint64_t(10) * uint32_t(t) >> 32) + '0' +#define D(N) t = uint64_t(100) * uint32_t(t), W(N, t >> 32) + +#define L0 b[0] = char(u) + '0' +#define L1 W(0, u) +#define L2 A(1), S(2) +#define L3 A(2), D(2) +#define L4 A(3), D(2), S(4) +#define L5 A(4), D(2), D(4) +#define L6 A(5), D(2), D(4), S(6) +#define L7 A(6), D(2), D(4), D(6) +#define L8 A(7), D(2), D(4), D(6), S(8) +#define L9 A(8), D(2), D(4), D(6), D(8) + +#endif + +#define LN(N) (L##N, b += N + 1) +// #define LZ LN +// if you want to '\0' terminate +#define LZ(N) &(L##N, b[N + 1] = '\0') + +#define LG(F) (u<100 ? u<10 ? F(0) : F(1) : u<1000000 ? u<10000 ? u<1000 ? F(2) : F(3) : u<100000 ? F(4) : F(5) : u<100000000 ? u<10000000 ? F(6) : F(7) : u<1000000000 ? F(8) : F(9)) + +char* u32toa_jeaiii(uint32_t u, char* b) +{ + uint64_t t; + return LG(LZ); +} + +char* i32toa_jeaiii(int32_t i, char* b) +{ + uint32_t u = i < 0 ? *b++ = '-', 0 - uint32_t(i) : i; + uint64_t t; + return LG(LZ); +} + +char* u64toa_jeaiii(uint64_t n, char* b) +{ + uint32_t u; + uint64_t t; + + if (uint32_t(n >> 32) == 0) + return u = uint32_t(n), LG(LZ); + + uint64_t a = n / 100000000; + + if (uint32_t(a >> 32) == 0) + { + u = uint32_t(a); + LG(LN); + } + else + { + u = uint32_t(a / 100000000); + LG(LN); + u = a % 100000000; + LN(7); + } + + u = n % 100000000; + return LZ(7); +} + +char* i64toa_jeaiii(int64_t i, char* b) +{ + uint64_t n = i < 0 ? *b++ = '-', 0 - uint64_t(i) : i; + return u64toa_jeaiii(n, b); +} \ No newline at end of file diff --git a/src/Plugins/Jeaiii/itoa_jeaiii.hpp b/src/Plugins/Jeaiii/itoa_jeaiii.hpp new file mode 100644 index 0000000000..8c3b7c8305 --- /dev/null +++ b/src/Plugins/Jeaiii/itoa_jeaiii.hpp @@ -0,0 +1,21 @@ + +/****************************************************************************** +* MODULE : itoa_jeaiii.hpp +* COPYRIGHT : (C) 2019 Darcy Shen +******************************************************************************* +* This software falls under the GNU general public license version 3 or later. +* It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE +* in the root directory or . +******************************************************************************/ + +#ifndef ITOA_JEAIII_H +#define ITOA_JEAIII_H + +#include + +char* u32toa_jeaiii (uint32_t u, char* b); +char* i32toa_jeaiii (int32_t i, char* b); +char* u64toa_jeaiii (uint64_t n, char* b); +char* i64toa_jeaiii (int64_t i, char* b); + +#endif // ITOA_JEAIII_H diff --git a/src/System/config.h.cmake b/src/System/config.h.cmake index 9cb1de341e..4e3acdea73 100644 --- a/src/System/config.h.cmake +++ b/src/System/config.h.cmake @@ -166,6 +166,8 @@ #cmakedefine USE_STACK_TRACE 1 +#cmakedefine USE_JEAIII 1 + /* Define to 1 if the X Window System is missing or not being used. */ #cmakedefine X_DISPLAY_MISSING 1