summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRoland Reichwein <mail@reichwein.it>2020-11-22 22:14:23 +0100
committerRoland Reichwein <mail@reichwein.it>2020-11-22 22:14:23 +0100
commitff69e8cab318101843cd8b49a0cb04df9763e10f (patch)
tree58778d0ba28264880df8bdf6bfe45766939c3af9
parentad3fd947005400c90f41baa4416a27d94b1bc157 (diff)
Generalize Add / Mul, Integer promotion, tests
-rw-r--r--TODO2
-rw-r--r--asm/intel64/encode.cpp2
-rw-r--r--cpp.cpp60
-rw-r--r--flowgraph/node.cpp7
-rw-r--r--flowgraph/node.h3
-rw-r--r--systemtest/mcc-execute.tests/exitcodes.exp3
-rw-r--r--systemtest/mcc-execute.tests/test-parentheses-left.cpp1
-rw-r--r--systemtest/mcc-execute.tests/test-parentheses-right.cpp1
-rw-r--r--systemtest/mcc-execute.tests/test-parentheses.cpp1
9 files changed, 69 insertions, 11 deletions
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<int>(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<FlowGraph::Node> node {std::make_shared<FlowGraph::UnaryOperation>(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<std::string, std::function<std::any(index_t)>> CPP::getNodeEvalMap()
{
return {
@@ -403,15 +431,17 @@ std::unordered_map<std::string, std::function<std::any(index_t)>> 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<FlowGraph::Graph>(getValue(index, 0))};
- std::shared_ptr<FlowGraph::Node> lastOp0{value0.lastOp()};
-
FlowGraph::Graph value1{std::any_cast<FlowGraph::Graph>(getValue(index, 2))};
+
+ promoteLastOps(value0, value1);
+
+ std::shared_ptr<FlowGraph::Node> lastOp0{value0.lastOp()};
std::shared_ptr<FlowGraph::Node> 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<std::string, std::function<std::any(index_t)>> 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<FlowGraph::Graph>(getValue(index, 0))};
- std::shared_ptr<FlowGraph::Node> lastOp0{value0.lastOp()};
-
FlowGraph::Graph value1{std::any_cast<FlowGraph::Graph>(getValue(index, 2))};
+
+ promoteLastOps(value0, value1);
+
+ std::shared_ptr<FlowGraph::Node> lastOp0{value0.lastOp()};
std::shared_ptr<FlowGraph::Node> 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<FlowGraph::Node> node {std::make_shared<FlowGraph::BinaryOperation>(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<FlowGraph::Node> node {std::make_shared<FlowGraph::BinaryOperation>(type,
destination,
lastOp0->destination(), lastOp1->destination())};
@@ -465,7 +505,7 @@ std::unordered_map<std::string, std::function<std::any(index_t)>> 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<FlowGraph::LocalScope> scope, DataType type)
+{
+ Data data{type, std::make_shared<TemporaryStorage>()};
+ scope->push_back(std::make_shared<Data>(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<LocalScope> scope, DataType type);
+
Data MakeConstantInt(int i);
Data MakeLocalInt(std::shared_ptr<FlowGraph::LocalScope> scope, const std::string& name);
Data MakeLocalPointer(std::shared_ptr<FlowGraph::LocalScope> 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)); }