summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Makefile10
-rw-r--r--asm/assembler.cpp4
-rw-r--r--asm/assembler.h6
-rw-r--r--asm/intel64/add.cpp6
-rw-r--r--asm/intel64/add.h2
-rw-r--r--asm/intel64/dec.cpp8
-rw-r--r--asm/intel64/dec.h2
-rw-r--r--asm/intel64/div.cpp8
-rw-r--r--asm/intel64/div.h2
-rw-r--r--asm/intel64/encode.cpp10
-rw-r--r--asm/intel64/idiv.cpp6
-rw-r--r--asm/intel64/idiv.h2
-rw-r--r--asm/intel64/imul.cpp8
-rw-r--r--asm/intel64/imul.h2
-rw-r--r--asm/intel64/inc.cpp8
-rw-r--r--asm/intel64/inc.h2
-rw-r--r--asm/intel64/int.cpp4
-rw-r--r--asm/intel64/int.h2
-rw-r--r--asm/intel64/jmp.cpp4
-rw-r--r--asm/intel64/jmp.h2
-rw-r--r--asm/intel64/mov.cpp21
-rw-r--r--asm/intel64/mov.h2
-rw-r--r--asm/intel64/mul.cpp8
-rw-r--r--asm/intel64/mul.h2
-rw-r--r--asm/intel64/pop.cpp4
-rw-r--r--asm/intel64/pop.h2
-rw-r--r--asm/intel64/push.cpp4
-rw-r--r--asm/intel64/push.h2
-rw-r--r--asm/intel64/sub.cpp6
-rw-r--r--asm/intel64/sub.h2
-rw-r--r--asm/intel64/trivials.cpp6
-rw-r--r--asm/intel64/xor.cpp4
-rw-r--r--asm/intel64/xor.h2
-rw-r--r--cpp.cpp24
-rw-r--r--cpp.h2
-rw-r--r--flowgraph/node.h2
-rw-r--r--minicc.cpp5
-rw-r--r--minicc.h4
-rw-r--r--tests/test-flowgraph.cpp2
39 files changed, 128 insertions, 74 deletions
diff --git a/Makefile b/Makefile
index e7d50dd..7120470 100644
--- a/Makefile
+++ b/Makefile
@@ -97,9 +97,13 @@ TESTSRC=\
SRC=$(PROGSRC) mcc.cpp
-all: test-$(PROJECTNAME) mcc
- ./test-$(PROJECTNAME) # --gtest_filter='CppTest.compile_1'
+all: mcc unittest systemtest
+# Tests on C++ level
+unittest: test-$(PROJECTNAME)
+ ./test-$(PROJECTNAME) --gtest_filter='CppTest.compile_2_times'
+
+# Testing mcc executable and compiled elf programs
systemtest:
./mcc systemtest/mcc-execute.tests/test-return-1.cpp
./mcc systemtest/mcc-execute.tests/test-addition.cpp
@@ -142,6 +146,6 @@ zip: clean
zip -r ../$(PROJECTNAME).zip *
ls -l ../$(PROJECTNAME).zip
-.PHONY: clean all zip dep systemtest
+.PHONY: clean all zip dep systemtest unittest
-include $(wildcard $(SRC:.cpp=.d))
diff --git a/asm/assembler.cpp b/asm/assembler.cpp
index 5d8a986..b555125 100644
--- a/asm/assembler.cpp
+++ b/asm/assembler.cpp
@@ -22,7 +22,7 @@ bool registerOp(const std::string& mnemonic, FactoryFunction f)
return true;
}
-std::string mangleName(const std::string& s, Asm::Args& args)
+std::string mangleName(const std::string& s, const Asm::Args& args)
{
std::string result {s};
@@ -33,7 +33,7 @@ std::string mangleName(const std::string& s, Asm::Args& args)
return result;
}
-std::shared_ptr<Op> makeOp(const std::string& mnemonic, Asm::Args& args)
+std::shared_ptr<Op> makeOp(const std::string& mnemonic, const Asm::Args& args)
{
std::string mangled{mangleName(mnemonic, args)};
diff --git a/asm/assembler.h b/asm/assembler.h
index b459b85..aa886b5 100644
--- a/asm/assembler.h
+++ b/asm/assembler.h
@@ -107,14 +107,14 @@ public:
} // namespace Asm
-using FactoryFunction = std::function<std::shared_ptr<Op>(Asm::Args&)>;
+using FactoryFunction = std::function<std::shared_ptr<Op>(const Asm::Args&)>;
// mnemonic: mnemonic including argument types
bool registerOp(const std::string& mnemonic, FactoryFunction f);
// Create Op from a registered mnemonic
// mnemonic: just the mnemonic name
-std::shared_ptr<Op> makeOp(const std::string& mnemonic, Asm::Args& args);
+std::shared_ptr<Op> makeOp(const std::string& mnemonic, const Asm::Args& args);
// overload for empty list of arguments
std::shared_ptr<Op> makeOp(const std::string& mnemonic);
@@ -137,5 +137,5 @@ std::string mangleName(const std::string& s)
return mangleName<Targs...>(s + "_" + typeid(T).name());
}
-std::string mangleName(const std::string& s, Asm::Args& args);
+std::string mangleName(const std::string& s, const Asm::Args& args);
diff --git a/asm/intel64/add.cpp b/asm/intel64/add.cpp
index 4438895..236436c 100644
--- a/asm/intel64/add.cpp
+++ b/asm/intel64/add.cpp
@@ -7,7 +7,7 @@
using namespace std::string_literals;
-Op_add::Op_add(Asm::Args& args)
+Op_add::Op_add(const Asm::Args& args)
{
if (args[0].type() == typeid(Asm::Args::Register32) &&
std::any_cast<Asm::Args::Register32>(args[0]).name() == "eax" &&
@@ -31,10 +31,10 @@ Op_add::Op_add(Asm::Args& args)
namespace {
bool registered {
- registerOp(mangleName<Asm::Args::Register32, Asm::Args::Immediate32>("add"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+ registerOp(mangleName<Asm::Args::Register32, Asm::Args::Immediate32>("add"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_add>(args);
}) &&
- registerOp(mangleName<Asm::Args::Register64, Asm::Args::Immediate32>("add"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+ registerOp(mangleName<Asm::Args::Register64, Asm::Args::Immediate32>("add"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_add>(args);
})
};
diff --git a/asm/intel64/add.h b/asm/intel64/add.h
index 1d55317..0c1b8ce 100644
--- a/asm/intel64/add.h
+++ b/asm/intel64/add.h
@@ -7,7 +7,7 @@
class Op_add: public Op
{
public:
- Op_add(Asm::Args& args);
+ Op_add(const Asm::Args& args);
public:
std::vector<uint8_t> getCode() override
diff --git a/asm/intel64/dec.cpp b/asm/intel64/dec.cpp
index dab603a..5ae61c4 100644
--- a/asm/intel64/dec.cpp
+++ b/asm/intel64/dec.cpp
@@ -9,7 +9,7 @@
using namespace std::string_literals;
-Op_dec::Op_dec(Asm::Args& args)
+Op_dec::Op_dec(const Asm::Args& args)
{
if (args[0].type() == typeid(Asm::Args::Register8)) { // dec reg8
machine_code = std::vector<uint8_t>{ 0xFE } +
@@ -28,13 +28,13 @@ Op_dec::Op_dec(Asm::Args& args)
namespace {
bool registered {
- registerOp(mangleName<Asm::Args::Register8>("dec"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+ registerOp(mangleName<Asm::Args::Register8>("dec"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_dec>(args);
}) &&
- registerOp(mangleName<Asm::Args::Register32>("dec"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+ registerOp(mangleName<Asm::Args::Register32>("dec"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_dec>(args);
}) &&
- registerOp(mangleName<Asm::Args::Register64>("dec"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+ registerOp(mangleName<Asm::Args::Register64>("dec"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_dec>(args);
})
};
diff --git a/asm/intel64/dec.h b/asm/intel64/dec.h
index 293ba8d..1b0eaf7 100644
--- a/asm/intel64/dec.h
+++ b/asm/intel64/dec.h
@@ -7,7 +7,7 @@
class Op_dec: public Op
{
public:
- Op_dec(Asm::Args& args);
+ Op_dec(const Asm::Args& args);
public:
std::vector<uint8_t> getCode() override
diff --git a/asm/intel64/div.cpp b/asm/intel64/div.cpp
index 5ed9988..9ca24e9 100644
--- a/asm/intel64/div.cpp
+++ b/asm/intel64/div.cpp
@@ -9,7 +9,7 @@
using namespace std::string_literals;
-Op_div::Op_div(Asm::Args& args)
+Op_div::Op_div(const Asm::Args& args)
{
if (args[0].type() == typeid(Asm::Args::Register8)) { // div reg8 (accu is al (remainder=ah) <- ah / reg8)
machine_code = std::vector<uint8_t>{ 0xF6 } +
@@ -28,13 +28,13 @@ Op_div::Op_div(Asm::Args& args)
namespace {
bool registered {
- registerOp(mangleName<Asm::Args::Register8>("div"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+ registerOp(mangleName<Asm::Args::Register8>("div"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_div>(args);
}) &&
- registerOp(mangleName<Asm::Args::Register32>("div"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+ registerOp(mangleName<Asm::Args::Register32>("div"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_div>(args);
}) &&
- registerOp(mangleName<Asm::Args::Register64>("div"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+ registerOp(mangleName<Asm::Args::Register64>("div"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_div>(args);
})
};
diff --git a/asm/intel64/div.h b/asm/intel64/div.h
index 9605f3e..89614fc 100644
--- a/asm/intel64/div.h
+++ b/asm/intel64/div.h
@@ -7,7 +7,7 @@
class Op_div: public Op
{
public:
- Op_div(Asm::Args& args);
+ Op_div(const Asm::Args& args);
public:
std::vector<uint8_t> getCode() override
diff --git a/asm/intel64/encode.cpp b/asm/intel64/encode.cpp
index b26bf9c..123dff2 100644
--- a/asm/intel64/encode.cpp
+++ b/asm/intel64/encode.cpp
@@ -96,8 +96,16 @@ void Asm::toMachineCode(const FlowGraph::Graph& graph, Segment& segment)
else
throw std::runtime_error("ICE: Asm: Unsupported binary operation type: "s + std::to_string(static_cast<int>(op.type())));
+ } else if (typeid(node_deref) == typeid(FlowGraph::CreateScopeOp)) {
+ //FlowGraph::CreateScopeOp& op {dynamic_cast<FlowGraph::CreateScopeOp&>(*node)};
+ segment.push_back(makeOp("push", Asm::Args{{Asm::Args::Register64("rbp")}}));
+ segment.push_back(makeOp("mov", Asm::Args{{Asm::Args::Register64("rbp"), Asm::Args::Register64("rsp")}}));
+
+ } else if (typeid(node_deref) == typeid(FlowGraph::DestroyScopeOp)) {
+ //FlowGraph::DestroyScopeOp& op {dynamic_cast<FlowGraph::DestroyScopeOp&>(*node)};
+ segment.push_back(makeOp("pop", Asm::Args{{Asm::Args::Register64("rbp")}}));
} else {
- throw std::runtime_error("ICE: Encoding: Unsupported node");
+ throw std::runtime_error("ICE: Encoding: Unsupported node: "s + demangle(typeid(node_deref)));
}
} else {
throw std::runtime_error("ICE: encode: flowgraph node is null");
diff --git a/asm/intel64/idiv.cpp b/asm/intel64/idiv.cpp
index 3ee17a3..debeeb4 100644
--- a/asm/intel64/idiv.cpp
+++ b/asm/intel64/idiv.cpp
@@ -9,7 +9,7 @@
using namespace std::string_literals;
-Op_idiv::Op_idiv(Asm::Args& args)
+Op_idiv::Op_idiv(const Asm::Args& args)
{
if (args[0].type() == typeid(Asm::Args::Register8)) { // idiv reg8 (accu is al (remainder=ah) <- ah / reg8)
machine_code = std::vector<uint8_t>{ 0xF6 } +
@@ -28,10 +28,10 @@ Op_idiv::Op_idiv(Asm::Args& args)
namespace {
bool registered {
- registerOp(mangleName<Asm::Args::Register8>("idiv"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+ registerOp(mangleName<Asm::Args::Register8>("idiv"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_idiv>(args);
}) &&
- registerOp(mangleName<Asm::Args::Register64>("idiv"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+ registerOp(mangleName<Asm::Args::Register64>("idiv"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_idiv>(args);
})
};
diff --git a/asm/intel64/idiv.h b/asm/intel64/idiv.h
index a6ef411..8b93043 100644
--- a/asm/intel64/idiv.h
+++ b/asm/intel64/idiv.h
@@ -7,7 +7,7 @@
class Op_idiv: public Op
{
public:
- Op_idiv(Asm::Args& args);
+ Op_idiv(const Asm::Args& args);
public:
std::vector<uint8_t> getCode() override
diff --git a/asm/intel64/imul.cpp b/asm/intel64/imul.cpp
index 4df8577..0ffca30 100644
--- a/asm/intel64/imul.cpp
+++ b/asm/intel64/imul.cpp
@@ -9,7 +9,7 @@
using namespace std::string_literals;
-Op_imul::Op_imul(Asm::Args& args)
+Op_imul::Op_imul(const Asm::Args& args)
{
if (args[0].type() == typeid(Asm::Args::Register8)) { // imul reg8 (accu is ax <- al)
machine_code = std::vector<uint8_t>{ 0xF6 } +
@@ -28,13 +28,13 @@ Op_imul::Op_imul(Asm::Args& args)
namespace {
bool registered {
- registerOp(mangleName<Asm::Args::Register8>("imul"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+ registerOp(mangleName<Asm::Args::Register8>("imul"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_imul>(args);
}) &&
- registerOp(mangleName<Asm::Args::Register32>("imul"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+ registerOp(mangleName<Asm::Args::Register32>("imul"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_imul>(args);
}) &&
- registerOp(mangleName<Asm::Args::Register64>("imul"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+ registerOp(mangleName<Asm::Args::Register64>("imul"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_imul>(args);
})
};
diff --git a/asm/intel64/imul.h b/asm/intel64/imul.h
index 387d87f..becf21d 100644
--- a/asm/intel64/imul.h
+++ b/asm/intel64/imul.h
@@ -7,7 +7,7 @@
class Op_imul: public Op
{
public:
- Op_imul(Asm::Args& args);
+ Op_imul(const Asm::Args& args);
public:
std::vector<uint8_t> getCode() override
diff --git a/asm/intel64/inc.cpp b/asm/intel64/inc.cpp
index 3df9104..cc7f1ff 100644
--- a/asm/intel64/inc.cpp
+++ b/asm/intel64/inc.cpp
@@ -9,7 +9,7 @@
using namespace std::string_literals;
-Op_inc::Op_inc(Asm::Args& args)
+Op_inc::Op_inc(const Asm::Args& args)
{
if (args[0].type() == typeid(Asm::Args::Register8)) { // inc reg8
machine_code = std::vector<uint8_t>{ 0xFE } +
@@ -28,13 +28,13 @@ Op_inc::Op_inc(Asm::Args& args)
namespace {
bool registered {
- registerOp(mangleName<Asm::Args::Register8>("inc"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+ registerOp(mangleName<Asm::Args::Register8>("inc"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_inc>(args);
}) &&
- registerOp(mangleName<Asm::Args::Register32>("inc"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+ registerOp(mangleName<Asm::Args::Register32>("inc"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_inc>(args);
}) &&
- registerOp(mangleName<Asm::Args::Register64>("inc"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+ registerOp(mangleName<Asm::Args::Register64>("inc"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_inc>(args);
})
};
diff --git a/asm/intel64/inc.h b/asm/intel64/inc.h
index 0887392..6c96ae2 100644
--- a/asm/intel64/inc.h
+++ b/asm/intel64/inc.h
@@ -7,7 +7,7 @@
class Op_inc: public Op
{
public:
- Op_inc(Asm::Args& args);
+ Op_inc(const Asm::Args& args);
public:
std::vector<uint8_t> getCode() override
diff --git a/asm/intel64/int.cpp b/asm/intel64/int.cpp
index de6c73b..dbc6ae7 100644
--- a/asm/intel64/int.cpp
+++ b/asm/intel64/int.cpp
@@ -2,7 +2,7 @@
#include <asm/assembler.h>
-Op_int::Op_int(Asm::Args& args)
+Op_int::Op_int(const Asm::Args& args)
{
// At this point, the registration already ensured the number and types of args
@@ -21,7 +21,7 @@ Op_int::Op_int(Asm::Args& args)
namespace {
-bool registered { registerOp(mangleName<Asm::Args::Immediate8>("int"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+bool registered { registerOp(mangleName<Asm::Args::Immediate8>("int"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_int>(args);
}) };
diff --git a/asm/intel64/int.h b/asm/intel64/int.h
index aee4962..b27f4a3 100644
--- a/asm/intel64/int.h
+++ b/asm/intel64/int.h
@@ -7,7 +7,7 @@
class Op_int: public Op
{
public:
- Op_int(Asm::Args& args);
+ Op_int(const Asm::Args& args);
public:
std::vector<uint8_t> getCode() override
diff --git a/asm/intel64/jmp.cpp b/asm/intel64/jmp.cpp
index 8542127..2fc4a13 100644
--- a/asm/intel64/jmp.cpp
+++ b/asm/intel64/jmp.cpp
@@ -61,7 +61,7 @@ namespace {
bool registerOps() {
bool result{true};
for (const auto& jumpOp: jumpOps) {
- result &= registerOp(mangleName<Asm::Args::Label>(jumpOp.name), [&](Asm::Args& args) -> std::shared_ptr<Op>{
+ result &= registerOp(mangleName<Asm::Args::Label>(jumpOp.name), [&](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_jmp>(jumpOp.name, args, jumpOp.jmp8, jumpOp.jmp32);
});
}
@@ -73,7 +73,7 @@ namespace {
};
}
-Op_jmp::Op_jmp(const std::string& name, Asm::Args& args, const OP_T& jmp8, const OP_T& jmp32)
+Op_jmp::Op_jmp(const std::string& name, const Asm::Args& args, const OP_T& jmp8, const OP_T& jmp32)
{
label = std::any_cast<Asm::Args::Label>(args[0]).name();
diff --git a/asm/intel64/jmp.h b/asm/intel64/jmp.h
index a7c7511..c96f4e2 100644
--- a/asm/intel64/jmp.h
+++ b/asm/intel64/jmp.h
@@ -10,7 +10,7 @@
class Op_jmp: public Op, public AddressFeature
{
public:
- Op_jmp(const std::string& name, Asm::Args& args, const OP_T& jmp8, const OP_T& jmp32);
+ Op_jmp(const std::string& name, const Asm::Args& args, const OP_T& jmp8, const OP_T& jmp32);
std::vector<uint8_t> getCode() override
{
diff --git a/asm/intel64/mov.cpp b/asm/intel64/mov.cpp
index 5741170..5b224c1 100644
--- a/asm/intel64/mov.cpp
+++ b/asm/intel64/mov.cpp
@@ -9,16 +9,29 @@
using namespace std::string_literals;
-Op_mov::Op_mov(Asm::Args& args)
+Op_mov::Op_mov(const Asm::Args& args)
{
if (args[0].type() == typeid(Asm::Args::Register8) && args[1].type() == typeid(Asm::Args::Register8)) { // mov reg8, reg8
// r/m8, r8: ModRM:r/m (w), ModRM:reg (r)
machine_code = std::vector<uint8_t>{ 0x88 } +
ModRM(std::any_cast<Asm::Args::Register8>(args[1]).name(), std::any_cast<Asm::Args::Register8>(args[0]).name());
+
+ } else if (args[0].type() == typeid(Asm::Args::Register32) && args[1].type() == typeid(Asm::Args::Register32)) { // mov reg32, reg32
+ // r/m32, r32: ModRM:r/m (w), ModRM:reg (r)
+ machine_code = std::vector<uint8_t>{ 0x89 } +
+ ModRM(std::any_cast<Asm::Args::Register32>(args[1]).name(), std::any_cast<Asm::Args::Register32>(args[0]).name());
+
+ } else if (args[0].type() == typeid(Asm::Args::Register64) && args[1].type() == typeid(Asm::Args::Register64)) { // mov reg64, reg64
+ // r/m64, r64: ModRM:r/m (w), ModRM:reg (r)
+ machine_code = REX("W") + std::vector<uint8_t>{ 0x89 } +
+ ModRM(std::any_cast<Asm::Args::Register64>(args[1]).name(), std::any_cast<Asm::Args::Register64>(args[0]).name());
+
} else if (args[0].type() == typeid(Asm::Args::Register32) && args[1].type() == typeid(Asm::Args::Immediate32)) { // mov reg32, imm32
machine_code = std::vector<uint8_t>{ static_cast<uint8_t>(0xB8 + RegNo(std::any_cast<Asm::Args::Register32>(args[0]).name())) } + std::any_cast<Asm::Args::Immediate32>(args[1]).getCode();
+
} else if (args[0].type() == typeid(Asm::Args::Register64) && args[1].type() == typeid(Asm::Args::Immediate64)) { // mov reg64, imm64
machine_code = std::vector<uint8_t>{ REX("W") + static_cast<uint8_t>(0xB8 + RegNo(std::any_cast<Asm::Args::Register64>(args[0]).name())) } + std::any_cast<Asm::Args::Immediate64>(args[1]).getCode();
+
} else {
throw std::runtime_error("Unimplemented: mov "s + args[0].type().name() + " "s + args[1].type().name());
}
@@ -27,13 +40,13 @@ Op_mov::Op_mov(Asm::Args& args)
namespace {
bool registered {
- registerOp(mangleName<Asm::Args::Register8, Asm::Args::Register8>("mov"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+ registerOp(mangleName<Asm::Args::Register8, Asm::Args::Register8>("mov"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_mov>(args);
}) &&
- registerOp(mangleName<Asm::Args::Register32, Asm::Args::Immediate32>("mov"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+ registerOp(mangleName<Asm::Args::Register32, Asm::Args::Immediate32>("mov"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_mov>(args);
}) &&
- registerOp(mangleName<Asm::Args::Register64, Asm::Args::Immediate64>("mov"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+ registerOp(mangleName<Asm::Args::Register64, Asm::Args::Immediate64>("mov"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_mov>(args);
})
};
diff --git a/asm/intel64/mov.h b/asm/intel64/mov.h
index 53afed4..06c346e 100644
--- a/asm/intel64/mov.h
+++ b/asm/intel64/mov.h
@@ -7,7 +7,7 @@
class Op_mov: public Op
{
public:
- Op_mov(Asm::Args& args);
+ Op_mov(const Asm::Args& args);
public:
std::vector<uint8_t> getCode() override
diff --git a/asm/intel64/mul.cpp b/asm/intel64/mul.cpp
index e4c3489..502b1d9 100644
--- a/asm/intel64/mul.cpp
+++ b/asm/intel64/mul.cpp
@@ -9,7 +9,7 @@
using namespace std::string_literals;
-Op_mul::Op_mul(Asm::Args& args)
+Op_mul::Op_mul(const Asm::Args& args)
{
if (args[0].type() == typeid(Asm::Args::Register8)) { // mul reg8 (accu is ax <- al)
machine_code = std::vector<uint8_t>{ 0xF6 } +
@@ -28,13 +28,13 @@ Op_mul::Op_mul(Asm::Args& args)
namespace {
bool registered {
- registerOp(mangleName<Asm::Args::Register8>("mul"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+ registerOp(mangleName<Asm::Args::Register8>("mul"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_mul>(args);
}) &&
- registerOp(mangleName<Asm::Args::Register32>("mul"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+ registerOp(mangleName<Asm::Args::Register32>("mul"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_mul>(args);
}) &&
- registerOp(mangleName<Asm::Args::Register64>("mul"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+ registerOp(mangleName<Asm::Args::Register64>("mul"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_mul>(args);
})
};
diff --git a/asm/intel64/mul.h b/asm/intel64/mul.h
index 9ff31d1..0c4ab50 100644
--- a/asm/intel64/mul.h
+++ b/asm/intel64/mul.h
@@ -7,7 +7,7 @@
class Op_mul: public Op
{
public:
- Op_mul(Asm::Args& args);
+ Op_mul(const Asm::Args& args);
public:
std::vector<uint8_t> getCode() override
diff --git a/asm/intel64/pop.cpp b/asm/intel64/pop.cpp
index 8528b15..6d8b734 100644
--- a/asm/intel64/pop.cpp
+++ b/asm/intel64/pop.cpp
@@ -9,7 +9,7 @@
using namespace std::string_literals;
-Op_pop::Op_pop(Asm::Args& args)
+Op_pop::Op_pop(const Asm::Args& args)
{
if (args[0].type() == typeid(Asm::Args::Register64)) { // pop reg64
machine_code = std::vector<uint8_t>{ 0x58 } + RegNo(std::any_cast<Asm::Args::Register64>(args[0]).name());
@@ -21,7 +21,7 @@ Op_pop::Op_pop(Asm::Args& args)
namespace {
bool registered {
- registerOp(mangleName<Asm::Args::Register64>("pop"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+ registerOp(mangleName<Asm::Args::Register64>("pop"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_pop>(args);
})
};
diff --git a/asm/intel64/pop.h b/asm/intel64/pop.h
index 3bcd421..c020568 100644
--- a/asm/intel64/pop.h
+++ b/asm/intel64/pop.h
@@ -7,7 +7,7 @@
class Op_pop: public Op
{
public:
- Op_pop(Asm::Args& args);
+ Op_pop(const Asm::Args& args);
public:
std::vector<uint8_t> getCode() override
diff --git a/asm/intel64/push.cpp b/asm/intel64/push.cpp
index bad2c90..37acec9 100644
--- a/asm/intel64/push.cpp
+++ b/asm/intel64/push.cpp
@@ -9,7 +9,7 @@
using namespace std::string_literals;
-Op_push::Op_push(Asm::Args& args)
+Op_push::Op_push(const Asm::Args& args)
{
if (args[0].type() == typeid(Asm::Args::Register64)) { // push reg64
machine_code = std::vector<uint8_t>{ 0x50 } + RegNo(std::any_cast<Asm::Args::Register64>(args[0]).name());
@@ -21,7 +21,7 @@ Op_push::Op_push(Asm::Args& args)
namespace {
bool registered {
- registerOp(mangleName<Asm::Args::Register64>("push"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+ registerOp(mangleName<Asm::Args::Register64>("push"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_push>(args);
})
};
diff --git a/asm/intel64/push.h b/asm/intel64/push.h
index 9525981..e322622 100644
--- a/asm/intel64/push.h
+++ b/asm/intel64/push.h
@@ -7,7 +7,7 @@
class Op_push: public Op
{
public:
- Op_push(Asm::Args& args);
+ Op_push(const Asm::Args& args);
public:
std::vector<uint8_t> getCode() override
diff --git a/asm/intel64/sub.cpp b/asm/intel64/sub.cpp
index e055ee9..2447c15 100644
--- a/asm/intel64/sub.cpp
+++ b/asm/intel64/sub.cpp
@@ -7,7 +7,7 @@
using namespace std::string_literals;
-Op_sub::Op_sub(Asm::Args& args)
+Op_sub::Op_sub(const Asm::Args& args)
{
if (args[0].type() == typeid(Asm::Args::Register32) &&
std::any_cast<Asm::Args::Register32>(args[0]).name() == "eax" &&
@@ -31,10 +31,10 @@ Op_sub::Op_sub(Asm::Args& args)
namespace {
bool registered {
- registerOp(mangleName<Asm::Args::Register32, Asm::Args::Immediate32>("sub"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+ registerOp(mangleName<Asm::Args::Register32, Asm::Args::Immediate32>("sub"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_sub>(args);
}) &&
- registerOp(mangleName<Asm::Args::Register64, Asm::Args::Immediate32>("sub"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+ registerOp(mangleName<Asm::Args::Register64, Asm::Args::Immediate32>("sub"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_sub>(args);
})
};
diff --git a/asm/intel64/sub.h b/asm/intel64/sub.h
index cc0dd81..88dcbf4 100644
--- a/asm/intel64/sub.h
+++ b/asm/intel64/sub.h
@@ -7,7 +7,7 @@
class Op_sub: public Op
{
public:
- Op_sub(Asm::Args& args);
+ Op_sub(const Asm::Args& args);
public:
std::vector<uint8_t> getCode() override
diff --git a/asm/intel64/trivials.cpp b/asm/intel64/trivials.cpp
index 094d27f..eb1bbb8 100644
--- a/asm/intel64/trivials.cpp
+++ b/asm/intel64/trivials.cpp
@@ -9,13 +9,13 @@ Op_syscall::Op_syscall(): OpSimple({ 0x0F, 0x05 }) {}
namespace {
bool registered {
- registerOp("nop", [](Asm::Args& args) -> std::shared_ptr<Op>{
+ registerOp("nop", [](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_nop>();
}) &&
- registerOp("ret", [](Asm::Args& args) -> std::shared_ptr<Op>{
+ registerOp("ret", [](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_ret>();
}) &&
- registerOp("syscall", [](Asm::Args& args) -> std::shared_ptr<Op>{
+ registerOp("syscall", [](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_syscall>();
})
};
diff --git a/asm/intel64/xor.cpp b/asm/intel64/xor.cpp
index 2aa4272..aba6fb5 100644
--- a/asm/intel64/xor.cpp
+++ b/asm/intel64/xor.cpp
@@ -9,7 +9,7 @@
using namespace std::string_literals;
-Op_xor::Op_xor(Asm::Args& args)
+Op_xor::Op_xor(const Asm::Args& args)
{
if (args[0].type() == typeid(Asm::Args::Register8) && args[1].type() == typeid(Asm::Args::Register8)) { // xor reg8, reg8
// r8, r/m8: ModRM:reg (w), ModRM:r/m (r)
@@ -23,7 +23,7 @@ Op_xor::Op_xor(Asm::Args& args)
namespace {
bool registered {
- registerOp(mangleName<Asm::Args::Register8, Asm::Args::Register8>("xor"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+ registerOp(mangleName<Asm::Args::Register8, Asm::Args::Register8>("xor"), [](const Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_xor>(args);
})
};
diff --git a/asm/intel64/xor.h b/asm/intel64/xor.h
index 7e07006..8cae899 100644
--- a/asm/intel64/xor.h
+++ b/asm/intel64/xor.h
@@ -7,7 +7,7 @@
class Op_xor: public Op
{
public:
- Op_xor(Asm::Args& args);
+ Op_xor(const Asm::Args& args);
public:
std::vector<uint8_t> getCode() override
diff --git a/cpp.cpp b/cpp.cpp
index 887dbbd..4bb8a01 100644
--- a/cpp.cpp
+++ b/cpp.cpp
@@ -13,6 +13,8 @@
#include <gtest/gtest.h>
#include <gmock/gmock.h>
+#include <boost/core/demangle.hpp>
+
#include <functional>
#include <optional>
#include <unordered_set>
@@ -398,6 +400,11 @@ std::unordered_map<std::string, std::function<std::any(index_t)>> CPP::getNodeEv
{ "multiplicative-expression", [&](index_t index) -> std::any
{
if (childTypesOfNodeMatch(index, {"multiplicative-expression", "*", "pm-expression"})) {
+ if (getValue(index, 0).type() != typeid(FlowGraph::Data))
+ throw std::runtime_error("ICE: multiplicative-expression: Bad data type for argument 1: "s + demangle(getValue(index, 0).type()));
+ if (getValue(index, 2).type() != typeid(FlowGraph::Data))
+ throw std::runtime_error("ICE: multiplicative-expression: Bad data type for argument 3: "s + demangle(getValue(index, 2).type()));
+
FlowGraph::LocalScope scope; // TODO: move to context!
FlowGraph::Data destination{FlowGraph::MakeTemporaryInt(scope)};
FlowGraph::Data value0 {std::any_cast<FlowGraph::Data>(getValue(index, 0))};
@@ -414,6 +421,11 @@ std::unordered_map<std::string, std::function<std::any(index_t)>> CPP::getNodeEv
{ "additive-expression", [&](index_t index) -> std::any
{
if (childTypesOfNodeMatch(index, {"additive-expression", "+", "multiplicative-expression"})) {
+ if (getValue(index, 0).type() != typeid(FlowGraph::Data))
+ throw std::runtime_error("ICE: additive-expression: Bad data type for argument 1: "s + demangle(getValue(index, 0).type()));
+ if (getValue(index, 2).type() != typeid(FlowGraph::Data))
+ throw std::runtime_error("ICE: additive-expression: Bad data type for argument 3: "s + demangle(getValue(index, 2).type()));
+
FlowGraph::LocalScope scope; // TODO: move to context!
FlowGraph::Data destination{FlowGraph::MakeTemporaryInt(scope)};
FlowGraph::Data value0 {std::any_cast<FlowGraph::Data>(getValue(index, 0))};
@@ -507,19 +519,27 @@ std::unordered_map<std::string, std::function<std::any(index_t)>> CPP::getNodeEv
{ "expression", [&](index_t index) -> std::any
{
if (childTypesOfNodeMatch(index, {"assignment-expression"})) {
+ std::shared_ptr<FlowGraph::CreateScopeOp> scope_node {std::make_shared<FlowGraph::CreateScopeOp>()};
+ mCPPContext.graph.push_back(scope_node);
+
+ FlowGraph::LocalScope& scope{scope_node->scope()};
+
if (getValue(index, 0).type() == typeid(FlowGraph::Data)) { // got Data -> make trivial Node out of it and return it
- FlowGraph::LocalScope scope; // TODO: move to context!
+
FlowGraph::Data destination{FlowGraph::MakeTemporaryInt(scope)};
FlowGraph::Data source {std::any_cast<FlowGraph::Data>(getValue(index, 0))};
std::shared_ptr<FlowGraph::Node> node {std::make_shared<FlowGraph::UnaryOperation>(FlowGraph::UnaryOperationType::Store, destination, source)};
mCPPContext.graph.push_back(node);
return node;
- } else {
+ } else if (getValue(index, 0).type() == typeid(std::shared_ptr<FlowGraph::Node>)) {
std::shared_ptr<FlowGraph::Node> node {std::any_cast<std::shared_ptr<FlowGraph::Node>>(getValue(index, 0))};
mCPPContext.graph.push_back(node);
return getValue(index, 0);
+ } else {
+ throw std::runtime_error("ICE: expression: Unsupported argument type: "s + demangle(getValue(index, 0).type()));
}
+ mCPPContext.graph.push_back(std::make_shared<FlowGraph::DestroyScopeOp>(scope));
}
throw std::runtime_error("ICE: Unsupported childs: "s + ruleString(index)); // TODO
}
diff --git a/cpp.h b/cpp.h
index 8258011..11588b8 100644
--- a/cpp.h
+++ b/cpp.h
@@ -66,7 +66,7 @@ private:
std::unordered_map<std::string, std::function<std::any(index_t)>> getNodeEvalMap();
std::unordered_map<std::string, std::function<std::any(index_t)>> node_eval_map;
- CPPContext mCPPContext;
+ CPPContext mCPPContext; // intermediate data of phase 7.c
void getValueOfToken(index_t index);
void getValueOfNode(index_t index);
diff --git a/flowgraph/node.h b/flowgraph/node.h
index 98c684d..77395f0 100644
--- a/flowgraph/node.h
+++ b/flowgraph/node.h
@@ -174,7 +174,7 @@ namespace FlowGraph {
class DestroyScopeOp: public Node
{
public:
- DestroyScopeOp() {}
+ DestroyScopeOp(LocalScope& scope) {}
};
} // namespace FlowGraph
diff --git a/minicc.cpp b/minicc.cpp
index 88cb6ab..2e9c215 100644
--- a/minicc.cpp
+++ b/minicc.cpp
@@ -60,3 +60,8 @@ std::string Token::toString() const
return location.toString() + ": "s + value + " ("s + type + ")"s;
}
+std::string demangle(const std::type_info& type)
+{
+ return boost::core::demangle(type.name());
+}
+
diff --git a/minicc.h b/minicc.h
index 28b494a..59cc23a 100644
--- a/minicc.h
+++ b/minicc.h
@@ -2,6 +2,8 @@
#pragma once
+#include <boost/core/demangle.hpp>
+
#include <cstdlib>
#include <filesystem>
#include <iostream>
@@ -47,3 +49,5 @@ struct PairHashSS {
return h0 ^ (h1 << 1);
}
};
+
+std::string demangle(const std::type_info& type);
diff --git a/tests/test-flowgraph.cpp b/tests/test-flowgraph.cpp
index 021d6dd..469d816 100644
--- a/tests/test-flowgraph.cpp
+++ b/tests/test-flowgraph.cpp
@@ -51,7 +51,7 @@ TEST_F(FlowGraphTest, build_graph) {
std::shared_ptr<Node> free1{ std::make_shared<DeallocateDynamic>(pointer) };
graph.push_back(free1);
- std::shared_ptr<Node> destroyScope{std::make_shared<DestroyScopeOp>()};
+ std::shared_ptr<Node> destroyScope{std::make_shared<DestroyScopeOp>(createScope->scope())};
graph.push_back(destroyScope);
}