aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYann Herklotz <ymherklotz@gmail.com>2017-03-12 11:08:03 +0000
committerYann Herklotz <ymherklotz@gmail.com>2017-03-12 11:08:03 +0000
commitfd25256a37696de23d8f6c99827a97b63733845d (patch)
treedbfc5f680dcdf78ac62f0d7f1d6bb09271e8a6b2
parentde1f50c2bfa7dfc3b758a0cb89c856534c4ab3a1 (diff)
downloadCompiler-fd25256a37696de23d8f6c99827a97b63733845d.tar.gz
Compiler-fd25256a37696de23d8f6c99827a97b63733845d.zip
Have to improve reg allocation
-rw-r--r--c_compiler/include/bindings.hpp5
-rw-r--r--c_compiler/include/expression.hpp12
-rw-r--r--c_compiler/src/bindings.cpp24
-rw-r--r--c_compiler/src/c_lexer.flex6
-rw-r--r--c_compiler/src/c_parser.y2
-rw-r--r--c_compiler/src/expression.cpp33
-rw-r--r--c_compiler/src/statement.cpp10
-rw-r--r--c_compiler/test/in/Add.c2
-rw-r--r--c_compiler/test/in/AddMult.c10
-rw-r--r--c_compiler/test/in/Mult.c9
-rwxr-xr-xtest_compiler.sh6
11 files changed, 108 insertions, 11 deletions
diff --git a/c_compiler/include/bindings.hpp b/c_compiler/include/bindings.hpp
index 983a10d..5dd1e1f 100644
--- a/c_compiler/include/bindings.hpp
+++ b/c_compiler/include/bindings.hpp
@@ -25,16 +25,21 @@ class VariableStackBindings
private:
std::map<std::string, DeclarationData> bindings;
int32_t stack_counter;
+ int8_t current_register;
public:
VariableStackBindings();
void insertBinding(std::string id, TypePtr type, int32_t stack_position);
void increaseStackPosition();
+ void resetRegister();
+ void increaseRegister();
int32_t getCurrentStackPosition() const;
int32_t getStackPosition(const std::string& id) const;
+ int8_t getCurrentRegister() const;
+
bool bindingExists(const std::string& id) const;
};
diff --git a/c_compiler/include/expression.hpp b/c_compiler/include/expression.hpp
index df95a1e..a4939a9 100644
--- a/c_compiler/include/expression.hpp
+++ b/c_compiler/include/expression.hpp
@@ -54,6 +54,18 @@ public:
};
+class MultiplicativeExpression : public OperationExpression
+{
+private:
+ std::string operation;
+
+public:
+ MultiplicativeExpression(Expression* _lhs, const std::string& _operation, Expression* _rhs);
+
+ virtual VariableStackBindings printasm(VariableStackBindings bindings) const;
+};
+
+
class Identifier : public Expression
{
private:
diff --git a/c_compiler/src/bindings.cpp b/c_compiler/src/bindings.cpp
index 4315407..80375e7 100644
--- a/c_compiler/src/bindings.cpp
+++ b/c_compiler/src/bindings.cpp
@@ -1,10 +1,12 @@
#include "bindings.hpp"
+#include <iostream>
+
// VariableStackBindings definition
VariableStackBindings::VariableStackBindings()
- : stack_counter(4)
+ : stack_counter(4), current_register(2)
{}
void VariableStackBindings::insertBinding(std::string id, TypePtr type, int32_t stack_position)
@@ -21,6 +23,21 @@ void VariableStackBindings::increaseStackPosition()
stack_counter += 4;
}
+void VariableStackBindings::resetRegister()
+{
+ current_register = 2;
+}
+
+void VariableStackBindings::increaseRegister()
+{
+ if(current_register == 15)
+ current_register = 24;
+ else if(current_register == 25)
+ std::cerr << "Error : cannot allocate more registers" << std::endl;
+ else
+ current_register++;
+}
+
int32_t VariableStackBindings::getCurrentStackPosition() const
{
return stack_counter;
@@ -36,6 +53,11 @@ int32_t VariableStackBindings::getStackPosition(const std::string &id) const
else return 0;
}
+int8_t VariableStackBindings::getCurrentRegister() const
+{
+ return current_register;
+}
+
bool VariableStackBindings::bindingExists(const std::string &id) const
{
auto binding = bindings.find(id);
diff --git a/c_compiler/src/c_lexer.flex b/c_compiler/src/c_lexer.flex
index f6f2dd3..716e1ac 100644
--- a/c_compiler/src/c_lexer.flex
+++ b/c_compiler/src/c_lexer.flex
@@ -59,9 +59,9 @@ ALL .
[!][=] { return T_EQUALITY_OP; }
([<>][=])|[<>] { return T_REL_OP; }
[<>][<>] { return T_SHIFT_OP; }
-[*] { return T_MULT; }
-[\/] { return T_DIV; }
-[%] { return T_REM; }
+[*] { yylval.string = new std::string(yytext); return T_MULT; }
+[\/] { yylval.string = new std::string(yytext); return T_DIV; }
+[%] { yylval.string = new std::string(yytext); return T_REM; }
[~] { return T_TILDE; }
[!] { return T_NOT; }
[.] { return T_DOT; }
diff --git a/c_compiler/src/c_parser.y b/c_compiler/src/c_parser.y
index f262f58..5a35c63 100644
--- a/c_compiler/src/c_parser.y
+++ b/c_compiler/src/c_parser.y
@@ -283,7 +283,7 @@ AdditiveExpression:
MultiplicativeExpression:
CastExpression { $$ = $1; }
- | MultiplicativeExpression MultDivRemOP CastExpression { $$ = $3; }
+| MultiplicativeExpression MultDivRemOP CastExpression { $$ = new MultiplicativeExpression($1, *$2, $3); delete $2; }
;
MultDivRemOP:
diff --git a/c_compiler/src/expression.cpp b/c_compiler/src/expression.cpp
index 6c1ba97..dea282f 100644
--- a/c_compiler/src/expression.cpp
+++ b/c_compiler/src/expression.cpp
@@ -69,7 +69,7 @@ VariableStackBindings AdditiveExpression::printasm(VariableStackBindings binding
// currently using signed and sub because I only have signed numbers implemented
// must update this as I add more types
if(operation == "+")
- std::cout << "\tadd\t$2,$2,$3" << std::endl;
+ std::cout << "\tadd\t$2,$3,$2" << std::endl;
else if(operation == "-")
std::cout << "\tsub\t$2,$3,$2" << std::endl;
else
@@ -79,6 +79,37 @@ VariableStackBindings AdditiveExpression::printasm(VariableStackBindings binding
}
+// Multiplicative Expression definition
+
+
+MultiplicativeExpression::MultiplicativeExpression(Expression* _lhs, const std::string& _operation, Expression* _rhs)
+ : OperationExpression(_lhs, _rhs), operation(_operation)
+{}
+
+VariableStackBindings MultiplicativeExpression::printasm(VariableStackBindings bindings) const
+{
+ lhs->printasm(bindings);
+
+ std::cout << "\tmove\t$3,$2" << std::endl;
+
+ rhs->printasm(bindings);
+
+ // then perform the right operation
+ if(operation == "*")
+ std::cout << "\tmul\t$2,$3,$2" << std::endl;
+ else if(operation == "/" || operation == "%") {
+ std::cout << "\tdiv\t$3,$2" << std::endl;
+ if(operation == "/")
+ std::cout << "\tmflo\t$2" << std::endl;
+ else
+ std::cout << "\tmfhi\t$2" << std::endl;
+ } else
+ std::cerr << "Don't recognize symbol '" << operation << "'" << std::endl;
+
+ return bindings;
+}
+
+
// Identifier definition
Identifier::Identifier(const std::string& id)
diff --git a/c_compiler/src/statement.cpp b/c_compiler/src/statement.cpp
index fa85df0..f86329f 100644
--- a/c_compiler/src/statement.cpp
+++ b/c_compiler/src/statement.cpp
@@ -153,9 +153,12 @@ VariableStackBindings ExpressionStatement::printasm(VariableStackBindings bindin
{
if(next_statement != nullptr)
next_statement->printasm(bindings);
-
+
if(m_expr != nullptr)
+ {
+ bindings.resetRegister();
m_expr->printasm(bindings);
+ }
return bindings;
}
@@ -188,8 +191,11 @@ VariableStackBindings JumpStatement::printasm(VariableStackBindings bindings) co
next_statement->printasm(bindings);
if(m_expr != nullptr)
+ {
+ bindings.resetRegister();
m_expr->printasm(bindings);
-
+ }
+
return bindings;
}
diff --git a/c_compiler/test/in/Add.c b/c_compiler/test/in/Add.c
index 43e557e..b672efb 100644
--- a/c_compiler/test/in/Add.c
+++ b/c_compiler/test/in/Add.c
@@ -8,6 +8,8 @@ int main() {
z = x + y + x + y - x;
}
}
+
+ z = 2 + z - 2;
return z;
}
diff --git a/c_compiler/test/in/AddMult.c b/c_compiler/test/in/AddMult.c
new file mode 100644
index 0000000..a8fa566
--- /dev/null
+++ b/c_compiler/test/in/AddMult.c
@@ -0,0 +1,10 @@
+int main() {
+ int x;
+ int a = 8;
+ int b = 5;
+ int c = 7;
+ int d = 3;
+ x = a * b + c * d;
+
+ return x;
+}
diff --git a/c_compiler/test/in/Mult.c b/c_compiler/test/in/Mult.c
new file mode 100644
index 0000000..4855b54
--- /dev/null
+++ b/c_compiler/test/in/Mult.c
@@ -0,0 +1,9 @@
+int main() {
+ int x = 4*2;
+ int y = 7;
+ int z = 14 % 8;
+
+ z = x * y * z / z * x;
+
+ return z;
+}
diff --git a/test_compiler.sh b/test_compiler.sh
index 700afe5..65fb311 100755
--- a/test_compiler.sh
+++ b/test_compiler.sh
@@ -30,10 +30,10 @@ for i in c_compiler/test/in/*.c; do
BASENAME=$(basename $i .c);
cat $i | ./bin/c_compiler > c_compiler/test/out/$BASENAME.s 2> c_compiler/test/out/$BASENAME.stderr.txt
- mips-linux-gnu-gcc -S -c c_compiler/test/in/$BASENAME.c -o c_compiler/test/ref/$BASENAME.s
- mips-linux-gnu-gcc -static c_compiler/test/ref/$BASENAME.s -o c_compiler/test/ref/$BASENAME
+ mips-linux-gnu-gcc -O0 -S -c c_compiler/test/in/$BASENAME.c -o c_compiler/test/ref/$BASENAME.s
+ mips-linux-gnu-gcc -O0 -static c_compiler/test/ref/$BASENAME.s -o c_compiler/test/ref/$BASENAME
- mips-linux-gnu-gcc -static c_compiler/test/out/$BASENAME.s -o c_compiler/test/out/$BASENAME
+ mips-linux-gnu-gcc -O0 -static c_compiler/test/out/$BASENAME.s -o c_compiler/test/out/$BASENAME
qemu-mips c_compiler/test/ref/$BASENAME
REFOUTPUT=$?