rtlint.cpp 17 KB

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