restructure: get rid of cpu/utility
Signed-off-by: Amneesh Singh <natto@weirdnatto.in>
This commit is contained in:
@@ -1,74 +1,7 @@
|
|||||||
#include "utility.hh"
|
#include "alu.hh"
|
||||||
#include "util/bits.hh"
|
#include "util/bits.hh"
|
||||||
#include <bit>
|
|
||||||
|
|
||||||
namespace matar {
|
namespace matar {
|
||||||
namespace arm {
|
|
||||||
std::ostream&
|
|
||||||
operator<<(std::ostream& os, const Condition cond) {
|
|
||||||
|
|
||||||
#define CASE(cond) \
|
|
||||||
case Condition::cond: \
|
|
||||||
os << #cond; \
|
|
||||||
break;
|
|
||||||
|
|
||||||
switch (cond) {
|
|
||||||
CASE(EQ)
|
|
||||||
CASE(NE)
|
|
||||||
CASE(CS)
|
|
||||||
CASE(CC)
|
|
||||||
CASE(MI)
|
|
||||||
CASE(PL)
|
|
||||||
CASE(VS)
|
|
||||||
CASE(VC)
|
|
||||||
CASE(HI)
|
|
||||||
CASE(LS)
|
|
||||||
CASE(GE)
|
|
||||||
CASE(LT)
|
|
||||||
CASE(GT)
|
|
||||||
CASE(LE)
|
|
||||||
case Condition::AL: {
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef CASE
|
|
||||||
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ostream&
|
|
||||||
operator<<(std::ostream& os, const OpCode opcode) {
|
|
||||||
|
|
||||||
#define CASE(opcode) \
|
|
||||||
case OpCode::opcode: \
|
|
||||||
os << #opcode; \
|
|
||||||
break;
|
|
||||||
|
|
||||||
switch (opcode) {
|
|
||||||
CASE(AND)
|
|
||||||
CASE(EOR)
|
|
||||||
CASE(SUB)
|
|
||||||
CASE(RSB)
|
|
||||||
CASE(ADD)
|
|
||||||
CASE(ADC)
|
|
||||||
CASE(SBC)
|
|
||||||
CASE(RSC)
|
|
||||||
CASE(TST)
|
|
||||||
CASE(TEQ)
|
|
||||||
CASE(CMP)
|
|
||||||
CASE(CMN)
|
|
||||||
CASE(ORR)
|
|
||||||
CASE(MOV)
|
|
||||||
CASE(BIC)
|
|
||||||
CASE(MVN)
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef CASE
|
|
||||||
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
eval_shift(ShiftType shift_type, uint32_t value, uint8_t amount, bool& carry) {
|
eval_shift(ShiftType shift_type, uint32_t value, uint8_t amount, bool& carry) {
|
||||||
uint32_t eval = 0;
|
uint32_t eval = 0;
|
||||||
@@ -136,4 +69,3 @@ operator<<(std::ostream& os, const ShiftType shift_type) {
|
|||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
35
src/cpu/alu.hh
Normal file
35
src/cpu/alu.hh
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <cstdint>
|
||||||
|
#include <fmt/ostream.h>
|
||||||
|
|
||||||
|
namespace matar {
|
||||||
|
enum class ShiftType {
|
||||||
|
LSL = 0b00,
|
||||||
|
LSR = 0b01,
|
||||||
|
ASR = 0b10,
|
||||||
|
ROR = 0b11
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ShiftData {
|
||||||
|
ShiftType type;
|
||||||
|
bool immediate;
|
||||||
|
uint8_t operand;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Shift {
|
||||||
|
uint8_t rm;
|
||||||
|
ShiftData data;
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
eval_shift(ShiftType shift_type, uint32_t value, uint8_t amount, bool& carry);
|
||||||
|
|
||||||
|
// https://fmt.dev/dev/api.html#std-ostream-support
|
||||||
|
std::ostream&
|
||||||
|
operator<<(std::ostream& os, const ShiftType cond);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace fmt {
|
||||||
|
template<>
|
||||||
|
struct formatter<matar::ShiftType> : ostream_formatter {};
|
||||||
|
}
|
@@ -7,7 +7,7 @@ using namespace logger;
|
|||||||
namespace matar {
|
namespace matar {
|
||||||
void
|
void
|
||||||
CpuImpl::exec_arm(const arm::Instruction instruction) {
|
CpuImpl::exec_arm(const arm::Instruction instruction) {
|
||||||
arm::Condition cond = instruction.condition;
|
Condition cond = instruction.condition;
|
||||||
arm::InstructionData data = instruction.data;
|
arm::InstructionData data = instruction.data;
|
||||||
|
|
||||||
debug(cpsr.condition(cond));
|
debug(cpsr.condition(cond));
|
||||||
@@ -387,6 +387,8 @@ CpuImpl::exec_arm(const arm::Instruction instruction) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
[this, pc_error](DataProcessing& data) {
|
[this, pc_error](DataProcessing& data) {
|
||||||
|
using OpCode = DataProcessing::OpCode;
|
||||||
|
|
||||||
uint32_t op_1 = gpr[data.rn];
|
uint32_t op_1 = gpr[data.rn];
|
||||||
uint32_t op_2 = 0;
|
uint32_t op_2 = 0;
|
||||||
|
|
||||||
|
@@ -1,5 +1,4 @@
|
|||||||
#include "instruction.hh"
|
#include "instruction.hh"
|
||||||
#include "cpu/utility.hh"
|
|
||||||
#include "util/bits.hh"
|
#include "util/bits.hh"
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
|
||||||
@@ -153,6 +152,8 @@ Instruction::Instruction(uint32_t insn)
|
|||||||
|
|
||||||
// Data Processing
|
// Data Processing
|
||||||
} else if ((insn & 0x0C000000) == 0x00000000) {
|
} else if ((insn & 0x0C000000) == 0x00000000) {
|
||||||
|
using OpCode = DataProcessing::OpCode;
|
||||||
|
|
||||||
uint8_t rd = bit_range(insn, 12, 15);
|
uint8_t rd = bit_range(insn, 12, 15);
|
||||||
uint8_t rn = bit_range(insn, 16, 19);
|
uint8_t rn = bit_range(insn, 16, 19);
|
||||||
bool set = get_bit(insn, 20);
|
bool set = get_bit(insn, 20);
|
||||||
@@ -420,6 +421,8 @@ Instruction::disassemble() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
[this](DataProcessing& data) {
|
[this](DataProcessing& data) {
|
||||||
|
using OpCode = DataProcessing::OpCode;
|
||||||
|
|
||||||
std::string op_2;
|
std::string op_2;
|
||||||
|
|
||||||
if (const uint32_t* operand =
|
if (const uint32_t* operand =
|
||||||
@@ -496,5 +499,37 @@ Instruction::disassemble() {
|
|||||||
[](auto) { return std::string("unknown instruction"); } },
|
[](auto) { return std::string("unknown instruction"); } },
|
||||||
data);
|
data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::ostream&
|
||||||
|
operator<<(std::ostream& os, const DataProcessing::OpCode opcode) {
|
||||||
|
|
||||||
|
#define CASE(opcode) \
|
||||||
|
case DataProcessing::OpCode::opcode: \
|
||||||
|
os << #opcode; \
|
||||||
|
break;
|
||||||
|
|
||||||
|
switch (opcode) {
|
||||||
|
CASE(AND)
|
||||||
|
CASE(EOR)
|
||||||
|
CASE(SUB)
|
||||||
|
CASE(RSB)
|
||||||
|
CASE(ADD)
|
||||||
|
CASE(ADC)
|
||||||
|
CASE(SBC)
|
||||||
|
CASE(RSC)
|
||||||
|
CASE(TST)
|
||||||
|
CASE(TEQ)
|
||||||
|
CASE(CMP)
|
||||||
|
CASE(CMN)
|
||||||
|
CASE(ORR)
|
||||||
|
CASE(MOV)
|
||||||
|
CASE(BIC)
|
||||||
|
CASE(MVN)
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef CASE
|
||||||
|
|
||||||
|
return os;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "cpu/utility.hh"
|
#include "cpu/alu.hh"
|
||||||
|
#include "cpu/psr.hh"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <fmt/ostream.h>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
|
namespace matar {
|
||||||
|
namespace arm {
|
||||||
|
|
||||||
template<class... Ts>
|
template<class... Ts>
|
||||||
struct overloaded : Ts... {
|
struct overloaded : Ts... {
|
||||||
using Ts::operator()...;
|
using Ts::operator()...;
|
||||||
@@ -10,8 +15,6 @@ struct overloaded : Ts... {
|
|||||||
template<class... Ts>
|
template<class... Ts>
|
||||||
overloaded(Ts...) -> overloaded<Ts...>;
|
overloaded(Ts...) -> overloaded<Ts...>;
|
||||||
|
|
||||||
namespace matar {
|
|
||||||
namespace arm {
|
|
||||||
static constexpr size_t INSTRUCTION_SIZE = 4;
|
static constexpr size_t INSTRUCTION_SIZE = 4;
|
||||||
|
|
||||||
struct BranchAndExchange {
|
struct BranchAndExchange {
|
||||||
@@ -84,6 +87,25 @@ struct BlockDataTransfer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct DataProcessing {
|
struct DataProcessing {
|
||||||
|
enum class OpCode {
|
||||||
|
AND = 0b0000,
|
||||||
|
EOR = 0b0001,
|
||||||
|
SUB = 0b0010,
|
||||||
|
RSB = 0b0011,
|
||||||
|
ADD = 0b0100,
|
||||||
|
ADC = 0b0101,
|
||||||
|
SBC = 0b0110,
|
||||||
|
RSC = 0b0111,
|
||||||
|
TST = 0b1000,
|
||||||
|
TEQ = 0b1001,
|
||||||
|
CMP = 0b1010,
|
||||||
|
CMN = 0b1011,
|
||||||
|
ORR = 0b1100,
|
||||||
|
MOV = 0b1101,
|
||||||
|
BIC = 0b1110,
|
||||||
|
MVN = 0b1111
|
||||||
|
};
|
||||||
|
|
||||||
std::variant<Shift, uint32_t> operand;
|
std::variant<Shift, uint32_t> operand;
|
||||||
uint8_t rd;
|
uint8_t rd;
|
||||||
uint8_t rn;
|
uint8_t rn;
|
||||||
@@ -166,5 +188,13 @@ struct Instruction {
|
|||||||
|
|
||||||
std::string disassemble();
|
std::string disassemble();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::ostream&
|
||||||
|
operator<<(std::ostream& os, const DataProcessing::OpCode cond);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace fmt {
|
||||||
|
template<>
|
||||||
|
struct formatter<matar::arm::DataProcessing::OpCode> : ostream_formatter {};
|
||||||
|
}
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
#include "cpu-impl.hh"
|
#include "cpu-impl.hh"
|
||||||
#include "util/bits.hh"
|
#include "util/bits.hh"
|
||||||
#include "util/log.hh"
|
#include "util/log.hh"
|
||||||
#include "utility.hh"
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
|
@@ -2,7 +2,7 @@ lib_sources += files(
|
|||||||
'cpu-impl.cc',
|
'cpu-impl.cc',
|
||||||
'cpu.cc',
|
'cpu.cc',
|
||||||
'psr.cc',
|
'psr.cc',
|
||||||
'utility.cc'
|
'alu.cc'
|
||||||
)
|
)
|
||||||
|
|
||||||
subdir('arm')
|
subdir('arm')
|
@@ -60,9 +60,7 @@ GET_SET_NTH_BIT_FUNCTIONS(n, 31);
|
|||||||
#undef GET_SET_NTH_BIT_FUNCTIONS
|
#undef GET_SET_NTH_BIT_FUNCTIONS
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Psr::condition(arm::Condition cond) const {
|
Psr::condition(Condition cond) const {
|
||||||
using arm::Condition;
|
|
||||||
|
|
||||||
switch (cond) {
|
switch (cond) {
|
||||||
case Condition::EQ:
|
case Condition::EQ:
|
||||||
return z();
|
return z();
|
||||||
@@ -93,9 +91,42 @@ Psr::condition(arm::Condition cond) const {
|
|||||||
case Condition::LE:
|
case Condition::LE:
|
||||||
return z() || (n() != v());
|
return z() || (n() != v());
|
||||||
case Condition::AL:
|
case Condition::AL:
|
||||||
return true;
|
return true && state() == State::Arm;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::ostream&
|
||||||
|
operator<<(std::ostream& os, const Condition cond) {
|
||||||
|
|
||||||
|
#define CASE(cond) \
|
||||||
|
case Condition::cond: \
|
||||||
|
os << #cond; \
|
||||||
|
break;
|
||||||
|
|
||||||
|
switch (cond) {
|
||||||
|
CASE(EQ)
|
||||||
|
CASE(NE)
|
||||||
|
CASE(CS)
|
||||||
|
CASE(CC)
|
||||||
|
CASE(MI)
|
||||||
|
CASE(PL)
|
||||||
|
CASE(VS)
|
||||||
|
CASE(VC)
|
||||||
|
CASE(HI)
|
||||||
|
CASE(LS)
|
||||||
|
CASE(GE)
|
||||||
|
CASE(LT)
|
||||||
|
CASE(GT)
|
||||||
|
CASE(LE)
|
||||||
|
case Condition::AL: {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef CASE
|
||||||
|
|
||||||
|
return os;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,10 +1,43 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "arm/instruction.hh"
|
|
||||||
#include "utility.hh"
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <fmt/ostream.h>
|
||||||
|
|
||||||
namespace matar {
|
namespace matar {
|
||||||
|
enum class Mode {
|
||||||
|
/* M[4:0] in PSR */
|
||||||
|
User = 0b10000,
|
||||||
|
Fiq = 0b10001,
|
||||||
|
Irq = 0b10010,
|
||||||
|
Supervisor = 0b10011,
|
||||||
|
Abort = 0b10111,
|
||||||
|
Undefined = 0b11011,
|
||||||
|
System = 0b11111,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class State {
|
||||||
|
Arm = 0,
|
||||||
|
Thumb = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class Condition {
|
||||||
|
EQ = 0b0000,
|
||||||
|
NE = 0b0001,
|
||||||
|
CS = 0b0010,
|
||||||
|
CC = 0b0011,
|
||||||
|
MI = 0b0100,
|
||||||
|
PL = 0b0101,
|
||||||
|
VS = 0b0110,
|
||||||
|
VC = 0b0111,
|
||||||
|
HI = 0b1000,
|
||||||
|
LS = 0b1001,
|
||||||
|
GE = 0b1010,
|
||||||
|
LT = 0b1011,
|
||||||
|
GT = 0b1100,
|
||||||
|
LE = 0b1101,
|
||||||
|
AL = 0b1110
|
||||||
|
};
|
||||||
|
|
||||||
class Psr {
|
class Psr {
|
||||||
public:
|
public:
|
||||||
// clear the reserved bits i.e, [8:27]
|
// clear the reserved bits i.e, [8:27]
|
||||||
@@ -47,7 +80,7 @@ class Psr {
|
|||||||
|
|
||||||
#undef GET_SET_NTH_BIT_FUNCTIONS
|
#undef GET_SET_NTH_BIT_FUNCTIONS
|
||||||
|
|
||||||
bool condition(arm::Condition cond) const;
|
bool condition(Condition cond) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr uint32_t PSR_CLEAR_RESERVED = 0xF00000FF;
|
static constexpr uint32_t PSR_CLEAR_RESERVED = 0xF00000FF;
|
||||||
@@ -55,4 +88,13 @@ class Psr {
|
|||||||
|
|
||||||
uint32_t psr;
|
uint32_t psr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// https://fmt.dev/dev/api.html#std-ostream-support
|
||||||
|
std::ostream&
|
||||||
|
operator<<(std::ostream& os, const Condition cond);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace fmt {
|
||||||
|
template<>
|
||||||
|
struct formatter<matar::Condition> : ostream_formatter {};
|
||||||
}
|
}
|
||||||
|
@@ -1,103 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <fmt/ostream.h>
|
|
||||||
#include <ostream>
|
|
||||||
|
|
||||||
static constexpr size_t THUMB_INSTRUCTION_SIZE = 2;
|
|
||||||
|
|
||||||
namespace matar {
|
|
||||||
enum class Mode {
|
|
||||||
/* M[4:0] in PSR */
|
|
||||||
User = 0b10000,
|
|
||||||
Fiq = 0b10001,
|
|
||||||
Irq = 0b10010,
|
|
||||||
Supervisor = 0b10011,
|
|
||||||
Abort = 0b10111,
|
|
||||||
Undefined = 0b11011,
|
|
||||||
System = 0b11111,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class State {
|
|
||||||
Arm = 0,
|
|
||||||
Thumb = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace arm {
|
|
||||||
enum class Condition {
|
|
||||||
EQ = 0b0000,
|
|
||||||
NE = 0b0001,
|
|
||||||
CS = 0b0010,
|
|
||||||
CC = 0b0011,
|
|
||||||
MI = 0b0100,
|
|
||||||
PL = 0b0101,
|
|
||||||
VS = 0b0110,
|
|
||||||
VC = 0b0111,
|
|
||||||
HI = 0b1000,
|
|
||||||
LS = 0b1001,
|
|
||||||
GE = 0b1010,
|
|
||||||
LT = 0b1011,
|
|
||||||
GT = 0b1100,
|
|
||||||
LE = 0b1101,
|
|
||||||
AL = 0b1110
|
|
||||||
};
|
|
||||||
|
|
||||||
// https://fmt.dev/dev/api.html#std-ostream-support
|
|
||||||
std::ostream&
|
|
||||||
operator<<(std::ostream& os, const Condition cond);
|
|
||||||
|
|
||||||
enum class OpCode {
|
|
||||||
AND = 0b0000,
|
|
||||||
EOR = 0b0001,
|
|
||||||
SUB = 0b0010,
|
|
||||||
RSB = 0b0011,
|
|
||||||
ADD = 0b0100,
|
|
||||||
ADC = 0b0101,
|
|
||||||
SBC = 0b0110,
|
|
||||||
RSC = 0b0111,
|
|
||||||
TST = 0b1000,
|
|
||||||
TEQ = 0b1001,
|
|
||||||
CMP = 0b1010,
|
|
||||||
CMN = 0b1011,
|
|
||||||
ORR = 0b1100,
|
|
||||||
MOV = 0b1101,
|
|
||||||
BIC = 0b1110,
|
|
||||||
MVN = 0b1111
|
|
||||||
};
|
|
||||||
|
|
||||||
// https://fmt.dev/dev/api.html#std-ostream-support
|
|
||||||
std::ostream&
|
|
||||||
operator<<(std::ostream& os, const OpCode cond);
|
|
||||||
|
|
||||||
enum class ShiftType {
|
|
||||||
LSL = 0b00,
|
|
||||||
LSR = 0b01,
|
|
||||||
ASR = 0b10,
|
|
||||||
ROR = 0b11
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ShiftData {
|
|
||||||
ShiftType type;
|
|
||||||
bool immediate;
|
|
||||||
uint8_t operand;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Shift {
|
|
||||||
uint8_t rm;
|
|
||||||
ShiftData data;
|
|
||||||
};
|
|
||||||
|
|
||||||
uint32_t
|
|
||||||
eval_shift(ShiftType shift_type, uint32_t value, uint8_t amount, bool& carry);
|
|
||||||
|
|
||||||
// https://fmt.dev/dev/api.html#std-ostream-support
|
|
||||||
std::ostream&
|
|
||||||
operator<<(std::ostream& os, const ShiftType cond);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct fmt::formatter<matar::arm::Condition> : ostream_formatter {};
|
|
||||||
template<>
|
|
||||||
struct fmt::formatter<matar::arm::OpCode> : ostream_formatter {};
|
|
||||||
template<>
|
|
||||||
struct fmt::formatter<matar::arm::ShiftType> : ostream_formatter {};
|
|
@@ -1,11 +1,11 @@
|
|||||||
#include "cpu/cpu-impl.hh"
|
#include "cpu/cpu-impl.hh"
|
||||||
#include "cpu/utility.hh"
|
|
||||||
#include "util/bits.hh"
|
#include "util/bits.hh"
|
||||||
#include <catch2/catch_test_macros.hpp>
|
#include <catch2/catch_test_macros.hpp>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
using namespace matar;
|
using namespace matar;
|
||||||
|
|
||||||
class CpuFixture {
|
class CpuFixture {
|
||||||
public:
|
public:
|
||||||
CpuFixture()
|
CpuFixture()
|
||||||
@@ -13,8 +13,7 @@ class CpuFixture {
|
|||||||
std::vector<uint8_t>(Header::HEADER_SIZE)))) {}
|
std::vector<uint8_t>(Header::HEADER_SIZE)))) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void exec(arm::InstructionData data,
|
void exec(arm::InstructionData data, Condition condition = Condition::AL) {
|
||||||
arm::Condition condition = arm::Condition::AL) {
|
|
||||||
arm::Instruction instruction(condition, data);
|
arm::Instruction instruction(condition, data);
|
||||||
cpu.exec_arm(instruction);
|
cpu.exec_arm(instruction);
|
||||||
}
|
}
|
||||||
@@ -746,6 +745,8 @@ TEST_CASE_METHOD(CpuFixture, "PSR Transfer", TAG) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(CpuFixture, "Data Processing", TAG) {
|
TEST_CASE_METHOD(CpuFixture, "Data Processing", TAG) {
|
||||||
|
using OpCode = DataProcessing::OpCode;
|
||||||
|
|
||||||
InstructionData data =
|
InstructionData data =
|
||||||
DataProcessing{ .operand = Shift{ .rm = 3,
|
DataProcessing{ .operand = Shift{ .rm = 3,
|
||||||
.data =
|
.data =
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
#include "cpu/arm/instruction.hh"
|
#include "cpu/arm/instruction.hh"
|
||||||
#include "cpu/utility.hh"
|
|
||||||
#include <catch2/catch_test_macros.hpp>
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
|
||||||
#define TAG "disassembler"
|
#define TAG "disassembler"
|
||||||
|
|
||||||
using namespace matar::arm;
|
using namespace matar;
|
||||||
|
using namespace arm;
|
||||||
|
|
||||||
TEST_CASE("Branch and Exchange", TAG) {
|
TEST_CASE("Branch and Exchange", TAG) {
|
||||||
uint32_t raw = 0b11000001001011111111111100011010;
|
uint32_t raw = 0b11000001001011111111111100011010;
|
||||||
@@ -309,6 +309,8 @@ TEST_CASE("PSR Transfer", TAG) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Data Processing", TAG) {
|
TEST_CASE("Data Processing", TAG) {
|
||||||
|
using OpCode = DataProcessing::OpCode;
|
||||||
|
|
||||||
uint32_t raw = 0b11100000000111100111101101100001;
|
uint32_t raw = 0b11100000000111100111101101100001;
|
||||||
Instruction instruction(raw);
|
Instruction instruction(raw);
|
||||||
DataProcessing* alu = nullptr;
|
DataProcessing* alu = nullptr;
|
||||||
|
Reference in New Issue
Block a user