diff options
| author | Roland Reichwein <mail@reichwein.it> | 2020-10-13 21:36:07 +0200 | 
|---|---|---|
| committer | Roland Reichwein <mail@reichwein.it> | 2020-10-13 21:36:07 +0200 | 
| commit | 29b57bfa7c2c7b3297e88c66ad9e45a5979844a8 (patch) | |
| tree | d29b59dfa8ce3638b951f99dd876eaab9f8bd286 | |
| parent | efbbad04bc093a133ca2aa5a462de0d37b04f929 (diff) | |
New Ops implementation for assembler
| -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); | 
