1ff62002b4cf8103675514bf848f3f38bf26ba7ecsewardj#include "tests/malloc.h" 2da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj#include <stdio.h> 3da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj#include <assert.h> 4da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj 5da04f3ec707985d9c6cc963c1bbe06ee6131308esewardjtypedef unsigned long long int ULong; 6da04f3ec707985d9c6cc963c1bbe06ee6131308esewardjtypedef unsigned long int UWord; 7da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj 8da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj__attribute__((noinline)) 9da04f3ec707985d9c6cc963c1bbe06ee6131308esewardjstatic int my_ffsll ( ULong x ) 10da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj{ 11da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj int i; 12da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj for (i = 0; i < 64; i++) { 13da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj if ((x & 1ULL) == 1ULL) 14da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj break; 15da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj x >>= 1; 16da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj } 17da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj return i+1; 18da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj} 19da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj 20da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj/* Find length of string, assuming it is aligned and shorter than 8 21da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj characters. Little-endian only. */ 22da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj__attribute__((noinline)) 23da04f3ec707985d9c6cc963c1bbe06ee6131308esewardjstatic int aligned_strlen(char *s) 24da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj{ 25da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj /* This is for 64-bit platforms */ 26da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj assert(sizeof(ULong) == 8); 27da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj /* ..and only works for aligned input */ 28da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj assert(((unsigned long)s & 0x7) == 0); 29da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj 30da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj /* read 8 bytes */ 31da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj ULong val = *(ULong*)s; 32da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj /* Subtract one from each byte */ 33da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj ULong val2 = val - 0x0101010101010101ULL; 34da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj /* Find lowest byte whose high bit changed */ 35da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj val2 ^= val; 36da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj val2 &= 0x8080808080808080ULL; 37da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj 38da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj return (my_ffsll(val2) / 8) - 1; 39da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj} 40da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj 41da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj__attribute__((noinline)) void foo ( int x ) 42da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj{ 43da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj __asm__ __volatile__("":::"memory"); 44da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj} 45da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj 46da04f3ec707985d9c6cc963c1bbe06ee6131308esewardjint 47da04f3ec707985d9c6cc963c1bbe06ee6131308esewardjmain(int argc, char *argv[]) 48da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj{ 49ff62002b4cf8103675514bf848f3f38bf26ba7ecsewardj char *buf = memalign16(5); 50da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj buf[0] = 'a'; 51da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj buf[1] = 'b'; 52da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj buf[2] = 'c'; 53da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj buf[3] = 'd'; 54da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj buf[4] = '\0'; 55da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj 56da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj /* --partial-loads-ok=no: expect addr error (here) */ 57da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj /* --partial-loads-ok=yes: expect no error */ 58da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj if (aligned_strlen(buf) == 4) 59da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj foo(44); 60da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj 61da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj /* --partial-loads-ok=no: expect addr error (here) */ 62da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj /* --partial-loads-ok=yes: expect value error (in my_ffsll) */ 63da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj buf[4] = 'x'; 64da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj if (aligned_strlen(buf) == 0) 65da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj foo(37); 66da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj 67da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj free(buf); 68da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj 69da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj /* Also, we need to check that a completely out-of-range, 70da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj word-sized load gives an addressing error regardless of the 71da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj start of --partial-loads-ok=. *And* that the resulting 72da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj value is completely defined. */ 73da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj UWord* words = malloc(3 * sizeof(UWord)); 74da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj free(words); 75da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj 76da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj /* Should ALWAYS give an addr error. */ 77da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj UWord w = words[1]; 78da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj 79da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj /* Should NEVER give an error (you might expect a value one, but no.) */ 80da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj if (w == 0x31415927) { 81da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj fprintf(stderr, 82da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj "Elvis is alive and well and living in Milton Keynes.\n"); 83da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj } 84da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj 85da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj return 0; 86da04f3ec707985d9c6cc963c1bbe06ee6131308esewardj} 87