diff options
author | Yann Herklotz <ymherklotz@gmail.com> | 2017-03-12 11:08:03 +0000 |
---|---|---|
committer | Yann Herklotz <ymherklotz@gmail.com> | 2017-03-12 11:08:03 +0000 |
commit | fd25256a37696de23d8f6c99827a97b63733845d (patch) | |
tree | dbfc5f680dcdf78ac62f0d7f1d6bb09271e8a6b2 | |
parent | de1f50c2bfa7dfc3b758a0cb89c856534c4ab3a1 (diff) | |
download | Compiler-fd25256a37696de23d8f6c99827a97b63733845d.tar.gz Compiler-fd25256a37696de23d8f6c99827a97b63733845d.zip |
Have to improve reg allocation
-rw-r--r-- | c_compiler/include/bindings.hpp | 5 | ||||
-rw-r--r-- | c_compiler/include/expression.hpp | 12 | ||||
-rw-r--r-- | c_compiler/src/bindings.cpp | 24 | ||||
-rw-r--r-- | c_compiler/src/c_lexer.flex | 6 | ||||
-rw-r--r-- | c_compiler/src/c_parser.y | 2 | ||||
-rw-r--r-- | c_compiler/src/expression.cpp | 33 | ||||
-rw-r--r-- | c_compiler/src/statement.cpp | 10 | ||||
-rw-r--r-- | c_compiler/test/in/Add.c | 2 | ||||
-rw-r--r-- | c_compiler/test/in/AddMult.c | 10 | ||||
-rw-r--r-- | c_compiler/test/in/Mult.c | 9 | ||||
-rwxr-xr-x | test_compiler.sh | 6 |
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=$? |