annotate arm7dis/thumbdis.c @ 274:81641d82ccc6

fbdump2ppm: adjust for R2D's extra 32-bit word
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 20 Jan 2018 21:00:13 +0000
parents c883e60df239
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
107
c883e60df239 arm7dis: README and header comments added
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents: 103
diff changeset
1 /*
c883e60df239 arm7dis: README and header comments added
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents: 103
diff changeset
2 * Lean and mean ARM7TDMI disassembler
c883e60df239 arm7dis: README and header comments added
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents: 103
diff changeset
3 * Written by Spacefalcon the Outlaw
c883e60df239 arm7dis: README and header comments added
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents: 103
diff changeset
4 */
c883e60df239 arm7dis: README and header comments added
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents: 103
diff changeset
5
97
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
6 #include <sys/types.h>
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
7 #include <stdio.h>
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
8 #include <stdlib.h>
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
9 #include <string.h>
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
10 #include <strings.h>
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
11
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
12 extern char *binfilename;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
13 extern u_char *filemap;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
14 extern unsigned disasm_len, base_vma;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
15
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
16 extern unsigned get_u16(), get_u32();
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
17
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
18 extern char *regnames[16], *condition_decode[16], *shift_types[4];
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
19
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
20 static void
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
21 format_1_2(word)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
22 unsigned word;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
23 {
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
24 unsigned op, imm;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
25
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
26 op = (word >> 11) & 3;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
27 if (op != 3) {
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
28 /* format 1 */
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
29 imm = (word >> 6) & 0x1F;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
30 if (op != 0 && imm == 0)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
31 imm = 32;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
32 printf("%s\t%s, %s, #%u\n", shift_types[op], regnames[word&7],
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
33 regnames[(word>>3)&7], imm);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
34 return;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
35 }
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
36 /* format 2 */
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
37 printf("%s\t%s, %s, ", word&0x200 ? "sub" : "add", regnames[word&7],
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
38 regnames[(word>>3)&7]);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
39 if (word & 0x400)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
40 printf("#%u\n", (word >> 6) & 7);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
41 else
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
42 printf("%s\n", regnames[(word >> 6) & 7]);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
43 }
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
44
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
45 static void
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
46 format_3(word)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
47 unsigned word;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
48 {
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
49 static char *opctab[4] = {"mov", "cmp", "add", "sub"};
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
50 unsigned imm;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
51
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
52 imm = word & 0xFF;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
53 printf("%s\t%s, #%u", opctab[(word>>11)&3], regnames[(word>>8)&7], imm);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
54 if (imm > 9)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
55 printf("\t; 0x%x", imm);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
56 putchar('\n');
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
57 }
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
58
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
59 static void
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
60 format_4(word)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
61 unsigned word;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
62 {
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
63 static char *opc[16] = {"and", "eor", "lsl", "lsr",
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
64 "asr", "adc", "sbc", "ror",
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
65 "tst", "neg", "cmp", "cmn",
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
66 "orr", "mul", "bic", "mvn"};
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
67
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
68 printf("%s\t%s, %s\n", opc[(word>>6)&0xF], regnames[word&7],
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
69 regnames[(word>>3)&7]);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
70 }
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
71
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
72 static void
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
73 format_5_bx(word)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
74 unsigned word;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
75 {
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
76 if (word & 0x80)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
77 printf("<invalid: blx instead of bx>\n");
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
78 else
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
79 printf("bx\t%s\n", regnames[(word>>3)&0xF]);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
80 }
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
81
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
82 static void
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
83 format_5_hiops(word)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
84 unsigned word;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
85 {
101
78e4702884e3 thumbdis: nop recognition
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents: 97
diff changeset
86 static char *opctab[3] = {"add", "cmp", "mov"};
78e4702884e3 thumbdis: nop recognition
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents: 97
diff changeset
87 int reg1, reg2, op;
97
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
88
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
89 if (word & 0xC0) {
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
90 reg1 = word & 7;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
91 if (word & 0x80)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
92 reg1 += 8;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
93 reg2 = (word >> 3) & 0xF;
101
78e4702884e3 thumbdis: nop recognition
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents: 97
diff changeset
94 op = (word >> 8) & 3;
78e4702884e3 thumbdis: nop recognition
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents: 97
diff changeset
95 if (op == 2 && reg1 == reg2 && reg1 != 15)
78e4702884e3 thumbdis: nop recognition
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents: 97
diff changeset
96 printf("nop\t\t\t(mov %s, %s)\n",
78e4702884e3 thumbdis: nop recognition
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents: 97
diff changeset
97 regnames[reg1], regnames[reg2]);
78e4702884e3 thumbdis: nop recognition
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents: 97
diff changeset
98 else
78e4702884e3 thumbdis: nop recognition
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents: 97
diff changeset
99 printf("%s\t%s, %s\n", opctab[op],
78e4702884e3 thumbdis: nop recognition
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents: 97
diff changeset
100 regnames[reg1], regnames[reg2]);
97
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
101 } else
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
102 printf("<invalid: hi-reg format with both low regs>\n");
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
103 }
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
104
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
105 static void
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
106 format_5(word)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
107 unsigned word;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
108 {
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
109 if ((word & 0x300) == 0x300)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
110 format_5_bx(word);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
111 else
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
112 format_5_hiops(word);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
113 }
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
114
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
115 static void
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
116 format_6(off, word)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
117 unsigned off, word;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
118 {
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
119 unsigned loff, litoff;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
120
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
121 loff = (word & 0xFF) << 2;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
122 off &= ~3;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
123 off += 4;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
124 litoff = off + loff;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
125 if (litoff+4 <= disasm_len)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
126 printf("ldr\t%s, =0x%x\t; via 0x%x\n", regnames[(word>>8)&7],
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
127 get_u32(filemap + litoff), base_vma + litoff);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
128 else
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
129 printf("ldr\t%s, [pc, #%u]\t(0x%x)\n", regnames[(word>>8)&7],
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
130 loff, base_vma + litoff);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
131 }
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
132
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
133 static void
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
134 format_7(word)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
135 unsigned word;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
136 {
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
137 printf("%s%s\t%s, [%s, %s]\n", word&0x800 ? "ldr" : "str",
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
138 word&0x400 ? "b" : "", regnames[word&7],
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
139 regnames[(word>>3)&7], regnames[(word>>6)&7]);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
140 }
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
141
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
142 static void
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
143 format_8(word)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
144 unsigned word;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
145 {
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
146 static char *opc[4] = {"strh", "ldrsb", "ldrh", "ldrsh"};
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
147
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
148 printf("%s\t%s, [%s, %s]\n", opc[(word>>10)&3], regnames[word&7],
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
149 regnames[(word>>3)&7], regnames[(word>>6)&7]);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
150 }
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
151
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
152 static void
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
153 format_9(word)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
154 unsigned word;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
155 {
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
156 unsigned loff;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
157
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
158 loff = (word >> 6) & 0x1F;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
159 if (!(word & 0x1000))
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
160 loff <<= 2;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
161 printf("%s%s\t%s, [%s, #%u]", word&0x800 ? "ldr" : "str",
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
162 word&0x1000 ? "b" : "", regnames[word&7],
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
163 regnames[(word>>3)&7], loff);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
164 if (loff >= 10)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
165 printf("\t; 0x%x", loff);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
166 putchar('\n');
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
167 }
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
168
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
169 static void
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
170 format_10(word)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
171 unsigned word;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
172 {
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
173 unsigned loff;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
174
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
175 loff = (word >> 6) & 0x1F;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
176 loff <<= 1;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
177 printf("%sh\t%s, [%s, #%u]", word&0x800 ? "ldr" : "str",
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
178 regnames[word&7], regnames[(word>>3)&7], loff);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
179 if (loff >= 10)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
180 printf("\t; 0x%x", loff);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
181 putchar('\n');
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
182 }
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
183
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
184 static void
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
185 format_11(word)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
186 unsigned word;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
187 {
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
188 unsigned loff;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
189
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
190 loff = (word & 0xFF) << 2;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
191 printf("%s\t%s, [sp, #%u]", word&0x800 ? "ldr" : "str",
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
192 regnames[(word>>8)&7], loff);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
193 if (loff >= 10)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
194 printf("\t; 0x%x", loff);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
195 putchar('\n');
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
196 }
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
197
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
198 static void
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
199 format_12(off, word)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
200 unsigned off, word;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
201 {
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
202 unsigned loff;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
203
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
204 loff = (word & 0xFF) << 2;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
205 printf("add\t%s, %s, #%u", regnames[(word>>8)&7],
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
206 word&0x800 ? "sp" : "pc", loff);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
207 if (loff >= 10)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
208 printf("\t; 0x%x", loff);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
209 putchar('\n');
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
210 }
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
211
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
212 static void
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
213 format_13(word)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
214 unsigned word;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
215 {
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
216 unsigned loff;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
217
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
218 if ((word & 0xFF00) != 0xB000) {
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
219 printf("<invalid format 13>\n");
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
220 return;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
221 }
103
a10acb1688e0 thumbdis: buglet in the decoding of sub-from-sp
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents: 101
diff changeset
222 loff = (word & 0x7F) << 2;
97
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
223 printf("%s\tsp, #%u", word&0x80 ? "sub" : "add", loff);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
224 if (loff >= 10)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
225 printf("\t; 0x%x", loff);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
226 putchar('\n');
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
227 }
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
228
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
229 static void
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
230 format_14(word)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
231 unsigned word;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
232 {
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
233 int r, flag;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
234
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
235 if ((word & 0xF600) != 0xB400) {
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
236 printf("<invalid format 14>\n");
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
237 return;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
238 }
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
239 printf("%s\t{", word&0x800 ? "pop" : "push");
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
240 flag = 0;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
241 for (r = 0; r < 9; r++)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
242 if (word & (1 << r)) {
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
243 if (flag)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
244 fputs(", ", stdout);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
245 if (r == 8)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
246 fputs(word&0x800 ? "pc" : "lr", stdout);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
247 else
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
248 fputs(regnames[r], stdout);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
249 flag = 1;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
250 }
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
251 putchar('}');
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
252 putchar('\n');
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
253 }
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
254
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
255 static void
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
256 format_15(word)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
257 unsigned word;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
258 {
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
259 int r, flag;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
260
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
261 printf("%sia\t%s!, {", word&0x800 ? "ldm" : "stm",
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
262 regnames[(word>>8)&7]);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
263 flag = 0;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
264 for (r = 0; r < 8; r++)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
265 if (word & (1 << r)) {
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
266 if (flag)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
267 fputs(", ", stdout);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
268 fputs(regnames[r], stdout);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
269 flag = 1;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
270 }
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
271 putchar('}');
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
272 putchar('\n');
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
273 }
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
274
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
275 static void
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
276 format_16_17(off, word)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
277 unsigned off, word;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
278 {
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
279 unsigned cond;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
280 unsigned dest;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
281
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
282 cond = (word >> 8) & 0xF;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
283 switch (cond) {
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
284 case 0xE:
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
285 printf("<invalid: bal>\n");
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
286 return;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
287 case 0xF:
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
288 printf("swi\t0x%x\n", word & 0xFF);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
289 return;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
290 }
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
291 dest = (word & 0xFF) << 1;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
292 if (dest & 0x00000100)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
293 dest |= 0xFFFFFE00;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
294 dest += base_vma + off + 4;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
295 printf("b%s\t0x%x\n", condition_decode[cond], dest);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
296 }
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
297
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
298 static void
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
299 format_18(off, word)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
300 unsigned off, word;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
301 {
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
302 unsigned dest;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
303
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
304 if (word & 0x800) {
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
305 printf("<invalid format 18>\n");
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
306 return;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
307 }
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
308 dest = (word & 0x7FF) << 1;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
309 if (dest & 0x00000800)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
310 dest |= 0xFFFFF000;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
311 dest += base_vma + off + 4;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
312 printf("b\t0x%x\n", dest);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
313 }
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
314
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
315 void
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
316 thumb_disasm_line(off)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
317 unsigned off;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
318 {
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
319 unsigned word;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
320
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
321 word = get_u16(filemap + off);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
322 printf("%8x:\t%04x\t\t", base_vma + off, word);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
323 switch (word >> 12) {
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
324 case 0:
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
325 case 1:
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
326 format_1_2(word);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
327 return;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
328 case 2:
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
329 case 3:
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
330 format_3(word);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
331 return;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
332 case 4:
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
333 if (word & 0x800)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
334 format_6(off, word);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
335 else if (word & 0x400)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
336 format_5(word);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
337 else
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
338 format_4(word);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
339 return;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
340 case 5:
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
341 if (word & 0x200)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
342 format_8(word);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
343 else
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
344 format_7(word);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
345 return;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
346 case 6:
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
347 case 7:
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
348 format_9(word);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
349 return;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
350 case 8:
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
351 format_10(word);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
352 return;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
353 case 9:
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
354 format_11(word);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
355 return;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
356 case 0xA:
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
357 format_12(off, word);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
358 return;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
359 case 0xB:
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
360 if (word & 0x400)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
361 format_14(word);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
362 else
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
363 format_13(word);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
364 return;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
365 case 0xC:
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
366 format_15(word);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
367 return;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
368 case 0xD:
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
369 format_16_17(off, word);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
370 return;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
371 case 0xE:
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
372 format_18(off, word);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
373 return;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
374 case 0xF:
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
375 printf("<half-bl>\n");
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
376 return;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
377 }
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
378 }
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
379
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
380 thumb_check_bl(off)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
381 unsigned off;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
382 {
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
383 unsigned ins1, ins2;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
384 unsigned dest;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
385
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
386 if (off + 4 > disasm_len)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
387 return(0);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
388 ins1 = get_u16(filemap + off);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
389 if ((ins1 & 0xF800) != 0xF000)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
390 return(0);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
391 ins2 = get_u16(filemap + off + 2);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
392 if ((ins2 & 0xF800) != 0xF800)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
393 return(0);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
394 /* match */
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
395 dest = ((ins1 & 0x7FF) << 12) | ((ins2 & 0x7FF) << 1);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
396 if (dest & 0x00400000)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
397 dest |= 0xFF800000;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
398 dest += base_vma + off + 4;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
399 printf("%8x:\t%04x %04x\tbl\t0x%x\n", base_vma + off, ins1, ins2, dest);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
400 return(1);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
401 }
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
402
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
403 main(argc, argv)
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
404 char **argv;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
405 {
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
406 unsigned off;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
407
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
408 common_init(argc, argv, 2);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
409 for (off = 0; off < disasm_len; ) {
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
410 if (thumb_check_bl(off))
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
411 off += 4;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
412 else {
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
413 thumb_disasm_line(off);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
414 off += 2;
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
415 }
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
416 }
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
417 exit(0);
fb5ea2758482 thumbdis written, compiles
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
418 }