start implementing instruction union for cleaner switches and stuff
This commit is contained in:
@@ -2,129 +2,5 @@
|
||||
#include <common.hpp>
|
||||
|
||||
namespace n64 {
|
||||
constexpr u8 SPECIAL = 0b000000;
|
||||
constexpr u8 REGIMM = 0b000001;
|
||||
constexpr u8 J = 0b000010;
|
||||
constexpr u8 JAL = 0b000011;
|
||||
constexpr u8 BEQ = 0b000100;
|
||||
constexpr u8 BNE = 0b000101;
|
||||
constexpr u8 BLEZ = 0b000110;
|
||||
constexpr u8 BGTZ = 0b000111;
|
||||
constexpr u8 ADDI = 0b001000;
|
||||
constexpr u8 ADDIU = 0b001001;
|
||||
constexpr u8 SLTI = 0b001010;
|
||||
constexpr u8 SLTIU = 0b001011;
|
||||
constexpr u8 ANDI = 0b001100;
|
||||
constexpr u8 ORI = 0b001101;
|
||||
constexpr u8 XORI = 0b001110;
|
||||
constexpr u8 LUI = 0b001111;
|
||||
constexpr u8 COP0 = 0b010000;
|
||||
constexpr u8 COP1 = 0b010001;
|
||||
constexpr u8 COP2 = 0b010010;
|
||||
constexpr u8 BEQL = 0b010100;
|
||||
constexpr u8 BNEL = 0b010101;
|
||||
constexpr u8 BLEZL = 0b010110;
|
||||
constexpr u8 BGTZL = 0b010111;
|
||||
constexpr u8 DADDI = 0b011000;
|
||||
constexpr u8 DADDIU = 0b011001;
|
||||
constexpr u8 LDL = 0b011010;
|
||||
constexpr u8 LDR = 0b011011;
|
||||
constexpr u8 LB = 0b100000;
|
||||
constexpr u8 LH = 0b100001;
|
||||
constexpr u8 LWL = 0b100010;
|
||||
constexpr u8 LW = 0b100011;
|
||||
constexpr u8 LBU = 0b100100;
|
||||
constexpr u8 LHU = 0b100101;
|
||||
constexpr u8 LWR = 0b100110;
|
||||
constexpr u8 LWU = 0b100111;
|
||||
constexpr u8 SB = 0b101000;
|
||||
constexpr u8 SH = 0b101001;
|
||||
constexpr u8 SWL = 0b101010;
|
||||
constexpr u8 SW = 0b101011;
|
||||
constexpr u8 SDL = 0b101100;
|
||||
constexpr u8 SDR = 0b101101;
|
||||
constexpr u8 SWR = 0b101110;
|
||||
constexpr u8 CACHE = 0b101111;
|
||||
constexpr u8 LL = 0b110000;
|
||||
constexpr u8 LWC1 = 0b110001;
|
||||
constexpr u8 LWC2 = 0b110010;
|
||||
constexpr u8 LLD = 0b110100;
|
||||
constexpr u8 LDC1 = 0b110101;
|
||||
constexpr u8 LDC2 = 0b110110;
|
||||
constexpr u8 LD = 0b110111;
|
||||
constexpr u8 SC = 0b111000;
|
||||
constexpr u8 SWC1 = 0b111001;
|
||||
constexpr u8 SWC2 = 0b111010;
|
||||
constexpr u8 SCD = 0b111100;
|
||||
constexpr u8 SDC1 = 0b111101;
|
||||
constexpr u8 SDC2 = 0b111110;
|
||||
constexpr u8 SD = 0b111111;
|
||||
// special
|
||||
constexpr u8 SLL = 0b000000;
|
||||
constexpr u8 SRL = 0b000010;
|
||||
constexpr u8 SRA = 0b000011;
|
||||
constexpr u8 SLLV = 0b000100;
|
||||
constexpr u8 SRLV = 0b000110;
|
||||
constexpr u8 SRAV = 0b000111;
|
||||
constexpr u8 JR = 0b001000;
|
||||
constexpr u8 JALR = 0b001001;
|
||||
constexpr u8 SYSCALL = 0b001100;
|
||||
constexpr u8 BREAK = 0b001101;
|
||||
constexpr u8 SYNC = 0b001111;
|
||||
constexpr u8 MFHI = 0b010000;
|
||||
constexpr u8 MTHI = 0b010001;
|
||||
constexpr u8 MFLO = 0b010010;
|
||||
constexpr u8 MTLO = 0b010011;
|
||||
constexpr u8 DSLLV = 0b010100;
|
||||
constexpr u8 DSRLV = 0b010110;
|
||||
constexpr u8 DSRAV = 0b010111;
|
||||
constexpr u8 MULT = 0b011000;
|
||||
constexpr u8 MULTU = 0b011001;
|
||||
constexpr u8 DIV = 0b011010;
|
||||
constexpr u8 DIVU = 0b011011;
|
||||
constexpr u8 DMULT = 0b011100;
|
||||
constexpr u8 DMULTU = 0b011101;
|
||||
constexpr u8 DDIV = 0b011110;
|
||||
constexpr u8 DDIVU = 0b011111;
|
||||
constexpr u8 ADD = 0b100000;
|
||||
constexpr u8 ADDU = 0b100001;
|
||||
constexpr u8 SUB = 0b100010;
|
||||
constexpr u8 SUBU = 0b100011;
|
||||
constexpr u8 AND = 0b100100;
|
||||
constexpr u8 OR = 0b100101;
|
||||
constexpr u8 XOR = 0b100110;
|
||||
constexpr u8 NOR = 0b100111;
|
||||
constexpr u8 SLT = 0b101010;
|
||||
constexpr u8 SLTU = 0b101011;
|
||||
constexpr u8 DADD = 0b101100;
|
||||
constexpr u8 DADDU = 0b101101;
|
||||
constexpr u8 DSUB = 0b101110;
|
||||
constexpr u8 DSUBU = 0b101111;
|
||||
constexpr u8 TGE = 0b110000;
|
||||
constexpr u8 TGEU = 0b110001;
|
||||
constexpr u8 TLT = 0b110010;
|
||||
constexpr u8 TLTU = 0b110011;
|
||||
constexpr u8 TEQ = 0b110100;
|
||||
constexpr u8 TNE = 0b110110;
|
||||
constexpr u8 DSLL = 0b111000;
|
||||
constexpr u8 DSRL = 0b111010;
|
||||
constexpr u8 DSRA = 0b111011;
|
||||
constexpr u8 DSLL32 = 0b111100;
|
||||
constexpr u8 DSRL32 = 0b111110;
|
||||
constexpr u8 DSRA32 = 0b111111;
|
||||
// regimm
|
||||
constexpr u8 BLTZ = 0b00000;
|
||||
constexpr u8 BGEZ = 0b00001;
|
||||
constexpr u8 BLTZL = 0b00010;
|
||||
constexpr u8 BGEZL = 0b00011;
|
||||
constexpr u8 TGEI = 0b01000;
|
||||
constexpr u8 TGEIU = 0b01001;
|
||||
constexpr u8 TLTI = 0b01010;
|
||||
constexpr u8 TLTIU = 0b01011;
|
||||
constexpr u8 TEQI = 0b01100;
|
||||
constexpr u8 TNEI = 0b01110;
|
||||
constexpr u8 BLTZAL = 0b10000;
|
||||
constexpr u8 BGEZAL = 0b10001;
|
||||
constexpr u8 BLTZALL = 0b10010;
|
||||
constexpr u8 BGEZALL = 0b10011;
|
||||
|
||||
} // namespace n64
|
||||
|
||||
@@ -1,166 +1,168 @@
|
||||
#include <Core.hpp>
|
||||
#include <CpuDefinitions.hpp>
|
||||
#include <log.hpp>
|
||||
#include <Instruction.hpp>
|
||||
|
||||
namespace n64 {
|
||||
void Interpreter::special(const u32 instr) {
|
||||
Instruction helper(instr);
|
||||
// 00rr_rccc
|
||||
switch (const u8 mask = instr & 0x3F) {
|
||||
case SLL:
|
||||
switch (helper.special()) {
|
||||
case Instruction::SLL:
|
||||
if (instr != 0) {
|
||||
sll(instr);
|
||||
}
|
||||
break;
|
||||
case SRL:
|
||||
case Instruction::SRL:
|
||||
srl(instr);
|
||||
break;
|
||||
case SRA:
|
||||
case Instruction::SRA:
|
||||
sra(instr);
|
||||
break;
|
||||
case SLLV:
|
||||
case Instruction::SLLV:
|
||||
sllv(instr);
|
||||
break;
|
||||
case SRLV:
|
||||
case Instruction::SRLV:
|
||||
srlv(instr);
|
||||
break;
|
||||
case SRAV:
|
||||
case Instruction::SRAV:
|
||||
srav(instr);
|
||||
break;
|
||||
case JR:
|
||||
case Instruction::JR:
|
||||
jr(instr);
|
||||
break;
|
||||
case JALR:
|
||||
case Instruction::JALR:
|
||||
jalr(instr);
|
||||
break;
|
||||
case SYSCALL:
|
||||
case Instruction::SYSCALL:
|
||||
regs.cop0.FireException(ExceptionCode::Syscall, 0, regs.oldPC);
|
||||
break;
|
||||
case BREAK:
|
||||
case Instruction::BREAK:
|
||||
regs.cop0.FireException(ExceptionCode::Breakpoint, 0, regs.oldPC);
|
||||
break;
|
||||
case SYNC:
|
||||
case Instruction::SYNC:
|
||||
break; // SYNC
|
||||
case MFHI:
|
||||
case Instruction::MFHI:
|
||||
mfhi(instr);
|
||||
break;
|
||||
case MTHI:
|
||||
case Instruction::MTHI:
|
||||
mthi(instr);
|
||||
break;
|
||||
case MFLO:
|
||||
case Instruction::MFLO:
|
||||
mflo(instr);
|
||||
break;
|
||||
case MTLO:
|
||||
case Instruction::MTLO:
|
||||
mtlo(instr);
|
||||
break;
|
||||
case DSLLV:
|
||||
case Instruction::DSLLV:
|
||||
dsllv(instr);
|
||||
break;
|
||||
case DSRLV:
|
||||
case Instruction::DSRLV:
|
||||
dsrlv(instr);
|
||||
break;
|
||||
case DSRAV:
|
||||
case Instruction::DSRAV:
|
||||
dsrav(instr);
|
||||
break;
|
||||
case MULT:
|
||||
case Instruction::MULT:
|
||||
mult(instr);
|
||||
break;
|
||||
case MULTU:
|
||||
case Instruction::MULTU:
|
||||
multu(instr);
|
||||
break;
|
||||
case DIV:
|
||||
case Instruction::DIV:
|
||||
div(instr);
|
||||
break;
|
||||
case DIVU:
|
||||
case Instruction::DIVU:
|
||||
divu(instr);
|
||||
break;
|
||||
case DMULT:
|
||||
case Instruction::DMULT:
|
||||
dmult(instr);
|
||||
break;
|
||||
case DMULTU:
|
||||
case Instruction::DMULTU:
|
||||
dmultu(instr);
|
||||
break;
|
||||
case DDIV:
|
||||
case Instruction::DDIV:
|
||||
ddiv(instr);
|
||||
break;
|
||||
case DDIVU:
|
||||
case Instruction::DDIVU:
|
||||
ddivu(instr);
|
||||
break;
|
||||
case ADD:
|
||||
case Instruction::ADD:
|
||||
add(instr);
|
||||
break;
|
||||
case ADDU:
|
||||
case Instruction::ADDU:
|
||||
addu(instr);
|
||||
break;
|
||||
case SUB:
|
||||
case Instruction::SUB:
|
||||
sub(instr);
|
||||
break;
|
||||
case SUBU:
|
||||
case Instruction::SUBU:
|
||||
subu(instr);
|
||||
break;
|
||||
case AND:
|
||||
case Instruction::AND:
|
||||
and_(instr);
|
||||
break;
|
||||
case OR:
|
||||
case Instruction::OR:
|
||||
or_(instr);
|
||||
break;
|
||||
case XOR:
|
||||
case Instruction::XOR:
|
||||
xor_(instr);
|
||||
break;
|
||||
case NOR:
|
||||
case Instruction::NOR:
|
||||
nor(instr);
|
||||
break;
|
||||
case SLT:
|
||||
case Instruction::SLT:
|
||||
slt(instr);
|
||||
break;
|
||||
case SLTU:
|
||||
case Instruction::SLTU:
|
||||
sltu(instr);
|
||||
break;
|
||||
case DADD:
|
||||
case Instruction::DADD:
|
||||
dadd(instr);
|
||||
break;
|
||||
case DADDU:
|
||||
case Instruction::DADDU:
|
||||
daddu(instr);
|
||||
break;
|
||||
case DSUB:
|
||||
case Instruction::DSUB:
|
||||
dsub(instr);
|
||||
break;
|
||||
case DSUBU:
|
||||
case Instruction::DSUBU:
|
||||
dsubu(instr);
|
||||
break;
|
||||
case TGE:
|
||||
case Instruction::TGE:
|
||||
trap(regs.Read<s64>(RS(instr)) >= regs.Read<s64>(RT(instr)));
|
||||
break;
|
||||
case TGEU:
|
||||
case Instruction::TGEU:
|
||||
trap(regs.Read<u64>(RS(instr)) >= regs.Read<u64>(RT(instr)));
|
||||
break;
|
||||
case TLT:
|
||||
case Instruction::TLT:
|
||||
trap(regs.Read<s64>(RS(instr)) < regs.Read<s64>(RT(instr)));
|
||||
break;
|
||||
case TLTU:
|
||||
case Instruction::TLTU:
|
||||
trap(regs.Read<u64>(RS(instr)) < regs.Read<u64>(RT(instr)));
|
||||
break;
|
||||
case TEQ:
|
||||
case Instruction::TEQ:
|
||||
trap(regs.Read<s64>(RS(instr)) == regs.Read<s64>(RT(instr)));
|
||||
break;
|
||||
case TNE:
|
||||
case Instruction::TNE:
|
||||
trap(regs.Read<s64>(RS(instr)) != regs.Read<s64>(RT(instr)));
|
||||
break;
|
||||
case DSLL:
|
||||
case Instruction::DSLL:
|
||||
dsll(instr);
|
||||
break;
|
||||
case DSRL:
|
||||
case Instruction::DSRL:
|
||||
dsrl(instr);
|
||||
break;
|
||||
case DSRA:
|
||||
case Instruction::DSRA:
|
||||
dsra(instr);
|
||||
break;
|
||||
case DSLL32:
|
||||
case Instruction::DSLL32:
|
||||
dsll32(instr);
|
||||
break;
|
||||
case DSRL32:
|
||||
case Instruction::DSRL32:
|
||||
dsrl32(instr);
|
||||
break;
|
||||
case DSRA32:
|
||||
case Instruction::DSRA32:
|
||||
dsra32(instr);
|
||||
break;
|
||||
default:
|
||||
|
||||
145
src/utils/Instruction.hpp
Normal file
145
src/utils/Instruction.hpp
Normal file
@@ -0,0 +1,145 @@
|
||||
#pragma once
|
||||
#include <types.hpp>
|
||||
#include <common.hpp>
|
||||
|
||||
namespace n64 {
|
||||
struct Instruction {
|
||||
Instruction(u32 v) : raw(v) {}
|
||||
void operator=(u32 v) { raw = v; }
|
||||
|
||||
u32 raw;
|
||||
|
||||
FORCE_INLINE u8 special() const { return raw & 0x3F; }
|
||||
FORCE_INLINE u8 cop_funct() const { return special(); }
|
||||
FORCE_INLINE u8 regimm() const { return (raw >> 16) & 0x1F; }
|
||||
FORCE_INLINE u8 branch() const { return regimm(); }
|
||||
FORCE_INLINE u8 decode() const { return (raw >> 26) & 0x3F; }
|
||||
FORCE_INLINE u8 cop() const { return (raw >> 21) & 0x1F; }
|
||||
|
||||
static constexpr u8 SPECIAL = 0b000000;
|
||||
static constexpr u8 REGIMM = 0b000001;
|
||||
static constexpr u8 J = 0b000010;
|
||||
static constexpr u8 JAL = 0b000011;
|
||||
static constexpr u8 BEQ = 0b000100;
|
||||
static constexpr u8 BNE = 0b000101;
|
||||
static constexpr u8 BLEZ = 0b000110;
|
||||
static constexpr u8 BGTZ = 0b000111;
|
||||
static constexpr u8 ADDI = 0b001000;
|
||||
static constexpr u8 ADDIU = 0b001001;
|
||||
static constexpr u8 SLTI = 0b001010;
|
||||
static constexpr u8 SLTIU = 0b001011;
|
||||
static constexpr u8 ANDI = 0b001100;
|
||||
static constexpr u8 ORI = 0b001101;
|
||||
static constexpr u8 XORI = 0b001110;
|
||||
static constexpr u8 LUI = 0b001111;
|
||||
static constexpr u8 COP0 = 0b010000;
|
||||
static constexpr u8 COP1 = 0b010001;
|
||||
static constexpr u8 COP2 = 0b010010;
|
||||
static constexpr u8 BEQL = 0b010100;
|
||||
static constexpr u8 BNEL = 0b010101;
|
||||
static constexpr u8 BLEZL = 0b010110;
|
||||
static constexpr u8 BGTZL = 0b010111;
|
||||
static constexpr u8 DADDI = 0b011000;
|
||||
static constexpr u8 DADDIU = 0b011001;
|
||||
static constexpr u8 LDL = 0b011010;
|
||||
static constexpr u8 LDR = 0b011011;
|
||||
static constexpr u8 LB = 0b100000;
|
||||
static constexpr u8 LH = 0b100001;
|
||||
static constexpr u8 LWL = 0b100010;
|
||||
static constexpr u8 LW = 0b100011;
|
||||
static constexpr u8 LBU = 0b100100;
|
||||
static constexpr u8 LHU = 0b100101;
|
||||
static constexpr u8 LWR = 0b100110;
|
||||
static constexpr u8 LWU = 0b100111;
|
||||
static constexpr u8 SB = 0b101000;
|
||||
static constexpr u8 SH = 0b101001;
|
||||
static constexpr u8 SWL = 0b101010;
|
||||
static constexpr u8 SW = 0b101011;
|
||||
static constexpr u8 SDL = 0b101100;
|
||||
static constexpr u8 SDR = 0b101101;
|
||||
static constexpr u8 SWR = 0b101110;
|
||||
static constexpr u8 CACHE = 0b101111;
|
||||
static constexpr u8 LL = 0b110000;
|
||||
static constexpr u8 LWC1 = 0b110001;
|
||||
static constexpr u8 LWC2 = 0b110010;
|
||||
static constexpr u8 LLD = 0b110100;
|
||||
static constexpr u8 LDC1 = 0b110101;
|
||||
static constexpr u8 LDC2 = 0b110110;
|
||||
static constexpr u8 LD = 0b110111;
|
||||
static constexpr u8 SC = 0b111000;
|
||||
static constexpr u8 SWC1 = 0b111001;
|
||||
static constexpr u8 SWC2 = 0b111010;
|
||||
static constexpr u8 SCD = 0b111100;
|
||||
static constexpr u8 SDC1 = 0b111101;
|
||||
static constexpr u8 SDC2 = 0b111110;
|
||||
static constexpr u8 SD = 0b111111;
|
||||
// special
|
||||
static constexpr u8 SLL = 0b000000;
|
||||
static constexpr u8 SRL = 0b000010;
|
||||
static constexpr u8 SRA = 0b000011;
|
||||
static constexpr u8 SLLV = 0b000100;
|
||||
static constexpr u8 SRLV = 0b000110;
|
||||
static constexpr u8 SRAV = 0b000111;
|
||||
static constexpr u8 JR = 0b001000;
|
||||
static constexpr u8 JALR = 0b001001;
|
||||
static constexpr u8 SYSCALL = 0b001100;
|
||||
static constexpr u8 BREAK = 0b001101;
|
||||
static constexpr u8 SYNC = 0b001111;
|
||||
static constexpr u8 MFHI = 0b010000;
|
||||
static constexpr u8 MTHI = 0b010001;
|
||||
static constexpr u8 MFLO = 0b010010;
|
||||
static constexpr u8 MTLO = 0b010011;
|
||||
static constexpr u8 DSLLV = 0b010100;
|
||||
static constexpr u8 DSRLV = 0b010110;
|
||||
static constexpr u8 DSRAV = 0b010111;
|
||||
static constexpr u8 MULT = 0b011000;
|
||||
static constexpr u8 MULTU = 0b011001;
|
||||
static constexpr u8 DIV = 0b011010;
|
||||
static constexpr u8 DIVU = 0b011011;
|
||||
static constexpr u8 DMULT = 0b011100;
|
||||
static constexpr u8 DMULTU = 0b011101;
|
||||
static constexpr u8 DDIV = 0b011110;
|
||||
static constexpr u8 DDIVU = 0b011111;
|
||||
static constexpr u8 ADD = 0b100000;
|
||||
static constexpr u8 ADDU = 0b100001;
|
||||
static constexpr u8 SUB = 0b100010;
|
||||
static constexpr u8 SUBU = 0b100011;
|
||||
static constexpr u8 AND = 0b100100;
|
||||
static constexpr u8 OR = 0b100101;
|
||||
static constexpr u8 XOR = 0b100110;
|
||||
static constexpr u8 NOR = 0b100111;
|
||||
static constexpr u8 SLT = 0b101010;
|
||||
static constexpr u8 SLTU = 0b101011;
|
||||
static constexpr u8 DADD = 0b101100;
|
||||
static constexpr u8 DADDU = 0b101101;
|
||||
static constexpr u8 DSUB = 0b101110;
|
||||
static constexpr u8 DSUBU = 0b101111;
|
||||
static constexpr u8 TGE = 0b110000;
|
||||
static constexpr u8 TGEU = 0b110001;
|
||||
static constexpr u8 TLT = 0b110010;
|
||||
static constexpr u8 TLTU = 0b110011;
|
||||
static constexpr u8 TEQ = 0b110100;
|
||||
static constexpr u8 TNE = 0b110110;
|
||||
static constexpr u8 DSLL = 0b111000;
|
||||
static constexpr u8 DSRL = 0b111010;
|
||||
static constexpr u8 DSRA = 0b111011;
|
||||
static constexpr u8 DSLL32 = 0b111100;
|
||||
static constexpr u8 DSRL32 = 0b111110;
|
||||
static constexpr u8 DSRA32 = 0b111111;
|
||||
// regimm
|
||||
static constexpr u8 BLTZ = 0b00000;
|
||||
static constexpr u8 BGEZ = 0b00001;
|
||||
static constexpr u8 BLTZL = 0b00010;
|
||||
static constexpr u8 BGEZL = 0b00011;
|
||||
static constexpr u8 TGEI = 0b01000;
|
||||
static constexpr u8 TGEIU = 0b01001;
|
||||
static constexpr u8 TLTI = 0b01010;
|
||||
static constexpr u8 TLTIU = 0b01011;
|
||||
static constexpr u8 TEQI = 0b01100;
|
||||
static constexpr u8 TNEI = 0b01110;
|
||||
static constexpr u8 BLTZAL = 0b10000;
|
||||
static constexpr u8 BGEZAL = 0b10001;
|
||||
static constexpr u8 BLTZALL = 0b10010;
|
||||
static constexpr u8 BGEZALL = 0b10011;
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user