Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/snes/chip/armdsp/disassembler.cpp
2 views
1
#ifdef ARMDSP_CPP
2
3
string ArmDSP::disassemble_opcode(uint32 pc) {
4
static string conditions[] = { "eq", "ne", "cs", "cc", "mi" ,"pl", "vs", "vc", "hi", "ls", "ge", "lt", "gt", "le", "" /*al*/, "nv" };
5
static string opcodes[] = { "and", "eor", "sub", "rsb", "add", "adc", "sbc", "rsc", "tst", "teq", "cmp", "cmn", "orr", "mov", "bic", "mvn" };
6
static string registers[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" };
7
static string indices[] = { "da", "ia", "db", "ib" };
8
9
static auto is_move = [](uint4 opcode) { return opcode == 13 || opcode == 15; };
10
static auto is_comp = [](uint4 opcode) { return opcode >= 8 && opcode <= 11; };
11
static auto is_math = [](uint4 opcode) { return opcode < 8 || opcode == 12 || opcode == 14; };
12
13
string output{hex<8>(pc), " "};
14
15
uint32 instruction = bus_readword(pc);
16
output.append(hex<8>(instruction), " ");
17
18
//multiply
19
//(mul,mla){condition}{s} rd,rm,rs,rn
20
if((instruction & 0x0fc000f0) == 0x00000090) {
21
uint4 condition = instruction >> 28;
22
uint1 accumulate = instruction >> 21;
23
uint1 save = instruction >> 20;
24
uint4 rd = instruction >> 16;
25
uint4 rn = instruction >> 12;
26
uint4 rs = instruction >> 8;
27
uint4 rm = instruction >> 0;
28
29
output.append(accumulate ? "mla" : "mul", condition[conditions], save ? "s " : " ");
30
output.append(registers[rd], ",", registers[rm], ",", registers[rs]);
31
if(accumulate) output.append(",", registers[rn]);
32
33
return output;
34
}
35
36
//move to register from status register
37
//mrs{condition} rd,(c,s)psr
38
if((instruction & 0x0fb000f0) == 0x01000000) {
39
uint4 condition = instruction >> 28;
40
uint1 psr = instruction >> 22;
41
uint4 rd = instruction >> 12;
42
43
output.append("mrs", condition[conditions], " ");
44
output.append(registers[rd], ",", psr ? "spsr" : "cpsr");
45
46
return output;
47
}
48
49
//move to status register from register
50
//msr{condition} (c,s)psr:{fields},rm
51
if((instruction & 0x0fb000f0) == 0x01200000) {
52
uint4 condition = instruction >> 28;
53
uint1 psr = instruction >> 22;
54
uint4 field = instruction >> 16;
55
56
output.append("msr", conditions[condition], " ");
57
output.append(psr ? "spsr:" : "cpsr:",
58
field & 1 ? "c" : "",
59
field & 2 ? "x" : "",
60
field & 4 ? "s" : "",
61
field & 8 ? "f" : "",
62
",", registers[(uint4)instruction]);
63
64
return output;
65
}
66
67
//data immediate shift
68
//{opcode}{condition}{s} rd,rm {shift} #immediate
69
//{opcode}{condition} rn,rm {shift} #immediate
70
//{opcode}{condition}{s} rd,rn,rm {shift} #immediate
71
if((instruction & 0x0e000010) == 0x00000000) {
72
uint4 condition = instruction >> 28;
73
uint4 opcode = instruction >> 21;
74
uint1 save = instruction >> 20;
75
uint4 rn = instruction >> 16;
76
uint4 rd = instruction >> 12;
77
uint5 shift = instruction >> 7;
78
uint2 op = instruction >> 5;
79
uint4 rm = instruction;
80
81
output.append(opcodes[opcode], conditions[condition]);
82
if(is_move(opcode)) output.append(save ? "s " : " ", registers[rd]);
83
if(is_comp(opcode)) output.append(" ", registers[rn]);
84
if(is_math(opcode)) output.append(save ? "s " : " ", registers[rd], ",", registers[rn]);
85
output.append(",", registers[rm]);
86
if(op == 0 && shift != 0) output.append(" lsl #", shift);
87
if(op == 1) output.append(" lsr #", shift == 0 ? 32u : (unsigned)shift);
88
if(op == 2) output.append(" asr #", shift == 0 ? 32u : (unsigned)shift);
89
if(op == 3 && shift != 0) output.append(" ror #", shift);
90
if(op == 3 && shift == 0) output.append(" rrx");
91
92
return output;
93
}
94
95
//data register shift
96
//{opcode}{condition}{s} rd,rm {shift} rs
97
//{opcode}{condition} rn,rm {shift} rs
98
//{opcode}{condition}{s} rd,rn,rm {shift} rs
99
if((instruction & 0x0e000090) == 0x00000010) {
100
uint4 condition = instruction >> 28;
101
uint4 opcode = instruction >> 21;
102
uint1 save = instruction >> 20;
103
uint4 rn = instruction >> 16;
104
uint4 rd = instruction >> 12;
105
uint4 rs = instruction >> 8;
106
uint2 mode = instruction >> 5;
107
uint4 rm = instruction;
108
109
output.append(opcodes[opcode], conditions[condition]);
110
if(is_move(opcode)) output.append(save ? "s " : " ", registers[rd], ",");
111
if(is_comp(opcode)) output.append(registers[rn], ",");
112
if(is_math(opcode)) output.append(save ? "s " : " ", registers[rd], ",", registers[rn], ",");
113
output.append(registers[rm]);
114
if(mode == 0) output.append(" lsl ");
115
if(mode == 1) output.append(" lsr ");
116
if(mode == 2) output.append(" asr ");
117
if(mode == 3) output.append(" ror ");
118
output.append(registers[rs]);
119
120
return output;
121
}
122
123
//data immediate
124
//{opcode}{condition}{s} rd,#immediate
125
//{opcode}{condition} rn,#immediate
126
//{opcode}{condition}{s} rd,rn,#immediate
127
if((instruction & 0x0e000000) == 0x02000000) {
128
uint4 condition = instruction >> 28;
129
uint4 opcode = instruction >> 21;
130
uint1 save = instruction >> 20;
131
uint4 rn = instruction >> 16;
132
uint4 rd = instruction >> 12;
133
uint4 rotate = instruction >> 8;
134
uint8 immediate = instruction;
135
136
uint32 shifter = (immediate >> (rotate << 1)) | (immediate << (32 - (rotate << 1)));
137
output.append(opcodes[opcode], conditions[condition]);
138
if(is_move(opcode)) output.append(save ? "s " : " ", registers[rd]);
139
if(is_comp(opcode)) output.append(" ", registers[rn]);
140
if(is_math(opcode)) output.append(save ? "s " : " ", registers[rd], ",", registers[rn]);
141
output.append(",#0x", hex<8>(shifter));
142
143
return output;
144
}
145
146
//move immediate offset
147
//(ldr,str){condition}{b} rd,[rn{,+/-offset}]{!}
148
//(ldr,str){condition}{b} rd,[rn]{,+/-offset}
149
if((instruction & 0x0e000000) == 0x04000000) {
150
uint4 condition = instruction >> 28;
151
uint1 p = instruction >> 24;
152
uint1 u = instruction >> 23;
153
uint1 b = instruction >> 22;
154
uint1 w = instruction >> 21;
155
uint1 load = instruction >> 20;
156
uint4 rn = instruction >> 16;
157
uint4 rd = instruction >> 12;
158
uint12 immediate = instruction;
159
160
output.append(load ? "ldr" : "str", conditions[condition], b ? "b " : " ");
161
output.append(registers[rd], ",[", registers[rn]);
162
if(p == 0) output.append("]");
163
if(immediate) output.append(",", u ? "+" : "-", "0x", hex<3>(immediate));
164
if(p == 1) output.append("]");
165
if(p == 1 && w == 1) output.append("!");
166
167
if(rn == 15) output.append(" =0x", hex<8>(bus_readword(pc + 8 + (u ? +immediate : -immediate))));
168
169
return output;
170
}
171
172
//move register offset
173
//(ldr)(str){condition}{b} rd,[rn,rm {mode} #immediate]{!}
174
//(ldr)(str){condition}{b} rd,[rn],rm {mode} #immediate
175
if((instruction & 0x0e000010) == 0x06000000) {
176
uint4 condition = instruction >> 28;
177
uint1 p = instruction >> 24;
178
uint1 u = instruction >> 23;
179
uint1 b = instruction >> 22;
180
uint1 w = instruction >> 21;
181
uint1 load = instruction >> 20;
182
uint4 rn = instruction >> 16;
183
uint4 rd = instruction >> 12;
184
uint5 shift = instruction >> 7;
185
uint2 mode = instruction >> 5;
186
uint4 rm = instruction;
187
188
output.append(load ? "ldr" : "str", conditions[condition], b ? "b " : " ");
189
output.append(registers[rd], ",[", registers[rn]);
190
if(p == 0) output.append("]");
191
output.append(",", u ? "+" : "-", registers[rm]);
192
if(mode == 0 && shift != 0) output.append(" lsl #", shift);
193
if(mode == 1) output.append(" lsr #", shift == 0 ? 32u : (unsigned)shift);
194
if(mode == 2) output.append(" asr #", shift == 0 ? 32u : (unsigned)shift);
195
if(mode == 3 && shift != 0) output.append(" ror #", shift);
196
if(mode == 3 && shift == 0) output.append(" rrx");
197
if(p == 1) output.append("]");
198
if(p == 1 && w == 1) output.append("!");
199
200
return output;
201
}
202
203
//move multiple
204
//(ldm,stm){condition}{mode} rn{!},{r...}
205
if((instruction & 0x0e000000) == 0x08000000) {
206
uint4 condition = instruction >> 28;
207
uint4 rn = instruction >> 16;
208
209
output.append(instruction & 0x00100000 ? "ldm" : "stm", conditions[condition], indices[(uint2)(instruction >> 23)]);
210
output.append(" ", registers[rn], instruction & 0x00200000 ? "!" : "", ",{");
211
for(unsigned n = 0; n < 16; n++) if(instruction & (1 << n)) output.append(registers[n], ",");
212
output.rtrim<1>(",");
213
output.append("}");
214
215
return output;
216
}
217
218
//branch
219
//b{l}{condition} address
220
if((instruction & 0x0e000000) == 0x0a000000) {
221
uint4 condition = instruction >> 28;
222
uint1 l = instruction >> 24;
223
224
output.append("b", l ? "l" : "", conditions[condition]);
225
output.append(" 0x", hex<8>(pc + 8 + (int24)instruction * 4));
226
227
return output;
228
}
229
230
output.append("???");
231
return output;
232
}
233
234
string ArmDSP::disassemble_registers() {
235
return {
236
"r0:", hex<8>(r[ 0]), " r1:", hex<8>(r[ 1]), " r2:", hex<8>(r[ 2]), " r3:", hex<8>(r[ 3]),
237
" r4:", hex<8>(r[ 4]), " r5:", hex<8>(r[ 5]), " r6:", hex<8>(r[ 6]), " r7:", hex<8>(r[ 7]), " ",
238
"cpsr:", cpsr.n ? "N" : "n", cpsr.z ? "Z" : "z", cpsr.c ? "C" : "c", cpsr.v ? "V" : "v", "\n",
239
"r8:", hex<8>(r[ 8]), " r9:", hex<8>(r[ 9]), " r10:", hex<8>(r[10]), " r11:", hex<8>(r[11]),
240
" r12:", hex<8>(r[12]), " r13:", hex<8>(r[13]), " r14:", hex<8>(r[14]), " r15:", hex<8>(r[15]), " ",
241
"spsr:", spsr.n ? "N" : "n", spsr.z ? "Z" : "z", spsr.c ? "C" : "c", spsr.v ? "V" : "v"
242
243
};
244
}
245
246
#endif
247
248