rtlint.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566
  1. /*##############################################################################
  2. Copyright (C) 2011 HPCC Systems.
  3. All rights reserved. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Affero General Public License as
  5. published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Affero General Public License for more details.
  11. You should have received a copy of the GNU Affero General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. ############################################################################## */
  14. #include "platform.h"
  15. #include <math.h>
  16. #include <stdio.h>
  17. #include "jexcept.hpp"
  18. #include "jmisc.hpp"
  19. #include "jutil.hpp"
  20. #include "jlib.hpp"
  21. #include "jptree.hpp"
  22. #include "eclrtl.hpp"
  23. #include "bcd.hpp"
  24. //#define _FAST_AND_LOOSE_
  25. #ifdef _FAST_AND_LOOSE_
  26. #if __BYTE_ORDER == __LITTLE_ENDIAN
  27. //These could read beyond a page boundary....
  28. int rtlReadInt3(const void * data) { return ((*(int *)data << 8) >> 8); }
  29. __int64 rtlReadInt5(const void * data) { return ((*(__int64 *)data << 24) >> 24); }
  30. __int64 rtlReadInt6(const void * data) { return ((*(__int64 *)data << 16) >> 16); }
  31. __int64 rtlReadInt7(const void * data) { return ((*(__int64 *)data << 8) >> 8); }
  32. unsigned rtlReadUInt3(const void * data) { return (*(unsigned *)data & 0xFFFFFF); }
  33. unsigned __int64 rtlReadUInt5(const void * data) { return (*(unsigned __int64 *)data & 0xFFFFFFFFFF); }
  34. unsigned __int64 rtlReadUInt6(const void * data) { return (*(unsigned __int64 *)data & 0xFFFFFFFFFFFF); }
  35. unsigned __int64 rtlReadUInt7(const void * data) { return (*(unsigned __int64 *)data & 0xFFFFFFFFFFFFFF); }
  36. #else
  37. //Probably have problems of misaligned access as well.....
  38. int rtlReadInt3(const void * data) { return (*(int *)data >> 8); }
  39. __int64 rtlReadInt5(const void * data) { return (*(__int64 *)data >> 24); }
  40. __int64 rtlReadInt6(const void * data) { return (*(__int64 *)data >> 16); }
  41. __int64 rtlReadInt7(const void * data) { return (*(__int64 *)data >> 8); }
  42. unsigned rtlReadUInt3(const void * data) { return (*(unsigned *)data >> 8); }
  43. unsigned __int64 rtlReadUInt5(const void * data) { return (*(unsigned __int64 *)data >> 24); }
  44. unsigned __int64 rtlReadUInt6(const void * data) { return (*(unsigned __int64 *)data >> 16); }
  45. unsigned __int64 rtlReadUInt7(const void * data) { return (*(unsigned __int64 *)data >> 8); }
  46. #endif
  47. #else
  48. #if __BYTE_ORDER == __LITTLE_ENDIAN
  49. int rtlReadInt3(const void * _data)
  50. {
  51. const unsigned short * usdata = (const unsigned short *)_data;
  52. const signed char * scdata = (const signed char *)_data;
  53. return ((int)scdata[2] << 16) | ((int)usdata[0]);
  54. }
  55. unsigned rtlReadUInt3(const void * _data)
  56. {
  57. const unsigned short * usdata = (const unsigned short *)_data;
  58. const unsigned char * ucdata = (const unsigned char *)_data;
  59. return ((unsigned)ucdata[2] << 16) | ((unsigned)usdata[0]);
  60. }
  61. //no sign extension issues, so same functions can be used for signed and unsigned.
  62. void rtlWriteInt3(void * _data, unsigned value)
  63. {
  64. unsigned short * usdata = (unsigned short *)_data;
  65. unsigned char * scdata = (unsigned char *)_data;
  66. scdata[2] = value >> 16;
  67. usdata[0] = value;
  68. }
  69. void rtlWriteInt5(void * _data, unsigned __int64 value)
  70. {
  71. unsigned * udata = (unsigned *)_data;
  72. unsigned char * ucdata = (unsigned char *)_data;
  73. ucdata[4] = (unsigned char) (value>>32);
  74. udata[0] = (unsigned)value;
  75. }
  76. void rtlWriteInt6(void * _data, unsigned __int64 value)
  77. {
  78. unsigned * udata = (unsigned *)_data;
  79. unsigned short * usdata = (unsigned short *)_data;
  80. usdata[2] = (unsigned short) (value>>32);
  81. udata[0] = (unsigned)value;
  82. }
  83. void rtlWriteInt7(void * _data, unsigned __int64 value)
  84. {
  85. unsigned * udata = (unsigned *)_data;
  86. unsigned short * usdata = (unsigned short *)_data;
  87. unsigned char * ucdata = (unsigned char *)_data;
  88. ucdata[6] = (unsigned char) (value>>48);
  89. usdata[2] = (unsigned short) (value>>32);
  90. udata[0] = (unsigned)value;
  91. }
  92. #ifdef _WIN32
  93. //MSVC seems to optimize these much better than you would expect.... in release
  94. __int64 rtlReadInt5(const void * _data)
  95. {
  96. const unsigned * udata = (const unsigned *)_data;
  97. const unsigned short * usdata = (const unsigned short *)_data;
  98. const signed char * scdata = (const signed char *)_data;
  99. LARGE_INTEGER x;
  100. x.HighPart = (int)scdata[4];
  101. x.LowPart = udata[0];
  102. return x.QuadPart;
  103. }
  104. __int64 rtlReadInt6(const void * _data)
  105. {
  106. const unsigned * udata = (const unsigned *)_data;
  107. const signed short * ssdata = (const signed short *)_data;
  108. LARGE_INTEGER x;
  109. x.HighPart = (int)ssdata[2];
  110. x.LowPart = udata[0];
  111. return x.QuadPart;
  112. }
  113. __int64 rtlReadInt7(const void * _data)
  114. {
  115. const unsigned * udata = (const unsigned *)_data;
  116. const unsigned short * usdata = (const unsigned short *)_data;
  117. const signed char * scdata = (const signed char *)_data;
  118. LARGE_INTEGER x;
  119. x.HighPart = ((int)scdata[6] << 16) | usdata[2];
  120. x.LowPart = udata[0];
  121. return x.QuadPart;
  122. }
  123. unsigned __int64 rtlReadUInt5(const void * _data)
  124. {
  125. const unsigned * udata = (const unsigned *)_data;
  126. const unsigned char * ucdata = (const unsigned char *)_data;
  127. LARGE_INTEGER x;
  128. x.HighPart = (int)ucdata[4];
  129. x.LowPart = udata[0];
  130. return x.QuadPart;
  131. }
  132. unsigned __int64 rtlReadUInt6(const void * _data)
  133. {
  134. const unsigned * udata = (const unsigned *)_data;
  135. const unsigned short * usdata = (const unsigned short *)_data;
  136. LARGE_INTEGER x;
  137. x.HighPart = (int)usdata[2];
  138. x.LowPart = udata[0];
  139. return x.QuadPart;
  140. }
  141. unsigned __int64 rtlReadUInt7(const void * _data)
  142. {
  143. const unsigned * udata = (const unsigned *)_data;
  144. const unsigned short * usdata = (const unsigned short *)_data;
  145. const unsigned char * ucdata = (const unsigned char *)_data;
  146. LARGE_INTEGER x;
  147. x.HighPart = ((unsigned)ucdata[6] << 16) | usdata[2];
  148. x.LowPart = udata[0];
  149. return x.QuadPart;
  150. }
  151. #else
  152. __int64 rtlReadInt5(const void * _data)
  153. {
  154. const unsigned * udata = (const unsigned *)_data;
  155. const signed char * scdata = (const signed char *)_data;
  156. return ((__int64)scdata[4] << 32) | ((__int64)udata[0]);
  157. }
  158. __int64 rtlReadInt6(const void * _data)
  159. {
  160. const unsigned * udata = (const unsigned *)_data;
  161. const signed short * ssdata = (const signed short *)_data;
  162. return ((__int64)ssdata[2] << 32) | ((__int64)udata[0]);
  163. }
  164. __int64 rtlReadInt7(const void * _data)
  165. {
  166. const unsigned * udata = (const unsigned *)_data;
  167. const unsigned short * usdata = (const unsigned short *)_data;
  168. const signed char * scdata = (const signed char *)_data;
  169. return ((__int64)scdata[6] << 48) | ((__int64)usdata[2] << 32) | ((__int64)udata[0]);
  170. }
  171. unsigned __int64 rtlReadUInt5(const void * _data)
  172. {
  173. const unsigned * udata = (const unsigned *)_data;
  174. const unsigned char * ucdata = (const unsigned char *)_data;
  175. return ((unsigned __int64)ucdata[4] << 32) | ((unsigned __int64)udata[0]);
  176. }
  177. unsigned __int64 rtlReadUInt6(const void * _data)
  178. {
  179. const unsigned * udata = (const unsigned *)_data;
  180. const unsigned short * usdata = (const unsigned short *)_data;
  181. return ((unsigned __int64)usdata[2] << 32) | ((unsigned __int64)udata[0]);
  182. }
  183. unsigned __int64 rtlReadUInt7(const void * _data)
  184. {
  185. const unsigned * udata = (const unsigned *)_data;
  186. const unsigned short * usdata = (const unsigned short *)_data;
  187. const unsigned char * ucdata = (const unsigned char *)_data;
  188. return ((unsigned __int64)ucdata[6] << 48) | ((unsigned __int64)usdata[2] << 32) | ((unsigned __int64)udata[0]);
  189. }
  190. #endif
  191. int rtlReadSwapInt2(const void * _data)
  192. {
  193. short temp;
  194. _cpyrev2(&temp, _data);
  195. return temp;
  196. }
  197. int rtlReadSwapInt3(const void * _data)
  198. {
  199. const signed char * scdata = (const signed char *)_data;
  200. int temp = scdata[0] << 16;
  201. _cpyrev2(&temp, scdata+1);
  202. return temp;
  203. }
  204. int rtlReadSwapInt4(const void * _data)
  205. {
  206. int temp;
  207. _cpyrev4(&temp, _data);
  208. return temp;
  209. }
  210. __int64 rtlReadSwapInt5(const void * _data)
  211. {
  212. const signed char * scdata = (const signed char *)_data;
  213. __int64 temp = ((__int64)scdata[0]) << 32;
  214. _cpyrev4(&temp, scdata+1);
  215. return temp;
  216. }
  217. __int64 rtlReadSwapInt6(const void * _data)
  218. {
  219. const signed char * scdata = (const signed char *)_data;
  220. __int64 temp = ((__int64)scdata[0]) << 40;
  221. _cpyrev5(&temp, scdata+1);
  222. return temp;
  223. }
  224. __int64 rtlReadSwapInt7(const void * _data)
  225. {
  226. const signed char * scdata = (const signed char *)_data;
  227. __int64 temp = ((__int64)scdata[0]) << 48;
  228. _cpyrev6(&temp, scdata+1);
  229. return temp;
  230. }
  231. __int64 rtlReadSwapInt8(const void * _data)
  232. {
  233. __int64 temp;
  234. _cpyrev8(&temp, _data);
  235. return temp;
  236. }
  237. unsigned rtlReadSwapUInt2(const void * _data)
  238. {
  239. unsigned short temp;
  240. _cpyrev2(&temp, _data);
  241. return temp;
  242. }
  243. unsigned rtlReadSwapUInt3(const void * _data)
  244. {
  245. unsigned temp = 0;
  246. _cpyrev3(&temp, _data);
  247. return temp;
  248. }
  249. unsigned rtlReadSwapUInt4(const void * _data)
  250. {
  251. unsigned temp;
  252. _cpyrev4(&temp, _data);
  253. return temp;
  254. }
  255. unsigned __int64 rtlReadSwapUInt5(const void * _data)
  256. {
  257. unsigned __int64 temp = 0;
  258. _cpyrev5(&temp, _data);
  259. return temp;
  260. }
  261. unsigned __int64 rtlReadSwapUInt6(const void * _data)
  262. {
  263. unsigned __int64 temp = 0;
  264. _cpyrev6(&temp, _data);
  265. return temp;
  266. }
  267. unsigned __int64 rtlReadSwapUInt7(const void * _data)
  268. {
  269. unsigned __int64 temp = 0;
  270. _cpyrev7(&temp, _data);
  271. return temp;
  272. }
  273. unsigned __int64 rtlReadSwapUInt8(const void * _data)
  274. {
  275. unsigned __int64 temp;
  276. _cpyrev8(&temp, _data);
  277. return temp;
  278. }
  279. //no sign extension issues, so same functions can be used for signed and unsigned.
  280. void rtlWriteSwapInt3(void * _data, unsigned value)
  281. {
  282. _cpyrev3(_data, &value);
  283. }
  284. void rtlWriteSwapInt5(void * _data, unsigned __int64 value)
  285. {
  286. _cpyrev5(_data, &value);
  287. }
  288. void rtlWriteSwapInt6(void * _data, unsigned __int64 value)
  289. {
  290. _cpyrev6(_data, &value);
  291. }
  292. void rtlWriteSwapInt7(void * _data, unsigned __int64 value)
  293. {
  294. _cpyrev7(_data, &value);
  295. }
  296. //The following functions are identical to the rtlReadSwapIntX functions for little endian.
  297. //big endian functions would be different.
  298. short rtlRevInt2(const void * _data)
  299. {
  300. short temp;
  301. _cpyrev2(&temp, _data);
  302. return temp;
  303. }
  304. int rtlRevInt3(const void * _data)
  305. {
  306. const signed char * scdata = (const signed char *)_data;
  307. int temp = scdata[0] << 16;
  308. _cpyrev2(&temp, scdata+1);
  309. return temp;
  310. }
  311. int rtlRevInt4(const void * _data)
  312. {
  313. int temp;
  314. _cpyrev4(&temp, _data);
  315. return temp;
  316. }
  317. __int64 rtlRevInt5(const void * _data)
  318. {
  319. const signed char * scdata = (const signed char *)_data;
  320. __int64 temp = ((__int64)scdata[0]) << 32;
  321. _cpyrev4(&temp, scdata+1);
  322. return temp;
  323. }
  324. __int64 rtlRevInt6(const void * _data)
  325. {
  326. const signed char * scdata = (const signed char *)_data;
  327. __int64 temp = ((__int64)scdata[0]) << 40;
  328. _cpyrev5(&temp, scdata+1);
  329. return temp;
  330. }
  331. __int64 rtlRevInt7(const void * _data)
  332. {
  333. const signed char * scdata = (const signed char *)_data;
  334. __int64 temp = ((__int64)scdata[0]) << 48;
  335. _cpyrev6(&temp, scdata+1);
  336. return temp;
  337. }
  338. __int64 rtlRevInt8(const void * _data)
  339. {
  340. __int64 temp;
  341. _cpyrev8(&temp, _data);
  342. return temp;
  343. }
  344. unsigned short rtlRevUInt2(const void * _data)
  345. {
  346. unsigned short temp;
  347. _cpyrev2(&temp, _data);
  348. return temp;
  349. }
  350. unsigned rtlRevUInt3(const void * _data)
  351. {
  352. unsigned temp = 0;
  353. _cpyrev3(&temp, _data);
  354. return temp;
  355. }
  356. unsigned rtlRevUInt4(const void * _data)
  357. {
  358. unsigned temp;
  359. _cpyrev4(&temp, _data);
  360. return temp;
  361. }
  362. unsigned __int64 rtlRevUInt5(const void * _data)
  363. {
  364. unsigned __int64 temp = 0;
  365. _cpyrev5(&temp, _data);
  366. return temp;
  367. }
  368. unsigned __int64 rtlRevUInt6(const void * _data)
  369. {
  370. unsigned __int64 temp = 0;
  371. _cpyrev6(&temp, _data);
  372. return temp;
  373. }
  374. unsigned __int64 rtlRevUInt7(const void * _data)
  375. {
  376. unsigned __int64 temp = 0;
  377. _cpyrev7(&temp, _data);
  378. return temp;
  379. }
  380. unsigned __int64 rtlRevUInt8(const void * _data)
  381. {
  382. unsigned __int64 temp;
  383. _cpyrev8(&temp, _data);
  384. return temp;
  385. }
  386. #else
  387. //Big endian form
  388. #error "Big endian implementation of rtlReadIntX functions need implementing...."
  389. #endif
  390. unsigned rtlCastUInt3(unsigned value)
  391. {
  392. return (value & 0xffffff);
  393. }
  394. unsigned __int64 rtlCastUInt5(unsigned __int64 value)
  395. {
  396. return (value & I64C(0xffffffffff));
  397. }
  398. unsigned __int64 rtlCastUInt6(unsigned __int64 value)
  399. {
  400. return (value & I64C(0xffffffffffff));
  401. }
  402. unsigned __int64 rtlCastUInt7(unsigned __int64 value)
  403. {
  404. return (value & I64C(0xffffffffffffff));
  405. }
  406. signed rtlCastInt3(signed value)
  407. {
  408. return (value << 8) >> 8;
  409. }
  410. __int64 rtlCastInt5(__int64 value)
  411. {
  412. return (value << 24) >> 24;
  413. }
  414. __int64 rtlCastInt6(__int64 value)
  415. {
  416. return (value << 16) >> 16;
  417. }
  418. __int64 rtlCastInt7(__int64 value)
  419. {
  420. return (value << 8) >> 8;
  421. }
  422. unsigned __int64 rtlReadUInt(const void * self, unsigned length)
  423. {
  424. switch (length)
  425. {
  426. case 1: return rtlReadUInt1(self);
  427. case 2: return rtlReadUInt2(self);
  428. case 3: return rtlReadUInt3(self);
  429. case 4: return rtlReadUInt4(self);
  430. case 5: return rtlReadUInt5(self);
  431. case 6: return rtlReadUInt6(self);
  432. case 7: return rtlReadUInt7(self);
  433. case 8: return rtlReadUInt8(self);
  434. }
  435. rtlFailUnexpected();
  436. return 0;
  437. }
  438. __int64 rtlReadInt(const void * self, unsigned length)
  439. {
  440. switch (length)
  441. {
  442. case 1: return rtlReadInt1(self);
  443. case 2: return rtlReadInt2(self);
  444. case 3: return rtlReadInt3(self);
  445. case 4: return rtlReadInt4(self);
  446. case 5: return rtlReadInt5(self);
  447. case 6: return rtlReadInt6(self);
  448. case 7: return rtlReadInt7(self);
  449. case 8: return rtlReadInt8(self);
  450. }
  451. rtlFailUnexpected();
  452. return 0;
  453. }
  454. unsigned __int64 rtlReadSwapUInt(const void * self, unsigned length)
  455. {
  456. switch (length)
  457. {
  458. case 1: return rtlReadSwapUInt1(self);
  459. case 2: return rtlReadSwapUInt2(self);
  460. case 3: return rtlReadSwapUInt3(self);
  461. case 4: return rtlReadSwapUInt4(self);
  462. case 5: return rtlReadSwapUInt5(self);
  463. case 6: return rtlReadSwapUInt6(self);
  464. case 7: return rtlReadSwapUInt7(self);
  465. case 8: return rtlReadSwapUInt8(self);
  466. }
  467. rtlFailUnexpected();
  468. return 0;
  469. }
  470. __int64 rtlReadSwapInt(const void * self, unsigned length)
  471. {
  472. switch (length)
  473. {
  474. case 1: return rtlReadSwapInt1(self);
  475. case 2: return rtlReadSwapInt2(self);
  476. case 3: return rtlReadSwapInt3(self);
  477. case 4: return rtlReadSwapInt4(self);
  478. case 5: return rtlReadSwapInt5(self);
  479. case 6: return rtlReadSwapInt6(self);
  480. case 7: return rtlReadSwapInt7(self);
  481. case 8: return rtlReadSwapInt8(self);
  482. }
  483. rtlFailUnexpected();
  484. return 0;
  485. }
  486. #endif