#define MAX_OFFSET 32 #define MAX_LENGTH 34 #define MAX_EXTRA 16 typedef __SIZE_TYPE__ size_t; extern void *memcpy (void *, const void *, size_t); extern void *memset (void *, int, size_t); extern void abort (void); char buf[MAX_OFFSET + MAX_LENGTH + MAX_EXTRA] __attribute__((aligned)); char buf2[MAX_LENGTH]; char buf3[MAX_LENGTH]; char buf4[MAX_LENGTH]; char A = 'A'; void check (int off, int len, int ch) { char *q; int i; q = buf; for (i = 0; i < off; i++, q++) if (*q != 'a') abort (); for (i = 0; i < len; i++, q++) if (*q != ch) abort (); for (i = 0; i < MAX_EXTRA; i++, q++) if (*q != 'a') abort (); } #define TEST0(off, val, len) \ p = memcpy (buf + (off), val, len); \ if (p != buf + (off)) abort (); \ check (off, len, val[0]) #define TEST1(off, len) \ TEST0 (off, buf3, len); \ TEST0 (off, buf4, len) #define TEST2(off, len) \ asm ("" : "=r" (voff) : "0" (off)); \ asm ("" : "=r" (vlen) : "0" (len)); \ TEST1 (off, len); \ TEST1 (voff, len); \ TEST1 (off, vlen); \ TEST1 (voff, vlen); \ TEST0 (off, buf2, len) #define TEST3(off, len) \ void test_##off##_##len (void) \ __attribute__((noinline)); \ void test_##off##_##len (void) \ { \ int vlen, voff; \ char *p; \ TEST2 (off, len); \ TEST2 (off, len | 1); \ TEST2 (off, len | 2); \ if (len < 32) \ { \ TEST2 (off, len | 3); \ TEST2 (off, len | 4); \ TEST2 (off, len | 5); \ TEST2 (off, len | 6); \ TEST2 (off, len | 7); \ } \ } #define TEST4(off) \ TEST3 (off, 0) \ TEST3 (off, 8) \ TEST3 (off, 16) \ TEST3 (off, 24) \ TEST3 (off, 32) #define TEST5(off) \ TEST4 (off##0) \ TEST4 (off##1) \ TEST4 (off##2) \ TEST4 (off##3) \ TEST4 (off##4) \ TEST4 (off##5) \ TEST4 (off##6) \ TEST4 (off##7) #define TEST6 \ TEST5 (00) \ TEST5 (01) \ TEST5 (02) \ TEST5 (03) \ TEST4 (040) TEST6 #undef TEST3 #define TEST3(off, len) test_##off##_##len (); int main () { memset (buf, 'a', sizeof buf); memset (buf2, 'a', sizeof buf2); memset (buf3, '\0', sizeof buf3); memset (buf4, 'A', sizeof buf4); TEST6 return 0; }