compiler-rt.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. /* compiler-rt.c - compiler helpers. */
  2. /*
  3. * GRUB -- GRand Unified Bootloader
  4. * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010-2014 Free Software Foundation, Inc.
  5. *
  6. * GRUB is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * GRUB is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include <grub/misc.h>
  20. #include <grub/compiler-rt.h>
  21. #ifndef GRUB_EMBED_DECOMPRESSOR
  22. void * GRUB_BUILTIN_ATTR
  23. memcpy (void *dest, const void *src, grub_size_t n)
  24. {
  25. return grub_memmove (dest, src, n);
  26. }
  27. void * GRUB_BUILTIN_ATTR
  28. memmove (void *dest, const void *src, grub_size_t n)
  29. {
  30. return grub_memmove (dest, src, n);
  31. }
  32. int GRUB_BUILTIN_ATTR
  33. memcmp (const void *s1, const void *s2, grub_size_t n)
  34. {
  35. return grub_memcmp (s1, s2, n);
  36. }
  37. void * GRUB_BUILTIN_ATTR
  38. memset (void *s, int c, grub_size_t n)
  39. {
  40. return grub_memset (s, c, n);
  41. }
  42. #ifdef __APPLE__
  43. void GRUB_BUILTIN_ATTR
  44. __bzero (void *s, grub_size_t n)
  45. {
  46. grub_memset (s, 0, n);
  47. }
  48. #endif
  49. #if GRUB_DIVISION_IN_SOFTWARE
  50. grub_uint32_t
  51. __udivsi3 (grub_uint32_t a, grub_uint32_t b)
  52. {
  53. return grub_divmod64 (a, b, 0);
  54. }
  55. grub_int32_t
  56. __divsi3 (grub_int32_t a, grub_int32_t b)
  57. {
  58. return grub_divmod64s (a, b, 0);
  59. }
  60. grub_uint32_t
  61. __umodsi3 (grub_uint32_t a, grub_uint32_t b)
  62. {
  63. grub_uint64_t ret;
  64. grub_divmod64 (a, b, &ret);
  65. return ret;
  66. }
  67. grub_int32_t
  68. __modsi3 (grub_int32_t a, grub_int32_t b)
  69. {
  70. grub_int64_t ret;
  71. grub_divmod64s (a, b, &ret);
  72. return ret;
  73. }
  74. grub_uint64_t
  75. __udivdi3 (grub_uint64_t a, grub_uint64_t b)
  76. {
  77. return grub_divmod64 (a, b, 0);
  78. }
  79. grub_uint64_t
  80. __umoddi3 (grub_uint64_t a, grub_uint64_t b)
  81. {
  82. grub_uint64_t ret;
  83. grub_divmod64 (a, b, &ret);
  84. return ret;
  85. }
  86. grub_int64_t
  87. __divdi3 (grub_int64_t a, grub_int64_t b)
  88. {
  89. return grub_divmod64s (a, b, 0);
  90. }
  91. grub_int64_t
  92. __moddi3 (grub_int64_t a, grub_int64_t b)
  93. {
  94. grub_int64_t ret;
  95. grub_divmod64s (a, b, &ret);
  96. return ret;
  97. }
  98. #endif
  99. #endif
  100. #ifdef NEED_CTZDI2
  101. unsigned
  102. __ctzdi2 (grub_uint64_t x)
  103. {
  104. unsigned ret = 0;
  105. if (!x)
  106. return 64;
  107. if (!(x & 0xffffffff))
  108. {
  109. x >>= 32;
  110. ret |= 32;
  111. }
  112. if (!(x & 0xffff))
  113. {
  114. x >>= 16;
  115. ret |= 16;
  116. }
  117. if (!(x & 0xff))
  118. {
  119. x >>= 8;
  120. ret |= 8;
  121. }
  122. if (!(x & 0xf))
  123. {
  124. x >>= 4;
  125. ret |= 4;
  126. }
  127. if (!(x & 0x3))
  128. {
  129. x >>= 2;
  130. ret |= 2;
  131. }
  132. if (!(x & 0x1))
  133. {
  134. x >>= 1;
  135. ret |= 1;
  136. }
  137. return ret;
  138. }
  139. #endif
  140. #ifdef NEED_CTZSI2
  141. unsigned
  142. __ctzsi2 (grub_uint32_t x)
  143. {
  144. unsigned ret = 0;
  145. if (!x)
  146. return 32;
  147. if (!(x & 0xffff))
  148. {
  149. x >>= 16;
  150. ret |= 16;
  151. }
  152. if (!(x & 0xff))
  153. {
  154. x >>= 8;
  155. ret |= 8;
  156. }
  157. if (!(x & 0xf))
  158. {
  159. x >>= 4;
  160. ret |= 4;
  161. }
  162. if (!(x & 0x3))
  163. {
  164. x >>= 2;
  165. ret |= 2;
  166. }
  167. if (!(x & 0x1))
  168. {
  169. x >>= 1;
  170. ret |= 1;
  171. }
  172. return ret;
  173. }
  174. #endif
  175. #if (defined (__MINGW32__) || defined (__CYGWIN__))
  176. void __register_frame_info (void)
  177. {
  178. }
  179. void __deregister_frame_info (void)
  180. {
  181. }
  182. void ___chkstk_ms (void)
  183. {
  184. }
  185. void __chkstk_ms (void)
  186. {
  187. }
  188. #endif
  189. union component64
  190. {
  191. grub_uint64_t full;
  192. struct
  193. {
  194. #ifdef GRUB_CPU_WORDS_BIGENDIAN
  195. grub_uint32_t high;
  196. grub_uint32_t low;
  197. #else
  198. grub_uint32_t low;
  199. grub_uint32_t high;
  200. #endif
  201. };
  202. };
  203. #if defined (__powerpc__) || defined (__arm__) || defined(__mips__) || \
  204. (defined(__riscv) && (__riscv_xlen == 32))
  205. /* Based on libgcc2.c from gcc suite. */
  206. grub_uint64_t
  207. __lshrdi3 (grub_uint64_t u, int b)
  208. {
  209. if (b == 0)
  210. return u;
  211. const union component64 uu = {.full = u};
  212. const int bm = 32 - b;
  213. union component64 w;
  214. if (bm <= 0)
  215. {
  216. w.high = 0;
  217. w.low = (grub_uint32_t) uu.high >> -bm;
  218. }
  219. else
  220. {
  221. const grub_uint32_t carries = (grub_uint32_t) uu.high << bm;
  222. w.high = (grub_uint32_t) uu.high >> b;
  223. w.low = ((grub_uint32_t) uu.low >> b) | carries;
  224. }
  225. return w.full;
  226. }
  227. /* Based on libgcc2.c from gcc suite. */
  228. grub_uint64_t
  229. __ashrdi3 (grub_uint64_t u, int b)
  230. {
  231. if (b == 0)
  232. return u;
  233. const union component64 uu = {.full = u};
  234. const int bm = 32 - b;
  235. union component64 w;
  236. if (bm <= 0)
  237. {
  238. /* w.high = 1..1 or 0..0 */
  239. w.high = ((grub_int32_t) uu.high) >> (32 - 1);
  240. w.low = ((grub_int32_t) uu.high) >> -bm;
  241. }
  242. else
  243. {
  244. const grub_uint32_t carries = ((grub_uint32_t) uu.high) << bm;
  245. w.high = ((grub_int32_t) uu.high) >> b;
  246. w.low = ((grub_uint32_t) uu.low >> b) | carries;
  247. }
  248. return w.full;
  249. }
  250. /* Based on libgcc2.c from gcc suite. */
  251. grub_uint64_t
  252. __ashldi3 (grub_uint64_t u, int b)
  253. {
  254. if (b == 0)
  255. return u;
  256. const union component64 uu = {.full = u};
  257. const int bm = 32 - b;
  258. union component64 w;
  259. if (bm <= 0)
  260. {
  261. w.low = 0;
  262. w.high = (grub_uint32_t) uu.low << -bm;
  263. }
  264. else
  265. {
  266. const grub_uint32_t carries = (grub_uint32_t) uu.low >> bm;
  267. w.low = (grub_uint32_t) uu.low << b;
  268. w.high = ((grub_uint32_t) uu.high << b) | carries;
  269. }
  270. return w.full;
  271. }
  272. /* Based on libgcc2.c from gcc suite. */
  273. int
  274. __ucmpdi2 (grub_uint64_t a, grub_uint64_t b)
  275. {
  276. union component64 ac, bc;
  277. ac.full = a;
  278. bc.full = b;
  279. if (ac.high < bc.high)
  280. return 0;
  281. else if (ac.high > bc.high)
  282. return 2;
  283. if (ac.low < bc.low)
  284. return 0;
  285. else if (ac.low > bc.low)
  286. return 2;
  287. return 1;
  288. }
  289. #endif
  290. #if defined (__powerpc__) || defined(__mips__) || defined(__sparc__) || \
  291. defined(__arm__) || defined(__riscv)
  292. /* Based on libgcc2.c from gcc suite. */
  293. grub_uint32_t
  294. __bswapsi2 (grub_uint32_t u)
  295. {
  296. return ((((u) & 0xff000000) >> 24)
  297. | (((u) & 0x00ff0000) >> 8)
  298. | (((u) & 0x0000ff00) << 8)
  299. | (((u) & 0x000000ff) << 24));
  300. }
  301. /* Based on libgcc2.c from gcc suite. */
  302. grub_uint64_t
  303. __bswapdi2 (grub_uint64_t u)
  304. {
  305. return ((((u) & 0xff00000000000000ull) >> 56)
  306. | (((u) & 0x00ff000000000000ull) >> 40)
  307. | (((u) & 0x0000ff0000000000ull) >> 24)
  308. | (((u) & 0x000000ff00000000ull) >> 8)
  309. | (((u) & 0x00000000ff000000ull) << 8)
  310. | (((u) & 0x0000000000ff0000ull) << 24)
  311. | (((u) & 0x000000000000ff00ull) << 40)
  312. | (((u) & 0x00000000000000ffull) << 56));
  313. }
  314. #endif
  315. #ifdef __arm__
  316. grub_uint32_t
  317. __aeabi_uidiv (grub_uint32_t a, grub_uint32_t b)
  318. __attribute__ ((alias ("__udivsi3")));
  319. grub_int32_t
  320. __aeabi_idiv (grub_int32_t a, grub_int32_t b)
  321. __attribute__ ((alias ("__divsi3")));
  322. void *__aeabi_memcpy (void *dest, const void *src, grub_size_t n)
  323. __attribute__ ((alias ("grub_memcpy")));
  324. void *__aeabi_memcpy4 (void *dest, const void *src, grub_size_t n)
  325. __attribute__ ((alias ("grub_memcpy")));
  326. void *__aeabi_memcpy8 (void *dest, const void *src, grub_size_t n)
  327. __attribute__ ((alias ("grub_memcpy")));
  328. void *__aeabi_memset (void *s, int c, grub_size_t n)
  329. __attribute__ ((alias ("memset")));
  330. void
  331. __aeabi_memclr (void *s, grub_size_t n)
  332. {
  333. grub_memset (s, 0, n);
  334. }
  335. void __aeabi_memclr4 (void *s, grub_size_t n)
  336. __attribute__ ((alias ("__aeabi_memclr")));
  337. void __aeabi_memclr8 (void *s, grub_size_t n)
  338. __attribute__ ((alias ("__aeabi_memclr")));
  339. int
  340. __aeabi_ulcmp (grub_uint64_t a, grub_uint64_t b)
  341. {
  342. return __ucmpdi2 (a, b) - 1;
  343. }
  344. grub_uint64_t
  345. __aeabi_lasr (grub_uint64_t u, int b)
  346. __attribute__ ((alias ("__ashrdi3")));
  347. grub_uint64_t
  348. __aeabi_llsr (grub_uint64_t u, int b)
  349. __attribute__ ((alias ("__lshrdi3")));
  350. grub_uint64_t
  351. __aeabi_llsl (grub_uint64_t u, int b)
  352. __attribute__ ((alias ("__ashldi3")));
  353. #endif
  354. #if defined(__mips__) || defined(__riscv) || defined(__sparc__)
  355. /* Based on libgcc from gcc suite. */
  356. int
  357. __clzsi2 (grub_uint32_t val)
  358. {
  359. int i = 32;
  360. int j = 16;
  361. int temp;
  362. for (; j; j >>= 1)
  363. {
  364. if ((temp = val >> j))
  365. {
  366. if (j == 1)
  367. {
  368. return (i - 2);
  369. }
  370. else
  371. {
  372. i -= j;
  373. val = temp;
  374. }
  375. }
  376. }
  377. return (i - val);
  378. }
  379. #endif
  380. #if defined(__mips__) || defined(__riscv) || defined(__sparc__)
  381. int
  382. __clzdi2 (grub_uint64_t val)
  383. {
  384. if (val >> 32)
  385. {
  386. return __clzsi2 (val >> 32);
  387. }
  388. else
  389. {
  390. return __clzsi2 (val) + 32;
  391. }
  392. }
  393. #endif