refactor: reorganize everything

Signed-off-by: Amneesh Singh <natto@weirdnatto.in>
This commit is contained in:
2023-10-04 01:41:38 +05:30
parent 36d71a4ee2
commit e0f7f32699
28 changed files with 297 additions and 338 deletions

View File

@@ -0,0 +1,230 @@
#pragma once
#include "cpu/alu.hh"
#include "cpu/psr.hh"
#include <cstdint>
#include <fmt/ostream.h>
#include <variant>
namespace matar {
class Cpu;
namespace arm {
// https://en.cppreference.com/w/cpp/utility/variant/visit
template<class... Ts>
struct overloaded : Ts... {
using Ts::operator()...;
};
template<class... Ts>
overloaded(Ts...) -> overloaded<Ts...>;
static constexpr size_t INSTRUCTION_SIZE = 4;
struct BranchAndExchange {
uint8_t rn;
};
struct Branch {
bool link;
uint32_t offset;
};
struct Multiply {
uint8_t rm;
uint8_t rs;
uint8_t rn;
uint8_t rd;
bool set;
bool acc;
};
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 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 {
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;
uint8_t rd;
uint8_t rn;
bool set;
OpCode opcode;
};
constexpr auto
stringify(DataProcessing::OpCode opcode) {
#define CASE(opcode) \
case DataProcessing::OpCode::opcode: \
return #opcode;
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 "";
}
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>;
struct Instruction {
Instruction(uint32_t insn);
Instruction(Condition condition, InstructionData data)
: condition(condition)
, data(data){};
void exec(Cpu& cpu);
#ifdef DISASSEMBLER
std::string disassemble();
#endif
Condition condition;
InstructionData data;
};
}
}

View File

@@ -0,0 +1,3 @@
headers += files(
'instruction.hh'
)