system/corennnnn
Revision | a0c0d8a89e1cd775d0ecf5a3df744d8ac0ccfc2f (tree) |
---|---|
Time | 2009-07-10 05:36:07 |
Author | Android (Google) Code Review <android-gerrit@goog...> |
Commiter | Android (Google) Code Review |
Merge change 6658
* changes:
@@ -1213,7 +1213,19 @@ class Compiler : public ErrorSink { | ||
1213 | 1213 | |
1214 | 1214 | /* l = 0: je, l == 1: jne */ |
1215 | 1215 | 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 | |
1217 | 1229 | return psym(0x84 + l, t); |
1218 | 1230 | } |
1219 | 1231 |
@@ -1327,8 +1339,6 @@ class Compiler : public ErrorSink { | ||
1327 | 1339 | } |
1328 | 1340 | } |
1329 | 1341 | |
1330 | - | |
1331 | - | |
1332 | 1342 | virtual void gUnaryCmp(int op, Type* pResultType) { |
1333 | 1343 | if (op != OP_LOGICAL_NOT) { |
1334 | 1344 | error("Unknown unary cmp %d", op); |
@@ -1411,7 +1421,7 @@ class Compiler : public ErrorSink { | ||
1411 | 1421 | o(0x241cdd); // fstpl 0(%esp) |
1412 | 1422 | break; |
1413 | 1423 | default: |
1414 | - error("pushR0 %d", r0ct); | |
1424 | + error("pushR0 unsupported type %d", r0ct); | |
1415 | 1425 | break; |
1416 | 1426 | } |
1417 | 1427 | pushType(); |
@@ -1444,16 +1454,22 @@ class Compiler : public ErrorSink { | ||
1444 | 1454 | assert(pPointerType->tag == TY_POINTER); |
1445 | 1455 | switch (pPointerType->pHead->tag) { |
1446 | 1456 | case TY_INT: |
1447 | - o(0x8b); /* mov (%eax), %eax */ | |
1457 | + o2(0x008b); /* mov (%eax), %eax */ | |
1448 | 1458 | break; |
1449 | 1459 | case TY_CHAR: |
1450 | 1460 | 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) | |
1451 | 1468 | break; |
1452 | 1469 | default: |
1453 | 1470 | error("loadR0FromR0: unsupported type"); |
1454 | 1471 | break; |
1455 | 1472 | } |
1456 | - ob(0); /* add zero in code */ | |
1457 | 1473 | setR0Type(pPointerType->pHead); |
1458 | 1474 | } |
1459 | 1475 |
@@ -1704,6 +1720,13 @@ class Compiler : public ErrorSink { | ||
1704 | 1720 | } |
1705 | 1721 | } |
1706 | 1722 | |
1723 | + /* Output exactly 2 bytes | |
1724 | + */ | |
1725 | + void o2(int n) { | |
1726 | + ob(n & 0xff); | |
1727 | + ob(0xff & (n >> 8)); | |
1728 | + } | |
1729 | + | |
1707 | 1730 | /* psym is used to put an instruction with a data field which is a |
1708 | 1731 | reference to a symbol. It is in fact the same as oad ! */ |
1709 | 1732 | int psym(int n, int t) { |
@@ -3197,6 +3220,7 @@ class Compiler : public ErrorSink { | ||
3197 | 3220 | /* push args and invert order */ |
3198 | 3221 | a = pGen->beginFunctionCallArguments(); |
3199 | 3222 | int l = 0; |
3223 | + int argCount = 0; | |
3200 | 3224 | while (tok != ')' && tok != EOF) { |
3201 | 3225 | if (! varArgs && !pArgList) { |
3202 | 3226 | error ("Unexpected argument."); |
@@ -3212,16 +3236,22 @@ class Compiler : public ErrorSink { | ||
3212 | 3236 | pTargetType = mkpDouble; |
3213 | 3237 | } |
3214 | 3238 | } |
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 | + } | |
3217 | 3246 | if (accept(',')) { |
3218 | 3247 | // fine |
3219 | 3248 | } else if ( tok != ')') { |
3220 | 3249 | error("Expected ',' or ')'"); |
3221 | 3250 | } |
3251 | + argCount += 1; | |
3222 | 3252 | } |
3223 | 3253 | if (! varArgs && pArgList) { |
3224 | - error ("Expected more argument(s)."); | |
3254 | + error ("Expected more argument(s). Saw %d", argCount); | |
3225 | 3255 | } |
3226 | 3256 | pGen->endFunctionCallArguments(a, l); |
3227 | 3257 | skip(')'); |
@@ -3353,7 +3383,15 @@ class Compiler : public ErrorSink { | ||
3353 | 3383 | if (accept(TOK_RETURN)) { |
3354 | 3384 | if (tok != ';') { |
3355 | 3385 | 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 | + } | |
3357 | 3395 | } |
3358 | 3396 | rsym = pGen->gjmp(rsym); /* jmp */ |
3359 | 3397 | } else if (accept(TOK_BREAK)) { |
@@ -32,9 +32,13 @@ void testVars(float arg0, float arg1, double arg2, double arg3) { | ||
32 | 32 | printf("args: %g %g %g %g\n", arg0, arg1, arg2, arg3); |
33 | 33 | printf("locals: %g %g %g %g\n", local0, local1, local2, local3); |
34 | 34 | |
35 | + | |
36 | + printf("cast rval: %g %g\n", * (float*) & f1, * (double*) & d1); | |
37 | + | |
35 | 38 | * (float*) & f0 = 1.1f; |
36 | 39 | * (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 | + | |
38 | 42 | } |
39 | 43 | |
40 | 44 | int main() { |
@@ -106,10 +106,21 @@ void comparisonOps() { | ||
106 | 106 | comparisonOpsdi(); |
107 | 107 | } |
108 | 108 | |
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 | +} | |
109 | 119 | |
110 | 120 | int main() { |
111 | 121 | unaryOps(); |
112 | 122 | binaryOps(); |
113 | 123 | comparisonOps(); |
124 | + testBranching(); | |
114 | 125 | return 0; |
115 | 126 | } |