align_test.c
上传用户:xiejiait
上传日期:2007-01-06
资源大小:881k
文件大小:14k
源码类别:

SCSI/ASPI

开发平台:

MultiPlatform

  1. /* @(#)align_test.c 1.12 00/01/07 Copyright 1995 J. Schilling */
  2. #ifndef lint
  3. static char sccsid[] =
  4. "@(#)align_test.c 1.12 00/01/07 Copyright 1995 J. Schilling";
  5. #endif
  6. /*
  7.  * Generate machine dependant align.h
  8.  *
  9.  * Copyright (c) 1995 J. Schilling
  10.  */
  11. /*
  12.  * This program is free software; you can redistribute it and/or modify
  13.  * it under the terms of the GNU General Public License as published by
  14.  * the Free Software Foundation; either version 2, or (at your option)
  15.  * any later version.
  16.  *
  17.  * This program is distributed in the hope that it will be useful,
  18.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20.  * GNU General Public License for more details.
  21.  *
  22.  * You should have received a copy of the GNU General Public License
  23.  * along with this program; see the file COPYING.  If not, write to
  24.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  25.  */
  26. #include <mconfig.h>
  27. #include <stdio.h>
  28. #include <standard.h>
  29. /*#define FORCE_ALIGN*/
  30. /*#define OFF_ALIGN*/
  31. /*#define CHECK_ALIGN*/
  32. EXPORT int main __PR((int ac, char** av));
  33. #if !defined(FORCE_ALIGN) && !defined(OFF_ALIGN) && !defined(CHECK_ALIGN)
  34. #define OFF_ALIGN
  35. #endif
  36. char buf[8192+1024];
  37. char *buf_aligned;
  38. #ifdef FORCE_ALIGN
  39. # undef CHECK_ALIGN
  40. # undef OFF_ALIGN
  41. #endif
  42. #ifdef CHECK_ALIGN
  43. # undef FORCE_ALIGN
  44. # undef OFF_ALIGN
  45. #endif
  46. #ifdef OFF_ALIGN
  47. # undef FORCE_ALIGN
  48. # undef CHECK_ALIGN
  49. #endif
  50. #ifdef FORCE_ALIGN
  51. #define ALIGN_short sizeof (short)
  52. #define ALIGN_int sizeof (int)
  53. #define ALIGN_long sizeof (long)
  54. #define ALIGN_longlong sizeof (long long)
  55. #define ALIGN_float sizeof (float)
  56. #define ALIGN_double sizeof (double)
  57. #define ALIGN_ptr sizeof (char *)
  58. #endif
  59. #ifdef CHECK_ALIGN
  60. #include <signal.h>
  61. #include <setjmp.h>
  62. LOCAL jmp_buf jb;
  63. LOCAL int check_align __PR((int (*)(char*, int), void (*)(char*, int), int));
  64. LOCAL int check_short __PR((char *, int));
  65. LOCAL int check_int __PR((char *, int));
  66. LOCAL int check_long __PR((char *, int));
  67. LOCAL int check_longlong __PR((char *, int));
  68. LOCAL int check_float __PR((char *, int));
  69. LOCAL int check_double __PR((char *, int));
  70. LOCAL int check_ptr __PR((char *, int));
  71. LOCAL int speed_check __PR((char *, void (*)(char*, int), int));
  72. LOCAL void speed_short __PR((char *, int));
  73. LOCAL void speed_int __PR((char *, int));
  74. LOCAL void speed_long __PR((char *, int));
  75. LOCAL void speed_longlong __PR((char *, int));
  76. LOCAL void speed_float __PR((char *, int));
  77. LOCAL void speed_double __PR((char *, int));
  78. LOCAL void speed_ptr __PR((char *, int));
  79. #define ALIGN_short check_align(check_short, speed_short, sizeof (short))
  80. #define ALIGN_int check_align(check_int, speed_int, sizeof (int))
  81. #define ALIGN_long check_align(check_long, speed_long, sizeof (long))
  82. #define ALIGN_longlong check_align(check_longlong, speed_longlong, sizeof (long long))
  83. #define ALIGN_float check_align(check_float, speed_float, sizeof (float))
  84. #define ALIGN_double check_align(check_double, speed_double, sizeof (double))
  85. #define ALIGN_ptr check_align(check_ptr, speed_ptr, sizeof (char *))
  86. #endif
  87. #ifdef OFF_ALIGN
  88. #define sm_off(s, m) ((int)&((s)0)->m)
  89. LOCAL int off_short __PR((void));
  90. LOCAL int off_int __PR((void));
  91. LOCAL int off_long __PR((void));
  92. LOCAL int off_longlong __PR((void));
  93. LOCAL int off_float __PR((void));
  94. LOCAL int off_double __PR((void));
  95. LOCAL int off_ptr __PR((void));
  96. #define ALIGN_short off_short()
  97. #define ALIGN_int off_int()
  98. #define ALIGN_long off_long()
  99. #define ALIGN_longlong off_longlong()
  100. #define ALIGN_float off_float()
  101. #define ALIGN_double off_double()
  102. #define ALIGN_ptr off_ptr()
  103. #endif
  104. LOCAL void printmacs __PR((void));
  105. #ifdef CHECK_ALIGN
  106. LOCAL void sig __PR((int));
  107. LOCAL void
  108. sig(signo)
  109. int signo;
  110. {
  111. signal(signo, sig);
  112. longjmp(jb, 1);
  113. }
  114. #endif
  115. #if defined(mc68000) || defined(mc68020)
  116. #define MIN_ALIGN 2
  117. #else
  118. #define MIN_ALIGN 2
  119. #endif
  120. #define min_align(i) (((i) < MIN_ALIGN) ? MIN_ALIGN : (i))
  121. char al[] = "alignment value for ";
  122. char ms[] = "alignment mask  for ";
  123. char so[] = "sizeof ";
  124. char sh[] = "short";
  125. char in[] = "int";
  126. char lo[] = "long";
  127. char ll[] = "long long";
  128. char fl[] = "float";
  129. char db[] = "double";
  130. char pt[] = "pointer";
  131. #define xalign(x, a, m) ( ((char *)(x)) + ( (a) - (((int)(x))&(m))) )
  132. EXPORT int
  133. main(ac, av)
  134. int ac;
  135. char **av;
  136. {
  137. char *p;
  138. int i;
  139. int s;
  140. #ifdef CHECK_ALIGN
  141. signal(SIGBUS, sig);
  142. #endif
  143. i = ((int)buf) % 1024;
  144. i = 1024 - i;
  145. p = &buf[i];
  146. buf_aligned = p;
  147. #ifdef DEBUG
  148. printf("buf: %lX %lXn",
  149. (unsigned long)buf, (unsigned long)xalign(buf, 1024, 1023));
  150. #endif
  151. printf("/*n");
  152. printf(" * This file has been generated automaticallyn");
  153. printf(" * by %sn", sccsid);
  154. printf(" * do not edit by hand.n");
  155. printf(" */n");
  156. printf("#ifndef _UTYPES_Hn");
  157. printf("#include <utypes.h>n");
  158. printf("#endifn");
  159. s = sizeof(short);
  160. i  = ALIGN_short;
  161. i = min_align(i);
  162. printf("n");
  163. printf("#define ALIGN_SHORT %dt/* %s(%s *)t*/n", i, al, sh);
  164. printf("#define ALIGN_SMASK %dt/* %s(%s *)t*/n", i-1, ms, sh);
  165. printf("#define SIZE_SHORT %dt/* %s(%s)ttt*/n", s, so, sh);
  166. s = sizeof(int);
  167. i  = ALIGN_int;
  168. i = min_align(i);
  169. printf("n");
  170. printf("#define ALIGN_INT %dt/* %s(%s *)tt*/n", i, al, in);
  171. printf("#define ALIGN_IMASK %dt/* %s(%s *)tt*/n", i-1, ms, in);
  172. printf("#define SIZE_INT %dt/* %s(%s)tttt*/n", s, so, in);
  173. s = sizeof(long);
  174. i  = ALIGN_long;
  175. i = min_align(i);
  176. printf("n");
  177. printf("#define ALIGN_LONG %dt/* %s(%s *)tt*/n", i, al, lo);
  178. printf("#define ALIGN_LMASK %dt/* %s(%s *)tt*/n", i-1, ms, lo);
  179. printf("#define SIZE_LONG %dt/* %s(%s)ttt*/n", s, so, lo);
  180. #ifdef HAVE_LONGLONG
  181. s = sizeof(long long);
  182. i  = ALIGN_longlong;
  183. i = min_align(i);
  184. #endif
  185. printf("n");
  186. printf("#define ALIGN_LLONG %dt/* %s(%s *)t*/n", i, al, ll);
  187. printf("#define ALIGN_LLMASK %dt/* %s(%s *)t*/n", i-1, ms, ll);
  188. printf("#define SIZE_LLONG %dt/* %s(%s)ttt*/n", s, so, ll);
  189. s = sizeof(float);
  190. i  = ALIGN_float;
  191. i = min_align(i);
  192. printf("n");
  193. printf("#define ALIGN_FLOAT %dt/* %s(%s *)t*/n", i, al, fl);
  194. printf("#define ALIGN_FMASK %dt/* %s(%s *)t*/n", i-1, ms, fl);
  195. printf("#define SIZE_FLOAT %dt/* %s(%s)ttt*/n", s, so, fl);
  196. s = sizeof(double);
  197. i  = ALIGN_double;
  198. i = min_align(i);
  199. printf("n");
  200. printf("#define ALIGN_DOUBLE %dt/* %s(%s *)t*/n", i, al, db);
  201. printf("#define ALIGN_DMASK %dt/* %s(%s *)t*/n", i-1, ms, db);
  202. printf("#define SIZE_DOUBLE %dt/* %s(%s)ttt*/n", s, so, db);
  203. s = sizeof(char *);
  204. i  = ALIGN_ptr;
  205. i = min_align(i);
  206. printf("n");
  207. printf("#define ALIGN_PTR %dt/* %s(%s *)t*/n", i, al, pt);
  208. printf("#define ALIGN_PMASK %dt/* %s(%s *)t*/n", i-1, ms, pt);
  209. printf("#define SIZE_PTR %dt/* %s(%s)ttt*/n", s, so, pt);
  210. printmacs();
  211. return (0);
  212. }
  213. LOCAL void
  214. printmacs()
  215. {
  216. printf("nn");
  217. printf("/*n * There used to be a cast to an int but we get a warning from GCC.n");
  218. printf(" * This warning message from GCC is wrong.n");
  219. printf(" * Believe me that this macro would even be usable if I would cast to short.n");
  220. printf(" * In order to avoid this warning, we are now using UIntptr_tn */n");
  221. /*printf("n");*/
  222. /*printf("n");*/
  223. printf("#define xaligned(a, s) ((((UIntptr_t)(a)) & s) == 0 )n");
  224. printf("#define x2aligned(a, b, s) (((((UIntptr_t)(a)) | ((UIntptr_t)(b))) & s) == 0 )n");
  225. printf("n");
  226. printf("#define saligned(a) xaligned(a, ALIGN_SMASK)n");
  227. printf("#define s2aligned(a, b) x2aligned(a, b, ALIGN_SMASK)n");
  228. printf("n");
  229. printf("#define ialigned(a) xaligned(a, ALIGN_IMASK)n");
  230. printf("#define i2aligned(a, b) x2aligned(a, b, ALIGN_IMASK)n");
  231. printf("n");
  232. printf("#define laligned(a) xaligned(a, ALIGN_LMASK)n");
  233. printf("#define l2aligned(a, b) x2aligned(a, b, ALIGN_LMASK)n");
  234. printf("n");
  235. printf("#define llaligned(a) xaligned(a, ALIGN_LLMASK)n");
  236. printf("#define ll2aligned(a, b) x2aligned(a, b, ALIGN_LLMASK)n");
  237. printf("n");
  238. printf("#define faligned(a) xaligned(a, ALIGN_FMASK)n");
  239. printf("#define f2aligned(a, b) x2aligned(a, b, ALIGN_FMASK)n");
  240. printf("n");
  241. printf("#define daligned(a) xaligned(a, ALIGN_DMASK)n");
  242. printf("#define d2aligned(a, b) x2aligned(a, b, ALIGN_DMASK)n");
  243. printf("n");
  244. printf("#define paligned(a) xaligned(a, ALIGN_PMASK)n");
  245. printf("#define p2aligned(a, b) x2aligned(a, b, ALIGN_PMASK)n");
  246. printf("nn");
  247. printf("/*n * There used to be a cast to an int but we get a warning from GCC.n");
  248. printf(" * This warning message from GCC is wrong.n");
  249. printf(" * Believe me that this macro would even be usable if I would cast to short.n");
  250. printf(" * In order to avoid this warning, we are now using UIntptr_tn */n");
  251. printf("#define xalign(x, a, m) ( ((char *)(x)) + ( (a) - 1 - ((((UIntptr_t)(x))-1)&(m))) )n");
  252. printf("n");
  253. printf("#define salign(x) xalign((x), ALIGN_SHORT, ALIGN_SMASK)n");
  254. printf("#define ialign(x) xalign((x), ALIGN_INT, ALIGN_IMASK)n");
  255. printf("#define lalign(x) xalign((x), ALIGN_LONG, ALIGN_LMASK)n");
  256. printf("#define llalign(x) xalign((x), ALIGN_LLONG, ALIGN_LLMASK)n");
  257. printf("#define falign(x) xalign((x), ALIGN_FLOAT, ALIGN_FMASK)n");
  258. printf("#define dalign(x) xalign((x), ALIGN_DOUBLE, ALIGN_DMASK)n");
  259. printf("#define palign(x) xalign((x), ALIGN_PTR, ALIGN_PMASK)n");
  260. }
  261. #ifdef CHECK_ALIGN
  262. /*
  263.  * Routines to compute the alignement by checking if the assignement
  264.  * causes a bus error.
  265.  * Some systems (e.g. Linux on DEC Aplha) will allow to fetch any
  266.  * type from any address. On these systems we must check the speed
  267.  * because unaligned fetches will take more time.
  268.  */
  269. LOCAL int
  270. check_align(cfunc, sfunc, tsize)
  271. int (*cfunc)();
  272. void (*sfunc)();
  273. int tsize;
  274. {
  275.  int calign;
  276.  int align;
  277.  int tcheck;
  278.  int t;
  279. register int i;
  280. register char *p = buf_aligned;
  281. for (i=1; i < 128; i++) {
  282. if (!setjmp(jb)) {
  283. (cfunc)(p, i);
  284. break;
  285. }
  286. }
  287. #ifdef DEBUG
  288. printf("i: %d tsize: %dn", i, tsize);
  289. #endif
  290. if (i == tsize)
  291. return (i);
  292. align = calign = i;
  293. tcheck = speed_check(p, sfunc, i);
  294. #ifdef DEBUG
  295. printf("tcheck: %dn", tcheck);
  296. #endif
  297. for (i = calign*2; i <= tsize; i *= 2) {
  298. t = speed_check(p, sfunc, i);
  299. #ifdef DEBUG
  300. printf("tcheck: %d t: %d i: %dn", tcheck, t, i);
  301. printf("tcheck - t: %d ... * 3: %dn",  (tcheck - t), (tcheck - t) * 3);
  302. #endif
  303. if (((tcheck - t) > 0) && ((tcheck - t) * 3) > tcheck) {
  304. #ifdef DEBUG
  305. printf("kleinern");
  306. #endif
  307. align = i;
  308. tcheck = t;
  309. }
  310. }
  311. return (align);
  312. }
  313. LOCAL int
  314. check_short(p, i)
  315. char *p;
  316. int i;
  317. {
  318. short *sp;
  319. sp = (short *)&p[i];
  320. *sp = 1;
  321. return (0);
  322. }
  323. LOCAL int
  324. check_int(p, i)
  325. char *p;
  326. int i;
  327. {
  328. int *ip;
  329. ip = (int *)&p[i];
  330. *ip = 1;
  331. return (0);
  332. }
  333. LOCAL int
  334. check_long(p, i)
  335. char *p;
  336. int i;
  337. {
  338. long *lp;
  339. lp = (long *)&p[i];
  340. *lp = 1;
  341. return (0);
  342. }
  343. #ifdef HAVE_LONGLONG
  344. LOCAL int
  345. check_longlong(p, i)
  346. char *p;
  347. int i;
  348. {
  349. long long *llp;
  350. llp = (long long *)&p[i];
  351. *llp = 1;
  352. return (0);
  353. }
  354. #endif
  355. LOCAL int
  356. check_float(p, i)
  357. char *p;
  358. int i;
  359. {
  360. float *fp;
  361. fp = (float *)&p[i];
  362. *fp = 1.0;
  363. return (0);
  364. }
  365. LOCAL int
  366. check_double(p, i)
  367. char *p;
  368. int i;
  369. {
  370. double *dp;
  371. dp = (double *)&p[i];
  372. *dp = 1.0;
  373. return (0);
  374. }
  375. LOCAL int
  376. check_ptr(p, i)
  377. char *p;
  378. int i;
  379. {
  380. char **pp;
  381. pp = (char  **)&p[i];
  382. *pp = (char *)1;
  383. return (0);
  384. }
  385. /*
  386.  * Routines to compute the alignement by checking the speed of the
  387.  * assignement.
  388.  * Some systems (e.g. Linux on DEC Aplha) will allow to fetch any
  389.  * type from any address. On these systems we must check the speed
  390.  * because unaligned fetches will take more time.
  391.  */
  392. LOCAL void
  393. speed_short(p, n)
  394. char *p;
  395. int n;
  396. {
  397. short *sp;
  398. int i;
  399. sp = (short *)&p[n];
  400. for (i = 1000000; --i >= 0;)
  401. *sp = i;
  402. }
  403. LOCAL void
  404. speed_int(p, n)
  405. char *p;
  406. int n;
  407. {
  408. int *ip;
  409. int i;
  410. ip = (int *)&p[n];
  411. for (i = 1000000; --i >= 0;)
  412. *ip = i;
  413. }
  414. LOCAL void
  415. speed_long(p, n)
  416. char *p;
  417. int n;
  418. {
  419. long *lp;
  420. int i;
  421. lp = (long *)&p[n];
  422. for (i = 1000000; --i >= 0;)
  423. *lp = i;
  424. }
  425. #ifdef HAVE_LONGLONG
  426. LOCAL void
  427. speed_longlong(p, n)
  428. char *p;
  429. int n;
  430. {
  431. long long *llp;
  432. int i;
  433. llp = (long long *)&p[n];
  434. for (i = 1000000; --i >= 0;)
  435. *llp = i;
  436. }
  437. #endif
  438. LOCAL void
  439. speed_float(p, n)
  440. char *p;
  441. int n;
  442. {
  443. float *fp;
  444. int i;
  445. fp = (float *)&p[n];
  446. for (i = 1000000; --i >= 0;)
  447. *fp = i;
  448. }
  449. LOCAL void
  450. speed_double(p, n)
  451. char *p;
  452. int n;
  453. {
  454. double *dp;
  455. int i;
  456. dp = (double *)&p[n];
  457. for (i = 1000000; --i >= 0;)
  458. *dp = i;
  459. }
  460. LOCAL void
  461. speed_ptr(p, n)
  462. char *p;
  463. int n;
  464. {
  465. char **pp;
  466. int i;
  467. pp = (char **)&p[n];
  468. for (i = 1000000; --i >= 0;)
  469. *pp = (char *)i;
  470. }
  471. #include <sys/times.h>
  472. LOCAL int
  473. speed_check(p, sfunc, n)
  474. char *p;
  475. void (*sfunc)();
  476. int n;
  477. {
  478. struct tms tm1;
  479. struct tms tm2;
  480. times(&tm1);
  481. (*sfunc)(p, n);
  482. times(&tm2);
  483. #ifdef DEBUG
  484. printf("t1: %ldn", (long) tm2.tms_utime-tm1.tms_utime);
  485. #endif
  486. return ((int) tm2.tms_utime-tm1.tms_utime);
  487. }
  488. #endif /* CHECK_ALIGN */
  489. #ifdef OFF_ALIGN
  490. /*
  491.  * Routines to compute the alignement by using the knowledge
  492.  * of the C-compiler.
  493.  * We define a structure and check the padding that has been inserted
  494.  * by the compiler to keep the apropriate type on a properly aligned
  495.  * address.
  496.  */
  497. LOCAL int
  498. off_short()
  499. {
  500. struct ss {
  501. char c;
  502. short s;
  503. } ss;
  504. ss.c = 0; /* fool C-compiler */
  505. return (sm_off(struct ss *, s));
  506. }
  507. LOCAL int
  508. off_int()
  509. {
  510. struct si {
  511. char c;
  512. int i;
  513. } si;
  514. si.c = 0; /* fool C-compiler */
  515. return (sm_off(struct si *, i));
  516. }
  517. LOCAL int
  518. off_long()
  519. {
  520. struct sl {
  521. char c;
  522. long l;
  523. } sl;
  524. sl.c = 0; /* fool C-compiler */
  525. return (sm_off(struct sl *, l));
  526. }
  527. #ifdef HAVE_LONGLONG
  528. LOCAL int
  529. off_longlong()
  530. {
  531. struct sll {
  532. char c;
  533. long long ll;
  534. } sll;
  535. sll.c = 0; /* fool C-compiler */
  536. return (sm_off(struct sll *, ll));
  537. }
  538. #endif
  539. LOCAL int
  540. off_float()
  541. {
  542. struct sf {
  543. char c;
  544. float f;
  545. } sf;
  546. sf.c = 0; /* fool C-compiler */
  547. return (sm_off(struct sf *, f));
  548. }
  549. LOCAL int
  550. off_double()
  551. {
  552. struct sd {
  553. char c;
  554. double d;
  555. } sd;
  556. sd.c = 0; /* fool C-compiler */
  557. return (sm_off(struct sd *, d));
  558. }
  559. LOCAL int
  560. off_ptr()
  561. {
  562. struct sp {
  563. char c;
  564. char *p;
  565. } sp;
  566. sp.c = 0; /* fool C-compiler */
  567. return (sm_off(struct sp *, p));
  568. }
  569. #endif /* OFF_ALIGN */