Merge change 1627
* changes:
Add stub Arm code generator.
diff --git a/libacc/acc.cpp b/libacc/acc.cpp
index 0f8e606..13a863f 100644
--- a/libacc/acc.cpp
+++ b/libacc/acc.cpp
@@ -30,7 +30,6 @@
namespace acc {
class compiler {
-
class CodeBuf {
char* ind;
char* pProgramBase;
@@ -116,12 +115,60 @@
CodeGenerator() {}
virtual ~CodeGenerator() {}
- void init(CodeBuf* pCodeBuf) {
+ virtual void init(CodeBuf* pCodeBuf) {
this->pCodeBuf = pCodeBuf;
}
+ /* returns address to patch with local variable size
+ */
+ virtual int functionEntry() = 0;
+
+ virtual void functionExit() = 0;
+
+ /* load immediate value */
+ virtual int li(int t) = 0;
+
+ virtual int gjmp(int t) = 0;
+
+ /* l = 0: je, l == 1: jne */
+ virtual int gtst(bool l, int t) = 0;
+
+ virtual void gcmp(int op) = 0;
+
+ virtual int genOp(int op) = 0;
+
+ virtual void clearECX() = 0;
+
+ virtual void pushEAX() = 0;
+
+ virtual void popECX() = 0;
+
+ virtual void storeEAXToAddressECX(bool isInt) = 0;
+
+ virtual void loadEAXIndirect(bool isInt) = 0;
+
+ virtual void leaEAX(int ea) = 0;
+
+ virtual void storeEAX(int ea) = 0;
+
+ virtual void loadEAX(int ea) = 0;
+
+ virtual void postIncrementOrDecrement(int n, int op) = 0;
+
+ virtual int allocStackSpaceForArgs() = 0;
+
+ virtual void storeEAToArg(int l) = 0;
+
+ virtual int callForward(int symbol) = 0;
+
+ virtual void callRelative(int t) = 0;
+
+ virtual void callIndirect(int l) = 0;
+
+ virtual void adjustStackAfterCall(int l) = 0;
+
/* output a symbol and patch all calls to it */
- void gsym(int t) {
+ virtual void gsym(int t) {
pCodeBuf->gsym(t);
}
@@ -156,6 +203,157 @@
CodeBuf* pCodeBuf;
};
+ class ARMCodeGenerator : public CodeGenerator {
+ public:
+ ARMCodeGenerator() {}
+ virtual ~ARMCodeGenerator() {}
+
+ /* returns address to patch with local variable size
+ */
+ virtual int functionEntry() {
+ fprintf(stderr, "functionEntry();\n");
+ o(0xe58955); /* push %ebp, mov %esp, %ebp */
+ return oad(0xec81, 0); /* sub $xxx, %esp */
+ }
+
+ virtual void functionExit() {
+ fprintf(stderr, "functionExit();\n");
+ o(0xc3c9); /* leave, ret */
+ }
+
+ /* load immediate value */
+ virtual int li(int t) {
+ fprintf(stderr, "li(%d);\n", t);
+ oad(0xb8, t); /* mov $xx, %eax */
+ }
+
+ virtual int gjmp(int t) {
+ fprintf(stderr, "gjmp(%d);\n", t);
+ return psym(0xe9, t);
+ }
+
+ /* l = 0: je, l == 1: jne */
+ virtual int gtst(bool l, int t) {
+ fprintf(stderr, "gtst(%d, %d);\n", l, t);
+ o(0x0fc085); /* test %eax, %eax, je/jne xxx */
+ return psym(0x84 + l, t);
+ }
+
+ virtual void gcmp(int op) {
+ fprintf(stderr, "gcmp(%d);\n", op);
+#if 0
+ int t = decodeOp(op);
+ o(0xc139); /* cmp %eax,%ecx */
+ li(0);
+ o(0x0f); /* setxx %al */
+ o(t + 0x90);
+ o(0xc0);
+#endif
+ }
+
+ virtual int genOp(int op) {
+ fprintf(stderr, "genOp(%d);\n", op);
+#if 0
+ o(decodeOp(op));
+ if (op == OP_MOD)
+ o(0x92); /* xchg %edx, %eax */
+#endif
+ }
+
+ virtual void clearECX() {
+ fprintf(stderr, "clearECX();\n");
+ oad(0xb9, 0); /* movl $0, %ecx */
+ }
+
+ virtual void pushEAX() {
+ fprintf(stderr, "pushEAX();\n");
+ o(0x50); /* push %eax */
+ }
+
+ virtual void popECX() {
+ fprintf(stderr, "popECX();\n");
+ o(0x59); /* pop %ecx */
+ }
+
+ virtual void storeEAXToAddressECX(bool isInt) {
+ fprintf(stderr, "storeEAXToAddressECX(%d);\n", isInt);
+ o(0x0188 + isInt); /* movl %eax/%al, (%ecx) */
+ }
+
+ virtual void loadEAXIndirect(bool isInt) {
+ fprintf(stderr, "loadEAXIndirect(%d);\n", isInt);
+ if (isInt)
+ o(0x8b); /* mov (%eax), %eax */
+ else
+ o(0xbe0f); /* movsbl (%eax), %eax */
+ ob(0); /* add zero in code */
+ }
+
+ virtual void leaEAX(int ea) {
+ fprintf(stderr, "leaEAX(%d);\n", ea);
+#if 0
+ gmov(10, ea); /* leal EA, %eax */
+#endif
+ }
+
+ virtual void storeEAX(int ea) {
+ fprintf(stderr, "storeEAX(%d);\n", ea);
+#if 0
+ gmov(6, ea); /* mov %eax, EA */
+#endif
+ }
+
+ virtual void loadEAX(int ea) {
+ fprintf(stderr, "loadEAX(%d);\n", ea);
+#if 0
+ gmov(8, ea); /* mov EA, %eax */
+#endif
+ }
+
+ virtual void postIncrementOrDecrement(int n, int op) {
+ fprintf(stderr, "postIncrementOrDecrement(%d, %d);\n", n, op);
+ /* Implement post-increment or post decrement.
+ */
+#if 0
+ gmov(0, n); /* 83 ADD */
+ o(decodeOp(op));
+#endif
+ }
+
+ virtual int allocStackSpaceForArgs() {
+ fprintf(stderr, "allocStackSpaceForArgs();\n");
+ return oad(0xec81, 0); /* sub $xxx, %esp */
+ }
+
+ virtual void storeEAToArg(int l) {
+ fprintf(stderr, "storeEAToArg(%d);\n", l);
+ oad(0x248489, l); /* movl %eax, xxx(%esp) */
+ }
+
+ virtual int callForward(int symbol) {
+ fprintf(stderr, "callForward(%d);\n", symbol);
+ return psym(0xe8, symbol); /* call xxx */
+ }
+
+ virtual void callRelative(int t) {
+ fprintf(stderr, "callRelative(%d);\n", t);
+ psym(0xe8, t); /* call xxx */
+ }
+
+ virtual void callIndirect(int l) {
+ fprintf(stderr, "callIndirect(%d);\n", l);
+ oad(0x2494ff, l); /* call *xxx(%esp) */
+ }
+
+ virtual void adjustStackAfterCall(int l) {
+ fprintf(stderr, "adjustStackAfterCall(%d);\n", l);
+ oad(0xc481, l); /* add $xxx, %esp */
+ }
+
+ private:
+
+ };
+
class X86CodeGenerator : public CodeGenerator {
public:
X86CodeGenerator() {}
@@ -163,31 +361,31 @@
/* returns address to patch with local variable size
*/
- int functionEntry() {
+ virtual int functionEntry() {
o(0xe58955); /* push %ebp, mov %esp, %ebp */
return oad(0xec81, 0); /* sub $xxx, %esp */
}
- void functionExit() {
+ virtual void functionExit() {
o(0xc3c9); /* leave, ret */
}
/* load immediate value */
- int li(int t) {
+ virtual int li(int t) {
oad(0xb8, t); /* mov $xx, %eax */
}
- int gjmp(int t) {
+ virtual int gjmp(int t) {
return psym(0xe9, t);
}
/* l = 0: je, l == 1: jne */
- int gtst(int l, int t) {
+ virtual int gtst(bool l, int t) {
o(0x0fc085); /* test %eax, %eax, je/jne xxx */
return psym(0x84 + l, t);
}
- int gcmp(int op) {
+ virtual void gcmp(int op) {
int t = decodeOp(op);
o(0xc139); /* cmp %eax,%ecx */
li(0);
@@ -196,29 +394,29 @@
o(0xc0);
}
- int genOp(int op) {
+ virtual int genOp(int op) {
o(decodeOp(op));
if (op == OP_MOD)
o(0x92); /* xchg %edx, %eax */
}
- void clearECX() {
+ virtual void clearECX() {
oad(0xb9, 0); /* movl $0, %ecx */
}
- void pushEAX() {
+ virtual void pushEAX() {
o(0x50); /* push %eax */
}
- void popECX() {
+ virtual void popECX() {
o(0x59); /* pop %ecx */
}
- void storeEAXToAddressECX(bool isInt) {
+ virtual void storeEAXToAddressECX(bool isInt) {
o(0x0188 + isInt); /* movl %eax/%al, (%ecx) */
}
- void loadEAXIndirect(bool isInt) {
+ virtual void loadEAXIndirect(bool isInt) {
if (isInt)
o(0x8b); /* mov (%eax), %eax */
else
@@ -226,46 +424,46 @@
ob(0); /* add zero in code */
}
- void leaEAX(int ea) {
+ virtual void leaEAX(int ea) {
gmov(10, ea); /* leal EA, %eax */
}
- void storeEAX(int ea) {
+ virtual void storeEAX(int ea) {
gmov(6, ea); /* mov %eax, EA */
}
- void loadEAX(int ea) {
+ virtual void loadEAX(int ea) {
gmov(8, ea); /* mov EA, %eax */
}
- void postIncrementOrDecrement(int n, int op) {
+ virtual void postIncrementOrDecrement(int n, int op) {
/* Implement post-increment or post decrement.
*/
gmov(0, n); /* 83 ADD */
o(decodeOp(op));
}
- int allocStackSpaceForArgs() {
+ virtual int allocStackSpaceForArgs() {
return oad(0xec81, 0); /* sub $xxx, %esp */
}
- void storeEAToArg(int l) {
+ virtual void storeEAToArg(int l) {
oad(0x248489, l); /* movl %eax, xxx(%esp) */
}
- int callForward(int symbol) {
+ virtual int callForward(int symbol) {
return psym(0xe8, symbol); /* call xxx */
}
- void callRelative(int t) {
+ virtual void callRelative(int t) {
psym(0xe8, t); /* call xxx */
}
- void callIndirect(int l) {
+ virtual void callIndirect(int l) {
oad(0x2494ff, l); /* call *xxx(%esp) */
}
- void adjustStackAfterCall(int l) {
+ virtual void adjustStackAfterCall(int l) {
oad(0xc481, l); /* add $xxx, %esp */
}
@@ -303,7 +501,7 @@
FILE* file;
CodeBuf codeBuf;
- X86CodeGenerator* pGen;
+ CodeGenerator* pGen;
static const int ALLOC_SIZE = 99999;
@@ -853,7 +1051,33 @@
pGen = 0;
}
+ void setArchitecture(const char* architecture) {
+ delete pGen;
+ pGen = 0;
+
+ if (architecture != NULL) {
+ if (strcmp(architecture, "arm") == 0) {
+ pGen = new ARMCodeGenerator();
+ } else if (strcmp(architecture, "x86") == 0) {
+ pGen = new X86CodeGenerator();
+ } else {
+ fprintf(stderr, "Unknown architecture %s", architecture);
+ }
+ }
+
+ if (pGen == NULL) {
+ pGen = new ARMCodeGenerator();
+ }
+ }
+
public:
+ struct args {
+ args() {
+ architecture = 0;
+ }
+ const char* architecture;
+ };
+
compiler() {
clear();
}
@@ -862,11 +1086,11 @@
cleanup();
}
- int compile(FILE* in) {
+ int compile(FILE* in, args& args) {
cleanup();
clear();
codeBuf.init(ALLOC_SIZE);
- pGen = new X86CodeGenerator();
+ setArchitecture(args.architecture);
pGen->init(&codeBuf);
file = in;
sym_stk = (int) calloc(1, ALLOC_SIZE);
@@ -939,20 +1163,29 @@
} // namespace acc
int main(int argc, char** argv) {
- bool doTest = false;
+ bool doDump = false;
const char* inFile = NULL;
const char* outFile = NULL;
+ const char* architecture = "arm";
int i;
for (i = 1; i < argc; i++) {
char* arg = argv[i];
if (arg[0] == '-') {
switch (arg[1]) {
- case 'T':
+ case 'a':
if (i + 1 >= argc) {
- fprintf(stderr, "Expected filename after -T\n");
+ fprintf(stderr, "Expected architecture after -a\n");
return 2;
}
- doTest = true;
+ architecture = argv[i+1];
+ i += 1;
+ break;
+ case 'd':
+ if (i + 1 >= argc) {
+ fprintf(stderr, "Expected filename after -d\n");
+ return 2;
+ }
+ doDump = true;
outFile = argv[i + 1];
i += 1;
break;
@@ -976,7 +1209,9 @@
}
}
acc::compiler compiler;
- int compileResult = compiler.compile(in);
+ acc::compiler::args args;
+ args.architecture = architecture;
+ int compileResult = compiler.compile(in, args);
if (in != stdin) {
fclose(in);
}
@@ -984,7 +1219,7 @@
fprintf(stderr, "Compile failed: %d\n", compileResult);
return 6;
}
- if (doTest) {
+ if (doDump) {
FILE* save = fopen(outFile, "w");
if (!save) {
fprintf(stderr, "Could not open output file %s\n", outFile);
@@ -997,7 +1232,9 @@
int codeArgc = argc - i + 1;
char** codeArgv = argv + i - 1;
codeArgv[0] = (char*) (inFile ? inFile : "stdin");
- return compiler.run(codeArgc, codeArgv);
+ int result = compiler.run(codeArgc, codeArgv);
+ fprintf(stderr, "result: %d\n", result);
+ return result;
}
return 0;
diff --git a/libacc/test b/libacc/test
index 17d7b55..be883a6 100755
--- a/libacc/test
+++ b/libacc/test
@@ -1,2 +1,3 @@
#!/bin/sh
-g++ acc.cpp -ldl -o tests/acc && tests/acc tests/otcc.c -T tests/otcc.out && diff tests/otcc.out tests/otcc.out-orig
+g++ acc.cpp -ldl -o tests/acc && tests/acc tests/otcc.c -a x86 -d tests/otcc.out && diff tests/otcc.out tests/otcc.out-orig
+tests/acc tests/simplest.c
diff --git a/libacc/tests/simplest.c b/libacc/tests/simplest.c
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/libacc/tests/simplest.c
@@ -0,0 +1 @@
+main() {}