diff options
| author | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
|---|---|---|
| committer | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
| commit | 37da2899f40661e3e9631e497da8dc59b971cbd0 (patch) | |
| tree | cbc6d4680e347d906f5fa7fca73214418741df72 /libinterp/decgen.c | |
| parent | 54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff) | |
20060303a
Diffstat (limited to 'libinterp/decgen.c')
| -rw-r--r-- | libinterp/decgen.c | 122 |
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"); +} |
