You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

583 lines
37 KiB

25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
  1. /* Bestimmung einiger Maschinen-Parameter und -Abhängigkeiten */
  2. /* und Ausgabe in ein Include-File */
  3. /* Bruno Haible 10.9.1991, 12.10.1992, 6.12.1992, 24.10.1993 */
  4. /* Auf einigen Systemen werden in <sys/types.h> die Typen uchar, ushort, uint, */
  5. /* ulong definiert. Normalerweise reicht _POSIX_SOURCE aus, dies zu verhindern, */
  6. /* bei AIX 3.2.5 (rs6000-ibm-aix3.2.5) jedoch nicht. Wir müssen Gewalt anwenden. */
  7. #define _POSIX_SOURCE
  8. #define uchar os_uchar
  9. #define ushort os_ushort
  10. #define uint os_uint
  11. #define ulong os_ulong
  12. #include <stdio.h>
  13. #undef ulong
  14. #undef uint
  15. #undef ushort
  16. #undef uchar
  17. #define loop while(1)
  18. typedef int boolean;
  19. #define TRUE 1
  20. #define FALSE 0
  21. #ifdef __CHAR_UNSIGNED__
  22. typedef signed char schar;
  23. #else
  24. typedef char schar;
  25. #endif
  26. typedef unsigned char uchar;
  27. typedef unsigned short ushort;
  28. typedef unsigned /* int */ uint;
  29. typedef unsigned long ulong;
  30. #ifdef HAVE_LONGLONG
  31. typedef long long longlong;
  32. typedef unsigned long long ulonglong;
  33. #endif
  34. typedef int (function)();
  35. static int random_table[256] = /* 2048 zufällige Bits, hier von pi */
  36. { 0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,
  37. 0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
  38. 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,
  39. 0x8E,0x34,0x04,0xDD,0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,
  40. 0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,
  41. 0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
  42. 0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,
  43. 0xF4,0x06,0xB7,0xED,0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,
  44. 0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,
  45. 0xEC,0xE4,0x5B,0x3D,0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,
  46. 0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,
  47. 0xFD,0x24,0xCF,0x5F,0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,
  48. 0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,
  49. 0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
  50. 0xF1,0x74,0x6C,0x08,0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,
  51. 0x2E,0x36,0xCE,0x3B,0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,
  52. 0x9B,0x27,0x83,0xA2,0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,
  53. 0x6F,0x4C,0x52,0xC9,0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,
  54. 0x39,0x95,0x49,0x7C,0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,
  55. 0x98,0xFA,0x05,0x10,0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,
  56. 0xAD,0x33,0x17,0x0D,0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,
  57. 0xDF,0x1C,0xBA,0x65,
  58. };
  59. #define random_table_length (8*256)
  60. static int random_position = -1;
  61. int next_random_bit(void)
  62. { random_position++;
  63. if (random_position==random_table_length) random_position = 0;
  64. return (random_table[random_position/8] >> (random_position % 8)) & 1;
  65. }
  66. void printf_underscored (const char* string)
  67. { char c;
  68. while (!((c = *string++) == '\0')) { printf("%c",(c==' ' ? '_' : c)); }
  69. }
  70. /* string_length(string) is the same as strlen(string). */
  71. /* Better avoid to depend on <string.h>. */
  72. int string_length (char* string)
  73. { int count = 0;
  74. while (!(*string++ == '\0')) { count++; }
  75. return count;
  76. }
  77. static int char_bitsize, short_bitsize, int_bitsize, long_bitsize;
  78. static int uchar_bitsize, ushort_bitsize, uint_bitsize, ulong_bitsize;
  79. static boolean char_uchar_same, short_ushort_same, int_uint_same, long_ulong_same;
  80. static int pointer_bitsize;
  81. #ifdef HAVE_LONGLONG
  82. static int longlong_bitsize, ulonglong_bitsize;
  83. static boolean longlong_ulonglong_same;
  84. #endif
  85. void main1(void) {
  86. #define get_unsigned_integer_bitsize(type,where) \
  87. { type x = 1; \
  88. int bits = 0; \
  89. loop { \
  90. if (x==0) break; \
  91. x = x+x; \
  92. bits++; \
  93. if (bits==1000) { bits = -1; break; } \
  94. } \
  95. where = bits; \
  96. }
  97. #define get_signed_integer_bitsize(type,unsigned_type,where) \
  98. { /* Signed integer overflow is "undefined behaviour" in C99, and gcc-4.3 \
  99. (without -fwrapv option) actually does weird things when signed integer \
  100. overflow occurs. Therefore perform the addition on the unsigned type. \
  101. Drawback: This will not detect cases where the signed type has more bits\
  102. than the unsigned type but the same size according to sizeof. Blech. */ \
  103. type x = 1; \
  104. int bits = 0; \
  105. loop { \
  106. if (x==0) break; \
  107. x = (unsigned_type)x + (unsigned_type)x;\
  108. bits++; \
  109. if (bits==1000) { bits = -1; break; } \
  110. } \
  111. where = bits; \
  112. }
  113. #define print_integer_bitsize(type,typestr,where) \
  114. { if (where >= 0) \
  115. { printf("/* Integers of type %s have %ld bits. */\n",typestr,(long)where); \
  116. if (!(typestr[0] == 'u')) \
  117. { printf("#define "); printf_underscored(typestr); printf("_bitsize %ld\n",(long)where); } \
  118. printf("\n"); \
  119. } \
  120. else \
  121. { printf("#error \"Integers of type %s have no binary representation!!\"\n",typestr); } \
  122. if (!(where == char_bitsize * sizeof(type))) \
  123. { printf("#error \"Formula BITSIZE(T) = SIZEOF(T) * BITSPERBYTE does not hold for type %s!!\"\n",typestr); } \
  124. }
  125. get_signed_integer_bitsize(schar,uchar,char_bitsize);
  126. get_signed_integer_bitsize(short,ushort,short_bitsize);
  127. get_signed_integer_bitsize(int,uint,int_bitsize);
  128. get_signed_integer_bitsize(long,ulong,long_bitsize);
  129. print_integer_bitsize(schar,"char",char_bitsize);
  130. print_integer_bitsize(short,"short",short_bitsize);
  131. print_integer_bitsize(int,"int",int_bitsize);
  132. print_integer_bitsize(long,"long",long_bitsize);
  133. #ifdef HAVE_LONGLONG
  134. get_signed_integer_bitsize(longlong,ulonglong,longlong_bitsize);
  135. print_integer_bitsize(longlong,"long long",longlong_bitsize);
  136. #endif
  137. get_unsigned_integer_bitsize(uchar,uchar_bitsize);
  138. get_unsigned_integer_bitsize(ushort,ushort_bitsize);
  139. get_unsigned_integer_bitsize(uint,uint_bitsize);
  140. get_unsigned_integer_bitsize(ulong,ulong_bitsize);
  141. print_integer_bitsize(uchar,"unsigned char",uchar_bitsize);
  142. print_integer_bitsize(ushort,"unsigned short",ushort_bitsize);
  143. print_integer_bitsize(uint,"unsigned int",uint_bitsize);
  144. print_integer_bitsize(ulong,"unsigned long",ulong_bitsize);
  145. #ifdef HAVE_LONGLONG
  146. get_unsigned_integer_bitsize(ulonglong,ulonglong_bitsize);
  147. print_integer_bitsize(ulonglong,"unsigned long long",ulonglong_bitsize);
  148. #endif
  149. }
  150. void main2(void) {
  151. #define compare_integer_bitsizes(typestr1,typestr2,type1_bitsize,type2_bitsize) \
  152. { if (!(type1_bitsize==type2_bitsize)) \
  153. printf("#error \"Integer types %s and %s have different sizes!!\"\n",typestr1,typestr2); \
  154. }
  155. compare_integer_bitsizes("char","unsigned char",char_bitsize,uchar_bitsize);
  156. compare_integer_bitsizes("short","unsigned short",short_bitsize,ushort_bitsize);
  157. compare_integer_bitsizes("int","unsigned int",int_bitsize,uint_bitsize);
  158. compare_integer_bitsizes("long","unsigned long",long_bitsize,ulong_bitsize);
  159. #ifdef HAVE_LONGLONG
  160. compare_integer_bitsizes("long long","unsigned long long",longlong_bitsize,ulonglong_bitsize);
  161. #endif
  162. }
  163. #define get_a_random(type,bitsize,where) \
  164. { type x = 0; \
  165. int i = bitsize; \
  166. while (i>0) { x = (x<<1) + next_random_bit(); i--; } \
  167. where = x; \
  168. }
  169. #define get_a_random_twice(type1,type2,bitsize,where1,where2) \
  170. { type1 x1 = 0; type2 x2 = 0; \
  171. int i = bitsize; \
  172. while (i>0) \
  173. { type1 b = next_random_bit(); \
  174. x1 = ((x1<<1) + b); x2 = ((x2<<1) + b); \
  175. i--; \
  176. } \
  177. where1 = x1; where2 = x2; \
  178. }
  179. void main3(void) {
  180. #define compare_integer_representation(type1,type2,typestr1,typestr2,type1_bitsize,type2_bitsize,where) \
  181. { if ((type1_bitsize>=0) && (type2_bitsize>=0) && (type1_bitsize==type2_bitsize)) \
  182. { int i,j; \
  183. type1 sample1; type2 sample2; \
  184. where = TRUE; \
  185. for (i = 0; i<100; i++) \
  186. { get_a_random_twice(type1,type2,type1_bitsize,sample1,sample2); \
  187. if (!(sample1 == (type1)(sample2))) { where = FALSE; } \
  188. if (!(sample2 == (type2)(sample1))) { where = FALSE; } \
  189. } \
  190. for (i = 0; i<100; i++) \
  191. { get_a_random(type1,type1_bitsize,sample1); \
  192. sample2 = (type2)(sample1); \
  193. for (j = 0; j < type1_bitsize; j++) \
  194. if (!( ((sample1 & ((type1)1<<j)) == 0) \
  195. == ((sample2 & ((type2)1<<j)) == 0) \
  196. ) ) \
  197. { where = FALSE; } \
  198. } \
  199. if (where) \
  200. { printf("/* Integer types %s and %s have the same binary representation. */\n",typestr1,typestr2); } \
  201. else \
  202. { printf("#error \"Integer types %s and %s have different binary representations!!\"\n",typestr1,typestr2); } \
  203. } \
  204. else \
  205. { where = FALSE; } \
  206. }
  207. compare_integer_representation(schar,uchar,"char","unsigned char",char_bitsize,uchar_bitsize,char_uchar_same);
  208. compare_integer_representation(short,ushort,"short","unsigned short",short_bitsize,ushort_bitsize,short_ushort_same);
  209. compare_integer_representation(int,uint,"int","unsigned int",int_bitsize,uint_bitsize,int_uint_same);
  210. compare_integer_representation(long,ulong,"long","unsigned long",long_bitsize,ulong_bitsize,long_ulong_same);
  211. #ifdef HAVE_LONGLONG
  212. compare_integer_representation(longlong,ulonglong,"long long","unsigned long long",longlong_bitsize,ulonglong_bitsize,longlong_ulonglong_same);
  213. #endif
  214. printf("\n");
  215. }
  216. void main4(void) {
  217. #define test_integer_ushift(type,typestr,type_bitsize) \
  218. if (type_bitsize >= 0) \
  219. { int i,j,shc; \
  220. type sample1,sample2; \
  221. boolean left_works = TRUE, right_works = TRUE; \
  222. for (i = 0; i<100; i++) \
  223. { get_a_random(type,type_bitsize,sample1); \
  224. for (shc = 0; shc < type_bitsize; shc++) \
  225. { sample2 = sample1 << shc; \
  226. for (j=0; j < type_bitsize; j++) \
  227. { if (!( ((sample2 & ((type)1<<j)) == 0) \
  228. == \
  229. (j < shc ? TRUE : ((sample1 & ((type)1<<(j-shc))) == 0)) \
  230. ) ) \
  231. { left_works = FALSE; } \
  232. } } } \
  233. for (i = 0; i<100; i++) \
  234. { get_a_random(type,type_bitsize,sample1); \
  235. for (shc = 0; shc < type_bitsize; shc++) \
  236. { sample2 = sample1 >> shc; \
  237. for (j=0; j < type_bitsize; j++) \
  238. { if (!( ((sample2 & ((type)1<<j)) == 0) \
  239. == \
  240. (j >= type_bitsize-shc ? TRUE : ((sample1 & ((type)1<<(j+shc))) == 0)) \
  241. ) ) \
  242. { right_works = FALSE; } \
  243. } } } \
  244. if (!left_works) \
  245. { printf("#error \"Left shift of integers of type %s does not work!!\"\n",typestr); } \
  246. if (!right_works) \
  247. { printf("#error \"Right shift of integers of type %s does not work!!\"\n",typestr); } \
  248. }
  249. #define test_integer_sshift(type,typestr,type_bitsize) \
  250. if (type_bitsize >= 0) \
  251. { int i,j,shc; \
  252. type sample1,sample2; \
  253. boolean left_works = TRUE, right_works = TRUE; \
  254. for (i = 0; i<100; i++) \
  255. { get_a_random(type,type_bitsize,sample1); \
  256. for (shc = 0; shc < type_bitsize; shc++) \
  257. { sample2 = sample1 << shc; \
  258. for (j=0; j < type_bitsize; j++) \
  259. { if (!( ((sample2 & ((type)1<<j)) == 0) \
  260. == \
  261. (j < shc ? TRUE : ((sample1 & ((type)1<<(j-shc))) == 0)) \
  262. ) ) \
  263. { left_works = FALSE; } \
  264. } } } \
  265. for (i = 0; i<100; i++) \
  266. { get_a_random(type,type_bitsize,sample1); \
  267. for (shc = 0; shc < type_bitsize; shc++) \
  268. { sample2 = sample1 >> shc; \
  269. for (j=0; j < type_bitsize; j++) \
  270. { if (!( ((sample2 & ((type)1<<j)) == 0) \
  271. == \
  272. ((sample1 & ((type)1<< (j+shc>=type_bitsize ? type_bitsize-1 : j+shc))) == 0) \
  273. ) ) \
  274. { right_works = FALSE; } \
  275. } } } \
  276. if (!left_works) \
  277. { printf("#error \"Left shift of integers of type %s does not work!!\"\n",typestr); } \
  278. if (!right_works) \
  279. { printf("#error \"Right shift of integers of type %s does not work!!\"\n",typestr); } \
  280. }
  281. test_integer_ushift(uchar,"unsigned char",uchar_bitsize);
  282. test_integer_ushift(ushort,"unsigned short",ushort_bitsize);
  283. test_integer_ushift(uint,"unsigned int",uint_bitsize);
  284. test_integer_ushift(ulong,"unsigned long",ulong_bitsize);
  285. #ifdef HAVE_LONGLONG
  286. test_integer_ushift(ulonglong,"unsigned long long",ulonglong_bitsize);
  287. #endif
  288. test_integer_sshift(schar,"char",char_bitsize);
  289. test_integer_sshift(short,"short",short_bitsize);
  290. test_integer_sshift(int,"int",int_bitsize);
  291. test_integer_sshift(long,"long",long_bitsize);
  292. #ifdef HAVE_LONGLONG
  293. test_integer_sshift(longlong,"long long",longlong_bitsize);
  294. #endif
  295. }
  296. void main5(void) {
  297. #define test_integer_casts(type1,type2,typestr1,typestr2,type1_bitsize,type2_bitsize,want) \
  298. if (type1_bitsize <= type2_bitsize) \
  299. { int i,j; \
  300. boolean modifies = FALSE; \
  301. boolean zero_extends = TRUE; \
  302. boolean sign_extends = TRUE; \
  303. for (i = 0; i<100; i++) \
  304. { type1 sample1; \
  305. type2 sample2; \
  306. get_a_random(type1,type1_bitsize,sample1); \
  307. sample2 = (type2)sample1; \
  308. if (!(sample1 == (type1)sample2)) { modifies = TRUE; } \
  309. for (j = 0; j<type1_bitsize; j++) \
  310. if (!( ((sample1 & ((type1)1<<j)) == 0) == ((sample2 & ((type2)1<<j)) == 0) )) \
  311. { zero_extends = FALSE; sign_extends = FALSE; } \
  312. for (j = type1_bitsize; j<type2_bitsize; j++) \
  313. if (!((sample2 & ((type2)1<<j)) == 0)) \
  314. { zero_extends = FALSE; } \
  315. for (j = type1_bitsize; j<type2_bitsize; j++) \
  316. if (!( ((sample1 & ((type1)1<<(type1_bitsize-1))) == 0) == ((sample2 & ((type2)1<<j)) == 0) )) \
  317. { sign_extends = FALSE; } \
  318. } \
  319. if (modifies) \
  320. printf("#error \"Casts: (%s)(%s)(x) == x does not hold for every %s x !!\"\n",typestr1,typestr2,typestr1); \
  321. if (zero_extends && sign_extends) \
  322. { if (!(type1_bitsize == type2_bitsize)) \
  323. printf("#error \"Casts from %s to %s works by identity!!\"\n",typestr1,typestr2); \
  324. } \
  325. if (zero_extends && !sign_extends) \
  326. { if ((type1_bitsize == type2_bitsize) || !(typestr1[0] == 'u') || !(want==1)) \
  327. printf("#error \"Casts from %s to %s works by zero-extend!!\"\n",typestr1,typestr2); \
  328. } \
  329. if (sign_extends && !zero_extends) \
  330. { if ((type1_bitsize == type2_bitsize) || (typestr1[0] == 'u') || !(want==2)) \
  331. printf("#error \"Casts from %s to %s works by sign-extend!!\"\n",typestr1,typestr2); \
  332. } \
  333. if (!sign_extends && !zero_extends) \
  334. printf("#error \"Casts from %s to %s works in an unknown manner!!\"\n",typestr1,typestr2); \
  335. }
  336. /* erst Casts zwischen Integers vermutlich gleicher Größe: */
  337. test_integer_casts(schar,uchar,"char","unsigned char",char_bitsize,uchar_bitsize,0);
  338. test_integer_casts(short,ushort,"short","unsigned short",short_bitsize,ushort_bitsize,0);
  339. test_integer_casts(int,uint,"int","unsigned int",int_bitsize,uint_bitsize,0);
  340. test_integer_casts(long,ulong,"long","unsigned long",long_bitsize,ulong_bitsize,0);
  341. test_integer_casts(uchar,schar,"unsigned char","char",uchar_bitsize,char_bitsize,0);
  342. test_integer_casts(ushort,short,"unsigned short","short",ushort_bitsize,short_bitsize,0);
  343. test_integer_casts(uint,int,"unsigned int","int",uint_bitsize,int_bitsize,0);
  344. test_integer_casts(ulong,long,"unsigned long","long",ulong_bitsize,long_bitsize,0);
  345. #ifdef HAVE_LONGLONG
  346. test_integer_casts(longlong,ulonglong,"long long","unsigned long long",longlong_bitsize,ulonglong_bitsize,0);
  347. test_integer_casts(ulonglong,longlong,"unsigned long long","long long",ulonglong_bitsize,longlong_bitsize,0);
  348. #endif
  349. /* dann Casts zwischen Integers unterschiedlicher Größe, aber gleichen Vorzeichens: */
  350. test_integer_casts(uchar,ushort,"unsigned char","unsigned short",uchar_bitsize,ushort_bitsize,1);
  351. test_integer_casts(uchar,uint,"unsigned char","unsigned int",uchar_bitsize,uint_bitsize,1);
  352. test_integer_casts(uchar,ulong,"unsigned char","unsigned long",uchar_bitsize,ulong_bitsize,1);
  353. test_integer_casts(ushort,uint,"unsigned short","unsigned int",ushort_bitsize,uint_bitsize,1);
  354. test_integer_casts(ushort,ulong,"unsigned short","unsigned long",ushort_bitsize,ulong_bitsize,1);
  355. test_integer_casts(uint,ulong,"unsigned int","unsigned long",uint_bitsize,ulong_bitsize,1);
  356. #ifdef HAVE_LONGLONG
  357. test_integer_casts(uchar,ulonglong,"unsigned char","unsigned long long",uchar_bitsize,ulonglong_bitsize,1);
  358. test_integer_casts(ushort,ulonglong,"unsigned short","unsigned long long",ushort_bitsize,ulonglong_bitsize,1);
  359. test_integer_casts(uint,ulonglong,"unsigned int","unsigned long long",uint_bitsize,ulonglong_bitsize,1);
  360. test_integer_casts(ulong,ulonglong,"unsigned long","unsigned long long",ulong_bitsize,ulonglong_bitsize,1);
  361. #endif
  362. test_integer_casts(schar,short,"char","short",char_bitsize,short_bitsize,2);
  363. test_integer_casts(schar,int,"char","int",char_bitsize,int_bitsize,2);
  364. test_integer_casts(schar,long,"char","long",char_bitsize,long_bitsize,2);
  365. test_integer_casts(short,int,"short","int",short_bitsize,int_bitsize,2);
  366. test_integer_casts(short,long,"short","long",short_bitsize,long_bitsize,2);
  367. test_integer_casts(int,long,"int","long",int_bitsize,long_bitsize,2);
  368. #ifdef HAVE_LONGLONG
  369. test_integer_casts(schar,longlong,"char","long long",char_bitsize,longlong_bitsize,2);
  370. test_integer_casts(short,longlong,"short","long long",short_bitsize,longlong_bitsize,2);
  371. test_integer_casts(int,longlong,"int","long long",int_bitsize,longlong_bitsize,2);
  372. test_integer_casts(long,longlong,"long","long long",long_bitsize,longlong_bitsize,2);
  373. #endif
  374. /* dann Casts zwischen Integers unterschiedlicher Größe und unterschiedlichen Vorzeichens: */
  375. test_integer_casts(uchar,short,"unsigned char","short",uchar_bitsize,short_bitsize,1);
  376. test_integer_casts(uchar,int,"unsigned char","int",uchar_bitsize,int_bitsize,1);
  377. test_integer_casts(uchar,long,"unsigned char","long",uchar_bitsize,long_bitsize,1);
  378. test_integer_casts(ushort,int,"unsigned short","int",ushort_bitsize,int_bitsize,1);
  379. test_integer_casts(ushort,long,"unsigned short","long",ushort_bitsize,long_bitsize,1);
  380. test_integer_casts(uint,long,"unsigned int","long",uint_bitsize,long_bitsize,1);
  381. #ifdef HAVE_LONGLONG
  382. test_integer_casts(uchar,longlong,"unsigned char","long long",uchar_bitsize,longlong_bitsize,1);
  383. test_integer_casts(ushort,longlong,"unsigned short","long long",ushort_bitsize,longlong_bitsize,1);
  384. test_integer_casts(uint,longlong,"unsigned int","long long",uint_bitsize,longlong_bitsize,1);
  385. test_integer_casts(ulong,longlong,"unsigned long","long long",ulong_bitsize,longlong_bitsize,1);
  386. #endif
  387. test_integer_casts(schar,ushort,"char","unsigned short",char_bitsize,ushort_bitsize,2);
  388. test_integer_casts(schar,uint,"char","unsigned int",char_bitsize,uint_bitsize,2);
  389. test_integer_casts(schar,ulong,"char","unsigned long",char_bitsize,ulong_bitsize,2);
  390. test_integer_casts(short,uint,"short","unsigned int",short_bitsize,uint_bitsize,2);
  391. test_integer_casts(short,ulong,"short","unsigned long",short_bitsize,ulong_bitsize,2);
  392. test_integer_casts(int,ulong,"int","unsigned long",int_bitsize,ulong_bitsize,2);
  393. #ifdef HAVE_LONGLONG
  394. test_integer_casts(schar,ulonglong,"char","unsigned long long",char_bitsize,ulonglong_bitsize,2);
  395. test_integer_casts(short,ulonglong,"short","unsigned long long",short_bitsize,ulonglong_bitsize,2);
  396. test_integer_casts(int,ulonglong,"int","unsigned long long",int_bitsize,ulonglong_bitsize,2);
  397. test_integer_casts(long,ulonglong,"long","unsigned long long",long_bitsize,ulonglong_bitsize,2);
  398. #endif
  399. }
  400. void main6(void) {
  401. #define check_sizeof_pointer(type,typestr) \
  402. { if (!(sizeof(type) <= sizeof(long))) \
  403. printf("#error \"Type %s does not fit into a long!!\"\n",typestr); \
  404. }
  405. check_sizeof_pointer(char*,"char *");
  406. check_sizeof_pointer(long*,"long *");
  407. check_sizeof_pointer(function*,"function *");
  408. pointer_bitsize = char_bitsize * sizeof(char*);
  409. printf("/* Pointers of type %s have %ld bits. */\n","char *",(long)pointer_bitsize);
  410. printf("#define pointer_bitsize %ld\n",(long)pointer_bitsize);
  411. printf("\n");
  412. }
  413. void main7(void) {
  414. #define test_pointer_casts(type1,type2,typestr1,typestr2) \
  415. if (!(sizeof(type1) == sizeof(type2))) \
  416. { printf("#error \"Pointer types %s and %s have different sizes!!\"\n",typestr1,typestr2); } \
  417. else \
  418. { int i; \
  419. ulong differences1 = 0, differences2 = 0; \
  420. for (i = 0; i<100; i++) \
  421. { ulong sample; \
  422. type1 sample1; \
  423. type2 sample2; \
  424. get_a_random(ulong,ulong_bitsize,sample); \
  425. sample1 = (type1)sample; \
  426. sample2 = (type2)sample; \
  427. differences1 |= ((ulong)sample1 ^ (ulong)(type1)(sample2)); \
  428. differences2 |= ((ulong)sample2 ^ (ulong)(type2)(sample1)); \
  429. } \
  430. if (differences1==0) \
  431. printf("/* Casts from %s to %s is OK (does nothing). */\n",typestr2,typestr1); \
  432. else \
  433. if (differences1 == ~(ulong)0) \
  434. printf("#error \"Casts from %s to %s work in an unknown way!!\"\n",typestr2,typestr1); \
  435. else \
  436. printf("#error \"Casts from %s to %s modify part 0x%8lX of pointer!!\"\n",typestr2,typestr1,differences1); \
  437. if (differences2==0) \
  438. printf("/* Casts from %s to %s is OK (does nothing). */\n",typestr1,typestr2); \
  439. else \
  440. if (differences2 == ~(ulong)0) \
  441. printf("#error \"Casts from %s to %s work in an unknown way!!\"\n",typestr1,typestr2); \
  442. else \
  443. printf("#error \"Casts from %s to %s modify part 0x%8lX of pointer!!\"\n",typestr1,typestr2,differences2); \
  444. }
  445. test_pointer_casts(char*,long*,"char *","long *");
  446. test_pointer_casts(char*,function*,"char *","function *");
  447. printf("\n");
  448. }
  449. void main8(void) {
  450. /* The following macro works only in C, not in C++, because C++ restricts the
  451. use of NULL pointers and also because C++ forbids defining types within a
  452. cast. */
  453. #define alignmentof(type) \
  454. (int)(&((struct { char dummy1; type dummy2; } *)0)->dummy2)
  455. #define get_alignment(type,typestr) \
  456. { struct { char dummy1; type dummy2; } dummy; \
  457. long alignment = (char*)&dummy.dummy2 - (char*)&dummy; \
  458. printf("/* Type %s has sizeof = %ld and alignment = %ld. */\n",typestr,(long)sizeof(type),alignment); \
  459. if (!(typestr[0] == 'u') && !(typestr[string_length(typestr)-1] == '*')) \
  460. { printf("#define sizeof_"); printf_underscored(typestr); printf(" %ld\n",(long)sizeof(type)); \
  461. printf("#define alignment_"); printf_underscored(typestr); printf(" %ld\n",alignment); \
  462. } \
  463. if (!((alignment & (alignment-1)) == 0)) \
  464. printf("#error \"The alignment %ld of type %s is not a power of two!!\"\n",alignment,typestr); \
  465. printf("\n"); \
  466. }
  467. get_alignment(char,"char"); get_alignment(uchar,"unsigned char");
  468. get_alignment(short,"short"); get_alignment(ushort,"unsigned short");
  469. get_alignment(int,"int"); get_alignment(uint,"unsigned int");
  470. get_alignment(long,"long"); get_alignment(ulong,"unsigned long");
  471. #ifdef HAVE_LONGLONG
  472. get_alignment(longlong,"long long"); get_alignment(ulonglong,"unsigned long long");
  473. #endif
  474. get_alignment(float,"float");
  475. get_alignment(double,"double");
  476. get_alignment(char*,"char *");
  477. get_alignment(long*,"long *");
  478. get_alignment(function*,"function *");
  479. }
  480. void main9(void) {
  481. #define get_endian(type,typestr,type_bitsize) \
  482. { if (type_bitsize == uchar_bitsize * sizeof(type)) \
  483. { auto union { uchar einzeln[sizeof(type)]; type gesamt; } x; \
  484. int i,j; \
  485. boolean big_endian = TRUE; \
  486. boolean little_endian = TRUE; \
  487. for (i = 0; i<100; i++) \
  488. { type sample; \
  489. get_a_random(type,type_bitsize,sample); \
  490. x.gesamt = sample; \
  491. for (j = 0; j<sizeof(type); j++, sample >>= uchar_bitsize) \
  492. { if (!( (sample & (((type)1<<uchar_bitsize)-1)) == x.einzeln[j] )) \
  493. { little_endian = FALSE; } \
  494. if (!( (sample & (((type)1<<uchar_bitsize)-1)) == x.einzeln[sizeof(type)-1-j] )) \
  495. { big_endian = FALSE; } \
  496. } } \
  497. if (big_endian && little_endian) \
  498. { if (!(sizeof(type) == 1)) \
  499. printf("#error \"Endianness of type %s in memory doesn't matter.\"\n",typestr); } \
  500. if (big_endian && !little_endian) \
  501. { printf("/* Type %s is stored BIG-ENDIAN in memory (i.e. like mc68000 or sparc). */\n",typestr); \
  502. printf("#define "); printf_underscored(&typestr[9]); printf("_big_endian\n"); \
  503. } \
  504. if (little_endian && !big_endian) \
  505. { printf("/* Type %s is stored LITTLE-ENDIAN in memory (i.e. like Z80 or VAX). */\n",typestr); \
  506. printf("#define "); printf_underscored(&typestr[9]); printf("_little_endian\n"); \
  507. } \
  508. if (!big_endian && !little_endian) \
  509. { printf("#error \"Type %s is stored in memory in an obscure manner!!\"\n",typestr); } \
  510. } \
  511. else \
  512. { printf("#error \"Endianness makes no sense for type %s !!\"\n",typestr); } \
  513. }
  514. get_endian(uchar,"unsigned char",uchar_bitsize);
  515. get_endian(ushort,"unsigned short",ushort_bitsize);
  516. get_endian(uint,"unsigned int",uint_bitsize);
  517. get_endian(ulong,"unsigned long",ulong_bitsize);
  518. #ifdef HAVE_LONGLONG
  519. get_endian(ulonglong,"unsigned long long",ulonglong_bitsize);
  520. #endif
  521. printf("\n");
  522. }
  523. long get_stack_direction(void)
  524. { auto char dummy;
  525. static char* dummyaddr = (char*)0;
  526. if (!(dummyaddr == (char*)0))
  527. { return (&dummy) - dummyaddr; }
  528. else
  529. { dummyaddr = &dummy;
  530. { long result = get_stack_direction();
  531. /* The next assignment avoids tail recursion elimination (IRIX 6.4 CC). */
  532. dummyaddr = (char*)0;
  533. return result;
  534. } }
  535. }
  536. void main10(void)
  537. { long stack_direction = get_stack_direction();
  538. if (stack_direction > 0)
  539. { printf("/* Stack grows up, ca. %ld bytes per function call. */\n",(long)stack_direction);
  540. printf("#define stack_grows_up\n");
  541. }
  542. else if (stack_direction < 0)
  543. { printf("/* Stack grows down, ca. %ld bytes per function call. */\n",-(long)stack_direction);
  544. printf("#define stack_grows_down\n");
  545. }
  546. else
  547. printf("#error \"Unknown stack model -- incorrect C semantics!!\"\n");
  548. }
  549. int main()
  550. { main1();
  551. main2();
  552. main3();
  553. main4();
  554. main5();
  555. main6();
  556. main7();
  557. main8();
  558. main9();
  559. main10();
  560. if (ferror(stdout) || fclose(stdout)) return 1;
  561. return 0;
  562. }