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

SCSI/ASPI

开发平台:

MultiPlatform

  1. /* @(#)align_test.c 1.10 99/08/30 Copyright 1995 J. Schilling */
  2. #ifndef lint
  3. static char sccsid[] =
  4. "@(#)align_test.c 1.10 99/08/30 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. s = sizeof(short);
  157. i  = ALIGN_short;
  158. i = min_align(i);
  159. printf("n");
  160. printf("#define ALIGN_SHORT %dt/* %s(%s *)t*/n", i, al, sh);
  161. printf("#define ALIGN_SMASK %dt/* %s(%s *)t*/n", i-1, ms, sh);
  162. printf("#define SIZE_SHORT %dt/* %s(%s)ttt*/n", s, so, sh);
  163. s = sizeof(int);
  164. i  = ALIGN_int;
  165. i = min_align(i);
  166. printf("n");
  167. printf("#define ALIGN_INT %dt/* %s(%s *)tt*/n", i, al, in);
  168. printf("#define ALIGN_IMASK %dt/* %s(%s *)tt*/n", i-1, ms, in);
  169. printf("#define SIZE_INT %dt/* %s(%s)tttt*/n", s, so, in);
  170. s = sizeof(long);
  171. i  = ALIGN_long;
  172. i = min_align(i);
  173. printf("n");
  174. printf("#define ALIGN_LONG %dt/* %s(%s *)tt*/n", i, al, lo);
  175. printf("#define ALIGN_LMASK %dt/* %s(%s *)tt*/n", i-1, ms, lo);
  176. printf("#define SIZE_LONG %dt/* %s(%s)ttt*/n", s, so, lo);
  177. #ifdef HAVE_LONGLONG
  178. s = sizeof(long long);
  179. i  = ALIGN_longlong;
  180. i = min_align(i);
  181. #endif
  182. printf("n");
  183. printf("#define ALIGN_LLONG %dt/* %s(%s *)t*/n", i, al, ll);
  184. printf("#define ALIGN_LLMASK %dt/* %s(%s *)t*/n", i-1, ms, ll);
  185. printf("#define SIZE_LLONG %dt/* %s(%s)ttt*/n", s, so, ll);
  186. s = sizeof(float);
  187. i  = ALIGN_float;
  188. i = min_align(i);
  189. printf("n");
  190. printf("#define ALIGN_FLOAT %dt/* %s(%s *)t*/n", i, al, fl);
  191. printf("#define ALIGN_FMASK %dt/* %s(%s *)t*/n", i-1, ms, fl);
  192. printf("#define SIZE_FLOAT %dt/* %s(%s)ttt*/n", s, so, fl);
  193. s = sizeof(double);
  194. i  = ALIGN_double;
  195. i = min_align(i);
  196. printf("n");
  197. printf("#define ALIGN_DOUBLE %dt/* %s(%s *)t*/n", i, al, db);
  198. printf("#define ALIGN_DMASK %dt/* %s(%s *)t*/n", i-1, ms, db);
  199. printf("#define SIZE_DOUBLE %dt/* %s(%s)ttt*/n", s, so, db);
  200. s = sizeof(char *);
  201. i  = ALIGN_ptr;
  202. i = min_align(i);
  203. printf("n");
  204. printf("#define ALIGN_PTR %dt/* %s(%s *)t*/n", i, al, pt);
  205. printf("#define ALIGN_PMASK %dt/* %s(%s *)t*/n", i-1, ms, pt);
  206. printf("#define SIZE_PTR %dt/* %s(%s)ttt*/n", s, so, pt);
  207. printmacs();
  208. return (0);
  209. }
  210. LOCAL void
  211. printmacs()
  212. {
  213. printf("n");
  214. printf("#define xaligned(a, s) ((((int)(a)) & s) == 0 )n");
  215. printf("#define x2aligned(a, b, s) (((((int)(a)) | ((int)(b))) & s) == 0 )n");
  216. printf("n");
  217. printf("#define saligned(a) xaligned(a, ALIGN_SMASK)n");
  218. printf("#define s2aligned(a, b) x2aligned(a, b, ALIGN_SMASK)n");
  219. printf("n");
  220. printf("#define ialigned(a) xaligned(a, ALIGN_IMASK)n");
  221. printf("#define i2aligned(a, b) x2aligned(a, b, ALIGN_IMASK)n");
  222. printf("n");
  223. printf("#define laligned(a) xaligned(a, ALIGN_LMASK)n");
  224. printf("#define l2aligned(a, b) x2aligned(a, b, ALIGN_LMASK)n");
  225. printf("n");
  226. printf("#define llaligned(a) xaligned(a, ALIGN_LLMASK)n");
  227. printf("#define ll2aligned(a, b) x2aligned(a, b, ALIGN_LLMASK)n");
  228. printf("n");
  229. printf("#define faligned(a) xaligned(a, ALIGN_FMASK)n");
  230. printf("#define f2aligned(a, b) x2aligned(a, b, ALIGN_FMASK)n");
  231. printf("n");
  232. printf("#define daligned(a) xaligned(a, ALIGN_DMASK)n");
  233. printf("#define d2aligned(a, b) x2aligned(a, b, ALIGN_DMASK)n");
  234. printf("n");
  235. printf("#define paligned(a) xaligned(a, ALIGN_PMASK)n");
  236. printf("#define p2aligned(a, b) x2aligned(a, b, ALIGN_PMASK)n");
  237. printf("nn");
  238. printf("/*n * I know excatly what I am doing here!n * The warning message from GCC is wrong.n");
  239. printf(" * Believe me that this macro would even be usable if I would cast to short.n */n");
  240. printf("#define xalign(x, a, m) ( ((char *)(x)) + ( (a) - (((int)(x))&(m))) )n");
  241. printf("n");
  242. printf("#define salign(x) xalign((x), ALIGN_SHORT, ALIGN_SMASK)n");
  243. printf("#define ialign(x) xalign((x), ALIGN_INT, ALIGN_IMASK)n");
  244. printf("#define lalign(x) xalign((x), ALIGN_LONG, ALIGN_LMASK)n");
  245. printf("#define llalign(x) xalign((x), ALIGN_LLONG, ALIGN_LLMASK)n");
  246. printf("#define falign(x) xalign((x), ALIGN_FLOAT, ALIGN_FMASK)n");
  247. printf("#define dalign(x) xalign((x), ALIGN_DOUBLE, ALIGN_DMASK)n");
  248. printf("#define palign(x) xalign((x), ALIGN_PTR, ALIGN_PMASK)n");
  249. }
  250. #ifdef CHECK_ALIGN
  251. /*
  252.  * Routines to compute the alignement by checking if the assignement
  253.  * causes a bus error.
  254.  * Some systems (e.g. Linux on DEC Aplha) will allow to fetch any
  255.  * type from any address. On these systems we must check the speed
  256.  * because unaligned fetches will take more time.
  257.  */
  258. LOCAL int
  259. check_align(cfunc, sfunc, tsize)
  260. int (*cfunc)();
  261. void (*sfunc)();
  262. int tsize;
  263. {
  264.  int calign;
  265.  int align;
  266.  int tcheck;
  267.  int t;
  268. register int i;
  269. register char *p = buf_aligned;
  270. for (i=1; i < 128; i++) {
  271. if (!setjmp(jb)) {
  272. (cfunc)(p, i);
  273. break;
  274. }
  275. }
  276. #ifdef DEBUG
  277. printf("i: %d tsize: %dn", i, tsize);
  278. #endif
  279. if (i == tsize)
  280. return (i);
  281. align = calign = i;
  282. tcheck = speed_check(p, sfunc, i);
  283. #ifdef DEBUG
  284. printf("tcheck: %dn", tcheck);
  285. #endif
  286. for (i = calign*2; i <= tsize; i *= 2) {
  287. t = speed_check(p, sfunc, i);
  288. #ifdef DEBUG
  289. printf("tcheck: %d t: %d i: %dn", tcheck, t, i);
  290. printf("tcheck - t: %d ... * 3: %dn",  (tcheck - t), (tcheck - t) * 3);
  291. #endif
  292. if (((tcheck - t) > 0) && ((tcheck - t) * 3) > tcheck) {
  293. #ifdef DEBUG
  294. printf("kleinern");
  295. #endif
  296. align = i;
  297. tcheck = t;
  298. }
  299. }
  300. return (align);
  301. }
  302. LOCAL int
  303. check_short(p, i)
  304. char *p;
  305. int i;
  306. {
  307. short *sp;
  308. sp = (short *)&p[i];
  309. *sp = 1;
  310. return (0);
  311. }
  312. LOCAL int
  313. check_int(p, i)
  314. char *p;
  315. int i;
  316. {
  317. int *ip;
  318. ip = (int *)&p[i];
  319. *ip = 1;
  320. return (0);
  321. }
  322. LOCAL int
  323. check_long(p, i)
  324. char *p;
  325. int i;
  326. {
  327. long *lp;
  328. lp = (long *)&p[i];
  329. *lp = 1;
  330. return (0);
  331. }
  332. #ifdef HAVE_LONGLONG
  333. LOCAL int
  334. check_longlong(p, i)
  335. char *p;
  336. int i;
  337. {
  338. long long *llp;
  339. llp = (long long *)&p[i];
  340. *llp = 1;
  341. return (0);
  342. }
  343. #endif
  344. LOCAL int
  345. check_float(p, i)
  346. char *p;
  347. int i;
  348. {
  349. float *fp;
  350. fp = (float *)&p[i];
  351. *fp = 1.0;
  352. return (0);
  353. }
  354. LOCAL int
  355. check_double(p, i)
  356. char *p;
  357. int i;
  358. {
  359. double *dp;
  360. dp = (double *)&p[i];
  361. *dp = 1.0;
  362. return (0);
  363. }
  364. LOCAL int
  365. check_ptr(p, i)
  366. char *p;
  367. int i;
  368. {
  369. char **pp;
  370. pp = (char  **)&p[i];
  371. *pp = (char *)1;
  372. return (0);
  373. }
  374. /*
  375.  * Routines to compute the alignement by checking the speed of the
  376.  * assignement.
  377.  * Some systems (e.g. Linux on DEC Aplha) will allow to fetch any
  378.  * type from any address. On these systems we must check the speed
  379.  * because unaligned fetches will take more time.
  380.  */
  381. LOCAL void
  382. speed_short(p, n)
  383. char *p;
  384. int n;
  385. {
  386. short *sp;
  387. int i;
  388. sp = (short *)&p[n];
  389. for (i = 1000000; --i >= 0;)
  390. *sp = i;
  391. }
  392. LOCAL void
  393. speed_int(p, n)
  394. char *p;
  395. int n;
  396. {
  397. int *ip;
  398. int i;
  399. ip = (int *)&p[n];
  400. for (i = 1000000; --i >= 0;)
  401. *ip = i;
  402. }
  403. LOCAL void
  404. speed_long(p, n)
  405. char *p;
  406. int n;
  407. {
  408. long *lp;
  409. int i;
  410. lp = (long *)&p[n];
  411. for (i = 1000000; --i >= 0;)
  412. *lp = i;
  413. }
  414. #ifdef HAVE_LONGLONG
  415. LOCAL void
  416. speed_longlong(p, n)
  417. char *p;
  418. int n;
  419. {
  420. long long *llp;
  421. int i;
  422. llp = (long long *)&p[n];
  423. for (i = 1000000; --i >= 0;)
  424. *llp = i;
  425. }
  426. #endif
  427. LOCAL void
  428. speed_float(p, n)
  429. char *p;
  430. int n;
  431. {
  432. float *fp;
  433. int i;
  434. fp = (float *)&p[n];
  435. for (i = 1000000; --i >= 0;)
  436. *fp = i;
  437. }
  438. LOCAL void
  439. speed_double(p, n)
  440. char *p;
  441. int n;
  442. {
  443. double *dp;
  444. int i;
  445. dp = (double *)&p[n];
  446. for (i = 1000000; --i >= 0;)
  447. *dp = i;
  448. }
  449. LOCAL void
  450. speed_ptr(p, n)
  451. char *p;
  452. int n;
  453. {
  454. char **pp;
  455. int i;
  456. pp = (char **)&p[n];
  457. for (i = 1000000; --i >= 0;)
  458. *pp = (char *)i;
  459. }
  460. #include <sys/times.h>
  461. LOCAL int
  462. speed_check(p, sfunc, n)
  463. char *p;
  464. void (*sfunc)();
  465. int n;
  466. {
  467. struct tms tm1;
  468. struct tms tm2;
  469. times(&tm1);
  470. (*sfunc)(p, n);
  471. times(&tm2);
  472. #ifdef DEBUG
  473. printf("t1: %ldn", (long) tm2.tms_utime-tm1.tms_utime);
  474. #endif
  475. return ((int) tm2.tms_utime-tm1.tms_utime);
  476. }
  477. #endif /* CHECK_ALIGN */
  478. #ifdef OFF_ALIGN
  479. /*
  480.  * Routines to compute the alignement by using the knowledge
  481.  * of the C-compiler.
  482.  * We define a structure and check the padding that has been inserted
  483.  * by the compiler to keep the apropriate type on a properly aligned
  484.  * address.
  485.  */
  486. LOCAL int
  487. off_short()
  488. {
  489. struct ss {
  490. char c;
  491. short s;
  492. } ss;
  493. ss.c = 0; /* fool C-compiler */
  494. return (sm_off(struct ss *, s));
  495. }
  496. LOCAL int
  497. off_int()
  498. {
  499. struct si {
  500. char c;
  501. int i;
  502. } si;
  503. si.c = 0; /* fool C-compiler */
  504. return (sm_off(struct si *, i));
  505. }
  506. LOCAL int
  507. off_long()
  508. {
  509. struct sl {
  510. char c;
  511. long l;
  512. } sl;
  513. sl.c = 0; /* fool C-compiler */
  514. return (sm_off(struct sl *, l));
  515. }
  516. #ifdef HAVE_LONGLONG
  517. LOCAL int
  518. off_longlong()
  519. {
  520. struct sll {
  521. char c;
  522. long long ll;
  523. } sll;
  524. sll.c = 0; /* fool C-compiler */
  525. return (sm_off(struct sll *, ll));
  526. }
  527. #endif
  528. LOCAL int
  529. off_float()
  530. {
  531. struct sf {
  532. char c;
  533. float f;
  534. } sf;
  535. sf.c = 0; /* fool C-compiler */
  536. return (sm_off(struct sf *, f));
  537. }
  538. LOCAL int
  539. off_double()
  540. {
  541. struct sd {
  542. char c;
  543. double d;
  544. } sd;
  545. sd.c = 0; /* fool C-compiler */
  546. return (sm_off(struct sd *, d));
  547. }
  548. LOCAL int
  549. off_ptr()
  550. {
  551. struct sp {
  552. char c;
  553. char *p;
  554. } sp;
  555. sp.c = 0; /* fool C-compiler */
  556. return (sm_off(struct sp *, p));
  557. }
  558. #endif /* OFF_ALIGN */