compiler-rt.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  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 (__clang__) && !defined(GRUB_EMBED_DECOMPRESSOR)
  176. /* clang emits references to abort(). */
  177. void __attribute__ ((noreturn))
  178. abort (void)
  179. {
  180. grub_fatal ("compiler abort");
  181. }
  182. #endif
  183. #if (defined (__MINGW32__) || defined (__CYGWIN__))
  184. void __register_frame_info (void)
  185. {
  186. }
  187. void __deregister_frame_info (void)
  188. {
  189. }
  190. void ___chkstk_ms (void)
  191. {
  192. }
  193. void __chkstk_ms (void)
  194. {
  195. }
  196. #endif
  197. union component64
  198. {
  199. grub_uint64_t full;
  200. struct
  201. {
  202. #ifdef GRUB_CPU_WORDS_BIGENDIAN
  203. grub_uint32_t high;
  204. grub_uint32_t low;
  205. #else
  206. grub_uint32_t low;
  207. grub_uint32_t high;
  208. #endif
  209. };
  210. };
  211. #if defined (__powerpc__) || defined (__arm__) || defined(__mips__)
  212. /* Based on libgcc2.c from gcc suite. */
  213. grub_uint64_t
  214. __lshrdi3 (grub_uint64_t u, int b)
  215. {
  216. if (b == 0)
  217. return u;
  218. const union component64 uu = {.full = u};
  219. const int bm = 32 - b;
  220. union component64 w;
  221. if (bm <= 0)
  222. {
  223. w.high = 0;
  224. w.low = (grub_uint32_t) uu.high >> -bm;
  225. }
  226. else
  227. {
  228. const grub_uint32_t carries = (grub_uint32_t) uu.high << bm;
  229. w.high = (grub_uint32_t) uu.high >> b;
  230. w.low = ((grub_uint32_t) uu.low >> b) | carries;
  231. }
  232. return w.full;
  233. }
  234. /* Based on libgcc2.c from gcc suite. */
  235. grub_uint64_t
  236. __ashrdi3 (grub_uint64_t u, int b)
  237. {
  238. if (b == 0)
  239. return u;
  240. const union component64 uu = {.full = u};
  241. const int bm = 32 - b;
  242. union component64 w;
  243. if (bm <= 0)
  244. {
  245. /* w.high = 1..1 or 0..0 */
  246. w.high = ((grub_int32_t) uu.high) >> (32 - 1);
  247. w.low = ((grub_int32_t) uu.high) >> -bm;
  248. }
  249. else
  250. {
  251. const grub_uint32_t carries = ((grub_uint32_t) uu.high) << bm;
  252. w.high = ((grub_int32_t) uu.high) >> b;
  253. w.low = ((grub_uint32_t) uu.low >> b) | carries;
  254. }
  255. return w.full;
  256. }
  257. /* Based on libgcc2.c from gcc suite. */
  258. grub_uint64_t
  259. __ashldi3 (grub_uint64_t u, int b)
  260. {
  261. if (b == 0)
  262. return u;
  263. const union component64 uu = {.full = u};
  264. const int bm = 32 - b;
  265. union component64 w;
  266. if (bm <= 0)
  267. {
  268. w.low = 0;
  269. w.high = (grub_uint32_t) uu.low << -bm;
  270. }
  271. else
  272. {
  273. const grub_uint32_t carries = (grub_uint32_t) uu.low >> bm;
  274. w.low = (grub_uint32_t) uu.low << b;
  275. w.high = ((grub_uint32_t) uu.high << b) | carries;
  276. }
  277. return w.full;
  278. }
  279. /* Based on libgcc2.c from gcc suite. */
  280. int
  281. __ucmpdi2 (grub_uint64_t a, grub_uint64_t b)
  282. {
  283. union component64 ac, bc;
  284. ac.full = a;
  285. bc.full = b;
  286. if (ac.high < bc.high)
  287. return 0;
  288. else if (ac.high > bc.high)
  289. return 2;
  290. if (ac.low < bc.low)
  291. return 0;
  292. else if (ac.low > bc.low)
  293. return 2;
  294. return 1;
  295. }
  296. #endif
  297. #if defined (__powerpc__) || defined(__mips__) || defined(__sparc__) || defined(__arm__)
  298. /* Based on libgcc2.c from gcc suite. */
  299. grub_uint32_t
  300. __bswapsi2 (grub_uint32_t u)
  301. {
  302. return ((((u) & 0xff000000) >> 24)
  303. | (((u) & 0x00ff0000) >> 8)
  304. | (((u) & 0x0000ff00) << 8)
  305. | (((u) & 0x000000ff) << 24));
  306. }
  307. /* Based on libgcc2.c from gcc suite. */
  308. grub_uint64_t
  309. __bswapdi2 (grub_uint64_t u)
  310. {
  311. return ((((u) & 0xff00000000000000ull) >> 56)
  312. | (((u) & 0x00ff000000000000ull) >> 40)
  313. | (((u) & 0x0000ff0000000000ull) >> 24)
  314. | (((u) & 0x000000ff00000000ull) >> 8)
  315. | (((u) & 0x00000000ff000000ull) << 8)
  316. | (((u) & 0x0000000000ff0000ull) << 24)
  317. | (((u) & 0x000000000000ff00ull) << 40)
  318. | (((u) & 0x00000000000000ffull) << 56));
  319. }
  320. #endif
  321. #ifdef __arm__
  322. grub_uint32_t
  323. __aeabi_uidiv (grub_uint32_t a, grub_uint32_t b)
  324. __attribute__ ((alias ("__udivsi3")));
  325. grub_int32_t
  326. __aeabi_idiv (grub_int32_t a, grub_int32_t b)
  327. __attribute__ ((alias ("__divsi3")));
  328. void *__aeabi_memcpy (void *dest, const void *src, grub_size_t n)
  329. __attribute__ ((alias ("grub_memcpy")));
  330. void *__aeabi_memcpy4 (void *dest, const void *src, grub_size_t n)
  331. __attribute__ ((alias ("grub_memcpy")));
  332. void *__aeabi_memcpy8 (void *dest, const void *src, grub_size_t n)
  333. __attribute__ ((alias ("grub_memcpy")));
  334. void *__aeabi_memset (void *s, int c, grub_size_t n)
  335. __attribute__ ((alias ("memset")));
  336. void
  337. __aeabi_memclr (void *s, grub_size_t n)
  338. {
  339. grub_memset (s, 0, n);
  340. }
  341. void __aeabi_memclr4 (void *s, grub_size_t n)
  342. __attribute__ ((alias ("__aeabi_memclr")));
  343. void __aeabi_memclr8 (void *s, grub_size_t n)
  344. __attribute__ ((alias ("__aeabi_memclr")));
  345. int
  346. __aeabi_ulcmp (grub_uint64_t a, grub_uint64_t b)
  347. {
  348. return __ucmpdi2 (a, b) - 1;
  349. }
  350. grub_uint64_t
  351. __aeabi_lasr (grub_uint64_t u, int b)
  352. __attribute__ ((alias ("__ashrdi3")));
  353. grub_uint64_t
  354. __aeabi_llsr (grub_uint64_t u, int b)
  355. __attribute__ ((alias ("__lshrdi3")));
  356. grub_uint64_t
  357. __aeabi_llsl (grub_uint64_t u, int b)
  358. __attribute__ ((alias ("__ashldi3")));
  359. #endif