Loading libacc/acc.cpp +65 −10 Original line number Diff line number Diff line Loading @@ -532,7 +532,10 @@ class Compiler : public ErrorSink { } bool isFloatType(Type* pType) { TypeTag tag = pType->tag; return isFloatTag(pType->tag); } bool isFloatTag(TypeTag tag) { return tag == TY_FLOAT || tag == TY_DOUBLE; } Loading Loading @@ -1283,6 +1286,9 @@ class Compiler : public ErrorSink { } virtual void loadR0(int ea, bool isIncDec, int op, Type* pType) { TypeTag tag = collapseType(pType->tag); switch (tag) { case TY_INT: gmov(8, ea); /* mov EA, %eax */ if (isIncDec) { /* Implement post-increment or post decrement. Loading @@ -1290,13 +1296,38 @@ class Compiler : public ErrorSink { gmov(0, ea); /* 83 ADD */ o(decodeOp(op)); } break; case TY_FLOAT: if (ea < -LOCAL || ea > LOCAL) { oad(0x05d9, ea); // flds ea } else { oad(0x85d9, ea); // flds ea(%ebp) } if (isIncDec) { error("inc/dec not implemented for float."); } break; case TY_DOUBLE: if (ea < -LOCAL || ea > LOCAL) { oad(0x05dd, ea); // fldl ea } else { oad(0x85dd, ea); // fldl ea(%ebp) } if (isIncDec) { error("inc/dec not implemented for double."); } break; default: error("Unable to load type %d", tag); break; } setR0Type(pType); } virtual void convertR0(Type* pType){ Type* pR0Type = getR0Type(); if (pR0Type == NULL) { error("don't know R0Type"); assert(false); setR0Type(pType); return; } Loading @@ -1304,10 +1335,34 @@ class Compiler : public ErrorSink { // do nothing special } else if (isFloatType(pType) && isFloatType(pR0Type)) { // do nothing special, both held in same register on x87. } else { TypeTag r0Tag = collapseType(pR0Type->tag); TypeTag destTag = collapseType(pType->tag); if (r0Tag == TY_INT && isFloatTag(destTag)) { // Convert R0 from int to float o(0x50); // push %eax o(0x2404DB); // fildl 0(%esp) o(0x58); // pop %eax } else if (isFloatTag(r0Tag) && destTag == TY_INT) { // Convert R0 from float to int. Complicated because // need to save and restore the rounding mode. o(0x50); // push %eax o(0x50); // push %eax o(0x02247cD9); // fnstcw 2(%esp) o(0x2444b70f); // movzwl 2(%esp), %eax o(0x02); o(0x0cb4); // movb $12, %ah o(0x24048966); // movw %ax, 0(%esp) o(0x242cd9); // fldcw 0(%esp) o(0x04245cdb); // fistpl 4(%esp) o(0x02246cd9); // fldcw 2(%esp) o(0x58); // pop %eax o(0x58); // pop %eax } else { error("Incompatible types old: %d new: %d", pR0Type->tag, pType->tag); } } setR0Type(pType); } Loading libacc/tests/data/float.c +20 −2 Original line number Diff line number Diff line int ftoi(float f) { return f; } int dtoi(double d) { return d; } float itof(int i) { return i; } double itod(int i) { return i; } int main() { printf("int: %d float: %g double: %g\n", 1, 2.2f, 3.3); return 42; 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)); return 0; } Loading
libacc/acc.cpp +65 −10 Original line number Diff line number Diff line Loading @@ -532,7 +532,10 @@ class Compiler : public ErrorSink { } bool isFloatType(Type* pType) { TypeTag tag = pType->tag; return isFloatTag(pType->tag); } bool isFloatTag(TypeTag tag) { return tag == TY_FLOAT || tag == TY_DOUBLE; } Loading Loading @@ -1283,6 +1286,9 @@ class Compiler : public ErrorSink { } virtual void loadR0(int ea, bool isIncDec, int op, Type* pType) { TypeTag tag = collapseType(pType->tag); switch (tag) { case TY_INT: gmov(8, ea); /* mov EA, %eax */ if (isIncDec) { /* Implement post-increment or post decrement. Loading @@ -1290,13 +1296,38 @@ class Compiler : public ErrorSink { gmov(0, ea); /* 83 ADD */ o(decodeOp(op)); } break; case TY_FLOAT: if (ea < -LOCAL || ea > LOCAL) { oad(0x05d9, ea); // flds ea } else { oad(0x85d9, ea); // flds ea(%ebp) } if (isIncDec) { error("inc/dec not implemented for float."); } break; case TY_DOUBLE: if (ea < -LOCAL || ea > LOCAL) { oad(0x05dd, ea); // fldl ea } else { oad(0x85dd, ea); // fldl ea(%ebp) } if (isIncDec) { error("inc/dec not implemented for double."); } break; default: error("Unable to load type %d", tag); break; } setR0Type(pType); } virtual void convertR0(Type* pType){ Type* pR0Type = getR0Type(); if (pR0Type == NULL) { error("don't know R0Type"); assert(false); setR0Type(pType); return; } Loading @@ -1304,10 +1335,34 @@ class Compiler : public ErrorSink { // do nothing special } else if (isFloatType(pType) && isFloatType(pR0Type)) { // do nothing special, both held in same register on x87. } else { TypeTag r0Tag = collapseType(pR0Type->tag); TypeTag destTag = collapseType(pType->tag); if (r0Tag == TY_INT && isFloatTag(destTag)) { // Convert R0 from int to float o(0x50); // push %eax o(0x2404DB); // fildl 0(%esp) o(0x58); // pop %eax } else if (isFloatTag(r0Tag) && destTag == TY_INT) { // Convert R0 from float to int. Complicated because // need to save and restore the rounding mode. o(0x50); // push %eax o(0x50); // push %eax o(0x02247cD9); // fnstcw 2(%esp) o(0x2444b70f); // movzwl 2(%esp), %eax o(0x02); o(0x0cb4); // movb $12, %ah o(0x24048966); // movw %ax, 0(%esp) o(0x242cd9); // fldcw 0(%esp) o(0x04245cdb); // fistpl 4(%esp) o(0x02246cd9); // fldcw 2(%esp) o(0x58); // pop %eax o(0x58); // pop %eax } else { error("Incompatible types old: %d new: %d", pR0Type->tag, pType->tag); } } setR0Type(pType); } Loading
libacc/tests/data/float.c +20 −2 Original line number Diff line number Diff line int ftoi(float f) { return f; } int dtoi(double d) { return d; } float itof(int i) { return i; } double itod(int i) { return i; } int main() { printf("int: %d float: %g double: %g\n", 1, 2.2f, 3.3); return 42; 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)); return 0; }