CNDP  22.08.0
cne_pktcpy.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (c) 2019-2022 Intel Corporation
3  */
4 
5 #ifndef _CNE_PKTCPY_H_
6 #define _CNE_PKTCPY_H_
7 
15 #include <stdio.h>
16 #include <stdint.h>
17 #include <string.h>
18 #include <cne_vect.h>
19 #include <cne_common.h>
20 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24 
34 static __cne_always_inline void cne_mov16(uint8_t *dst, const uint8_t *src);
35 
45 static __cne_always_inline void cne_mov32(uint8_t *dst, const uint8_t *src);
46 
56 static __cne_always_inline void cne_mov64(uint8_t *dst, const uint8_t *src);
57 
67 static __cne_always_inline void cne_mov128(uint8_t *dst, const uint8_t *src);
68 
78 static __cne_always_inline void cne_mov256(uint8_t *dst, const uint8_t *src);
79 
95 static __cne_always_inline void *cne_pktcpy(void *dst, const void *src, size_t n);
96 
97 #ifdef CNE_MACHINE_CPUFLAG_AVX512F
98 
99 #define ALIGNMENT_MASK 0x3F
100 
109 static __cne_always_inline void
110 cne_mov16(uint8_t *dst, const uint8_t *src)
111 {
112  __m128i xmm0;
113 
114  xmm0 = _mm_loadu_si128((const __m128i *)src);
115  _mm_storeu_si128((__m128i *)dst, xmm0);
116 }
117 
122 static __cne_always_inline void
123 cne_mov32(uint8_t *dst, const uint8_t *src)
124 {
125  __m256i ymm0;
126 
127  ymm0 = _mm256_loadu_si256((const __m256i *)src);
128  _mm256_storeu_si256((__m256i *)dst, ymm0);
129 }
130 
135 static __cne_always_inline void
136 cne_mov64(uint8_t *dst, const uint8_t *src)
137 {
138  __m512i zmm0;
139 
140  zmm0 = _mm512_loadu_si512((const void *)src);
141  _mm512_storeu_si512((void *)dst, zmm0);
142 }
143 
148 static __cne_always_inline void
149 cne_mov128(uint8_t *dst, const uint8_t *src)
150 {
151  cne_mov64(dst + 0 * 64, src + 0 * 64);
152  cne_mov64(dst + 1 * 64, src + 1 * 64);
153 }
154 
159 static __cne_always_inline void
160 cne_mov256(uint8_t *dst, const uint8_t *src)
161 {
162  cne_mov64(dst + 0 * 64, src + 0 * 64);
163  cne_mov64(dst + 1 * 64, src + 1 * 64);
164  cne_mov64(dst + 2 * 64, src + 2 * 64);
165  cne_mov64(dst + 3 * 64, src + 3 * 64);
166 }
167 
172 static __cne_always_inline void
173 cne_mov128blocks(uint8_t *dst, const uint8_t *src, size_t n)
174 {
175  __m512i zmm0, zmm1;
176 
177  while (n >= 128) {
178  zmm0 = _mm512_loadu_si512((const void *)(src + 0 * 64));
179  n -= 128;
180  zmm1 = _mm512_loadu_si512((const void *)(src + 1 * 64));
181  src = src + 128;
182  _mm512_storeu_si512((void *)(dst + 0 * 64), zmm0);
183  _mm512_storeu_si512((void *)(dst + 1 * 64), zmm1);
184  dst = dst + 128;
185  }
186 }
187 
192 static inline void
193 cne_mov512blocks(uint8_t *dst, const uint8_t *src, size_t n)
194 {
195  __m512i zmm0, zmm1, zmm2, zmm3, zmm4, zmm5, zmm6, zmm7;
196 
197  while (n >= 512) {
198  zmm0 = _mm512_loadu_si512((const void *)(src + 0 * 64));
199  n -= 512;
200  zmm1 = _mm512_loadu_si512((const void *)(src + 1 * 64));
201  zmm2 = _mm512_loadu_si512((const void *)(src + 2 * 64));
202  zmm3 = _mm512_loadu_si512((const void *)(src + 3 * 64));
203  zmm4 = _mm512_loadu_si512((const void *)(src + 4 * 64));
204  zmm5 = _mm512_loadu_si512((const void *)(src + 5 * 64));
205  zmm6 = _mm512_loadu_si512((const void *)(src + 6 * 64));
206  zmm7 = _mm512_loadu_si512((const void *)(src + 7 * 64));
207  src = src + 512;
208  _mm512_storeu_si512((void *)(dst + 0 * 64), zmm0);
209  _mm512_storeu_si512((void *)(dst + 1 * 64), zmm1);
210  _mm512_storeu_si512((void *)(dst + 2 * 64), zmm2);
211  _mm512_storeu_si512((void *)(dst + 3 * 64), zmm3);
212  _mm512_storeu_si512((void *)(dst + 4 * 64), zmm4);
213  _mm512_storeu_si512((void *)(dst + 5 * 64), zmm5);
214  _mm512_storeu_si512((void *)(dst + 6 * 64), zmm6);
215  _mm512_storeu_si512((void *)(dst + 7 * 64), zmm7);
216  dst = dst + 512;
217  }
218 }
219 
220 static __cne_always_inline void *
221 cne_pktcpy_generic(void *dst, const void *src, size_t n)
222 {
223  uintptr_t dstu = (uintptr_t)dst;
224  uintptr_t srcu = (uintptr_t)src;
225  void *ret = dst;
226  size_t dstofss;
227  size_t bits;
228 
232  if (n < 16) {
233  if (n & 0x01) {
234  *(uint8_t *)dstu = *(const uint8_t *)srcu;
235  srcu = (uintptr_t)((const uint8_t *)srcu + 1);
236  dstu = (uintptr_t)((uint8_t *)dstu + 1);
237  }
238  if (n & 0x02) {
239  *(uint16_t *)dstu = *(const uint16_t *)srcu;
240  srcu = (uintptr_t)((const uint16_t *)srcu + 1);
241  dstu = (uintptr_t)((uint16_t *)dstu + 1);
242  }
243  if (n & 0x04) {
244  *(uint32_t *)dstu = *(const uint32_t *)srcu;
245  srcu = (uintptr_t)((const uint32_t *)srcu + 1);
246  dstu = (uintptr_t)((uint32_t *)dstu + 1);
247  }
248  if (n & 0x08)
249  *(uint64_t *)dstu = *(const uint64_t *)srcu;
250  return ret;
251  }
252 
256  if (n <= 32) {
257  cne_mov16((uint8_t *)dst, (const uint8_t *)src);
258  cne_mov16((uint8_t *)dst - 16 + n, (const uint8_t *)src - 16 + n);
259  return ret;
260  }
261  if (n <= 64) {
262  cne_mov32((uint8_t *)dst, (const uint8_t *)src);
263  cne_mov32((uint8_t *)dst - 32 + n, (const uint8_t *)src - 32 + n);
264  return ret;
265  }
266  if (n <= 512) {
267  if (n >= 256) {
268  n -= 256;
269  cne_mov256((uint8_t *)dst, (const uint8_t *)src);
270  src = (const uint8_t *)src + 256;
271  dst = (uint8_t *)dst + 256;
272  }
273  if (n >= 128) {
274  n -= 128;
275  cne_mov128((uint8_t *)dst, (const uint8_t *)src);
276  src = (const uint8_t *)src + 128;
277  dst = (uint8_t *)dst + 128;
278  }
279  COPY_BLOCK_128_BACK63:
280  if (n > 64) {
281  cne_mov64((uint8_t *)dst, (const uint8_t *)src);
282  cne_mov64((uint8_t *)dst - 64 + n, (const uint8_t *)src - 64 + n);
283  return ret;
284  }
285  if (n > 0)
286  cne_mov64((uint8_t *)dst - 64 + n, (const uint8_t *)src - 64 + n);
287  return ret;
288  }
289 
293  dstofss = ((uintptr_t)dst & 0x3F);
294  if (dstofss > 0) {
295  dstofss = 64 - dstofss;
296  n -= dstofss;
297  cne_mov64((uint8_t *)dst, (const uint8_t *)src);
298  src = (const uint8_t *)src + dstofss;
299  dst = (uint8_t *)dst + dstofss;
300  }
301 
307  cne_mov512blocks((uint8_t *)dst, (const uint8_t *)src, n);
308  bits = n;
309  n = n & 511;
310  bits -= n;
311  src = (const uint8_t *)src + bits;
312  dst = (uint8_t *)dst + bits;
313 
319  if (n >= 128) {
320  cne_mov128blocks((uint8_t *)dst, (const uint8_t *)src, n);
321  bits = n;
322  n = n & 127;
323  bits -= n;
324  src = (const uint8_t *)src + bits;
325  dst = (uint8_t *)dst + bits;
326  }
327 
331  goto COPY_BLOCK_128_BACK63;
332 }
333 
334 #elif defined CNE_MACHINE_CPUFLAG_AVX2
335 
336 #define ALIGNMENT_MASK 0x1F
337 
346 static __cne_always_inline void
347 cne_mov16(uint8_t *dst, const uint8_t *src)
348 {
349  __m128i xmm0;
350 
351  xmm0 = _mm_loadu_si128((const __m128i *)src);
352  _mm_storeu_si128((__m128i *)dst, xmm0);
353 }
354 
359 static __cne_always_inline void
360 cne_mov32(uint8_t *dst, const uint8_t *src)
361 {
362  __m256i ymm0;
363 
364  ymm0 = _mm256_loadu_si256((const __m256i *)src);
365  _mm256_storeu_si256((__m256i *)dst, ymm0);
366 }
367 
372 static __cne_always_inline void
373 cne_mov64(uint8_t *dst, const uint8_t *src)
374 {
375  cne_mov32((uint8_t *)dst + 0 * 32, (const uint8_t *)src + 0 * 32);
376  cne_mov32((uint8_t *)dst + 1 * 32, (const uint8_t *)src + 1 * 32);
377 }
378 
383 static __cne_always_inline void
384 cne_mov128(uint8_t *dst, const uint8_t *src)
385 {
386  cne_mov32((uint8_t *)dst + 0 * 32, (const uint8_t *)src + 0 * 32);
387  cne_mov32((uint8_t *)dst + 1 * 32, (const uint8_t *)src + 1 * 32);
388  cne_mov32((uint8_t *)dst + 2 * 32, (const uint8_t *)src + 2 * 32);
389  cne_mov32((uint8_t *)dst + 3 * 32, (const uint8_t *)src + 3 * 32);
390 }
391 
396 static __cne_always_inline void
397 cne_mov128blocks(uint8_t *dst, const uint8_t *src, size_t n)
398 {
399  __m256i ymm0, ymm1, ymm2, ymm3;
400 
401  while (n >= 128) {
402  ymm0 = _mm256_loadu_si256((const __m256i *)((const uint8_t *)src + 0 * 32));
403  n -= 128;
404  ymm1 = _mm256_loadu_si256((const __m256i *)((const uint8_t *)src + 1 * 32));
405  ymm2 = _mm256_loadu_si256((const __m256i *)((const uint8_t *)src + 2 * 32));
406  ymm3 = _mm256_loadu_si256((const __m256i *)((const uint8_t *)src + 3 * 32));
407  src = (const uint8_t *)src + 128;
408  _mm256_storeu_si256((__m256i *)((uint8_t *)dst + 0 * 32), ymm0);
409  _mm256_storeu_si256((__m256i *)((uint8_t *)dst + 1 * 32), ymm1);
410  _mm256_storeu_si256((__m256i *)((uint8_t *)dst + 2 * 32), ymm2);
411  _mm256_storeu_si256((__m256i *)((uint8_t *)dst + 3 * 32), ymm3);
412  dst = (uint8_t *)dst + 128;
413  }
414 }
415 
420 static __cne_always_inline void
421 cne_mov256(uint8_t *dst, const uint8_t *src)
422 {
423  cne_mov128(dst + 0 * 128, src + 0 * 128);
424  cne_mov128(dst + 1 * 128, src + 1 * 128);
425 }
426 
441 static __cne_always_inline void *
442 cne_pktcpy_generic(void *dst, const void *src, size_t n)
443 {
444  uintptr_t dstu = (uintptr_t)dst;
445  uintptr_t srcu = (uintptr_t)src;
446  void *ret = dst;
447  size_t dstofss;
448  size_t bits;
449 
453  if (n < 16) {
454  if (n & 0x01) {
455  *(uint8_t *)dstu = *(const uint8_t *)srcu;
456  srcu = (uintptr_t)((const uint8_t *)srcu + 1);
457  dstu = (uintptr_t)((uint8_t *)dstu + 1);
458  }
459  if (n & 0x02) {
460  *(uint16_t *)dstu = *(const uint16_t *)srcu;
461  srcu = (uintptr_t)((const uint16_t *)srcu + 1);
462  dstu = (uintptr_t)((uint16_t *)dstu + 1);
463  }
464  if (n & 0x04) {
465  *(uint32_t *)dstu = *(const uint32_t *)srcu;
466  srcu = (uintptr_t)((const uint32_t *)srcu + 1);
467  dstu = (uintptr_t)((uint32_t *)dstu + 1);
468  }
469  if (n & 0x08) {
470  *(uint64_t *)dstu = *(const uint64_t *)srcu;
471  }
472  return ret;
473  }
474 
478  if (n <= 32) {
479  cne_mov16((uint8_t *)dst, (const uint8_t *)src);
480  cne_mov16((uint8_t *)dst - 16 + n, (const uint8_t *)src - 16 + n);
481  return ret;
482  }
483  if (n <= 48) {
484  cne_mov16((uint8_t *)dst, (const uint8_t *)src);
485  cne_mov16((uint8_t *)dst + 16, (const uint8_t *)src + 16);
486  cne_mov16((uint8_t *)dst - 16 + n, (const uint8_t *)src - 16 + n);
487  return ret;
488  }
489  if (n <= 64) {
490  cne_mov32((uint8_t *)dst, (const uint8_t *)src);
491  cne_mov32((uint8_t *)dst - 32 + n, (const uint8_t *)src - 32 + n);
492  return ret;
493  }
494  if (n <= 256) {
495  if (n >= 128) {
496  n -= 128;
497  cne_mov128((uint8_t *)dst, (const uint8_t *)src);
498  src = (const uint8_t *)src + 128;
499  dst = (uint8_t *)dst + 128;
500  }
501  COPY_BLOCK_128_BACK31:
502  if (n >= 64) {
503  n -= 64;
504  cne_mov64((uint8_t *)dst, (const uint8_t *)src);
505  src = (const uint8_t *)src + 64;
506  dst = (uint8_t *)dst + 64;
507  }
508  if (n > 32) {
509  cne_mov32((uint8_t *)dst, (const uint8_t *)src);
510  cne_mov32((uint8_t *)dst - 32 + n, (const uint8_t *)src - 32 + n);
511  return ret;
512  }
513  if (n > 0) {
514  cne_mov32((uint8_t *)dst - 32 + n, (const uint8_t *)src - 32 + n);
515  }
516  return ret;
517  }
518 
522  dstofss = (uintptr_t)dst & 0x1F;
523  if (dstofss > 0) {
524  dstofss = 32 - dstofss;
525  n -= dstofss;
526  cne_mov32((uint8_t *)dst, (const uint8_t *)src);
527  src = (const uint8_t *)src + dstofss;
528  dst = (uint8_t *)dst + dstofss;
529  }
530 
534  cne_mov128blocks((uint8_t *)dst, (const uint8_t *)src, n);
535  bits = n;
536  n = n & 127;
537  bits -= n;
538  src = (const uint8_t *)src + bits;
539  dst = (uint8_t *)dst + bits;
540 
544  goto COPY_BLOCK_128_BACK31;
545 }
546 
547 #else /* CNE_MACHINE_CPUFLAG */
548 
549 #define ALIGNMENT_MASK 0x0F
550 
559 static __cne_always_inline void
560 cne_mov16(uint8_t *dst, const uint8_t *src)
561 {
562  __m128i xmm0;
563 
564  xmm0 = _mm_loadu_si128((const __m128i *)(const __m128i *)src);
565  _mm_storeu_si128((__m128i *)dst, xmm0);
566 }
567 
572 static __cne_always_inline void
573 cne_mov32(uint8_t *dst, const uint8_t *src)
574 {
575  cne_mov16((uint8_t *)dst + 0 * 16, (const uint8_t *)src + 0 * 16);
576  cne_mov16((uint8_t *)dst + 1 * 16, (const uint8_t *)src + 1 * 16);
577 }
578 
583 static __cne_always_inline void
584 cne_mov64(uint8_t *dst, const uint8_t *src)
585 {
586  cne_mov16((uint8_t *)dst + 0 * 16, (const uint8_t *)src + 0 * 16);
587  cne_mov16((uint8_t *)dst + 1 * 16, (const uint8_t *)src + 1 * 16);
588  cne_mov16((uint8_t *)dst + 2 * 16, (const uint8_t *)src + 2 * 16);
589  cne_mov16((uint8_t *)dst + 3 * 16, (const uint8_t *)src + 3 * 16);
590 }
591 
596 static __cne_always_inline void
597 cne_mov128(uint8_t *dst, const uint8_t *src)
598 {
599  cne_mov16((uint8_t *)dst + 0 * 16, (const uint8_t *)src + 0 * 16);
600  cne_mov16((uint8_t *)dst + 1 * 16, (const uint8_t *)src + 1 * 16);
601  cne_mov16((uint8_t *)dst + 2 * 16, (const uint8_t *)src + 2 * 16);
602  cne_mov16((uint8_t *)dst + 3 * 16, (const uint8_t *)src + 3 * 16);
603  cne_mov16((uint8_t *)dst + 4 * 16, (const uint8_t *)src + 4 * 16);
604  cne_mov16((uint8_t *)dst + 5 * 16, (const uint8_t *)src + 5 * 16);
605  cne_mov16((uint8_t *)dst + 6 * 16, (const uint8_t *)src + 6 * 16);
606  cne_mov16((uint8_t *)dst + 7 * 16, (const uint8_t *)src + 7 * 16);
607 }
608 
613 static __cne_always_inline void
614 cne_mov256(uint8_t *dst, const uint8_t *src)
615 {
616  cne_mov16((uint8_t *)dst + 0 * 16, (const uint8_t *)src + 0 * 16);
617  cne_mov16((uint8_t *)dst + 1 * 16, (const uint8_t *)src + 1 * 16);
618  cne_mov16((uint8_t *)dst + 2 * 16, (const uint8_t *)src + 2 * 16);
619  cne_mov16((uint8_t *)dst + 3 * 16, (const uint8_t *)src + 3 * 16);
620  cne_mov16((uint8_t *)dst + 4 * 16, (const uint8_t *)src + 4 * 16);
621  cne_mov16((uint8_t *)dst + 5 * 16, (const uint8_t *)src + 5 * 16);
622  cne_mov16((uint8_t *)dst + 6 * 16, (const uint8_t *)src + 6 * 16);
623  cne_mov16((uint8_t *)dst + 7 * 16, (const uint8_t *)src + 7 * 16);
624  cne_mov16((uint8_t *)dst + 8 * 16, (const uint8_t *)src + 8 * 16);
625  cne_mov16((uint8_t *)dst + 9 * 16, (const uint8_t *)src + 9 * 16);
626  cne_mov16((uint8_t *)dst + 10 * 16, (const uint8_t *)src + 10 * 16);
627  cne_mov16((uint8_t *)dst + 11 * 16, (const uint8_t *)src + 11 * 16);
628  cne_mov16((uint8_t *)dst + 12 * 16, (const uint8_t *)src + 12 * 16);
629  cne_mov16((uint8_t *)dst + 13 * 16, (const uint8_t *)src + 13 * 16);
630  cne_mov16((uint8_t *)dst + 14 * 16, (const uint8_t *)src + 14 * 16);
631  cne_mov16((uint8_t *)dst + 15 * 16, (const uint8_t *)src + 15 * 16);
632 }
633 
646 // clang-format off
647 #define MOVEUNALIGNED_LEFT47_IMM(dst, src, len, offset) \
648 __extension__ ({ \
649  size_t tmp; \
650  while (len >= 128 + 16 - offset) { \
651  xmm0 = _mm_loadu_si128((const __m128i *)((const uint8_t *)src - offset + 0 * 16)); \
652  len -= 128; \
653  xmm1 = _mm_loadu_si128((const __m128i *)((const uint8_t *)src - offset + 1 * 16)); \
654  xmm2 = _mm_loadu_si128((const __m128i *)((const uint8_t *)src - offset + 2 * 16)); \
655  xmm3 = _mm_loadu_si128((const __m128i *)((const uint8_t *)src - offset + 3 * 16)); \
656  xmm4 = _mm_loadu_si128((const __m128i *)((const uint8_t *)src - offset + 4 * 16)); \
657  xmm5 = _mm_loadu_si128((const __m128i *)((const uint8_t *)src - offset + 5 * 16)); \
658  xmm6 = _mm_loadu_si128((const __m128i *)((const uint8_t *)src - offset + 6 * 16)); \
659  xmm7 = _mm_loadu_si128((const __m128i *)((const uint8_t *)src - offset + 7 * 16)); \
660  xmm8 = _mm_loadu_si128((const __m128i *)((const uint8_t *)src - offset + 8 * 16)); \
661  src = (const uint8_t *)src + 128; \
662  _mm_storeu_si128((__m128i *)((uint8_t *)dst + 0 * 16), _mm_alignr_epi8(xmm1, xmm0, offset)); \
663  _mm_storeu_si128((__m128i *)((uint8_t *)dst + 1 * 16), _mm_alignr_epi8(xmm2, xmm1, offset)); \
664  _mm_storeu_si128((__m128i *)((uint8_t *)dst + 2 * 16), _mm_alignr_epi8(xmm3, xmm2, offset)); \
665  _mm_storeu_si128((__m128i *)((uint8_t *)dst + 3 * 16), _mm_alignr_epi8(xmm4, xmm3, offset)); \
666  _mm_storeu_si128((__m128i *)((uint8_t *)dst + 4 * 16), _mm_alignr_epi8(xmm5, xmm4, offset)); \
667  _mm_storeu_si128((__m128i *)((uint8_t *)dst + 5 * 16), _mm_alignr_epi8(xmm6, xmm5, offset)); \
668  _mm_storeu_si128((__m128i *)((uint8_t *)dst + 6 * 16), _mm_alignr_epi8(xmm7, xmm6, offset)); \
669  _mm_storeu_si128((__m128i *)((uint8_t *)dst + 7 * 16), _mm_alignr_epi8(xmm8, xmm7, offset)); \
670  dst = (uint8_t *)dst + 128; \
671  } \
672  tmp = len; \
673  len = ((len - 16 + offset) & 127) + 16 - offset; \
674  tmp -= len; \
675  src = (const uint8_t *)src + tmp; \
676  dst = (uint8_t *)dst + tmp; \
677  if (len >= 32 + 16 - offset) { \
678  while (len >= 32 + 16 - offset) { \
679  xmm0 = _mm_loadu_si128((const __m128i *)((const uint8_t *)src - offset + 0 * 16)); \
680  len -= 32; \
681  xmm1 = _mm_loadu_si128((const __m128i *)((const uint8_t *)src - offset + 1 * 16)); \
682  xmm2 = _mm_loadu_si128((const __m128i *)((const uint8_t *)src - offset + 2 * 16)); \
683  src = (const uint8_t *)src + 32; \
684  _mm_storeu_si128((__m128i *)((uint8_t *)dst + 0 * 16), _mm_alignr_epi8(xmm1, xmm0, offset)); \
685  _mm_storeu_si128((__m128i *)((uint8_t *)dst + 1 * 16), _mm_alignr_epi8(xmm2, xmm1, offset)); \
686  dst = (uint8_t *)dst + 32; \
687  } \
688  tmp = len; \
689  len = ((len - 16 + offset) & 31) + 16 - offset; \
690  tmp -= len; \
691  src = (const uint8_t *)src + tmp; \
692  dst = (uint8_t *)dst + tmp; \
693  } \
694 })
695 
708 #define MOVEUNALIGNED_LEFT47(dst, src, len, offset) \
709 __extension__ ({ \
710  switch (offset) { \
711  case 0x01: MOVEUNALIGNED_LEFT47_IMM(dst, src, n, 0x01); break; \
712  case 0x02: MOVEUNALIGNED_LEFT47_IMM(dst, src, n, 0x02); break; \
713  case 0x03: MOVEUNALIGNED_LEFT47_IMM(dst, src, n, 0x03); break; \
714  case 0x04: MOVEUNALIGNED_LEFT47_IMM(dst, src, n, 0x04); break; \
715  case 0x05: MOVEUNALIGNED_LEFT47_IMM(dst, src, n, 0x05); break; \
716  case 0x06: MOVEUNALIGNED_LEFT47_IMM(dst, src, n, 0x06); break; \
717  case 0x07: MOVEUNALIGNED_LEFT47_IMM(dst, src, n, 0x07); break; \
718  case 0x08: MOVEUNALIGNED_LEFT47_IMM(dst, src, n, 0x08); break; \
719  case 0x09: MOVEUNALIGNED_LEFT47_IMM(dst, src, n, 0x09); break; \
720  case 0x0A: MOVEUNALIGNED_LEFT47_IMM(dst, src, n, 0x0A); break; \
721  case 0x0B: MOVEUNALIGNED_LEFT47_IMM(dst, src, n, 0x0B); break; \
722  case 0x0C: MOVEUNALIGNED_LEFT47_IMM(dst, src, n, 0x0C); break; \
723  case 0x0D: MOVEUNALIGNED_LEFT47_IMM(dst, src, n, 0x0D); break; \
724  case 0x0E: MOVEUNALIGNED_LEFT47_IMM(dst, src, n, 0x0E); break; \
725  case 0x0F: MOVEUNALIGNED_LEFT47_IMM(dst, src, n, 0x0F); break; \
726  default:; \
727  } \
728 })
729 // clang-format on
730 
745 static __cne_always_inline void *
746 cne_pktcpy_generic(void *dst, const void *src, size_t n)
747 {
748  __m128i xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8;
749  uintptr_t dstu = (uintptr_t)dst;
750  uintptr_t srcu = (uintptr_t)src;
751  void *ret = dst;
752  size_t dstofss;
753  size_t srcofs;
754 
758  if (n < 16) {
759  if (n & 0x01) {
760  *(uint8_t *)dstu = *(const uint8_t *)srcu;
761  srcu = (uintptr_t)((const uint8_t *)srcu + 1);
762  dstu = (uintptr_t)((uint8_t *)dstu + 1);
763  }
764  if (n & 0x02) {
765  *(uint16_t *)dstu = *(const uint16_t *)srcu;
766  srcu = (uintptr_t)((const uint16_t *)srcu + 1);
767  dstu = (uintptr_t)((uint16_t *)dstu + 1);
768  }
769  if (n & 0x04) {
770  *(uint32_t *)dstu = *(const uint32_t *)srcu;
771  srcu = (uintptr_t)((const uint32_t *)srcu + 1);
772  dstu = (uintptr_t)((uint32_t *)dstu + 1);
773  }
774  if (n & 0x08) {
775  *(uint64_t *)dstu = *(const uint64_t *)srcu;
776  }
777  return ret;
778  }
779 
783  if (n <= 32) {
784  cne_mov16((uint8_t *)dst, (const uint8_t *)src);
785  cne_mov16((uint8_t *)dst - 16 + n, (const uint8_t *)src - 16 + n);
786  return ret;
787  }
788  if (n <= 48) {
789  cne_mov32((uint8_t *)dst, (const uint8_t *)src);
790  cne_mov16((uint8_t *)dst - 16 + n, (const uint8_t *)src - 16 + n);
791  return ret;
792  }
793  if (n <= 64) {
794  cne_mov32((uint8_t *)dst, (const uint8_t *)src);
795  cne_mov16((uint8_t *)dst + 32, (const uint8_t *)src + 32);
796  cne_mov16((uint8_t *)dst - 16 + n, (const uint8_t *)src - 16 + n);
797  return ret;
798  }
799  if (n <= 128) {
800  goto COPY_BLOCK_128_BACK15;
801  }
802  if (n <= 512) {
803  if (n >= 256) {
804  n -= 256;
805  cne_mov128((uint8_t *)dst, (const uint8_t *)src);
806  cne_mov128((uint8_t *)dst + 128, (const uint8_t *)src + 128);
807  src = (const uint8_t *)src + 256;
808  dst = (uint8_t *)dst + 256;
809  }
810  COPY_BLOCK_255_BACK15:
811  if (n >= 128) {
812  n -= 128;
813  cne_mov128((uint8_t *)dst, (const uint8_t *)src);
814  src = (const uint8_t *)src + 128;
815  dst = (uint8_t *)dst + 128;
816  }
817  COPY_BLOCK_128_BACK15:
818  if (n >= 64) {
819  n -= 64;
820  cne_mov64((uint8_t *)dst, (const uint8_t *)src);
821  src = (const uint8_t *)src + 64;
822  dst = (uint8_t *)dst + 64;
823  }
824  COPY_BLOCK_64_BACK15:
825  if (n >= 32) {
826  n -= 32;
827  cne_mov32((uint8_t *)dst, (const uint8_t *)src);
828  src = (const uint8_t *)src + 32;
829  dst = (uint8_t *)dst + 32;
830  }
831  if (n > 16) {
832  cne_mov16((uint8_t *)dst, (const uint8_t *)src);
833  cne_mov16((uint8_t *)dst - 16 + n, (const uint8_t *)src - 16 + n);
834  return ret;
835  }
836  if (n > 0) {
837  cne_mov16((uint8_t *)dst - 16 + n, (const uint8_t *)src - 16 + n);
838  }
839  return ret;
840  }
841 
848  dstofss = (uintptr_t)dst & 0x0F;
849  if (dstofss > 0) {
850  dstofss = 16 - dstofss + 16;
851  n -= dstofss;
852  cne_mov32((uint8_t *)dst, (const uint8_t *)src);
853  src = (const uint8_t *)src + dstofss;
854  dst = (uint8_t *)dst + dstofss;
855  }
856  srcofs = ((uintptr_t)src & 0x0F);
857 
861  if (srcofs == 0) {
865  for (; n >= 256; n -= 256) {
866  cne_mov256((uint8_t *)dst, (const uint8_t *)src);
867  dst = (uint8_t *)dst + 256;
868  src = (const uint8_t *)src + 256;
869  }
870 
874  goto COPY_BLOCK_255_BACK15;
875  }
876 
880  MOVEUNALIGNED_LEFT47(dst, src, n, srcofs);
881 
885  goto COPY_BLOCK_64_BACK15;
886 }
887 
888 #endif /* CNE_MACHINE_CPUFLAG */
889 
904 static __cne_always_inline void *
905 cne_pktcpy_aligned(void *dst, const void *src, size_t n)
906 {
907  void *ret = dst;
908 
909  /* Copy size <= 16 bytes */
910  if (n < 16) {
911  if (n & 0x01) {
912  *(uint8_t *)dst = *(const uint8_t *)src;
913  src = (const uint8_t *)src + 1;
914  dst = (uint8_t *)dst + 1;
915  }
916  if (n & 0x02) {
917  *(uint16_t *)dst = *(const uint16_t *)src;
918  src = (const uint16_t *)src + 1;
919  dst = (uint16_t *)dst + 1;
920  }
921  if (n & 0x04) {
922  *(uint32_t *)dst = *(const uint32_t *)src;
923  src = (const uint32_t *)src + 1;
924  dst = (uint32_t *)dst + 1;
925  }
926  if (n & 0x08)
927  *(uint64_t *)dst = *(const uint64_t *)src;
928 
929  return ret;
930  }
931 
932  /* Copy 16 <= size <= 32 bytes */
933  if (n <= 32) {
934  cne_mov16((uint8_t *)dst, (const uint8_t *)src);
935  cne_mov16((uint8_t *)dst - 16 + n, (const uint8_t *)src - 16 + n);
936 
937  return ret;
938  }
939 
940  /* Copy 32 < size <= 64 bytes */
941  if (n <= 64) {
942  cne_mov32((uint8_t *)dst, (const uint8_t *)src);
943  cne_mov32((uint8_t *)dst - 32 + n, (const uint8_t *)src - 32 + n);
944 
945  return ret;
946  }
947 
948  /* Copy 64 bytes blocks */
949  for (; n >= 64; n -= 64) {
950  cne_mov64((uint8_t *)dst, (const uint8_t *)src);
951  dst = (uint8_t *)dst + 64;
952  src = (const uint8_t *)src + 64;
953  }
954 
955  /* Copy whatever left */
956  cne_mov64((uint8_t *)dst - 64 + n, (const uint8_t *)src - 64 + n);
957 
958  return ret;
959 }
960 
961 static __cne_always_inline void *
962 cne_pktcpy(void *dst, const void *src, size_t n)
963 {
964  if (!(((uintptr_t)dst | (uintptr_t)src) & ALIGNMENT_MASK))
965  return cne_pktcpy_aligned(dst, src, n);
966  else
967  return cne_pktcpy_generic(dst, src, n);
968 }
969 
970 #ifdef __cplusplus
971 }
972 #endif
973 
974 #endif /* _CNE_PKTCPY_H_ */
#define __cne_always_inline
Definition: cne_common.h:218
static __cne_always_inline void * cne_pktcpy_generic(void *dst, const void *src, size_t n)
Definition: cne_pktcpy.h:746
static __cne_always_inline void cne_mov64(uint8_t *dst, const uint8_t *src)
Definition: cne_pktcpy.h:584
static __cne_always_inline void cne_mov32(uint8_t *dst, const uint8_t *src)
Definition: cne_pktcpy.h:573
#define MOVEUNALIGNED_LEFT47(dst, src, len, offset)
Definition: cne_pktcpy.h:708
static __cne_always_inline void cne_mov256(uint8_t *dst, const uint8_t *src)
Definition: cne_pktcpy.h:614
static __cne_always_inline void * cne_pktcpy(void *dst, const void *src, size_t n)
Definition: cne_pktcpy.h:962
static __cne_always_inline void cne_mov16(uint8_t *dst, const uint8_t *src)
Definition: cne_pktcpy.h:560
static __cne_always_inline void cne_mov128(uint8_t *dst, const uint8_t *src)
Definition: cne_pktcpy.h:597
static __cne_always_inline void * cne_pktcpy_aligned(void *dst, const void *src, size_t n)
Definition: cne_pktcpy.h:905