~linaro-toolchain-dev/cortex-strings/trunk

91 by Marcus Shawcroft
Add memmove tests from glibc.
1
/* Test and measure memmove functions.
2
   Copyright (C) 1999-2012 Free Software Foundation, Inc.
3
   This file is part of the GNU C Library.
4
   Written by Jakub Jelinek <jakub@redhat.com>, 1999.
5
6
   The GNU C Library is free software; you can redistribute it and/or
7
   modify it under the terms of the GNU Lesser General Public
8
   License as published by the Free Software Foundation; either
9
   version 2.1 of the License, or (at your option) any later version.
10
11
   The GNU C Library 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 GNU
14
   Lesser General Public License for more details.
15
16
   You should have received a copy of the GNU Lesser General Public
17
   License along with the GNU C Library; if not, see
18
   <http://www.gnu.org/licenses/>.  */
19
20
#define TEST_MAIN
21
#ifdef TEST_BCOPY
22
# define TEST_NAME "bcopy"
23
#else
24
# define TEST_NAME "memmove"
25
#endif
26
#include "test-string.h"
27
28
char *simple_memmove (char *, const char *, size_t);
29
30
#ifdef TEST_BCOPY
31
typedef void (*proto_t) (const char *, char *, size_t);
32
void simple_bcopy (const char *, char *, size_t);
33
34
IMPL (simple_bcopy, 0)
35
IMPL (bcopy, 1)
36
37
void
38
simple_bcopy (const char *src, char *dst, size_t n)
39
{
40
  simple_memmove (dst, src, n);
41
}
42
#else
43
typedef char *(*proto_t) (char *, const char *, size_t);
44
45
IMPL (simple_memmove, 0)
46
IMPL (memmove, 1)
47
#endif
48
49
char *
50
simple_memmove (char *dst, const char *src, size_t n)
51
{
52
  char *ret = dst;
53
  if (src < dst)
54
    {
55
      dst += n;
56
      src += n;
57
      while (n--)
58
	*--dst = *--src;
59
    }
60
  else
61
    while (n--)
62
      *dst++ = *src++;
63
  return ret;
64
}
65
66
static void
67
do_one_test (impl_t *impl, char *dst, char *src, const char *orig_src,
68
	     size_t len)
69
{
70
  memcpy (src, orig_src, len);
71
#ifdef TEST_BCOPY
72
  CALL (impl, src, dst, len);
73
#else
74
  char *res;
75
76
  res = CALL (impl, dst, src, len);
77
  if (res != dst)
78
    {
79
      error (0, 0, "Wrong result in function %s %p %p", impl->name,
80
	     res, dst);
81
      ret = 1;
82
      return;
83
    }
84
#endif
85
86
  if (memcmp (dst, orig_src, len) != 0)
87
    {
88
      error (0, 0, "Wrong result in function %s dst \"%s\" src \"%s\"",
89
	     impl->name, dst, src);
90
      ret = 1;
91
      return;
92
    }
93
94
  if (HP_TIMING_AVAIL)
95
    {
96
      hp_timing_t start __attribute ((unused));
97
      hp_timing_t stop __attribute ((unused));
98
      hp_timing_t best_time = ~ (hp_timing_t) 0;
99
      size_t i;
100
101
      for (i = 0; i < 32; ++i)
102
	{
103
	  HP_TIMING_NOW (start);
104
#ifdef TEST_BCOPY
105
	  CALL (impl, src, dst, len);
106
#else
107
	  CALL (impl, dst, src, len);
108
#endif
109
	  HP_TIMING_NOW (stop);
110
	  HP_TIMING_BEST (best_time, start, stop);
111
	}
112
113
      printf ("\t%zd", (size_t) best_time);
114
    }
115
}
116
117
static void
118
do_test (size_t align1, size_t align2, size_t len)
119
{
120
  size_t i, j;
121
  char *s1, *s2;
122
123
  align1 &= 63;
124
  if (align1 + len >= page_size)
125
    return;
126
127
  align2 &= 63;
128
  if (align2 + len >= page_size)
129
    return;
130
131
  s1 = (char *) (buf1 + align1);
132
  s2 = (char *) (buf2 + align2);
133
134
  for (i = 0, j = 1; i < len; i++, j += 23)
135
    s1[i] = j;
136
137
  if (HP_TIMING_AVAIL)
138
    printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2);
139
140
  FOR_EACH_IMPL (impl, 0)
141
    do_one_test (impl, s2, (char *) (buf2 + align1), s1, len);
142
143
  if (HP_TIMING_AVAIL)
144
    putchar ('\n');
