25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: generate_arm_multi.c,v 1.6 2005/10/26 14:37:03 debug Exp $ |
* $Id: generate_arm_multi.c,v 1.11 2005/11/19 18:53:07 debug Exp $ |
29 |
* |
* |
30 |
* Generation of commonly used ARM load/store multiple instructions. |
* Generation of commonly used ARM load/store multiple instructions. |
31 |
|
* |
32 |
* The main idea is to first check whether a load/store would be possible |
* The main idea is to first check whether a load/store would be possible |
33 |
* without going outside a page, and if so, use the host_load or _store |
* without going outside a page, and if so, use the host_load or _store |
34 |
* arrays for quick access to emulated RAM. Otherwise, fall back to using |
* arrays for quick access to emulated RAM. Otherwise, fall back to using |
94 |
exit(1); |
exit(1); |
95 |
} |
} |
96 |
|
|
97 |
printf("\nX(multi_0x%08x) {\n", opcode); |
printf("\nvoid arm_instr_multi_0x%08x(struct cpu *cpu," |
98 |
|
" struct arm_instr_call *ic) {\n", opcode); |
99 |
|
|
100 |
printf("\tunsigned char *page;\n"); |
printf("\tunsigned char *page;\n"); |
101 |
printf("\tuint32_t addr = cpu->cd.arm.r[%i];\n", r); |
printf("\tuint32_t addr = cpu->cd.arm.r[%i];\n", r); |
104 |
printf("\tuint32_t tmp_pc = ((size_t)ic - (size_t)\n\t" |
printf("\tuint32_t tmp_pc = ((size_t)ic - (size_t)\n\t" |
105 |
" cpu->cd.arm.cur_ic_page) / sizeof(struct " |
" cpu->cd.arm.cur_ic_page) / sizeof(struct " |
106 |
"arm_instr_call);\n" |
"arm_instr_call);\n" |
107 |
"\ttmp_pc = ((cpu->cd.arm.r[ARM_PC] & " |
"\ttmp_pc = ((cpu->pc & ~((ARM_IC_ENTRIES_PER_PAGE-1)" |
|
"~((ARM_IC_ENTRIES_PER_PAGE-1)" |
|
108 |
"\n\t << ARM_INSTR_ALIGNMENT_SHIFT)))\n" |
"\n\t << ARM_INSTR_ALIGNMENT_SHIFT)))\n" |
109 |
"\t + (tmp_pc << ARM_INSTR_ALIGNMENT_SHIFT) + 12;\n"); |
"\t + (tmp_pc << ARM_INSTR_ALIGNMENT_SHIFT) + 12;\n"); |
110 |
} |
} |
148 |
|
|
149 |
if (load && w && i == r) { |
if (load && w && i == r) { |
150 |
/* Skip the load if we're using writeback. */ |
/* Skip the load if we're using writeback. */ |
151 |
} else if (load) |
} else if (load) { |
152 |
printf("\t\tcpu->cd.arm.r[%i] = p[%i];\n", i, x); |
if (i == 15) |
153 |
else { |
printf("\t\tcpu->pc = p[%i];\n", x); |
154 |
|
else |
155 |
|
printf("\t\tcpu->cd.arm.r[%i] = " |
156 |
|
"p[%i];\n", i, x); |
157 |
|
} else { |
158 |
if (i == 15) |
if (i == 15) |
159 |
printf("\t\tp[%i] = tmp_pc;\n", x); |
printf("\t\tp[%i] = tmp_pc;\n", x); |
160 |
else |
else |
161 |
printf("\t\tp[%i] = cpu->cd.arm.r[%i];\n", x, i); |
printf("\t\tp[%i] = cpu->cd.arm.r" |
162 |
|
"[%i];\n", x, i); |
163 |
} |
} |
164 |
|
|
165 |
x ++; |
x ++; |
175 |
|
|
176 |
if (load && w && i == r) { |
if (load && w && i == r) { |
177 |
/* Skip the load if we're using writeback. */ |
/* Skip the load if we're using writeback. */ |
178 |
} else if (load) |
} else if (load) { |
179 |
printf("\t\tcpu->cd.arm.r[%i] = p[%i];\n", i, x); |
if (i == 15) |
180 |
else { |
printf("\t\tcpu->pc = p[%i];\n", x); |
181 |
|
else |
182 |
|
printf("\t\tcpu->cd.arm.r[%i] = " |
183 |
|
"p[%i];\n", i, x); |
184 |
|
} else { |
185 |
if (i == 15) |
if (i == 15) |
186 |
printf("\t\tp[%i] = tmp_pc;\n", x); |
printf("\t\tp[%i] = tmp_pc;\n", x); |
187 |
else |
else |
188 |
printf("\t\tp[%i] = cpu->cd.arm.r[%i];\n", x, i); |
printf("\t\tp[%i] = " |
189 |
|
"cpu->cd.arm.r[%i];\n", x, i); |
190 |
} |
} |
191 |
} |
} |
192 |
} |
} |
196 |
r, u? "+=" : "-=", 4*n_regs); |
r, u? "+=" : "-=", 4*n_regs); |
197 |
|
|
198 |
if (load && opcode & 0x8000) { |
if (load && opcode & 0x8000) { |
199 |
printf("\t\tcpu->pc = cpu->cd.arm.r[15];\n" |
printf("\t\tquick_pc_to_pointers(cpu);\n"); |
|
"\t\tarm_pc_to_pointers(cpu);\n"); |
|
200 |
} |
} |
201 |
|
|
202 |
printf("\t} else\n"); |
printf("\t} else\n"); |
231 |
exit(1); |
exit(1); |
232 |
} |
} |
233 |
|
|
234 |
printf("\n/* AUTOMATICALLY GENERATED! Do not edit. */\n\n"); |
printf("\n/* AUTOMATICALLY GENERATED! Do not edit. */\n\n" |
235 |
|
"#include <stdio.h>\n" |
236 |
|
"#include <stdlib.h>\n" |
237 |
|
"#include \"cpu.h\"\n" |
238 |
|
"#include \"misc.h\"\n" |
239 |
|
"#include \"arm_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_instr_nop(struct cpu *, " |
243 |
|
"struct arm_instr_call *);\n"); |
244 |
|
printf("extern void arm_instr_bdt_load(struct cpu *, " |
245 |
|
"struct arm_instr_call *);\n"); |
246 |
|
printf("extern void arm_instr_bdt_store(struct cpu *, " |
247 |
|
"struct arm_instr_call *);\n"); |
248 |
|
printf("\n\n"); |
249 |
|
|
250 |
/* Generate the opcode functions: */ |
/* Generate the opcode functions: */ |
251 |
for (i=1; i<argc; i++) |
for (i=1; i<argc; i++) |