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

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

Merge change 6658

* changes:
  Finish implementing x86 floating point
parents 5b633990 2a4e1a9f
Loading
Loading
Loading
Loading
+48 −10
Original line number Diff line number Diff line
@@ -1213,7 +1213,19 @@ class Compiler : public ErrorSink {

        /* l = 0: je, l == 1: jne */
        virtual int gtst(bool l, int t) {
            o(0x0fc085); /* test %eax, %eax, je/jne xxx */
            Type* pR0Type = getR0Type();
            TypeTag tagR0 = pR0Type->tag;
            bool isFloatR0 = isFloatTag(tagR0);
            if (isFloatR0) {
                o(0xeed9); // fldz
                o(0xe9da); // fucompp
                o(0xe0df); // fnstsw %ax
                o(0x9e);   // sahf
            } else {
                o(0xc085); // test %eax, %eax
            }
            // Use two output statements to generate one instruction.
            o(0x0f);   // je/jne xxx
            return psym(0x84 + l, t);
        }

@@ -1327,8 +1339,6 @@ class Compiler : public ErrorSink {
            }
        }



        virtual void gUnaryCmp(int op, Type* pResultType) {
            if (op != OP_LOGICAL_NOT) {
                error("Unknown unary cmp %d", op);
@@ -1411,7 +1421,7 @@ class Compiler : public ErrorSink {
                    o(0x241cdd); // fstpl 0(%esp)
                    break;
                default:
                    error("pushR0 %d", r0ct);
                    error("pushR0 unsupported type %d", r0ct);
                    break;
            }
            pushType();
@@ -1444,16 +1454,22 @@ class Compiler : public ErrorSink {
            assert(pPointerType->tag == TY_POINTER);
            switch (pPointerType->pHead->tag) {
                case TY_INT:
                    o(0x8b); /* mov (%eax), %eax */
                    o2(0x008b); /* mov (%eax), %eax */
                    break;
                case TY_CHAR:
                    o(0xbe0f); /* movsbl (%eax), %eax */
                    ob(0); /* add zero in code */
                    break;
                case TY_FLOAT:
                    o2(0x00d9); // flds (%eax)
                    break;
                case TY_DOUBLE:
                    o2(0x00dd); // fldl (%eax)
                    break;
                default:
                    error("loadR0FromR0: unsupported type");
                    break;
            }
            ob(0); /* add zero in code */
            setR0Type(pPointerType->pHead);
        }

@@ -1704,6 +1720,13 @@ class Compiler : public ErrorSink {
            }
        }

        /* Output exactly 2 bytes
         */
        void o2(int n) {
            ob(n & 0xff);
            ob(0xff & (n >> 8));
        }

        /* psym is used to put an instruction with a data field which is a
         reference to a symbol. It is in fact the same as oad ! */
        int psym(int n, int t) {
@@ -3197,6 +3220,7 @@ class Compiler : public ErrorSink {
            /* push args and invert order */
            a = pGen->beginFunctionCallArguments();
            int l = 0;
            int argCount = 0;
            while (tok != ')' && tok != EOF) {
                if (! varArgs && !pArgList) {
                    error ("Unexpected argument.");
@@ -3212,16 +3236,22 @@ class Compiler : public ErrorSink {
                        pTargetType = mkpDouble;
                    }
                }
                if (pTargetType->tag == TY_VOID) {
                    error("Can't pass void value for argument %d",
                          argCount + 1);
                } else {
                    pGen->convertR0(pTargetType);
                    l += pGen->storeR0ToArg(l);
                }
                if (accept(',')) {
                    // fine
                } else if ( tok != ')') {
                    error("Expected ',' or ')'");
                }
                argCount += 1;
            }
            if (! varArgs && pArgList) {
                error ("Expected more argument(s).");
                error ("Expected more argument(s). Saw %d", argCount);
            }
            pGen->endFunctionCallArguments(a, l);
            skip(')');
@@ -3353,8 +3383,16 @@ class Compiler : public ErrorSink {
            if (accept(TOK_RETURN)) {
                if (tok != ';') {
                    expr();
                    if (pReturnType->tag == TY_VOID) {
                        error("Must not return a value from a void function");
                    } else {
                        pGen->convertR0(pReturnType);
                    }
                } else {
                    if (pReturnType->tag != TY_VOID) {
                        error("Must specify a value here");
                    }
                }
                rsym = pGen->gjmp(rsym); /* jmp */
            } else if (accept(TOK_BREAK)) {
                *(int *) l = pGen->gjmp(*(int *) l);
+5 −1
Original line number Diff line number Diff line
@@ -32,9 +32,13 @@ void testVars(float arg0, float arg1, double arg2, double arg3) {
    printf("args: %g %g %g %g\n", arg0, arg1, arg2, arg3);
    printf("locals: %g %g %g %g\n", local0, local1, local2, local3);


    printf("cast rval: %g %g\n", * (float*) & f1, * (double*) & d1);

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

}

int main() {
+11 −0
Original line number Diff line number Diff line
@@ -106,10 +106,21 @@ void comparisonOps() {
    comparisonOpsdi();
}

int branch(double d) {
    if (d) {
        return 1;
    }
    return 0;
}

void testBranching() {
    printf("branching: %d %d %d\n", branch(-1.0), branch(0.0), branch(1.0));
}

int main() {
    unaryOps();
    binaryOps();
    comparisonOps();
    testBranching();
    return 0;
}