/* * Bestimmung einiger Maschinen-Parameter und -Abhängigkeiten * und Ausgabe in ein Include-File * Bruno Haible 10.9.1991, 12.10.1992, 6.12.1992, 24.10.1993 */ #define HAVE_LONGLONG 1 #define HAVE_ULONGLONG 1 /* Auf einigen Systemen werden in die Typen uchar, ushort, * uint, ulong definiert. Normalerweise reicht _POSIX_SOURCE aus, dies * zu verhindern, bei AIX 3.2.5 (rs6000-ibm-aix3.2.5) jedoch nicht. Wir * müssen Gewalt anwenden. */ #define _POSIX_SOURCE #define uchar os_uchar #define ushort os_ushort #define uint os_uint #define ulong os_ulong #include #undef ulong #undef uint #undef ushort #undef uchar #if !(defined(__STDC__) || defined(__cplusplus)) /* Only for use in function parameter lists and as function return type. */ #define void #endif /* Boolean type. */ /* Not a typedef because AIX already defines boolean_t. */ #define boolean_t int #define TRUE 1 #define FALSE 0 #ifdef __CHAR_UNSIGNED__ typedef signed char schar; #else typedef char schar; #endif typedef unsigned char uchar; typedef unsigned short ushort; typedef unsigned /* int */ uint; typedef unsigned long ulong; #ifdef HAVE_LONGLONG typedef long long longlong; #endif #ifdef HAVE_ULONGLONG typedef unsigned long long ulonglong; #endif typedef int (function)(); static int random_table[256] = /* 2048 zufällige Bits, hier von pi */ { 0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B, 0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74, 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79, 0x8E,0x34,0x04,0xDD,0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B, 0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D, 0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6, 0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6, 0xF4,0x06,0xB7,0xED,0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5, 0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51, 0xEC,0xE4,0x5B,0x3D,0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05, 0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8, 0xFD,0x24,0xCF,0x5F,0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96, 0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07, 0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04, 0xF1,0x74,0x6C,0x08,0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46, 0x2E,0x36,0xCE,0x3B,0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03, 0x9B,0x27,0x83,0xA2,0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0, 0x6F,0x4C,0x52,0xC9,0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18, 0x39,0x95,0x49,0x7C,0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18, 0x98,0xFA,0x05,0x10,0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D, 0xAD,0x33,0x17,0x0D,0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB, 0xDF,0x1C,0xBA,0x65, }; #define random_table_length (8*256) static int random_position = -1; int next_random_bit(void) { random_position++; if (random_position==random_table_length) random_position = 0; return (random_table[random_position/8] >> (random_position % 8)) & 1; } #if defined(__STDC__) || defined(__cplusplus) void printf_underscored (const char* string) #else void printf_underscored(string) char* string; #endif { char c; while ((c = *string++) != '\0') { printf("%c",(c==' ' ? '_' : c)); } } /* string_length(string) is the same as strlen(string). Better avoid depending on . */ #if defined(__STDC__) || defined(__cplusplus) int string_length (char* string) #else int string_length(string) char* string; #endif { int count = 0; while (*string++ != '\0') { count++; } return count; } static int char_bitsize, short_bitsize, int_bitsize, long_bitsize; static int uchar_bitsize, ushort_bitsize, uint_bitsize, ulong_bitsize; static boolean_t char_uchar_same, short_ushort_same, int_uint_same, long_ulong_same; static int pointer_bitsize; #ifdef HAVE_LONGLONG static int longlong_bitsize; #endif #ifdef HAVE_ULONGLONG static int ulonglong_bitsize; #endif #if defined HAVE_LONGLONG && defined HAVE_ULONGLONG static boolean_t longlong_ulonglong_same; #endif void main1(void) { #define get_integer_bitsize(type,where) \ { type x = 1; \ int bits = 0; \ while(1) { \ if (x==0) break; \ x = x+x; \ bits++; \ if (bits==1000) { bits = -1; break; } \ } \ where = bits; \ } #define print_integer_bitsize(type,typestr,where) \ { if (where >= 0) { \ printf("/* Integers of t%spe %s have %ld bits. */\n","y",typestr,(long)where); \ if (typestr[0] != 'u') \ { printf("#define "); printf_underscored(typestr); printf("_bitsize %ld\n",(long)where); } \ printf("\n"); \ } else \ printf("#error \"Integers of t%spe %s have no binary representation!!\"\n","y",typestr); \ if (where != char_bitsize * sizeof(type)) \ printf("#error \"Formula BITSIZE(T) = SIZEOF(T) * BITSPERBYTE does not hold for t%spe %s!!\"\n","y",typestr); \ } get_integer_bitsize(schar,char_bitsize); get_integer_bitsize(short,short_bitsize); get_integer_bitsize(int,int_bitsize); get_integer_bitsize(long,long_bitsize); print_integer_bitsize(schar,"char",char_bitsize); print_integer_bitsize(short,"short",short_bitsize); print_integer_bitsize(int,"int",int_bitsize); print_integer_bitsize(long,"long",long_bitsize); #ifdef HAVE_LONGLONG get_integer_bitsize(longlong,longlong_bitsize); print_integer_bitsize(longlong,"long long",longlong_bitsize); #endif get_integer_bitsize(uchar,uchar_bitsize); get_integer_bitsize(ushort,ushort_bitsize); get_integer_bitsize(uint,uint_bitsize); get_integer_bitsize(ulong,ulong_bitsize); print_integer_bitsize(uchar,"unsigned char",uchar_bitsize); print_integer_bitsize(ushort,"unsigned short",ushort_bitsize); print_integer_bitsize(uint,"unsigned int",uint_bitsize); print_integer_bitsize(ulong,"unsigned long",ulong_bitsize); #ifdef HAVE_ULONGLONG get_integer_bitsize(ulonglong,ulonglong_bitsize); print_integer_bitsize(ulonglong,"unsigned long long",ulonglong_bitsize); #endif } void main2(void) { #define compare_integer_bitsizes(typestr1,typestr2,type1_bitsize,type2_bitsize) \ { if (type1_bitsize!=type2_bitsize) \ printf("#error \"Integer types %s and %s have different sizes!!\"\n",typestr1,typestr2); \ } compare_integer_bitsizes("char","unsigned char",char_bitsize,uchar_bitsize); compare_integer_bitsizes("short","unsigned short",short_bitsize,ushort_bitsize); compare_integer_bitsizes("int","unsigned int",int_bitsize,uint_bitsize); compare_integer_bitsizes("long","unsigned long",long_bitsize,ulong_bitsize); #if defined HAVE_LONGLONG && defined HAVE_ULONGLONG compare_integer_bitsizes("long long","unsigned long long",longlong_bitsize,ulonglong_bitsize); #endif } #define get_a_random(type,bitsize,where) \ { type x = 0; \ int i = bitsize; \ while (i>0) { x = (x<<1) + next_random_bit(); i--; } \ where = x; \ } #define get_a_random_twice(type1,type2,bitsize,where1,where2) \ { type1 x1 = 0; type2 x2 = 0; \ int i = bitsize; \ while (i>0) { \ type1 b = next_random_bit(); \ x1 = ((x1<<1) + b); x2 = ((x2<<1) + b); \ i--; \ } \ where1 = x1; where2 = x2; \ } void main3(void) { #define compare_integer_representation(type1,type2,typestr1,typestr2,type1_bitsize,type2_bitsize,where) \ { if ((type1_bitsize>=0) && (type2_bitsize>=0) \ && (type1_bitsize==type2_bitsize)) { \ int i,j; \ type1 sample1; type2 sample2; \ where = TRUE; \ for (i = 0; i<100; i++) { \ get_a_random_twice(type1,type2,type1_bitsize,sample1,sample2); \ if (sample1 != (type1)(sample2)) { where = FALSE; } \ if (sample2 != (type2)(sample1)) { where = FALSE; } \ } \ for (i = 0; i<100; i++) { \ get_a_random(type1,type1_bitsize,sample1); \ sample2 = (type2)(sample1); \ for (j = 0; j < type1_bitsize; j++) \ if (((sample1 & ((type1)1<= 0) { \ int i,j,shc; \ type sample1,sample2; \ boolean_t left_works = TRUE, right_works = TRUE; \ for (i = 0; i<100; i++) { \ get_a_random(type,type_bitsize,sample1); \ for (shc = 0; shc < type_bitsize; shc++) { \ sample2 = sample1 << shc; \ for (j=0; j < type_bitsize; j++) { \ if (((sample2 & ((type)1<> shc; \ for (j=0; j < type_bitsize; j++) { \ if (((sample2 & ((type)1<= type_bitsize-shc ? TRUE : ((sample1 & ((type)1<<(j+shc))) == 0))) \ { right_works = FALSE; } \ } \ } \ } \ if (!left_works) \ printf("#error \"Left shift of integers of t%spe %s does not work!!\"\n","y",typestr); \ if (!right_works) \ printf("#error \"Right shift of integers of t%spe %s does not work!!\"\n","y",typestr); \ } #define test_integer_sshift(type,typestr,type_bitsize) \ if (type_bitsize >= 0) { \ int i,j,shc; \ type sample1,sample2; \ boolean_t left_works = TRUE, right_works = TRUE; \ for (i = 0; i<100; i++) { \ get_a_random(type,type_bitsize,sample1); \ for (shc = 0; shc < type_bitsize; shc++) { \ sample2 = sample1 << shc; \ for (j=0; j < type_bitsize; j++) { \ if (((sample2 & ((type)1<> shc; \ for (j=0; j < type_bitsize; j++) { \ if (((sample2 & ((type)1<=type_bitsize ? type_bitsize-1 : j+shc))) == 0)) \ { right_works = FALSE; } \ } \ } \ } \ if (!left_works) \ printf("#error \"Left shift of integers of t%spe %s does not work!!\"\n","y",typestr); \ if (!right_works) \ printf("#error \"Right shift of integers of t%spe %s does not work!!\"\n","y",typestr); \ } test_integer_ushift(uchar,"unsigned char",uchar_bitsize); test_integer_ushift(ushort,"unsigned short",ushort_bitsize); test_integer_ushift(uint,"unsigned int",uint_bitsize); test_integer_ushift(ulong,"unsigned long",ulong_bitsize); #ifdef HAVE_ULONGLONG test_integer_ushift(ulonglong,"unsigned long long",ulonglong_bitsize); #endif test_integer_sshift(schar,"char",char_bitsize); test_integer_sshift(short,"short",short_bitsize); test_integer_sshift(int,"int",int_bitsize); test_integer_sshift(long,"long",long_bitsize); #ifdef HAVE_LONGLONG test_integer_sshift(longlong,"long long",longlong_bitsize); #endif } void main5(void) { #define test_integer_casts(type1,type2,typestr1,typestr2,type1_bitsize,type2_bitsize,want) \ if (type1_bitsize <= type2_bitsize) { \ int i,j; \ boolean_t modifies = FALSE; \ boolean_t zero_extends = TRUE; \ boolean_t sign_extends = TRUE; \ for (i = 0; i<100; i++) { \ type1 sample1; \ type2 sample2; \ get_a_random(type1,type1_bitsize,sample1); \ sample2 = (type2)sample1; \ if (sample1 != (type1)sample2) { modifies = TRUE; } \ for (j = 0; j sizeof(long)) \ printf("#error \"Type %s does not fit into a long!!\"\n",typestr); \ } check_sizeof_pointer(char*,"char *"); check_sizeof_pointer(long*,"long *"); check_sizeof_pointer(function*,"function *"); pointer_bitsize = char_bitsize * sizeof(char*); printf("/* Pointers of t%spe %s have %ld bits. */\n","y","char *",(long)pointer_bitsize); printf("#define pointer_bitsize %ld\n",(long)pointer_bitsize); printf("\n"); } void main7(void) { #define test_pointer_casts(type1,type2,typestr1,typestr2) \ if (sizeof(type1) != sizeof(type2)) { \ printf("#error \"Pointer types %s and %s have different sizes!!\"\n",typestr1,typestr2); \ } else { \ int i; \ ulong differences1 = 0, differences2 = 0; \ for (i = 0; i<100; i++) { \ ulong sample; \ type1 sample1; \ type2 sample2; \ get_a_random(ulong,ulong_bitsize,sample); \ sample1 = (type1)sample; \ sample2 = (type2)sample; \ differences1 |= ((ulong)sample1 ^ (ulong)(type1)(sample2)); \ differences2 |= ((ulong)sample2 ^ (ulong)(type2)(sample1)); \ } \ if (differences1==0) \ printf("/* Casts from %s to %s is OK (does nothing). */\n",typestr2,typestr1); \ else \ if (differences1 == ~(ulong)0) \ printf("#error \"Casts from %s to %s work in an unknown way!!\"\n",typestr2,typestr1); \ else \ printf("#error \"Casts from %s to %s modify part 0x%8lX of pointer!!\"\n",typestr2,typestr1,differences1); \ if (differences2==0) \ printf("/* Casts from %s to %s is OK (does nothing). */\n",typestr1,typestr2); \ else \ if (differences2 == ~(ulong)0) \ printf("#error \"Casts from %s to %s work in an unknown way!!\"\n",typestr1,typestr2); \ else \ printf("#error \"Casts from %s to %s modify part 0x%8lX of pointer!!\"\n",typestr1,typestr2,differences2); \ } test_pointer_casts(char*,long*,"char *","long *"); test_pointer_casts(char*,function*,"char *","function *"); printf("\n"); } void main8(void) { /* The following macro works only in C, not in C++, because C++ restricts the use of NULL pointers and also because C++ forbids defining types within a cast. */ #define alignmentof(type) \ (int)(&((struct { char dummy1; type dummy2; } *)0)->dummy2) #define get_alignment(type,typestr) \ { struct { char dummy1; type dummy2; } dummy; \ long alignment = (char*)&dummy.dummy2 - (char*)&dummy; \ printf("/* Type %s has sizeof = %ld and alignment = %ld. */\n",typestr,(long)sizeof(type),alignment); \ if (typestr[0] != 'u' && (typestr[string_length(typestr)-1] != '*')) { \ printf("#define sizeof_"); printf_underscored(typestr); \ printf(" %ld\n",(long)sizeof(type)); \ printf("#define alignment_"); printf_underscored(typestr); \ printf(" %ld\n",alignment); \ } \ if ((alignment & (alignment-1)) != 0) \ printf("#error \"The alignment %ld of t%spe %s is not a power of two!!\"\n",alignment,"y",typestr); \ printf("\n"); \ } get_alignment(char,"char"); get_alignment(uchar,"unsigned char"); get_alignment(short,"short"); get_alignment(ushort,"unsigned short"); get_alignment(int,"int"); get_alignment(uint,"unsigned int"); get_alignment(long,"long"); get_alignment(ulong,"unsigned long"); #ifdef HAVE_LONGLONG get_alignment(longlong,"long long"); #endif #ifdef HAVE_ULONGLONG get_alignment(ulonglong,"unsigned long long"); #endif get_alignment(float,"float"); get_alignment(double,"double"); get_alignment(char*,"char *"); get_alignment(long*,"long *"); get_alignment(function*,"function *"); } void main9(void) { #define get_endian(type,typestr,type_bitsize) \ { if (type_bitsize == uchar_bitsize * sizeof(type)) { \ auto union { uchar einzeln[sizeof(type)]; type gesamt; } x; \ int i,j; \ boolean_t big_endian = TRUE; \ boolean_t little_endian = TRUE; \ for (i = 0; i<100; i++) { \ type sample; \ get_a_random(type,type_bitsize,sample); \ x.gesamt = sample; \ for (j = 0; j>= uchar_bitsize) { \ if ((sample & (((type)1< 0) { printf("/* Stack grows up, ca. %ld bytes per function call. */\n",(long)stack_direction); printf("#define stack_grows_up\n"); } else if (stack_direction < 0) { printf("/* Stack grows down, ca. %ld bytes per function call. */\n",-(long)stack_direction); printf("#define stack_grows_down\n"); } else printf("#error \"Unknown stack model -- incorrect C semantics!!\"\n"); } int main() { main1(); main2(); main3(); main4(); main5(); main6(); main7(); main8(); main9(); main10(); if (ferror(stdout) || fclose(stdout)) return 1; return 0; }