+extern void putc(unsigned char c);
+
+void puts(unsigned char *s)
+{
+ while (*s)
+ putc(*(s++));
+}
+
+void puthex(unsigned int x)
+{
+ unsigned char *hex = "0123456789ABCDEF";
+ int i;
+
+ for (i = 7; i >= 0; i--)
+ putc(hex[(x >> (i * 4)) & 0xF]);
+}
+
+#define putchar putc
+#include "ack.c"
+#include "j4cbo.c"
+#include "corecurse.c"
+
+int fact(int n)
+{
+ if (n == 0)
+ return 1;
+ else
+ return n * fact(n-1);
+}
+
+void facttest()
+{
+ if (fact(10) != 3628800)
+ puts("FAIL\n");
+ else
+ puts("PASS\n");
+}
+
+struct tests {
+ char *name;
+ void (*test)();
+};
+
+extern int ldm_bonehead();
+
+__asm__(
+".globl ldm_bonehead\n"
+"ldm_bonehead:;"
+"mov r3, lr;"
+"bl 1f;"
+"nop;"
+"nop;"
+"nop;"
+"nop;"
+"nop;"
+"nop;"
+"nop;"
+"nop;"
+"nop;"
+"mov pc, r3\n;"
+"1:\n"
+"ldr r2, =0x00002FE0;"
+"ldr r1, =0x0000004C;"
+"mov ip, sp;"
+"stmdb sp!, {fp, ip, lr, pc};"
+"mov r0, #0x00880000;"
+"ldmia sp, {fp, sp, pc};"
+"mul r0, r1, r2;"
+"nop;"
+"nop;\n"
+);
+
+void ldm_tester()
+{
+ int x = ldm_bonehead();
+ if (x != 0x00880000)
+ {
+ puts("FAIL: result was ");
+ puthex(x);
+ puts("\n");
+ } else
+ puts("PASS\n");
+}
+
+struct tests tlist[] = {
+ {"ldm pc/mul", ldm_tester},
+ {"fact", facttest},
+ {"j4cbo", j4cbo},
+ {"ack", acktest},
+ {"corecurse", corecurse},
+ {0, 0}};
+
+int main()
+{
+ struct tests *t;
+
+ puts("Testbench running\n");
+
+ for (t = tlist; t->name; t++)
+ {
+ puts("Running ");
+ puts(t->name);
+ puts(": ");
+ t->test();
+ }
+ puts("Done!\n");
+
+ return 0;
+}