Loading libacc/acc.cpp +106 −32 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. Loading Loading @@ -541,6 +549,7 @@ class Compiler : public ErrorSink { } void setR0Type(Type* pType) { assert(pType != NULL); mExpressionStack.back().pType = pType; } Loading @@ -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(); } Loading Loading @@ -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)){ Loading Loading @@ -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); Loading @@ -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(); Loading Loading @@ -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(); Loading Loading @@ -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 Loading Loading @@ -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); } } } Loading Loading @@ -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) { Loading libacc/tests/data/inc.c 0 → 100644 +10 −0 Original line number Diff line number Diff line // 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; } libacc/tests/test.py +9 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading
libacc/acc.cpp +106 −32 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. Loading Loading @@ -541,6 +549,7 @@ class Compiler : public ErrorSink { } void setR0Type(Type* pType) { assert(pType != NULL); mExpressionStack.back().pType = pType; } Loading @@ -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(); } Loading Loading @@ -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)){ Loading Loading @@ -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); Loading @@ -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(); Loading Loading @@ -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(); Loading Loading @@ -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 Loading Loading @@ -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); } } } Loading Loading @@ -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) { Loading
libacc/tests/data/inc.c 0 → 100644 +10 −0 Original line number Diff line number Diff line // 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; }
libacc/tests/test.py +9 −0 Original line number Diff line number Diff line Loading @@ -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 Loading