diff options
author | Jack Palevich <jackpal@google.com> | 2009-07-29 10:28:18 -0700 |
---|---|---|
committer | Jack Palevich <jackpal@google.com> | 2009-07-29 10:28:18 -0700 |
commit | ddf7c9c14184acffe5ac33d06389cf733cfe11da (patch) | |
tree | b60fb8d0f963df5166a6fdb7f97e35715afc5cec /libacc | |
parent | 7fcdf1c5f8f25228bf348be9360594679329616f (diff) | |
download | system_core-ddf7c9c14184acffe5ac33d06389cf733cfe11da.zip system_core-ddf7c9c14184acffe5ac33d06389cf733cfe11da.tar.gz system_core-ddf7c9c14184acffe5ac33d06389cf733cfe11da.tar.bz2 |
Implement inc/dec in a more lval-friendly way.
Diffstat (limited to 'libacc')
-rw-r--r-- | libacc/acc.cpp | 138 | ||||
-rw-r--r-- | libacc/tests/data/inc.c | 10 | ||||
-rw-r--r-- | libacc/tests/test.py | 9 |
3 files changed, 125 insertions, 32 deletions
diff --git a/libacc/acc.cpp b/libacc/acc.cpp index 877cc4d..1a3d315 100644 --- a/libacc/acc.cpp +++ b/libacc/acc.cpp @@ -356,11 +356,15 @@ class Compiler : public ErrorSink { */ virtual void genUnaryOp(int op) = 0; - /* Push R0 onto the stack. + /* Push R0 onto the stack. (Also known as "dup" for duplicate.) */ virtual void pushR0() = 0; - /* Pop R0 from the stack. + /* Turn R0, TOS into R0 TOS R0 */ + + virtual void over() = 0; + + /* Pop R0 from the stack. (Also known as "drop") */ virtual void popR0() = 0; @@ -490,18 +494,22 @@ class Compiler : public ErrorSink { */ virtual size_t stackSizeOf(Type* pType) = 0; - Type* getR0Type() { + virtual Type* getR0Type() { return mExpressionStack.back().pType; } - ExpressionType getR0ExpressionType() { + virtual ExpressionType getR0ExpressionType() { return mExpressionStack.back().et; } - void setR0ExpressionType(ExpressionType et) { + virtual void setR0ExpressionType(ExpressionType et) { mExpressionStack.back().et = et; } + virtual size_t getExpressionStackDepth() { + return mExpressionStack.size(); + } + protected: /* * Output a byte. Handles all values, 0..ff. @@ -541,6 +549,7 @@ class Compiler : public ErrorSink { } void setR0Type(Type* pType) { + assert(pType != NULL); mExpressionStack.back().pType = pType; } @@ -557,6 +566,15 @@ class Compiler : public ErrorSink { } + void overType() { + size_t size = mExpressionStack.size(); + if (size >= 2) { + mExpressionStack.push_back(mExpressionStack.back()); + mExpressionStack[size-1] = mExpressionStack[size-2]; + mExpressionStack[size-2] = mExpressionStack[size]; + } + } + void popType() { mExpressionStack.pop_back(); } @@ -1014,6 +1032,24 @@ class Compiler : public ErrorSink { LOG_STACK("pushR0: %d\n", mStackUse); } + virtual void over() { + // We know it's only used for int-ptr ops (++/--) + + Type* pR0Type = getR0Type(); + TypeTag r0ct = collapseType(pR0Type->tag); + + Type* pTOSType = getTOSType(); + TypeTag tosct = collapseType(pTOSType->tag); + + assert (r0ct == TY_INT && tosct == TY_INT); + + o4(0xE8BD0002); // ldmfd sp!,{r1} + o4(0xE92D0001); // stmfd sp!,{r0} + o4(0xE92D0002); // stmfd sp!,{r1} + overType(); + mStackUse += 4; + } + virtual void popR0() { Type* pTOSType = getTOSType(); switch (collapseType(pTOSType->tag)){ @@ -2129,6 +2165,24 @@ class Compiler : public ErrorSink { pushType(); } + virtual void over() { + // We know it's only used for int-ptr ops (++/--) + + Type* pR0Type = getR0Type(); + TypeTag r0ct = collapseType(pR0Type->tag); + + Type* pTOSType = getTOSType(); + TypeTag tosct = collapseType(pTOSType->tag); + + assert (r0ct == TY_INT && tosct == TY_INT); + + o(0x59); /* pop %ecx */ + o(0x50); /* push %eax */ + o(0x51); /* push %ecx */ + + overType(); + } + virtual void popR0() { Type* pR0Type = getR0Type(); TypeTag r0ct = collapseType(pR0Type->tag); @@ -2146,7 +2200,7 @@ class Compiler : public ErrorSink { o(0x58); /* popl %eax */ break; default: - error("pushR0 unsupported type %d", r0ct); + error("popR0 unsupported type %d", r0ct); break; } popType(); @@ -2613,6 +2667,11 @@ class Compiler : public ErrorSink { mpBase->pushR0(); } + virtual void over() { + fprintf(stderr, "over()\n"); + mpBase->over(); + } + virtual void popR0() { fprintf(stderr, "popR0()\n"); mpBase->popR0(); @@ -2721,14 +2780,30 @@ class Compiler : public ErrorSink { } + virtual size_t stackAlignmentOf(Type* pType) { + return mpBase->stackAlignmentOf(pType); + } + + virtual size_t stackSizeOf(Type* pType) { return mpBase->stackSizeOf(pType); } - virtual Type* getR0Type() { return mpBase->getR0Type(); } + + virtual ExpressionType getR0ExpressionType() { + return mpBase->getR0ExpressionType(); + } + + virtual void setR0ExpressionType(ExpressionType et) { + mpBase->setR0ExpressionType(et); + } + + virtual size_t getExpressionStackDepth() { + return mpBase->getExpressionStackDepth(); + } }; #endif // PROVIDE_TRACE_CODEGEN @@ -4001,14 +4076,35 @@ class Compiler : public ErrorSink { } } // load a variable - pGen->loadR0(n, pVI->pType); if (tokl == 11) { // post inc / post dec + pGen->leaR0(n, createPtrType(pVI->pType)); + pGen->pushR0(); - impInc(tokc); - pGen->storeR0(n, pVI->pType); + pGen->loadR0FromR0(); + pGen->over(); + int lit = 1; + if (tokc == OP_DECREMENT) { + lit = -1; + } + switch (pVI->pType->tag) { + case TY_INT: + case TY_CHAR: + case TY_POINTER: + pGen->pushR0(); + pGen->li(lit); + pGen->genOp(OP_PLUS); + break; + default: + error("++/-- illegal for this type."); + break; + } + + pGen->storeR0ToTOS(); pGen->popR0(); next(); + } else { + pGen->loadR0(n, pVI->pType); } } } @@ -4078,28 +4174,6 @@ class Compiler : public ErrorSink { } } - /* Increment / decrement R0 */ - - void impInc(int op) { - Type* pType = pGen->getR0Type(); - int lit = 1; - if (op == OP_DECREMENT) { - lit = -1; - } - switch (pType->tag) { - case TY_INT: - case TY_CHAR: - case TY_POINTER: - pGen->pushR0(); - pGen->li(lit); - pGen->genOp(OP_PLUS); - break; - default: - error("++/-- illegal for this type."); - break; - } - } - /* Recursive descent parser for binary operations. */ void binaryOp(int level) { diff --git a/libacc/tests/data/inc.c b/libacc/tests/data/inc.c new file mode 100644 index 0000000..eda3659 --- /dev/null +++ b/libacc/tests/data/inc.c @@ -0,0 +1,10 @@ +// Check integer operations + +int main() { + int a = 0; + printf("%d\n", a++); + printf("%d\n", a++); + printf("%d\n", a--); + printf("%d\n", a--); + return a; +} diff --git a/libacc/tests/test.py b/libacc/tests/test.py index 2a20696..eafe442 100644 --- a/libacc/tests/test.py +++ b/libacc/tests/test.py @@ -287,6 +287,15 @@ result: 10""", """""") self.compileCheck(["-R", "data/floatdouble.c"], """Executing compiled code: result: 0""", """0.002 0.1 10""") + def testIncDec(self): + self.compileCheck(["-R", "data/inc.c"], """Executing compiled code: +0 +1 +2 +1 +result: 0 +""","""""") + def testIops(self): self.compileCheck(["-R", "data/iops.c"], """Executing compiled code: result: 0""", """Literals: 1 -1 |