66 static int arm_dpi_uses_d[16] = { 1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1 };
67 static int arm_dpi_uses_n[16] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0 };
99 while (i >= 0 && cpu_type_defs[i].
name != NULL) {
100 if (strcasecmp(cpu_type_defs[i].
name, cpu_type_name) == 0) {
143 isize = 1 << (isize - 10);
145 dsize = 1 << (dsize - 10);
146 debug(
" (I+D = %i+%i KB)", isize, dsize);
189 struct interrupt templ;
191 snprintf(name,
sizeof(name),
"%s.irq", cpu->
path);
193 memset(&templ, 0,
sizeof(templ));
217 unsigned char nothing[16384];
225 memset(nothing, 0,
sizeof(nothing));
228 for (i=0; i<256; i++)
229 for (j=0x0; j<=0xf; j++) {
230 unsigned char descr[4];
232 (((j << 28) + (i << 20)) >> 18);
233 uint32_t d = (1048576*i) | 0xc02;
236 descr[0] = d; descr[1] = d >> 8;
237 descr[2] = d >> 16; descr[3] = d >> 24;
239 descr[3] = d; descr[2] = d >> 8;
240 descr[1] = d >> 16; descr[0] = d >> 24;
254 unsigned int i, j, vhigh = vaddr >> 28, phigh = paddr >> 28;
256 for (i=0; i<256; i++)
257 for (j=vhigh; j<=vhigh; j++) {
258 unsigned char descr[4];
260 (((j << 28) + (i << 20)) >> 18);
261 uint32_t d = ((phigh << 28) + 1048576*i) | 0xc02;
264 descr[0] = d; descr[1] = d >> 8;
265 descr[2] = d >> 16; descr[3] = d >> 24;
267 descr[3] = d; descr[2] = d >> 8;
268 descr[1] = d >> 16; descr[0] = d >> 24;
282 unsigned int i, j, vhigh = vaddr >> 24, phigh = paddr >> 24;
285 for (j=vhigh; j<=vhigh; j++) {
286 unsigned char descr[4];
288 (((j << 24) + (i << 20)) >> 18);
289 uint32_t d = ((phigh << 24) + 1048576*i) | 0xc02;
292 descr[0] = d; descr[1] = d >> 8;
293 descr[2] = d >> 16; descr[3] = d >> 24;
295 descr[3] = d; descr[2] = d >> 8;
296 descr[1] = d >> 16; descr[0] = d >> 24;
311 debug(
" (I+D = %i+%i KB)\n",
327 while (tdefs[i].
name != NULL) {
329 for (j=13 -
strlen(tdefs[i].name); j>0; j--)
332 if ((i % 5) == 0 || tdefs[i].name == NULL)
359 debug(
"cpu%i: cpsr = ", x);
360 debug(
"%s%s%s%s%s%s%s%s%s%s%s",
373 debug(
" pc = 0x%07x", (
int)(cpu->
pc & 0x03ffffff));
375 debug(
" pc = 0x%08x", (
int)cpu->
pc);
377 debug(
" <%s>\n", symbol != NULL? symbol :
" no symbol ");
383 debug(
" %s = 0x%08x", arm_regname[i],
395 debug(
"USR32)\n");
break;
397 debug(
"SYS32)\n");
break;
399 debug(
"FIQ32)\n");
break;
401 debug(
"IRQ32)\n");
break;
403 debug(
"SVC32)\n");
break;
405 debug(
"ABT32)\n");
break;
407 debug(
"UND32)\n");
break;
408 default:
debug(
"unimplemented)\n");
412 debug(
"cpu%i: usr r8-14:", x);
419 debug(
"cpu%i: fiq r8-14:", x);
426 debug(
"cpu%i: irq r13-14:", x);
433 debug(
"cpu%i: svc r13-14:", x);
440 debug(
"cpu%i: abt r13-14:", x);
447 debug(
"cpu%i: und r13-14:", x);
456 debug(
"cpu%i: MMU: %s\n", x,
459 debug(
"cpu%i: alignment checks: %s\n", x,
462 debug(
"cpu%i: [data] cache: %s\n", x,
465 debug(
"cpu%i: instruction cache: %s\n", x,
468 debug(
"cpu%i: write buffer: %s\n", x,
471 debug(
"cpu%i: prog32: %s\n", x,
474 debug(
"cpu%i: data32: %s\n", x,
477 debug(
"cpu%i: endianness: %s\n", x,
480 debug(
"cpu%i: high vectors: %s\n", x,
486 debug(
"cpu%i: auxctrl = 0x%08x\n", x,
488 debug(
"cpu%i: minidata cache attr = 0x%x\n", x,
491 debug(
"cpu%i: page table memory attr: %i\n", x,
493 debug(
"cpu%i: write buffer coalescing: %s\n", x,
495 "disabled" :
"enabled");
498 debug(
"cpu%i: ttb = 0x%08x dacr = 0x%08x\n", x,
500 debug(
"cpu%i: fsr = 0x%08x far = 0x%08x\n", x,
516 &cpu->
cd.
arm.
r[8],
sizeof(uint32_t) * 7);
520 &cpu->
cd.
arm.
r[8],
sizeof(uint32_t) * 7);
524 &cpu->
cd.
arm.
r[8],
sizeof(uint32_t) * 5);
530 &cpu->
cd.
arm.
r[8],
sizeof(uint32_t) * 5);
536 &cpu->
cd.
arm.
r[8],
sizeof(uint32_t) * 5);
542 &cpu->
cd.
arm.
r[8],
sizeof(uint32_t) * 5);
546 default:
fatal(
"arm_save_register_bank: unimplemented mode %i\n",
567 sizeof(uint32_t) * 7);
593 default:
fatal(
"arm_load_register_bank: unimplemented mode %i\n",
605 int oldmode, newmode;
609 fatal(
"arm_exception(): exception_nr = %i\n", exception_nr);
616 debug(
"[ arm_exception(): ");
617 switch (exception_nr) {
619 fatal(
"RESET: TODO");
628 debug(
"PREFETCH ABORT");
637 debug(
"DATA ABORT, far=0x%08x fsr=0x%02x",
644 switch (exception_nr) {
647 fatal(
"ARM RESET: TODO");
661 switch (arm_exception_to_mode[exception_nr]) {
672 default:
fatal(
"arm_exception(): unimplemented exception nr\n");
685 cpu->
cd.
arm.
cpsr |= arm_exception_to_mode[exception_nr];
696 fatal(
"[ WARNING! Exception caused no mode change? " 697 "mode 0x%02x (pc=0x%x) ]\n", newmode, (
int)cpu->
pc);
744 struct cpu *cpu = (
struct cpu *) interrupt->
extra;
749 struct cpu *cpu = (
struct cpu *) interrupt->
extra;
762 int running, uint64_t dumpaddr)
766 iw = ib[0] + (ib[1]<<8);
768 iw = ib[1] + (ib[0]<<8);
769 debug(
"%04x \t", (
int)iw);
771 int main_opcode = (iw >> 12) & 15;
772 int r6 = (iw >> 6) & 7;
773 int rs_rb = (iw >> 3) & 7;
775 int offset5 = (iw >> 6) & 0x1f;
776 int b_bit = (iw >> 12) & 1;
777 int l_bit = (iw >> 11) & 1;
778 int addsub_op = (iw >> 9) & 1;
779 int addsub_immediate = (iw >> 10) & 1;
780 int op11 = (iw >> 11) & 3;
781 int op10 = (iw >> 10) & 3;
782 int rd8 = (iw >> 8) & 7;
783 int op8 = (iw >> 8) & 3;
784 int h1 = (iw >> 7) & 1;
785 int h2 = (iw >> 6) & 1;
786 int condition_code = (iw >> 8) & 15;
787 const char* condition = arm_condition_string[condition_code];
799 debug(
"%ss\tr%i,r%i,#%i\n",
800 op11 & 1 ?
"lsr" : (op11 & 2 ?
"asr" :
"lsl"),
806 debug(
"%s\tr%i,r%i,%s%i\n",
807 addsub_op ?
"subs" :
"adds",
810 addsub_immediate ?
"#" :
"r",
820 debug(
"%s\tr%i,r%i,#%i\n",
821 op11 & 1 ?
"subs" :
"adds",
825 debug(
"%s\tr%i,#%i\n",
826 op11 & 1 ?
"cmp" :
"movs",
837 arm_thumb_dpiname[(iw >> 6) & 15],
842 debug(
"\t\t; %s = 0x%x", arm_regname[rd], cpu->
cd.
arm.
r[rd]);
843 debug(
", %s = 0x%x", arm_regname[rs_rb], cpu->
cd.
arm.
r[rs_rb]);
859 if (h1 == 0 && h2 == 0) {
860 debug(
"TODO main_opcode = %i, op10 = %i, h1 AND h2 are zero?!\n", main_opcode, op10);
863 debug(
"add\tr%i,r%i,r%i\n", rd, rd, rs_rb);
865 if (op8 == 2 && rd == rs_rb)
869 op8 == 1 ?
"cmp" :
"mov",
873 debug(
"\t\t; %s = 0x%x", arm_regname[rd], cpu->
cd.
arm.
r[rd]);
874 debug(
", %s = 0x%x", arm_regname[rs_rb], cpu->
cd.
arm.
r[rs_rb]);
883 debug(
"TODO main_opcode = %i, op10 = %i, h1 set for BX?!\n", main_opcode, op10);
885 debug(
"bx\t%s\n", arm_regname[rs_rb]);
898 debug(
"ldr\t%s,[pc,#%i]\t; ",
905 tmp = (dumpaddr & ~3) + 4 + (iw & 0xff) * 4;
906 debug(
"0x%x", (
int)tmp);
910 debug(
" <%s>", symbol);
918 switch ((iw >> 9) & 7) {
919 case 0:
debug(
"str");
break;
920 case 1:
debug(
"strh");
break;
921 case 2:
debug(
"strb");
break;
922 case 3:
debug(
"ldrsb");
break;
923 case 4:
debug(
"ldr");
break;
924 case 5:
debug(
"ldrh");
break;
925 case 6:
debug(
"ldrb");
break;
926 case 7:
debug(
"ldrsh");
break;
928 debug(
"\t%s,[%s,%s]\n",
937 debug(
"%s%s\tr%i,[r%i,#%i]\n",
938 l_bit ?
"ldr" :
"str",
942 offset5 * (b_bit ?
sizeof(uint8_t) :
sizeof(uint32_t)));
947 debug(
"%sh\tr%i,[r%i,#%i]\n",
948 l_bit ?
"ldr" :
"str",
951 offset5 *
sizeof(uint16_t));
956 debug(
"%s\t%s,[sp,#%i]\n",
957 l_bit ?
"ldr" :
"str",
964 debug(
"add\t%s,%s,#%i\n",
966 iw & 0x0800 ?
"sp" :
"pc",
972 switch (condition_code) {
974 tmp = (iw & 0x7f) << 2;
975 debug(iw & 0x80 ?
"sub" :
"add");
976 debug(
"\tsp,#%i\n", tmp);
982 debug(condition_code & 8 ?
"pop" :
"push");
984 for (tmp=0; tmp<8; ++tmp) {
986 debug(
"%s,", arm_regname[tmp]);
988 if (condition_code & 1) {
989 if (condition_code & 8)
1001 debug(
"TODO: unimplemented opcode 0x%x,0x%x\n", main_opcode, condition_code);
1006 if (condition_code < 0xe) {
1008 debug(
"b%s\t", condition);
1009 tmp = (iw & 0xff) << 1;
1012 tmp = (int32_t)(dumpaddr + 4 + tmp);
1013 debug(
"0x%x", (
int)tmp);
1017 debug(
" \t<%s>", symbol);
1019 }
else if (condition_code == 0xf) {
1020 debug(
"swi\t#0x%x\n", iw & 0xff);
1022 debug(
"UNIMPLEMENTED\n");
1029 uint32_t
addr = (dumpaddr + 4 + (cpu->
cd.
arm.
tmp_branch + (((iw >> 1) & 0x3ff) << 2))) & ~3;
1033 debug(
"0x%x", addr);
1036 debug(
" \t<%s>", symbol);
1039 debug(
"offset depending on prefix at runtime\n");
1041 tmp = (iw & 0x7ff) << 1;
1044 tmp = (int32_t)(dumpaddr + 4 + tmp);
1045 debug(
"b\t0x%x", (
int)tmp);
1048 debug(
" \t<%s>", symbol);
1059 debug(
"0x%x", addr);
1062 debug(
" \t<%s>", symbol);
1065 debug(
"offset depending on prefix at runtime\n");
1067 tmp32 = iw & 0x07ff;
1069 tmp32 |= 0xfffff800;
1071 debug(
"bprefix\t0x%x\n", tmp32);
1076 debug(
"TODO: unimplemented opcode 0x%x\n", main_opcode);
1079 return sizeof(uint16_t);
1095 uint8_t ib[
sizeof(uint16_t)];
1096 uint32_t
addr = cpu->
pc & ~1;
1099 fatal(
"arm_cpu_interpret_thumb_SLOW called when not in " 1107 fatal(
"arm_cpu_interpret_thumb_SLOW(): could not read " 1108 "the instruction\n");
1117 if (symbol != NULL && offset == 0)
1118 debug(
"<%s>\n", symbol);
1123 debug(
"%08x: ", (
int)addr & ~1);
1128 iw = ib[0] + (ib[1]<<8);
1130 iw = ib[1] + (ib[0]<<8);
1134 int main_opcode = (iw >> 12) & 15;
1135 int condition_code = (iw >> 8) & 15;
1136 int op10 = (iw >> 10) & 3;
1137 int op11_8 = (iw >> 8) & 15;
1138 int rd8 = (iw >> 8) & 7;
1139 int r6 = (iw >> 6) & 7;
1140 int r3 = (iw >> 3) & 7;
1141 int rd = (iw >> 0) & 7;
1142 int hd = (iw >> 7) & 1;
1143 int hm = (iw >> 6) & 1;
1144 int imm6 = (iw >> 6) & 31;
1145 uint8_t word[
sizeof(uint32_t)];
1149 switch (main_opcode)
1168 if (cpu->
cd.
arm.
r[rd] == 0)
1170 if ((int32_t)cpu->
cd.
arm.
r[rd] < 0)
1181 if (!(iw & 0x0800)) {
1185 tmp = (int32_t)tmp >> (imm6 - 1);
1186 cpu->
cd.
arm.
r[rd] = (int32_t)cpu->
cd.
arm.
r[r3] >> imm6;
1189 if (cpu->
cd.
arm.
r[rd8] == 0)
1191 if ((int32_t)cpu->
cd.
arm.
r[rd8] < 0)
1201 int isSub = iw & 0x0200;
1202 int isImm3 = iw & 0x0400;
1203 uint64_t old = cpu->
cd.
arm.
r[r3];
1204 uint64_t tmp64 = isImm3 ? r6 : cpu->
cd.
arm.
r[r6];
1205 tmp64 = (uint32_t)(isSub ? -tmp64 : tmp64);
1206 uint64_t result = old + tmp64;
1207 cpu->
cd.
arm.
r[rd] = result;
1211 if ((int32_t)result < 0)
1213 if (result & 0x100000000ULL)
1215 if (result & 0x80000000) {
1216 if ((tmp64 & 0x80000000) == 0 && (old & 0x80000000) == 0)
1219 if ((tmp64 & 0x80000000) != 0 && (old & 0x80000000) != 0)
1228 uint64_t old = cpu->
cd.
arm.
r[rd8];
1229 uint64_t tmp64 = (uint32_t)(-(iw & 0xff));
1230 uint64_t result = old + tmp64;
1234 if ((int32_t)result < 0)
1236 if (result & 0x100000000ULL)
1238 if (result & 0x80000000) {
1239 if ((tmp64 & 0x80000000) == 0 && (old & 0x80000000) == 0)
1242 if ((tmp64 & 0x80000000) != 0 && (old & 0x80000000) != 0)
1246 cpu->
cd.
arm.
r[rd8] = iw & 0xff;
1248 if (cpu->
cd.
arm.
r[rd8] == 0)
1256 uint64_t old = cpu->
cd.
arm.
r[rd8];
1257 uint64_t tmp64 = iw & 0xff;
1260 tmp64 = (uint32_t)(-tmp64);
1262 uint64_t result = old + tmp64;
1263 cpu->
cd.
arm.
r[rd8] = result;
1268 if ((int32_t)result < 0)
1270 if (result & 0x100000000ULL)
1272 if (result & 0x80000000) {
1273 if ((tmp64 & 0x80000000) == 0 && (old & 0x80000000) == 0)
1276 if ((tmp64 & 0x80000000) != 0 && (old & 0x80000000) != 0)
1286 switch ((iw >> 6) & 15) {
1290 if (cpu->
cd.
arm.
r[rd] == 0)
1292 if ((int32_t)cpu->
cd.
arm.
r[rd] < 0)
1298 if (cpu->
cd.
arm.
r[rd] == 0)
1300 if ((int32_t)cpu->
cd.
arm.
r[rd] < 0)
1305 int amount = cpu->
cd.
arm.
r[r3] & 0xff;
1306 for (
int i = 0; i < (amount & 31); ++i) {
1307 int c = cpu->
cd.
arm.
r[rd] & 1;
1312 cpu->
cd.
arm.
r[rd] |= 0x80000000;
1319 if (amount != 0 && (amount & 31) == 0) {
1321 if (cpu->
cd.
arm.
r[rd] & 0x80000000)
1325 if (cpu->
cd.
arm.
r[rd] == 0)
1327 if ((int32_t)cpu->
cd.
arm.
r[rd] < 0)
1336 if ((int32_t)tmp < 0)
1341 uint64_t old = cpu->
cd.
arm.
r[rd];
1342 uint64_t tmp64 = (uint32_t) (-cpu->
cd.
arm.
r[r3]);
1343 uint64_t result = old + tmp64;
1347 if ((int32_t)result < 0)
1349 if (result & 0x100000000ULL)
1351 if (result & 0x80000000) {
1352 if ((tmp64 & 0x80000000) == 0 && (old & 0x80000000) == 0)
1355 if ((tmp64 & 0x80000000) != 0 && (old & 0x80000000) != 0)
1363 if (cpu->
cd.
arm.
r[rd] == 0)
1365 if ((int32_t)cpu->
cd.
arm.
r[rd] < 0)
1371 if (cpu->
cd.
arm.
r[rd] == 0)
1373 if ((int32_t)cpu->
cd.
arm.
r[rd] < 0)
1377 debug(
"TODO: unimplemented DPI %i at pc 0x%08x\n", (iw >> 6) & 15, (int)cpu->
pc);
1392 debug(
"TODO: double check with manual whether it is correct to use old pc + 8 here; at pc 0x%08x\n", (
int)cpu->
pc);
1403 cpu->
pc = addr -
sizeof(uint16_t);
1407 if ((iw & 0xff87) == 0x4700) {
1409 int rm = (iw >> 3) & 15;
1411 cpu->
pc = cpu->
cd.
arm.
r[rm] -
sizeof(uint16_t);
1417 debug(
"TODO: unimplemented opcode 0x%x,%i at pc 0x%08x\n", main_opcode, op11_8, (
int)cpu->
pc);
1423 debug(
"TODO: unimplemented opcode 0x%x,%i at pc 0x%08x\n", main_opcode, op11_8, (
int)cpu->
pc);
1435 tmp = (addr & ~3) + 4 + (iw & 0xff) * 4;
1439 fatal(
"arm_cpu_interpret_thumb_SLOW(): could not load pc-relative word\n");
1445 tmp = word[0] + (word[1]<<8) + (word[2]<<16) + (word[3]<<24);
1447 tmp = word[3] + (word[2]<<8) + (word[1]<<16) + (word[0]<<24);
1449 cpu->
cd.
arm.
r[rd8] = tmp;
1453 debug(
"TODO: unimplemented opcode 0x%x,%i at pc 0x%08x\n", main_opcode, op10, (
int)cpu->
pc);
1463 len = main_opcode == 6 ? 4 : (main_opcode == 7 ? 1 : 2);
1464 isLoad = iw & 0x0800;
1465 addr = (cpu->
cd.
arm.
r[r3] + imm6 * len) & ~(len - 1);
1472 for (
int i = 0; i < len; ++i)
1473 word[i] = (tmp >> (8*i));
1475 for (
int i = 0; i < len; ++i)
1476 word[len - 1 - i] = (tmp >> (8*i));
1482 fatal(
"arm_cpu_interpret_thumb_SLOW(): could not load with immediate offset\n");
1490 for (
int i = 0; i < len; ++i) {
1492 tmp |= word[len - 1 - i];
1495 for (
int i = 0; i < len; ++i) {
1511 fatal(
"arm_cpu_interpret_thumb_SLOW(): could not load sp-relative word\n");
1517 tmp = word[0] + (word[1]<<8) + (word[2]<<16) + (word[3]<<24);
1519 tmp = word[3] + (word[2]<<8) + (word[1]<<16) + (word[0]<<24);
1521 cpu->
cd.
arm.
r[rd8] = tmp;
1523 tmp = cpu->
cd.
arm.
r[rd8];
1525 for (
size_t i = 0; i <
sizeof(word); ++i)
1526 word[i] = (tmp >> (8*i));
1528 for (
size_t i = 0; i <
sizeof(word); ++i)
1529 word[
sizeof(word) - 1 - i] = (tmp >> (8*i));
1535 fatal(
"arm_cpu_interpret_thumb_SLOW(): could not store sp-relative word\n");
1554 (iw & 0x100 ? (1 <<
ARM_LR) : 0));
1561 (iw & 0x100 ? (1 <<
ARM_PC) : 0));
1569 cpu->
pc +=
sizeof(uint16_t);
1572 debug(
"TODO: unimplemented opcode 0x%x,%i at pc 0x%08x\n", main_opcode, op11_8, (
int)cpu->
pc);
1579 if (condition_code < 0xe) {
1581 tmp = (iw & 0xff) << 1;
1584 tmp = (int32_t)(cpu->
pc + 4 + tmp);
1586 switch (condition_code) {
1635 }
else if (condition_code == 0xf) {
1639 debug(
"TODO: unimplemented opcode 0x%x, non-branch, at pc 0x%08x\n", main_opcode, (
int)cpu->
pc);
1651 fatal(
"lowest bit set in thumb blx instruction?\n");
1664 tmp = (iw & 0x7ff) << 1;
1667 cpu->
pc = (int32_t)(cpu->
pc + 4 + tmp);
1683 uint32_t tmp32 = iw & 0x07ff;
1685 tmp32 |= 0xfffff800;
1692 debug(
"TODO: unimplemented opcode 0x%x at pc 0x%08x\n", main_opcode, (
int)cpu->
pc);
1697 cpu->
pc +=
sizeof(uint16_t);
1716 int running, uint64_t dumpaddr)
1719 int main_opcode, secondary_opcode, s_bit, r16, r12, r8;
1720 int i, n, p_bit, u_bit, b_bit, w_bit, l_bit;
1721 const char *
symbol, *condition;
1729 if (symbol != NULL && offset == 0)
1730 debug(
"<%s>\n", symbol);
1735 debug(
"%08x: ", (
int)dumpaddr & ~1);
1741 iw = ib[0] + (ib[1]<<8) + (ib[2]<<16) + (ib[3]<<24);
1743 iw = ib[3] + (ib[2]<<8) + (ib[1]<<16) + (ib[0]<<24);
1744 debug(
"%08x\t", (
int)iw);
1746 condition = arm_condition_string[iw >> 28];
1747 main_opcode = (iw >> 24) & 15;
1748 secondary_opcode = (iw >> 21) & 15;
1749 u_bit = (iw >> 23) & 1;
1750 b_bit = (iw >> 22) & 1;
1751 w_bit = (iw >> 21) & 1;
1752 s_bit = l_bit = (iw >> 20) & 1;
1753 r16 = (iw >> 16) & 15;
1754 r12 = (iw >> 12) & 15;
1755 r8 = (iw >> 8) & 15;
1757 if ((iw >> 28) == 0xf) {
1758 switch (main_opcode) {
1761 tmp = (iw & 0xffffff);
1764 tmp = (int32_t)(dumpaddr + 8 + 4*tmp + (main_opcode == 0xb? 2 : 0)) + 1;
1765 debug(
"blx\t0x%x", (
int)tmp);
1769 debug(
" \t<%s>", symbol);
1772 default:
debug(
"UNIMPLEMENTED\n");
1774 return sizeof(uint32_t);
1777 switch (main_opcode) {
1790 if ((iw & 0x0fc000f0) == 0x00000090) {
1791 int a_bit = (iw >> 21) & 1;
1792 debug(
"%s%s%s\t", a_bit?
"mla" :
"mul",
1793 condition, s_bit?
"s" :
"");
1794 debug(
"%s,", arm_regname[r16]);
1795 debug(
"%s,", arm_regname[iw & 15]);
1796 debug(
"%s", arm_regname[r8]);
1798 debug(
",%s", arm_regname[r12]);
1807 if ((iw & 0x0f8000f0) == 0x00800090) {
1808 int a_bit = (iw >> 21) & 1;
1809 u_bit = (iw >> 22) & 1;
1810 debug(
"%s%sl%s%s\t", u_bit?
"s" :
"u",
1811 a_bit?
"mla" :
"mul", condition, s_bit?
"s" :
"");
1812 debug(
"%s,%s,", arm_regname[r12], arm_regname[r16]);
1813 debug(
"%s,%s\n", arm_regname[iw&15], arm_regname[r8]);
1823 if ((iw & 0x0f900ff0) == 0x01000050) {
1824 debug(
"q%s%s%s\t", iw & 0x400000?
"d" :
"",
1825 iw & 0x200000?
"sub" :
"add", condition);
1826 debug(
"%s,%s,%s\n", arm_regname[r12],
1827 arm_regname[iw&15], arm_regname[r16]);
1834 if ((iw & 0x0ff000d0) == 0x01200010) {
1836 debug(
"b%sx%s\t%s\n", l_bit?
"l" :
"", condition,
1837 arm_regname[iw & 15]);
1846 if ((iw & 0x0fb0fff0) == 0x0120f000 ||
1847 (iw & 0x0fb0f000) == 0x0320f000) {
1848 debug(
"msr%s\t%s", condition, (iw&0x400000)?
"S":
"C");
1850 if (iw & (1<<19))
debug(
"f");
1851 if (iw & (1<<18))
debug(
"s");
1852 if (iw & (1<<17))
debug(
"x");
1853 if (iw & (1<<16))
debug(
"c");
1854 if (iw & 0x02000000) {
1855 int r = (iw >> 7) & 30;
1856 uint32_t b = iw & 0xff;
1858 b = (b >> 1) | ((b & 1) << 31);
1859 debug(
",#0x%x\n", b);
1861 debug(
",%s\n", arm_regname[iw & 15]);
1864 if ((iw & 0x0fbf0fff) == 0x010f0000) {
1865 debug(
"mrs%s\t", condition);
1866 debug(
"%s,%sPSR\n", arm_regname[r12],
1867 (iw&0x400000)?
"S":
"C");
1874 if ((iw & 0x0fb00ff0) == 0x01000090) {
1875 debug(
"swp%s%s\t", condition, (iw&0x400000)?
"b":
"");
1876 debug(
"%s,%s,[%s]\n", arm_regname[r12],
1877 arm_regname[iw & 15], arm_regname[r16]);
1884 if ((iw & 0x0ff000f0) == 0x01200070) {
1885 debug(
"bkpt%s\t0x%04x\n", condition,
1886 ((iw & 0x000fff00) >> 4) + (iw & 0xf));
1893 if ((iw & 0x0fff0ff0) == 0x016f0f10) {
1894 debug(
"clz%s\t", condition);
1895 debug(
"%s,%s\n", arm_regname[r12], arm_regname[iw&15]);
1906 if ((iw & 0x0ff00090) == 0x01000080) {
1907 debug(
"smla%s%s%s\t",
1908 iw & 0x20?
"t" :
"b", iw & 0x40?
"t" :
"b",
1910 debug(
"%s,%s,%s,%s\n", arm_regname[r16],
1911 arm_regname[iw&15], arm_regname[r8],
1915 if ((iw & 0x0ff00090) == 0x01400080) {
1916 debug(
"smlal%s%s%s\t",
1917 iw & 0x20?
"t" :
"b", iw & 0x40?
"t" :
"b",
1919 debug(
"%s,%s,%s,%s\n", arm_regname[r12],
1920 arm_regname[r16], arm_regname[iw&15],
1924 if ((iw & 0x0ff000b0) == 0x01200080) {
1925 debug(
"smlaw%s%s\t", iw & 0x40?
"t" :
"b",
1927 debug(
"%s,%s,%s,%s\n", arm_regname[r16],
1928 arm_regname[iw&15], arm_regname[r8],
1932 if ((iw & 0x0ff0f090) == 0x01600080) {
1933 debug(
"smul%s%s%s\t",
1934 iw & 0x20?
"t" :
"b", iw & 0x40?
"t" :
"b",
1936 debug(
"%s,%s,%s\n", arm_regname[r16],
1937 arm_regname[iw&15], arm_regname[r8]);
1940 if ((iw & 0x0ff0f0b0) == 0x012000a0) {
1941 debug(
"smulw%s%s\t", iw & 0x40?
"t" :
"b",
1943 debug(
"%s,%s,%s\n", arm_regname[r16],
1944 arm_regname[iw&15], arm_regname[r8]);
1951 if ((iw & 0x0e000090) == 0x00000090) {
1952 const char *
op =
"st";
1953 int imm = ((iw >> 4) & 0xf0) | (iw & 0xf);
1954 int regform = !(iw & 0x00400000);
1955 p_bit = main_opcode & 1;
1960 if (!l_bit && (iw & 0xd0) == 0xd0 && (r12 & 1)) {
1961 debug(
"TODO: r12 odd, not load/store\n");
1965 if (iw & 0x00100000)
1967 if (!l_bit && (iw & 0xd0) == 0xd0) {
1973 debug(
"%sr%s", op, condition);
1974 if (!l_bit && (iw & 0xd0) == 0xd0) {
1984 debug(
"\t%s,[%s", arm_regname[r12], arm_regname[r16]);
1988 debug(
",%s%s", u_bit?
"" :
"-",
1989 arm_regname[iw & 15]);
1992 debug(
",#%s%i", u_bit?
"" :
"-",
1995 debug(
"]%s\n", w_bit?
"!" :
"");
2000 debug(
"%s%s\n", u_bit?
"" :
"-",
2001 arm_regname[iw & 15]);
2003 debug(
"#%s%i\n", u_bit?
"" :
"-", imm);
2009 if (iw & 0x80 && !(main_opcode & 2) && iw & 0x10) {
2010 debug(
"UNIMPLEMENTED reg (c!=0), t odd\n");
2021 debug(
"%s%s%s\t", arm_dpiname[secondary_opcode],
2022 condition, s_bit?
"s" :
"");
2023 if (arm_dpi_uses_d[secondary_opcode])
2024 debug(
"%s,", arm_regname[r12]);
2025 if (arm_dpi_uses_n[secondary_opcode])
2026 debug(
"%s,", arm_regname[r16]);
2028 if (main_opcode & 2) {
2030 int r = (iw >> 7) & 30;
2031 uint32_t b = iw & 0xff;
2033 b = (b >> 1) | ((b & 1) << 31);
2040 int t = (iw >> 4) & 7;
2041 int c = (iw >> 7) & 31;
2042 debug(
"%s", arm_regname[iw & 15]);
2045 debug(
", lsl #%i", c);
2047 case 1:
debug(
", lsl %s", arm_regname[c >> 1]);
2049 case 2:
debug(
", lsr #%i", c? c : 32);
2051 case 3:
debug(
", lsr %s", arm_regname[c >> 1]);
2053 case 4:
debug(
", asr #%i", c? c : 32);
2055 case 5:
debug(
", asr %s", arm_regname[c >> 1]);
2058 debug(
", ror #%i", c);
2062 case 7:
debug(
", ror %s", arm_regname[c >> 1]);
2067 if (running && t == 0 && c == 0 && secondary_opcode
2073 debug(
" \t<%s>", symbol);
2083 if ((iw & 0xfc70f000) == 0xf450f000) {
2085 debug(
"pld\t[%s]\n", arm_regname[r16]);
2093 p_bit = main_opcode & 1;
2094 if (main_opcode >= 6 && iw & 0x10) {
2095 debug(
"TODO: single data transf. but 0x10\n");
2098 debug(
"%s%s%s", l_bit?
"ldr" :
"str",
2099 condition, b_bit?
"b" :
"");
2100 if (!p_bit && w_bit)
2102 debug(
"\t%s,[%s", arm_regname[r12], arm_regname[r16]);
2103 if ((iw & 0x0e000000) == 0x04000000) {
2105 uint32_t imm = iw & 0xfff;
2109 debug(
",#%s%i", u_bit?
"" :
"-", imm);
2112 }
else if ((iw & 0x0e000010) == 0x06000000) {
2116 if ((iw & 0xfff) != 0)
2117 debug(
",%s%s", u_bit?
"" :
"-",
2118 arm_regname[iw & 15]);
2119 if ((iw & 0xff0) != 0x000) {
2120 int c = (iw >> 7) & 31;
2121 int t = (iw >> 4) & 7;
2124 debug(
", lsl #%i", c);
2126 case 2:
debug(
", lsr #%i", c? c : 32);
2128 case 4:
debug(
", asr #%i", c? c : 32);
2131 debug(
", ror #%i", c);
2143 debug(
"%s", (p_bit && w_bit)?
"!" :
"");
2144 if ((iw & 0x0f000000) == 0x05000000 &&
2145 (r16 ==
ARM_PC || running)) {
2146 unsigned char tmpw[4];
2147 uint32_t imm = iw & 0xfff;
2148 uint32_t
addr = (u_bit? imm : -imm);
2150 addr += dumpaddr + 8;
2152 addr += cpu->
cd.
arm.
r[r16];
2156 debug(
" \t<%s", symbol);
2158 debug(
" \t<0x%08x", addr);
2159 if ((l_bit && cpu->
memory_rw(cpu, cpu->
mem, addr, tmpw,
2161 || (!l_bit && running)) {
2165 addr = tmpw[0] +(tmpw[1] << 8) +
2166 (tmpw[2]<<16)+(tmpw[3]<<24);
2168 addr = tmpw[3] + (tmpw[2]<<8) +
2169 (tmpw[1]<<16)+(tmpw[0]<<24);
2171 tmpw[0] = addr = cpu->
cd.
arm.
r[r12];
2177 debug(
"%i", tmpw[0]);
2182 debug(
"%s", symbol);
2183 else if ((int32_t)addr > -256 &&
2184 (int32_t)addr < 256)
2187 debug(
"0x%x", addr);
2197 p_bit = main_opcode & 1;
2199 debug(
"%s%s", l_bit?
"ldm" :
"stm", condition);
2200 switch (u_bit * 2 + p_bit) {
2201 case 0:
debug(
"da");
break;
2202 case 1:
debug(
"db");
break;
2203 case 2:
debug(
"ia");
break;
2204 case 3:
debug(
"ib");
break;
2206 debug(
"\t%s", arm_regname[r16]);
2211 for (i=0; i<16; i++)
2212 if ((iw >> i) & 1) {
2213 debug(
"%s%s", (n > 0)?
",":
"", arm_regname[i]);
2223 debug(
"b%s%s\t", main_opcode == 0xa?
"" :
"l", condition);
2224 tmp = (iw & 0x00ffffff) << 2;
2225 if (tmp & 0x02000000)
2227 tmp = (int32_t)(dumpaddr + tmp + 8);
2228 debug(
"0x%x", (
int)tmp);
2232 debug(
" \t<%s>", symbol);
2241 if ((iw & 0x0fe00fff) == 0x0c400000) {
2242 debug(
"%s%s\t", iw & 0x100000?
"mra" :
"mar",
2245 debug(
"%s,%s,acc0\n",
2246 arm_regname[r12], arm_regname[r16]);
2248 debug(
"acc0,%s,%s\n",
2249 arm_regname[r12], arm_regname[r16]);
2252 if ((iw & 0x0fe00000) == 0x0c400000) {
2253 debug(
"%s%s\t", iw & 0x100000?
"mrrc" :
"mcrr",
2255 debug(
"%i,%i,%s,%s,cr%i\n", r8, (iw >> 4) & 15,
2256 arm_regname[r12], arm_regname[r16], iw & 15);
2261 debug(
"TODO: coprocessor LDC/STC\n");
2268 if ((iw & 0x0ff00ff0) == 0x0e200010) {
2270 switch ((iw >> 16) & 0xf) {
2271 case 0:
debug(
"mia");
break;
2272 case 8:
debug(
"miaph");
break;
2273 case 12:
debug(
"miaBB");
break;
2274 case 13:
debug(
"miaTB");
break;
2275 case 14:
debug(
"miaBT");
break;
2276 case 15:
debug(
"miaTT");
break;
2277 default:
debug(
"UNKNOWN mia vector instruction?");
2279 debug(
"%s\t", condition);
2280 debug(
"acc%i,%s,%s\n", ((iw >> 5) & 7),
2281 arm_regname[iw & 15], arm_regname[r12]);
2286 (iw & 0x00100000)?
"mrc" :
"mcr", condition);
2287 debug(
"%i,%i,r%i,cr%i,cr%i,%i",
2288 (
int)((iw >> 8) & 15), (
int)((iw >>21) & 7),
2289 (
int)((iw >>12) & 15), (
int)((iw >>16) & 15),
2290 (
int)((iw >> 0) & 15), (
int)((iw >> 5) & 7));
2292 debug(
"cdp%s\t", condition);
2293 debug(
"%i,%i,cr%i,cr%i,cr%i",
2294 (
int)((iw >> 8) & 15),
2295 (
int)((iw >>20) & 15),
2296 (
int)((iw >>12) & 15),
2297 (
int)((iw >>16) & 15),
2298 (
int)((iw >> 0) & 15));
2300 debug(
",0x%x", (
int)((iw >> 5) & 7));
2305 debug(
"swi%s\t", condition);
2306 debug(
"0x%x\n", (
int)(iw & 0x00ffffff));
2308 default:
debug(
"UNIMPLEMENTED\n");
2311 return sizeof(uint32_t);
2328 int opcode1 = (iword >> 21) & 7;
2329 int l_bit = (iword >> 20) & 1;
2330 int crn = (iword >> 16) & 15;
2331 int rd = (iword >> 12) & 15;
2332 int cp_num = (iword >> 8) & 15;
2333 int opcode2 = (iword >> 5) & 7;
2334 int crm = iword & 15;
2337 cpu->
cd.
arm.
coproc[cp_num](cpu, opcode1, opcode2, l_bit,
2340 fatal(
"[ arm_mcr_mrc: pc=0x%08x, iword=0x%08x: " 2341 "cp_num=%i ]\n", (
int)cpu->
pc, iword, cp_num);
2358 fatal(
"[ arm_cdp: pc=0x%08x, iword=0x%08x ]\n", (
int)cpu->
pc, iword);
#define ARM_CONTROL_ALIGN
void fatal(const char *fmt,...)
void arm_save_register_bank(struct cpu *cpu)
void(* interrupt_assert)(struct interrupt *)
int(* translate_v2p)(struct cpu *, uint64_t vaddr, uint64_t *return_paddr, int flags)
int arm_memory_rw(struct cpu *cpu, struct memory *mem, uint64_t vaddr, unsigned char *data, size_t len, int writeflag, int cache_flags)
#define ARM_EXCEPTION_TO_MODE
int arm_translate_v2p_mmu(struct cpu *cpu, uint64_t vaddr64, uint64_t *return_paddr, int flags)
int store_32bit_word(struct cpu *cpu, uint64_t addr, uint64_t data32)
void arm_cpu_list_available_types(void)
struct arm_cpu_type_def cpu_type
#define ARM_CACHETYPE_IASSOC_SHIFT
void arm_invalidate_code_translation(struct cpu *cpu, uint64_t, int)
#define ARM_AUXCTRL_MD_SHIFT
void arm_update_translation_table(struct cpu *cpu, uint64_t vaddr_page, unsigned char *host_page, int writeflag, uint64_t paddr_page)
void arm_push(struct cpu *cpu, uint32_t *np, int p_bit, int u_bit, int s_bit, int w_bit, uint16_t regs)
#define ARM_EXCEPTION_DATA_ABT
void interrupt_handler_register(struct interrupt *templ)
void(* interrupt_deassert)(struct interrupt *)
void arm_coproc_15(struct cpu *cpu, int opcode1, int opcode2, int l_bit, int crn, int crm, int rd)
void arm_load_register_bank(struct cpu *cpu)
void arm_cpu_register_dump(struct cpu *cpu, int gprs, int coprocs)
void arm_translation_table_set_l1_b(struct cpu *cpu, uint32_t vaddr, uint32_t paddr)
int(* run_instr)(struct cpu *cpu)
char * get_symbol_name(struct symbol_context *, uint64_t addr, uint64_t *offset)
uint32_t default_r8_r14[7]
#define ARM_CACHETYPE_DLINE_SHIFT
#define EMUL_LITTLE_ENDIAN
void arm_pop(struct cpu *cpu, uint32_t *np, int p_bit, int u_bit, int s_bit, int w_bit, uint32_t iw)
#define quick_pc_to_pointers(cpu)
#define ARM_CACHETYPE_HARVARD_SHIFT
void arm_exception(struct cpu *cpu, int exception_nr)
int arm_run_instr(struct cpu *cpu)
#define ARM_EXCEPTION_IRQ
#define ARM_CONTROL_ICACHE
#define ARM_CACHETYPE_CLASS_SHIFT
#define ARM_CACHETYPE_DSIZE_SHIFT
int(* memory_rw)(struct cpu *cpu, struct memory *mem, uint64_t vaddr, unsigned char *data, size_t len, int writeflag, int cache_flags)
#define ARM_EXCEPTION_SWI
int arm_translate_v2p(struct cpu *cpu, uint64_t vaddr64, uint64_t *return_paddr, int flags)
#define ARM_CONTROL_DATA32
#define ARM_CACHETYPE_ILINE_SHIFT
#define ARM_EXCEPTION_RESET
#define ARM_CONTROL_WBUFFER
#define ARM_CACHETYPE_ISIZE_SHIFT
#define ARM_CACHETYPE_DASSOC_SHIFT
void arm_pc_to_pointers(struct cpu *cpu)
#define ARM_THUMB_DPI_NAMES
int arm_cpu_disassemble_instr_thumb(struct cpu *cpu, unsigned char *ib, int running, uint64_t dumpaddr)
void cpu_functioncall_trace(struct cpu *cpu, uint64_t f)
#define CPU_SETTINGS_ADD_REGISTER32(name, var)
#define ARM_EXCEPTION_PREF_ABT
void cpu_functioncall_trace_return(struct cpu *cpu)
void arm_cpu_tlbdump(struct machine *m, int x, int rawflag)
void COMBINE() strlen(struct cpu *cpu, struct arm_instr_call *ic, int low_addr)
int arm_cpu_disassemble_instr(struct cpu *cpu, unsigned char *ib, int running, uint64_t dumpaddr)
#define CACHE_INSTRUCTION
struct symbol_context symbol_context
#define ARM_CONDITION_STRINGS
int arm_cpu_new(struct cpu *cpu, struct memory *mem, struct machine *machine, int cpu_id, char *cpu_type_name)
void(* coproc[16])(struct cpu *, int opcode1, int opcode2, int l_bit, int crn, int crm, int rd)
void(* update_translation_table)(struct cpu *, uint64_t vaddr_page, unsigned char *host_page, int writeflag, uint64_t paddr_page)
void arm_irq_interrupt_assert(struct interrupt *interrupt)
void arm_irq_interrupt_deassert(struct interrupt *interrupt)
addr & if(addr >=0x24 &&page !=NULL)
#define ARM_CPU_TYPE_DEFS
#define ARM_CONTROL_CACHE
#define ARM_EXCEPTION_FIQ
void arm_coproc_xscale_14(struct cpu *cpu, int opcode1, int opcode2, int l_bit, int crn, int crm, int rd)
void(* invalidate_code_translation)(struct cpu *, uint64_t paddr, int flags)
void arm_invalidate_translation_caches(struct cpu *cpu, uint64_t, int)
void arm_mcr_mrc(struct cpu *cpu, uint32_t iword)
#define CPU_SETTINGS_ADD_REGISTER64(name, var)
void arm_translation_table_set_l1(struct cpu *cpu, uint32_t vaddr, uint32_t paddr)
void arm_cpu_dumpinfo(struct cpu *cpu)
#define ARM_CONTROL_PROG32
void arm_setup_initial_translation_table(struct cpu *cpu, uint32_t ttb_addr)
void arm_cdp(struct cpu *cpu, uint32_t iword)
#define ARM_EXCEPTION_UND
int arm_cpu_interpret_thumb_SLOW(struct cpu *cpu)
void(* invalidate_translation_caches)(struct cpu *, uint64_t paddr, int flags)