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.
This commit is contained in:
parent
894c5cd214
commit
7fcdf1c5f8
1 changed files with 43 additions and 7 deletions
|
|
@ -481,14 +481,27 @@ class Compiler : public ErrorSink {
|
|||
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 @@ class Compiler : public ErrorSink {
|
|||
*/
|
||||
virtual size_t alignmentOf(Type* pType){
|
||||
switch(pType->tag) {
|
||||
case TY_CHAR:
|
||||
return 1;
|
||||
case TY_DOUBLE:
|
||||
return 8;
|
||||
default:
|
||||
|
|
@ -1477,6 +1492,15 @@ class Compiler : public ErrorSink {
|
|||
}
|
||||
}
|
||||
|
||||
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 @@ class Compiler : public ErrorSink {
|
|||
* 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 @@ class Compiler : public ErrorSink {
|
|||
}
|
||||
}
|
||||
|
||||
virtual size_t stackAlignmentOf(Type* pType){
|
||||
return 4;
|
||||
}
|
||||
|
||||
virtual size_t stackSizeOf(Type* pType) {
|
||||
switch(pType->tag) {
|
||||
case TY_DOUBLE:
|
||||
|
|
@ -4538,9 +4571,12 @@ class Compiler : public ErrorSink {
|
|||
}
|
||||
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 @@ class Compiler : public ErrorSink {
|
|||
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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue