• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Keine Tags

Frequently used words (click to add to your profile)

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

system/corennnnn


Commit MetaInfo

Revision45431bc2528246f829383abda8c2cd72c57fcb65 (tree)
Zeit2009-07-14 07:57:26
AutorJack Palevich <jackpal@goog...>
CommiterJack Palevich

Log Message

Implement general casts and pointer dereferencing.

Prior to this casts and pointer dereferencing were special-cased.

Ändern Zusammenfassung

Diff

--- a/libacc/acc.cpp
+++ b/libacc/acc.cpp
@@ -1019,6 +1019,7 @@ class Compiler : public ErrorSink {
10191019 LOG_API("storeR0(%d);\n", ea);
10201020 TypeTag tag = pType->tag;
10211021 switch (tag) {
1022+ case TY_POINTER:
10221023 case TY_INT:
10231024 case TY_FLOAT:
10241025 if (ea > -LOCAL && ea < LOCAL) {
@@ -2027,6 +2028,7 @@ class Compiler : public ErrorSink {
20272028 TypeTag tag = pType->tag;
20282029 switch (tag) {
20292030 case TY_INT:
2031+ case TY_POINTER:
20302032 gmov(6, ea); /* mov %eax, EA */
20312033 break;
20322034 case TY_FLOAT:
@@ -3663,41 +3665,34 @@ class Compiler : public ErrorSink {
36633665 pGen->genUnaryOp(a);
36643666 }
36653667 } else if (t == '(') {
3666- expr();
3667- skip(')');
3668- } else if (t == '*') {
3669- /* This is a pointer dereference, but we currently only
3670- * support a pointer dereference if it's immediately
3671- * in front of a cast. So parse the cast right here.
3672- */
3673- skip('(');
3674- Type* pCast = expectCastTypeDeclaration(mLocalArena);
3675- // We currently only handle 3 types of cast:
3676- // (int*), (char*) , (int (*)())
3677- if(typeEqual(pCast, mkpIntPtr)) {
3678- t = TOK_INT;
3679- } else if (typeEqual(pCast, mkpCharPtr)) {
3680- t = TOK_CHAR;
3681- } else if (typeEqual(pCast, mkpFloatPtr)) {
3682- t = TOK_FLOAT;
3683- } else if (typeEqual(pCast, mkpDoublePtr)) {
3684- t = TOK_DOUBLE;
3685- } else if (typeEqual(pCast, mkpPtrIntFn)){
3686- t = 0;
3668+ // It's either a cast or an expression
3669+ Type* pCast = acceptCastTypeDeclaration(mLocalArena);
3670+ if (pCast) {
3671+ skip(')');
3672+ unary(false);
3673+ pGen->convertR0(pCast);
36873674 } else {
3688- String buffer;
3689- decodeType(buffer, pCast);
3690- error("Unsupported cast type %s", buffer.getUnwrapped());
3691- decodeType(buffer, mkpPtrIntFn);
3675+ expr();
3676+ skip(')');
36923677 }
3693- skip(')');
3678+ } else if (t == '*') {
3679+ /* This is a pointer dereference.
3680+ */
36943681 unary(false);
3695- if (accept('=')) {
3696- pGen->pushR0();
3697- expr();
3698- pGen->storeR0ToTOS(pCast);
3699- } else if (t) {
3700- pGen->loadR0FromR0(pCast);
3682+ Type* pR0Type = pGen->getR0Type();
3683+ if (pR0Type->tag != TY_POINTER) {
3684+ error("Expected a pointer type.");
3685+ } else {
3686+ if (pR0Type->pHead->tag == TY_FUNC) {
3687+ t = 0;
3688+ }
3689+ if (accept('=')) {
3690+ pGen->pushR0();
3691+ expr();
3692+ pGen->storeR0ToTOS(pR0Type);
3693+ } else if (t) {
3694+ pGen->loadR0FromR0(pR0Type);
3695+ }
37013696 }
37023697 // Else we fall through to the function call below, with
37033698 // t == 0 to trigger an indirect function call. Hack!
--- /dev/null
+++ b/libacc/tests/data/casts.c
@@ -0,0 +1,85 @@
1+void test1() {
2+ int a = 3;
3+ int* pb = &a;
4+ int c = *pb;
5+ printf("Reading from a pointer: %d %d\n", a, c);
6+ *pb = 4;
7+ printf("Writing to a pointer: %d\n", a);
8+ printf("Testing casts: %d %g %g %d\n", 3, (float) 3, 4.5, (int) 4.5);
9+}
10+
11+void test2() {
12+ int x = 4;
13+ int px = &x;
14+ // int z = * px; // An error, expected a pointer type
15+ int y = * (int*) px;
16+ printf("Testing reading (int*): %d\n", y);
17+}
18+
19+void test3() {
20+ int px = (int) malloc(120);
21+ * (int*) px = 8;
22+ * (int*) (px + 4) = 9;
23+ printf("Testing writing (int*): %d %d\n", * (int*) px, * (int*) (px + 4));
24+ free((void*) px);
25+}
26+
27+void test4() {
28+ int x = 0x12345678;
29+ int px = &x;
30+ int a = * (char*) px;
31+ int b = * (char*) (px + 1);
32+ int c = * (char*) (px + 2);
33+ int d = * (char*) (px + 3);
34+ printf("Testing reading (char*): 0x%02x 0x%02x 0x%02x 0x%02x\n", a, b, c, d);
35+}
36+
37+void test5() {
38+ int x = 0xFFFFFFFF;
39+ int px = &x;
40+ * (char*) px = 0x21;
41+ * (char*) (px + 1) = 0x43;
42+ * (char*) (px + 2) = 0x65;
43+ * (char*) (px + 3) = 0x87;
44+ printf("Testing writing (char*): 0x%08x\n", x);
45+}
46+
47+int f(int b) {
48+ printf("f(%d)\n", b);
49+ return 7 * b;
50+}
51+
52+void test6() {
53+ int fp = &f;
54+ int x = (*(int(*)()) fp)(10);
55+ printf("Function pointer result: %d\n", x);
56+}
57+
58+void test7() {
59+ int px = (int) malloc(120);
60+ * (float*) px = 8.8f;
61+ * (float*) (px + 4) = 9.9f;
62+ printf("Testing read/write (float*): %g %g\n", * (float*) px, * (float*) (px + 4));
63+ free((void*) px);
64+}
65+
66+void test8() {
67+ int px = (int) malloc(120);
68+ * (double*) px = 8.8;
69+ * (double*) (px + 8) = 9.9;
70+ printf("Testing read/write (double*): %g %g\n", * (double*) px, * (double*) (px + 8));
71+ free((void*) px);
72+}
73+
74+
75+int main() {
76+ test1();
77+ test2();
78+ test3();
79+ test4();
80+ test5();
81+ test6();
82+ test7();
83+ test8();
84+ return 0;
85+}
--- a/libacc/tests/test.py
+++ b/libacc/tests/test.py
@@ -77,7 +77,14 @@ def firstDifference(a, b):
7777 return i
7878 return commonLen
7979
80-def compareSet(a1,a2,b1,b2):
80+# a1 and a2 are the expected stdout and stderr.
81+# b1 and b2 are the actual stdout and stderr.
82+# Compare the two, sets. Allow any individual line
83+# to appear in either stdout or stderr. This is because
84+# the way we obtain output on the ARM combines both
85+# streams into one sequence.
86+
87+def compareOuput(a1,a2,b1,b2):
8188 while True:
8289 totalLen = len(a1) + len(a2) + len(b1) + len(b2)
8390 a1, b1 = matchCommon(a1, b1)
@@ -96,6 +103,8 @@ def compareSet(a1,a2,b1,b2):
96103 return False
97104
98105 def matchCommon(a, b):
106+ """Remove common items from the beginning of a and b,
107+ return just the tails that are different."""
99108 while len(a) > 0 and len(b) > 0 and a[0] == b[0]:
100109 a = a[1:]
101110 b = b[1:]
@@ -105,25 +114,20 @@ def rewritePaths(args):
105114 return [rewritePath(x) for x in args]
106115
107116 def rewritePath(p):
117+ """Take a path that's correct on the x86 and convert to a path
118+ that's correct on ARM."""
108119 if p.startswith("data/"):
109120 p = "/system/bin/accdata/" + p
110121 return p
111122
112123 class TestACC(unittest.TestCase):
113-
114- def compileCheckOld(self, args, stdErrResult, stdOutResult=""):
115- out, err = compile(args)
116- compare(out, stdOutResult)
117- compare(err, stdErrResult)
118- self.assertEqual(out, stdOutResult)
119- self.assertEqual(err, stdErrResult)
120124
121125 def checkResult(self, out, err, stdErrResult, stdOutResult=""):
122126 a1 = out.splitlines()
123127 a2 = err.splitlines()
124128 b2 = stdErrResult.splitlines()
125129 b1 = stdOutResult.splitlines()
126- self.assertEqual(True, compareSet(a1,a2,b1,b2))
130+ self.assertEqual(True, compareOuput(a1,a2,b1,b2))
127131
128132 def compileCheck(self, args, stdErrResult, stdOutResult="",
129133 targets=['arm', 'x86']):
@@ -174,65 +178,77 @@ class TestACC(unittest.TestCase):
174178
175179 def testRunFlops(self):
176180 self.compileCheck(["-R", "data/flops.c"],
177- "Executing compiled code:\nresult: 0\n",
178- "-1.1 = -1.1\n" +
179- "!1.2 = 0\n" +
180- "!0 = 1\n" +
181- "double op double:\n" +
182- "1 + 2 = 3\n" +
183- "1 - 2 = -1\n" +
184- "1 * 2 = 2\n" +
185- "1 / 2 = 0.5\n" +
186- "float op float:\n" +
187- "1 + 2 = 3\n" +
188- "1 - 2 = -1\n" +
189- "1 * 2 = 2\n" +
190- "1 / 2 = 0.5\n" +
191- "double op float:\n" +
192- "1 + 2 = 3\n" +
193- "1 - 2 = -1\n" +
194- "1 * 2 = 2\n" +
195- "1 / 2 = 0.5\n" +
196- "double op int:\n" +
197- "1 + 2 = 3\n" +
198- "1 - 2 = -1\n" +
199- "1 * 2 = 2\n" +
200- "1 / 2 = 0.5\n" +
201- "int op double:\n" +
202- "1 + 2 = 3\n" +
203- "1 - 2 = -1\n" +
204- "1 * 2 = 2\n" +
205- "1 / 2 = 0.5\n" +
206- "double op double:\n" +
207- "1 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1\n" +
208- "1 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0\n" +
209- "2 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1\n" +
210- "double op float:\n" +
211- "1 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1\n" +
212- "1 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0\n" +
213- "2 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1\n" +
214- "float op float:\n" +
215- "1 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1\n" +
216- "1 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0\n" +
217- "2 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1\n" +
218- "int op double:\n" +
219- "1 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1\n" +
220- "1 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0\n" +
221- "2 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1\n" +
222- "double op int:\n" +
223- "1 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1\n" +
224- "1 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0\n" +
225- "2 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1\n" +
226- "branching: 1 0 1\n" +
227- "testpassi: 1 2 3 4 5 6 7 8\n" +
228- "testpassf: 1 2 3 4 5 6 7 8\n" +
229- "testpassd: 1 2 3 4 5 6 7 8\n" +
230- "testpassidf: 1 2 3\n"
231- )
232-
233- def oldtestArmRunReturnVal(self):
234- self.compileCheckArm(["-R", "/system/bin/accdata/data/returnval-ansi.c"],
235- "Executing compiled code:\nresult: 42\n")
181+ """Executing compiled code:
182+result: 0""",
183+"""-1.1 = -1.1
184+!1.2 = 0
185+!0 = 1
186+double op double:
187+1 + 2 = 3
188+1 - 2 = -1
189+1 * 2 = 2
190+1 / 2 = 0.5
191+float op float:
192+1 + 2 = 3
193+1 - 2 = -1
194+1 * 2 = 2
195+1 / 2 = 0.5
196+double op float:
197+1 + 2 = 3
198+1 - 2 = -1
199+1 * 2 = 2
200+1 / 2 = 0.5
201+double op int:
202+1 + 2 = 3
203+1 - 2 = -1
204+1 * 2 = 2
205+1 / 2 = 0.5
206+int op double:
207+1 + 2 = 3
208+1 - 2 = -1
209+1 * 2 = 2
210+1 / 2 = 0.5
211+double op double:
212+1 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1
213+1 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0
214+2 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1
215+double op float:
216+1 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1
217+1 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0
218+2 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1
219+float op float:
220+1 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1
221+1 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0
222+2 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1
223+int op double:
224+1 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1
225+1 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0
226+2 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1
227+double op int:
228+1 op 2: < 1 <= 1 == 0 >= 0 > 0 != 1
229+1 op 1: < 0 <= 1 == 1 >= 1 > 0 != 0
230+2 op 1: < 0 <= 0 == 0 >= 1 > 1 != 1
231+branching: 1 0 1
232+testpassi: 1 2 3 4 5 6 7 8
233+testpassf: 1 2 3 4 5 6 7 8
234+testpassd: 1 2 3 4 5 6 7 8
235+testpassidf: 1 2 3
236+""")
237+ def testCasts(self):
238+ self.compileCheck(["-R", "data/casts.c"],
239+ """Executing compiled code:
240+result: 0""", """Reading from a pointer: 3 3
241+Writing to a pointer: 4
242+Testing casts: 3 3 4.5 4
243+Testing reading (int*): 4
244+Testing writing (int*): 8 9
245+Testing reading (char*): 0x78 0x56 0x34 0x12
246+Testing writing (char*): 0x87654321
247+f(10)
248+Function pointer result: 70
249+Testing read/write (float*): 8.8 9.9
250+Testing read/write (double*): 8.8 9.9
251+""")
236252
237253 if __name__ == '__main__':
238254 if not outputCanRun():