summaryrefslogtreecommitdiff
path: root/gp2x/test
diff options
context:
space:
mode:
authornotaz2009-05-22 18:33:46 +0300
committernotaz2009-05-22 18:33:46 +0300
commita6c41a382bd4c79ab5d337536152717afcfa624f (patch)
treeddbdd9943e1f0f70dafcfb8453568ce47c8b50a0 /gp2x/test
parent90206450327a222607119b04f34cf1853faf37f8 (diff)
downloadpicogpsp-a6c41a382bd4c79ab5d337536152717afcfa624f.tar.gz
picogpsp-a6c41a382bd4c79ab5d337536152717afcfa624f.tar.bz2
picogpsp-a6c41a382bd4c79ab5d337536152717afcfa624f.zip
cleanup: remove cpu ctrl files, move tests
Diffstat (limited to 'gp2x/test')
-rw-r--r--gp2x/test/align_test.c48
-rw-r--r--gp2x/test/load_imm_test.c135
2 files changed, 183 insertions, 0 deletions
diff --git a/gp2x/test/align_test.c b/gp2x/test/align_test.c
new file mode 100644
index 0000000..b7b3512
--- /dev/null
+++ b/gp2x/test/align_test.c
@@ -0,0 +1,48 @@
+// Betting on GCC aligning this for efficiency.
+#include <stdio.h>
+
+int main()
+{
+ unsigned short int read_16 = 0xF1F2;
+ unsigned int read_32 = 0xF1F2F3F4;
+
+ unsigned short int write_16 = 0xF00D;
+ unsigned int write_32 = 0xF00DFEED;
+ // 16bit unsigned reads, we expect 0xF1F2 and 0xF20000F1
+ fprintf(stderr, "%04x %04x\n",
+ *((unsigned short int *)((char *)&read_16)),
+ *((unsigned short int *)((char *)&read_16 + 1)));
+
+ // 16bit signed reads, we expect 0xFFFFF1F2 and 0xFFFFFFF1
+ fprintf(stderr, "%04x %04x\n",
+ *((short int *)((char *)&read_16)),
+ *((short int *)((char *)&read_16 + 1)));
+
+ // 32bit reads, we expect 0xF1F2F3F4, 0xF4F1F2F3, 0xF3F4F1F2,
+ // and 0xF2F3F4F1
+
+ fprintf(stderr, "%08x %08x %08x %08x\n",
+ *((int *)((char *)&read_32)),
+ *((int *)((char *)&read_32 + 1)),
+ *((int *)((char *)&read_32 + 2)),
+ *((int *)((char *)&read_32 + 3)));
+
+ // 16bit writes, we expect write_16 to remain 0xF00D
+
+ *((short int *)((char *)&write_16)) = 0xF00D;
+ *((short int *)((char *)&write_16) + 1) = 0xF00D;
+
+ fprintf(stderr, "%04x\n", write_16);
+
+ // 32bit writes, we expect write_32 to remain 0xF00DFEED
+
+ *((int *)((char *)&write_16)) = 0xF00DFEED;
+ *((int *)((char *)&write_16) + 1) = 0xF00DFEED;
+ *((int *)((char *)&write_16) + 2) = 0xF00DFEED;
+ *((int *)((char *)&write_16) + 3) = 0xF00DFEED;
+
+ fprintf(stderr, "%08x\n", write_32);
+
+ return 0;
+}
+
diff --git a/gp2x/test/load_imm_test.c b/gp2x/test/load_imm_test.c
new file mode 100644
index 0000000..b850d56
--- /dev/null
+++ b/gp2x/test/load_imm_test.c
@@ -0,0 +1,135 @@
+#include <stdio.h>
+
+typedef unsigned int u32;
+
+u32 arm_imm_find_nonzero(u32 imm, u32 start_bit)
+{
+ u32 i;
+
+ for(i = start_bit; i < 32; i += 2)
+ {
+ if((imm >> i) & 0x03)
+ break;
+ }
+
+ return i;
+}
+
+u32 arm_disect_imm_32bit(u32 imm, u32 *stores, u32 *rotations)
+{
+ u32 store_count = 0;
+ u32 left_shift = 0;
+
+ // Otherwise it'll return 0 things to store because it'll never
+ // find anything.
+ if(imm == 0)
+ {
+ rotations[0] = 0;
+ stores[0] = 0;
+ return 1;
+ }
+
+ // Find chunks of non-zero data at 2 bit alignments.
+ while(1)
+ {
+ left_shift = arm_imm_find_nonzero(imm, left_shift);
+
+ if(left_shift == 32)
+ {
+ // We've hit the end of the useful data.
+ return store_count;
+ }
+
+ // Hit the end, it might wrap back around to the beginning.
+ if(left_shift >= 24)
+ {
+ // Make a mask for the residual bits. IE, if we have
+ // 5 bits of data at the end we can wrap around to 3
+ // bits of data in the beginning. Thus the first
+ // thing, after being shifted left, has to be less
+ // than 111b, 0x7, or (1 << 3) - 1.
+ u32 top_bits = 32 - left_shift;
+ u32 residual_bits = 8 - top_bits;
+ u32 residual_mask = (1 << residual_bits) - 1;
+
+ if((store_count > 1) && (left_shift > 24) &&
+ ((stores[0] << (32 - rotations[0])) < residual_mask))
+ {
+ // Then we can throw out the last bit and tack it on
+ // to the first bit.
+ u32 initial_bits = rotations[0];
+ stores[0] = (stores[0] << (top_bits + (32 - rotations[0]))) |
+ ((imm >> left_shift) & 0xFF);
+ rotations[0] = top_bits;
+
+ return store_count;
+ }
+ else
+ {
+ // There's nothing to wrap over to in the beginning
+ stores[store_count] = (imm >> left_shift) & 0xFF;
+ rotations[store_count] = (32 - left_shift) & 0x1F;
+ return store_count + 1;
+ }
+ break;
+ }
+
+ stores[store_count] = (imm >> left_shift) & 0xFF;
+ rotations[store_count] = (32 - left_shift) & 0x1F;
+
+ store_count++;
+ left_shift += 8;
+ }
+}
+
+#define ror(value, shift) \
+ ((value) >> shift) | ((value) << (32 - shift)) \
+
+u32 arm_assemble_imm_32bit(u32 *stores, u32 *rotations, u32 store_count)
+{
+ u32 n = ror(stores[0], rotations[0]);
+ u32 i;
+ printf("%x : %x\n", stores[0], rotations[0]);
+
+ for(i = 1; i < store_count; i++)
+ {
+ printf("%x : %x\n", stores[i], rotations[i]);
+ n |= ror(stores[i], rotations[i]);
+ }
+
+ return n;
+}
+
+
+int main(int argc, char *argv[])
+{
+ u32 n = 0;
+ u32 stores[4];
+ u32 rotations[4];
+ u32 store_count;
+ u32 n2;
+
+ if(argc != 1)
+ {
+ n = strtoul(argv[1], NULL, 16);
+ store_count = arm_disect_imm_32bit(n, stores, rotations);
+ n2 = arm_assemble_imm_32bit(stores, rotations, store_count);
+ printf("%08x -> %08x (%d stores)\n", n, n2, store_count);
+ return 0;
+ }
+
+ do
+ {
+ store_count = arm_disect_imm_32bit(n, stores, rotations);
+ n2 = arm_assemble_imm_32bit(stores, rotations, store_count);
+ if(n != n2)
+ {
+ printf("Failure: %08x -/-> %08x\n", n, n2);
+ return -1;
+ }
+ n++;
+ } while(n != 0);
+
+ printf("Done!\n");
+ return 0;
+}