• 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

Revisione7b590666dba83c72b7f7bf210dad7239ab04b4f (tree)
Zeit2009-05-21 03:27:04
AutorJack Palevich <jackpal@goog...>
CommiterJack Palevich

Log Message

Implement architecture-dependent defaults.

If libacc is built on x86, then x86 is the default code generator.
If libacc is built on arm. then ARM is the default code generator
And so on for future architectures.

The 64-bit x64 machine has no working code generator currently.
We may add one to support the simulator builds.

Improved the test program so we don't try to run tests if the
compile failed. Also avoid running tests that don't work on
a given platform.

Ändern Zusammenfassung

Diff

--- a/libacc/acc.cpp
+++ b/libacc/acc.cpp
@@ -1,4 +1,15 @@
11 /*
2+ * Android "Almost" C Compiler.
3+ * This is a compiler for a small subset of the C language, intended for use
4+ * in scripting environments where speed and memory footprint are important.
5+ *
6+ * This code is based upon the "unobfuscated" version of the
7+ * Obfuscated Tiny C compiler, and retains the
8+ * original copyright notice and license from that compiler, see below.
9+ *
10+ */
11+
12+/*
213 Obfuscated Tiny C Compiler
314
415 Copyright (C) 2001-2003 Fabrice Bellard
@@ -31,11 +42,24 @@
3142 #include <unistd.h>
3243 #endif
3344
45+#if defined(__arm__)
46+#define DEFAULT_ARM_CODEGEN
47+#elif defined(__i386__)
48+#define DEFAULT_X86_CODEGEN
49+#elif defined(__x86_64__)
50+#define DEFAULT_X64_CODEGEN
51+#endif
52+
53+#define PROVIDE_X86_CODEGEN
54+#define PROVIDE_ARM_CODEGEN
55+
56+#ifdef PROVIDE_ARM_CODEGEN
3457 #include "disassem.h"
58+#endif
3559
3660 namespace acc {
3761
38-class compiler {
62+class Compiler {
3963 class CodeBuf {
4064 char* ind;
4165 char* pProgramBase;
@@ -63,14 +87,6 @@ class compiler {
6387 ind = pProgramBase;
6488 }
6589
66- void o(int n) {
67- /* cannot use unsigned, so we must do a hack */
68- while (n && n != -1) {
69- *ind++ = n;
70- n = n >> 8;
71- }
72- }
73-
7490 int o4(int n) {
7591 int result = (int) ind;
7692 * (int*) ind = n;
@@ -85,31 +101,6 @@ class compiler {
85101 *ind++ = n;
86102 }
87103
88- /* output a symbol and patch all calls to it */
89- void gsym(int t) {
90- int n;
91- while (t) {
92- n = *(int *) t; /* next value */
93- *(int *) t = ((int) ind) - t - 4;
94- t = n;
95- }
96- }
97-
98- /* psym is used to put an instruction with a data field which is a
99- reference to a symbol. It is in fact the same as oad ! */
100- int psym(int n, int t) {
101- return oad(n, t);
102- }
103-
104- /* instruction + address */
105- int oad(int n, int t) {
106- o(n);
107- *(int *) ind = t;
108- t = (int) ind;
109- ind = ind + 4;
110- return t;
111- }
112-
113104 inline void* getBase() {
114105 return (void*) pProgramBase;
115106 }
@@ -184,9 +175,7 @@ class compiler {
184175 virtual int disassemble(FILE* out) = 0;
185176
186177 /* output a symbol and patch all calls to it */
187- virtual void gsym(int t) {
188- pCodeBuf->gsym(t);
189- }
178+ virtual void gsym(int t) = 0;
190179
191180 virtual int finishCompile() {
192181 #if defined(__arm__)
@@ -205,10 +194,6 @@ class compiler {
205194 virtual int jumpOffset() = 0;
206195
207196 protected:
208- void o(int n) {
209- pCodeBuf->o(n);
210- }
211-
212197 /*
213198 * Output a byte. Handles all values, 0..ff.
214199 */
@@ -216,15 +201,8 @@ class compiler {
216201 pCodeBuf->ob(n);
217202 }
218203
219- /* psym is used to put an instruction with a data field which is a
220- reference to a symbol. It is in fact the same as oad ! */
221- int psym(int n, int t) {
222- return oad(n, t);
223- }
224-
225- /* instruction + address */
226- int oad(int n, int t) {
227- return pCodeBuf->oad(n,t);
204+ int o4(int data) {
205+ return pCodeBuf->o4(data);
228206 }
229207
230208 int getBase() {
@@ -234,14 +212,12 @@ class compiler {
234212 int getPC() {
235213 return pCodeBuf->getPC();
236214 }
237-
238- int o4(int data) {
239- return pCodeBuf->o4(data);
240- }
241215 private:
242216 CodeBuf* pCodeBuf;
243217 };
244218
219+#ifdef PROVIDE_ARM_CODEGEN
220+
245221 class ARMCodeGenerator : public CodeGenerator {
246222 public:
247223 ARMCodeGenerator() {}
@@ -701,6 +677,10 @@ class compiler {
701677 }
702678 };
703679
680+#endif // PROVIDE_X86_CODEGEN
681+
682+#ifdef PROVIDE_X86_CODEGEN
683+
704684 class X86CodeGenerator : public CodeGenerator {
705685 public:
706686 X86CodeGenerator() {}
@@ -829,7 +809,45 @@ class compiler {
829809 return 1;
830810 }
831811
812+ /* output a symbol and patch all calls to it */
813+ virtual void gsym(int t) {
814+ int n;
815+ int pc = getPC();
816+ while (t) {
817+ n = *(int *) t; /* next value */
818+ *(int *) t = pc - t - 4;
819+ t = n;
820+ }
821+ }
822+
832823 private:
824+
825+ /** Output 1 to 4 bytes.
826+ *
827+ */
828+ void o(int n) {
829+ /* cannot use unsigned, so we must do a hack */
830+ while (n && n != -1) {
831+ ob(n & 0xff);
832+ n = n >> 8;
833+ }
834+ }
835+
836+ /* psym is used to put an instruction with a data field which is a
837+ reference to a symbol. It is in fact the same as oad ! */
838+ int psym(int n, int t) {
839+ return oad(n, t);
840+ }
841+
842+ /* instruction + address */
843+ int oad(int n, int t) {
844+ o(n);
845+ int result = getPC();
846+ o4(t);
847+ return result;
848+ }
849+
850+
833851 static const int operatorHelper[];
834852
835853 int decodeOp(int op) {
@@ -846,6 +864,8 @@ class compiler {
846864 }
847865 };
848866
867+#endif // PROVIDE_X86_CODEGEN
868+
849869 /* vars: value of variables
850870 loc : local variable index
851871 glo : global variable index
@@ -1426,16 +1446,31 @@ class compiler {
14261446
14271447 if (architecture != NULL) {
14281448 if (strcmp(architecture, "arm") == 0) {
1449+#ifdef PROVIDE_ARM_CODEGEN
14291450 pGen = new ARMCodeGenerator();
1451+#else
1452+ fprintf(stderr, "Unsupported architecture %s", architecture);
1453+#endif
14301454 } else if (strcmp(architecture, "x86") == 0) {
1455+#ifdef PROVIDE_X86_CODEGEN
14311456 pGen = new X86CodeGenerator();
1457+#else
1458+ fprintf(stderr, "Unsupported architecture %s", architecture);
1459+#endif
14321460 } else {
14331461 fprintf(stderr, "Unknown architecture %s", architecture);
14341462 }
14351463 }
14361464
14371465 if (pGen == NULL) {
1466+#if defined(DEFAULT_ARM_CODEGEN)
14381467 pGen = new ARMCodeGenerator();
1468+#elif defined(DEFAULT_X86_CODEGEN)
1469+ pGen = new X86CodeGenerator();
1470+#endif
1471+ }
1472+ if (pGen == NULL) {
1473+ fprintf(stderr, "No code generator defined.");
14391474 }
14401475 }
14411476
@@ -1447,11 +1482,11 @@ public:
14471482 const char* architecture;
14481483 };
14491484
1450- compiler() {
1485+ Compiler() {
14511486 clear();
14521487 }
14531488
1454- ~compiler() {
1489+ ~Compiler() {
14551490 cleanup();
14561491 }
14571492
@@ -1498,10 +1533,10 @@ public:
14981533
14991534 };
15001535
1501-const char* compiler::operatorChars =
1536+const char* Compiler::operatorChars =
15021537 "++--*@/@%@+@-@<<>><=>=<@>@==!=&&||&@^@|@~@!@";
15031538
1504-const char compiler::operatorLevel[] =
1539+const char Compiler::operatorLevel[] =
15051540 {11, 11, 1, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4,
15061541 5, 5, /* ==, != */
15071542 9, 10, /* &&, || */
@@ -1509,9 +1544,9 @@ const char compiler::operatorLevel[] =
15091544 2, 2 /* ~ ! */
15101545 };
15111546
1512-FILE* compiler::ARMCodeGenerator::disasmOut;
1547+FILE* Compiler::ARMCodeGenerator::disasmOut;
15131548
1514-const int compiler::X86CodeGenerator::operatorHelper[] = {
1549+const int Compiler::X86CodeGenerator::operatorHelper[] = {
15151550 0x1, // ++
15161551 0xff, // --
15171552 0xc1af0f, // *
@@ -1539,7 +1574,7 @@ const int compiler::X86CodeGenerator::operatorHelper[] = {
15391574 } // namespace acc
15401575
15411576 // This is a separate function so it can easily be set by breakpoint in gdb.
1542-int run(acc::compiler& c, int argc, char** argv) {
1577+int run(acc::Compiler& c, int argc, char** argv) {
15431578 return c.run(argc, argv);
15441579 }
15451580
@@ -1548,7 +1583,7 @@ int main(int argc, char** argv) {
15481583 bool doDisassemble = false;
15491584 const char* inFile = NULL;
15501585 const char* outFile = NULL;
1551- const char* architecture = "arm";
1586+ const char* architecture = NULL;
15521587 int i;
15531588 for (i = 1; i < argc; i++) {
15541589 char* arg = argv[i];
@@ -1593,9 +1628,11 @@ int main(int argc, char** argv) {
15931628 return 1;
15941629 }
15951630 }
1596- acc::compiler compiler;
1597- acc::compiler::args args;
1598- args.architecture = architecture;
1631+ acc::Compiler compiler;
1632+ acc::Compiler::args args;
1633+ if (architecture != NULL) {
1634+ args.architecture = architecture;
1635+ }
15991636 int compileResult = compiler.compile(in, args);
16001637 if (in != stdin) {
16011638 fclose(in);
--- a/libacc/test
+++ b/libacc/test
@@ -1,3 +1,13 @@
11 #!/bin/sh
2+rm -f tests/acc
23 g++ acc.cpp disassem.cpp -g -ldl -o tests/acc && tests/acc tests/otcc.c -a x86 -d tests/otcc.out && diff tests/otcc.out tests/otcc.out-orig
3-tests/acc -S tests/returnval.c
4+if [ -x "tests/acc" ]; then
5+ tests/acc -S tests/returnval.c
6+
7+ if [ "$(uname)" = "Linux" ]; then
8+ if [ "$(uname -m)" = "i686" ]; then
9+ echo "Linux i686. Testing otcc.c"
10+ tests/acc tests/otcc.c tests/otcc.c tests/returnval.c
11+ fi
12+ fi
13+fi