cleanup: remove cpu ctrl files, move tests
[gpsp.git] / gp2x / test / load_imm_test.c
CommitLineData
2823a4c8 1#include <stdio.h>\r
2\r
3typedef unsigned int u32;\r
4\r
5u32 arm_imm_find_nonzero(u32 imm, u32 start_bit)\r
6{\r
7 u32 i;\r
8\r
9 for(i = start_bit; i < 32; i += 2)\r
10 {\r
11 if((imm >> i) & 0x03)\r
12 break;\r
13 }\r
14\r
15 return i;\r
16}\r
17\r
18u32 arm_disect_imm_32bit(u32 imm, u32 *stores, u32 *rotations)\r
19{\r
20 u32 store_count = 0;\r
21 u32 left_shift = 0;\r
22\r
23 // Otherwise it'll return 0 things to store because it'll never\r
24 // find anything.\r
25 if(imm == 0)\r
26 {\r
27 rotations[0] = 0;\r
28 stores[0] = 0;\r
29 return 1;\r
30 }\r
31\r
32 // Find chunks of non-zero data at 2 bit alignments.\r
33 while(1)\r
34 {\r
35 left_shift = arm_imm_find_nonzero(imm, left_shift);\r
36\r
37 if(left_shift == 32)\r
38 {\r
39 // We've hit the end of the useful data.\r
40 return store_count;\r
41 }\r
42\r
43 // Hit the end, it might wrap back around to the beginning.\r
44 if(left_shift >= 24)\r
45 {\r
46 // Make a mask for the residual bits. IE, if we have\r
47 // 5 bits of data at the end we can wrap around to 3\r
48 // bits of data in the beginning. Thus the first\r
49 // thing, after being shifted left, has to be less\r
50 // than 111b, 0x7, or (1 << 3) - 1.\r
51 u32 top_bits = 32 - left_shift;\r
52 u32 residual_bits = 8 - top_bits;\r
53 u32 residual_mask = (1 << residual_bits) - 1;\r
54\r
55 if((store_count > 1) && (left_shift > 24) &&\r
56 ((stores[0] << (32 - rotations[0])) < residual_mask))\r
57 {\r
58 // Then we can throw out the last bit and tack it on\r
59 // to the first bit.\r
60 u32 initial_bits = rotations[0];\r
61 stores[0] = (stores[0] << (top_bits + (32 - rotations[0]))) |\r
62 ((imm >> left_shift) & 0xFF);\r
63 rotations[0] = top_bits;\r
64\r
65 return store_count;\r
66 }\r
67 else\r
68 {\r
69 // There's nothing to wrap over to in the beginning\r
70 stores[store_count] = (imm >> left_shift) & 0xFF;\r
71 rotations[store_count] = (32 - left_shift) & 0x1F;\r
72 return store_count + 1;\r
73 }\r
74 break;\r
75 }\r
76\r
77 stores[store_count] = (imm >> left_shift) & 0xFF;\r
78 rotations[store_count] = (32 - left_shift) & 0x1F;\r
79\r
80 store_count++;\r
81 left_shift += 8;\r
82 }\r
83}\r
84\r
85#define ror(value, shift) \\r
86 ((value) >> shift) | ((value) << (32 - shift)) \\r
87\r
88u32 arm_assemble_imm_32bit(u32 *stores, u32 *rotations, u32 store_count)\r
89{\r
90 u32 n = ror(stores[0], rotations[0]);\r
91 u32 i;\r
92 printf("%x : %x\n", stores[0], rotations[0]);\r
93\r
94 for(i = 1; i < store_count; i++)\r
95 {\r
96 printf("%x : %x\n", stores[i], rotations[i]);\r
97 n |= ror(stores[i], rotations[i]);\r
98 }\r
99\r
100 return n;\r
101}\r
102\r
103\r
104int main(int argc, char *argv[])\r
105{\r
106 u32 n = 0;\r
107 u32 stores[4];\r
108 u32 rotations[4];\r
109 u32 store_count;\r
110 u32 n2;\r
111\r
112 if(argc != 1)\r
113 {\r
114 n = strtoul(argv[1], NULL, 16);\r
115 store_count = arm_disect_imm_32bit(n, stores, rotations);\r
116 n2 = arm_assemble_imm_32bit(stores, rotations, store_count);\r
117 printf("%08x -> %08x (%d stores)\n", n, n2, store_count);\r
118 return 0;\r
119 }\r
120\r
121 do\r
122 {\r
123 store_count = arm_disect_imm_32bit(n, stores, rotations);\r
124 n2 = arm_assemble_imm_32bit(stores, rotations, store_count);\r
125 if(n != n2)\r
126 {\r
127 printf("Failure: %08x -/-> %08x\n", n, n2);\r
128 return -1;\r
129 }\r
130 n++;\r
131 } while(n != 0);\r
132\r
133 printf("Done!\n");\r
134 return 0;\r
135}\r