host-utils.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. /*
  2. * Utility compute operations used by translated code.
  3. *
  4. * Copyright (c) 2003 Fabrice Bellard
  5. * Copyright (c) 2007 Aurelien Jarno
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a copy
  8. * of this software and associated documentation files (the "Software"), to deal
  9. * in the Software without restriction, including without limitation the rights
  10. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. * copies of the Software, and to permit persons to whom the Software is
  12. * furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in
  15. * all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. * THE SOFTWARE.
  24. */
  25. #include "qemu/osdep.h"
  26. #include "qemu/host-utils.h"
  27. #ifndef CONFIG_INT128
  28. /* Long integer helpers */
  29. static inline void mul64(uint64_t *plow, uint64_t *phigh,
  30. uint64_t a, uint64_t b)
  31. {
  32. typedef union {
  33. uint64_t ll;
  34. struct {
  35. #if HOST_BIG_ENDIAN
  36. uint32_t high, low;
  37. #else
  38. uint32_t low, high;
  39. #endif
  40. } l;
  41. } LL;
  42. LL rl, rm, rn, rh, a0, b0;
  43. uint64_t c;
  44. a0.ll = a;
  45. b0.ll = b;
  46. rl.ll = (uint64_t)a0.l.low * b0.l.low;
  47. rm.ll = (uint64_t)a0.l.low * b0.l.high;
  48. rn.ll = (uint64_t)a0.l.high * b0.l.low;
  49. rh.ll = (uint64_t)a0.l.high * b0.l.high;
  50. c = (uint64_t)rl.l.high + rm.l.low + rn.l.low;
  51. rl.l.high = c;
  52. c >>= 32;
  53. c = c + rm.l.high + rn.l.high + rh.l.low;
  54. rh.l.low = c;
  55. rh.l.high += (uint32_t)(c >> 32);
  56. *plow = rl.ll;
  57. *phigh = rh.ll;
  58. }
  59. /* Unsigned 64x64 -> 128 multiplication */
  60. void mulu64 (uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b)
  61. {
  62. mul64(plow, phigh, a, b);
  63. }
  64. /* Signed 64x64 -> 128 multiplication */
  65. void muls64 (uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b)
  66. {
  67. uint64_t rh;
  68. mul64(plow, &rh, a, b);
  69. /* Adjust for signs. */
  70. if (b < 0) {
  71. rh -= a;
  72. }
  73. if (a < 0) {
  74. rh -= b;
  75. }
  76. *phigh = rh;
  77. }
  78. /*
  79. * Unsigned 128-by-64 division.
  80. * Returns the remainder.
  81. * Returns quotient via plow and phigh.
  82. * Also returns the remainder via the function return value.
  83. */
  84. uint64_t divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
  85. {
  86. uint64_t dhi = *phigh;
  87. uint64_t dlo = *plow;
  88. uint64_t rem, dhighest;
  89. int sh;
  90. if (divisor == 0 || dhi == 0) {
  91. *plow = dlo / divisor;
  92. *phigh = 0;
  93. return dlo % divisor;
  94. } else {
  95. sh = clz64(divisor);
  96. if (dhi < divisor) {
  97. if (sh != 0) {
  98. /* normalize the divisor, shifting the dividend accordingly */
  99. divisor <<= sh;
  100. dhi = (dhi << sh) | (dlo >> (64 - sh));
  101. dlo <<= sh;
  102. }
  103. *phigh = 0;
  104. *plow = udiv_qrnnd(&rem, dhi, dlo, divisor);
  105. } else {
  106. if (sh != 0) {
  107. /* normalize the divisor, shifting the dividend accordingly */
  108. divisor <<= sh;
  109. dhighest = dhi >> (64 - sh);
  110. dhi = (dhi << sh) | (dlo >> (64 - sh));
  111. dlo <<= sh;
  112. *phigh = udiv_qrnnd(&dhi, dhighest, dhi, divisor);
  113. } else {
  114. /**
  115. * dhi >= divisor
  116. * Since the MSB of divisor is set (sh == 0),
  117. * (dhi - divisor) < divisor
  118. *
  119. * Thus, the high part of the quotient is 1, and we can
  120. * calculate the low part with a single call to udiv_qrnnd
  121. * after subtracting divisor from dhi
  122. */
  123. dhi -= divisor;
  124. *phigh = 1;
  125. }
  126. *plow = udiv_qrnnd(&rem, dhi, dlo, divisor);
  127. }
  128. /*
  129. * since the dividend/divisor might have been normalized,
  130. * the remainder might also have to be shifted back
  131. */
  132. return rem >> sh;
  133. }
  134. }
  135. /*
  136. * Signed 128-by-64 division.
  137. * Returns quotient via plow and phigh.
  138. * Also returns the remainder via the function return value.
  139. */
  140. int64_t divs128(uint64_t *plow, int64_t *phigh, int64_t divisor)
  141. {
  142. bool neg_quotient = false, neg_remainder = false;
  143. uint64_t unsig_hi = *phigh, unsig_lo = *plow;
  144. uint64_t rem;
  145. if (*phigh < 0) {
  146. neg_quotient = !neg_quotient;
  147. neg_remainder = !neg_remainder;
  148. if (unsig_lo == 0) {
  149. unsig_hi = -unsig_hi;
  150. } else {
  151. unsig_hi = ~unsig_hi;
  152. unsig_lo = -unsig_lo;
  153. }
  154. }
  155. if (divisor < 0) {
  156. neg_quotient = !neg_quotient;
  157. divisor = -divisor;
  158. }
  159. rem = divu128(&unsig_lo, &unsig_hi, (uint64_t)divisor);
  160. if (neg_quotient) {
  161. if (unsig_lo == 0) {
  162. *phigh = -unsig_hi;
  163. *plow = 0;
  164. } else {
  165. *phigh = ~unsig_hi;
  166. *plow = -unsig_lo;
  167. }
  168. } else {
  169. *phigh = unsig_hi;
  170. *plow = unsig_lo;
  171. }
  172. if (neg_remainder) {
  173. return -rem;
  174. } else {
  175. return rem;
  176. }
  177. }
  178. #endif
  179. /**
  180. * urshift - 128-bit Unsigned Right Shift.
  181. * @plow: in/out - lower 64-bit integer.
  182. * @phigh: in/out - higher 64-bit integer.
  183. * @shift: in - bytes to shift, between 0 and 127.
  184. *
  185. * Result is zero-extended and stored in plow/phigh, which are
  186. * input/output variables. Shift values outside the range will
  187. * be mod to 128. In other words, the caller is responsible to
  188. * verify/assert both the shift range and plow/phigh pointers.
  189. */
  190. void urshift(uint64_t *plow, uint64_t *phigh, int32_t shift)
  191. {
  192. shift &= 127;
  193. if (shift == 0) {
  194. return;
  195. }
  196. uint64_t h = *phigh >> (shift & 63);
  197. if (shift >= 64) {
  198. *plow = h;
  199. *phigh = 0;
  200. } else {
  201. *plow = (*plow >> (shift & 63)) | (*phigh << (64 - (shift & 63)));
  202. *phigh = h;
  203. }
  204. }
  205. /**
  206. * ulshift - 128-bit Unsigned Left Shift.
  207. * @plow: in/out - lower 64-bit integer.
  208. * @phigh: in/out - higher 64-bit integer.
  209. * @shift: in - bytes to shift, between 0 and 127.
  210. * @overflow: out - true if any 1-bit is shifted out.
  211. *
  212. * Result is zero-extended and stored in plow/phigh, which are
  213. * input/output variables. Shift values outside the range will
  214. * be mod to 128. In other words, the caller is responsible to
  215. * verify/assert both the shift range and plow/phigh pointers.
  216. */
  217. void ulshift(uint64_t *plow, uint64_t *phigh, int32_t shift, bool *overflow)
  218. {
  219. uint64_t low = *plow;
  220. uint64_t high = *phigh;
  221. shift &= 127;
  222. if (shift == 0) {
  223. return;
  224. }
  225. /* check if any bit will be shifted out */
  226. urshift(&low, &high, 128 - shift);
  227. if (low | high) {
  228. *overflow = true;
  229. }
  230. if (shift >= 64) {
  231. *phigh = *plow << (shift & 63);
  232. *plow = 0;
  233. } else {
  234. *phigh = (*plow >> (64 - (shift & 63))) | (*phigh << (shift & 63));
  235. *plow = *plow << shift;
  236. }
  237. }
  238. /*
  239. * Unsigned 256-by-128 division.
  240. * Returns the remainder via r.
  241. * Returns lower 128 bit of quotient.
  242. * Needs a normalized divisor (most significant bit set to 1).
  243. *
  244. * Adapted from include/qemu/host-utils.h udiv_qrnnd,
  245. * from the GNU Multi Precision Library - longlong.h __udiv_qrnnd
  246. * (https://gmplib.org/repo/gmp/file/tip/longlong.h)
  247. *
  248. * Licensed under the GPLv2/LGPLv3
  249. */
  250. static Int128 udiv256_qrnnd(Int128 *r, Int128 n1, Int128 n0, Int128 d)
  251. {
  252. Int128 d0, d1, q0, q1, r1, r0, m;
  253. uint64_t mp0, mp1;
  254. d0 = int128_make64(int128_getlo(d));
  255. d1 = int128_make64(int128_gethi(d));
  256. r1 = int128_remu(n1, d1);
  257. q1 = int128_divu(n1, d1);
  258. mp0 = int128_getlo(q1);
  259. mp1 = int128_gethi(q1);
  260. mulu128(&mp0, &mp1, int128_getlo(d0));
  261. m = int128_make128(mp0, mp1);
  262. r1 = int128_make128(int128_gethi(n0), int128_getlo(r1));
  263. if (int128_ult(r1, m)) {
  264. q1 = int128_sub(q1, int128_one());
  265. r1 = int128_add(r1, d);
  266. if (int128_uge(r1, d)) {
  267. if (int128_ult(r1, m)) {
  268. q1 = int128_sub(q1, int128_one());
  269. r1 = int128_add(r1, d);
  270. }
  271. }
  272. }
  273. r1 = int128_sub(r1, m);
  274. r0 = int128_remu(r1, d1);
  275. q0 = int128_divu(r1, d1);
  276. mp0 = int128_getlo(q0);
  277. mp1 = int128_gethi(q0);
  278. mulu128(&mp0, &mp1, int128_getlo(d0));
  279. m = int128_make128(mp0, mp1);
  280. r0 = int128_make128(int128_getlo(n0), int128_getlo(r0));
  281. if (int128_ult(r0, m)) {
  282. q0 = int128_sub(q0, int128_one());
  283. r0 = int128_add(r0, d);
  284. if (int128_uge(r0, d)) {
  285. if (int128_ult(r0, m)) {
  286. q0 = int128_sub(q0, int128_one());
  287. r0 = int128_add(r0, d);
  288. }
  289. }
  290. }
  291. r0 = int128_sub(r0, m);
  292. *r = r0;
  293. return int128_or(int128_lshift(q1, 64), q0);
  294. }
  295. /*
  296. * Unsigned 256-by-128 division.
  297. * Returns the remainder.
  298. * Returns quotient via plow and phigh.
  299. * Also returns the remainder via the function return value.
  300. */
  301. Int128 divu256(Int128 *plow, Int128 *phigh, Int128 divisor)
  302. {
  303. Int128 dhi = *phigh;
  304. Int128 dlo = *plow;
  305. Int128 rem, dhighest;
  306. int sh;
  307. if (!int128_nz(divisor) || !int128_nz(dhi)) {
  308. *plow = int128_divu(dlo, divisor);
  309. *phigh = int128_zero();
  310. return int128_remu(dlo, divisor);
  311. } else {
  312. sh = clz128(divisor);
  313. if (int128_ult(dhi, divisor)) {
  314. if (sh != 0) {
  315. /* normalize the divisor, shifting the dividend accordingly */
  316. divisor = int128_lshift(divisor, sh);
  317. dhi = int128_or(int128_lshift(dhi, sh),
  318. int128_urshift(dlo, (128 - sh)));
  319. dlo = int128_lshift(dlo, sh);
  320. }
  321. *phigh = int128_zero();
  322. *plow = udiv256_qrnnd(&rem, dhi, dlo, divisor);
  323. } else {
  324. if (sh != 0) {
  325. /* normalize the divisor, shifting the dividend accordingly */
  326. divisor = int128_lshift(divisor, sh);
  327. dhighest = int128_rshift(dhi, (128 - sh));
  328. dhi = int128_or(int128_lshift(dhi, sh),
  329. int128_urshift(dlo, (128 - sh)));
  330. dlo = int128_lshift(dlo, sh);
  331. *phigh = udiv256_qrnnd(&dhi, dhighest, dhi, divisor);
  332. } else {
  333. /*
  334. * dhi >= divisor
  335. * Since the MSB of divisor is set (sh == 0),
  336. * (dhi - divisor) < divisor
  337. *
  338. * Thus, the high part of the quotient is 1, and we can
  339. * calculate the low part with a single call to udiv_qrnnd
  340. * after subtracting divisor from dhi
  341. */
  342. dhi = int128_sub(dhi, divisor);
  343. *phigh = int128_one();
  344. }
  345. *plow = udiv256_qrnnd(&rem, dhi, dlo, divisor);
  346. }
  347. /*
  348. * since the dividend/divisor might have been normalized,
  349. * the remainder might also have to be shifted back
  350. */
  351. rem = int128_urshift(rem, sh);
  352. return rem;
  353. }
  354. }
  355. /*
  356. * Signed 256-by-128 division.
  357. * Returns quotient via plow and phigh.
  358. * Also returns the remainder via the function return value.
  359. */
  360. Int128 divs256(Int128 *plow, Int128 *phigh, Int128 divisor)
  361. {
  362. bool neg_quotient = false, neg_remainder = false;
  363. Int128 unsig_hi = *phigh, unsig_lo = *plow;
  364. Int128 rem;
  365. if (!int128_nonneg(*phigh)) {
  366. neg_quotient = !neg_quotient;
  367. neg_remainder = !neg_remainder;
  368. if (!int128_nz(unsig_lo)) {
  369. unsig_hi = int128_neg(unsig_hi);
  370. } else {
  371. unsig_hi = int128_not(unsig_hi);
  372. unsig_lo = int128_neg(unsig_lo);
  373. }
  374. }
  375. if (!int128_nonneg(divisor)) {
  376. neg_quotient = !neg_quotient;
  377. divisor = int128_neg(divisor);
  378. }
  379. rem = divu256(&unsig_lo, &unsig_hi, divisor);
  380. if (neg_quotient) {
  381. if (!int128_nz(unsig_lo)) {
  382. *phigh = int128_neg(unsig_hi);
  383. *plow = int128_zero();
  384. } else {
  385. *phigh = int128_not(unsig_hi);
  386. *plow = int128_neg(unsig_lo);
  387. }
  388. } else {
  389. *phigh = unsig_hi;
  390. *plow = unsig_lo;
  391. }
  392. if (neg_remainder) {
  393. return int128_neg(rem);
  394. } else {
  395. return rem;
  396. }
  397. }