tests: complete disassembler tests
Signed-off-by: Amneesh Singh <natto@weirdnatto.in>
This commit is contained in:
@@ -116,7 +116,7 @@ Cpu::chg_mode(const Mode to) {
|
||||
}
|
||||
|
||||
void
|
||||
Cpu::exec_arm(const arm::ArmInstruction instruction) {
|
||||
Cpu::exec_arm(const arm::Instruction instruction) {
|
||||
auto cond = instruction.condition;
|
||||
auto data = instruction.data;
|
||||
|
||||
@@ -470,8 +470,8 @@ Cpu::exec_arm(const arm::ArmInstruction instruction) {
|
||||
|
||||
if (cpsr.mode() != Mode::User) {
|
||||
psr.set_all(gpr[data.operand]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PsrTransfer::Type::Msr_flg:
|
||||
psr.set_n(get_bit(data.operand, 31));
|
||||
psr.set_z(get_bit(data.operand, 30));
|
||||
@@ -648,7 +648,7 @@ Cpu::exec_arm(const arm::ArmInstruction instruction) {
|
||||
debug(zero);
|
||||
debug(negative);
|
||||
|
||||
auto set_conditions = [=]() {
|
||||
auto set_conditions = [this, carry, overflow, negative, zero]() {
|
||||
cpsr.set_c(carry);
|
||||
cpsr.set_v(overflow);
|
||||
cpsr.set_n(negative);
|
||||
@@ -693,7 +693,7 @@ Cpu::step() {
|
||||
if (cpsr.state() == State::Arm) {
|
||||
debug(cur_pc);
|
||||
uint32_t x = bus->read_word(cur_pc);
|
||||
arm::ArmInstruction instruction(x);
|
||||
arm::Instruction instruction(x);
|
||||
log_info("{:#034b}", x);
|
||||
|
||||
exec_arm(instruction);
|
||||
|
@@ -5,7 +5,7 @@
|
||||
|
||||
using namespace arm;
|
||||
|
||||
ArmInstruction::ArmInstruction(uint32_t insn)
|
||||
Instruction::Instruction(uint32_t insn)
|
||||
: condition(static_cast<Condition>(bit_range(insn, 28, 31))) {
|
||||
// Branch and exhcange
|
||||
if ((insn & 0x0FFFFFF0) == 0x012FFF10) {
|
||||
@@ -164,10 +164,9 @@ ArmInstruction::ArmInstruction(uint32_t insn)
|
||||
.type = PsrTransfer::Type::Mrs,
|
||||
.imm = 0 };
|
||||
} else if ((opcode == OpCode::TEQ || opcode == OpCode::CMN) && !set) {
|
||||
bool imm = get_bit(insn, 25);
|
||||
uint32_t operand = 0;
|
||||
|
||||
if (imm) {
|
||||
if (!imm) {
|
||||
operand = bit_range(insn, 0, 3);
|
||||
} else {
|
||||
uint32_t immediate = bit_range(insn, 0, 7);
|
||||
@@ -185,12 +184,11 @@ ArmInstruction::ArmInstruction(uint32_t insn)
|
||||
} else {
|
||||
std::variant<Shift, uint32_t> operand;
|
||||
|
||||
if (imm) {
|
||||
if (!imm) {
|
||||
uint32_t immediate = bit_range(insn, 0, 7);
|
||||
uint8_t rotate = bit_range(insn, 8, 11);
|
||||
|
||||
operand = std::rotr(immediate, rotate * 2);
|
||||
|
||||
} else {
|
||||
uint8_t rm = bit_range(insn, 0, 3);
|
||||
bool reg = get_bit(insn, 4);
|
||||
@@ -240,7 +238,7 @@ ArmInstruction::ArmInstruction(uint32_t insn)
|
||||
|
||||
// Coprocessor data operation
|
||||
} else if ((insn & 0x0F000010) == 0x0E000000) {
|
||||
uint8_t crm = bit_range(insn, 0, 4);
|
||||
uint8_t crm = bit_range(insn, 0, 3);
|
||||
uint8_t cp = bit_range(insn, 5, 7);
|
||||
uint8_t cpn = bit_range(insn, 8, 11);
|
||||
uint8_t crd = bit_range(insn, 12, 15);
|
||||
@@ -256,7 +254,7 @@ ArmInstruction::ArmInstruction(uint32_t insn)
|
||||
|
||||
// Coprocessor register transfer
|
||||
} else if ((insn & 0x0F000010) == 0x0E000010) {
|
||||
uint8_t crm = bit_range(insn, 0, 4);
|
||||
uint8_t crm = bit_range(insn, 0, 3);
|
||||
uint8_t cp = bit_range(insn, 5, 7);
|
||||
uint8_t cpn = bit_range(insn, 8, 11);
|
||||
uint8_t rd = bit_range(insn, 12, 15);
|
||||
@@ -277,8 +275,7 @@ ArmInstruction::ArmInstruction(uint32_t insn)
|
||||
}
|
||||
|
||||
std::string
|
||||
ArmInstruction::disassemble() {
|
||||
static const std::string undefined = "UNDEFINED";
|
||||
Instruction::disassemble() {
|
||||
// goddamn this is gore
|
||||
// TODO: make this less ugly
|
||||
return std::visit(
|
||||
@@ -319,7 +316,7 @@ ArmInstruction::disassemble() {
|
||||
data.rm,
|
||||
data.rs);
|
||||
},
|
||||
[](Undefined) { return undefined; },
|
||||
[](Undefined) { return std::string("UND"); },
|
||||
[this](SingleDataSwap& data) {
|
||||
return fmt::format("SWP{}{} R{:d},R{:d},[R{:d}]",
|
||||
condition,
|
||||
@@ -485,7 +482,7 @@ ArmInstruction::disassemble() {
|
||||
data.cp);
|
||||
},
|
||||
[this](CoprocessorRegisterTransfer& data) {
|
||||
return fmt::format("{}{} p{},{},c{},c{},c{},{}",
|
||||
return fmt::format("{}{} p{},{},R{},c{},c{},{}",
|
||||
(data.load ? "MRC" : "MCR"),
|
||||
condition,
|
||||
data.cpn,
|
||||
@@ -495,6 +492,6 @@ ArmInstruction::disassemble() {
|
||||
data.crm,
|
||||
data.cp);
|
||||
},
|
||||
[](auto) { return undefined; } },
|
||||
[](auto) { return std::string("unknown instruction"); } },
|
||||
data);
|
||||
}
|
||||
|
@@ -92,4 +92,6 @@ Psr::condition(Condition cond) const {
|
||||
case Condition::AL:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@@ -69,6 +69,8 @@ operator<<(std::ostream& os, const OpCode opcode) {
|
||||
|
||||
uint32_t
|
||||
eval_shift(ShiftType shift_type, uint32_t value, uint8_t amount, bool& carry) {
|
||||
uint32_t eval = 0;
|
||||
|
||||
switch (shift_type) {
|
||||
case ShiftType::LSL:
|
||||
|
||||
@@ -77,7 +79,8 @@ eval_shift(ShiftType shift_type, uint32_t value, uint8_t amount, bool& carry) {
|
||||
else if (amount > 32)
|
||||
carry = 0;
|
||||
|
||||
return value << amount;
|
||||
eval = value << amount;
|
||||
break;
|
||||
case ShiftType::LSR:
|
||||
|
||||
if (amount > 0 && amount <= 32)
|
||||
@@ -87,7 +90,8 @@ eval_shift(ShiftType shift_type, uint32_t value, uint8_t amount, bool& carry) {
|
||||
else
|
||||
carry = get_bit(value, 31);
|
||||
|
||||
return value >> amount;
|
||||
eval = value >> amount;
|
||||
break;
|
||||
case ShiftType::ASR:
|
||||
if (amount > 0 && amount <= 32)
|
||||
carry = get_bit(value, amount - 1);
|
||||
@@ -95,17 +99,21 @@ eval_shift(ShiftType shift_type, uint32_t value, uint8_t amount, bool& carry) {
|
||||
carry = get_bit(value, 31);
|
||||
|
||||
return static_cast<int32_t>(value) >> amount;
|
||||
break;
|
||||
case ShiftType::ROR:
|
||||
if (amount == 0) {
|
||||
bool old_carry = carry;
|
||||
|
||||
carry = get_bit(value, 0);
|
||||
return (value >> 1) | (old_carry << 31);
|
||||
eval = (value >> 1) | (old_carry << 31);
|
||||
} else {
|
||||
carry = get_bit(value, (amount % 32 + 31) % 32);
|
||||
return std::rotr(value, amount);
|
||||
eval = std::rotr(value, amount);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return eval;
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
|
Reference in New Issue
Block a user