summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Palevich <jackpal@google.com>2009-07-30 19:06:34 -0700
committerJack Palevich <jackpal@google.com>2009-07-30 19:06:34 -0700
commitb5e33311593e8b6d52ccb1eb5d5453a6cdd2d9e0 (patch)
tree43724a4c4bda12eae8de7f465b9bc5dc3d1faabd
parent8968e8e1158deda0ad035852791d5be8dcdc1632 (diff)
downloadsystem_core-b5e33311593e8b6d52ccb1eb5d5453a6cdd2d9e0.zip
system_core-b5e33311593e8b6d52ccb1eb5d5453a6cdd2d9e0.tar.gz
system_core-b5e33311593e8b6d52ccb1eb5d5453a6cdd2d9e0.tar.bz2
Start using lvals and rvals.
-rw-r--r--libacc/acc.cpp79
1 files changed, 60 insertions, 19 deletions
diff --git a/libacc/acc.cpp b/libacc/acc.cpp
index d9be2fd..f5b5923 100644
--- a/libacc/acc.cpp
+++ b/libacc/acc.cpp
@@ -382,8 +382,10 @@ class Compiler : public ErrorSink {
* argument, addressed relative to FP.
* else it is an absolute global address.
*
+ * et is ET_RVALUE for things like string constants, ET_LVALUE for
+ * variables.
*/
- virtual void leaR0(int ea, Type* pPointerType) = 0;
+ virtual void leaR0(int ea, Type* pPointerType, ExpressionType et) = 0;
/* Load the pc-relative address of a forward-referenced variable to R0.
* Return the address of the 4-byte constant so that it can be filled
@@ -504,6 +506,12 @@ class Compiler : public ErrorSink {
return mExpressionStack.size();
}
+ virtual void forceR0RVal() {
+ if (getR0ExpressionType() == ET_LVALUE) {
+ loadR0FromR0();
+ }
+ }
+
protected:
/*
* Output a byte. Handles all values, 0..ff.
@@ -545,6 +553,13 @@ class Compiler : public ErrorSink {
void setR0Type(Type* pType) {
assert(pType != NULL);
mExpressionStack.back().pType = pType;
+ mExpressionStack.back().et = ET_RVALUE;
+ }
+
+ void setR0Type(Type* pType, ExpressionType et) {
+ assert(pType != NULL);
+ mExpressionStack.back().pType = pType;
+ mExpressionStack.back().et = et;
}
Type* getTOSType() {
@@ -1085,7 +1100,8 @@ class Compiler : public ErrorSink {
o4(0xE1C200F0); // strd r0, [r2]
break;
default:
- error("storeR0ToTOS: unimplemented type");
+ error("storeR0ToTOS: unimplemented type %d",
+ pDestType->tag);
break;
}
}
@@ -1112,7 +1128,7 @@ class Compiler : public ErrorSink {
setR0Type(pPointerType->pHead);
}
- virtual void leaR0(int ea, Type* pPointerType) {
+ virtual void leaR0(int ea, Type* pPointerType, ExpressionType et) {
if (ea > -LOCAL && ea < LOCAL) {
// Local, fp relative
if (ea < -1023 || ea > 1023 || ((ea & 3) != 0)) {
@@ -1130,7 +1146,7 @@ class Compiler : public ErrorSink {
o4(ea); // .L1: .word 0
// .L99:
}
- setR0Type(pPointerType);
+ setR0Type(pPointerType, et);
}
virtual int leaForward(int ea, Type* pPointerType) {
@@ -2089,7 +2105,8 @@ class Compiler : public ErrorSink {
o(0x19dd); /* fstpl (%ecx) */
break;
default:
- error("storeR0ToTOS: unsupported type");
+ error("storeR0ToTOS: unsupported type %d",
+ pTargetType->tag);
break;
}
}
@@ -2119,9 +2136,9 @@ class Compiler : public ErrorSink {
setR0Type(pPointerType->pHead);
}
- virtual void leaR0(int ea, Type* pPointerType) {
+ virtual void leaR0(int ea, Type* pPointerType, ExpressionType et) {
gmov(10, ea); /* leal EA, %eax */
- setR0Type(pPointerType);
+ setR0Type(pPointerType, et);
}
virtual int leaForward(int ea, Type* pPointerType) {
@@ -2208,6 +2225,7 @@ class Compiler : public ErrorSink {
virtual void callIndirect(int l, Type* pFunc) {
assert(pFunc->tag == TY_FUNC);
+ popType(); // Get rid of indirect fn pointer type
setR0Type(pFunc->pHead);
oad(0x2494ff, l); /* call *xxx(%esp) */
}
@@ -2495,9 +2513,10 @@ class Compiler : public ErrorSink {
mpBase->loadR0FromR0();
}
- virtual void leaR0(int ea, Type* pPointerType) {
- fprintf(stderr, "leaR0(%d)\n", ea);
- mpBase->leaR0(ea, pPointerType);
+ virtual void leaR0(int ea, Type* pPointerType, ExpressionType et) {
+ fprintf(stderr, "leaR0(%d, %d, %d)\n", ea,
+ pPointerType->pHead->tag, et);
+ mpBase->leaR0(ea, pPointerType, et);
}
virtual int leaForward(int ea, Type* pPointerType) {
@@ -2607,6 +2626,10 @@ class Compiler : public ErrorSink {
virtual size_t getExpressionStackDepth() {
return mpBase->getExpressionStackDepth();
}
+
+ virtual void forceR0RVal() {
+ return mpBase->forceR0RVal();
+ }
};
#endif // PROVIDE_TRACE_CODEGEN
@@ -3728,7 +3751,7 @@ class Compiler : public ErrorSink {
bool acceptStringLiteral() {
if (tok == '"') {
- pGen->leaR0((int) glo, mkpCharPtr);
+ pGen->leaR0((int) glo, mkpCharPtr, ET_RVALUE);
// This while loop merges multiple adjacent string constants.
while (tok == '"') {
while (ch != '"' && ch != EOF) {
@@ -3799,6 +3822,7 @@ class Compiler : public ErrorSink {
} else if (c == 2) {
/* -, +, !, ~ */
unary(false);
+ pGen->forceR0RVal();
if (t == '!')
pGen->gUnaryCmp(a);
else if (t == '+') {
@@ -3812,6 +3836,7 @@ class Compiler : public ErrorSink {
if (pCast) {
skip(')');
unary(false);
+ pGen->forceR0RVal();
pGen->convertR0(pCast);
} else {
expr();
@@ -3821,6 +3846,7 @@ class Compiler : public ErrorSink {
/* This is a pointer dereference.
*/
unary(false);
+ pGen->forceR0RVal();
Type* pR0Type = pGen->getR0Type();
if (pR0Type->tag != TY_POINTER) {
error("Expected a pointer type.");
@@ -3831,6 +3857,7 @@ class Compiler : public ErrorSink {
if (accept('=')) {
pGen->pushR0();
expr();
+ pGen->forceR0RVal();
pGen->storeR0ToTOS();
} else if (t) {
pGen->loadR0FromR0();
@@ -3840,7 +3867,8 @@ class Compiler : public ErrorSink {
// t == 0 to trigger an indirect function call. Hack!
} else if (t == '&') {
VariableInfo* pVI = VI(tok);
- pGen->leaR0((int) pVI->pAddress, createPtrType(pVI->pType));
+ pGen->leaR0((int) pVI->pAddress, createPtrType(pVI->pType),
+ ET_RVALUE);
next();
} else if (t == EOF ) {
error("Unexpected EOF.");
@@ -3867,9 +3895,11 @@ class Compiler : public ErrorSink {
if ((tok == '=') & allowAssignment) {
/* assignment */
next();
- pGen->leaR0(n, createPtrType(pVI->pType));
+ pGen->leaR0(n, createPtrType(pVI->pType), ET_LVALUE);
+ checkLVal();
pGen->pushR0();
expr();
+ pGen->forceR0RVal();
pGen->storeR0ToTOS();
} else if (tok != '(') {
/* variable */
@@ -3883,7 +3913,7 @@ class Compiler : public ErrorSink {
// load a variable
if (tokl == 11) {
// post inc / post dec
- pGen->leaR0(n, createPtrType(pVI->pType));
+ pGen->leaR0(n, createPtrType(pVI->pType), ET_LVALUE);
pGen->pushR0();
pGen->loadR0FromR0();
@@ -3909,8 +3939,7 @@ class Compiler : public ErrorSink {
pGen->popR0();
next();
} else {
- pGen->leaR0(n, createPtrType(pVI->pType));
- pGen->loadR0FromR0();
+ pGen->leaR0(n, createPtrType(pVI->pType), ET_LVALUE);
}
}
}
@@ -3934,7 +3963,7 @@ class Compiler : public ErrorSink {
pVI->pForward = (void*) pGen->leaForward(
(int) pVI->pForward, pFn);
} else {
- pGen->leaR0(n, pFn);
+ pGen->leaR0(n, pFn, ET_RVALUE);
}
pGen->pushR0();
}
@@ -3949,6 +3978,7 @@ class Compiler : public ErrorSink {
error("Unexpected argument.");
}
expr();
+ pGen->forceR0RVal();
Type* pTargetType;
if (pArgList) {
pTargetType = pArgList->pHead;
@@ -3997,7 +4027,7 @@ class Compiler : public ErrorSink {
while (level == tokl) {
t = tokc;
next();
-
+ pGen->forceR0RVal();
if (level > 8) {
a = pGen->gtst(t == OP_LOGICAL_OR, a); /* && and || output code generation */
binaryOp(level);
@@ -4010,6 +4040,7 @@ class Compiler : public ErrorSink {
// Push a dummy value so we don't fail
pGen->li(0);
}
+ pGen->forceR0RVal();
if ((level == 4) | (level == 5)) {
pGen->gcmp(t);
} else {
@@ -4019,6 +4050,7 @@ class Compiler : public ErrorSink {
}
/* && and || output code generation */
if (a && level > 8) {
+ pGen->forceR0RVal();
a = pGen->gtst(t == OP_LOGICAL_OR, a);
pGen->li(t != OP_LOGICAL_OR);
int b = pGen->gjmp(0);
@@ -4035,6 +4067,7 @@ class Compiler : public ErrorSink {
int test_expr() {
expr();
+ pGen->forceR0RVal();
return pGen->gtst(0, 0);
}
@@ -4103,6 +4136,7 @@ class Compiler : public ErrorSink {
if (accept(TOK_RETURN)) {
if (tok != ';') {
expr();
+ pGen->forceR0RVal();
if (pReturnType->tag == TY_VOID) {
error("Must not return a value from a void function");
} else {
@@ -4424,6 +4458,12 @@ class Compiler : public ErrorSink {
return pType;
}
+ void checkLVal() {
+ if (pGen->getR0ExpressionType() != ET_LVALUE) {
+ error("Expected an lval");
+ }
+ }
+
void addGlobalSymbol(Type* pDecl) {
tokenid_t t = pDecl->id;
VariableInfo* pVI = VI(t);
@@ -4466,9 +4506,10 @@ class Compiler : public ErrorSink {
VI(pDecl->id)->pAddress = (void*) variableAddress;
if (accept('=')) {
/* assignment */
- pGen->leaR0(variableAddress, createPtrType(pDecl));
+ pGen->leaR0(variableAddress, createPtrType(pDecl), ET_LVALUE);
pGen->pushR0();
expr();
+ pGen->forceR0RVal();
pGen->storeR0ToTOS();
}
if (tok == ',')