1 #include <stdio.h>
2 #include <string.h>
3 
4 #define NUM_OF_ARRAY(x) (sizeof(x) / sizeof(x[0]))
5 
genVsibSub(bool isJIT,const char * name,const char * tbl[],size_t tblSize)6 void genVsibSub(bool isJIT, const char *name, const char *tbl[], size_t tblSize)
7 {
8 	for (size_t i = 0; i < tblSize; i++) {
9 		if (isJIT) {
10 			printf("%s (ymm7, ptr[", name);
11 		} else {
12 			printf("%s ymm7, [", name);
13 		}
14 		printf("%s", tbl[i]);
15 		if (isJIT) {
16 			printf("], ymm4); dump();\n");
17 		} else {
18 			printf("], ymm4\n");
19 		}
20 	}
21 }
genVsib(bool isJIT)22 void genVsib(bool isJIT)
23 {
24 	if (isJIT) puts("void genVsib() {");
25 	const char *vm32xTbl[] = {
26 		"xmm0",
27 		"xmm0 * 1",
28 		"xmm0 + 4",
29 		"xmm0 + eax",
30 		"xmm0 * 4 + ecx",
31 		"xmm3 * 8 + edi + 123",
32 		"xmm2 * 2 + 5",
33 		"eax + xmm0",
34 		"esp + xmm4",
35 	};
36 	const char *vm32yTbl[] = {
37 		"ymm0",
38 		"ymm0 * 1",
39 		"ymm0 + 4",
40 		"ymm0 + eax",
41 		"ymm0 * 4 + ecx",
42 		"ymm3 * 8 + edi + 123",
43 		"ymm2 * 2 + 5",
44 		"eax + ymm0",
45 		"esp + ymm4",
46 	};
47 	genVsibSub(isJIT, "vgatherdpd", vm32xTbl, NUM_OF_ARRAY(vm32xTbl));
48 	genVsibSub(isJIT, "vgatherqpd", vm32yTbl, NUM_OF_ARRAY(vm32yTbl));
49 #ifdef XBYAK64
50 	const char *vm32x64Tbl[] = {
51 		"xmm0 + r11",
52 		"r13 + xmm15",
53 		"123 + rsi + xmm2 * 4",
54 	};
55 	genVsibSub(isJIT, "vgatherdpd", vm32x64Tbl, NUM_OF_ARRAY(vm32x64Tbl));
56 #endif
57 	if (isJIT) puts("}");
58 }
59 
genAddress(bool isJIT,const char regTbl[][5],size_t regTblNum)60 void genAddress(bool isJIT, const char regTbl[][5], size_t regTblNum)
61 {
62 	int count = 0;
63 	int funcNum = 1;
64 	if (isJIT) {
65 		puts("void gen0(){");
66 	}
67 	for (size_t i = 0; i < regTblNum + 1; i++) {
68 		const char *base = regTbl[i];
69 		for (size_t j = 0; j < regTblNum + 1; j++) {
70 			if (j == 4) continue; /* esp is not index register */
71 			const char *index = regTbl[j];
72 			static const int scaleTbl[] = { 0, 1, 2, 4, 8 };
73 			for (size_t k = 0; k < NUM_OF_ARRAY(scaleTbl); k++) {
74 				int scale = scaleTbl[k];
75 				static const int dispTbl[] = { 0, 1, 1000, -1, -1000 };
76 				for (size_t m = 0; m < NUM_OF_ARRAY(dispTbl); m++) {
77 					int disp = dispTbl[m];
78 					bool isFirst = true;
79 					if (isJIT) {
80 						printf("mov (ecx, ptr[");
81 					} else {
82 						printf("mov ecx, [");
83 					}
84 					if (i < regTblNum) {
85 						printf("%s", base);
86 						isFirst = false;
87 					}
88 					if (j < regTblNum) {
89 						if (!isFirst) putchar('+');
90 						printf("%s", index);
91 						if (scale) printf("*%d", scale);
92 						isFirst = false;
93 					}
94 					if (isFirst) {
95 						if (isJIT) printf("(void*)");
96 						printf("0x%08X", disp);
97 					} else {
98 						if (disp >= 0) {
99 							putchar('+');
100 						}
101 						printf("%d", disp);
102 						isFirst = false;
103 					}
104 					if (isJIT) {
105 						printf("]); dump();\n");
106 					} else {
107 						printf("]\n");
108 					}
109 					if (isJIT) {
110 						count++;
111 						if ((count % 100) == 0) {
112 							printf("}\n    void gen%d(){\n", funcNum++);
113 						}
114 					}
115 				}
116 			}
117 		}
118 	}
119 	if (isJIT) puts("}");
120 	genVsib(isJIT);
121 	if (isJIT) {
122 		printf("void gen(){\n");
123 		for (int i = 0; i < funcNum; i++) {
124 			printf("   gen%d();\n", i);
125 		}
126 		puts("genVsib();");
127 		printf("}\n");
128 	}
129 }
130 
main(int argc,char * argv[])131 int main(int argc, char *argv[])
132 {
133 	argc--, argv++;
134 	bool phase = argc > 0 && strcmp(*argv, "1") == 0;
135 	bool isJIT = (argc > 1);
136 	fprintf(stderr, "phase:%c %s\n", phase ? '1' : '2', isJIT ? "jit" : "asm");
137 	if (phase) {
138 		fprintf(stderr, "32bit reg\n");
139 		static const char reg32Tbl[][5] = {
140 			"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
141 #ifdef XBYAK64
142 			"r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d",
143 #endif
144 		};
145 		genAddress(isJIT, reg32Tbl, NUM_OF_ARRAY(reg32Tbl));
146 	} else {
147 #ifdef XBYAK64
148 		fprintf(stderr, "64bit reg\n");
149 		static const char reg64Tbl[][5] = {
150 			"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
151 		};
152 		genAddress(isJIT, reg64Tbl, NUM_OF_ARRAY(reg64Tbl));
153 #endif
154 	}
155 }
156