* support/regression/tests/swap.c: added in response to #1638622
[fw/sdcc] / support / regression / tests / swap.c
1 /** various ways to swap nibbles/bytes/words
2 */
3 #include <testfwk.h>
4
5 #define TEST_VECT_8 0x12
6 #define TEST_VECT_16 0x1234
7 #define TEST_VECT_32 0x12345678
8
9 #define SWAP_4(x) ((unsigned char)((x)<<4)|(unsigned char)((x)>>4))
10     
11 typedef union {unsigned  int i; unsigned char c[2];} WORD;
12 typedef union {unsigned long l; unsigned char c[4];} LONG;
13
14 static void testSwap_4(void)
15 {
16     volatile unsigned char t=TEST_VECT_8;
17     unsigned char tt;
18
19     tt = t;
20     tt = SWAP_4(tt);
21     ASSERT( tt == SWAP_4(TEST_VECT_8));
22 }
23
24
25 #define SWAP_8(x) (((x)<<8)|((x)>>8))
26
27 static void testSwap_8(void)
28 {
29     volatile unsigned int t=TEST_VECT_16;
30     unsigned int tt;
31     WORD x;
32
33     tt = t;
34     tt = SWAP_8(tt);
35     ASSERT( tt == SWAP_8(TEST_VECT_16));
36
37     x.i = t;
38     x.i = SWAP_8(x.i);
39     ASSERT( x.i == SWAP_8(TEST_VECT_16));
40
41 #if defined (SDCC_mcs51)
42     /* this was filed as bug #1638622 (rejected) */
43     x.i = t;
44     x.i = x.c[1] + 256*x.c[0];
45     ASSERT( x.i == SWAP_8(TEST_VECT_16));
46
47     /* and with OR instead of ADD */
48     x.i = t;
49     x.i = x.c[1] | 256*x.c[0];
50     ASSERT( x.i == SWAP_8(TEST_VECT_16));
51
52     /* swapping union with little register pressure */
53     {
54         unsigned char tmp;
55         x.i = t;
56
57         tmp = x.c[0];
58         x.c[0]=x.c[1];
59         x.c[1]=tmp;
60
61         ASSERT( x.i == SWAP_8(TEST_VECT_16));
62     }
63 #endif
64 }
65
66
67 #define SWAP_16(x) (((x)<<16) | ((x)>>16))
68 #define SWAP_16_2(x) ((unsigned int)((SWAP_8((unsigned int)x))<<16) | (SWAP_8(x)>>16))
69
70 static void testSwap_16(void)
71 {
72     volatile unsigned long t=TEST_VECT_32;
73     unsigned long tt;
74     LONG x;
75
76     tt = t;
77     tt = SWAP_16(tt);
78     ASSERT( tt == SWAP_16(TEST_VECT_32));
79
80     tt = t;
81     tt = SWAP_16_2(tt);
82     ASSERT( tt == SWAP_16_2(TEST_VECT_32));
83
84     /* swapping union with little register pressure */
85     {
86         unsigned char c;
87         x.l = t;
88
89         c = x.c[0];
90         x.c[0]=x.c[2];
91         x.c[2]=c;
92         c = x.c[1];
93         x.c[1]=x.c[3];
94         x.c[3]=c;
95
96         ASSERT( x.l == SWAP_16(TEST_VECT_32));
97     }
98 }
99
100 /* now for something ugly */
101 static void testSwap_16_ptr(void)
102 {
103 #if defined (SDCC)
104 #include <sdcc-lib.h> /* just to get _AUTOMEM or _STATMEM */
105 #if defined (SDCC_STACK_AUTO)
106 #define MY_STATIC static
107 #else
108 #define MY_STATIC
109 #endif
110     MY_STATIC unsigned long _STATMEM tt=TEST_VECT_32;
111
112     /* swapping with little register pressure */
113     {
114         unsigned char c;
115
116         /* uglyness += 1 */
117         c = *(0+(unsigned char _STATMEM *)&tt);
118         *(0+(unsigned char _STATMEM *)&tt) = *(2+(unsigned char _STATMEM *)&tt);
119         *(2+(unsigned char _STATMEM *)&tt) = c;
120         c = *(1+(unsigned char _STATMEM *)&tt);
121         *(1+(unsigned char _STATMEM *)&tt) = *(3+(unsigned char _STATMEM *)&tt);
122         *(3+(unsigned char _STATMEM *)&tt) = c;
123         /* uglyness -= 1 */
124     }
125     ASSERT( tt == SWAP_16(TEST_VECT_32));
126 #endif
127 }
128
129
130 static void
131 testSwap(void)
132 {
133    testSwap_4();
134    testSwap_8();
135    testSwap_16();
136    testSwap_16_ptr();
137 }