Implement global, local, and stack based float and double variables.
diff --git a/libacc/acc.cpp b/libacc/acc.cpp
index 38c23d0..e4e5baa 100644
--- a/libacc/acc.cpp
+++ b/libacc/acc.cpp
@@ -360,7 +360,7 @@
* argument, addressed relative to FP.
* else it is an absolute global address.
*/
- virtual void storeR0(int ea) = 0;
+ virtual void storeR0(int ea, Type* pType) = 0;
/* load R0 from a variable.
* If ea <= LOCAL, then this is a local variable, or an
@@ -449,15 +449,20 @@
virtual int jumpOffset() = 0;
/**
- * Stack alignment (in bytes) for this type of data
+ * Memory alignment (in bytes) for this type of data
*/
- virtual size_t stackAlignment(Type* type) = 0;
+ virtual size_t alignment(Type* type) = 0;
/**
* Array element alignment (in bytes) for this type of data.
*/
virtual size_t sizeOf(Type* type) = 0;
+ /**
+ * Stack argument size of this data type.
+ */
+ virtual size_t stackSizeOf(Type* pType) = 0;
+
virtual Type* getR0Type() {
return mExpressionStack.back();
}
@@ -823,7 +828,7 @@
setR0Type(pPointerType);
}
- virtual void storeR0(int ea) {
+ virtual void storeR0(int ea, Type* pType) {
LOG_API("storeR0(%d);\n", ea);
if (ea < LOCAL) {
// Local, fp relative
@@ -1056,9 +1061,9 @@
}
/**
- * Stack alignment (in bytes) for this type of data
+ * alignment (in bytes) for this type of data
*/
- virtual size_t stackAlignment(Type* pType){
+ virtual size_t alignment(Type* pType){
switch(pType->tag) {
case TY_DOUBLE:
return 8;
@@ -1086,6 +1091,16 @@
return 4;
}
}
+
+ virtual size_t stackSizeOf(Type* pType) {
+ switch(pType->tag) {
+ case TY_DOUBLE:
+ return 8;
+ default:
+ return 4;
+ }
+ }
+
private:
static FILE* disasmOut;
@@ -1238,7 +1253,25 @@
}
virtual void pushR0() {
- o(0x50); /* push %eax */
+ Type* pR0Type = getR0Type();
+ TypeTag r0ct = collapseType(pR0Type->tag);
+ switch(r0ct) {
+ case TY_INT:
+ o(0x50); /* push %eax */
+ break;
+ case TY_FLOAT:
+ o(0x50); /* push %eax */
+ o(0x241cd9); // fstps 0(%esp)
+ break;
+ case TY_DOUBLE:
+ o(0x50); /* push %eax */
+ o(0x50); /* push %eax */
+ o(0x241cdd); // fstpl 0(%esp)
+ break;
+ default:
+ error("pushR0 %d", r0ct);
+ break;
+ }
pushType();
}
@@ -1253,6 +1286,12 @@
case TY_CHAR:
o(0x0188); /* movl %eax/%al, (%ecx) */
break;
+ case TY_FLOAT:
+ o(0x19d9); /* fstps (%ecx) */
+ break;
+ case TY_DOUBLE:
+ o(0x19dd); /* fstpl (%ecx) */
+ break;
default:
error("storeR0ToTOS: unsupported type");
break;
@@ -1281,8 +1320,30 @@
setR0Type(pPointerType);
}
- virtual void storeR0(int ea) {
- gmov(6, ea); /* mov %eax, EA */
+ virtual void storeR0(int ea, Type* pType) {
+ TypeTag tag = pType->tag;
+ switch (tag) {
+ case TY_INT:
+ gmov(6, ea); /* mov %eax, EA */
+ break;
+ case TY_FLOAT:
+ if (ea < -LOCAL || ea > LOCAL) {
+ oad(0x1dd9, ea); // fstps ea
+ } else {
+ oad(0x9dd9, ea); // fstps ea(%ebp)
+ }
+ break;
+ case TY_DOUBLE:
+ if (ea < -LOCAL || ea > LOCAL) {
+ oad(0x1ddd, ea); // fstpl ea
+ } else {
+ oad(0x9ddd, ea); // fstpl ea(%ebp)
+ }
+ break;
+ default:
+ error("Unable to store to type %d", tag);
+ break;
+ }
}
virtual void loadR0(int ea, bool isIncDec, int op, Type* pType) {
@@ -1448,9 +1509,9 @@
}
/**
- * Stack alignment (in bytes) for this type of data
+ * Alignment (in bytes) for this type of data
*/
- virtual size_t stackAlignment(Type* pType){
+ virtual size_t alignment(Type* pType){
switch(pType->tag) {
case TY_DOUBLE:
return 8;
@@ -1479,6 +1540,15 @@
}
}
+ virtual size_t stackSizeOf(Type* pType) {
+ switch(pType->tag) {
+ case TY_DOUBLE:
+ return 8;
+ default:
+ return 4;
+ }
+ }
+
private:
/** Output 1 to 4 bytes.
@@ -1626,9 +1696,9 @@
mpBase->leaR0(ea, pPointerType);
}
- virtual void storeR0(int ea) {
- fprintf(stderr, "storeR0(%d)\n", ea);
- mpBase->storeR0(ea);
+ virtual void storeR0(int ea, Type* pType) {
+ fprintf(stderr, "storeR0(%d, pType)\n", ea);
+ mpBase->storeR0(ea, pType);
}
virtual void loadR0(int ea, bool isIncDec, int op, Type* pType) {
@@ -1699,10 +1769,10 @@
}
/**
- * Stack alignment (in bytes) for this type of data
+ * Alignment (in bytes) for this type of data
*/
- virtual size_t stackAlignment(Type* pType){
- return mpBase->stackAlignment(pType);
+ virtual size_t alignment(Type* pType){
+ return mpBase->alignment(pType);
}
/**
@@ -1712,6 +1782,12 @@
return mpBase->sizeOf(pType);
}
+
+ virtual size_t stackSizeOf(Type* pType) {
+ return mpBase->stackSizeOf(pType);
+ }
+
+
virtual Type* getR0Type() {
return mpBase->getR0Type();
}
@@ -2795,7 +2871,7 @@
// This while loop merges multiple adjacent string constants.
while (tok == '"') {
while (ch != '"' && ch != EOF) {
- *allocGlobalSpace(1) = getq();
+ *allocGlobalSpace(1,1) = getq();
}
if (ch != '"') {
error("Unterminated string constant.");
@@ -2806,7 +2882,7 @@
/* Null terminate */
*glo = 0;
/* align heap */
- allocGlobalSpace((char*) (((intptr_t) glo + 4) & -4) - glo);
+ allocGlobalSpace(1,(char*) (((intptr_t) glo + 4) & -4) - glo);
return true;
}
@@ -2864,6 +2940,10 @@
t = TOK_INT;
} else if (typeEqual(pCast, mkpCharPtr)) {
t = TOK_CHAR;
+ } else if (typeEqual(pCast, mkpFloatPtr)) {
+ t = TOK_FLOAT;
+ } else if (typeEqual(pCast, mkpDoublePtr)) {
+ t = TOK_DOUBLE;
} else if (typeEqual(pCast, mkpPtrIntFn)){
t = 0;
} else {
@@ -2914,7 +2994,7 @@
/* assignment */
next();
expr();
- pGen->storeR0(n);
+ pGen->storeR0(n, pVI->pType);
} else if (tok != '(') {
/* variable */
if (!n) {
@@ -3445,7 +3525,7 @@
if (accept('=')) {
/* assignment */
expr();
- pGen->storeR0(variableAddress);
+ pGen->storeR0(variableAddress, pDecl);
}
if (tok == ',')
next();
@@ -3517,7 +3597,9 @@
// it's a variable declaration
for(;;) {
if (name && !name->pAddress) {
- name->pAddress = (int*) allocGlobalSpace(4);
+ name->pAddress = (int*) allocGlobalSpace(
+ pGen->alignment(name->pType),
+ pGen->sizeOf(name->pType));
}
if (accept('=')) {
if (tok == TOK_NUM) {
@@ -3563,7 +3645,7 @@
addLocalSymbol(pArg);
/* read param name and compute offset */
VI(pArg->id)->pAddress = (void*) a;
- a = a + 4;
+ a = a + pGen->stackSizeOf(pArg);
argCount++;
}
rsym = loc = 0;
@@ -3578,13 +3660,15 @@
}
}
- char* allocGlobalSpace(int bytes) {
- if (glo - pGlobalBase + bytes > ALLOC_SIZE) {
+ char* allocGlobalSpace(size_t alignment, size_t bytes) {
+ size_t base = (((size_t) glo) + alignment - 1) & ~(alignment-1);
+ size_t end = base + bytes;
+ if ((end - (size_t) pGlobalBase) > ALLOC_SIZE) {
error("Global space exhausted");
return NULL;
}
- char* result = glo;
- glo += bytes;
+ char* result = (char*) base;
+ glo = (char*) end;
return result;
}