xref: /inferno-os/libinterp/decgen.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1 #include "lib9.h"
2 #include "isa.h"
3 #include "interp.h"
4 
5 void	decgen(int);
6 
7 /*
8  * Force intermediate dereference of $o(o(reg)) modes to ensure intermediate
9  * pointer is valid. This is required if you want secure memory.
10  */
11 #define	SOFTMMU		0
12 
13 void
main(void)14 main(void)
15 {
16 	int i;
17 
18 	print("/* Machine generated by decgen.c */\n\n");
19 
20 	print("#include \"lib9.h\"\n");
21 	print("#include \"isa.h\"\n");
22 	print("#include \"interp.h\"\n\n");
23 
24 	print("#define DIND(reg, xxx) (uchar*)((*(ulong*)(R.reg+R.PC->xxx.i.f))+R.PC->xxx.i.s)\n");
25 
26 	for(i = 0; i < 256; i++)
27 		decgen(i);
28 
29 	print("\nvoid	(*dec[])(void) =\n{\n");
30 	for(i = 0; i < 256; i++)
31 		print("\tD%.2uX%c\n", i, i != 255 ? ',' : ' ');
32 	print("};\n");
33 }
34 
35 void
decgen(int addr)36 decgen(int addr)
37 {
38 	int nodst;
39 
40 	print("static void\nD%.2uX(void)\n{\n", addr);
41 
42 	switch(USRC(addr)) {
43 	case AMP:
44 		print("\tR.s = R.MP+R.PC->s.ind;\n");
45 		break;
46 	case AFP:
47 		print("\tR.s = R.FP+R.PC->s.ind;\n");
48 		break;
49 	case AIMM:
50 		print("\tR.s = (uchar*)&R.PC->s.imm;\n");
51 		break;
52 	case AMP|AIND:
53 		if(SOFTMMU) {
54 			print("R.s = R.MP+R.PC->s.i.f\n");
55 			print("R.s = *(WORD**)R.s\n");
56 			print("R.s = (uchar*)R.s + R.PC->s.i.s\n");
57 		}
58 		else
59 			print("\tR.s = DIND(MP, s);\n");
60 		break;
61 	case AFP|AIND:
62 		if(SOFTMMU) {
63 			print("R.s = R.FP+R.PC->s.i.f\n");
64 			print("R.s = *(WORD**)R.s\n");
65 			print("R.s = (uchar*)R.s + R.PC->s.i.s\n");
66 		}
67 		else
68 			print("\tR.s = DIND(FP, s);\n");
69 		break;
70 	}
71 	nodst = 0;
72 	switch(UDST(addr)) {
73 	default:
74 		nodst = 1;
75 		break;
76 	case AMP:
77 		print("\tR.d = R.MP+R.PC->d.ind;\n");
78 		break;
79 	case AFP:
80 		print("\tR.d = R.FP+R.PC->d.ind;\n");
81 		break;
82 	case AIMM:
83 		print("\tR.d = (uchar*)&R.PC->d.imm;\n");
84 		break;
85 	case AMP|AIND:
86 		if(SOFTMMU) {
87 			print("R.d = R.MP+R.PC->d.i.f\n");
88 			print("R.d = *(WORD**)R.d\n");
89 			print("R.d = (uchar*)R.d + R.PC->d.i.s\n");
90 		}
91 		else
92 			print("\tR.d = DIND(MP, d);\n");
93 		break;
94 	case AFP|AIND:
95 		if(SOFTMMU) {
96 			print("R.d = R.FP+R.PC->d.i.f\n");
97 			print("R.d = *(WORD**)R.d\n");
98 			print("R.d = (uchar*)R.d + R.PC->d.i.s\n");
99 		}
100 		else
101 			print("\tR.d = DIND(FP, d);\n");
102 		break;
103 	}
104 
105 	if(nodst == 0)
106 	switch(addr&ARM) {
107 	case AXNON:
108 		print("\tR.m = R.d;\n");
109 		break;
110 	case AXIMM:
111 		print("\tR.t = (short)R.PC->reg;\n");
112 		print("\tR.m = &R.t;\n");
113 		break;
114 	case AXINF:
115 		print("\tR.m = R.FP+R.PC->reg;\n");
116 		break;
117 	case AXINM:
118 		print("\tR.m = R.MP+R.PC->reg;\n");
119 		break;
120 	}
121 	print("}\n");
122 }
123