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