25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: generate_arm_r.c,v 1.1 2005/10/09 21:32:07 debug Exp $ |
* $Id: generate_arm_r.c,v 1.5 2005/12/26 14:14:27 debug Exp $ |
29 |
* |
* |
30 |
* Generate functions for computing "reg" operands. |
* Generate functions for computing "reg" operands. |
31 |
*/ |
*/ |
34 |
#include <stdlib.h> |
#include <stdlib.h> |
35 |
|
|
36 |
|
|
|
#if 0 |
|
|
/* |
|
|
* update_c is set if the C flag should be updated with the last shifted/ |
|
|
* rotated bit. |
|
|
*/ |
|
|
uint32_t R(struct cpu *cpu, struct arm_instr_call *ic, |
|
|
uint32_t iword, int update_c) |
|
|
{ |
|
|
int rm = iword & 15, lastbit, t, c; |
|
|
uint32_t tmp = cpu->cd.arm.r[rm]; |
|
|
|
|
|
case 2: /* lsr #c (c = 1..32) */ |
|
|
if (c == 0) |
|
|
c = 32; |
|
|
if (update_c) { |
|
|
lastbit = ((uint64_t)tmp >> (c-1)) & 1; |
|
|
} |
|
|
tmp = (uint64_t)tmp >> c; |
|
|
break; |
|
|
case 3: /* lsr Rc */ |
|
|
c = cpu->cd.arm.r[c >> 1] & 255; |
|
|
if (c >= 32) |
|
|
c = 33; |
|
|
if (update_c) { |
|
|
if (c == 0) |
|
|
update_c = 0; |
|
|
else |
|
|
lastbit = ((uint64_t)tmp >> (c-1)) & 1; |
|
|
} |
|
|
tmp = (uint64_t)tmp >> c; |
|
|
break; |
|
|
case 4: /* asr #c (c = 1..32) */ |
|
|
if (c == 0) |
|
|
c = 32; |
|
|
if (update_c) { |
|
|
lastbit = ((int64_t)(int32_t)tmp >> (c-1)) & 1; |
|
|
} |
|
|
tmp = (int64_t)(int32_t)tmp >> c; |
|
|
break; |
|
|
case 5: /* asr Rc */ |
|
|
c = cpu->cd.arm.r[c >> 1] & 255; |
|
|
if (c >= 32) |
|
|
c = 33; |
|
|
if (update_c) { |
|
|
if (c == 0) |
|
|
update_c = 0; |
|
|
else |
|
|
lastbit = ((int64_t)(int32_t)tmp >> (c-1)) & 1; |
|
|
} |
|
|
tmp = (int64_t)(int32_t)tmp >> c; |
|
|
break; |
|
|
case 6: /* ror 1..31 */ |
|
|
if (c == 0) { |
|
|
fatal("TODO: rrx\n"); |
|
|
exit(1); |
|
|
} |
|
|
if (update_c) |
|
|
lastbit = ((int64_t)(int32_t)tmp >> (c-1)) & 1; |
|
|
tmp = (uint64_t)(((uint64_t)tmp << 32) | tmp) >> c; |
|
|
break; |
|
|
case 7: /* ror Rc */ |
|
|
c = cpu->cd.arm.r[c >> 1] & 255; |
|
|
if (update_c) { |
|
|
if (c == 0) |
|
|
update_c = 0; |
|
|
else { |
|
|
c &= 31; |
|
|
if (c == 0) |
|
|
lastbit = tmp & 0x80000000; |
|
|
else |
|
|
lastbit = ((int64_t)(int32_t)tmp |
|
|
>> (c-1)) & 1; |
|
|
tmp = (uint64_t)(((uint64_t)tmp << 32) |
|
|
| tmp) >> c; |
|
|
} |
|
|
} |
|
|
break; |
|
|
} |
|
|
if (update_c) { |
|
|
cpu->cd.arm.cpsr &= ~ARM_FLAG_C; |
|
|
if (lastbit) |
|
|
cpu->cd.arm.cpsr |= ARM_FLAG_C; |
|
|
} |
|
|
return tmp; |
|
|
} |
|
|
#endif |
|
|
|
|
|
|
|
37 |
void sync_pc(void) |
void sync_pc(void) |
38 |
{ |
{ |
39 |
printf("\tuint32_t tmp, low_pc = ((size_t)ic - (size_t)\n" |
printf("\tuint32_t tmp, low_pc = ((size_t)ic - (size_t)\n" |
40 |
"\t cpu->cd.arm.cur_ic_page)/sizeof(struct arm_instr_call);\n"); |
"\t cpu->cd.arm.cur_ic_page)/sizeof(struct arm_instr_call);\n"); |
41 |
printf("\ttmp = cpu->cd.arm.r[15] & ~((ARM_IC_ENTRIES_PER_PAGE-1) <<\n" |
printf("\ttmp = cpu->pc & ~((ARM_IC_ENTRIES_PER_PAGE-1) <<\n" |
42 |
"\t ARM_INSTR_ALIGNMENT_SHIFT);\n"); |
"\t ARM_INSTR_ALIGNMENT_SHIFT);\n"); |
43 |
printf("\ttmp += (low_pc << ARM_INSTR_ALIGNMENT_SHIFT) + 8;\n"); |
printf("\ttmp += (low_pc << ARM_INSTR_ALIGNMENT_SHIFT) + 8;\n"); |
44 |
} |
} |
75 |
printf("cpu->cd.arm.r[%i]", rm); |
printf("cpu->cd.arm.r[%i]", rm); |
76 |
printf(";\n"); |
printf(";\n"); |
77 |
if (c != 0) { |
if (c != 0) { |
78 |
printf("cpu->cd.arm.cpsr &= ~ARM_FLAG_C;\n"); |
printf("cpu->cd.arm.flags &= ~ARM_F_C;\n"); |
79 |
printf("if (x & 0x%x)\n" |
printf("if (x & 0x%x)\n" |
80 |
"\tcpu->cd.arm.cpsr |= ARM_FLAG_C;\n", |
"\tcpu->cd.arm.flags |= ARM_F_C;\n", |
81 |
(int)(0x80000000 >> (c-1))); |
(int)(0x80000000 >> (c-1))); |
82 |
printf("x <<= %i;\n", c); |
printf("x <<= %i;\n", c); |
83 |
} |
} |
103 |
printf(";\n"); |
printf(";\n"); |
104 |
printf(" uint32_t y = cpu->cd.arm.r[%i] & 255;\n", rc); |
printf(" uint32_t y = cpu->cd.arm.r[%i] & 255;\n", rc); |
105 |
printf(" if (y != 0) {\n"); |
printf(" if (y != 0) {\n"); |
106 |
printf(" cpu->cd.arm.cpsr &= ~ARM_FLAG_C;\n"); |
printf(" cpu->cd.arm.flags &= ~ARM_F_C;\n"); |
107 |
printf(" if (y >= 32) return 0;\n"); |
printf(" if (y >= 32) return 0;\n"); |
108 |
printf(" x <<= (y - 1);\n"); |
printf(" x <<= (y - 1);\n"); |
109 |
printf(" if (x & 0x80000000)\n" |
printf(" if (x & 0x80000000)\n" |
110 |
"\tcpu->cd.arm.cpsr |= ARM_FLAG_C;\n"); |
"\tcpu->cd.arm.flags |= ARM_F_C;\n"); |
111 |
printf(" x <<= 1;\n"); |
printf(" x <<= 1;\n"); |
112 |
printf(" }\n"); |
printf(" }\n"); |
113 |
printf(" return x; }\n"); |
printf(" return x; }\n"); |
135 |
printf(";\n"); |
printf(";\n"); |
136 |
if (c == 0) |
if (c == 0) |
137 |
c = 32; |
c = 32; |
138 |
printf("cpu->cd.arm.cpsr &= ~ARM_FLAG_C;\n"); |
printf("cpu->cd.arm.flags &= ~ARM_F_C;\n"); |
139 |
printf("if (x & 0x%x)\n" |
printf("if (x & 0x%x)\n" |
140 |
"\tcpu->cd.arm.cpsr |= ARM_FLAG_C;\n", |
"\tcpu->cd.arm.flags |= ARM_F_C;\n", |
141 |
(int)(1 << (c-1))); |
(int)(1 << (c-1))); |
142 |
if (c == 32) |
if (c == 32) |
143 |
printf("x = 0;\n"); |
printf("x = 0;\n"); |
166 |
printf("cpu->cd.arm.r[%i]", rm); |
printf("cpu->cd.arm.r[%i]", rm); |
167 |
printf(",y=cpu->cd.arm.r[%i]&255;\n", rc); |
printf(",y=cpu->cd.arm.r[%i]&255;\n", rc); |
168 |
printf("if(y==0) return x;\n"); |
printf("if(y==0) return x;\n"); |
169 |
printf("cpu->cd.arm.cpsr &= ~ARM_FLAG_C;\n"); |
printf("cpu->cd.arm.flags &= ~ARM_F_C;\n"); |
170 |
printf("if(y>31) y=32;\n"); |
printf("if(y>31) y=32;\n"); |
171 |
printf("y--; x >>= y;\n"); |
printf("y--; x >>= y;\n"); |
172 |
printf("if (x & 1) " |
printf("if (x & 1) " |
173 |
"cpu->cd.arm.cpsr |= ARM_FLAG_C;\n"); |
"cpu->cd.arm.flags |= ARM_F_C;\n"); |
174 |
printf(" return x >> 1; }\n"); |
printf(" return x >> 1; }\n"); |
175 |
} else { |
} else { |
176 |
printf("{ uint32_t y=cpu->cd.arm.r[%i]&255;\n", rc); |
printf("{ uint32_t y=cpu->cd.arm.r[%i]&255;\n", rc); |
196 |
printf(";\n"); |
printf(";\n"); |
197 |
if (c == 0) |
if (c == 0) |
198 |
c = 32; |
c = 32; |
199 |
printf("cpu->cd.arm.cpsr &= ~ARM_FLAG_C;\n"); |
printf("cpu->cd.arm.flags &= ~ARM_F_C;\n"); |
200 |
printf("if (x & 0x%x)\n" |
printf("if (x & 0x%x)\n" |
201 |
"\tcpu->cd.arm.cpsr |= ARM_FLAG_C;\n", |
"\tcpu->cd.arm.flags |= ARM_F_C;\n", |
202 |
(int)(1 << (c-1))); |
(int)(1 << (c-1))); |
203 |
if (c == 32) |
if (c == 32) |
204 |
printf("x = (x<0)? 0xffffffff : 0;\n"); |
printf("x = (x<0)? 0xffffffff : 0;\n"); |
233 |
printf("cpu->cd.arm.r[%i]", rm); |
printf("cpu->cd.arm.r[%i]", rm); |
234 |
printf(",y=cpu->cd.arm.r[%i]&255;\n", rc); |
printf(",y=cpu->cd.arm.r[%i]&255;\n", rc); |
235 |
printf("if(y==0) return x;\n"); |
printf("if(y==0) return x;\n"); |
236 |
printf("cpu->cd.arm.cpsr &= ~ARM_FLAG_C;\n"); |
printf("cpu->cd.arm.flags &= ~ARM_F_C;\n"); |
237 |
printf("if(y>31) y=31;\n"); |
printf("if(y>31) y=31;\n"); |
238 |
printf("y--; x >>= y;\n"); |
printf("y--; x >>= y;\n"); |
239 |
printf("if (x & 1) " |
printf("if (x & 1) " |
240 |
"cpu->cd.arm.cpsr |= ARM_FLAG_C;\n"); |
"cpu->cd.arm.flags |= ARM_F_C;\n"); |
241 |
printf(" return (int32_t)x >> 1; }\n"); |
printf(" return (int32_t)x >> 1; }\n"); |
242 |
} else { |
} else { |
243 |
printf("{ int32_t y=cpu->cd.arm.r[%i]&255;\n", rc); |
printf("{ int32_t y=cpu->cd.arm.r[%i]&255;\n", rc); |
255 |
case 6: /* ror c OR rrx (Arithmetic Shift Right by constant) */ |
case 6: /* ror c OR rrx (Arithmetic Shift Right by constant) */ |
256 |
/* 0=rrx, 1..31=ror */ |
/* 0=rrx, 1..31=ror */ |
257 |
if (c == 0) { |
if (c == 0) { |
258 |
printf("\tprintf(\"%s\\n\");\n", name); |
printf("{ uint64_t x="); |
259 |
printf("\texit(1); /* TODO */\n\treturn 0;\n"); |
if (pc) |
260 |
|
printf("tmp"); |
261 |
|
else |
262 |
|
printf("cpu->cd.arm.r[%i]",rm); |
263 |
|
printf("; if (cpu->cd.arm.flags & ARM_F_C)" |
264 |
|
" x |= 0x100000000ULL;"); |
265 |
|
if (s) { |
266 |
|
printf("cpu->cd.arm.flags &= ~ARM_F_C;" |
267 |
|
"if(x&1) cpu->cd.arm.flags |= " |
268 |
|
"ARM_F_C;"); |
269 |
|
} |
270 |
|
printf("return x >> 1; }\n"); |
271 |
} else if (s) { |
} else if (s) { |
272 |
printf("{ uint64_t x = "); |
printf("{ uint64_t x = "); |
273 |
if (pc) |
if (pc) |
275 |
else |
else |
276 |
printf("cpu->cd.arm.r[%i]", rm); |
printf("cpu->cd.arm.r[%i]", rm); |
277 |
printf("; x |= (x << 32);\n"); |
printf("; x |= (x << 32);\n"); |
278 |
printf("cpu->cd.arm.cpsr &= ~ARM_FLAG_C;\n"); |
printf("cpu->cd.arm.flags &= ~ARM_F_C;\n"); |
279 |
printf("if (x & 0x%x)\n" |
printf("if (x & 0x%x)\n" |
280 |
"\tcpu->cd.arm.cpsr |= ARM_FLAG_C;\n", |
"\tcpu->cd.arm.flags |= ARM_F_C;\n", |
281 |
(int)(1 << (c-1))); |
(int)(1 << (c-1))); |
282 |
printf(" return x >> %i; }\n", c); |
printf(" return x >> %i; }\n", c); |
283 |
} else { |
} else { |
284 |
printf("uint64_t x="); |
printf("{ uint64_t x="); |
285 |
if (pc) |
if (pc) |
286 |
printf("tmp"); |
printf("tmp"); |
287 |
else |
else |
288 |
printf("cpu->cd.arm.r[%i]",rm); |
printf("cpu->cd.arm.r[%i]",rm); |
289 |
printf("; x |= (x << 32); "); |
printf("; x |= (x << 32); "); |
290 |
printf("return x >> %i;\n", c); |
printf("return x >> %i; }\n", c); |
291 |
} |
} |
292 |
break; |
break; |
293 |
|
|
301 |
printf("; int y=cpu->cd.arm.r[%i]&255;\n", rc); |
printf("; int y=cpu->cd.arm.r[%i]&255;\n", rc); |
302 |
printf("if(y==0) return x;\n"); |
printf("if(y==0) return x;\n"); |
303 |
printf("y --; y &= 31; x >>= y;\n"); |
printf("y --; y &= 31; x >>= y;\n"); |
304 |
printf("cpu->cd.arm.cpsr &= ~ARM_FLAG_C;\n"); |
printf("cpu->cd.arm.flags &= ~ARM_F_C;\n"); |
305 |
printf("if (x & 1) " |
printf("if (x & 1) " |
306 |
"cpu->cd.arm.cpsr |= ARM_FLAG_C;\n"); |
"cpu->cd.arm.flags |= ARM_F_C;\n"); |
307 |
printf(" return x >> 1; }\n"); |
printf(" return x >> 1; }\n"); |
308 |
} else { |
} else { |
309 |
printf("{ int y=cpu->cd.arm.r[%i]&31;\n", rc); |
printf("{ int y=cpu->cd.arm.r[%i]&31;\n", rc); |