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

Commit 02393118 authored by Android (Google) Code Review's avatar Android (Google) Code Review
Browse files

Merge change 6551

* changes:
  Implement global, local, and stack based float and double variables.
parents e86161de 9cbd2269
Loading
Loading
Loading
Loading
+111 −27
Original line number Diff line number Diff line
@@ -360,7 +360,7 @@ class Compiler : public ErrorSink {
         * argument, addressed relative to FP.
         * else it is an absolute global address.
         */
        virtual void storeR0(int ea) = 0;
        virtual void storeR0(int ea, Type* pType) = 0;

        /* load R0 from a variable.
         * If ea <= LOCAL, then this is a local variable, or an
@@ -449,15 +449,20 @@ class Compiler : public ErrorSink {
        virtual int jumpOffset() = 0;

        /**
         * Stack alignment (in bytes) for this type of data
         * Memory alignment (in bytes) for this type of data
         */
        virtual size_t stackAlignment(Type* type) = 0;
        virtual size_t alignment(Type* type) = 0;

        /**
         * Array element alignment (in bytes) for this type of data.
         */
        virtual size_t sizeOf(Type* type) = 0;

        /**
         * Stack argument size of this data type.
         */
        virtual size_t stackSizeOf(Type* pType) = 0;

        virtual Type* getR0Type() {
            return mExpressionStack.back();
        }
@@ -823,7 +828,7 @@ class Compiler : public ErrorSink {
            setR0Type(pPointerType);
        }

        virtual void storeR0(int ea) {
        virtual void storeR0(int ea, Type* pType) {
            LOG_API("storeR0(%d);\n", ea);
            if (ea < LOCAL) {
                // Local, fp relative
@@ -1056,9 +1061,9 @@ class Compiler : public ErrorSink {
        }

        /**
         * Stack alignment (in bytes) for this type of data
         * alignment (in bytes) for this type of data
         */
        virtual size_t stackAlignment(Type* pType){
        virtual size_t alignment(Type* pType){
            switch(pType->tag) {
                case TY_DOUBLE:
                    return 8;
@@ -1086,6 +1091,16 @@ class Compiler : public ErrorSink {
                    return 4;
            }
        }

        virtual size_t stackSizeOf(Type* pType) {
            switch(pType->tag) {
                case TY_DOUBLE:
                    return 8;
                default:
                    return 4;
            }
        }

    private:
        static FILE* disasmOut;

@@ -1238,7 +1253,25 @@ class Compiler : public ErrorSink {
        }

        virtual void pushR0() {
            Type* pR0Type = getR0Type();
            TypeTag r0ct = collapseType(pR0Type->tag);
            switch(r0ct) {
                case TY_INT:
                    o(0x50); /* push %eax */
                    break;
                case TY_FLOAT:
                    o(0x50); /* push %eax */
                    o(0x241cd9); // fstps 0(%esp)
                    break;
                case TY_DOUBLE:
                    o(0x50); /* push %eax */
                    o(0x50); /* push %eax */
                    o(0x241cdd); // fstpl 0(%esp)
                    break;
                default:
                    error("pushR0 %d", r0ct);
                    break;
            }
            pushType();
        }

@@ -1253,6 +1286,12 @@ class Compiler : public ErrorSink {
                case TY_CHAR:
                    o(0x0188); /* movl %eax/%al, (%ecx) */
                    break;
                case TY_FLOAT:
                    o(0x19d9); /* fstps (%ecx) */
                    break;
                case TY_DOUBLE:
                    o(0x19dd); /* fstpl (%ecx) */
                    break;
                default:
                    error("storeR0ToTOS: unsupported type");
                    break;
@@ -1281,8 +1320,30 @@ class Compiler : public ErrorSink {
            setR0Type(pPointerType);
        }

        virtual void storeR0(int ea) {
        virtual void storeR0(int ea, Type* pType) {
            TypeTag tag = pType->tag;
            switch (tag) {
                case TY_INT:
                    gmov(6, ea); /* mov %eax, EA */
                    break;
                case TY_FLOAT:
                    if (ea < -LOCAL || ea > LOCAL) {
                        oad(0x1dd9, ea); // fstps ea
                    } else {
                        oad(0x9dd9, ea); // fstps ea(%ebp)
                    }
                    break;
                case TY_DOUBLE:
                    if (ea < -LOCAL || ea > LOCAL) {
                        oad(0x1ddd, ea); // fstpl ea
                    } else {
                        oad(0x9ddd, ea); // fstpl ea(%ebp)
                    }
                    break;
                default:
                    error("Unable to store to type %d", tag);
                    break;
            }
        }

        virtual void loadR0(int ea, bool isIncDec, int op, Type* pType) {
@@ -1448,9 +1509,9 @@ class Compiler : public ErrorSink {
        }

        /**
         * Stack alignment (in bytes) for this type of data
         * Alignment (in bytes) for this type of data
         */
        virtual size_t stackAlignment(Type* pType){
        virtual size_t alignment(Type* pType){
            switch(pType->tag) {
                case TY_DOUBLE:
                    return 8;
@@ -1479,6 +1540,15 @@ class Compiler : public ErrorSink {
            }
        }

        virtual size_t stackSizeOf(Type* pType) {
            switch(pType->tag) {
                case TY_DOUBLE:
                    return 8;
                default:
                    return 4;
            }
        }

    private:

        /** Output 1 to 4 bytes.
@@ -1626,9 +1696,9 @@ class Compiler : public ErrorSink {
            mpBase->leaR0(ea, pPointerType);
        }

        virtual void storeR0(int ea) {
            fprintf(stderr, "storeR0(%d)\n", ea);
            mpBase->storeR0(ea);
        virtual void storeR0(int ea, Type* pType) {
            fprintf(stderr, "storeR0(%d, pType)\n", ea);
            mpBase->storeR0(ea, pType);
        }

        virtual void loadR0(int ea, bool isIncDec, int op, Type* pType) {
@@ -1699,10 +1769,10 @@ class Compiler : public ErrorSink {
        }

        /**
         * Stack alignment (in bytes) for this type of data
         * Alignment (in bytes) for this type of data
         */
        virtual size_t stackAlignment(Type* pType){
            return mpBase->stackAlignment(pType);
        virtual size_t alignment(Type* pType){
            return mpBase->alignment(pType);
        }

        /**
@@ -1712,6 +1782,12 @@ class Compiler : public ErrorSink {
            return mpBase->sizeOf(pType);
        }


        virtual size_t stackSizeOf(Type* pType) {
            return mpBase->stackSizeOf(pType);
        }


        virtual Type* getR0Type() {
            return mpBase->getR0Type();
        }
@@ -2795,7 +2871,7 @@ class Compiler : public ErrorSink {
            // This while loop merges multiple adjacent string constants.
            while (tok == '"') {
                while (ch != '"' && ch != EOF) {
                    *allocGlobalSpace(1) = getq();
                    *allocGlobalSpace(1,1) = getq();
                }
                if (ch != '"') {
                    error("Unterminated string constant.");
@@ -2806,7 +2882,7 @@ class Compiler : public ErrorSink {
            /* Null terminate */
            *glo = 0;
            /* align heap */
            allocGlobalSpace((char*) (((intptr_t) glo + 4) & -4) - glo);
            allocGlobalSpace(1,(char*) (((intptr_t) glo + 4) & -4) - glo);

            return true;
        }
@@ -2864,6 +2940,10 @@ class Compiler : public ErrorSink {
                    t = TOK_INT;
                } else if (typeEqual(pCast, mkpCharPtr)) {
                    t = TOK_CHAR;
                } else if (typeEqual(pCast, mkpFloatPtr)) {
                    t = TOK_FLOAT;
                } else if (typeEqual(pCast, mkpDoublePtr)) {
                    t = TOK_DOUBLE;
                } else if (typeEqual(pCast, mkpPtrIntFn)){
                    t = 0;
                } else {
@@ -2914,7 +2994,7 @@ class Compiler : public ErrorSink {
                    /* assignment */
                    next();
                    expr();
                    pGen->storeR0(n);
                    pGen->storeR0(n, pVI->pType);
                } else if (tok != '(') {
                    /* variable */
                    if (!n) {
@@ -3445,7 +3525,7 @@ class Compiler : public ErrorSink {
                if (accept('=')) {
                    /* assignment */
                    expr();
                    pGen->storeR0(variableAddress);
                    pGen->storeR0(variableAddress, pDecl);
                }
                if (tok == ',')
                    next();
@@ -3517,7 +3597,9 @@ class Compiler : public ErrorSink {
                // it's a variable declaration
                for(;;) {
                    if (name && !name->pAddress) {
                        name->pAddress = (int*) allocGlobalSpace(4);
                        name->pAddress = (int*) allocGlobalSpace(
                                                   pGen->alignment(name->pType),
                                                   pGen->sizeOf(name->pType));
                    }
                    if (accept('=')) {
                        if (tok == TOK_NUM) {
@@ -3563,7 +3645,7 @@ class Compiler : public ErrorSink {
                        addLocalSymbol(pArg);
                        /* read param name and compute offset */
                        VI(pArg->id)->pAddress = (void*) a;
                        a = a + 4;
                        a = a + pGen->stackSizeOf(pArg);
                        argCount++;
                    }
                    rsym = loc = 0;
@@ -3578,13 +3660,15 @@ class Compiler : public ErrorSink {
        }
    }

    char* allocGlobalSpace(int bytes) {
        if (glo - pGlobalBase + bytes > ALLOC_SIZE) {
    char* allocGlobalSpace(size_t alignment, size_t bytes) {
        size_t base = (((size_t) glo) + alignment - 1) & ~(alignment-1);
        size_t end = base + bytes;
        if ((end - (size_t) pGlobalBase) > ALLOC_SIZE) {
            error("Global space exhausted");
            return NULL;
        }
        char* result = glo;
        glo += bytes;
        char* result = (char*) base;
        glo = (char*) end;
        return result;
    }

+24 −0
Original line number Diff line number Diff line
@@ -14,11 +14,35 @@ double itod(int i) {
    return i;
}

float f0, f1;
double d0, d1;

void testVars(float arg0, float arg1, double arg2, double arg3) {
    float local0, local1;
    double local2, local3;
    f0 = arg0;
    f1 = arg1;
    d0 = arg2;
    d1 = arg3;
    local0 = arg0;
    local1 = arg1;
    local2 = arg2;
    local3 = arg3;
    printf("globals: %g %g %g %g\n", f0, f1, d0, d1);
    printf("args: %g %g %g %g\n", arg0, arg1, arg2, arg3);
    printf("locals: %g %g %g %g\n", local0, local1, local2, local3);

    * (float*) & f0 = 1.1f;
    * (double*) & d0 = 3.3;
    printf("pointer tests: %g %g %g %g\n", f0, f1, d0, d1);
}

int main() {
    printf("int: %d float: %g double: %g\n", 1, 2.2f, 3.3);
    printf(" ftoi(1.4f)=%d\n", ftoi(1.4f));
    printf(" dtoi(2.4f)=%d\n", dtoi(2.4f));
    printf(" itof(3)=%g\n", itof(3));
    printf(" itod(4)=%g\n", itod(4));
    testVars(1.0f, 2.0f, 3.0, 4.0);
    return 0;
}