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

« back to all changes in this revision

Viewing changes to tests/test-memmove.c

  • Committer: Matthew Gretton-Dann
  • Author(s): Marcus Shawcroft
  • Date: 2013-01-07 14:10:24 UTC
  • Revision ID: matthew.gretton-dann@linaro.org-20130107141024-572870j604t2h8p8
Add memmove tests from glibc.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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"