Merge change 1819
* changes:
ACC ARM code gen: Implement global variables.
diff --git a/libacc/acc.cpp b/libacc/acc.cpp
index 50d90dd..559b146 100644
--- a/libacc/acc.cpp
+++ b/libacc/acc.cpp
@@ -164,9 +164,7 @@
virtual void storeEAX(int ea) = 0;
- virtual void loadEAX(int ea) = 0;
-
- virtual void postIncrementOrDecrement(int n, int op) = 0;
+ virtual void loadEAX(int ea, bool isIncDec, int op) = 0;
virtual int beginFunctionCallArguments() = 0;
@@ -429,62 +427,90 @@
virtual void leaEAX(int ea) {
fprintf(stderr, "leaEAX(%d);\n", ea);
- if (ea < -1023 || ea > 1023 || ((ea & 3) != 0)) {
- error("Offset out of range: %08x", ea);
- }
- if (ea < 0) {
- o4(0xE24B0F00 | (0xff & ((-ea) >> 2))); // sub r0, fp, #ea
+ if (ea < LOCAL) {
+ // Local, fp relative
+ if (ea < -1023 || ea > 1023 || ((ea & 3) != 0)) {
+ error("Offset out of range: %08x", ea);
+ }
+ if (ea < 0) {
+ o4(0xE24B0F00 | (0xff & ((-ea) >> 2))); // sub r0, fp, #ea
+ } else {
+ o4(0xE28B0F00 | (0xff & (ea >> 2))); // add r0, fp, #ea
+ }
} else {
- o4(0xE28B0F00 | (0xff & (ea >> 2))); // add r0, fp, #ea
+ // Global, absolute.
+ o4(0xE59F0000); // ldr r0, .L1
+ o4(0xEA000000); // b .L99
+ o4(ea); // .L1: .word 0
+ // .L99:
}
-
}
virtual void storeEAX(int ea) {
fprintf(stderr, "storeEAX(%d);\n", ea);
- if (ea < -4095 || ea > 4095) {
- error("Offset out of range: %08x", ea);
- }
- if (ea < 0) {
- o4(0xE50B0000 | (0xfff & (-ea))); // str r0, [fp,#-ea]
- } else {
- o4(0xE58B0000 | (0xfff & ea)); // str r0, [fp,#ea]
+ if (ea < LOCAL) {
+ // Local, fp relative
+ if (ea < -4095 || ea > 4095) {
+ error("Offset out of range: %08x", ea);
+ }
+ if (ea < 0) {
+ o4(0xE50B0000 | (0xfff & (-ea))); // str r0, [fp,#-ea]
+ } else {
+ o4(0xE58B0000 | (0xfff & ea)); // str r0, [fp,#ea]
+ }
+ } else{
+ // Global, absolute
+ o4(0xE59F1000); // ldr r1, .L1
+ o4(0xEA000000); // b .L99
+ o4(ea); // .L1: .word 0
+ o4(0xE5810000); // .L99: str r0, [r1]
}
}
- virtual void loadEAX(int ea) {
- fprintf(stderr, "loadEAX(%d);\n", ea);
- if (ea < -4095 || ea > 4095) {
- error("Offset out of range: %08x", ea);
- }
- if (ea < 0) {
- o4(0xE51B0000 | (0xfff & (-ea))); // ldr r0, [fp,#-ea]
+ virtual void loadEAX(int ea, bool isIncDec, int op) {
+ fprintf(stderr, "loadEAX(%d, %d, %d);\n", ea, isIncDec, op);
+ if (ea < LOCAL) {
+ // Local, fp relative
+ if (ea < -4095 || ea > 4095) {
+ error("Offset out of range: %08x", ea);
+ }
+ if (ea < 0) {
+ o4(0xE51B0000 | (0xfff & (-ea))); // ldr r0, [fp,#-ea]
+ } else {
+ o4(0xE59B0000 | (0xfff & ea)); // ldr r0, [fp,#ea]
+ }
} else {
- o4(0xE59B0000 | (0xfff & ea)); // ldr r0, [fp,#ea]
+ // Global, absolute
+ o4(0xE59F2000); // ldr r2, .L1
+ o4(0xEA000000); // b .L99
+ o4(ea); // .L1: .word ea
+ o4(0xE5920000); // .L99: ldr r0, [r2]
}
- }
- virtual void postIncrementOrDecrement(int ea, int op) {
- fprintf(stderr, "postIncrementOrDecrement(%d, %d);\n", ea, op);
- /* R0 has the original value.
- */
- switch (op) {
- case OP_INCREMENT:
- o4(0xE2801001); // add r1, r0, #1
- break;
- case OP_DECREMENT:
- o4(0xE2401001); // sub r1, r0, #1
- break;
- default:
- error("unknown opcode: %d", op);
- }
- if (ea < -4095 || ea > 4095) {
- error("Offset out of range: %08x", ea);
- }
- if (ea < 0) {
- o4(0xE50B1000 | (0xfff & (-ea))); // str r1, [fp,#-ea]
- } else {
- o4(0xE58B1000 | (0xfff & ea)); // str r1, [fp,#ea]
+ if (isIncDec) {
+ switch (op) {
+ case OP_INCREMENT:
+ o4(0xE2801001); // add r1, r0, #1
+ break;
+ case OP_DECREMENT:
+ o4(0xE2401001); // sub r1, r0, #1
+ break;
+ default:
+ error("unknown opcode: %d", op);
+ }
+ if (ea < LOCAL) {
+ // Local, fp relative
+ // Don't need range check, was already checked above
+ if (ea < 0) {
+ o4(0xE50B1000 | (0xfff & (-ea))); // str r1, [fp,#-ea]
+ } else {
+ o4(0xE58B1000 | (0xfff & ea)); // str r1, [fp,#ea]
+ }
+ } else{
+ // Global, absolute
+ // r2 is already set up from before.
+ o4(0xE5821000); // str r1, [r2]
+ }
}
}
@@ -723,15 +749,14 @@
gmov(6, ea); /* mov %eax, EA */
}
- virtual void loadEAX(int ea) {
+ virtual void loadEAX(int ea, bool isIncDec, int op) {
gmov(8, ea); /* mov EA, %eax */
- }
-
- virtual void postIncrementOrDecrement(int n, int op) {
- /* Implement post-increment or post decrement.
- */
- gmov(0, n); /* 83 ADD */
- o(decodeOp(op));
+ if (isIncDec) {
+ /* Implement post-increment or post decrement.
+ */
+ gmov(0, ea); /* 83 ADD */
+ o(decodeOp(op));
+ }
}
virtual int beginFunctionCallArguments() {
@@ -1117,9 +1142,8 @@
pGen->storeEAX(n);
} else if (tok != '(') {
/* variable */
- pGen->loadEAX(n);
+ pGen->loadEAX(n, tokl == 11, tokc);
if (tokl == 11) {
- pGen->postIncrementOrDecrement(n, tokc);
next();
}
}