summaryrefslogtreecommitdiffstats
path: root/libacc
diff options
context:
space:
mode:
authorJack Palevich <jackpal@google.com>2009-07-29 10:28:18 -0700
committerJack Palevich <jackpal@google.com>2009-07-29 10:28:18 -0700
commitddf7c9c14184acffe5ac33d06389cf733cfe11da (patch)
treeb60fb8d0f963df5166a6fdb7f97e35715afc5cec /libacc
parent7fcdf1c5f8f25228bf348be9360594679329616f (diff)
downloadsystem_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.cpp138
-rw-r--r--libacc/tests/data/inc.c10
-rw-r--r--libacc/tests/test.py9
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