Nugget
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages Concepts
decoder.hh
Go to the documentation of this file.
1/*
2
3MIT License
4
5Copyright (c) 2025 PCSX-Redux authors
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24
25*/
26
27#pragma once
28
29#include <stdint.h>
30
31#include "mips.hh"
32
33namespace Mips {
34namespace Decoder {
35
38
39 // clang-format off
40 // MIPS I instruction set mnemonics
41 enum Mnemonic {
42 // Arithmetic Instructions
44
45 // Logical Instructions
47
48 // Shift Instructions
50
51 // Load Instructions
52 LB, LBU, LH, LHU, LUI, LW, LWL, LWR,
53
54 // Store Instructions
55 SB, SH, SW, SWL, SWR,
56
57 // Branch Instructions
59
60 // Jump Instructions
62
63 // Move Instructions
65
66 // System Instructions
68
69 // Coprocessor Instructions
71
72 // Invalid Instruction
74 };
75 // clang-format on
76
77 uint32_t opcode() const { return code >> 26; }
78 uint32_t funct() const { return code & 0x3f; }
79 uint32_t rs() const { return (code >> 21) & 0x1f; }
80 uint32_t rt() const { return (code >> 16) & 0x1f; }
81 uint32_t rd() const { return (code >> 11) & 0x1f; }
82 uint32_t sa() const { return (code >> 6) & 0x1f; }
83 int32_t imm() const { return static_cast<int16_t>(code & 0xffff); }
84 uint32_t target() const { return code & 0x3ffffff; }
85 int32_t offset() const { return code & 0x3ffffff; }
86 uint32_t cop() const { return (code >> 26) & 0x1f; }
87 uint32_t copFunc() const { return code & 0x3f; }
88
90 switch (opcode()) {
91 case 0b000000: // special
92 switch (funct()) {
93 case 0b100000:
94 return ADD;
95 case 0b100001:
96 return ADDU;
97 case 0b100010:
98 return SUB;
99 case 0b100011:
100 return SUBU;
101 case 0b101010:
102 return SLT;
103 case 0b101011:
104 return SLTU;
105 case 0b011010:
106 return DIV;
107 case 0b011011:
108 return DIVU;
109 case 0b011000:
110 return MULT;
111 case 0b011001:
112 return MULTU;
113 case 0b010000:
114 return MFHI;
115 case 0b010001:
116 return MTHI;
117 case 0b010010:
118 return MFLO;
119 case 0b010011:
120 return MTLO;
121 case 0b000000:
122 return SLL;
123 case 0b000010:
124 return SRL;
125 case 0b000011:
126 return SRA;
127 case 0b000100:
128 return SLLV;
129 case 0b000110:
130 return SRLV;
131 case 0b000111:
132 return SRAV;
133 case 0b100111:
134 return NOR;
135 case 0b001000:
136 return JR;
137 case 0b001001:
138 return JALR;
139 case 0b001101:
140 return BREAK;
141 case 0b001100:
142 return SYSCALL;
143 }
144 break;
145 case 0b000001: // REGIMM
146 switch (rt()) {
147 case 0b00001:
148 return BGEZ;
149 case 0b10001:
150 return BGEZAL;
151 case 0b00000:
152 return BLTZ;
153 case 0b10000:
154 return BLTZAL;
155 }
156 break;
157 case 0b001000:
158 return ADDI;
159 case 0b001001:
160 return ADDIU;
161 case 0b001010:
162 return SLTI;
163 case 0b001011:
164 return SLTIU;
165 case 0b001100:
166 return ANDI;
167 case 0b001101:
168 return ORI;
169 case 0b001110:
170 return XORI;
171 case 0b000010:
172 return J;
173 case 0b000011:
174 return JAL;
175 case 0b000100:
176 return BEQ;
177 case 0b000101:
178 return BNE;
179 case 0b000111:
180 return BGTZ;
181 case 0b000110:
182 return BLEZ;
183 case 0b100000:
184 return LB;
185 case 0b100100:
186 return LBU;
187 case 0b100001:
188 return LH;
189 case 0b100101:
190 return LHU;
191 case 0b001111:
192 return LUI;
193 case 0b100011:
194 return LW;
195 case 0b100010:
196 return LWL;
197 case 0b100110:
198 return LWR;
199 case 0b101000:
200 return SB;
201 case 0b101001:
202 return SH;
203 case 0b101011:
204 return SW;
205 case 0b101010:
206 return SWL;
207 case 0b101110:
208 return SWR;
209 case 0b010000: // COP0
210 switch (rs()) {
211 case 0b00000:
212 return MFC0;
213 case 0b00100:
214 return MTC0;
215 case 0b00010:
216 return CFC0;
217 case 0b00110:
218 return CTC0;
219 }
220 break;
221 case 0b010010: // COP2
222 switch (rs()) {
223 case 0b00000:
224 return MFC2;
225 case 0b00100:
226 return MTC2;
227 case 0b00010:
228 return CFC2;
229 case 0b00110:
230 return CTC2;
231 }
232 break;
233 case 0b111010:
234 return SWC2;
235 case 0b110010:
236 return LWC2;
237 }
238 return INVALID;
239 }
240
241 bool isLoad() const {
242 switch (mnemonic()) {
243 case LB:
244 case LBU:
245 case LH:
246 case LHU:
247 case LUI:
248 case LW:
249 case LWL:
250 case LWR:
251 case LWC2:
252 return true;
253 default:
254 return false;
255 }
256 }
257
258 bool isStore() const {
259 switch (mnemonic()) {
260 case SB:
261 case SH:
262 case SW:
263 case SWL:
264 case SWR:
265 case SWC2:
266 return true;
267 default:
268 return false;
269 }
270 }
271
273 switch (mnemonic()) {
274 case LB:
275 case LBU:
276 case LH:
277 case LHU:
278 case LW:
279 case LWL:
280 case LWR:
281 case LWC2:
282 return gpr.r[rs()] + imm();
283 default:
284 return 0;
285 }
286 }
287
289 switch (mnemonic()) {
290 case SB:
291 case SH:
292 case SW:
293 case SWL:
294 case SWR:
295 case SWC2:
296 return gpr.r[rs()] + imm();
297 default:
298 return 0;
299 }
300 }
301
303 switch (mnemonic()) {
304 case LB:
305 case LBU:
306 return 0xff;
307 case LH:
308 case LHU:
309 return 0xffff;
310 case LWL: {
311 uint32_t address = gpr.r[rs()] + imm();
312 switch (address & 0x3) {
313 case 0:
314 return 0x000000ff;
315 case 1:
316 return 0x0000ffff;
317 case 2:
318 return 0x00ffffff;
319 case 3:
320 return 0xffffffff;
321 }
322 return 0xffffffff;
323 }
324 case LWR: {
325 uint32_t address = gpr.r[rs()] + imm();
326 switch (address & 0x3) {
327 case 0:
328 return 0xffffffff;
329 case 1:
330 return 0xffffff00;
331 case 2:
332 return 0xffff0000;
333 case 3:
334 return 0xff000000;
335 }
336 return 0xffffffff;
337 }
338 default:
339 return 0xffffffff;
340 }
341 }
342
343 uint32_t getValueToStore(GPRRegs& gpr, uint32_t cop2regs[32]) const {
344 switch (mnemonic()) {
345 case SB:
346 return gpr.r[rt()] & 0xff;
347 case SH:
348 return gpr.r[rt()] & 0xffff;
349 case SWL: {
350 uint32_t address = gpr.r[rs()] + imm();
351 switch (address & 0x3) {
352 case 0:
353 return gpr.r[rt()] << 24;
354 case 1:
355 return gpr.r[rt()] << 16;
356 case 2:
357 return gpr.r[rt()] << 8;
358 case 3:
359 return gpr.r[rt()];
360 }
361 return gpr.r[rt()];
362 }
363 case SWR: {
364 uint32_t address = gpr.r[rs()] + imm();
365 switch (address & 0x3) {
366 case 0:
367 return gpr.r[rt()];
368 case 1:
369 return gpr.r[rt()] >> 8;
370 case 2:
371 return gpr.r[rt()] >> 16;
372 case 3:
373 return gpr.r[rt()] >> 24;
374 }
375 return gpr.r[rt()];
376 }
377 case SWC2:
378 return cop2regs[rt()];
379 default:
380 return gpr.r[rt()];
381 }
382 }
383
385 switch (mnemonic()) {
386 case SB:
387 return 0xff;
388 case SH:
389 return 0xffff;
390 case SWL: {
391 uint32_t address = gpr.r[rs()] + imm();
392 switch (address & 0x3) {
393 case 0:
394 return 0xff000000;
395 case 1:
396 return 0xffff0000;
397 case 2:
398 return 0xffffff00;
399 case 3:
400 return 0xffffffff;
401 }
402 return 0xffffffff;
403 }
404 case SWR: {
405 uint32_t address = gpr.r[rs()] + imm();
406 switch (address & 0x3) {
407 case 0:
408 return 0x000000ff;
409 case 1:
410 return 0x0000ffff;
411 case 2:
412 return 0x00ffffff;
413 case 3:
414 return 0xffffffff;
415 }
416 return 0xffffffff;
417 }
418 default:
419 return 0xffffffff;
420 }
421 }
422
424 switch (mnemonic()) {
425 case BEQ:
426 case BNE:
427 case BGEZ:
428 case BGTZ:
429 case BLEZ:
430 case BLTZ:
431 case BGEZAL:
432 case BLTZAL:
433 return pc + (imm() << 2) + 4;
434 default:
435 return 0;
436 }
437 }
438
440 switch (mnemonic()) {
441 case J:
442 case JAL:
443 return (pc & 0xf0000000) | (target() << 2);
444 default:
445 return 0;
446 }
447 }
448
450 switch (mnemonic()) {
451 case JR:
452 case JALR:
453 return gpr.r[rs()];
454 default:
455 return 0;
456 }
457 }
458
460};
461} // namespace Decoder
462} // namespace Mips
Definition decoder.hh:33
Definition decoder.hh:36
uint32_t code
Definition decoder.hh:459
int32_t imm() const
Definition decoder.hh:83
uint32_t sa() const
Definition decoder.hh:82
uint32_t rd() const
Definition decoder.hh:81
uint32_t getJumpRegisterAddress(GPRRegs &gpr) const
Definition decoder.hh:449
uint32_t rs() const
Definition decoder.hh:79
uint32_t getJumpAddress(uint32_t pc) const
Definition decoder.hh:439
bool isStore() const
Definition decoder.hh:258
Mnemonic mnemonic() const
Definition decoder.hh:89
uint32_t getLoadMask(GPRRegs &gpr) const
Definition decoder.hh:302
uint32_t target() const
Definition decoder.hh:84
uint32_t getLoadAddress(GPRRegs &gpr) const
Definition decoder.hh:272
uint32_t getStoreAddress(GPRRegs &gpr) const
Definition decoder.hh:288
uint32_t getValueToStore(GPRRegs &gpr, uint32_t cop2regs[32]) const
Definition decoder.hh:343
bool isLoad() const
Definition decoder.hh:241
uint32_t cop() const
Definition decoder.hh:86
uint32_t opcode() const
Definition decoder.hh:77
int32_t offset() const
Definition decoder.hh:85
Mnemonic
Definition decoder.hh:41
@ NOR
Definition decoder.hh:46
@ BGTZ
Definition decoder.hh:58
@ SLTU
Definition decoder.hh:43
@ INVALID
Definition decoder.hh:73
@ SWR
Definition decoder.hh:55
@ MFC2
Definition decoder.hh:70
@ LB
Definition decoder.hh:52
@ CFC0
Definition decoder.hh:70
@ MTHI
Definition decoder.hh:64
@ SH
Definition decoder.hh:55
@ ORI
Definition decoder.hh:46
@ BLTZAL
Definition decoder.hh:58
@ BGEZAL
Definition decoder.hh:58
@ SLLV
Definition decoder.hh:49
@ JR
Definition decoder.hh:61
@ LW
Definition decoder.hh:52
@ ANDI
Definition decoder.hh:46
@ CTC0
Definition decoder.hh:70
@ SLT
Definition decoder.hh:43
@ SW
Definition decoder.hh:55
@ ADDU
Definition decoder.hh:43
@ CTC2
Definition decoder.hh:70
@ SYSCALL
Definition decoder.hh:67
@ SUB
Definition decoder.hh:43
@ BLEZ
Definition decoder.hh:58
@ MFLO
Definition decoder.hh:64
@ AND
Definition decoder.hh:46
@ SLL
Definition decoder.hh:49
@ MTC0
Definition decoder.hh:70
@ BLTZ
Definition decoder.hh:58
@ MTLO
Definition decoder.hh:64
@ MTC2
Definition decoder.hh:70
@ LUI
Definition decoder.hh:52
@ XORI
Definition decoder.hh:46
@ DIVU
Definition decoder.hh:43
@ SRL
Definition decoder.hh:49
@ LH
Definition decoder.hh:52
@ SUBU
Definition decoder.hh:43
@ MFHI
Definition decoder.hh:64
@ J
Definition decoder.hh:61
@ ADDIU
Definition decoder.hh:43
@ SLTI
Definition decoder.hh:43
@ DIV
Definition decoder.hh:43
@ SRAV
Definition decoder.hh:49
@ JAL
Definition decoder.hh:61
@ LWR
Definition decoder.hh:52
@ SLTIU
Definition decoder.hh:43
@ CFC2
Definition decoder.hh:70
@ JALR
Definition decoder.hh:61
@ MULTU
Definition decoder.hh:43
@ SWC2
Definition decoder.hh:70
@ LBU
Definition decoder.hh:52
@ MFC0
Definition decoder.hh:70
@ BGEZ
Definition decoder.hh:58
@ BREAK
Definition decoder.hh:67
@ ADD
Definition decoder.hh:43
@ SWL
Definition decoder.hh:55
@ SB
Definition decoder.hh:55
@ LWL
Definition decoder.hh:52
@ SRA
Definition decoder.hh:49
@ SRLV
Definition decoder.hh:49
@ XOR
Definition decoder.hh:46
@ ADDI
Definition decoder.hh:43
@ LWC2
Definition decoder.hh:70
@ BEQ
Definition decoder.hh:58
@ MULT
Definition decoder.hh:43
@ BNE
Definition decoder.hh:58
@ LHU
Definition decoder.hh:52
@ OR
Definition decoder.hh:46
uint32_t getStoreMask(GPRRegs &gpr) const
Definition decoder.hh:384
Instruction(uint32_t opcode)
Definition decoder.hh:37
uint32_t funct() const
Definition decoder.hh:78
uint32_t rt() const
Definition decoder.hh:80
uint32_t copFunc() const
Definition decoder.hh:87
uint32_t getBranchAddress(uint32_t pc) const
Definition decoder.hh:423
void uint32_t(classId, spec)
Definition mips.hh:42
uint32_t r[34]
Definition mips.hh:50