Merge change 6498

* changes:
  Some x86 floating point code works.
This commit is contained in:
Android (Google) Code Review 2009-07-08 13:13:40 -07:00
commit d773ff289e
2 changed files with 136 additions and 61 deletions

View File

@ -37,7 +37,6 @@
#define PROVIDE_X64_CODEGEN
#endif
#ifdef PROVIDE_ARM_CODEGEN
#include "disassem.h"
#endif
@ -297,11 +296,8 @@ class Compiler : public ErrorSink {
/* load immediate value to R0 */
virtual void li(int i, Type* pType) = 0;
/* load floating point immediate value to R0 */
virtual void lif(float f, Type* pType) = 0;
/* load double-precision floating point immediate value to R0 */
virtual void lid(double d, Type* pType) = 0;
/* Load floating point value from global address. */
virtual void loadFloat(int address, Type* pType) = 0;
/* Jump to a target, and return the address of the word that
* holds the target data, in case it needs to be fixed up later.
@ -389,8 +385,9 @@ class Compiler : public ErrorSink {
virtual int beginFunctionCallArguments() = 0;
/* Emit code to store R0 to the stack at byte offset l.
* Returns stack size of object (typically 4 or 8 bytes)
*/
virtual void storeR0ToArg(int l) = 0;
virtual size_t storeR0ToArg(int l) = 0;
/* Patch the function call preamble.
* a is the address returned from beginFunctionCallArguments
@ -461,6 +458,10 @@ class Compiler : public ErrorSink {
*/
virtual size_t sizeOf(Type* type) = 0;
virtual Type* getR0Type() {
return mExpressionStack.back();
}
protected:
/*
* Output a byte. Handles all values, 0..ff.
@ -494,6 +495,7 @@ class Compiler : public ErrorSink {
void assert(bool test) {
if (!test) {
* (char*) 0 = 0;
error("code generator assertion failed.");
}
}
@ -502,10 +504,6 @@ class Compiler : public ErrorSink {
mExpressionStack.back() = pType;
}
Type* getR0Type() {
return mExpressionStack.back();
}
Type* getTOSType() {
return mExpressionStack[mExpressionStack.size()-2];
}
@ -529,6 +527,15 @@ class Compiler : public ErrorSink {
return collapsedTag[tag];
}
TypeTag collapseTypeR0() {
return collapseType(getR0Type()->tag);
}
bool isFloatType(Type* pType) {
TypeTag tag = pType->tag;
return tag == TY_FLOAT || tag == TY_DOUBLE;
}
private:
Vector<Type*> mExpressionStack;
CodeBuf* pCodeBuf;
@ -613,16 +620,8 @@ class Compiler : public ErrorSink {
setR0Type(pType);
}
virtual void lif(float f, Type* pType) {
union { float f; int i; } converter;
converter.f = f;
li(converter.i, pType);
}
virtual void lid(double d, Type* pType) {
union { double d; int i[2]; } converter;
converter.d = d;
error("lid: unimplemented");
virtual void loadFloat(int address, Type* pType) {
error("Unimplemented.\n");
setR0Type(pType);
}
@ -843,7 +842,7 @@ class Compiler : public ErrorSink {
}
virtual void loadR0(int ea, bool isIncDec, int op, Type* pType) {
LOG_API("loadR0(%d, %d, %d);\n", ea, isIncDec, op);
LOG_API("loadR0(%d, %d, %d, %d);\n", ea, isIncDec, op, pType);
if (ea < LOCAL) {
// Local, fp relative
if (ea < -4095 || ea > 4095) {
@ -891,10 +890,16 @@ class Compiler : public ErrorSink {
}
virtual void convertR0(Type* pType){
if (bitsSame(pType, getR0Type())) {
return;
Type* pR0Type = getR0Type();
if (bitsSame(pType, pR0Type)) {
// do nothing special
} else if (isFloatType(pType) && isFloatType(pR0Type)) {
// do nothing special, both held in same register on x87.
} else {
error("Incompatible types old: %d new: %d",
pR0Type->tag, pType->tag);
}
error("Incompatible types");
setR0Type(pType);
}
virtual int beginFunctionCallArguments() {
@ -902,12 +907,13 @@ class Compiler : public ErrorSink {
return o4(0xE24DDF00); // Placeholder
}
virtual void storeR0ToArg(int l) {
virtual size_t storeR0ToArg(int l) {
LOG_API("storeR0ToArg(%d);\n", l);
if (l < 0 || l > 4096-4) {
error("l out of range for stack offset: 0x%08x", l);
}
o4(0xE58D0000 + l); // str r0, [sp, #4]
return 4;
}
virtual void endFunctionCallArguments(int a, int l) {
@ -1169,18 +1175,19 @@ class Compiler : public ErrorSink {
setR0Type(pType);
}
virtual void lif(float f, Type* pType) {
union { float f; int i; } converter;
converter.f = f;
virtual void loadFloat(int address, Type* pType) {
setR0Type(pType);
error("unimplemented: lif");
}
virtual void lid(double d, Type* pType) {
union { double d; int i[2]; } converter;
converter.d = d;
setR0Type(pType);
error("unimplemented: lid");
switch (pType->tag) {
case TY_FLOAT:
oad(0x05D9, address); // flds
break;
case TY_DOUBLE:
oad(0x05DD, address); // fldl
break;
default:
assert(false);
break;
}
}
virtual int gjmp(int t) {
@ -1287,19 +1294,44 @@ class Compiler : public ErrorSink {
}
virtual void convertR0(Type* pType){
if (bitsSame(pType, getR0Type())) {
Type* pR0Type = getR0Type();
if (pR0Type == NULL) {
error("don't know R0Type");
setR0Type(pType);
return;
}
error("convertR0: unsupported conversion %d <- %d", pType->tag,
getR0Type()->tag);
if (bitsSame(pType, pR0Type)) {
// do nothing special
} else if (isFloatType(pType) && isFloatType(pR0Type)) {
// do nothing special, both held in same register on x87.
} else {
error("Incompatible types old: %d new: %d",
pR0Type->tag, pType->tag);
}
setR0Type(pType);
}
virtual int beginFunctionCallArguments() {
return oad(0xec81, 0); /* sub $xxx, %esp */
}
virtual void storeR0ToArg(int l) {
oad(0x248489, l); /* movl %eax, xxx(%esp) */
virtual size_t storeR0ToArg(int l) {
Type* pR0Type = getR0Type();
TypeTag r0ct = collapseType(pR0Type->tag);
switch(r0ct) {
case TY_INT:
oad(0x248489, l); /* movl %eax, xxx(%esp) */
return 4;
case TY_FLOAT:
oad(0x249CD9, l); /* fstps xxx(%esp) */
return 4;
case TY_DOUBLE:
oad(0x249CDD, l); /* fstpl xxx(%esp) */
return 8;
default:
assert(false);
return 0;
}
}
virtual void endFunctionCallArguments(int a, int l) {
@ -1480,14 +1512,9 @@ class Compiler : public ErrorSink {
mpBase->li(t, pType);
}
virtual void lif(float f, Type* pType) {
fprintf(stderr, "lif(%g)\n", f);
mpBase->lif(f, pType);
}
virtual void lid(double d, Type* pType) {
fprintf(stderr, "lid(%g)\n", d);
mpBase->lid(d, pType);
virtual void loadFloat(int address, Type* pType) {
fprintf(stderr, "loadFloat(%d, type)\n", address);
mpBase->loadFloat(address, pType);
}
virtual int gjmp(int t) {
@ -1550,7 +1577,7 @@ class Compiler : public ErrorSink {
}
virtual void loadR0(int ea, bool isIncDec, int op, Type* pType) {
fprintf(stderr, "loadR0(%d, %d, %d)\n", ea, isIncDec, op);
fprintf(stderr, "loadR0(%d, %d, %d, pType)\n", ea, isIncDec, op);
mpBase->loadR0(ea, isIncDec, op, pType);
}
@ -1565,9 +1592,9 @@ class Compiler : public ErrorSink {
return result;
}
virtual void storeR0ToArg(int l) {
virtual size_t storeR0ToArg(int l) {
fprintf(stderr, "storeR0ToArg(%d)\n", l);
mpBase->storeR0ToArg(l);
return mpBase->storeR0ToArg(l);
}
virtual void endFunctionCallArguments(int a, int l) {
@ -1629,6 +1656,10 @@ class Compiler : public ErrorSink {
virtual size_t sizeOf(Type* pType){
return mpBase->sizeOf(pType);
}
virtual Type* getR0Type() {
return mpBase->getR0Type();
}
};
#endif // PROVIDE_TRACE_CODEGEN
@ -2185,6 +2216,8 @@ class Compiler : public ErrorSink {
Type* mkpIntFn;
Type* mkpIntPtr;
Type* mkpCharPtr;
Type* mkpFloatPtr;
Type* mkpDoublePtr;
Type* mkpPtrIntFn;
InputStream* file;
@ -2742,9 +2775,17 @@ class Compiler : public ErrorSink {
if (t == TOK_NUM) {
pGen->li(a, mkpInt);
} else if (t == TOK_NUM_FLOAT) {
pGen->lif(ad, mkpFloat);
// Align to 4-byte boundary
glo = (char*) (((intptr_t) glo + 3) & -4);
* (float*) glo = (float) ad;
pGen->loadFloat((int) glo, mkpFloat);
glo += 4;
} else if (t == TOK_NUM_DOUBLE) {
pGen->lid(ad, mkpDouble);
// Align to 8-byte boundary
glo = (char*) (((intptr_t) glo + 7) & -8);
* (double*) glo = ad;
pGen->loadFloat((int) glo, mkpDouble);
glo += 8;
} else if (c == 2) {
/* -, +, !, ~ */
unary(false);
@ -2807,7 +2848,11 @@ class Compiler : public ErrorSink {
/* forward reference: try dlsym */
if (!n) {
n = (intptr_t) dlsym(RTLD_DEFAULT, nameof(t));
pVI->pType = mkpIntFn;
if (tok == '(') {
pVI->pType = mkpIntFn;
} else {
pVI->pType = mkpInt;
}
pVI->pAddress = (void*) n;
}
if ((tok == '=') & allowAssignment) {
@ -2830,27 +2875,49 @@ class Compiler : public ErrorSink {
/* function call */
if (accept('(')) {
if (n == 1)
Type* pArgList = NULL;
VariableInfo* pVI = NULL;
if (n == 1) { // Indirect function call, push address of fn.
pArgList = pGen->getR0Type()->pTail;
pGen->pushR0();
} else {
pVI = VI(t);
pArgList = pVI->pType->pTail;
}
bool varArgs = pArgList == NULL;
/* push args and invert order */
a = pGen->beginFunctionCallArguments();
int l = 0;
while (tok != ')' && tok != EOF) {
if (! varArgs && !pArgList) {
error ("Unexpected argument.");
}
expr();
pGen->storeR0ToArg(l);
l = l + 4;
Type* pTargetType;
if (pArgList) {
pTargetType = pArgList->pHead;
pArgList = pArgList->pTail;
} else {
pTargetType = pGen->getR0Type();
if (pTargetType->tag == TY_FLOAT) {
pTargetType = mkpDouble;
}
}
pGen->convertR0(pTargetType);
l += pGen->storeR0ToArg(l);
if (accept(',')) {
// fine
} else if ( tok != ')') {
error("Expected ',' or ')'");
}
}
if (! varArgs && pArgList) {
error ("Expected more argument(s).");
}
pGen->endFunctionCallArguments(a, l);
skip(')');
if (!n) {
/* forward reference */
VariableInfo* pVI = VI(t);
pVI->pForward = (void*) pGen->callForward((int) pVI->pForward,
pVI->pType);
} else if (n == 1) {
@ -3595,6 +3662,8 @@ public:
mkpIntFn = createType(TY_FUNC, mkpInt, NULL, mGlobalArena);
mkpIntPtr = createPtrType(mkpInt, mGlobalArena);
mkpCharPtr = createPtrType(mkpChar, mGlobalArena);
mkpFloatPtr = createPtrType(mkpFloat, mGlobalArena);
mkpDoublePtr = createPtrType(mkpDouble, mGlobalArena);
mkpPtrIntFn = createPtrType(mkpIntFn, mGlobalArena);
}

View File

@ -0,0 +1,6 @@
int main() {
printf("int: %d float: %g double: %g\n", 1, 2.2f, 3.3);
return 42;
}