Merge change 6551

* changes:
  Implement global, local, and stack based float and double variables.
This commit is contained in:
Android (Google) Code Review 2009-07-08 16:51:30 -07:00
commit 023931180c
2 changed files with 135 additions and 27 deletions

View File

@ -360,7 +360,7 @@ class Compiler : public ErrorSink {
* 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 @@ class Compiler : public ErrorSink {
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 @@ class Compiler : public ErrorSink {
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 @@ class Compiler : public ErrorSink {
}
/**
* 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 @@ class Compiler : public ErrorSink {
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 @@ class Compiler : public ErrorSink {
}
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 @@ class Compiler : public ErrorSink {
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 @@ class Compiler : public ErrorSink {
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 @@ class Compiler : public ErrorSink {
}
/**
* 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 @@ class Compiler : public ErrorSink {
}
}
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 @@ class Compiler : public ErrorSink {
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 @@ class Compiler : public ErrorSink {
}
/**
* 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 @@ class Compiler : public ErrorSink {
return mpBase->sizeOf(pType);
}
virtual size_t stackSizeOf(Type* pType) {
return mpBase->stackSizeOf(pType);
}
virtual Type* getR0Type() {
return mpBase->getR0Type();
}
@ -2795,7 +2871,7 @@ class Compiler : public ErrorSink {
// 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 @@ class Compiler : public ErrorSink {
/* 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 @@ class Compiler : public ErrorSink {
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 @@ class Compiler : public ErrorSink {
/* assignment */
next();
expr();
pGen->storeR0(n);
pGen->storeR0(n, pVI->pType);
} else if (tok != '(') {
/* variable */
if (!n) {
@ -3445,7 +3525,7 @@ class Compiler : public ErrorSink {
if (accept('=')) {
/* assignment */
expr();
pGen->storeR0(variableAddress);
pGen->storeR0(variableAddress, pDecl);
}
if (tok == ',')
next();
@ -3517,7 +3597,9 @@ class Compiler : public ErrorSink {
// 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 @@ class Compiler : public ErrorSink {
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 @@ class Compiler : public ErrorSink {
}
}
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;
}

View File

@ -14,11 +14,35 @@ double itod(int i) {
return i;
}
float f0, f1;
double d0, d1;
void testVars(float arg0, float arg1, double arg2, double arg3) {
float local0, local1;
double local2, local3;
f0 = arg0;
f1 = arg1;
d0 = arg2;
d1 = arg3;
local0 = arg0;
local1 = arg1;
local2 = arg2;
local3 = arg3;
printf("globals: %g %g %g %g\n", f0, f1, d0, d1);
printf("args: %g %g %g %g\n", arg0, arg1, arg2, arg3);
printf("locals: %g %g %g %g\n", local0, local1, local2, local3);
* (float*) & f0 = 1.1f;
* (double*) & d0 = 3.3;
printf("pointer tests: %g %g %g %g\n", f0, f1, d0, d1);
}
int main() {
printf("int: %d float: %g double: %g\n", 1, 2.2f, 3.3);
printf(" ftoi(1.4f)=%d\n", ftoi(1.4f));
printf(" dtoi(2.4f)=%d\n", dtoi(2.4f));
printf(" itof(3)=%g\n", itof(3));
printf(" itod(4)=%g\n", itod(4));
testVars(1.0f, 2.0f, 3.0, 4.0);
return 0;
}