mirror of
https://github.com/ApfelTeeSaft/WebMetal.git
synced 2026-08-26 19:43:24 +00:00
130 lines
3.1 KiB
C++
130 lines
3.1 KiB
C++
#pragma once
|
|
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
namespace webmetal {
|
|
|
|
// ---- machine model ----
|
|
|
|
struct BankDecl {
|
|
std::string name;
|
|
std::uint32_t width = 8;
|
|
std::uint32_t count = 1;
|
|
};
|
|
|
|
struct MemoryDecl {
|
|
std::string name;
|
|
std::uint32_t size = 0;
|
|
std::uint32_t width = 8;
|
|
};
|
|
|
|
struct MachineModel {
|
|
std::vector<BankDecl> banks;
|
|
std::vector<MemoryDecl> memories;
|
|
std::vector<std::string> flags;
|
|
std::uint32_t pcWidth = 16;
|
|
std::string programMemory;
|
|
};
|
|
|
|
// ---- micro-op IR ----
|
|
|
|
struct SrcIndex {
|
|
bool isOperand = false;
|
|
std::uint32_t literal = 0;
|
|
std::string field; // when isOperand
|
|
};
|
|
|
|
struct Src {
|
|
enum class Kind { Const, Reg, Pc, Temp, Operand, Flag };
|
|
Kind kind = Kind::Const;
|
|
std::uint32_t value = 0; // Const / Temp index
|
|
std::string name; // Reg bank / Operand field / Flag name
|
|
SrcIndex index; // Reg
|
|
};
|
|
|
|
struct Dst {
|
|
enum class Kind { Reg, Pc, Temp };
|
|
Kind kind = Kind::Temp;
|
|
std::uint32_t tempIndex = 0; // Temp
|
|
std::string bank; // Reg
|
|
SrcIndex index; // Reg
|
|
};
|
|
|
|
struct MicroOp {
|
|
enum class Op { Move, Alu, Load, Store, SetFlag, Jump, Branch, Halt };
|
|
Op op = Op::Halt;
|
|
// move / alu / load
|
|
Dst dst;
|
|
// move src / store src / setFlag src
|
|
Src src;
|
|
// alu
|
|
std::string fn;
|
|
std::uint32_t width = 8;
|
|
Src a;
|
|
Src b;
|
|
bool hasB = false;
|
|
bool setFlags = false;
|
|
// load / store
|
|
std::string memory;
|
|
Src addr;
|
|
// setFlag / branch
|
|
std::string flagName;
|
|
bool ifSet = true;
|
|
// jump / branch
|
|
Src target;
|
|
};
|
|
|
|
// ---- ISA tables ----
|
|
|
|
struct BitField {
|
|
std::uint32_t word = 0;
|
|
std::uint32_t offset = 0;
|
|
std::uint32_t width = 8;
|
|
};
|
|
|
|
struct OperandDef {
|
|
std::string name;
|
|
BitField field;
|
|
};
|
|
|
|
struct InstructionDef {
|
|
std::string mnemonic;
|
|
std::uint32_t opcode = 0;
|
|
std::uint32_t words = 1;
|
|
std::vector<OperandDef> operands;
|
|
std::vector<MicroOp> microOps;
|
|
};
|
|
|
|
struct IsaTables {
|
|
BitField opcodeField; // always word 0
|
|
std::vector<InstructionDef> instructions;
|
|
};
|
|
|
|
// ---- parsing (returns false + error on malformed input) ----
|
|
|
|
bool parseMachineModel(const std::string& json, MachineModel& out,
|
|
std::string& error);
|
|
bool parseIsa(const std::string& json, IsaTables& out, std::string& error);
|
|
// [{ "address": n, "values": [...] }]
|
|
struct ProgramSegment {
|
|
std::uint32_t address = 0;
|
|
std::vector<std::uint32_t> values;
|
|
};
|
|
bool parseProgram(const std::string& json, std::vector<ProgramSegment>& out,
|
|
std::string& error);
|
|
// A bare micro-op sequence (used by the conformance/test surface).
|
|
bool parseMicroOps(const std::string& json, std::vector<MicroOp>& out,
|
|
std::string& error);
|
|
// {"name": value, ...} decoded operand values.
|
|
bool parseOperands(const std::string& json,
|
|
std::vector<std::pair<std::string, std::uint32_t>>& out,
|
|
std::string& error);
|
|
|
|
inline std::uint32_t maskOf(std::uint32_t width) {
|
|
return width >= 32 ? 0xFFFFFFFFu : ((1u << width) - 1u);
|
|
}
|
|
|
|
} // namespace webmetal
|