Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ddf7c9c1 authored by Jack Palevich's avatar Jack Palevich
Browse files

Implement inc/dec in a more lval-friendly way.

parent 7fcdf1c5
Loading
Loading
Loading
Loading
+106 −32
Original line number Diff line number Diff line
@@ -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) {
+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;
}
+9 −0
Original line number Diff line number Diff line
@@ -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