Adjust stack alignment for local variables to work more like arguments.
This makes it easier to generate frame-pointer-relative addresses for ARM.
Prior to this we had stored char sized local variables in the highest
address of the 4-byte stack allocation. Now we store "char"s in the
lowest address of the 4-byte stack allocation, just like chars are
passed as arguments.
We now store global chars on byte boundaries.
diff --git a/libacc/acc.cpp b/libacc/acc.cpp
index a21fd74..877cc4d 100644
--- a/libacc/acc.cpp
+++ b/libacc/acc.cpp
@@ -481,14 +481,27 @@
virtual size_t sizeOf(Type* type) = 0;
/**
- * Stack argument size of this data type.
+ * Stack alignment of this type of data
+ */
+ virtual size_t stackAlignmentOf(Type* pType) = 0;
+
+ /**
+ * Argument stack argument size of this data type.
*/
virtual size_t stackSizeOf(Type* pType) = 0;
- virtual Type* getR0Type() {
+ Type* getR0Type() {
return mExpressionStack.back().pType;
}
+ ExpressionType getR0ExpressionType() {
+ return mExpressionStack.back().et;
+ }
+
+ void setR0ExpressionType(ExpressionType et) {
+ mExpressionStack.back().et = et;
+ }
+
protected:
/*
* Output a byte. Handles all values, 0..ff.
@@ -1450,6 +1463,8 @@
*/
virtual size_t alignmentOf(Type* pType){
switch(pType->tag) {
+ case TY_CHAR:
+ return 1;
case TY_DOUBLE:
return 8;
default:
@@ -1477,6 +1492,15 @@
}
}
+ virtual size_t stackAlignmentOf(Type* pType) {
+ switch(pType->tag) {
+ case TY_DOUBLE:
+ return 8;
+ default:
+ return 4;
+ }
+ }
+
virtual size_t stackSizeOf(Type* pType) {
switch(pType->tag) {
case TY_DOUBLE:
@@ -2381,7 +2405,12 @@
* Alignment (in bytes) for this type of data
*/
virtual size_t alignmentOf(Type* pType){
- return 4;
+ switch (pType->tag) {
+ case TY_CHAR:
+ return 1;
+ default:
+ return 4;
+ }
}
/**
@@ -2404,6 +2433,10 @@
}
}
+ virtual size_t stackAlignmentOf(Type* pType){
+ return 4;
+ }
+
virtual size_t stackSizeOf(Type* pType) {
switch(pType->tag) {
case TY_DOUBLE:
@@ -4538,9 +4571,12 @@
}
int variableAddress = 0;
addLocalSymbol(pDecl);
- size_t alignment = pGen->alignmentOf(pDecl);
- loc = (loc + alignment - 1) & ~ (alignment-1);
- loc = loc + pGen->sizeOf(pDecl);
+ size_t alignment = pGen->stackAlignmentOf(pDecl);
+ size_t alignmentMask = ~ (alignment - 1);
+ size_t sizeOf = pGen->sizeOf(pDecl);
+ loc = (loc + alignment - 1) & alignmentMask;
+ size_t alignedSize = (sizeOf + alignment - 1) & alignmentMask;
+ loc = loc + alignedSize;
variableAddress = -loc;
VI(pDecl->id)->pAddress = (void*) variableAddress;
if (accept('=')) {
@@ -4674,7 +4710,7 @@
Type* pArg = pP->pHead;
addLocalSymbol(pArg);
/* read param name and compute offset */
- size_t alignment = pGen->alignmentOf(pArg);
+ size_t alignment = pGen->stackAlignmentOf(pArg);
a = (a + alignment - 1) & ~ (alignment-1);
VI(pArg->id)->pAddress = (void*) a;
a = a + pGen->stackSizeOf(pArg);