From d07c5bc14edbe071ee7b4f47f174780e95e451aa Mon Sep 17 00:00:00 2001 From: Roland Reichwein Date: Sun, 15 Nov 2020 13:55:18 +0100 Subject: Simplify Asm construction --- Makefile | 10 +++++++--- asm/assembler.cpp | 4 ++-- asm/assembler.h | 6 +++--- asm/intel64/add.cpp | 6 +++--- asm/intel64/add.h | 2 +- asm/intel64/dec.cpp | 8 ++++---- asm/intel64/dec.h | 2 +- asm/intel64/div.cpp | 8 ++++---- asm/intel64/div.h | 2 +- asm/intel64/encode.cpp | 10 +++++++++- asm/intel64/idiv.cpp | 6 +++--- asm/intel64/idiv.h | 2 +- asm/intel64/imul.cpp | 8 ++++---- asm/intel64/imul.h | 2 +- asm/intel64/inc.cpp | 8 ++++---- asm/intel64/inc.h | 2 +- asm/intel64/int.cpp | 4 ++-- asm/intel64/int.h | 2 +- asm/intel64/jmp.cpp | 4 ++-- asm/intel64/jmp.h | 2 +- asm/intel64/mov.cpp | 21 +++++++++++++++++---- asm/intel64/mov.h | 2 +- asm/intel64/mul.cpp | 8 ++++---- asm/intel64/mul.h | 2 +- asm/intel64/pop.cpp | 4 ++-- asm/intel64/pop.h | 2 +- asm/intel64/push.cpp | 4 ++-- asm/intel64/push.h | 2 +- asm/intel64/sub.cpp | 6 +++--- asm/intel64/sub.h | 2 +- asm/intel64/trivials.cpp | 6 +++--- asm/intel64/xor.cpp | 4 ++-- asm/intel64/xor.h | 2 +- cpp.cpp | 24 ++++++++++++++++++++++-- cpp.h | 2 +- flowgraph/node.h | 2 +- minicc.cpp | 5 +++++ minicc.h | 4 ++++ tests/test-flowgraph.cpp | 2 +- 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 makeOp(const std::string& mnemonic, Asm::Args& args) +std::shared_ptr 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(Asm::Args&)>; +using FactoryFunction = std::function(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 makeOp(const std::string& mnemonic, Asm::Args& args); +std::shared_ptr makeOp(const std::string& mnemonic, const Asm::Args& args); // overload for empty list of arguments std::shared_ptr makeOp(const std::string& mnemonic); @@ -137,5 +137,5 @@ std::string mangleName(const std::string& s) return mangleName(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(args[0]).name() == "eax" && @@ -31,10 +31,10 @@ Op_add::Op_add(Asm::Args& args) namespace { bool registered { - registerOp(mangleName("add"), [](Asm::Args& args) -> std::shared_ptr{ + registerOp(mangleName("add"), [](const Asm::Args& args) -> std::shared_ptr{ return std::make_shared(args); }) && - registerOp(mangleName("add"), [](Asm::Args& args) -> std::shared_ptr{ + registerOp(mangleName("add"), [](const Asm::Args& args) -> std::shared_ptr{ return std::make_shared(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 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{ 0xFE } + @@ -28,13 +28,13 @@ Op_dec::Op_dec(Asm::Args& args) namespace { bool registered { - registerOp(mangleName("dec"), [](Asm::Args& args) -> std::shared_ptr{ + registerOp(mangleName("dec"), [](const Asm::Args& args) -> std::shared_ptr{ return std::make_shared(args); }) && - registerOp(mangleName("dec"), [](Asm::Args& args) -> std::shared_ptr{ + registerOp(mangleName("dec"), [](const Asm::Args& args) -> std::shared_ptr{ return std::make_shared(args); }) && - registerOp(mangleName("dec"), [](Asm::Args& args) -> std::shared_ptr{ + registerOp(mangleName("dec"), [](const Asm::Args& args) -> std::shared_ptr{ return std::make_shared(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 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{ 0xF6 } + @@ -28,13 +28,13 @@ Op_div::Op_div(Asm::Args& args) namespace { bool registered { - registerOp(mangleName("div"), [](Asm::Args& args) -> std::shared_ptr{ + registerOp(mangleName("div"), [](const Asm::Args& args) -> std::shared_ptr{ return std::make_shared(args); }) && - registerOp(mangleName("div"), [](Asm::Args& args) -> std::shared_ptr{ + registerOp(mangleName("div"), [](const Asm::Args& args) -> std::shared_ptr{ return std::make_shared(args); }) && - registerOp(mangleName("div"), [](Asm::Args& args) -> std::shared_ptr{ + registerOp(mangleName("div"), [](const Asm::Args& args) -> std::shared_ptr{ return std::make_shared(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 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(op.type()))); + } else if (typeid(node_deref) == typeid(FlowGraph::CreateScopeOp)) { + //FlowGraph::CreateScopeOp& op {dynamic_cast(*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(*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{ 0xF6 } + @@ -28,10 +28,10 @@ Op_idiv::Op_idiv(Asm::Args& args) namespace { bool registered { - registerOp(mangleName("idiv"), [](Asm::Args& args) -> std::shared_ptr{ + registerOp(mangleName("idiv"), [](const Asm::Args& args) -> std::shared_ptr{ return std::make_shared(args); }) && - registerOp(mangleName("idiv"), [](Asm::Args& args) -> std::shared_ptr{ + registerOp(mangleName("idiv"), [](const Asm::Args& args) -> std::shared_ptr{ return std::make_shared(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 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{ 0xF6 } + @@ -28,13 +28,13 @@ Op_imul::Op_imul(Asm::Args& args) namespace { bool registered { - registerOp(mangleName("imul"), [](Asm::Args& args) -> std::shared_ptr{ + registerOp(mangleName("imul"), [](const Asm::Args& args) -> std::shared_ptr{ return std::make_shared(args); }) && - registerOp(mangleName("imul"), [](Asm::Args& args) -> std::shared_ptr{ + registerOp(mangleName("imul"), [](const Asm::Args& args) -> std::shared_ptr{ return std::make_shared(args); }) && - registerOp(mangleName("imul"), [](Asm::Args& args) -> std::shared_ptr{ + registerOp(mangleName("imul"), [](const Asm::Args& args) -> std::shared_ptr{ return std::make_shared(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 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{ 0xFE } + @@ -28,13 +28,13 @@ Op_inc::Op_inc(Asm::Args& args) namespace { bool registered { - registerOp(mangleName("inc"), [](Asm::Args& args) -> std::shared_ptr{ + registerOp(mangleName("inc"), [](const Asm::Args& args) -> std::shared_ptr{ return std::make_shared(args); }) && - registerOp(mangleName("inc"), [](Asm::Args& args) -> std::shared_ptr{ + registerOp(mangleName("inc"), [](const Asm::Args& args) -> std::shared_ptr{ return std::make_shared(args); }) && - registerOp(mangleName("inc"), [](Asm::Args& args) -> std::shared_ptr{ + registerOp(mangleName("inc"), [](const Asm::Args& args) -> std::shared_ptr{ return std::make_shared(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 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 -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("int"), [](Asm::Args& args) -> std::shared_ptr{ +bool registered { registerOp(mangleName("int"), [](const Asm::Args& args) -> std::shared_ptr{ return std::make_shared(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 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(jumpOp.name), [&](Asm::Args& args) -> std::shared_ptr{ + result &= registerOp(mangleName(jumpOp.name), [&](const Asm::Args& args) -> std::shared_ptr{ return std::make_shared(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(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 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{ 0x88 } + ModRM(std::any_cast(args[1]).name(), std::any_cast(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{ 0x89 } + + ModRM(std::any_cast(args[1]).name(), std::any_cast(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{ 0x89 } + + ModRM(std::any_cast(args[1]).name(), std::any_cast(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{ static_cast(0xB8 + RegNo(std::any_cast(args[0]).name())) } + std::any_cast(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{ REX("W") + static_cast(0xB8 + RegNo(std::any_cast(args[0]).name())) } + std::any_cast(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("mov"), [](Asm::Args& args) -> std::shared_ptr{ + registerOp(mangleName("mov"), [](const Asm::Args& args) -> std::shared_ptr{ return std::make_shared(args); }) && - registerOp(mangleName("mov"), [](Asm::Args& args) -> std::shared_ptr{ + registerOp(mangleName("mov"), [](const Asm::Args& args) -> std::shared_ptr{ return std::make_shared(args); }) && - registerOp(mangleName("mov"), [](Asm::Args& args) -> std::shared_ptr{ + registerOp(mangleName("mov"), [](const Asm::Args& args) -> std::shared_ptr{ return std::make_shared(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 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{ 0xF6 } + @@ -28,13 +28,13 @@ Op_mul::Op_mul(Asm::Args& args) namespace { bool registered { - registerOp(mangleName("mul"), [](Asm::Args& args) -> std::shared_ptr{ + registerOp(mangleName("mul"), [](const Asm::Args& args) -> std::shared_ptr{ return std::make_shared(args); }) && - registerOp(mangleName("mul"), [](Asm::Args& args) -> std::shared_ptr{ + registerOp(mangleName("mul"), [](const Asm::Args& args) -> std::shared_ptr{ return std::make_shared(args); }) && - registerOp(mangleName("mul"), [](Asm::Args& args) -> std::shared_ptr{ + registerOp(mangleName("mul"), [](const Asm::Args& args) -> std::shared_ptr{ return std::make_shared(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 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{ 0x58 } + RegNo(std::any_cast(args[0]).name()); @@ -21,7 +21,7 @@ Op_pop::Op_pop(Asm::Args& args) namespace { bool registered { - registerOp(mangleName("pop"), [](Asm::Args& args) -> std::shared_ptr{ + registerOp(mangleName("pop"), [](const Asm::Args& args) -> std::shared_ptr{ return std::make_shared(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 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{ 0x50 } + RegNo(std::any_cast(args[0]).name()); @@ -21,7 +21,7 @@ Op_push::Op_push(Asm::Args& args) namespace { bool registered { - registerOp(mangleName("push"), [](Asm::Args& args) -> std::shared_ptr{ + registerOp(mangleName("push"), [](const Asm::Args& args) -> std::shared_ptr{ return std::make_shared(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 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(args[0]).name() == "eax" && @@ -31,10 +31,10 @@ Op_sub::Op_sub(Asm::Args& args) namespace { bool registered { - registerOp(mangleName("sub"), [](Asm::Args& args) -> std::shared_ptr{ + registerOp(mangleName("sub"), [](const Asm::Args& args) -> std::shared_ptr{ return std::make_shared(args); }) && - registerOp(mangleName("sub"), [](Asm::Args& args) -> std::shared_ptr{ + registerOp(mangleName("sub"), [](const Asm::Args& args) -> std::shared_ptr{ return std::make_shared(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 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{ + registerOp("nop", [](const Asm::Args& args) -> std::shared_ptr{ return std::make_shared(); }) && - registerOp("ret", [](Asm::Args& args) -> std::shared_ptr{ + registerOp("ret", [](const Asm::Args& args) -> std::shared_ptr{ return std::make_shared(); }) && - registerOp("syscall", [](Asm::Args& args) -> std::shared_ptr{ + registerOp("syscall", [](const Asm::Args& args) -> std::shared_ptr{ return std::make_shared(); }) }; 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("xor"), [](Asm::Args& args) -> std::shared_ptr{ + registerOp(mangleName("xor"), [](const Asm::Args& args) -> std::shared_ptr{ return std::make_shared(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 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 #include +#include + #include #include #include @@ -398,6 +400,11 @@ std::unordered_map> 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(getValue(index, 0))}; @@ -414,6 +421,11 @@ std::unordered_map> 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(getValue(index, 0))}; @@ -507,19 +519,27 @@ std::unordered_map> CPP::getNodeEv { "expression", [&](index_t index) -> std::any { if (childTypesOfNodeMatch(index, {"assignment-expression"})) { + std::shared_ptr scope_node {std::make_shared()}; + 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(getValue(index, 0))}; std::shared_ptr node {std::make_shared(FlowGraph::UnaryOperationType::Store, destination, source)}; mCPPContext.graph.push_back(node); return node; - } else { + } else if (getValue(index, 0).type() == typeid(std::shared_ptr)) { std::shared_ptr node {std::any_cast>(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(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> getNodeEvalMap(); std::unordered_map> 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 + #include #include #include @@ -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 free1{ std::make_shared(pointer) }; graph.push_back(free1); - std::shared_ptr destroyScope{std::make_shared()}; + std::shared_ptr destroyScope{std::make_shared(createScope->scope())}; graph.push_back(destroyScope); } -- cgit v1.2.3