summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--asm/assembler.cpp17
-rw-r--r--asm/assembler.h31
-rw-r--r--asm/chunk.cpp1
-rw-r--r--asm/chunk.h79
-rw-r--r--asm/intel64/nop.cpp11
-rw-r--r--asm/intel64/nop.h11
-rw-r--r--asm/segment.cpp20
-rw-r--r--asm/segment.h15
-rw-r--r--intel.cpp136
10 files changed, 189 insertions, 136 deletions
diff --git a/Makefile b/Makefile
index e907b75..5971b19 100644
--- a/Makefile
+++ b/Makefile
@@ -45,6 +45,10 @@ LIBS+= \
endif
PROGSRC=\
+ asm/assembler.cpp \
+ asm/chunk.cpp \
+ asm/segment.cpp \
+ asm/intel64/nop.cpp \
bnf.cpp \
cpp.cpp \
cppbnf.cpp \
diff --git a/asm/assembler.cpp b/asm/assembler.cpp
new file mode 100644
index 0000000..275bd4a
--- /dev/null
+++ b/asm/assembler.cpp
@@ -0,0 +1,17 @@
+#include "assembler.h"
+
+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;
+}
diff --git a/asm/assembler.h b/asm/assembler.h
new file mode 100644
index 0000000..b9c39a6
--- /dev/null
+++ b/asm/assembler.h
@@ -0,0 +1,31 @@
+#pragma once
+
+#include "chunk.h"
+
+#include <any>
+#include <functional>
+#include <iostream>
+#include <memory>
+#include <string>
+#include <unordered_map>
+
+using AsmArgs = std::vector<std::any>; // 0th element is mnemonic
+using FactoryFunction = std::function<std::shared_ptr<Op>(AsmArgs&)>;
+
+bool registerOp(const std::string& mnemonic, FactoryFunction f);
+
+template<typename T>
+std::string mangleNameOne(const std::string& s)
+{
+ return s + "_" + typeid(T).name();
+}
+
+template<typename T, typename... Targs>
+std::string mangleName(const std::string& s)
+{
+ if constexpr (sizeof...(Targs) == 0)
+ return mangleNameOne<T>(s);
+ else
+ return mangleName<Targs...>(s + "_" + typeid(T).name());
+}
+
diff --git a/asm/chunk.cpp b/asm/chunk.cpp
new file mode 100644
index 0000000..3a07abc
--- /dev/null
+++ b/asm/chunk.cpp
@@ -0,0 +1 @@
+#include "chunk.h"
diff --git a/asm/chunk.h b/asm/chunk.h
new file mode 100644
index 0000000..723e711
--- /dev/null
+++ b/asm/chunk.h
@@ -0,0 +1,79 @@
+// Chunk data type, and derived types
+
+#pragma once
+
+#include <cstdint>
+#include <string>
+#include <vector>
+
+class Chunk
+{
+public:
+ virtual ~Chunk(){}
+ virtual std::vector<uint8_t> getCode() = 0;
+ virtual size_t size() = 0; ///< returns size in bytes
+};
+
+class Label: public Chunk
+{
+public:
+ Label(const std::string& name) : m_name(name) {}
+ std::string name(){return m_name;}
+ std::vector<uint8_t> getCode() override { return {}; }
+ size_t size() override { return 0; }
+
+private:
+ std::string m_name;
+};
+
+class Data: public Chunk
+{
+public:
+ Data(std::vector<uint8_t> data): m_data(data) {}
+ virtual ~Data(){}
+
+ std::vector<uint8_t> getCode() override
+ {
+ return m_data;
+ }
+
+ size_t size() override
+ {
+ return m_data.size();
+ }
+
+protected:
+ std::vector<uint8_t> m_data;
+};
+
+class Op: public Chunk
+{
+public:
+ virtual ~Op(){};
+ virtual bool optimize() = 0; ///< returns true if changed
+};
+
+class OpSimple: public Op
+{
+public:
+ OpSimple(std::vector<uint8_t> machine_code): machine_code(machine_code) {}
+
+ std::vector<uint8_t> getCode() 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;
+};
+
diff --git a/asm/intel64/nop.cpp b/asm/intel64/nop.cpp
new file mode 100644
index 0000000..450de46
--- /dev/null
+++ b/asm/intel64/nop.cpp
@@ -0,0 +1,11 @@
+#include "nop.h"
+
+#include <asm/assembler.h>
+
+namespace {
+
+bool registered { registerOp("nop", [](AsmArgs& args) -> std::shared_ptr<Op>{
+ return std::make_shared<Op_nop>();
+ }) };
+
+}
diff --git a/asm/intel64/nop.h b/asm/intel64/nop.h
new file mode 100644
index 0000000..72d6d1b
--- /dev/null
+++ b/asm/intel64/nop.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include <asm/chunk.h>
+
+class Op_nop: public OpSimple
+{
+public:
+ Op_nop() : OpSimple({ 0x90 }) {}
+
+};
+
diff --git a/asm/segment.cpp b/asm/segment.cpp
new file mode 100644
index 0000000..db83941
--- /dev/null
+++ b/asm/segment.cpp
@@ -0,0 +1,20 @@
+#include "segment.h"
+
+using namespace std::string_literals;
+
+size_t Segment::getAddressOfLabel(const std::string& label)
+ {
+ size_t address{0};
+ auto i{begin()};
+ while (i != end()) {
+ Chunk& chunk{**i};
+ address += chunk.size();
+ if (typeid(chunk) == typeid(Label)) {
+ if (dynamic_cast<Label&>(chunk).name() == label) {
+ return address;
+ }
+ }
+ }
+
+ throw std::runtime_error("Bad label: "s + label);
+ }
diff --git a/asm/segment.h b/asm/segment.h
new file mode 100644
index 0000000..1c080d3
--- /dev/null
+++ b/asm/segment.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "chunk.h"
+
+#include <exception>
+#include <memory>
+#include <string>
+#include <vector>
+
+class Segment: public std::vector<std::shared_ptr<Chunk>>
+{
+ size_t getAddressOfLabel(const std::string& label);
+};
+
+
diff --git a/intel.cpp b/intel.cpp
index 7ef6be3..9dac6c0 100644
--- a/intel.cpp
+++ b/intel.cpp
@@ -314,142 +314,6 @@ namespace {
} // namespace
-class Chunk
-{
-public:
- virtual ~Chunk(){}
- virtual std::vector<uint8_t> getCode() = 0;
- virtual size_t size() = 0; ///< returns size in bytes
-};
-
-class Label: public Chunk
-{
-public:
- Label(const std::string& name) : m_name(name) {}
- std::string name(){return m_name;}
- std::vector<uint8_t> getCode() override { return {}; }
- size_t size() override { return 0; }
-
-private:
- std::string m_name;
-};
-
-class Data: public Chunk
-{
-public:
- Data(std::vector<uint8_t> data): m_data(data) {}
- virtual ~Data(){}
-
- std::vector<uint8_t> getCode() override
- {
- return m_data;
- }
-
- size_t size() override
- {
- return m_data.size();
- }
-
-protected:
- std::vector<uint8_t> m_data;
-};
-
-class Segment: public std::vector<std::shared_ptr<Chunk>>
-{
- size_t getAddressOfLabel(const std::string& label)
- {
- size_t address{0};
- auto i{begin()};
- while (i != end()) {
- Chunk& chunk{**i};
- address += chunk.size();
- if (typeid(chunk) == typeid(Label)) {
- if (dynamic_cast<Label&>(chunk).name() == label) {
- return address;
- }
- }
- }
-
- throw std::runtime_error("Bad label: "s + label);
- }
-};
-
-class Op: public Chunk
-{
-public:
- virtual ~Op(){};
- 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> getCode() 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 }) {}
-
-};
-
-template<typename T>
-std::string mangleNameOne(const std::string& s)
-{
- return s + "_" + typeid(T).name();
-}
-
-template<typename T, typename... Targs>
-std::string mangleName(const std::string& s)
-{
- if constexpr (sizeof...(Targs) == 0)
- return mangleNameOne<T>(s);
- else
- return mangleName<Targs...>(s + "_" + typeid(T).name());
-}
-
-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