FreeCalypso > hg > freecalypso-reveng
comparison arm7dis/armdis.c @ 88:691551f0635b
armdis: implemented decoding of data processing instructions
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Sat, 29 Mar 2014 20:28:13 +0000 |
parents | f7fba8518fa2 |
children | c5d52666d2eb |
comparison
equal
deleted
inserted
replaced
87:f7fba8518fa2 | 88:691551f0635b |
---|---|
7 extern unsigned disasm_len, base_vma; | 7 extern unsigned disasm_len, base_vma; |
8 | 8 |
9 extern unsigned get_u16(), get_u32(); | 9 extern unsigned get_u16(), get_u32(); |
10 | 10 |
11 extern char *regnames[16], *condition_decode[16]; | 11 extern char *regnames[16], *condition_decode[16]; |
12 | |
13 static char *dataproc_ops[16] = {"and", "eor", "sub", "rsb", | |
14 "add", "adc", "sbc", "rsc", | |
15 "tst", "teq", "cmp", "cmn", | |
16 "orr", "mov", "bic", "mvn"}; | |
17 static char *shift_types[4] = {"lsl", "lsr", "asr", "ror"}; | |
12 | 18 |
13 static void | 19 static void |
14 arm_branch(off, word) | 20 arm_branch(off, word) |
15 unsigned off, word; | 21 unsigned off, word; |
16 { | 22 { |
22 dest += base_vma + off + 8; | 28 dest += base_vma + off + 8; |
23 printf("b%s%s\t0x%x\n", word&0x1000000 ? "l" : "", | 29 printf("b%s%s\t0x%x\n", word&0x1000000 ? "l" : "", |
24 condition_decode[word>>28], dest); | 30 condition_decode[word>>28], dest); |
25 } | 31 } |
26 | 32 |
33 static void | |
34 op2_immed(word) | |
35 unsigned word; | |
36 { | |
37 unsigned low8, rot, val; | |
38 | |
39 low8 = word & 0xFF; | |
40 rot = (word & 0xF00) >> 7; | |
41 val = (low8 << (32 - rot)) | (low8 >> rot); | |
42 if (val <= 9) | |
43 printf("#%u\n", val); | |
44 else | |
45 printf("#%u\t; 0x%x\n", val, val); | |
46 } | |
47 | |
48 static void | |
49 op2_regbyconst(word) | |
50 unsigned word; | |
51 { | |
52 unsigned c, t; | |
53 | |
54 c = (word >> 7) & 0x1F; | |
55 t = (word >> 5) & 3; | |
56 if (!c) { | |
57 switch (t) { | |
58 case 0: | |
59 printf("%s\n", regnames[word&0xF]); | |
60 return; | |
61 case 3: | |
62 printf("%s, rrx\n", regnames[word&0xF]); | |
63 return; | |
64 default: | |
65 c = 32; | |
66 } | |
67 } | |
68 printf("%s, %s #%u\n", regnames[word&0xF], shift_types[t], c); | |
69 } | |
70 | |
71 static void | |
72 op2_regbyreg(word) | |
73 unsigned word; | |
74 { | |
75 printf("%s, %s %s\n", regnames[word&0xF], shift_types[(word>>5)&3], | |
76 regnames[(word>>8)&0xF]); | |
77 } | |
78 | |
79 static void | |
80 op2_regshift(word) | |
81 unsigned word; | |
82 { | |
83 if (word & 0x10) | |
84 op2_regbyreg(word); | |
85 else | |
86 op2_regbyconst(word); | |
87 } | |
88 | |
89 static void | |
90 dataproc_op2(word) | |
91 unsigned word; | |
92 { | |
93 if (word & 0x02000000) | |
94 op2_immed(word); | |
95 else | |
96 op2_regshift(word); | |
97 } | |
98 | |
99 static void | |
100 dataproc_74_overlay(off, word) | |
101 unsigned off, word; | |
102 { | |
103 printf("<dataproc overlay with 7&4 set>\n"); | |
104 } | |
105 | |
106 static void | |
107 dataproc_tstcmp_overlay(off, word) | |
108 unsigned off, word; | |
109 { | |
110 printf("<dataproc overlay with S=0 for tst/cmp>\n"); | |
111 } | |
112 | |
113 static void | |
114 dataproc(off, word) | |
115 unsigned off, word; | |
116 { | |
117 unsigned opc; | |
118 | |
119 opc = (word >> 21) & 0xF; | |
120 switch (opc) { | |
121 case 0: | |
122 case 1: | |
123 case 2: | |
124 case 3: | |
125 case 4: | |
126 case 5: | |
127 case 6: | |
128 case 7: | |
129 case 0xC: | |
130 case 0xE: | |
131 printf("%s%s%s\t%s, %s, ", dataproc_ops[opc], | |
132 condition_decode[word>>28], word&0x100000 ? "s" : "", | |
133 regnames[(word>>12)&0xF], regnames[(word>>16)&0xF]); | |
134 dataproc_op2(word); | |
135 return; | |
136 case 0xD: | |
137 case 0xF: | |
138 printf("%s%s%s\t%s, ", dataproc_ops[opc], | |
139 condition_decode[word>>28], word&0x100000 ? "s" : "", | |
140 regnames[(word>>12)&0xF]); | |
141 dataproc_op2(word); | |
142 return; | |
143 case 8: | |
144 case 9: | |
145 case 0xA: | |
146 case 0xB: | |
147 if (word & 0x100000) { | |
148 printf("%s%s\t%s, ", dataproc_ops[opc], | |
149 condition_decode[word>>28], | |
150 regnames[(word>>16)&0xF]); | |
151 dataproc_op2(word); | |
152 } else | |
153 dataproc_tstcmp_overlay(off, word); | |
154 return; | |
155 } | |
156 } | |
157 | |
27 void | 158 void |
28 arm_disasm_line(off) | 159 arm_disasm_line(off) |
29 unsigned off; | 160 unsigned off; |
30 { | 161 { |
31 unsigned word; | 162 unsigned word; |
37 return; | 168 return; |
38 } | 169 } |
39 switch ((word >> 24) & 0xF) { | 170 switch ((word >> 24) & 0xF) { |
40 case 0: | 171 case 0: |
41 case 1: | 172 case 1: |
42 printf("<data processing, register operand>\n"); | 173 if ((word & 0x90) == 0x90) |
174 dataproc_74_overlay(off, word); | |
175 else | |
176 dataproc(off, word); | |
43 return; | 177 return; |
44 case 2: | 178 case 2: |
45 case 3: | 179 case 3: |
46 printf("<data processing, immediate operand>\n"); | 180 dataproc(off, word); |
47 return; | 181 return; |
48 case 4: | 182 case 4: |
49 case 5: | 183 case 5: |
50 printf("<ldr/str, immediate offset>\n"); | 184 printf("<ldr/str, immediate offset>\n"); |
51 return; | 185 return; |