Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/attic/PsxHawk.Core/dis.cpp
2 views
1
/*
2
this disassembler is courtesy of mednafen
3
*/
4
5
#include "psx.h"
6
#include "types.h"
7
#include <string>
8
#include <string.h>
9
10
//TODO - add break opcode to disassembly
11
12
namespace MDFN_IEN_PSX
13
{
14
15
struct OpEntry
16
{
17
u32 mask;
18
u32 value;
19
const char *mnemonic;
20
const char *format;
21
};
22
23
#define MASK_OP (0x3F << 26)
24
#define MASK_FUNC (0x3F)
25
#define MASK_RS (0x1F << 21)
26
#define MASK_RT (0x1F << 16)
27
#define MASK_RD (0x1F << 11)
28
#define MASK_SA (0x1F << 6)
29
30
#define MK_OP(mnemonic, format, op, func, extra_mask) { MASK_OP | (op ? 0 : MASK_FUNC) | extra_mask, (op << 26) | func, mnemonic, format }
31
32
#define MK_OP_REGIMM(mnemonic, regop) { MASK_OP | MASK_RT, (0x01 << 26) | (regop << 16), mnemonic, "s, p" }
33
34
static OpEntry ops[] =
35
{
36
MK_OP("nop", "", 0, 0, MASK_RT | MASK_RD | MASK_SA),
37
MK_OP("sll", "d, t, a", 0, 0, 0),
38
MK_OP("srl", "d, t, a", 0, 2, 0),
39
MK_OP("sra", "d, t, a", 0, 3, 0),
40
41
MK_OP("sllv", "d, t, s", 0, 4, 0),
42
MK_OP("srlv", "d, t, s", 0, 6, 0),
43
MK_OP("srav", "d, t, s", 0, 7, 0),
44
45
MK_OP("jr", "s", 0, 8, 0),
46
MK_OP("jalr", "d, s", 0, 9, 0),
47
48
MK_OP("syscall", "", 0, 12, 0), // TODO
49
MK_OP("break", "", 0, 13, 0), // TODO
50
51
MK_OP("mfhi", "d", 0, 16, 0),
52
MK_OP("mthi", "s", 0, 17, 0),
53
MK_OP("mflo", "d", 0, 18, 0),
54
MK_OP("mtlo", "s", 0, 19, 0),
55
56
MK_OP("mult", "s, t", 0, 24, 0),
57
MK_OP("multu", "s, t", 0, 25, 0),
58
MK_OP("div", "s, t", 0, 26, 0),
59
MK_OP("divu", "s, t", 0, 27, 0),
60
61
MK_OP("add", "d, s, t", 0, 32, 0),
62
MK_OP("addu", "d, s, t", 0, 33, 0),
63
MK_OP("sub", "d, s, t", 0, 34, 0),
64
MK_OP("subu", "d, s, t", 0, 35, 0),
65
MK_OP("and", "d, s, t", 0, 36, 0),
66
MK_OP("or", "d, s, t", 0, 37, 0),
67
MK_OP("xor", "d, s, t", 0, 38, 0),
68
MK_OP("nor", "d, s, t", 0, 39, 0),
69
MK_OP("slt", "d, s, t", 0, 42, 0),
70
MK_OP("sltu", "d, s, t", 0, 43, 0),
71
72
MK_OP_REGIMM("bgez", 0x01),
73
MK_OP_REGIMM("bgezal", 0x11),
74
MK_OP_REGIMM("bltz", 0x00),
75
MK_OP_REGIMM("bltzal", 0x10),
76
77
78
MK_OP("j", "P", 2, 0, 0),
79
MK_OP("jal", "P", 3, 0, 0),
80
81
MK_OP("beq", "s, t, p", 4, 0, 0),
82
MK_OP("bne", "s, t, p", 5, 0, 0),
83
MK_OP("blez", "s, p", 6, 0, 0),
84
MK_OP("bgtz", "s, p", 7, 0, 0),
85
86
MK_OP("addi", "t, s, i", 8, 0, 0),
87
MK_OP("addiu", "t, s, i", 9, 0, 0),
88
MK_OP("slti", "t, s, i", 10, 0, 0),
89
MK_OP("sltiu", "t, s, i", 11, 0, 0),
90
91
MK_OP("andi", "t, s, z", 12, 0, 0),
92
93
MK_OP("ori", "t, s, z", 13, 0, 0),
94
MK_OP("xori", "t, s, z", 14, 0, 0),
95
MK_OP("lui", "t, z", 15, 0, 0),
96
97
// COP0 stuff here
98
//#define MK_OP(mnemonic, format, op, func, extra_mask) { MASK_OP | (op ? 0 : MASK_FUNC) | extra_mask, (op << 26) | func, mnemonic, format }
99
#define COPMF(num) ((num)<<21)
100
MK_OP("mfc0", "t, D", 16, 0, 0x03E00000),
101
MK_OP("mfc1", "t, D", 17, 0, 0x03E00000),
102
MK_OP("mfc2", "t, D", 18, 0, 0x03E00000),
103
MK_OP("mfc3", "t, D", 19, 0, 0x03E00000),
104
MK_OP("mtc0", "t, D", 16, COPMF(4), 0x03E00000),
105
MK_OP("mtc1", "t, D", 17, COPMF(4), 0x03E00000),
106
MK_OP("mtc2", "t, D", 18, COPMF(4), 0x03E00000),
107
MK_OP("mtc3", "t, D", 19, COPMF(4), 0x03E00000),
108
//MK_OP("rfe", "", 19, COPMF(4), 0x03E00000), //TODO
109
110
MK_OP("lb", "t, i(s)", 32, 0, 0),
111
MK_OP("lh", "t, i(s)", 33, 0, 0),
112
MK_OP("lwl", "t, i(s)", 34, 0, 0),
113
MK_OP("lw", "t, i(s)", 35, 0, 0),
114
MK_OP("lbu", "t, i(s)", 36, 0, 0),
115
MK_OP("lhu", "t, i(s)", 37, 0, 0),
116
MK_OP("lwr", "t, i(s)", 38, 0, 0),
117
118
MK_OP("sb", "t, i(s)", 40, 0, 0),
119
MK_OP("sh", "t, i(s)", 41, 0, 0),
120
MK_OP("swl", "t, i(s)", 42, 0, 0),
121
MK_OP("sw", "t, i(s)", 43, 0, 0),
122
MK_OP("swr", "t, i(s)", 46, 0, 0),
123
124
{ 0, 0, NULL, NULL }
125
};
126
127
std::string DisassembleMIPS(u32 PC, u32 instr)
128
{
129
std::string ret = "UNKNOWN";
130
unsigned int rs = (instr >> 21) & 0x1F;
131
unsigned int rt = (instr >> 16) & 0x1F;
132
unsigned int rd = (instr >> 11) & 0x1F;
133
unsigned int shamt = (instr >> 6) & 0x1F;
134
unsigned int immediate = (s32)(s16)(instr & 0xFFFF);
135
unsigned int immediate_ze = (instr & 0xFFFF);
136
unsigned int jt = instr & ((1 << 26) - 1);
137
138
static const char *gpr_names[32] =
139
{
140
"r0", "at", "v0", "v1", "a0", "a1", "a2", "a3", "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
141
"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra"
142
};
143
144
OpEntry *op = ops;
145
146
while(op->mnemonic)
147
{
148
if((instr & op->mask) == op->value)
149
{
150
// a = shift amount
151
// s = rs
152
// t = rt
153
// d = rd
154
// i = immediate
155
// z = immediate, zero-extended
156
// p = PC + 4 + immediate
157
// P = ((PC + 4) & 0xF0000000) | (26bitval << 2)
158
char s_a[16];
159
char s_i[16];
160
char s_z[16];
161
char s_p[16];
162
char s_P[16];
163
char s_D[16];
164
165
_snprintf(s_D, sizeof(s_D), "%d", rd);
166
167
_snprintf(s_a, sizeof(s_a), "%d", shamt);
168
169
if(immediate < 0)
170
_snprintf(s_i, sizeof(s_i), "%d", immediate);
171
else
172
_snprintf(s_i, sizeof(s_i), "0x%04x", (u32)immediate);
173
174
_snprintf(s_z, sizeof(s_z), "0x%04x", immediate_ze);
175
176
_snprintf(s_p, sizeof(s_p), "0x%08x", PC + 4 + (immediate << 2));
177
178
_snprintf(s_P, sizeof(s_P), "0x%08x", ((PC + 4) & 0xF0000000) | (jt << 2));
179
180
ret = std::string(op->mnemonic);
181
ret.append(10 - ret.size(), ' ');
182
183
for(unsigned int i = 0; i < strlen(op->format); i++)
184
{
185
switch(op->format[i])
186
{
187
case 'a':
188
ret.append(s_a);
189
break;
190
191
case 'i':
192
ret.append(s_i);
193
break;
194
195
case 'z':
196
ret.append(s_z);
197
break;
198
199
case 'p':
200
ret.append(s_p);
201
break;
202
203
case 'P':
204
ret.append(s_P);
205
break;
206
207
case 's':
208
ret.append(gpr_names[rs]);
209
break;
210
211
case 't':
212
ret.append(gpr_names[rt]);
213
break;
214
215
case 'd':
216
ret.append(gpr_names[rd]);
217
break;
218
219
case 'D':
220
ret.append(s_D);
221
break;
222
223
default:
224
ret.append(1, op->format[i]);
225
break;
226
}
227
}
228
break;
229
}
230
op++;
231
}
232
233
return(ret);
234
}
235
236
}
237
238
239