183b62cbbab29bde83eba40231f307c2a311e73c8njn#include "tests/asm.h"
2b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj#include <stdio.h>
3b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj#include <stdlib.h>
4b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj#include <string.h>
5b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj#include <assert.h>
6b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj
7b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj/* These fns taken from dietlibc-0.30 (is GPL v2'd) */
8b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj
9b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj/*
10b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  Copyright (C) 2002 Thomas M. Ogrisegg
11b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj
12b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  This is free software. You can redistribute and
13b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  modify it under the terms of the GNU General Public
14b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  Public License.
15b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj
16b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  strncpy.S
17b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj    i386 assembler implementation of strncpy(3)
18b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj*/
19b95cd589e448ef0bc22f26f2d31a0522df899c23sewardjextern char *mystrncpy(char *dest, const char *src, size_t n);
20b95cd589e448ef0bc22f26f2d31a0522df899c23sewardjasm(
21b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj".text\n"
22b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"\n"
2383b62cbbab29bde83eba40231f307c2a311e73c8njnVG_SYM(mystrncpy) ":\n"
24b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"	pushl %esi\n"
25b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"	pushl %edi\n"
26b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"	movl %esp, %ecx\n"
27b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"	movl  0x0c(%ecx), %edi\n"
28b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"	movl  0x10(%ecx), %esi\n"
29b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"	movl  0x14(%ecx), %ecx\n"
30b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"\n"
31b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"	movl %edi, %edx\n"
32b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"	cld\n"
3383b62cbbab29bde83eba40231f307c2a311e73c8njn"0:\n"
34b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"	dec %ecx\n"
3583b62cbbab29bde83eba40231f307c2a311e73c8njn"	js 1f\n"
36b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"	lodsb\n"
37b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"	stosb\n"
38b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"	or %al, %al\n"
3983b62cbbab29bde83eba40231f307c2a311e73c8njn"	jnz 0b\n"
40b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"	repnz stosb\n"
4183b62cbbab29bde83eba40231f307c2a311e73c8njn"1:\n"
42b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"	movl %edx, %eax\n"
43b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"	popl %edi\n"
44b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"	popl %esi\n"
45b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"	ret\n"
46b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"\n"
47b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj);
48b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj
49b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj
50b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj/*
51b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj   Copyright (C) 2002 Thomas M. Ogrisegg
52b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj
53b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj   __ltostr.S -- convert an integer into a string
54b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj
55b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj %eax = dividend
56b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj %ebx = divisor
57b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj %ecx = size of output-buffer
58b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj %edi = output-buffer
59b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj %ebp = if uppercase is set, then %ebp is 'A'-10 else %ebp is 'a'-10
60b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj
61b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj*/
62b95cd589e448ef0bc22f26f2d31a0522df899c23sewardjextern int __ltostr(char *s, unsigned int size, unsigned long i,
63b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj                             unsigned int base, int UpCase);
64b95cd589e448ef0bc22f26f2d31a0522df899c23sewardjasm(
65b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj".text\n"
6683b62cbbab29bde83eba40231f307c2a311e73c8njnVG_SYM(__ltostr) ":\n"
67b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        pushl %esi\n"
68b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        pushl %edi              # destination\n"
69b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        pushl %ebp\n"
70b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        pushl %ebx\n"
71b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        movl %esp, %eax\n"
72b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        movl 0x14(%eax), %edi\n"
73b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        movl 0x18(%eax), %ecx   # size\n"
74b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        movl 0x20(%eax), %ebx   # divisor\n"
75b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        movl 0x1c(%eax), %eax   # dividend\n"
76b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        decl %ecx\n"
77b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        movl %ecx, %esi\n"
7883b62cbbab29bde83eba40231f307c2a311e73c8njn"        movl $55, %ebp          # 55 == char(A)-10\n"
79b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        xorl %edx, %edx         # must be 0 -- used by idiv\n"
80b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        cmpl $0x0, 36(%esp)     # check for uppercase\n"
8183b62cbbab29bde83eba40231f307c2a311e73c8njn"        jnz 0f\n"
82b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        addl $0x20, %ebp        # set lowercase\n"
8383b62cbbab29bde83eba40231f307c2a311e73c8njn"0:\n"
84b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        idiv %ebx, %eax\n"
85b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        cmpb $0x9, %dl\n"
8683b62cbbab29bde83eba40231f307c2a311e73c8njn"        jg 1f\n"
8783b62cbbab29bde83eba40231f307c2a311e73c8njn"        addb $48, %dl           # 48 == '0'\n"
8883b62cbbab29bde83eba40231f307c2a311e73c8njn"        jmp 2f\n"
8983b62cbbab29bde83eba40231f307c2a311e73c8njn"1:\n"
90b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        addl %ebp, %edx\n"
9183b62cbbab29bde83eba40231f307c2a311e73c8njn"2:\n"
92b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        movb %dl, (%edi, %ecx)\n"
93b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        xorl %edx, %edx\n"
94b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        decl %ecx\n"
9583b62cbbab29bde83eba40231f307c2a311e73c8njn"        jz 3f\n"
96b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        orl %eax, %eax\n"
9783b62cbbab29bde83eba40231f307c2a311e73c8njn"        jnz 0b\n"
9883b62cbbab29bde83eba40231f307c2a311e73c8njn"3:\n"
99b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        cld\n"
100b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        movl %esi, %ebx\n"
101b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        leal 1(%edi, %ecx), %esi\n"
102b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        subl %ebx, %ecx\n"
103b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        negl %ecx\n"
104b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        movl %ecx, %eax\n"
105b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        repnz movsb\n"
106b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        movb $0x0, (%edi)\n"
107b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        popl %ebx\n"
108b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        popl %ebp\n"
109b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        popl %edi\n"
110b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        popl %esi\n"
111b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj"        ret\n"
112b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj);
113b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj
114b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj#define STREQ(a, b)     (strcmp((a), (b)) == 0)
115b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj
116b95cd589e448ef0bc22f26f2d31a0522df899c23sewardjconst char *it = "<UNSET>";     /* Routine name for message routines. */
117b95cd589e448ef0bc22f26f2d31a0522df899c23sewardjsize_t errors = 0;
118b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj
119b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj/* Complain if condition is not true.  */
120b95cd589e448ef0bc22f26f2d31a0522df899c23sewardjstatic void
121b95cd589e448ef0bc22f26f2d31a0522df899c23sewardjcheck (int thing, int number)
122b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj{
123b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  if (!thing)
124b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj    {
125b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj      printf("%s flunked test %d\n", it, number);
126b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj      ++errors;
127b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj    }
128b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj}
129b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj
130b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj/* Complain if first two args don't strcmp as equal.  */
131b95cd589e448ef0bc22f26f2d31a0522df899c23sewardjstatic void
132b95cd589e448ef0bc22f26f2d31a0522df899c23sewardjequal (const char *a, const char *b, int number)
133b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj{
134b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  check(a != NULL && b != NULL && STREQ (a, b), number);
135b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj}
136b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj
137b95cd589e448ef0bc22f26f2d31a0522df899c23sewardjchar one[50];
138b95cd589e448ef0bc22f26f2d31a0522df899c23sewardjchar two[50];
139b95cd589e448ef0bc22f26f2d31a0522df899c23sewardjchar *cp;
140b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj
141b95cd589e448ef0bc22f26f2d31a0522df899c23sewardjstatic void
142b95cd589e448ef0bc22f26f2d31a0522df899c23sewardjtest_strncpy (void)
143b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj{
144b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  /* Testing is a bit different because of odd semantics.  */
145b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  it = "strncpy";
146b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  check (mystrncpy (one, "abc", 4) == one, 1);    /* Returned value. */
147b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  equal (one, "abc", 2);                        /* Did the copy go right? */
148b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj
149b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  (void) strcpy (one, "abcdefgh");
150b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  (void) mystrncpy (one, "xyz", 2);
151b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  equal (one, "xycdefgh", 3);                   /* Copy cut by count. */
152b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj
153b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  (void) strcpy (one, "abcdefgh");
154b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  (void) mystrncpy (one, "xyz", 3);               /* Copy cut just before NUL. */
155b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  equal (one, "xyzdefgh", 4);
156b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj
157b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  (void) strcpy (one, "abcdefgh");
158b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  (void) mystrncpy (one, "xyz", 4);               /* Copy just includes NUL. */
159b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  equal (one, "xyz", 5);
160b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  equal (one+4, "efgh", 6);                     /* Wrote too much? */
161b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj
162b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  (void) strcpy (one, "abcdefgh");
163b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  (void) mystrncpy (one, "xyz", 5);               /* Copy includes padding. */
164b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  equal (one, "xyz", 7);
165b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  equal (one+4, "", 8);
166b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  equal (one+5, "fgh", 9);
167b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj
168b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  (void) strcpy (one, "abc");
169b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  (void) mystrncpy (one, "xyz", 0);               /* Zero-length copy. */
170b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  equal (one, "abc", 10);
171b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj
172b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  (void) mystrncpy (one, "", 2);          /* Zero-length source. */
173b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  equal (one, "", 11);
174b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  equal (one+1, "", 12);
175b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  equal (one+2, "c", 13);
176b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj
177b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  (void) strcpy (one, "hi there");
178b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  (void) mystrncpy (two, one, 9);
179b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  equal (two, "hi there", 14);          /* Just paranoia. */
180b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  equal (one, "hi there", 15);          /* Stomped on source? */
181b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj}
182b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj
183b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj
184b95cd589e448ef0bc22f26f2d31a0522df899c23sewardjint main ( void )
185b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj{
186b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  char buf[1024];
187b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj
188b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  /* test strncpy, hence repnz stosb */
189b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  test_strncpy();
190b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj    if (errors == 0)
191b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj    {
192b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj      printf("No errors.\n");
193b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj    }
194b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  else
195b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj    {
196b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj      printf("%d errors.\n", (int)errors);
197b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj    }
198b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj
199b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj    /* test __ltostr, hence repnz stosb */
200b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  assert(__ltostr(buf,10,1723,10,0)==4); assert(!strcmp(buf,"1723"));
201b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  assert(__ltostr(buf,3,1723,10,0)==2); assert(!strcmp(buf,"23"));
202b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  assert(__ltostr(buf,2,0x1234,16,0)==1); assert(!strcmp(buf,"4"));
203b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj  assert(__ltostr(buf,3,0xFEFE,16,1)==2); assert(!strcmp(buf,"FE"));
204b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj
205b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj return 0;
206b95cd589e448ef0bc22f26f2d31a0522df899c23sewardj}
207