tests: [WIP] add unit tests for some of the instructions

Signed-off-by: Amneesh Singh <natto@weirdnatto.in>
This commit is contained in:
2023-09-15 14:07:23 +05:30
parent aa96237c37
commit be7deb349a
11 changed files with 445 additions and 173 deletions

View File

@@ -35,7 +35,7 @@ class Cpu {
bool is_flushed;
void chg_mode(const Mode to);
void exec_arm(const ArmInstruction instruction);
void exec_arm(const arm::ArmInstruction instruction);
struct {
std::array<uint32_t, GPR_COUNT - GPR_FIQ_FIRST - 1> fiq;

View File

@@ -9,159 +9,154 @@ struct overloaded : Ts... {
template<class... Ts>
overloaded(Ts...) -> overloaded<Ts...>;
class ArmInstruction {
public:
ArmInstruction() = delete;
ArmInstruction(uint32_t insn);
namespace arm {
struct BranchAndExchange {
uint8_t rn;
};
auto get_condition() const { return condition; }
auto get_data() const { return data; }
struct Branch {
bool link;
uint32_t offset;
};
std::string disassemble();
struct Multiply {
uint8_t rm;
uint8_t rs;
uint8_t rn;
uint8_t rd;
bool set;
bool acc;
};
struct BranchAndExchange {
uint8_t rn;
struct MultiplyLong {
uint8_t rm;
uint8_t rs;
uint8_t rdlo;
uint8_t rdhi;
bool set;
bool acc;
bool uns;
};
struct SingleDataSwap {
uint8_t rm;
uint8_t rd;
uint8_t rn;
bool byte;
};
struct SingleDataTransfer {
std::variant<uint16_t, Shift> offset;
uint8_t rd;
uint8_t rn;
bool load;
bool write;
bool byte;
bool up;
bool pre;
};
struct HalfwordTransfer {
uint8_t offset;
bool half;
bool sign;
uint8_t rd;
uint8_t rn;
bool load;
bool write;
bool byte;
bool imm;
bool up;
bool pre;
};
struct BlockDataTransfer {
uint16_t regs;
uint8_t rn;
bool load;
bool write;
bool s;
bool up;
bool pre;
};
struct DataProcessing {
std::variant<Shift, uint32_t> operand;
uint8_t rd;
uint8_t rn;
bool set;
OpCode opcode;
};
struct PsrTransfer {
enum class Type {
Mrs,
Msr,
Msr_flg
};
struct Branch {
bool link;
uint32_t offset;
};
uint32_t operand;
bool spsr;
Type type;
// ignored outside MSR_flg
bool imm;
};
struct Multiply {
uint8_t rm;
uint8_t rs;
uint8_t rn;
uint8_t rd;
bool set;
bool acc;
};
struct CoprocessorDataTransfer {
uint8_t offset;
uint8_t cpn;
uint8_t crd;
uint8_t rn;
bool load;
bool write;
bool len;
bool up;
bool pre;
};
struct MultiplyLong {
uint8_t rm;
uint8_t rs;
uint8_t rdlo;
uint8_t rdhi;
bool set;
bool acc;
bool uns;
};
struct CoprocessorDataOperation {
uint8_t crm;
uint8_t cp;
uint8_t cpn;
uint8_t crd;
uint8_t crn;
uint8_t cp_opc;
};
struct SingleDataSwap {
uint8_t rm;
uint8_t rd;
uint8_t rn;
bool byte;
};
struct CoprocessorRegisterTransfer {
uint8_t crm;
uint8_t cp;
uint8_t cpn;
uint8_t rd;
uint8_t crn;
bool load;
uint8_t cp_opc;
};
struct SingleDataTransfer {
std::variant<uint16_t, Shift> offset;
uint8_t rd;
uint8_t rn;
bool load;
bool write;
bool byte;
bool up;
bool pre;
};
struct Undefined {};
struct SoftwareInterrupt {};
struct HalfwordTransfer {
uint8_t offset;
bool half;
bool sign;
uint8_t rd;
uint8_t rn;
bool load;
bool write;
bool byte;
bool imm;
bool up;
bool pre;
};
using InstructionData = std::variant<BranchAndExchange,
Branch,
Multiply,
MultiplyLong,
SingleDataSwap,
SingleDataTransfer,
HalfwordTransfer,
BlockDataTransfer,
DataProcessing,
PsrTransfer,
CoprocessorDataTransfer,
CoprocessorDataOperation,
CoprocessorRegisterTransfer,
Undefined,
SoftwareInterrupt>;
struct BlockDataTransfer {
uint16_t regs;
uint8_t rn;
bool load;
bool write;
bool s;
bool up;
bool pre;
};
struct DataProcessing {
std::variant<Shift, uint32_t> operand;
uint8_t rd;
uint8_t rn;
bool set;
OpCode opcode;
};
struct PsrTransfer {
enum class Type {
Mrs,
Msr,
Msr_flg
};
uint32_t operand;
bool spsr;
Type type;
// ignored outside MSR_flg
bool imm;
};
struct CoprocessorDataTransfer {
uint8_t offset;
uint8_t cpn;
uint8_t crd;
uint8_t rn;
bool load;
bool write;
bool len;
bool up;
bool pre;
};
struct CoprocessorDataOperation {
uint8_t crm;
uint8_t cp;
uint8_t cpn;
uint8_t crd;
uint8_t crn;
uint8_t cp_opc;
};
struct CoprocessorRegisterTransfer {
uint8_t crm;
uint8_t cp;
uint8_t cpn;
uint8_t rd;
uint8_t crn;
bool load;
uint8_t cp_opc;
};
struct Undefined {};
struct SoftwareInterrupt {};
using InstructionData = std::variant<BranchAndExchange,
Branch,
Multiply,
MultiplyLong,
SingleDataSwap,
SingleDataTransfer,
HalfwordTransfer,
BlockDataTransfer,
DataProcessing,
PsrTransfer,
CoprocessorDataTransfer,
CoprocessorDataOperation,
CoprocessorRegisterTransfer,
Undefined,
SoftwareInterrupt>;
private:
struct ArmInstruction {
Condition condition;
InstructionData data;
ArmInstruction(uint32_t insn);
std::string disassemble();
};
}