69 static int arm_dpi_uses_d[16] = { 1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1 };
70 static int arm_dpi_uses_n[16] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0 };
102 while (i >= 0 && cpu_type_defs[i].
name != NULL) {
103 if (strcasecmp(cpu_type_defs[i].
name, cpu_type_name) == 0) {
148 isize = 1 << (isize - 10);
150 dsize = 1 << (dsize - 10);
151 debug(
" (I+D = %i+%i KB)", isize, dsize);
198 memset(&templ, 0,
sizeof(templ));
222 unsigned char nothing[16384];
230 memset(nothing, 0,
sizeof(nothing));
233 for (i=0; i<256; i++)
234 for (j=0x0; j<=0xf; j++) {
235 unsigned char descr[4];
237 (((j << 28) + (i << 20)) >> 18);
238 uint32_t d = (1048576*i) | 0xc02;
241 descr[0] = d; descr[1] = d >> 8;
242 descr[2] = d >> 16; descr[3] = d >> 24;
244 descr[3] = d; descr[2] = d >> 8;
245 descr[1] = d >> 16; descr[0] = d >> 24;
259 unsigned int i, j, vhigh = vaddr >> 28, phigh = paddr >> 28;
261 for (i=0; i<256; i++)
262 for (j=vhigh; j<=vhigh; j++) {
263 unsigned char descr[4];
265 (((j << 28) + (i << 20)) >> 18);
266 uint32_t d = ((phigh << 28) + 1048576*i) | 0xc02;
269 descr[0] = d; descr[1] = d >> 8;
270 descr[2] = d >> 16; descr[3] = d >> 24;
272 descr[3] = d; descr[2] = d >> 8;
273 descr[1] = d >> 16; descr[0] = d >> 24;
287 unsigned int i, j, vhigh = vaddr >> 24, phigh = paddr >> 24;
290 for (j=vhigh; j<=vhigh; j++) {
291 unsigned char descr[4];
293 (((j << 24) + (i << 20)) >> 18);
294 uint32_t d = ((phigh << 24) + 1048576*i) | 0xc02;
297 descr[0] = d; descr[1] = d >> 8;
298 descr[2] = d >> 16; descr[3] = d >> 24;
300 descr[3] = d; descr[2] = d >> 8;
301 descr[1] = d >> 16; descr[0] = d >> 24;
316 debug(
" (I+D = %i+%i KB)\n",
332 while (tdefs[i].
name != NULL) {
337 if ((i % 5) == 0 || tdefs[i].
name == NULL)
364 debug(
"cpu%i: cpsr = ", x);
365 debug(
"%s%s%s%s%s%s%s%s%s%s%s",
378 debug(
" pc = 0x%07x", (
int)(
cpu->
pc & 0x03ffffff));
388 debug(
" %s = 0x%08x", arm_regname[i],
400 debug(
"USR32)\n");
break;
402 debug(
"SYS32)\n");
break;
404 debug(
"FIQ32)\n");
break;
406 debug(
"IRQ32)\n");
break;
408 debug(
"SVC32)\n");
break;
410 debug(
"ABT32)\n");
break;
412 debug(
"UND32)\n");
break;
413 default:
debug(
"unimplemented)\n");
417 debug(
"cpu%i: usr r8-14:", x);
424 debug(
"cpu%i: fiq r8-14:", x);
431 debug(
"cpu%i: irq r13-14:", x);
438 debug(
"cpu%i: svc r13-14:", x);
445 debug(
"cpu%i: abt r13-14:", x);
452 debug(
"cpu%i: und r13-14:", x);
461 debug(
"cpu%i: MMU: %s\n", x,
464 debug(
"cpu%i: alignment checks: %s\n", x,
467 debug(
"cpu%i: [data] cache: %s\n", x,
470 debug(
"cpu%i: instruction cache: %s\n", x,
473 debug(
"cpu%i: write buffer: %s\n", x,
476 debug(
"cpu%i: prog32: %s\n", x,
479 debug(
"cpu%i: data32: %s\n", x,
482 debug(
"cpu%i: endianness: %s\n", x,
485 debug(
"cpu%i: high vectors: %s\n", x,
491 debug(
"cpu%i: auxctrl = 0x%08x\n", x,
493 debug(
"cpu%i: minidata cache attr = 0x%x\n", x,
496 debug(
"cpu%i: page table memory attr: %i\n", x,
498 debug(
"cpu%i: write buffer coalescing: %s\n", x,
500 "disabled" :
"enabled");
503 debug(
"cpu%i: ttb = 0x%08x dacr = 0x%08x\n", x,
505 debug(
"cpu%i: fsr = 0x%08x far = 0x%08x\n", x,
521 &
cpu->
cd.
arm.
r[8],
sizeof(uint32_t) * 7);
525 &
cpu->
cd.
arm.
r[8],
sizeof(uint32_t) * 7);
529 &
cpu->
cd.
arm.
r[8],
sizeof(uint32_t) * 5);
535 &
cpu->
cd.
arm.
r[8],
sizeof(uint32_t) * 5);
541 &
cpu->
cd.
arm.
r[8],
sizeof(uint32_t) * 5);
547 &
cpu->
cd.
arm.
r[8],
sizeof(uint32_t) * 5);
551 default:
fatal(
"arm_save_register_bank: unimplemented mode %i\n",
572 sizeof(uint32_t) * 7);
598 default:
fatal(
"arm_load_register_bank: unimplemented mode %i\n",
610 int oldmode, newmode;
614 fatal(
"arm_exception(): exception_nr = %i\n", exception_nr);
621 debug(
"[ arm_exception(): ");
622 switch (exception_nr) {
624 fatal(
"RESET: TODO");
633 debug(
"PREFETCH ABORT");
642 debug(
"DATA ABORT, far=0x%08x fsr=0x%02x",
649 switch (exception_nr) {
652 fatal(
"ARM RESET: TODO");
666 switch (arm_exception_to_mode[exception_nr]) {
677 default:
fatal(
"arm_exception(): unimplemented exception nr\n");
690 cpu->
cd.
arm.
cpsr |= arm_exception_to_mode[exception_nr];
701 fatal(
"[ WARNING! Exception caused no mode change? "
702 "mode 0x%02x (pc=0x%x) ]\n", newmode, (
int)
cpu->
pc);
767 int running, uint64_t dumpaddr)
771 iw = ib[0] + (ib[1]<<8);
773 iw = ib[1] + (ib[0]<<8);
774 debug(
"%04x \t", (
int)iw);
776 int main_opcode = (iw >> 12) & 15;
777 int r6 = (iw >> 6) & 7;
778 int rs_rb = (iw >> 3) & 7;
780 int offset5 = (iw >> 6) & 0x1f;
781 int b_bit = (iw >> 12) & 1;
782 int l_bit = (iw >> 11) & 1;
783 int addsub_op = (iw >> 9) & 1;
784 int addsub_immediate = (iw >> 10) & 1;
785 int op11 = (iw >> 11) & 3;
786 int op10 = (iw >> 10) & 3;
787 int rd8 = (iw >> 8) & 7;
788 int op8 = (iw >> 8) & 3;
789 int h1 = (iw >> 7) & 1;
790 int h2 = (iw >> 6) & 1;
791 int condition_code = (iw >> 8) & 15;
792 const char* condition = arm_condition_string[condition_code];
804 debug(
"%ss\tr%i,r%i,#%i\n",
805 op11 & 1 ?
"lsr" : (op11 & 2 ?
"asr" :
"lsl"),
811 debug(
"%s\tr%i,r%i,%s%i\n",
812 addsub_op ?
"subs" :
"adds",
815 addsub_immediate ?
"#" :
"r",
825 debug(
"%s\tr%i,r%i,#%i\n",
826 op11 & 1 ?
"subs" :
"adds",
830 debug(
"%s\tr%i,#%i\n",
831 op11 & 1 ?
"cmp" :
"movs",
842 arm_thumb_dpiname[(iw >> 6) & 15],
864 if (h1 == 0 && h2 == 0) {
865 debug(
"TODO main_opcode = %i, op10 = %i, h1 AND h2 are zero?!\n", main_opcode, op10);
868 debug(
"add\tr%i,r%i,r%i\n", rd, rd, rs_rb);
870 if (op8 == 2 && rd == rs_rb)
874 op8 == 1 ?
"cmp" :
"mov",
888 debug(
"TODO main_opcode = %i, op10 = %i, h1 set for BX?!\n", main_opcode, op10);
890 debug(
"bx\t%s\n", arm_regname[rs_rb]);
903 debug(
"ldr\t%s,[pc,#%i]\t; ",
910 tmp = (dumpaddr & ~3) + 4 + (iw & 0xff) * 4;
911 debug(
"0x%x", (
int)tmp);
923 switch ((iw >> 9) & 7) {
924 case 0:
debug(
"str");
break;
925 case 1:
debug(
"strh");
break;
926 case 2:
debug(
"strb");
break;
927 case 3:
debug(
"ldrsb");
break;
928 case 4:
debug(
"ldr");
break;
929 case 5:
debug(
"ldrh");
break;
930 case 6:
debug(
"ldrb");
break;
931 case 7:
debug(
"ldrsh");
break;
933 debug(
"\t%s,[%s,%s]\n",
942 debug(
"%s%s\tr%i,[r%i,#%i]\n",
943 l_bit ?
"ldr" :
"str",
947 offset5 * (b_bit ?
sizeof(uint8_t) :
sizeof(uint32_t)));
952 debug(
"%sh\tr%i,[r%i,#%i]\n",
953 l_bit ?
"ldr" :
"str",
956 offset5 *
sizeof(uint16_t));
961 debug(
"%s\t%s,[sp,#%i]\n",
962 l_bit ?
"ldr" :
"str",
969 debug(
"add\t%s,%s,#%i\n",
971 iw & 0x0800 ?
"sp" :
"pc",
977 switch (condition_code) {
979 tmp = (iw & 0x7f) << 2;
980 debug(iw & 0x80 ?
"sub" :
"add");
981 debug(
"\tsp,#%i\n", tmp);
987 debug(condition_code & 8 ?
"pop" :
"push");
989 for (tmp=0; tmp<8; ++tmp) {
991 debug(
"%s,", arm_regname[tmp]);
993 if (condition_code & 1) {
994 if (condition_code & 8)
1006 debug(
"TODO: unimplemented opcode 0x%x,0x%x\n", main_opcode, condition_code);
1011 if (condition_code < 0xe) {
1013 debug(
"b%s\t", condition);
1014 tmp = (iw & 0xff) << 1;
1017 tmp = (int32_t)(dumpaddr + 4 + tmp);
1018 debug(
"0x%x", (
int)tmp);
1024 }
else if (condition_code == 0xf) {
1025 debug(
"swi\t#0x%x\n", iw & 0xff);
1027 debug(
"UNIMPLEMENTED\n");
1044 debug(
"offset depending on prefix at runtime\n");
1046 tmp = (iw & 0x7ff) << 1;
1049 tmp = (int32_t)(dumpaddr + 4 + tmp);
1050 debug(
"b\t0x%x", (
int)tmp);
1070 debug(
"offset depending on prefix at runtime\n");
1072 tmp32 = iw & 0x07ff;
1074 tmp32 |= 0xfffff800;
1076 debug(
"bprefix\t0x%x\n", tmp32);
1081 debug(
"TODO: unimplemented opcode 0x%x\n", main_opcode);
1084 return sizeof(uint16_t);
1100 uint8_t ib[
sizeof(uint16_t)];
1104 fatal(
"arm_cpu_interpret_thumb_SLOW called when not in "
1112 fatal(
"arm_cpu_interpret_thumb_SLOW(): could not read "
1113 "the instruction\n");
1122 if (
symbol != NULL && offset == 0)
1133 iw = ib[0] + (ib[1]<<8);
1135 iw = ib[1] + (ib[0]<<8);
1139 int main_opcode = (iw >> 12) & 15;
1140 int condition_code = (iw >> 8) & 15;
1141 int op10 = (iw >> 10) & 3;
1142 int op11_8 = (iw >> 8) & 15;
1143 int rd8 = (iw >> 8) & 7;
1144 int r6 = (iw >> 6) & 7;
1145 int r3 = (iw >> 3) & 7;
1146 int rd = (iw >> 0) & 7;
1147 int hd = (iw >> 7) & 1;
1148 int hm = (iw >> 6) & 1;
1149 int imm6 = (iw >> 6) & 31;
1150 uint8_t word[
sizeof(uint32_t)];
1154 switch (main_opcode)
1186 if (!(iw & 0x0800)) {
1190 tmp = (int32_t)tmp >> (imm6 - 1);
1206 int isSub = iw & 0x0200;
1207 int isImm3 = iw & 0x0400;
1209 uint64_t tmp64 = isImm3 ? r6 :
cpu->
cd.
arm.
r[r6];
1210 tmp64 = (uint32_t)(isSub ? -tmp64 : tmp64);
1211 uint64_t result = old + tmp64;
1216 if ((int32_t)result < 0)
1218 if (result & 0x100000000ULL)
1220 if (result & 0x80000000) {
1221 if ((tmp64 & 0x80000000) == 0 && (old & 0x80000000) == 0)
1224 if ((tmp64 & 0x80000000) != 0 && (old & 0x80000000) != 0)
1234 uint64_t tmp64 = (uint32_t)(-(iw & 0xff));
1235 uint64_t result = old + tmp64;
1239 if ((int32_t)result < 0)
1241 if (result & 0x100000000ULL)
1243 if (result & 0x80000000) {
1244 if ((tmp64 & 0x80000000) == 0 && (old & 0x80000000) == 0)
1247 if ((tmp64 & 0x80000000) != 0 && (old & 0x80000000) != 0)
1262 uint64_t tmp64 = iw & 0xff;
1265 tmp64 = (uint32_t)(-tmp64);
1267 uint64_t result = old + tmp64;
1273 if ((int32_t)result < 0)
1275 if (result & 0x100000000ULL)
1277 if (result & 0x80000000) {
1278 if ((tmp64 & 0x80000000) == 0 && (old & 0x80000000) == 0)
1281 if ((tmp64 & 0x80000000) != 0 && (old & 0x80000000) != 0)
1291 switch ((iw >> 6) & 15) {
1311 for (
int i = 0; i < (amount & 31); ++i) {
1324 if (amount != 0 && (amount & 31) == 0) {
1341 if ((int32_t)tmp < 0)
1347 uint64_t tmp64 = (uint32_t) (-
cpu->
cd.
arm.
r[r3]);
1348 uint64_t result = old + tmp64;
1352 if ((int32_t)result < 0)
1354 if (result & 0x100000000ULL)
1356 if (result & 0x80000000) {
1357 if ((tmp64 & 0x80000000) == 0 && (old & 0x80000000) == 0)
1360 if ((tmp64 & 0x80000000) != 0 && (old & 0x80000000) != 0)
1382 debug(
"TODO: unimplemented DPI %i at pc 0x%08x\n", (iw >> 6) & 15, (int)
cpu->
pc);
1397 debug(
"TODO: double check with manual whether it is correct to use old pc + 8 here; at pc 0x%08x\n", (
int)
cpu->
pc);
1412 if ((iw & 0xff87) == 0x4700) {
1414 int rm = (iw >> 3) & 15;
1422 debug(
"TODO: unimplemented opcode 0x%x,%i at pc 0x%08x\n", main_opcode, op11_8, (
int)
cpu->
pc);
1428 debug(
"TODO: unimplemented opcode 0x%x,%i at pc 0x%08x\n", main_opcode, op11_8, (
int)
cpu->
pc);
1440 tmp = (
addr & ~3) + 4 + (iw & 0xff) * 4;
1444 fatal(
"arm_cpu_interpret_thumb_SLOW(): could not load pc-relative word\n");
1450 tmp = word[0] + (word[1]<<8) + (word[2]<<16) + (word[3]<<24);
1452 tmp = word[3] + (word[2]<<8) + (word[1]<<16) + (word[0]<<24);
1458 debug(
"TODO: unimplemented opcode 0x%x,%i at pc 0x%08x\n", main_opcode, op10, (
int)
cpu->
pc);
1468 len = main_opcode == 6 ? 4 : (main_opcode == 7 ? 1 : 2);
1469 isLoad = iw & 0x0800;
1477 for (
int i = 0; i < len; ++i)
1478 word[i] = (tmp >> (8*i));
1480 for (
int i = 0; i < len; ++i)
1481 word[len - 1 - i] = (tmp >> (8*i));
1487 fatal(
"arm_cpu_interpret_thumb_SLOW(): could not load with immediate offset\n");
1495 for (
int i = 0; i < len; ++i) {
1497 tmp |= word[len - 1 - i];
1500 for (
int i = 0; i < len; ++i) {
1516 fatal(
"arm_cpu_interpret_thumb_SLOW(): could not load sp-relative word\n");
1522 tmp = word[0] + (word[1]<<8) + (word[2]<<16) + (word[3]<<24);
1524 tmp = word[3] + (word[2]<<8) + (word[1]<<16) + (word[0]<<24);
1530 for (
size_t i = 0; i <
sizeof(word); ++i)
1531 word[i] = (tmp >> (8*i));
1533 for (
size_t i = 0; i <
sizeof(word); ++i)
1534 word[
sizeof(word) - 1 - i] = (tmp >> (8*i));
1540 fatal(
"arm_cpu_interpret_thumb_SLOW(): could not store sp-relative word\n");
1559 (iw & 0x100 ? (1 <<
ARM_LR) : 0));
1566 (iw & 0x100 ? (1 <<
ARM_PC) : 0));
1574 cpu->
pc +=
sizeof(uint16_t);
1577 debug(
"TODO: unimplemented opcode 0x%x,%i at pc 0x%08x\n", main_opcode, op11_8, (
int)
cpu->
pc);
1584 if (condition_code < 0xe) {
1586 tmp = (iw & 0xff) << 1;
1589 tmp = (int32_t)(
cpu->
pc + 4 + tmp);
1591 switch (condition_code) {
1640 }
else if (condition_code == 0xf) {
1644 debug(
"TODO: unimplemented opcode 0x%x, non-branch, at pc 0x%08x\n", main_opcode, (
int)
cpu->
pc);
1656 fatal(
"lowest bit set in thumb blx instruction?\n");
1669 tmp = (iw & 0x7ff) << 1;
1688 uint32_t tmp32 = iw & 0x07ff;
1690 tmp32 |= 0xfffff800;
1697 debug(
"TODO: unimplemented opcode 0x%x at pc 0x%08x\n", main_opcode, (
int)
cpu->
pc);
1702 cpu->
pc +=
sizeof(uint16_t);
1721 int running, uint64_t dumpaddr)
1724 int main_opcode, secondary_opcode, s_bit, r16, r12, r8;
1725 int i, n, p_bit, u_bit, b_bit, w_bit, l_bit;
1726 const char *
symbol, *condition;
1734 if (
symbol != NULL && offset == 0)
1740 debug(
"%08x: ", (
int)dumpaddr & ~1);
1746 iw = ib[0] + (ib[1]<<8) + (ib[2]<<16) + (ib[3]<<24);
1748 iw = ib[3] + (ib[2]<<8) + (ib[1]<<16) + (ib[0]<<24);
1749 debug(
"%08x\t", (
int)iw);
1751 condition = arm_condition_string[iw >> 28];
1752 main_opcode = (iw >> 24) & 15;
1753 secondary_opcode = (iw >> 21) & 15;
1754 u_bit = (iw >> 23) & 1;
1755 b_bit = (iw >> 22) & 1;
1756 w_bit = (iw >> 21) & 1;
1757 s_bit = l_bit = (iw >> 20) & 1;
1758 r16 = (iw >> 16) & 15;
1759 r12 = (iw >> 12) & 15;
1760 r8 = (iw >> 8) & 15;
1762 if (iw == 0xf10c0040) {
1763 debug(
"cpsid\tf\n");
1764 return sizeof(uint32_t);
1765 }
else if (iw == 0xf10c0080) {
1766 debug(
"cpsid\ti\n");
1767 return sizeof(uint32_t);
1768 }
else if (iw == 0xf57ff04f) {
1770 return sizeof(uint32_t);
1771 }
else if (iw == 0xf57ff05f) {
1773 return sizeof(uint32_t);
1774 }
else if (iw == 0xf57ff06f) {
1776 return sizeof(uint32_t);
1777 }
else if ((iw >> 28) == 0xf) {
1778 switch (main_opcode) {
1781 tmp = (iw & 0xffffff);
1784 tmp = (int32_t)(dumpaddr + 8 + 4*tmp + (main_opcode == 0xb? 2 : 0)) + 1;
1785 debug(
"blx\t0x%x", (
int)tmp);
1792 default:
debug(
"UNIMPLEMENTED\n");
1794 return sizeof(uint32_t);
1797 switch (main_opcode) {
1810 if ((iw & 0x0ff00fff) == 0x01900f9f) {
1812 debug(
"ldrex%s\t%s,%s",
1819 if ((iw & 0x0ff00ff0) == 0x01800f90) {
1821 debug(
"strex%s\t%s,%s,%s",
1824 arm_regname[iw & 15],
1834 if ((iw & 0x0ff000f0) == 0x00600090) {
1835 debug(
"mls%s\t", condition);
1836 debug(
"%s,", arm_regname[r16]);
1837 debug(
"%s,", arm_regname[iw & 15]);
1838 debug(
"%s,", arm_regname[r8]);
1839 debug(
"%s", arm_regname[r12]);
1848 if ((iw & 0x0fc000f0) == 0x00000090) {
1849 int a_bit = (iw >> 21) & 1;
1850 debug(
"%s%s%s\t", a_bit?
"mla" :
"mul",
1851 condition, s_bit?
"s" :
"");
1852 debug(
"%s,", arm_regname[r16]);
1853 debug(
"%s,", arm_regname[iw & 15]);
1854 debug(
"%s", arm_regname[r8]);
1856 debug(
",%s", arm_regname[r12]);
1865 if ((iw & 0x0f8000f0) == 0x00800090) {
1866 int a_bit = (iw >> 21) & 1;
1867 u_bit = (iw >> 22) & 1;
1868 debug(
"%s%sl%s%s\t", u_bit?
"s" :
"u",
1869 a_bit?
"mla" :
"mul", condition, s_bit?
"s" :
"");
1870 debug(
"%s,%s,", arm_regname[r12], arm_regname[r16]);
1871 debug(
"%s,%s\n", arm_regname[iw&15], arm_regname[r8]);
1881 if ((iw & 0x0f900ff0) == 0x01000050) {
1882 debug(
"q%s%s%s\t", iw & 0x400000?
"d" :
"",
1883 iw & 0x200000?
"sub" :
"add", condition);
1884 debug(
"%s,%s,%s\n", arm_regname[r12],
1885 arm_regname[iw&15], arm_regname[r16]);
1892 if ((iw & 0x0ff000d0) == 0x01200010) {
1894 debug(
"b%sx%s\t%s\n", l_bit?
"l" :
"", condition,
1895 arm_regname[iw & 15]);
1904 if ((iw & 0x0fb0fff0) == 0x0120f000 ||
1905 (iw & 0x0fb0f000) == 0x0320f000) {
1906 debug(
"msr%s\t%s", condition, (iw&0x400000)?
"S":
"C");
1908 if (iw & (1<<19))
debug(
"f");
1909 if (iw & (1<<18))
debug(
"s");
1910 if (iw & (1<<17))
debug(
"x");
1911 if (iw & (1<<16))
debug(
"c");
1912 if (iw & 0x02000000) {
1913 int r = (iw >> 7) & 30;
1914 uint32_t b = iw & 0xff;
1916 b = (b >> 1) | ((b & 1) << 31);
1917 debug(
",#0x%x\n", b);
1919 debug(
",%s\n", arm_regname[iw & 15]);
1922 if ((iw & 0x0fbf0fff) == 0x010f0000) {
1923 debug(
"mrs%s\t", condition);
1924 debug(
"%s,%sPSR\n", arm_regname[r12],
1925 (iw&0x400000)?
"S":
"C");
1932 if ((iw & 0x0fb00ff0) == 0x01000090) {
1933 debug(
"swp%s%s\t", condition, (iw&0x400000)?
"b":
"");
1934 debug(
"%s,%s,[%s]\n", arm_regname[r12],
1935 arm_regname[iw & 15], arm_regname[r16]);
1942 if ((iw & 0x0ff000f0) == 0x01200070) {
1943 debug(
"bkpt%s\t0x%04x\n", condition,
1944 ((iw & 0x000fff00) >> 4) + (iw & 0xf));
1951 if ((iw & 0x0fff0ff0) == 0x016f0f10) {
1952 debug(
"clz%s\t", condition);
1953 debug(
"%s,%s\n", arm_regname[r12], arm_regname[iw&15]);
1960 if ((iw & 0x0ff00000) == 0x03000000) {
1961 debug(
"movw%s\t", condition);
1962 debug(
"%s,#%i\n", arm_regname[r12],
1963 ((iw & 0xf0000) >> 4) | (iw & 0xfff));
1970 if ((iw & 0x0ff00000) == 0x03400000) {
1971 debug(
"movt%s\t", condition);
1972 debug(
"%s,#%i\n", arm_regname[r12],
1973 ((iw & 0xf0000) >> 4) | (iw & 0xfff));
1984 if ((iw & 0x0ff00090) == 0x01000080) {
1985 debug(
"smla%s%s%s\t",
1986 iw & 0x20?
"t" :
"b", iw & 0x40?
"t" :
"b",
1988 debug(
"%s,%s,%s,%s\n", arm_regname[r16],
1989 arm_regname[iw&15], arm_regname[r8],
1993 if ((iw & 0x0ff00090) == 0x01400080) {
1994 debug(
"smlal%s%s%s\t",
1995 iw & 0x20?
"t" :
"b", iw & 0x40?
"t" :
"b",
1997 debug(
"%s,%s,%s,%s\n", arm_regname[r12],
1998 arm_regname[r16], arm_regname[iw&15],
2002 if ((iw & 0x0ff000b0) == 0x01200080) {
2003 debug(
"smlaw%s%s\t", iw & 0x40?
"t" :
"b",
2005 debug(
"%s,%s,%s,%s\n", arm_regname[r16],
2006 arm_regname[iw&15], arm_regname[r8],
2010 if ((iw & 0x0ff0f090) == 0x01600080) {
2011 debug(
"smul%s%s%s\t",
2012 iw & 0x20?
"t" :
"b", iw & 0x40?
"t" :
"b",
2014 debug(
"%s,%s,%s\n", arm_regname[r16],
2015 arm_regname[iw&15], arm_regname[r8]);
2018 if ((iw & 0x0ff0f0b0) == 0x012000a0) {
2019 debug(
"smulw%s%s\t", iw & 0x40?
"t" :
"b",
2021 debug(
"%s,%s,%s\n", arm_regname[r16],
2022 arm_regname[iw&15], arm_regname[r8]);
2029 if ((iw & 0x0e000090) == 0x00000090) {
2030 const char *
op =
"st";
2031 int imm = ((iw >> 4) & 0xf0) | (iw & 0xf);
2032 int regform = !(iw & 0x00400000);
2033 p_bit = main_opcode & 1;
2038 if (!l_bit && (iw & 0xd0) == 0xd0 && (r12 & 1)) {
2039 debug(
"TODO: r12 odd, not load/store\n");
2043 if (iw & 0x00100000)
2045 if (!l_bit && (iw & 0xd0) == 0xd0) {
2051 debug(
"%sr%s",
op, condition);
2052 if (!l_bit && (iw & 0xd0) == 0xd0) {
2062 debug(
"\t%s,[%s", arm_regname[r12], arm_regname[r16]);
2066 debug(
",%s%s", u_bit?
"" :
"-",
2067 arm_regname[iw & 15]);
2070 debug(
",#%s%i", u_bit?
"" :
"-",
2073 debug(
"]%s\n", w_bit?
"!" :
"");
2078 debug(
"%s%s\n", u_bit?
"" :
"-",
2079 arm_regname[iw & 15]);
2081 debug(
"#%s%i\n", u_bit?
"" :
"-", imm);
2087 if (iw & 0x80 && !(main_opcode & 2) && iw & 0x10) {
2088 debug(
"UNIMPLEMENTED reg (c!=0), t odd\n");
2099 debug(
"%s%s%s\t", arm_dpiname[secondary_opcode],
2100 condition, s_bit?
"s" :
"");
2101 if (arm_dpi_uses_d[secondary_opcode])
2102 debug(
"%s,", arm_regname[r12]);
2103 if (arm_dpi_uses_n[secondary_opcode])
2104 debug(
"%s,", arm_regname[r16]);
2106 if (main_opcode & 2) {
2108 int r = (iw >> 7) & 30;
2109 uint32_t b = iw & 0xff;
2111 b = (b >> 1) | ((b & 1) << 31);
2118 int t = (iw >> 4) & 7;
2119 int c = (iw >> 7) & 31;
2120 debug(
"%s", arm_regname[iw & 15]);
2123 debug(
", lsl #%i", c);
2125 case 1:
debug(
", lsl %s", arm_regname[c >> 1]);
2127 case 2:
debug(
", lsr #%i", c? c : 32);
2129 case 3:
debug(
", lsr %s", arm_regname[c >> 1]);
2131 case 4:
debug(
", asr #%i", c? c : 32);
2133 case 5:
debug(
", asr %s", arm_regname[c >> 1]);
2136 debug(
", ror #%i", c);
2140 case 7:
debug(
", ror %s", arm_regname[c >> 1]);
2145 if (
running &&
t == 0 && c == 0 && secondary_opcode
2161 if ((iw & 0xfc70f000) == 0xf450f000) {
2163 debug(
"pld\t[%s]\n", arm_regname[r16]);
2167 if ((iw & 0x0fff0ff0) == 0x06bf0f30) {
2169 debug(
"rev%s\t%s,%s",
2172 arm_regname[iw & 15]);
2177 if ((iw & 0x0fff03f0) == 0x06bf0070) {
2179 debug(
"sxth%s\t%s,%s",
2182 arm_regname[iw & 15]);
2183 int rot = ((iw & 0xc00) >> 10) << 3;
2190 if ((iw & 0x0fff03f0) == 0x06ef0070) {
2192 debug(
"uxtb%s\t%s,%s",
2195 arm_regname[iw & 15]);
2196 int rot = ((iw & 0xc00) >> 10) << 3;
2204 if ((iw & 0x0ff003f0) == 0x06e00070) {
2206 debug(
"uxtab%s\t%s,%s,%s",
2210 arm_regname[iw & 15]);
2211 int rot = ((iw & 0xc00) >> 10) << 3;
2218 if ((iw & 0x0fff03f0) == 0x06ff0070) {
2220 debug(
"uxth%s\t%s,%s",
2223 arm_regname[iw & 15]);
2224 int rot = ((iw & 0xc00) >> 10) << 3;
2232 if ((iw & 0x0ff003f0) == 0x06f00070) {
2234 debug(
"uxtah%s\t%s,%s,%s",
2238 arm_regname[iw & 15]);
2239 int rot = ((iw & 0xc00) >> 10) << 3;
2246 if ((iw & 0x0fe00070) == 0x07c00010) {
2248 debug(
"bfi%s\t%s,%s",
2251 arm_regname[iw & 15]);
2252 int lsb = (iw >> 7) & 31;
2253 int msb = (iw >> 16) & 31;
2254 int width = msb - lsb + 1;
2256 debug(
",%i", width);
2261 if ((iw & 0x0fe00070) == 0x07e00050) {
2263 debug(
"ubfx%s\t%s,%s",
2266 arm_regname[iw & 15]);
2267 debug(
",%i", (iw >> 7) & 31);
2268 debug(
",%i", 1 + ((iw >> 16) & 31));
2273 if ((iw & 0x0fe00070) == 0x07a00050) {
2275 debug(
"sbfx%s\t%s,%s",
2278 arm_regname[iw & 15]);
2279 debug(
",%i", (iw >> 7) & 31);
2280 debug(
",%i", 1 + ((iw >> 16) & 31));
2285 if ((iw & 0x0fffffff) == 0x07f001f2) {
2286 debug(
"linux_bug%s\t; see https://github.com/torvalds/linux/blob/master/arch/arm/include/asm/bug.h\n",
2296 p_bit = main_opcode & 1;
2297 if (main_opcode >= 6 && iw & 0x10) {
2298 debug(
"TODO: single data transf. but 0x10\n");
2301 debug(
"%s%s%s", l_bit?
"ldr" :
"str",
2302 condition, b_bit?
"b" :
"");
2303 if (!p_bit && w_bit)
2305 debug(
"\t%s,[%s", arm_regname[r12], arm_regname[r16]);
2306 if ((iw & 0x0e000000) == 0x04000000) {
2308 uint32_t imm = iw & 0xfff;
2312 debug(
",#%s%i", u_bit?
"" :
"-", imm);
2315 }
else if ((iw & 0x0e000010) == 0x06000000) {
2319 if ((iw & 0xfff) != 0)
2320 debug(
",%s%s", u_bit?
"" :
"-",
2321 arm_regname[iw & 15]);
2322 if ((iw & 0xff0) != 0x000) {
2323 int c = (iw >> 7) & 31;
2324 int t = (iw >> 4) & 7;
2327 debug(
", lsl #%i", c);
2329 case 2:
debug(
", lsr #%i", c? c : 32);
2331 case 4:
debug(
", asr #%i", c? c : 32);
2334 debug(
", ror #%i", c);
2346 debug(
"%s", (p_bit && w_bit)?
"!" :
"");
2347 if ((iw & 0x0f000000) == 0x05000000 &&
2349 unsigned char tmpw[4];
2350 uint32_t imm = iw & 0xfff;
2351 uint32_t
addr = (u_bit? imm : -imm);
2353 addr += dumpaddr + 8;
2368 addr = tmpw[0] +(tmpw[1] << 8) +
2369 (tmpw[2]<<16)+(tmpw[3]<<24);
2371 addr = tmpw[3] + (tmpw[2]<<8) +
2372 (tmpw[1]<<16)+(tmpw[0]<<24);
2380 debug(
"%i", tmpw[0]);
2386 else if ((int32_t)
addr > -256 &&
2387 (int32_t)
addr < 256)
2400 p_bit = main_opcode & 1;
2402 debug(
"%s%s", l_bit?
"ldm" :
"stm", condition);
2403 switch (u_bit * 2 + p_bit) {
2404 case 0:
debug(
"da");
break;
2405 case 1:
debug(
"db");
break;
2406 case 2:
debug(
"ia");
break;
2407 case 3:
debug(
"ib");
break;
2409 debug(
"\t%s", arm_regname[r16]);
2414 for (i=0; i<16; i++)
2415 if ((iw >> i) & 1) {
2416 debug(
"%s%s", (n > 0)?
",":
"", arm_regname[i]);
2426 debug(
"b%s%s\t", main_opcode == 0xa?
"" :
"l", condition);
2427 tmp = (iw & 0x00ffffff) << 2;
2428 if (tmp & 0x02000000)
2430 tmp = (int32_t)(dumpaddr + tmp + 8);
2431 debug(
"0x%x", (
int)tmp);
2444 if ((iw & 0x0fe00fff) == 0x0c400000) {
2445 debug(
"%s%s\t", iw & 0x100000?
"mra" :
"mar",
2448 debug(
"%s,%s,acc0\n",
2449 arm_regname[r12], arm_regname[r16]);
2451 debug(
"acc0,%s,%s\n",
2452 arm_regname[r12], arm_regname[r16]);
2455 if ((iw & 0x0fe00000) == 0x0c400000) {
2456 debug(
"%s%s\t", iw & 0x100000?
"mrrc" :
"mcrr",
2458 debug(
"%i,%i,%s,%s,cr%i\n", r8, (iw >> 4) & 15,
2459 arm_regname[r12], arm_regname[r16], iw & 15);
2464 debug(
"TODO: coprocessor LDC/STC\n");
2471 if ((iw & 0x0ff00ff0) == 0x0e200010) {
2473 switch ((iw >> 16) & 0xf) {
2474 case 0:
debug(
"mia");
break;
2475 case 8:
debug(
"miaph");
break;
2476 case 12:
debug(
"miaBB");
break;
2477 case 13:
debug(
"miaTB");
break;
2478 case 14:
debug(
"miaBT");
break;
2479 case 15:
debug(
"miaTT");
break;
2480 default:
debug(
"UNKNOWN mia vector instruction?");
2482 debug(
"%s\t", condition);
2483 debug(
"acc%i,%s,%s\n", ((iw >> 5) & 7),
2484 arm_regname[iw & 15], arm_regname[r12]);
2489 (iw & 0x00100000)?
"mrc" :
"mcr", condition);
2490 debug(
"%i,%i,r%i,cr%i,cr%i,%i",
2491 (
int)((iw >> 8) & 15), (
int)((iw >>21) & 7),
2492 (
int)((iw >>12) & 15), (
int)((iw >>16) & 15),
2493 (
int)((iw >> 0) & 15), (
int)((iw >> 5) & 7));
2495 debug(
"cdp%s\t", condition);
2496 debug(
"%i,%i,cr%i,cr%i,cr%i",
2497 (
int)((iw >> 8) & 15),
2498 (
int)((iw >>20) & 15),
2499 (
int)((iw >>12) & 15),
2500 (
int)((iw >>16) & 15),
2501 (
int)((iw >> 0) & 15));
2503 debug(
",0x%x", (
int)((iw >> 5) & 7));
2508 debug(
"swi%s\t", condition);
2509 debug(
"0x%x\n", (
int)(iw & 0x00ffffff));
2511 default:
debug(
"UNIMPLEMENTED\n");
2514 return sizeof(uint32_t);
2531 int opcode1 = (iword >> 21) & 7;
2532 int l_bit = (iword >> 20) & 1;
2533 int crn = (iword >> 16) & 15;
2534 int rd = (iword >> 12) & 15;
2535 int cp_num = (iword >> 8) & 15;
2536 int opcode2 = (iword >> 5) & 7;
2537 int crm = iword & 15;
2543 fatal(
"[ TODO: arm_mcr_mrc: pc=0x%08x, iword=0x%08x: "
2544 "cp_num=%i ]\n", (
int)
cpu->
pc, iword, cp_num);
2562 fatal(
"[ arm_cdp: pc=0x%08x, iword=0x%08x ]\n", (
int)
cpu->
pc, iword);