summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRoland Reichwein <mail@reichwein.it>2020-10-13 21:36:07 +0200
committerRoland Reichwein <mail@reichwein.it>2020-10-13 21:36:07 +0200
commit29b57bfa7c2c7b3297e88c66ad9e45a5979844a8 (patch)
treed29b59dfa8ce3638b951f99dd876eaab9f8bd286
parentefbbad04bc093a133ca2aa5a462de0d37b04f929 (diff)
New Ops implementation for assembler
-rw-r--r--intel.cpp69
1 files 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 <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);