From 29b57bfa7c2c7b3297e88c66ad9e45a5979844a8 Mon Sep 17 00:00:00 2001 From: Roland Reichwein Date: Tue, 13 Oct 2020 21:36:07 +0200 Subject: New Ops implementation for assembler --- intel.cpp | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 3 deletions(-) diff --git a/intel.cpp b/intel.cpp index dfcaa75..471dcbf 100644 --- a/intel.cpp +++ b/intel.cpp @@ -6,6 +6,7 @@ #include "minicc.h" #include +#include #include #include #include @@ -146,7 +147,7 @@ namespace { throw std::runtime_error("Unknown command: "s + sl[0].value); } - std::unordered_map&)>> ops{ + std::unordered_map&)>> ops_old{ // Integer Addition {"add", [](const std::vector& sl) -> InstructionCodeList { @@ -318,6 +319,68 @@ namespace { } // namespace + +class Op +{ +public: + virtual ~Op(){}; + virtual std::vector getMachineCode() = 0; + virtual size_t size() = 0; ///< returns size in bytes + virtual bool optimize() = 0; ///< returns true if changed +}; + +using AsmArgs = std::vector; // 0th element is mnemonic +using FactoryFunction = std::function(AsmArgs&)>; + +std::unordered_map 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 machine_code): machine_code(machine_code) {} + + std::vector 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 machine_code; +}; + +class Op_nop: public OpSimple +{ +public: + Op_nop() : OpSimple({ 0x90 }) {} + +}; + +bool registered { registerOp("nop", [](AsmArgs& args) -> std::shared_ptr{ return std::make_shared(); }) }; + class Assembler { std::unordered_map 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); -- cgit v1.2.3