Damjan Marion | 56f54af | 2021-10-12 20:30:02 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: Apache-2.0 |
| 2 | * Copyright(c) 2021 Cisco Systems, Inc. |
| 3 | */ |
| 4 | |
| 5 | #ifdef __x86_64__ |
| 6 | |
| 7 | #include <vppinfra/format.h> |
Damjan Marion | c3542e1 | 2023-03-15 11:42:06 +0000 | [diff] [blame] | 8 | #include <vppinfra/test/test.h> |
Damjan Marion | 98f7f0a | 2023-04-17 09:38:11 +0000 | [diff] [blame] | 9 | #include <vppinfra/memcpy_x86_64.h> |
Damjan Marion | 56f54af | 2021-10-12 20:30:02 +0200 | [diff] [blame] | 10 | |
Damjan Marion | 3323e20 | 2021-12-02 11:28:57 +0100 | [diff] [blame] | 11 | __test_funct_fn void |
Damjan Marion | 56f54af | 2021-10-12 20:30:02 +0200 | [diff] [blame] | 12 | wrapper (u8 *dst, u8 *src, uword n) |
| 13 | { |
| 14 | clib_memcpy_x86_64 (dst, src, n); |
| 15 | } |
| 16 | |
| 17 | /* clang-format off */ |
| 18 | #define foreach_const_n \ |
| 19 | _(1) _(2) _(3) _(4) _(5) _(6) _(7) _(8) _(9) _(10) _(11) _(12) _(13) _(14) \ |
| 20 | _(15) _(16) _(17) _(18) _(19) _(20) _(21) _(22) _(23) _(24) _(25) _(26) \ |
| 21 | _(27) _(28) _(29) _(30) _(31) _(32) _(33) _(34) _(35) _(36) _(37) _(38) \ |
| 22 | _(39) _(40) _(41) _(42) _(43) _(44) _(45) _(46) _(47) _(48) _(49) _(50) \ |
| 23 | _(51) _(52) _(53) _(54) _(55) _(56) _(57) _(58) _(59) _(60) _(61) _(62) \ |
| 24 | _(63) _(64) _(65) _(66) _(67) _(68) _(69) _(70) _(71) _(72) _(73) _(74) \ |
| 25 | _(75) _(76) _(77) _(78) _(79) _(80) _(81) _(82) _(83) _(84) _(85) _(86) \ |
| 26 | _(87) _(88) _(89) _(90) _(91) _(92) _(93) _(94) _(95) _(96) _(97) _(98) \ |
| 27 | _(99) _(100) _(101) _(102) _(103) _(104) _(105) _(106) _(107) _(108) \ |
| 28 | _(109) _(110) _(111) _(112) _(113) _(114) _(115) _(116) _(117) _(118) \ |
| 29 | _(119) _(120) _(121) _(122) _(123) _(124) _(125) _(126) _(127) _(128) \ |
| 30 | _(129) _(130) _(131) _(132) _(133) _(134) _(135) _(136) _(137) _(138) \ |
| 31 | _(139) _(140) _(141) _(142) _(143) _(144) _(145) _(146) _(147) _(148) \ |
| 32 | _(149) _(150) _(151) _(152) _(153) _(154) _(155) _(156) _(157) _(158) \ |
| 33 | _(159) _(160) _(161) _(162) _(163) _(164) _(165) _(166) _(167) _(168) \ |
| 34 | _(169) _(170) _(171) _(172) _(173) _(174) _(175) _(176) _(177) _(178) \ |
| 35 | _(179) _(180) _(181) _(182) _(183) _(184) _(185) _(186) _(187) _(188) \ |
| 36 | _(189) _(190) _(191) _(192) _(193) _(194) _(195) _(196) _(197) _(198) \ |
| 37 | _(199) _(200) _(201) _(202) _(203) _(204) _(205) _(206) _(207) _(208) \ |
| 38 | _(209) _(210) _(211) _(212) _(213) _(214) _(215) _(216) _(217) _(218) \ |
| 39 | _(219) _(220) _(221) _(222) _(223) _(224) _(225) _(226) _(227) _(228) \ |
| 40 | _(229) _(230) _(231) _(232) _(233) _(234) _(235) _(236) _(237) _(238) \ |
| 41 | _(239) _(240) _(241) _(242) _(243) _(244) _(245) _(246) _(247) _(248) \ |
| 42 | _(249) _(250) _(251) _(252) _(253) _(254) _(255) |
| 43 | /* clang-format on */ |
| 44 | |
| 45 | #define _(n) \ |
| 46 | static __clib_noinline void wrapper##n (u8 *dst, u8 *src) \ |
| 47 | { \ |
| 48 | clib_memcpy_x86_64 (dst, src, n); \ |
| 49 | } |
| 50 | |
| 51 | foreach_const_n; |
| 52 | #undef _ |
| 53 | |
| 54 | typedef void (const_fp_t) (u8 *dst, u8 *src); |
| 55 | typedef struct |
| 56 | { |
| 57 | u16 len; |
| 58 | const_fp_t *fp; |
| 59 | } counst_test_t; |
| 60 | |
| 61 | static counst_test_t const_tests[] = { |
| 62 | #define _(n) { .fp = wrapper##n, .len = n }, |
| 63 | foreach_const_n |
| 64 | #undef _ |
| 65 | }; |
| 66 | |
| 67 | #define MAX_LEN 1024 |
| 68 | |
| 69 | static clib_error_t * |
| 70 | validate_one (clib_error_t *err, u8 *d, u8 *s, u16 n, u8 off, int is_const) |
| 71 | { |
| 72 | for (int i = 0; i < n; i++) |
| 73 | if (d[i] != s[i]) |
| 74 | return clib_error_return (err, |
| 75 | "memcpy error at position %d " |
| 76 | "(n = %u, off = %u, expected 0x%02x " |
| 77 | "found 0x%02x%s)", |
| 78 | i, n, off, s[i], d[i], |
| 79 | is_const ? ", const" : ""); |
| 80 | for (int i = -64; i < 0; i++) |
| 81 | if (d[i] != 0xfe) |
| 82 | return clib_error_return (err, |
| 83 | "buffer underrun at position %d " |
| 84 | "(n = %u, off = %u, expected 0xfe " |
| 85 | "found 0x%02x%s)", |
| 86 | i, n, off, d[i], is_const ? ", const" : ""); |
| 87 | for (int i = n; i < n + 64; i++) |
| 88 | if (d[i] != 0xfe) |
| 89 | return clib_error_return (err, |
| 90 | "buffer overrun at position %d " |
| 91 | "(n = %u, off = %u, expected 0xfe " |
| 92 | "found 0x%02x%s)", |
| 93 | i, n, off, d[i], is_const ? ", const" : ""); |
| 94 | return err; |
| 95 | } |
| 96 | |
| 97 | static clib_error_t * |
| 98 | test_clib_memcpy_x86_64 (clib_error_t *err) |
| 99 | { |
| 100 | u8 src[MAX_LEN + 192]; |
Dmitry Valter | 0bef4cf | 2024-01-05 17:02:55 +0000 | [diff] [blame] | 101 | u8 dst[MAX_LEN + 192]; |
Damjan Marion | 56f54af | 2021-10-12 20:30:02 +0200 | [diff] [blame] | 102 | |
| 103 | for (int i = 0; i < ARRAY_LEN (src); i++) |
| 104 | src[i] = i & 0x7f; |
| 105 | |
| 106 | for (int j = 0; j < ARRAY_LEN (const_tests); j++) |
| 107 | { |
| 108 | u8 *d = dst + 64; |
| 109 | u8 *s = src + 64; |
| 110 | u16 n = const_tests[j].len; |
| 111 | |
| 112 | for (int i = 0; i < 128 + n; i++) |
| 113 | dst[i] = 0xfe; |
| 114 | const_tests[j].fp (d, s); |
| 115 | if ((err = validate_one (err, d, s, n, 0, /* is_const */ 1))) |
| 116 | return err; |
| 117 | } |
| 118 | |
| 119 | for (u16 n = 1; n <= MAX_LEN; n++) |
| 120 | { |
| 121 | for (int off = 0; off < 64; off += 7) |
| 122 | { |
| 123 | u8 *d = dst + 64 + off; |
| 124 | u8 *s = src + 64; |
| 125 | |
| 126 | for (int i = 0; i < 128 + n + off; i++) |
| 127 | dst[i] = 0xfe; |
| 128 | |
| 129 | wrapper (d, s, n); |
| 130 | |
| 131 | if ((err = validate_one (err, d, s, n, off, /* is_const */ 0))) |
| 132 | return err; |
| 133 | } |
| 134 | } |
| 135 | return err; |
| 136 | } |
| 137 | |
| 138 | REGISTER_TEST (clib_memcpy_x86_64) = { |
| 139 | .name = "clib_memcpy_x86_64", |
| 140 | .fn = test_clib_memcpy_x86_64, |
| 141 | }; |
| 142 | #endif |