From ff69e8cab318101843cd8b49a0cb04df9763e10f Mon Sep 17 00:00:00 2001 From: Roland Reichwein Date: Sun, 22 Nov 2020 22:14:23 +0100 Subject: Generalize Add / Mul, Integer promotion, tests --- TODO | 2 +- asm/intel64/encode.cpp | 2 + cpp.cpp | 60 ++++++++++++++++++---- flowgraph/node.cpp | 7 +++ flowgraph/node.h | 3 ++ systemtest/mcc-execute.tests/exitcodes.exp | 3 ++ .../mcc-execute.tests/test-parentheses-left.cpp | 1 + .../mcc-execute.tests/test-parentheses-right.cpp | 1 + systemtest/mcc-execute.tests/test-parentheses.cpp | 1 + 9 files changed, 69 insertions(+), 11 deletions(-) create mode 100644 systemtest/mcc-execute.tests/test-parentheses-left.cpp create mode 100644 systemtest/mcc-execute.tests/test-parentheses-right.cpp create mode 100644 systemtest/mcc-execute.tests/test-parentheses.cpp diff --git a/TODO b/TODO index 6f10842..eaf8e1a 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,3 @@ -Fix stack +encode.cpp: Sub grammer.cpp: match() : return point of match error ("Compile error") diff --git a/asm/intel64/encode.cpp b/asm/intel64/encode.cpp index 1cc1a6d..6118743 100644 --- a/asm/intel64/encode.cpp +++ b/asm/intel64/encode.cpp @@ -175,6 +175,8 @@ void Asm::toMachineCode(const FlowGraph::Graph& graph, Segment& segment) segment.push_back(makeLoadValue(operands[1], graph)); segment.append(parseAsm("neg eax")); segment.push_back(makeStoreValue(operands[0], graph)); + } else if (op.type() == FlowGraph::UnaryOperationType::Resize) { + throw std::runtime_error("ICE: Asm: Unsupported unary operation type: Resize"s); } else throw std::runtime_error("ICE: Asm: Unsupported unary operation type: "s + std::to_string(static_cast(op.type()))); diff --git a/cpp.cpp b/cpp.cpp index 61fdc0e..5dbf5e6 100644 --- a/cpp.cpp +++ b/cpp.cpp @@ -354,6 +354,34 @@ std::string CPP::ruleString(index_t node_id) return result; } +// Promote last op of specified graph if appropriate (i.e. if not yet big enough) +void promoteLastOp(FlowGraph::Graph& graph, FlowGraph::DataType targetType) +{ + FlowGraph::DataType sourceType {graph.lastOp()->destination().type()}; + + if (targetType != sourceType) { + FlowGraph::Data temporary {FlowGraph::MakeTemporary(graph.scope(), targetType)}; + std::shared_ptr node {std::make_shared(FlowGraph::UnaryOperationType::Resize, + temporary, + graph.lastOp()->destination())}; + graph.append(node); + } +} + +// Promote last ops of specified graphs until width is equal +void promoteLastOps(FlowGraph::Graph& graph0, FlowGraph::Graph& graph1) +{ + // Find target type + FlowGraph::DataType targetType = FlowGraph::DataType::Int; + if (graph0.lastOp()->destination().type() == FlowGraph::DataType::LongLong || + graph1.lastOp()->destination().type() == FlowGraph::DataType::LongLong) + targetType = FlowGraph::DataType::LongLong; // TODO: Support unsigned variants + + // promote both graph results to target types + promoteLastOp(graph0, targetType); + promoteLastOp(graph1, targetType); +} + std::unordered_map> CPP::getNodeEvalMap() { return { @@ -403,15 +431,17 @@ std::unordered_map> CPP::getNodeEv throw std::runtime_error("ICE: multiplicative-expression: Bad data type for argument 3: "s + demangle(getValue(index, 2).type())); FlowGraph::Graph value0{std::any_cast(getValue(index, 0))}; - std::shared_ptr lastOp0{value0.lastOp()}; - FlowGraph::Graph value1{std::any_cast(getValue(index, 2))}; + + promoteLastOps(value0, value1); + + std::shared_ptr lastOp0{value0.lastOp()}; std::shared_ptr lastOp1{value1.lastOp()}; FlowGraph::Graph result{value0}; result.append(value1); - FlowGraph::Data destination{FlowGraph::MakeTemporaryInt(result.scope())}; + FlowGraph::Data destination{FlowGraph::MakeTemporary(result.scope(), lastOp0->destination().type())}; FlowGraph::BinaryOperationType type{}; if (getType(index, 1) == "*") @@ -433,29 +463,39 @@ std::unordered_map> CPP::getNodeEv } if (childTypesOfNodeMatch(index, {"pm-expression"})) return getValue(index, 0); - throw std::runtime_error("ICE: Unsupported childs: "s + ruleString(index)); // TODO + throw std::runtime_error("ICE: Unsupported childs: "s + ruleString(index)); } }, { "additive-expression", [&](index_t index) -> std::any { - if (childTypesOfNodeMatch(index, {"additive-expression", "+", "multiplicative-expression"})) { + if (childTypesOfNodeMatch(index, {"additive-expression", "", "multiplicative-expression"})) { if (getValue(index, 0).type() != typeid(FlowGraph::Graph)) 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::Graph)) throw std::runtime_error("ICE: additive-expression: Bad data type for argument 3: "s + demangle(getValue(index, 2).type())); FlowGraph::Graph value0{std::any_cast(getValue(index, 0))}; - std::shared_ptr lastOp0{value0.lastOp()}; - FlowGraph::Graph value1{std::any_cast(getValue(index, 2))}; + + promoteLastOps(value0, value1); + + std::shared_ptr lastOp0{value0.lastOp()}; std::shared_ptr lastOp1{value1.lastOp()}; FlowGraph::Graph result{value0}; result.append(value1); - FlowGraph::Data destination{FlowGraph::MakeTemporaryInt(result.scope())}; + FlowGraph::Data destination{FlowGraph::MakeTemporary(result.scope(), lastOp0->destination().type())}; - std::shared_ptr node {std::make_shared(FlowGraph::BinaryOperationType::Add, + FlowGraph::BinaryOperationType type{}; + if (getType(index, 1) == "+") + type = FlowGraph::BinaryOperationType::Add; + else if (getType(index, 1) == "-") + type = FlowGraph::BinaryOperationType::Subtract; + else + throw std::runtime_error("ICE: additive-expression: Unknown operand: "s + getType(index, 1)); + + std::shared_ptr node {std::make_shared(type, destination, lastOp0->destination(), lastOp1->destination())}; @@ -465,7 +505,7 @@ std::unordered_map> CPP::getNodeEv } if (childTypesOfNodeMatch(index, {"multiplicative-expression"})) return getValue(index, 0); - throw std::runtime_error("ICE: Unsupported childs: "s + ruleString(index)); // TODO + throw std::runtime_error("ICE: Unsupported childs: "s + ruleString(index)); } }, { "shift-expression", [&](index_t index) -> std::any diff --git a/flowgraph/node.cpp b/flowgraph/node.cpp index cb7677a..27310a9 100644 --- a/flowgraph/node.cpp +++ b/flowgraph/node.cpp @@ -16,6 +16,13 @@ FlowGraph::Data& Node::destination() return mOperands[0]; } +Data FlowGraph::MakeTemporary(std::shared_ptr scope, DataType type) +{ + Data data{type, std::make_shared()}; + scope->push_back(std::make_shared(data)); + return data; +} + // 4 byte for now Data FlowGraph::MakeConstantInt(int i) { diff --git a/flowgraph/node.h b/flowgraph/node.h index 34e937b..f653096 100644 --- a/flowgraph/node.h +++ b/flowgraph/node.h @@ -47,6 +47,8 @@ namespace FlowGraph { {} }; + Data MakeTemporary(std::shared_ptr scope, DataType type); + Data MakeConstantInt(int i); Data MakeLocalInt(std::shared_ptr scope, const std::string& name); Data MakeLocalPointer(std::shared_ptr scope, const std::string& name); @@ -120,6 +122,7 @@ namespace FlowGraph { LogicalNot, BitwiseNot, Minus, + Resize, // Promote / narrow a value }; class UnaryOperation: public Node diff --git a/systemtest/mcc-execute.tests/exitcodes.exp b/systemtest/mcc-execute.tests/exitcodes.exp index 0480be8..dc4d377 100644 --- a/systemtest/mcc-execute.tests/exitcodes.exp +++ b/systemtest/mcc-execute.tests/exitcodes.exp @@ -5,4 +5,7 @@ runtest_exit_code "Addition" "systemtest/mcc-execute.tests/test-addition" 3 runtest_exit_code "Multiplication" "systemtest/mcc-execute.tests/test-multiplication" 6 runtest_exit_code "Division" "systemtest/mcc-execute.tests/test-division" 2 runtest_exit_code "Modulo" "systemtest/mcc-execute.tests/test-modulo" 1 +runtest_exit_code "Parentheses Tree" "systemtest/mcc-execute.tests/test-parentheses" 36 +runtest_exit_code "Parentheses Left" "systemtest/mcc-execute.tests/test-parentheses-left" 36 +runtest_exit_code "Parentheses Right" "systemtest/mcc-execute.tests/test-parentheses-right" 36 diff --git a/systemtest/mcc-execute.tests/test-parentheses-left.cpp b/systemtest/mcc-execute.tests/test-parentheses-left.cpp new file mode 100644 index 0000000..2ebc713 --- /dev/null +++ b/systemtest/mcc-execute.tests/test-parentheses-left.cpp @@ -0,0 +1 @@ +int main() { return (((((((1 + 2) + 3) + 4) + 5) + 6) + 7) + 8); } diff --git a/systemtest/mcc-execute.tests/test-parentheses-right.cpp b/systemtest/mcc-execute.tests/test-parentheses-right.cpp new file mode 100644 index 0000000..662af95 --- /dev/null +++ b/systemtest/mcc-execute.tests/test-parentheses-right.cpp @@ -0,0 +1 @@ +int main() { return (1 + (2 + (3 + (4 + (5 + (6 + (7 + 8))))))); } diff --git a/systemtest/mcc-execute.tests/test-parentheses.cpp b/systemtest/mcc-execute.tests/test-parentheses.cpp new file mode 100644 index 0000000..fca52e9 --- /dev/null +++ b/systemtest/mcc-execute.tests/test-parentheses.cpp @@ -0,0 +1 @@ +int main() { return ((1 + 2) + (3 + 4)) + ((5 + 6) + (7 + 8)); } -- cgit v1.2.3