mem.rs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. extern crate compiler_builtins;
  2. use compiler_builtins::mem::{memcmp, memcpy, memmove, memset};
  3. const WORD_SIZE: usize = core::mem::size_of::<usize>();
  4. #[test]
  5. fn memcpy_3() {
  6. let mut arr: [u8; 12] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
  7. unsafe {
  8. let src = arr.as_ptr().offset(9);
  9. let dst = arr.as_mut_ptr().offset(1);
  10. assert_eq!(memcpy(dst, src, 3), dst);
  11. assert_eq!(arr, [0, 9, 10, 11, 4, 5, 6, 7, 8, 9, 10, 11]);
  12. }
  13. arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
  14. unsafe {
  15. let src = arr.as_ptr().offset(1);
  16. let dst = arr.as_mut_ptr().offset(9);
  17. assert_eq!(memcpy(dst, src, 3), dst);
  18. assert_eq!(arr, [0, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3]);
  19. }
  20. }
  21. #[test]
  22. fn memcpy_10() {
  23. let arr: [u8; 18] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17];
  24. let mut dst: [u8; 12] = [0; 12];
  25. unsafe {
  26. let src = arr.as_ptr().offset(1);
  27. assert_eq!(memcpy(dst.as_mut_ptr(), src, 10), dst.as_mut_ptr());
  28. assert_eq!(dst, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0]);
  29. }
  30. unsafe {
  31. let src = arr.as_ptr().offset(8);
  32. assert_eq!(memcpy(dst.as_mut_ptr(), src, 10), dst.as_mut_ptr());
  33. assert_eq!(dst, [8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 0, 0]);
  34. }
  35. }
  36. #[test]
  37. fn memcpy_big() {
  38. // Make the arrays cross 3 pages
  39. const SIZE: usize = 8193;
  40. let src: [u8; SIZE] = [22; SIZE];
  41. struct Dst {
  42. start: usize,
  43. buf: [u8; SIZE],
  44. end: usize,
  45. }
  46. let mut dst = Dst {
  47. start: 0,
  48. buf: [0; SIZE],
  49. end: 0,
  50. };
  51. unsafe {
  52. assert_eq!(
  53. memcpy(dst.buf.as_mut_ptr(), src.as_ptr(), SIZE),
  54. dst.buf.as_mut_ptr()
  55. );
  56. assert_eq!(dst.start, 0);
  57. assert_eq!(dst.buf, [22; SIZE]);
  58. assert_eq!(dst.end, 0);
  59. }
  60. }
  61. #[test]
  62. fn memmove_forward() {
  63. let mut arr: [u8; 12] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
  64. unsafe {
  65. let src = arr.as_ptr().offset(6);
  66. let dst = arr.as_mut_ptr().offset(3);
  67. assert_eq!(memmove(dst, src, 5), dst);
  68. assert_eq!(arr, [0, 1, 2, 6, 7, 8, 9, 10, 8, 9, 10, 11]);
  69. }
  70. }
  71. #[test]
  72. fn memmove_backward() {
  73. let mut arr: [u8; 12] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
  74. unsafe {
  75. let src = arr.as_ptr().offset(3);
  76. let dst = arr.as_mut_ptr().offset(6);
  77. assert_eq!(memmove(dst, src, 5), dst);
  78. assert_eq!(arr, [0, 1, 2, 3, 4, 5, 3, 4, 5, 6, 7, 11]);
  79. }
  80. }
  81. #[test]
  82. fn memset_zero() {
  83. let mut arr: [u8; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
  84. unsafe {
  85. let ptr = arr.as_mut_ptr().offset(5);
  86. assert_eq!(memset(ptr, 0, 2), ptr);
  87. assert_eq!(arr, [0, 1, 2, 3, 4, 0, 0, 7]);
  88. // Only the LSB matters for a memset
  89. assert_eq!(memset(arr.as_mut_ptr(), 0x2000, 8), arr.as_mut_ptr());
  90. assert_eq!(arr, [0, 0, 0, 0, 0, 0, 0, 0]);
  91. }
  92. }
  93. #[test]
  94. fn memset_nonzero() {
  95. let mut arr: [u8; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
  96. unsafe {
  97. let ptr = arr.as_mut_ptr().offset(2);
  98. assert_eq!(memset(ptr, 22, 3), ptr);
  99. assert_eq!(arr, [0, 1, 22, 22, 22, 5, 6, 7]);
  100. // Only the LSB matters for a memset
  101. assert_eq!(memset(arr.as_mut_ptr(), 0x2009, 8), arr.as_mut_ptr());
  102. assert_eq!(arr, [9, 9, 9, 9, 9, 9, 9, 9]);
  103. }
  104. }
  105. #[test]
  106. fn memcmp_eq() {
  107. let arr1: [u8; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
  108. let arr2: [u8; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
  109. unsafe {
  110. assert_eq!(memcmp(arr1.as_ptr(), arr2.as_ptr(), 8), 0);
  111. assert_eq!(memcmp(arr1.as_ptr(), arr2.as_ptr(), 3), 0);
  112. }
  113. }
  114. #[test]
  115. fn memcmp_ne() {
  116. let arr1: [u8; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
  117. let arr2: [u8; 8] = [0, 1, 2, 3, 4, 5, 7, 7];
  118. unsafe {
  119. assert!(memcmp(arr1.as_ptr(), arr2.as_ptr(), 8) < 0);
  120. assert!(memcmp(arr2.as_ptr(), arr1.as_ptr(), 8) > 0);
  121. }
  122. }
  123. #[derive(Clone, Copy)]
  124. struct AlignedStorage<const N: usize>([u8; N], [usize; 0]);
  125. fn gen_arr<const N: usize>() -> AlignedStorage<N> {
  126. let mut ret = AlignedStorage::<N>([0; N], []);
  127. for i in 0..N {
  128. ret.0[i] = i as u8;
  129. }
  130. ret
  131. }
  132. #[test]
  133. fn memmove_forward_misaligned_nonaligned_start() {
  134. let mut arr = gen_arr::<32>();
  135. let mut reference = arr;
  136. unsafe {
  137. let src = arr.0.as_ptr().offset(6);
  138. let dst = arr.0.as_mut_ptr().offset(3);
  139. assert_eq!(memmove(dst, src, 17), dst);
  140. reference.0.copy_within(6..6 + 17, 3);
  141. assert_eq!(arr.0, reference.0);
  142. }
  143. }
  144. #[test]
  145. fn memmove_forward_misaligned_aligned_start() {
  146. let mut arr = gen_arr::<32>();
  147. let mut reference = arr;
  148. unsafe {
  149. let src = arr.0.as_ptr().offset(6);
  150. let dst = arr.0.as_mut_ptr().add(0);
  151. assert_eq!(memmove(dst, src, 17), dst);
  152. reference.0.copy_within(6..6 + 17, 0);
  153. assert_eq!(arr.0, reference.0);
  154. }
  155. }
  156. #[test]
  157. fn memmove_forward_aligned() {
  158. let mut arr = gen_arr::<32>();
  159. let mut reference = arr;
  160. unsafe {
  161. let src = arr.0.as_ptr().add(3 + WORD_SIZE);
  162. let dst = arr.0.as_mut_ptr().add(3);
  163. assert_eq!(memmove(dst, src, 17), dst);
  164. reference
  165. .0
  166. .copy_within(3 + WORD_SIZE..3 + WORD_SIZE + 17, 3);
  167. assert_eq!(arr.0, reference.0);
  168. }
  169. }
  170. #[test]
  171. fn memmove_backward_misaligned_nonaligned_start() {
  172. let mut arr = gen_arr::<32>();
  173. let mut reference = arr;
  174. unsafe {
  175. let src = arr.0.as_ptr().offset(3);
  176. let dst = arr.0.as_mut_ptr().offset(6);
  177. assert_eq!(memmove(dst, src, 17), dst);
  178. reference.0.copy_within(3..3 + 17, 6);
  179. assert_eq!(arr.0, reference.0);
  180. }
  181. }
  182. #[test]
  183. fn memmove_backward_misaligned_aligned_start() {
  184. let mut arr = gen_arr::<32>();
  185. let mut reference = arr;
  186. unsafe {
  187. let src = arr.0.as_ptr().offset(3);
  188. let dst = arr.0.as_mut_ptr().add(WORD_SIZE);
  189. assert_eq!(memmove(dst, src, 17), dst);
  190. reference.0.copy_within(3..3 + 17, WORD_SIZE);
  191. assert_eq!(arr.0, reference.0);
  192. }
  193. }
  194. #[test]
  195. fn memmove_backward_aligned() {
  196. let mut arr = gen_arr::<32>();
  197. let mut reference = arr;
  198. unsafe {
  199. let src = arr.0.as_ptr().add(3);
  200. let dst = arr.0.as_mut_ptr().add(3 + WORD_SIZE);
  201. assert_eq!(memmove(dst, src, 17), dst);
  202. reference.0.copy_within(3..3 + 17, 3 + WORD_SIZE);
  203. assert_eq!(arr.0, reference.0);
  204. }
  205. }
  206. #[test]
  207. fn memset_backward_misaligned_nonaligned_start() {
  208. let mut arr = gen_arr::<32>();
  209. let mut reference = arr;
  210. unsafe {
  211. let ptr = arr.0.as_mut_ptr().offset(6);
  212. assert_eq!(memset(ptr, 0xCC, 17), ptr);
  213. core::ptr::write_bytes(reference.0.as_mut_ptr().add(6), 0xCC, 17);
  214. assert_eq!(arr.0, reference.0);
  215. }
  216. }
  217. #[test]
  218. fn memset_backward_misaligned_aligned_start() {
  219. let mut arr = gen_arr::<32>();
  220. let mut reference = arr;
  221. unsafe {
  222. let ptr = arr.0.as_mut_ptr().add(WORD_SIZE);
  223. assert_eq!(memset(ptr, 0xCC, 17), ptr);
  224. core::ptr::write_bytes(reference.0.as_mut_ptr().add(WORD_SIZE), 0xCC, 17);
  225. assert_eq!(arr.0, reference.0);
  226. }
  227. }
  228. #[test]
  229. fn memset_backward_aligned() {
  230. let mut arr = gen_arr::<32>();
  231. let mut reference = arr;
  232. unsafe {
  233. let ptr = arr.0.as_mut_ptr().add(3 + WORD_SIZE);
  234. assert_eq!(memset(ptr, 0xCC, 17), ptr);
  235. core::ptr::write_bytes(reference.0.as_mut_ptr().add(3 + WORD_SIZE), 0xCC, 17);
  236. assert_eq!(arr.0, reference.0);
  237. }
  238. }