• R/O
  • HTTP
  • SSH
  • HTTPS

コミット

タグ
未設定

よく使われているワード(クリックで追加)

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

system/corennnnn


コミットメタ情報

リビジョン304176c90984efc0bda9d01ad07ea0c92af822bb (tree)
日時2009-08-05 06:56:12
作者Android (Google) Code Review <android-gerrit@goog...>
コミッターAndroid (Google) Code Review

ログメッセージ

Merge change 20014

* changes:

Implement arrays.

変更サマリ

差分

--- a/libacc/acc.cpp
+++ b/libacc/acc.cpp
@@ -139,16 +139,17 @@ class Compiler : public ErrorSink {
139139 TY_VOID, // 3
140140 TY_FLOAT, // 4
141141 TY_DOUBLE, // 5
142- TY_POINTER, // 6
143- TY_ARRAY, // 7
144- TY_STRUCT, // 8
145- TY_FUNC, // 9
146- TY_PARAM // 10
142+ TY_POINTER, // 6
143+ TY_ARRAY, // 7
144+ TY_STRUCT, // 8
145+ TY_FUNC, // 9
146+ TY_PARAM // 10
147147 };
148148
149149 struct Type {
150150 TypeTag tag;
151- tokenid_t id; // For function arguments (stores length for array)
151+ tokenid_t id; // For function arguments, local vars
152+ int length; // length of array
152153 Type* pHead;
153154 Type* pTail;
154155 };
@@ -405,7 +406,16 @@ class Compiler : public ErrorSink {
405406 /**
406407 * Convert R0 to the given type.
407408 */
408- virtual void convertR0(Type* pType) = 0;
409+
410+ void convertR0(Type* pType) {
411+ convertR0Imp(pType, false);
412+ }
413+
414+ void castR0(Type* pType) {
415+ convertR0Imp(pType, true);
416+ }
417+
418+ virtual void convertR0Imp(Type* pType, bool isCast) = 0;
409419
410420 /* Emit code to adjust the stack for a function call. Return the
411421 * label for the address of the instruction that adjusts the
@@ -622,14 +632,40 @@ class Compiler : public ErrorSink {
622632 return collapseType(getR0Type()->tag);
623633 }
624634
625- bool isFloatType(Type* pType) {
635+ static bool isFloatType(Type* pType) {
626636 return isFloatTag(pType->tag);
627637 }
628638
629- bool isFloatTag(TypeTag tag) {
639+ static bool isFloatTag(TypeTag tag) {
630640 return tag == TY_FLOAT || tag == TY_DOUBLE;
631641 }
632642
643+ static bool isPointerType(Type* pType) {
644+ return isPointerTag(pType->tag);
645+ }
646+
647+ static bool isPointerTag(TypeTag tag) {
648+ return tag == TY_POINTER || tag == TY_ARRAY;
649+ }
650+
651+ Type* getPointerArithmeticResultType(Type* a, Type* b) {
652+ TypeTag aTag = a->tag;
653+ TypeTag bTag = b->tag;
654+ if (aTag == TY_POINTER) {
655+ return a;
656+ }
657+ if (bTag == TY_POINTER) {
658+ return b;
659+ }
660+ if (aTag == TY_ARRAY) {
661+ return a->pTail;
662+ }
663+ if (bTag == TY_ARRAY) {
664+ return b->pTail;
665+ }
666+ return NULL;
667+ }
668+
633669 Type* mkpInt;
634670
635671 private:
@@ -848,8 +884,8 @@ class Compiler : public ErrorSink {
848884 bool isFloatTOS = isFloatTag(tagTOS);
849885 if (!isFloatR0 && !isFloatTOS) {
850886 setupIntPtrArgs();
851- bool isPtrR0 = tagR0 == TY_POINTER;
852- bool isPtrTOS = tagTOS == TY_POINTER;
887+ bool isPtrR0 = isPointerTag(tagR0);
888+ bool isPtrTOS = isPointerTag(tagTOS);
853889 if (isPtrR0 || isPtrTOS) {
854890 if (isPtrR0 && isPtrTOS) {
855891 if (op != OP_MINUS) {
@@ -871,7 +907,8 @@ class Compiler : public ErrorSink {
871907 if (! (op == OP_PLUS || (op == OP_MINUS && isPtrR0))) {
872908 error("Unsupported pointer-scalar operation %d", op);
873909 }
874- Type* pPtrType = isPtrR0 ? pR0Type : pTOSType;
910+ Type* pPtrType = getPointerArithmeticResultType(
911+ pR0Type, pTOSType);
875912 int size = sizeOf(pPtrType->pHead);
876913 if (size != 1) {
877914 // TODO: Optimize for power-of-two.
@@ -1131,7 +1168,8 @@ class Compiler : public ErrorSink {
11311168 virtual void loadR0FromR0() {
11321169 Type* pPointerType = getR0Type();
11331170 assert(pPointerType->tag == TY_POINTER);
1134- switch (pPointerType->pHead->tag) {
1171+ TypeTag tag = pPointerType->pHead->tag;
1172+ switch (tag) {
11351173 case TY_POINTER:
11361174 case TY_INT:
11371175 case TY_FLOAT:
@@ -1147,7 +1185,7 @@ class Compiler : public ErrorSink {
11471185 o4(0xE1C000D0); // ldrd r0, [r0]
11481186 break;
11491187 default:
1150- error("loadR0FromR0: unimplemented type");
1188+ error("loadR0FromR0: unimplemented type %d", tag);
11511189 break;
11521190 }
11531191 setR0Type(pPointerType->pHead);
@@ -1197,9 +1235,27 @@ class Compiler : public ErrorSink {
11971235 return result;
11981236 }
11991237
1200- virtual void convertR0(Type* pType){
1238+ virtual void convertR0Imp(Type* pType, bool isCast){
12011239 Type* pR0Type = getR0Type();
1202- if (bitsSame(pType, pR0Type)) {
1240+ if (isPointerType(pType) && isPointerType(pR0Type)) {
1241+ Type* pA = pR0Type;
1242+ Type* pB = pType;
1243+ // Array decays to pointer
1244+ if (pA->tag == TY_ARRAY && pB->tag == TY_POINTER) {
1245+ pA = pA->pTail;
1246+ }
1247+ if (typeEqual(pA, pB)) {
1248+ return; // OK
1249+ }
1250+ if (pB->pHead->tag == TY_VOID) {
1251+ return; // convert to void* is OK.
1252+ }
1253+ if (pA->tag == TY_POINTER && pB->tag == TY_POINTER
1254+ && isCast) {
1255+ return; // OK
1256+ }
1257+ error("Incompatible pointer or array types");
1258+ } else if (bitsSame(pType, pR0Type)) {
12031259 // do nothing special
12041260 } else {
12051261 TypeTag r0Tag = collapseType(pR0Type->tag);
@@ -1423,14 +1479,17 @@ class Compiler : public ErrorSink {
14231479 return 2;
14241480 case TY_CHAR:
14251481 return 1;
1426- default:
1427- return 0;
14281482 case TY_FLOAT:
14291483 return 4;
14301484 case TY_DOUBLE:
14311485 return 8;
14321486 case TY_POINTER:
14331487 return 4;
1488+ case TY_ARRAY:
1489+ return pType->length * sizeOf(pType->pHead);
1490+ default:
1491+ error("Unsupported type %d", pType->tag);
1492+ return 0;
14341493 }
14351494 }
14361495
@@ -1438,6 +1497,8 @@ class Compiler : public ErrorSink {
14381497 switch(pType->tag) {
14391498 case TY_DOUBLE:
14401499 return 8;
1500+ case TY_ARRAY:
1501+ return stackAlignmentOf(pType->pHead);
14411502 default:
14421503 return 4;
14431504 }
@@ -1447,6 +1508,11 @@ class Compiler : public ErrorSink {
14471508 switch(pType->tag) {
14481509 case TY_DOUBLE:
14491510 return 8;
1511+ case TY_ARRAY:
1512+ return sizeOf(pType);
1513+ case TY_FUNC:
1514+ error("stackSizeOf func not supported");
1515+ return 4;
14501516 default:
14511517 return 4;
14521518 }
@@ -1911,8 +1977,8 @@ class Compiler : public ErrorSink {
19111977 bool isFloatR0 = isFloatTag(tagR0);
19121978 bool isFloatTOS = isFloatTag(tagTOS);
19131979 if (!isFloatR0 && !isFloatTOS) {
1914- bool isPtrR0 = tagR0 == TY_POINTER;
1915- bool isPtrTOS = tagTOS == TY_POINTER;
1980+ bool isPtrR0 = isPointerTag(tagR0);
1981+ bool isPtrTOS = isPointerTag(tagTOS);
19161982 if (isPtrR0 || isPtrTOS) {
19171983 if (isPtrR0 && isPtrTOS) {
19181984 if (op != OP_MINUS) {
@@ -1936,7 +2002,8 @@ class Compiler : public ErrorSink {
19362002 if (! (op == OP_PLUS || (op == OP_MINUS && isPtrR0))) {
19372003 error("Unsupported pointer-scalar operation %d", op);
19382004 }
1939- Type* pPtrType = isPtrR0 ? pR0Type : pTOSType;
2005+ Type* pPtrType = getPointerArithmeticResultType(
2006+ pR0Type, pTOSType);
19402007 o(0x59); /* pop %ecx */
19412008 int size = sizeOf(pPtrType->pHead);
19422009 if (size != 1) {
@@ -2146,7 +2213,8 @@ class Compiler : public ErrorSink {
21462213 virtual void loadR0FromR0() {
21472214 Type* pPointerType = getR0Type();
21482215 assert(pPointerType->tag == TY_POINTER);
2149- switch (pPointerType->pHead->tag) {
2216+ TypeTag tag = pPointerType->pHead->tag;
2217+ switch (tag) {
21502218 case TY_POINTER:
21512219 case TY_INT:
21522220 o2(0x008b); /* mov (%eax), %eax */
@@ -2166,7 +2234,7 @@ class Compiler : public ErrorSink {
21662234 o2(0x00dd); // fldl (%eax)
21672235 break;
21682236 default:
2169- error("loadR0FromR0: unsupported type");
2237+ error("loadR0FromR0: unsupported type %d", tag);
21702238 break;
21712239 }
21722240 setR0Type(pPointerType->pHead);
@@ -2183,14 +2251,32 @@ class Compiler : public ErrorSink {
21832251 return getPC() - 4;
21842252 }
21852253
2186- virtual void convertR0(Type* pType){
2254+ virtual void convertR0Imp(Type* pType, bool isCast){
21872255 Type* pR0Type = getR0Type();
21882256 if (pR0Type == NULL) {
21892257 assert(false);
21902258 setR0Type(pType);
21912259 return;
21922260 }
2193- if (bitsSame(pType, pR0Type)) {
2261+ if (isPointerType(pType) && isPointerType(pR0Type)) {
2262+ Type* pA = pR0Type;
2263+ Type* pB = pType;
2264+ // Array decays to pointer
2265+ if (pA->tag == TY_ARRAY && pB->tag == TY_POINTER) {
2266+ pA = pA->pTail;
2267+ }
2268+ if (typeEqual(pA, pB)) {
2269+ return; // OK
2270+ }
2271+ if (pB->pHead->tag == TY_VOID) {
2272+ return; // convert to void* is OK.
2273+ }
2274+ if (pA->tag == TY_POINTER && pB->tag == TY_POINTER
2275+ && isCast) {
2276+ return; // OK
2277+ }
2278+ error("Incompatible pointer or array types");
2279+ } else if (bitsSame(pType, pR0Type)) {
21942280 // do nothing special
21952281 } else if (isFloatType(pType) && isFloatType(pR0Type)) {
21962282 // do nothing special, both held in same register on x87.
@@ -2326,6 +2412,11 @@ class Compiler : public ErrorSink {
23262412 return 1;
23272413 case TY_SHORT:
23282414 return 2;
2415+ case TY_ARRAY:
2416+ return alignmentOf(pType->pHead);
2417+ case TY_FUNC:
2418+ error("alignment of func not supported");
2419+ return 1;
23292420 default:
23302421 return 4;
23312422 }
@@ -2342,14 +2433,17 @@ class Compiler : public ErrorSink {
23422433 return 2;
23432434 case TY_CHAR:
23442435 return 1;
2345- default:
2346- return 0;
23472436 case TY_FLOAT:
23482437 return 4;
23492438 case TY_DOUBLE:
23502439 return 8;
23512440 case TY_POINTER:
23522441 return 4;
2442+ case TY_ARRAY:
2443+ return pType->length * sizeOf(pType->pHead);
2444+ default:
2445+ error("Unsupported type %d", pType->tag);
2446+ return 0;
23532447 }
23542448 }
23552449
@@ -2361,6 +2455,11 @@ class Compiler : public ErrorSink {
23612455 switch(pType->tag) {
23622456 case TY_DOUBLE:
23632457 return 8;
2458+ case TY_ARRAY:
2459+ return sizeOf(pType);
2460+ case TY_FUNC:
2461+ error("stackSizeOf func not supported");
2462+ return 4;
23642463 default:
23652464 return 4;
23662465 }
@@ -3911,7 +4010,7 @@ class Compiler : public ErrorSink {
39114010 skip(')');
39124011 unary();
39134012 pGen->forceR0RVal();
3914- pGen->convertR0(pCast);
4013+ pGen->castR0(pCast);
39154014 } else {
39164015 commaExpr();
39174016 skip(')');
@@ -3959,10 +4058,18 @@ class Compiler : public ErrorSink {
39594058 }
39604059 }
39614060 // load a variable
3962- Type* pVal = createPtrType(pVI->pType);
4061+ Type* pVal;
4062+ ExpressionType et;
4063+ if (pVI->pType->tag == TY_ARRAY) {
4064+ pVal = pVI->pType;
4065+ et = ET_RVALUE;
4066+ } else {
4067+ pVal = createPtrType(pVI->pType);
4068+ et = ET_LVALUE;
4069+ }
39634070 if (n) {
3964- ExpressionType et = ET_LVALUE;
3965- if (pVal->pHead->tag == TY_FUNC) {
4071+ int tag = pVal->pHead->tag;
4072+ if (tag == TY_FUNC) {
39664073 et = ET_RVALUE;
39674074 }
39684075 pGen->leaR0(n, pVal, et);
@@ -4251,6 +4358,8 @@ class Compiler : public ErrorSink {
42514358 }
42524359 if (at == TY_POINTER) {
42534360 return typeEqual(a->pHead, b->pHead);
4361+ } else if (at == TY_ARRAY) {
4362+ return a->length == b->length && typeEqual(a->pHead, b->pHead);
42544363 } else if (at == TY_FUNC || at == TY_PARAM) {
42554364 return typeEqual(a->pHead, b->pHead)
42564365 && typeEqual(a->pTail, b->pTail);
@@ -4345,6 +4454,9 @@ class Compiler : public ErrorSink {
43454454 }
43464455 buffer.append('*');
43474456 break;
4457+ case TY_ARRAY:
4458+ decodeTypeImpPrefix(buffer, pType->pHead);
4459+ break;
43484460 case TY_FUNC:
43494461 decodeTypeImp(buffer, pType->pHead);
43504462 break;
@@ -4369,6 +4481,13 @@ class Compiler : public ErrorSink {
43694481 }
43704482 decodeTypeImpPostfix(buffer, pType->pHead);
43714483 break;
4484+ case TY_ARRAY:
4485+ {
4486+ String temp;
4487+ temp.printf("[%d]", pType->length);
4488+ buffer.append(temp);
4489+ }
4490+ break;
43724491 case TY_FUNC:
43734492 buffer.append('(');
43744493 for(Type* pArg = pType->pTail; pArg; pArg = pArg->pTail) {
@@ -4418,9 +4537,13 @@ class Compiler : public ErrorSink {
44184537 nameRequired, reportFailure);
44194538 if (declName) {
44204539 // Clone the parent type so we can set a unique ID
4540+ Type* pOldType = pType;
44214541 pType = createType(pType->tag, pType->pHead, pType->pTail);
44224542
44234543 pType->id = declName;
4544+ pType->length = pOldType->length;
4545+ } else if (nameRequired) {
4546+ error("Expected a variable name");
44244547 }
44254548 // fprintf(stderr, "Parsed a declaration: ");
44264549 // printType(pType);
@@ -4490,11 +4613,27 @@ class Compiler : public ErrorSink {
44904613 error("Expected name. Got %s", temp.getUnwrapped());
44914614 reportFailure = true;
44924615 }
4493- while (accept('(')) {
4494- // Function declaration
4495- Type* pTail = acceptArgs(nameAllowed);
4496- pType = createType(TY_FUNC, pType, pTail);
4497- skip(')');
4616+ for(;;) {
4617+ if (accept('(')) {
4618+ // Function declaration
4619+ Type* pTail = acceptArgs(nameAllowed);
4620+ pType = createType(TY_FUNC, pType, pTail);
4621+ skip(')');
4622+ } if (accept('[')) {
4623+ if (tok != ']') {
4624+ if (tok != TOK_NUM || tokc <= 0) {
4625+ error("Expected positive integer constant");
4626+ } else {
4627+ Type* pDecayType = createPtrType(pType);
4628+ pType = createType(TY_ARRAY, pType, pDecayType);
4629+ pType->length = tokc;
4630+ }
4631+ next();
4632+ }
4633+ skip(']');
4634+ } else {
4635+ break;
4636+ }
44984637 }
44994638
45004639 if (pNewHead) {
--- /dev/null
+++ b/libacc/tests/data/array.c
@@ -0,0 +1,77 @@
1+// Array allocation tests
2+
3+void testLocalInt()
4+{
5+ int a[3];
6+ a[0] = 1;
7+ a[1] = 2;
8+ a[2] = a[0] + a[1];
9+ printf("localInt: %d\n", a[2]);
10+}
11+
12+char a[3];
13+double d[3];
14+
15+void testGlobalChar()
16+{
17+ a[0] = 1;
18+ a[1] = 2;
19+ a[2] = a[0] + a[1];
20+ printf("globalChar: %d\n", a[2]);
21+}
22+
23+void testGlobalDouble()
24+{
25+ d[0] = 1;
26+ d[1] = 2;
27+ d[2] = d[0] + d[1];
28+ printf("globalDouble: %g\n", d[2]);
29+}
30+
31+void testLocalDouble()
32+{
33+ double d[3];
34+ float m[12];
35+ m[0] = 1.0f;
36+ m[1] = 2.0f;
37+ d[0] = 1.0;
38+ d[1] = 2.0;
39+ d[2] = d[0] + d[1];
40+ m[2] = m[0] + m[1];
41+ printf("localDouble: %g %g\n", d[2], m[2]);
42+}
43+
44+void vectorAdd(int* a, int* b, float* c, int len) {
45+ int i;
46+ for(i = 0; i < len; i++) {
47+ c[i] = a[i] + b[i];
48+ }
49+}
50+
51+void testArgs() {
52+ int a[3], b[3];
53+ float c[3];
54+ int i;
55+ int len = 3;
56+ for(i = 0; i < len; i++) {
57+ a[i] = i;
58+ b[i] = i;
59+ c[i] = 0;
60+ }
61+ vectorAdd(a,b,c, len);
62+ printf("testArgs:");
63+ for(i = 0; i < len; i++) {
64+ printf(" %g", c[i]);
65+ }
66+ printf("\n");
67+}
68+
69+int main()
70+{
71+ testLocalInt();
72+ testLocalDouble();
73+ testGlobalChar();
74+ testGlobalDouble();
75+ testArgs();
76+ return 0;
77+}
--- a/libacc/tests/test.py
+++ b/libacc/tests/test.py
@@ -387,6 +387,16 @@ result: 0
387387 result: -2
388388 ""","""""")
389389
390+ def testArray(self):
391+ self.compileCheck(["-R", "data/array.c"], """Executing compiled code:
392+localInt: 3
393+localDouble: 3 3
394+globalChar: 3
395+globalDouble: 3
396+testArgs: 0 2 4
397+result: 0
398+""","""""")
399+
390400 if __name__ == '__main__':
391401 if not outputCanRun():
392402 print "Many tests are expected to fail, because acc is not a 32-bit x86 Linux executable."