mirror of
https://github.com/sqlite/sqlite.git
synced 2026-10-23 21:49:02 +03:00
Avoid using unsigned 64-bit integer division on platforms that do not support
it in hardware. FossilOrigin-Name: 2197677491dfc5ec87b57bbf807776875248a250f80ce9a5ce94ae385bb1d2bc
This commit is contained in:
@@ -2630,8 +2630,8 @@ smoketest: $(TESTPROGS)
|
||||
# Measure the performance of floating-point conversions.
|
||||
#
|
||||
fp-speed-test: fp-speed-1.exe fp-speed-2.exe
|
||||
fp-speed-1 10000000
|
||||
fp-speed-2 10000000
|
||||
fp-speed-1 1000000
|
||||
fp-speed-2 1000000
|
||||
|
||||
shelltest:
|
||||
$(TCLSH_CMD) $(TOP)\test\testrunner.tcl release shell
|
||||
|
||||
4
main.mk
4
main.mk
@@ -1923,8 +1923,8 @@ shelltest:
|
||||
# Test performance of floating-point conversions.
|
||||
#
|
||||
fp-speed-test: fp-speed-1$(T.exe) fp-speed-2$(T.exe)
|
||||
./fp-speed-1 10000000
|
||||
./fp-speed-2 10000000
|
||||
./fp-speed-1 1000000
|
||||
./fp-speed-2 1000000
|
||||
|
||||
#
|
||||
# sqlite3_analyzer.c build depends on $(LINK_TOOLS_DYNAMICALLY).
|
||||
|
||||
18
manifest
18
manifest
@@ -1,12 +1,12 @@
|
||||
C The\s_umulh()\sintrinsic\sfunction\sis\snot\savailable\son\s32-bit\swindows.\s\sSo\sdon't\nuse\sit\sthere.
|
||||
D 2026-03-29T10:32:25.815
|
||||
C Avoid\susing\sunsigned\s64-bit\sinteger\sdivision\son\splatforms\sthat\sdo\snot\ssupport\nit\sin\shardware.
|
||||
D 2026-03-29T19:06:36.213
|
||||
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md 6bc480fc673fb4acbc4094e77edb326267dd460162d7723c7f30bee2d3d9e97d
|
||||
F Makefile.in 3ce07126d7e87c7464301482e161fdae6a51d0a2aa06b200b8f0000ef4d6163b
|
||||
F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0
|
||||
F Makefile.msc 05dffae7914a3e3accd6056d71ec2bf5dff563a728592373b828882a52141067
|
||||
F Makefile.msc 92391304cf70f4c178b127aa83b88637abd28d1b83ede451616144037ea1d3dd
|
||||
F README.md 3fa51fc7ababc32edd175ae8b2986c86d5ea120c1cb1e57c7f7849492d1405ec
|
||||
F VERSION 31435e19ded2aae3c1c67dacf06a995a37fd1b253baec5899b78d64cd29db4f7
|
||||
F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5
|
||||
@@ -655,7 +655,7 @@ F ext/wasm/tests/opfs/sahpool/index.html be736567fd92d3ecb9754c145755037cbbd2bca
|
||||
F ext/wasm/tests/opfs/sahpool/sahpool-pausing.js f264925cfc82155de38cecb3d204c36e0f6991460fff0cb7c15079454679a4e2
|
||||
F ext/wasm/tests/opfs/sahpool/sahpool-worker.js bd25a43fc2ab2d1bafd8f2854ad3943ef673f7c3be03e95ecf1612ff6e8e2a61
|
||||
F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0
|
||||
F main.mk ac1cafc6f08d108f99cf74f686f1a7f8a08569279341f9d6ffb7745c1fba66f6
|
||||
F main.mk 0ed98e9faa3a8e2ce40ec5b55781101048c13c6970bc50d456d4c2834e74f4ea
|
||||
F make.bat a136fd0b1c93e89854a86d5f4edcf0386d211e5d5ec2434480f6eea436c7420c
|
||||
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
|
||||
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
|
||||
@@ -738,7 +738,7 @@ F src/shell.c.in 91ee40ec3f75192362cbaa0ad85316140b8dde00a184113d73a837fb6173dbc
|
||||
F src/sqlite.h.in e7acbb01518f05c5a342149ec1eeb1afcdccf9b90a6e9770a4893ae9a3c756ae
|
||||
F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
|
||||
F src/sqlite3ext.h 1b7a0ee438bb5c2896d0609c537e917d8057b3340f6ad004d2de44f03e3d3cca
|
||||
F src/sqliteInt.h 9716721fb57e32938a1d30a84560ce7633c63860a2209e188c87afad15d4b464
|
||||
F src/sqliteInt.h 9d6e04c079cade18c32bcf615552ac5dfba6a151b29abd2319c368764a5d297e
|
||||
F src/sqliteLimit.h c70656b67ab5b96741a8f1c812bdd80c81f2b1c1e443d0cc3ea8c33bb1f1a092
|
||||
F src/status.c 7565d63a79aa2f326339a24a0461a60096d0bd2bce711fefb50b5c89335f3592
|
||||
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
||||
@@ -798,7 +798,7 @@ F src/trigger.c 4bf3bfb3851d165e4404a9f9e69357345f3f7103378c07e07139fdd8aeb7bd20
|
||||
F src/update.c 3e5e7ff66fa19ebe4d1b113d480639a24cc1175adbefabbd1a948a07f28e37cf
|
||||
F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1
|
||||
F src/utf.c 7267c3fb9e2467020507601af3354c2446c61f444387e094c779dccd5ca62165
|
||||
F src/util.c 1fe895c652b3b1b9f4a298b95ebfcfd95e3383952dd26a5baf1c47655c483e5d
|
||||
F src/util.c f264a84eda716ae009089f1d788b55718062810792b0bfa331e7899f2add39c6
|
||||
F src/vacuum.c d3d35d8ae893d419ade5fa196d761a83bddcbb62137a1a157ae751ef38b26e82
|
||||
F src/vdbe.c 6c57525d7db0232d52687d30da1093db0c152f14206c2ef1adf0c19a09d863e3
|
||||
F src/vdbe.h 70e862ac8a11b590f8c1eaac17a0078429d42bc4ea3f757a9af0f451dd966a71
|
||||
@@ -2196,8 +2196,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee
|
||||
F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
|
||||
P ff9008e7615d877e6cc852c60097777006b274971646d368eaa56b99a7acf6c7
|
||||
R ff4274da2fda9408dbca94e175d79321
|
||||
P e75f30c7e66e725a2f3f46c7d4d69a2ff925e2de9a86c3a6ec38897545b43a58
|
||||
R afdcaa646f7e2c48f9521367d5bf245b
|
||||
U drh
|
||||
Z 399684f83892f09fa733c31059114ff6
|
||||
Z d27904683472a5531629ef5a5e64c8f1
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
||||
@@ -1 +1 @@
|
||||
e75f30c7e66e725a2f3f46c7d4d69a2ff925e2de9a86c3a6ec38897545b43a58
|
||||
2197677491dfc5ec87b57bbf807776875248a250f80ce9a5ce94ae385bb1d2bc
|
||||
|
||||
@@ -4828,17 +4828,22 @@ struct PrintfArguments {
|
||||
sqlite3_value **apArg; /* The argument values */
|
||||
};
|
||||
|
||||
/*
|
||||
** Maxium number of base-10 digits in an unsigned 64-bit integer
|
||||
*/
|
||||
#define SQLITE_U64_DIGITS 20
|
||||
|
||||
/*
|
||||
** An instance of this object receives the decoding of a floating point
|
||||
** value into an approximate decimal representation.
|
||||
*/
|
||||
struct FpDecode {
|
||||
int n; /* Significant digits in the decode */
|
||||
int iDP; /* Location of the decimal point */
|
||||
char *z; /* Start of significant digits */
|
||||
char zBuf[20]; /* Storage for significant digits */
|
||||
char sign; /* '+' or '-' */
|
||||
char isSpecial; /* 1: Infinity 2: NaN */
|
||||
int n; /* Significant digits in the decode */
|
||||
int iDP; /* Location of the decimal point */
|
||||
char *z; /* Start of significant digits */
|
||||
char zBuf[SQLITE_U64_DIGITS+1]; /* Storage for significant digits */
|
||||
char sign; /* '+' or '-' */
|
||||
char isSpecial; /* 1: Infinity 2: NaN */
|
||||
};
|
||||
|
||||
void sqlite3FpDecode(FpDecode*,double,int,int);
|
||||
|
||||
99
src/util.c
99
src/util.c
@@ -998,6 +998,69 @@ static const union {
|
||||
"90919293949596979899"
|
||||
};
|
||||
|
||||
/*
|
||||
** ARMv6, ARMv7, PPC32 are known to not support hardware u64 division.
|
||||
*/
|
||||
#if (defined(__arm__) && !defined(__aarch64__)) || \
|
||||
(defined(__ppc__) && !defined(__ppc64__))
|
||||
# define SQLITE_AVOID_U64_DIVIDE 1
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_AVOID_U64_DIVIDE
|
||||
/*
|
||||
** Render an unsigned 64-bit integer as text onto the end of a 2-byte
|
||||
** aligned buffer that is SQLITE_U64_DIGIT+1 bytes long. The last byte
|
||||
** of the buffer will be filled with a \000 byte.
|
||||
**
|
||||
** Return the index into the buffer of the first byte.
|
||||
**
|
||||
** This routine is used on platforms where u64-division is slow because
|
||||
** it is not available in hardware and has to be emulated in software.
|
||||
** It seeks to minimize the number of u64 divisions and use u32 divisions
|
||||
** instead. It is slower on platforms that have hardware u64 division,
|
||||
** but much faster on platforms that do not.
|
||||
*/
|
||||
static int sqlite3UInt64ToText(u64 v, char *zOut){
|
||||
u32 x32, kk;
|
||||
int i;
|
||||
zOut[SQLITE_U64_DIGITS] = 0;
|
||||
i = SQLITE_U64_DIGITS;
|
||||
assert( TWO_BYTE_ALIGNMENT(&sqlite3DigitPairs.a[0]) );
|
||||
assert( TWO_BYTE_ALIGNMENT(zOut) );
|
||||
while( (v>>32)!=0 ){
|
||||
u32 y, x0, x1, y0, y1;
|
||||
x32 = v % 100000000;
|
||||
v = v / 100000000;
|
||||
y = x32 % 10000;
|
||||
x32 /= 10000;
|
||||
x1 = x32 / 100;
|
||||
x0 = x32 % 100;
|
||||
y1 = y / 100;
|
||||
y0 = y % 100;
|
||||
assert( i>=8 );
|
||||
i -= 8;
|
||||
*(u16*)(&zOut[i]) = *(u16*)&sqlite3DigitPairs.a[x1*2];
|
||||
*(u16*)(&zOut[i+2]) = *(u16*)&sqlite3DigitPairs.a[x0*2];
|
||||
*(u16*)(&zOut[i+4]) = *(u16*)&sqlite3DigitPairs.a[y1*2];
|
||||
*(u16*)(&zOut[i+6]) = *(u16*)&sqlite3DigitPairs.a[y0*2];
|
||||
}
|
||||
x32 = v;
|
||||
while( x32>=10 ){
|
||||
kk = x32 % 100;
|
||||
x32 = x32 / 100;
|
||||
assert( TWO_BYTE_ALIGNMENT(&sqlite3DigitPairs.a[kk*2]) );
|
||||
assert( i>=2 );
|
||||
i -= 2;
|
||||
assert( TWO_BYTE_ALIGNMENT(&zOut[i]) );
|
||||
*(u16*)(&zOut[i]) = *(u16*)&sqlite3DigitPairs.a[kk*2];
|
||||
}
|
||||
if( x32 ){
|
||||
assert( i>0 );
|
||||
zOut[--i] = x32 + '0';
|
||||
}
|
||||
return i;
|
||||
}
|
||||
#endif /* defined(SQLITE_AVOID_U64_DIVIDE) */
|
||||
|
||||
/*
|
||||
** Render an signed 64-bit integer as text. Store the result in zOut[] and
|
||||
@@ -1011,7 +1074,7 @@ int sqlite3Int64ToText(i64 v, char *zOut){
|
||||
int i;
|
||||
u64 x;
|
||||
union {
|
||||
char a[23];
|
||||
char a[SQLITE_U64_DIGITS+1];
|
||||
u16 forceAlignment;
|
||||
} u;
|
||||
if( v>0 ){
|
||||
@@ -1023,6 +1086,9 @@ int sqlite3Int64ToText(i64 v, char *zOut){
|
||||
}else{
|
||||
x = (v==SMALLEST_INT64) ? ((u64)1)<<63 : (u64)-v;
|
||||
}
|
||||
#ifdef SQLITE_AVOID_U64_DIVIDE
|
||||
i = sqlite3UInt64ToText(x, u.a);
|
||||
#else
|
||||
i = sizeof(u.a)-1;
|
||||
u.a[i] = 0;
|
||||
while( x>=10 ){
|
||||
@@ -1036,6 +1102,7 @@ int sqlite3Int64ToText(i64 v, char *zOut){
|
||||
if( x ){
|
||||
u.a[--i] = x + '0';
|
||||
}
|
||||
#endif /* SQLITE_AVOID_U64_DIVIDE */
|
||||
if( v<0 ) u.a[--i] = '-';
|
||||
memcpy(zOut, &u.a[i], sizeof(u.a)-i);
|
||||
return sizeof(u.a)-1-i;
|
||||
@@ -1355,37 +1422,43 @@ void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRound){
|
||||
/* Extract significant digits, start at the right-most slot in p->zBuf
|
||||
** and working back to the right. "i" keeps track of the next slot in
|
||||
** which to store a digit. */
|
||||
i = sizeof(p->zBuf)-1;
|
||||
zBuf = p->zBuf;
|
||||
assert( sizeof(p->zBuf)==SQLITE_U64_DIGITS+1 );
|
||||
assert( v>0 );
|
||||
zBuf = p->zBuf;
|
||||
#ifdef SQLITE_AVOID_U64_DIVIDE
|
||||
i = sqlite3UInt64ToText(v, zBuf);
|
||||
#else
|
||||
i = SQLITE_U64_DIGITS;
|
||||
while( v>=10 ){
|
||||
int kk = (v%100)*2;
|
||||
assert( TWO_BYTE_ALIGNMENT(&sqlite3DigitPairs.a[kk]) );
|
||||
assert( TWO_BYTE_ALIGNMENT(&zBuf[i-1]) );
|
||||
*(u16*)(&zBuf[i-1]) = *(u16*)&sqlite3DigitPairs.a[kk];
|
||||
assert( TWO_BYTE_ALIGNMENT(&zBuf[i]) );
|
||||
assert( i-2>=0 );
|
||||
*(u16*)(&zBuf[i-2]) = *(u16*)&sqlite3DigitPairs.a[kk];
|
||||
i -= 2;
|
||||
v /= 100;
|
||||
}
|
||||
if( v ){
|
||||
assert( v<10 );
|
||||
zBuf[i--] = v + '0';
|
||||
assert( i>0 );
|
||||
zBuf[--i] = v + '0';
|
||||
}
|
||||
assert( i>=0 && i<sizeof(p->zBuf)-1 );
|
||||
n = sizeof(p->zBuf) - 1 - i; /* Total number of digits extracted */
|
||||
#endif /* SQLITE_AVOID_U64_DIVIDE */
|
||||
assert( i>=0 && i<SQLITE_U64_DIGITS );
|
||||
n = SQLITE_U64_DIGITS - i; /* Total number of digits extracted */
|
||||
assert( n>0 );
|
||||
assert( n<sizeof(p->zBuf) );
|
||||
testcase( n==sizeof(p->zBuf)-1 );
|
||||
assert( n<=SQLITE_U64_DIGITS );
|
||||
p->iDP = n + exp;
|
||||
if( iRound<=0 ){
|
||||
iRound = p->iDP - iRound;
|
||||
if( iRound==0 && zBuf[i+1]>='5' ){
|
||||
if( iRound==0 && zBuf[i]>='5' ){
|
||||
iRound = 1;
|
||||
zBuf[i--] = '0';
|
||||
zBuf[--i] = '0';
|
||||
n++;
|
||||
p->iDP++;
|
||||
}
|
||||
}
|
||||
z = &zBuf[i+1]; /* z points to the first digit */
|
||||
z = &zBuf[i]; /* z points to the first digit */
|
||||
if( iRound>0 && (iRound<n || n>mxRound) ){
|
||||
if( iRound>mxRound ) iRound = mxRound;
|
||||
if( iRound==17 ){
|
||||
|
||||
Reference in New Issue
Block a user