Loading libacc/acc.cpp +48 −10 Original line number Diff line number Diff line Loading @@ -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); } Loading Loading @@ -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); Loading Loading @@ -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(); Loading Loading @@ -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); } Loading Loading @@ -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) { Loading Loading @@ -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."); Loading @@ -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(')'); Loading Loading @@ -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); Loading libacc/tests/data/float.c +5 −1 Original line number Diff line number Diff line Loading @@ -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() { Loading libacc/tests/data/flops.c +11 −0 Original line number Diff line number Diff line Loading @@ -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; } Loading
libacc/acc.cpp +48 −10 Original line number Diff line number Diff line Loading @@ -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); } Loading Loading @@ -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); Loading Loading @@ -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(); Loading Loading @@ -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); } Loading Loading @@ -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) { Loading Loading @@ -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."); Loading @@ -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(')'); Loading Loading @@ -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); Loading
libacc/tests/data/float.c +5 −1 Original line number Diff line number Diff line Loading @@ -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() { Loading
libacc/tests/data/flops.c +11 −0 Original line number Diff line number Diff line Loading @@ -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; }