59 int p, u, s, w,
load, r, n_regs, i, x;
61 if ((opcode & 0x0e000000) != 0x08000000) {
62 fprintf(stderr,
"opcode 0x%08"PRIx32
" is not an ldm/stm\n",
67 r = (opcode >> 16) & 15;
68 p = opcode & 0x01000000? 1 : 0;
69 u = opcode & 0x00800000? 1 : 0;
70 s = opcode & 0x00400000? 1 : 0;
71 w = opcode & 0x00200000? 1 : 0;
72 load = opcode & 0x00100000? 1 : 0;
75 if (opcode & (1 << i))
81 fprintf(stderr,
"opcode 0x%08"PRIx32
" has no registers set\n",
87 fprintf(stderr,
"opcode 0x%08"PRIx32
" has s-bit set\n", opcode);
92 fprintf(stderr,
"opcode 0x%08"PRIx32
" has r=15\n", opcode);
96 printf(
"\nvoid arm_instr_multi_0x%08"PRIx32
"(struct cpu *cpu," 97 " struct arm_instr_call *ic) {\n", opcode);
99 printf(
"\tunsigned char *page;\n");
100 printf(
"\tuint32_t addr = cpu->cd.arm.r[%i];\n", r);
102 if (!load && opcode & 0x8000) {
103 printf(
"\tuint32_t tmp_pc = ((size_t)ic - (size_t)\n\t" 104 " cpu->cd.arm.cur_ic_page) / sizeof(struct " 106 "\ttmp_pc = ((cpu->pc & ~((ARM_IC_ENTRIES_PER_PAGE-1)" 107 "\n\t << ARM_INSTR_ALIGNMENT_SHIFT)))\n" 108 "\t + (tmp_pc << ARM_INSTR_ALIGNMENT_SHIFT) + 12;\n");
112 printf(
"\taddr %s 4;\n", u?
"+=" :
"-=");
114 printf(
"\tpage = cpu->cd.arm.host_%s[addr >> 12];\n",
115 load?
"load" :
"store");
117 printf(
"\taddr &= 0xffc;\n");
123 printf(
"addr >= 0x%x && ", 4*(n_regs-1));
127 printf(
"addr <= 0x%x && ", 0x1000 - 4*n_regs);
131 printf(
"addr >= 0x%x && ", 4*(n_regs-1));
135 printf(
"addr <= 0x%x && ", 0x1000 - 4*n_regs);
138 printf(
"page != NULL) {\n");
140 printf(
"\t\tuint32_t *p = (uint32_t *) (page + addr);\n");
144 for (i=0; i<=15; i++) {
145 if (!(opcode & (1 << i)))
148 if (load && w && i == r) {
152 printf(
"\t\tcpu->pc = p[%i];\n", x);
154 printf(
"\t\tcpu->cd.arm.r[%i] = " 158 printf(
"\t\tp[%i] = tmp_pc;\n", x);
160 printf(
"\t\tp[%i] = cpu->cd.arm.r" 169 for (i=0; i<=15; i++) {
170 if (!(opcode & (1 << i)))
175 if (load && w && i == r) {
179 printf(
"\t\tcpu->pc = p[%i];\n", x);
181 printf(
"\t\tcpu->cd.arm.r[%i] = " 185 printf(
"\t\tp[%i] = tmp_pc;\n", x);
187 printf(
"\t\tp[%i] = " 188 "cpu->cd.arm.r[%i];\n", x, i);
194 printf(
"\t\tcpu->cd.arm.r[%i] %s %i;\n",
195 r, u?
"+=" :
"-=", 4*n_regs);
197 if (load && opcode & 0x8000) {
198 printf(
"\t\tquick_pc_to_pointers(cpu);\n");
201 printf(
"\t} else\n");
202 printf(
"\t\tinstr(bdt_%s)(cpu, ic);\n", load?
"load" :
"store");
204 printf(
"}\nY(multi_0x%08"PRIx32
")\n", opcode);
223 int main(
int argc,
char *argv[])
229 fprintf(stderr,
"usage: %s opcode [..]\n", argv[0]);
233 printf(
"\n/* AUTOMATICALLY GENERATED! Do not edit. */\n\n" 234 "#include <stdio.h>\n" 235 "#include <stdlib.h>\n" 236 "#include \"cpu.h\"\n" 237 "#include \"misc.h\"\n" 238 "#define DYNTRANS_PC_TO_POINTERS arm_pc_to_pointers\n" 239 "#include \"quick_pc_to_pointers.h\"\n" 240 "#include \"arm_tmphead_1.h\"\n" 241 "\n#define instr(x) arm_instr_ ## x\n");
242 printf(
"extern void arm_pc_to_pointers(struct cpu *);\n");
243 printf(
"extern void arm_instr_nop(struct cpu *, " 244 "struct arm_instr_call *);\n");
245 printf(
"extern void arm_instr_bdt_load(struct cpu *, " 246 "struct arm_instr_call *);\n");
247 printf(
"extern void arm_instr_bdt_store(struct cpu *, " 248 "struct arm_instr_call *);\n");
252 for (i=1; i<argc; i++)
256 for (j=0; j<256; j++) {
258 for (i=1; i<argc; i++) {
259 zz = strtol(argv[i], NULL, 0);
260 zz = ((zz & 0x00800000) >> 16)
261 |((zz & 0x00100000) >> 14)
262 |((zz & 0x00040000) >> 13)
263 |((zz & 0x00010000) >> 12)
264 |((zz & 0x00000100) >> 5)
265 |((zz & 0x00000040) >> 4)
266 |((zz & 0x00000010) >> 3)
267 |((zz & 0x00000004) >> 2);
271 printf(
"\nuint32_t multi_opcode_%i[%i] = {\n", j, n+1);
272 for (i=1; i<argc; i++) {
273 zz = zz0 = strtol(argv[i], NULL, 0);
274 zz = ((zz & 0x00800000) >> 16)
275 |((zz & 0x00100000) >> 14)
276 |((zz & 0x00040000) >> 13)
277 |((zz & 0x00010000) >> 12)
278 |((zz & 0x00000100) >> 5)
279 |((zz & 0x00000040) >> 4)
280 |((zz & 0x00000010) >> 3)
281 |((zz & 0x00000004) >> 2);
283 printf(
"\t0x%08x,\n", zz0);
289 for (j=0; j<256; j++) {
291 for (i=1; i<argc; i++) {
292 zz = strtol(argv[i], NULL, 0);
293 zz = ((zz & 0x00800000) >> 16)
294 |((zz & 0x00100000) >> 14)
295 |((zz & 0x00040000) >> 13)
296 |((zz & 0x00010000) >> 12)
297 |((zz & 0x00000100) >> 5)
298 |((zz & 0x00000040) >> 4)
299 |((zz & 0x00000010) >> 3)
300 |((zz & 0x00000004) >> 2);
307 printf(
"void (*multi_opcode_f_%i[%i])(struct cpu *," 308 " struct arm_instr_call *) = {\n", j, n*16);
309 for (i=1; i<argc; i++) {
310 zz = zz0 = strtol(argv[i], NULL, 0);
311 zz = ((zz & 0x00800000) >> 16)
312 |((zz & 0x00100000) >> 14)
313 |((zz & 0x00040000) >> 13)
314 |((zz & 0x00010000) >> 12)
315 |((zz & 0x00000100) >> 5)
316 |((zz & 0x00000040) >> 4)
317 |((zz & 0x00000010) >> 3)
318 |((zz & 0x00000004) >> 2);
320 printf(
"\tarm_instr_multi_0x%08x__eq,\n", zz0);
321 printf(
"\tarm_instr_multi_0x%08x__ne,\n", zz0);
322 printf(
"\tarm_instr_multi_0x%08x__cs,\n", zz0);
323 printf(
"\tarm_instr_multi_0x%08x__cc,\n", zz0);
324 printf(
"\tarm_instr_multi_0x%08x__mi,\n", zz0);
325 printf(
"\tarm_instr_multi_0x%08x__pl,\n", zz0);
326 printf(
"\tarm_instr_multi_0x%08x__vs,\n", zz0);
327 printf(
"\tarm_instr_multi_0x%08x__vc,\n", zz0);
328 printf(
"\tarm_instr_multi_0x%08x__hi,\n", zz0);
329 printf(
"\tarm_instr_multi_0x%08x__ls,\n", zz0);
330 printf(
"\tarm_instr_multi_0x%08x__ge,\n", zz0);
331 printf(
"\tarm_instr_multi_0x%08x__lt,\n", zz0);
332 printf(
"\tarm_instr_multi_0x%08x__gt,\n", zz0);
333 printf(
"\tarm_instr_multi_0x%08x__le,\n", zz0);
334 printf(
"\tarm_instr_multi_0x%08x,\n", zz0);
335 printf(
"\tarm_instr_nop,\n");
342 printf(
"\nuint32_t *multi_opcode[256] = {\n");
343 for (i=0; i<256; i++) {
344 printf(
" multi_opcode_%i,", i);
350 printf(
"\nvoid (**multi_opcode_f[256])(struct cpu *," 351 " struct arm_instr_call *) = {\n");
352 for (i=0; i<256; i++) {
354 printf(
" multi_opcode_f_%i,", i);
int main(int argc, char *argv[])
void generate_opcode(uint32_t opcode)
void load(FILE *fh, unsigned char *ptr, unsigned long sz)