odds and sods
[tridge/junkcode.git] / alignspeed.c
1 #include <stdio.h>
2 #include <sys/time.h>
3 #include <time.h>
4
5 static struct timeval tp1,tp2;
6
7 static void start_timer()
8 {
9         gettimeofday(&tp1,NULL);
10 }
11
12 static double end_timer()
13 {
14         gettimeofday(&tp2,NULL);
15         return (tp2.tv_sec + (tp2.tv_usec*1.0e-6)) - 
16                 (tp1.tv_sec + (tp1.tv_usec*1.0e-6));
17 }
18
19 typedef unsigned short uint16;
20 typedef unsigned int uint32;
21
22 #if (defined(__powerpc__) && defined(__GNUC__))
23 static __inline__ uint16_t ld_le16(const uint16_t *addr)
24 {
25         uint16_t val;
26         __asm__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr));
27         return val;
28 }
29
30 static __inline__ void st_le16(uint16_t *addr, const uint16_t val)
31 {
32         __asm__ ("sthbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
33 }
34
35 static __inline__ uint32_t ld_le32(const uint32_t *addr)
36 {
37         uint32_t val;
38         __asm__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr));
39         return val;
40 }
41
42 static __inline__ void st_le32(uint32_t *addr, const uint32_t val)
43 {
44         __asm__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
45 }
46 #define HAVE_ASM_BYTEORDER 1
47 #endif
48
49
50
51 #undef CAREFUL_ALIGNMENT
52
53 /* we know that the 386 can handle misalignment and has the "right" 
54    byteorder */
55 #if defined(__i386__)
56 #define CAREFUL_ALIGNMENT 0
57 #endif
58
59 #ifndef CAREFUL_ALIGNMENT
60 #define CAREFUL_ALIGNMENT 1
61 #endif
62
63 #define CVAL(buf,pos) ((uint_t)(((const uint8_t *)(buf))[pos]))
64 #define CVAL_NC(buf,pos) (((uint8_t *)(buf))[pos]) /* Non-const version of CVAL */
65 #define PVAL(buf,pos) (CVAL(buf,pos))
66 #define SCVAL(buf,pos,val) (CVAL_NC(buf,pos) = (val))
67
68 #if HAVE_ASM_BYTEORDER
69
70 #define  _PTRPOS(buf,pos) (((const uint8_t *)buf)+(pos))
71 #define SVAL(buf,pos) ld_le16((const uint16_t *)_PTRPOS(buf,pos))
72 #define IVAL(buf,pos) ld_le32((const uint32_t *)_PTRPOS(buf,pos))
73 #define SSVAL(buf,pos,val) st_le16((uint16_t *)_PTRPOS(buf,pos), val)
74 #define SIVAL(buf,pos,val) st_le32((uint32_t *)_PTRPOS(buf,pos), val)
75 #define SVALS(buf,pos) ((int16_t)SVAL(buf,pos))
76 #define IVALS(buf,pos) ((int32_t)IVAL(buf,pos))
77 #define SSVALS(buf,pos,val) SSVAL((buf),(pos),((int16_t)(val)))
78 #define SIVALS(buf,pos,val) SIVAL((buf),(pos),((int32_t)(val)))
79
80 #elif CAREFUL_ALIGNMENT
81
82 #define SVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8)
83 #define IVAL(buf,pos) (SVAL(buf,pos)|SVAL(buf,(pos)+2)<<16)
84 #define SSVALX(buf,pos,val) (CVAL_NC(buf,pos)=(uint8_t)((val)&0xFF),CVAL_NC(buf,pos+1)=(uint8_t)((val)>>8))
85 #define SIVALX(buf,pos,val) (SSVALX(buf,pos,val&0xFFFF),SSVALX(buf,pos+2,val>>16))
86 #define SVALS(buf,pos) ((int16_t)SVAL(buf,pos))
87 #define IVALS(buf,pos) ((int32_t)IVAL(buf,pos))
88 #define SSVAL(buf,pos,val) SSVALX((buf),(pos),((uint16_t)(val)))
89 #define SIVAL(buf,pos,val) SIVALX((buf),(pos),((uint32_t)(val)))
90 #define SSVALS(buf,pos,val) SSVALX((buf),(pos),((int16_t)(val)))
91 #define SIVALS(buf,pos,val) SIVALX((buf),(pos),((int32_t)(val)))
92
93 #else /* CAREFUL_ALIGNMENT */
94
95 /* this handles things for architectures like the 386 that can handle
96    alignment errors */
97 /*
98    WARNING: This section is dependent on the length of int16_t and int32_t
99    being correct 
100 */
101
102 /* get single value from an SMB buffer */
103 #define SVAL(buf,pos) (*(const uint16_t *)((const char *)(buf) + (pos)))
104 #define SVAL_NC(buf,pos) (*(uint16_t *)((char *)(buf) + (pos))) /* Non const version of above. */
105 #define IVAL(buf,pos) (*(const uint32_t *)((const char *)(buf) + (pos)))
106 #define IVAL_NC(buf,pos) (*(uint32_t *)((char *)(buf) + (pos))) /* Non const version of above. */
107 #define SVALS(buf,pos) (*(const int16_t *)((const char *)(buf) + (pos)))
108 #define SVALS_NC(buf,pos) (*(int16_t *)((char *)(buf) + (pos))) /* Non const version of above. */
109 #define IVALS(buf,pos) (*(const int32_t *)((const char *)(buf) + (pos)))
110 #define IVALS_NC(buf,pos) (*(int32_t *)((char *)(buf) + (pos))) /* Non const version of above. */
111
112 /* store single value in an SMB buffer */
113 #define SSVAL(buf,pos,val) SVAL_NC(buf,pos)=((uint16_t)(val))
114 #define SIVAL(buf,pos,val) IVAL_NC(buf,pos)=((uint32_t)(val))
115 #define SSVALS(buf,pos,val) SVALS_NC(buf,pos)=((int16_t)(val))
116 #define SIVALS(buf,pos,val) IVALS_NC(buf,pos)=((int32_t)(val))
117
118 #endif /* CAREFUL_ALIGNMENT */
119
120
121 static void aligntest(char *buf, size_t size)
122 {
123         int i;
124         uint32 val=0;
125         for (i=0;i<size-4;i++) {
126                 val += IVAL(buf, i);
127         }
128 }
129
130 int main(void)
131 {
132         char *buf = calloc(1, 5000);
133         int count;
134
135         start_timer();
136         for (count=0;end_timer() < 5.0;count++) {
137                 aligntest1(buf, 5000);
138         }
139         printf("test1 %.2f loops/sec\n", count/end_timer());
140
141         return 0;
142 }