summaryrefslogtreecommitdiff
path: root/libinterp/decgen.c
diff options
context:
space:
mode:
Diffstat (limited to 'libinterp/decgen.c')
-rw-r--r--libinterp/decgen.c122
1 files changed, 122 insertions, 0 deletions
diff --git a/libinterp/decgen.c b/libinterp/decgen.c
new file mode 100644
index 00000000..f81749c7
--- /dev/null
+++ b/libinterp/decgen.c
@@ -0,0 +1,122 @@
+#include "lib9.h"
+#include "isa.h"
+#include "interp.h"
+
+void decgen(int);
+
+/*
+ * Force intermediate dereference of $o(o(reg)) modes to ensure intermediate
+ * pointer is valid. This is required if you want secure memory.
+ */
+#define SOFTMMU 0
+
+void
+main(void)
+{
+ int i;
+
+ print("/* Machine generated by decgen.c */\n\n");
+
+ print("#include \"lib9.h\"\n");
+ print("#include \"isa.h\"\n");
+ print("#include \"interp.h\"\n\n");
+
+ print("#define DIND(reg, xxx) (uchar*)((*(ulong*)(R.reg+R.PC->xxx.i.f))+R.PC->xxx.i.s)\n");
+
+ for(i = 0; i < 256; i++)
+ decgen(i);
+
+ print("\nvoid (*dec[])(void) =\n{\n");
+ for(i = 0; i < 256; i++)
+ print("\tD%.2uX%c\n", i, i != 255 ? ',' : ' ');
+ print("};\n");
+}
+
+void
+decgen(int addr)
+{
+ int nodst;
+
+ print("static void\nD%.2uX(void)\n{\n", addr);
+
+ switch(USRC(addr)) {
+ case AMP:
+ print("\tR.s = R.MP+R.PC->s.ind;\n");
+ break;
+ case AFP:
+ print("\tR.s = R.FP+R.PC->s.ind;\n");
+ break;
+ case AIMM:
+ print("\tR.s = (uchar*)&R.PC->s.imm;\n");
+ break;
+ case AMP|AIND:
+ if(SOFTMMU) {
+ print("R.s = R.MP+R.PC->s.i.f\n");
+ print("R.s = *(WORD**)R.s\n");
+ print("R.s = (uchar*)R.s + R.PC->s.i.s\n");
+ }
+ else
+ print("\tR.s = DIND(MP, s);\n");
+ break;
+ case AFP|AIND:
+ if(SOFTMMU) {
+ print("R.s = R.FP+R.PC->s.i.f\n");
+ print("R.s = *(WORD**)R.s\n");
+ print("R.s = (uchar*)R.s + R.PC->s.i.s\n");
+ }
+ else
+ print("\tR.s = DIND(FP, s);\n");
+ break;
+ }
+ nodst = 0;
+ switch(UDST(addr)) {
+ default:
+ nodst = 1;
+ break;
+ case AMP:
+ print("\tR.d = R.MP+R.PC->d.ind;\n");
+ break;
+ case AFP:
+ print("\tR.d = R.FP+R.PC->d.ind;\n");
+ break;
+ case AIMM:
+ print("\tR.d = (uchar*)&R.PC->d.imm;\n");
+ break;
+ case AMP|AIND:
+ if(SOFTMMU) {
+ print("R.d = R.MP+R.PC->d.i.f\n");
+ print("R.d = *(WORD**)R.d\n");
+ print("R.d = (uchar*)R.d + R.PC->d.i.s\n");
+ }
+ else
+ print("\tR.d = DIND(MP, d);\n");
+ break;
+ case AFP|AIND:
+ if(SOFTMMU) {
+ print("R.d = R.FP+R.PC->d.i.f\n");
+ print("R.d = *(WORD**)R.d\n");
+ print("R.d = (uchar*)R.d + R.PC->d.i.s\n");
+ }
+ else
+ print("\tR.d = DIND(FP, d);\n");
+ break;
+ }
+
+ if(nodst == 0)
+ switch(addr&ARM) {
+ case AXNON:
+ print("\tR.m = R.d;\n");
+ break;
+ case AXIMM:
+ print("\tR.t = (short)R.PC->reg;\n");
+ print("\tR.m = &R.t;\n");
+ break;
+ case AXINF:
+ print("\tR.m = R.FP+R.PC->reg;\n");
+ break;
+ case AXINM:
+ print("\tR.m = R.MP+R.PC->reg;\n");
+ break;
+ }
+ print("}\n");
+}