diff options
Diffstat (limited to 'intel.cpp')
-rw-r--r-- | intel.cpp | 69 |
1 files changed, 66 insertions, 3 deletions
@@ -6,6 +6,7 @@ #include "minicc.h" #include <algorithm> +#include <any> #include <array> #include <deque> #include <functional> @@ -146,7 +147,7 @@ namespace { throw std::runtime_error("Unknown command: "s + sl[0].value); } - std::unordered_map<std::string, std::function<InstructionCodeList(const std::vector<Token>&)>> ops{ + std::unordered_map<std::string, std::function<InstructionCodeList(const std::vector<Token>&)>> ops_old{ // Integer Addition {"add", [](const std::vector<Token>& sl) -> InstructionCodeList { @@ -318,6 +319,68 @@ namespace { } // namespace + +class Op +{ +public: + virtual ~Op(){}; + virtual std::vector<uint8_t> getMachineCode() = 0; + virtual size_t size() = 0; ///< returns size in bytes + virtual bool optimize() = 0; ///< returns true if changed +}; + +using AsmArgs = std::vector<std::any>; // 0th element is mnemonic +using FactoryFunction = std::function<std::shared_ptr<Op>(AsmArgs&)>; + +std::unordered_map<std::string, FactoryFunction> ops; + +bool registerOp(const std::string& mnemonic, FactoryFunction f) +{ + if (ops.contains(mnemonic)) { + std::cout << "Warning: mnemonic |" << mnemonic << "| already registered." << std::endl; + return false; + } + + std::cout << "Registering mnemonic |" << mnemonic << "|." << std::endl; + + ops[mnemonic] = f; + + return true; +} + +class OpSimple: public Op +{ +public: + OpSimple(std::vector<uint8_t> machine_code): machine_code(machine_code) {} + + std::vector<uint8_t> getMachineCode() override + { + return machine_code; + } + + size_t size() override + { + return machine_code.size(); + } + + bool optimize() override ///< returns true if changed + { + return false; + } + +protected: + std::vector<uint8_t> machine_code; +}; + +class Op_nop: public OpSimple +{ +public: + Op_nop() : OpSimple({ 0x90 }) {} + +}; + +bool registered { registerOp("nop", [](AsmArgs& args) -> std::shared_ptr<Op>{ return std::make_shared<Op_nop>(); }) }; + class Assembler { std::unordered_map<std::string, size_t> labels; ///< labels with their positions in instruction list @@ -404,8 +467,8 @@ class Assembler { labels[t[0].value] = insn_list.size(); } else if (t.size() >= 1 && t[0].type == "instruction") { // instruction std::string instruction{ t[0].value }; - auto it = ops.find(instruction); - if (it == ops.end()) + auto it = ops_old.find(instruction); + if (it == ops_old.end()) throw std::runtime_error("Unknown instruction: "s + instruction); InstructionCodeList codes = it->second(t); |