• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

system/corennnnn


Commit MetaInfo

Revisiona0c0d8a89e1cd775d0ecf5a3df744d8ac0ccfc2f (tree)
Time2009-07-10 05:36:07
AuthorAndroid (Google) Code Review <android-gerrit@goog...>
CommiterAndroid (Google) Code Review

Log Message

Merge change 6658

* changes:

Finish implementing x86 floating point

Change Summary

Incremental Difference

--- a/libacc/acc.cpp
+++ b/libacc/acc.cpp
@@ -1213,7 +1213,19 @@ class Compiler : public ErrorSink {
12131213
12141214 /* l = 0: je, l == 1: jne */
12151215 virtual int gtst(bool l, int t) {
1216- o(0x0fc085); /* test %eax, %eax, je/jne xxx */
1216+ Type* pR0Type = getR0Type();
1217+ TypeTag tagR0 = pR0Type->tag;
1218+ bool isFloatR0 = isFloatTag(tagR0);
1219+ if (isFloatR0) {
1220+ o(0xeed9); // fldz
1221+ o(0xe9da); // fucompp
1222+ o(0xe0df); // fnstsw %ax
1223+ o(0x9e); // sahf
1224+ } else {
1225+ o(0xc085); // test %eax, %eax
1226+ }
1227+ // Use two output statements to generate one instruction.
1228+ o(0x0f); // je/jne xxx
12171229 return psym(0x84 + l, t);
12181230 }
12191231
@@ -1327,8 +1339,6 @@ class Compiler : public ErrorSink {
13271339 }
13281340 }
13291341
1330-
1331-
13321342 virtual void gUnaryCmp(int op, Type* pResultType) {
13331343 if (op != OP_LOGICAL_NOT) {
13341344 error("Unknown unary cmp %d", op);
@@ -1411,7 +1421,7 @@ class Compiler : public ErrorSink {
14111421 o(0x241cdd); // fstpl 0(%esp)
14121422 break;
14131423 default:
1414- error("pushR0 %d", r0ct);
1424+ error("pushR0 unsupported type %d", r0ct);
14151425 break;
14161426 }
14171427 pushType();
@@ -1444,16 +1454,22 @@ class Compiler : public ErrorSink {
14441454 assert(pPointerType->tag == TY_POINTER);
14451455 switch (pPointerType->pHead->tag) {
14461456 case TY_INT:
1447- o(0x8b); /* mov (%eax), %eax */
1457+ o2(0x008b); /* mov (%eax), %eax */
14481458 break;
14491459 case TY_CHAR:
14501460 o(0xbe0f); /* movsbl (%eax), %eax */
1461+ ob(0); /* add zero in code */
1462+ break;
1463+ case TY_FLOAT:
1464+ o2(0x00d9); // flds (%eax)
1465+ break;
1466+ case TY_DOUBLE:
1467+ o2(0x00dd); // fldl (%eax)
14511468 break;
14521469 default:
14531470 error("loadR0FromR0: unsupported type");
14541471 break;
14551472 }
1456- ob(0); /* add zero in code */
14571473 setR0Type(pPointerType->pHead);
14581474 }
14591475
@@ -1704,6 +1720,13 @@ class Compiler : public ErrorSink {
17041720 }
17051721 }
17061722
1723+ /* Output exactly 2 bytes
1724+ */
1725+ void o2(int n) {
1726+ ob(n & 0xff);
1727+ ob(0xff & (n >> 8));
1728+ }
1729+
17071730 /* psym is used to put an instruction with a data field which is a
17081731 reference to a symbol. It is in fact the same as oad ! */
17091732 int psym(int n, int t) {
@@ -3197,6 +3220,7 @@ class Compiler : public ErrorSink {
31973220 /* push args and invert order */
31983221 a = pGen->beginFunctionCallArguments();
31993222 int l = 0;
3223+ int argCount = 0;
32003224 while (tok != ')' && tok != EOF) {
32013225 if (! varArgs && !pArgList) {
32023226 error ("Unexpected argument.");
@@ -3212,16 +3236,22 @@ class Compiler : public ErrorSink {
32123236 pTargetType = mkpDouble;
32133237 }
32143238 }
3215- pGen->convertR0(pTargetType);
3216- l += pGen->storeR0ToArg(l);
3239+ if (pTargetType->tag == TY_VOID) {
3240+ error("Can't pass void value for argument %d",
3241+ argCount + 1);
3242+ } else {
3243+ pGen->convertR0(pTargetType);
3244+ l += pGen->storeR0ToArg(l);
3245+ }
32173246 if (accept(',')) {
32183247 // fine
32193248 } else if ( tok != ')') {
32203249 error("Expected ',' or ')'");
32213250 }
3251+ argCount += 1;
32223252 }
32233253 if (! varArgs && pArgList) {
3224- error ("Expected more argument(s).");
3254+ error ("Expected more argument(s). Saw %d", argCount);
32253255 }
32263256 pGen->endFunctionCallArguments(a, l);
32273257 skip(')');
@@ -3353,7 +3383,15 @@ class Compiler : public ErrorSink {
33533383 if (accept(TOK_RETURN)) {
33543384 if (tok != ';') {
33553385 expr();
3356- pGen->convertR0(pReturnType);
3386+ if (pReturnType->tag == TY_VOID) {
3387+ error("Must not return a value from a void function");
3388+ } else {
3389+ pGen->convertR0(pReturnType);
3390+ }
3391+ } else {
3392+ if (pReturnType->tag != TY_VOID) {
3393+ error("Must specify a value here");
3394+ }
33573395 }
33583396 rsym = pGen->gjmp(rsym); /* jmp */
33593397 } else if (accept(TOK_BREAK)) {
--- a/libacc/tests/data/float.c
+++ b/libacc/tests/data/float.c
@@ -32,9 +32,13 @@ void testVars(float arg0, float arg1, double arg2, double arg3) {
3232 printf("args: %g %g %g %g\n", arg0, arg1, arg2, arg3);
3333 printf("locals: %g %g %g %g\n", local0, local1, local2, local3);
3434
35+
36+ printf("cast rval: %g %g\n", * (float*) & f1, * (double*) & d1);
37+
3538 * (float*) & f0 = 1.1f;
3639 * (double*) & d0 = 3.3;
37- printf("pointer tests: %g %g %g %g\n", f0, f1, d0, d1);
40+ printf("cast lval: %g %g %g %g\n", f0, f1, d0, d1);
41+
3842 }
3943
4044 int main() {
--- a/libacc/tests/data/flops.c
+++ b/libacc/tests/data/flops.c
@@ -106,10 +106,21 @@ void comparisonOps() {
106106 comparisonOpsdi();
107107 }
108108
109+int branch(double d) {
110+ if (d) {
111+ return 1;
112+ }
113+ return 0;
114+}
115+
116+void testBranching() {
117+ printf("branching: %d %d %d\n", branch(-1.0), branch(0.0), branch(1.0));
118+}
109119
110120 int main() {
111121 unaryOps();
112122 binaryOps();
113123 comparisonOps();
124+ testBranching();
114125 return 0;
115126 }