145
}
146
147
static void
148
do_random_tests (void)
149
{
150
  size_t i, n, align1, align2, len, size;
151
  size_t srcstart, srcend, dststart, dstend;
152
  int c;
153
  unsigned char *p1, *p2;
154
#ifndef TEST_BCOPY
155
  unsigned char *res;
156
#endif
157
158
  for (n = 0; n < ITERATIONS; n++)
159
    {
160
      if ((random () & 255) == 0)
161
	size = 65536;
162
      else
163
	size = 512;
164
      if (size > page_size)
165
	size = page_size;
166
      if ((random () & 3) == 0)
167
	{
168
	  len = random () & (size - 1);
169
	  align1 = size - len - (random () & 31);
170
	  align2 = size - len - (random () & 31);
171
	  if (align1 > size)
172
	    align1 = 0;
173
	  if (align2 > size)
174
	    align2 = 0;
175
	}
176
      else
177
	{
178
	  align1 = random () & (size / 2 - 1);
179
	  align2 = random () & (size / 2 - 1);
180
	  len = random () & (size - 1);
181
	  if (align1 + len > size)
182
	    align1 = size - len;
183
	  if (align2 + len > size)
184
	    align2 = size - len;
185
	}
186
187
      p1 = buf1 + page_size - size;
188
      p2 = buf2 + page_size - size;
189
      c = random () & 255;
190
      srcend = align1 + len + 256;
191
      if (srcend > size)
192
	srcend = size;
193
      if (align1 > 256)
194
	srcstart = align1 - 256;
195
      else
196
	srcstart = 0;
197
      for (i = srcstart; i < srcend; ++i)
198
	p1[i] = random () & 255;
199
      dstend = align2 + len + 256;
200
      if (dstend > size)
201
	dstend = size;
202
      if (align2 > 256)
203
	dststart = align2 - 256;
204
      else
205
	dststart = 0;
206
207
      FOR_EACH_IMPL (impl, 1)
208
	{
209
	  memset (p2 + dststart, c, dstend - dststart);
210
	  memcpy (p2 + srcstart, p1 + srcstart, srcend - srcstart);
211
#ifdef TEST_BCOPY
212
	  CALL (impl, (char *) (p2 + align1), (char *) (p2 + align2), len);
213
#else
214
	  res = (unsigned char *) CALL (impl,
215
					(char *) (p2 + align2),
216
					(char *) (p2 + align1), len);
217
	  if (res != p2 + align2)
218
	    {
219
	      error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %zd, %zd) %p != %p",
220
		     n, impl->name, align1, align2, len, res, p2 + align2);
221
	      ret = 1;
222
	    }
223
#endif
224
	  if (memcmp (p1 + align1, p2 + align2, len))
225
	    {
226
	      error (0, 0, "Iteration %zd - different strings, %s (%zd, %zd, %zd)",
227
		     n, impl->name, align1, align2, len);
228
	      ret = 1;
229
	    }
230
	  for (i = dststart; i < dstend; ++i)
231
	    {
232
	      if (i >= align2 && i < align2 + len)
233
		{
234
		  i = align2 + len - 1;
235
		  continue;
236
		}
237
	      if (i >= srcstart && i < srcend)
238
		{
239
		  i = srcend - 1;
240
		  continue;
241
		}
242
	      if (p2[i] != c)
243
		{
244
		  error (0, 0, "Iteration %zd - garbage in memset area, %s (%zd, %zd, %zd)",
245
			 n, impl->name, align1, align2, len);
246
		  ret = 1;
247
		  break;
248
		}
249
	    }
250
251
	  if (srcstart < align2
252
	      && memcmp (p2 + srcstart, p1 + srcstart,
253
			 (srcend > align2 ? align2 : srcend) - srcstart))
254
	    {
255
	      error (0, 0, "Iteration %zd - garbage before dst, %s (%zd, %zd, %zd)",
256
		     n, impl->name, align1, align2, len);
257
	      ret = 1;
258
	      break;
259
	    }
260
261
	  i = srcstart > align2 + len ? srcstart : align2 + len;
262
	  if (srcend > align2 + len
263
	      && memcmp (p2 + i, p1 + i, srcend - i))
264
	    {
265
	      error (0, 0, "Iteration %zd - garbage after dst, %s (%zd, %zd, %zd)",
266
		     n, impl->name, align1, align2, len);
267
	      ret = 1;
268
	      break;
269
	    }
270
	}
271
    }
272
}
273
274
int
275
test_main (void)
276
{
277
  size_t i;
278
279
  test_init ();
280
281
  printf ("%23s", "");
282
  FOR_EACH_IMPL (impl, 0)
283
    printf ("\t%s", impl->name);
284
  putchar ('\n');
285
286
  for (i = 0; i < 14; ++i)
287
    {
288
      do_test (0, 32, 1 << i);
289
      do_test (32, 0, 1 << i);
290
      do_test (0, i, 1 << i);
291
      do_test (i, 0, 1 << i);
292
    }
293
294
  for (i = 0; i < 32; ++i)
295
    {
296
      do_test (0, 32, i);
297
      do_test (32, 0, i);
298
      do_test (0, i, i);
299
      do_test (i, 0, i);
300
    }
301
302
  for (i = 3; i < 32; ++i)
303
    {
304
      if ((i & (i - 1)) == 0)
305
	continue;
306
      do_test (0, 32, 16 * i);
307
      do_test (32, 0, 16 * i);
308
      do_test (0, i, 16 * i);
309
      do_test (i, 0, 16 * i);
310
    }
311
312
  do_random_tests ();
313
  return ret;
314
}
315
316
#include "test-skeleton.c"