Code generator cleanup
Factor ARM integer binary operation setup code into a function. Don't pass redundant pType information into loadR0FromR0, storeR0ToTOS, gcmp, gUnaryCmp, li Separate inc/dec from variable loading. Generates worse code, but now we handle pointer inc/dec and char inc/dec.
This commit is contained in:
parent
b40367bde1
commit
58c30eef99
277
libacc/acc.cpp
277
libacc/acc.cpp
|
@ -282,6 +282,11 @@ class Compiler : public ErrorSink {
|
|||
}
|
||||
}
|
||||
|
||||
/* Give the code generator some utility types so it can
|
||||
* use its own types as needed for the results of some
|
||||
* operations like gcmp.
|
||||
*/
|
||||
|
||||
void setTypes(Type* pInt) {
|
||||
mkpInt = pInt;
|
||||
}
|
||||
|
@ -312,7 +317,7 @@ class Compiler : public ErrorSink {
|
|||
int localVariableSize) = 0;
|
||||
|
||||
/* load immediate value to R0 */
|
||||
virtual void li(int i, Type* pType) = 0;
|
||||
virtual void li(int i) = 0;
|
||||
|
||||
/* Load floating point value from global address. */
|
||||
virtual void loadFloat(int address, Type* pType) = 0;
|
||||
|
@ -333,7 +338,7 @@ class Compiler : public ErrorSink {
|
|||
* Pops TOS.
|
||||
* op specifies the comparison.
|
||||
*/
|
||||
virtual void gcmp(int op, Type* pResultType) = 0;
|
||||
virtual void gcmp(int op) = 0;
|
||||
|
||||
/* Perform the arithmetic op specified by op. TOS is the
|
||||
* left argument, R0 is the right argument.
|
||||
|
@ -344,7 +349,7 @@ class Compiler : public ErrorSink {
|
|||
/* Compare 0 against R0, and store the boolean result in R0.
|
||||
* op specifies the comparison.
|
||||
*/
|
||||
virtual void gUnaryCmp(int op, Type* pResultType) = 0;
|
||||
virtual void gUnaryCmp(int op) = 0;
|
||||
|
||||
/* Perform the arithmetic op specified by op. 0 is the
|
||||
* left argument, R0 is the right argument.
|
||||
|
@ -355,16 +360,18 @@ class Compiler : public ErrorSink {
|
|||
*/
|
||||
virtual void pushR0() = 0;
|
||||
|
||||
/* Pop R0 from the stack.
|
||||
*/
|
||||
virtual void popR0() = 0;
|
||||
|
||||
/* Store R0 to the address stored in TOS.
|
||||
* The TOS is popped.
|
||||
* pPointerType is the type of the pointer (of the input R0).
|
||||
*/
|
||||
virtual void storeR0ToTOS(Type* pPointerType) = 0;
|
||||
virtual void storeR0ToTOS() = 0;
|
||||
|
||||
/* Load R0 from the address stored in R0.
|
||||
* pPointerType is the type of the pointer (of the input R0).
|
||||
*/
|
||||
virtual void loadR0FromR0(Type* pPointerType) = 0;
|
||||
virtual void loadR0FromR0() = 0;
|
||||
|
||||
/* Load the absolute address of a variable to R0.
|
||||
* If ea <= LOCAL, then this is a local variable, or an
|
||||
|
@ -384,11 +391,8 @@ class Compiler : public ErrorSink {
|
|||
* If ea <= LOCAL, then this is a local variable, or an
|
||||
* argument, addressed relative to FP.
|
||||
* else it is an absolute global address.
|
||||
* If isIncDec is true, then the stored variable's value
|
||||
* should be post-incremented or post-decremented, based
|
||||
* on the value of op.
|
||||
*/
|
||||
virtual void loadR0(int ea, bool isIncDec, int op, Type* pType) = 0;
|
||||
virtual void loadR0(int ea, Type* pType) = 0;
|
||||
|
||||
/**
|
||||
* Convert R0 to the given type.
|
||||
|
@ -636,9 +640,9 @@ class Compiler : public ErrorSink {
|
|||
}
|
||||
|
||||
/* load immediate value */
|
||||
virtual void li(int t, Type* pType) {
|
||||
virtual void li(int t) {
|
||||
liReg(t, 0);
|
||||
setR0Type(pType);
|
||||
setR0Type(mkpInt);
|
||||
}
|
||||
|
||||
virtual void loadFloat(int address, Type* pType) {
|
||||
|
@ -685,14 +689,13 @@ class Compiler : public ErrorSink {
|
|||
return o4(branch | encodeAddress(t));
|
||||
}
|
||||
|
||||
virtual void gcmp(int op, Type* pResultType) {
|
||||
virtual void gcmp(int op) {
|
||||
Type* pR0Type = getR0Type();
|
||||
Type* pTOSType = getTOSType();
|
||||
TypeTag tagR0 = collapseType(pR0Type->tag);
|
||||
TypeTag tagTOS = collapseType(pTOSType->tag);
|
||||
if (tagR0 == TY_INT && tagTOS == TY_INT) {
|
||||
o4(0xE8BD0002); // ldmfd sp!,{r1}
|
||||
mStackUse -= 4;
|
||||
setupIntPtrArgs();
|
||||
o4(0xE1510000); // cmp r1, r1
|
||||
switch(op) {
|
||||
case OP_EQUALS:
|
||||
|
@ -723,7 +726,6 @@ class Compiler : public ErrorSink {
|
|||
error("Unknown comparison op %d", op);
|
||||
break;
|
||||
}
|
||||
popType();
|
||||
} else if (tagR0 == TY_DOUBLE || tagTOS == TY_DOUBLE) {
|
||||
setupDoubleArgs();
|
||||
switch(op) {
|
||||
|
@ -775,7 +777,7 @@ class Compiler : public ErrorSink {
|
|||
break;
|
||||
}
|
||||
}
|
||||
setR0Type(pResultType);
|
||||
setR0Type(mkpInt);
|
||||
}
|
||||
|
||||
virtual void genOp(int op) {
|
||||
|
@ -786,6 +788,7 @@ class Compiler : public ErrorSink {
|
|||
bool isFloatR0 = isFloatTag(tagR0);
|
||||
bool isFloatTOS = isFloatTag(tagTOS);
|
||||
if (!isFloatR0 && !isFloatTOS) {
|
||||
setupIntPtrArgs();
|
||||
bool isPtrR0 = tagR0 == TY_POINTER;
|
||||
bool isPtrTOS = tagTOS == TY_POINTER;
|
||||
if (isPtrR0 || isPtrTOS) {
|
||||
|
@ -796,14 +799,12 @@ class Compiler : public ErrorSink {
|
|||
if (! typeEqual(pR0Type, pTOSType)) {
|
||||
error("Incompatible pointer types for subtraction.");
|
||||
}
|
||||
o4(0xE8BD0002); // ldmfd sp!,{r1}
|
||||
o4(0xE0410000); // sub r0,r1,r0
|
||||
popType();
|
||||
setR0Type(mkpInt);
|
||||
int size = sizeOf(pR0Type->pHead);
|
||||
if (size != 1) {
|
||||
pushR0();
|
||||
li(size, mkpInt);
|
||||
li(size);
|
||||
// TODO: Optimize for power-of-two.
|
||||
genOp(OP_DIV);
|
||||
}
|
||||
|
@ -812,7 +813,6 @@ class Compiler : public ErrorSink {
|
|||
error("Unsupported pointer-scalar operation %d", op);
|
||||
}
|
||||
Type* pPtrType = isPtrR0 ? pR0Type : pTOSType;
|
||||
o4(0xE8BD0002); // ldmfd sp!,{r1}
|
||||
int size = sizeOf(pPtrType->pHead);
|
||||
if (size != 1) {
|
||||
// TODO: Optimize for power-of-two.
|
||||
|
@ -831,12 +831,9 @@ class Compiler : public ErrorSink {
|
|||
o4(0xE0410000); // sub r0,r1,r0
|
||||
break;
|
||||
}
|
||||
popType();
|
||||
setR0Type(pPtrType);
|
||||
}
|
||||
} else {
|
||||
o4(0xE8BD0002); // ldmfd sp!,{r1}
|
||||
mStackUse -= 4;
|
||||
switch(op) {
|
||||
case OP_MUL:
|
||||
o4(0x0E0000091); // mul r0,r1,r0
|
||||
|
@ -875,7 +872,6 @@ class Compiler : public ErrorSink {
|
|||
error("Unimplemented op %d\n", op);
|
||||
break;
|
||||
}
|
||||
popType();
|
||||
}
|
||||
} else {
|
||||
Type* pResultType = tagR0 > tagTOS ? pR0Type : pTOSType;
|
||||
|
@ -922,7 +918,7 @@ class Compiler : public ErrorSink {
|
|||
}
|
||||
}
|
||||
|
||||
virtual void gUnaryCmp(int op, Type* pResultType) {
|
||||
virtual void gUnaryCmp(int op) {
|
||||
if (op != OP_LOGICAL_NOT) {
|
||||
error("Unknown unary cmp %d", op);
|
||||
} else {
|
||||
|
@ -946,7 +942,7 @@ class Compiler : public ErrorSink {
|
|||
break;
|
||||
}
|
||||
}
|
||||
setR0Type(pResultType);
|
||||
setR0Type(mkpInt);
|
||||
}
|
||||
|
||||
virtual void genUnaryOp(int op) {
|
||||
|
@ -1005,7 +1001,28 @@ class Compiler : public ErrorSink {
|
|||
LOG_STACK("pushR0: %d\n", mStackUse);
|
||||
}
|
||||
|
||||
virtual void storeR0ToTOS(Type* pPointerType) {
|
||||
virtual void popR0() {
|
||||
Type* pTOSType = getTOSType();
|
||||
switch (collapseType(pTOSType->tag)){
|
||||
case TY_INT:
|
||||
case TY_FLOAT:
|
||||
o4(0xE8BD0001); // ldmfd sp!,{r0}
|
||||
mStackUse -= 4;
|
||||
break;
|
||||
case TY_DOUBLE:
|
||||
o4(0xE8BD0003); // ldmfd sp!,{r0, r1} // Restore R0
|
||||
mStackUse -= 8;
|
||||
break;
|
||||
default:
|
||||
error("Can't pop this type.");
|
||||
break;
|
||||
}
|
||||
popType();
|
||||
LOG_STACK("popR0: %d\n", mStackUse);
|
||||
}
|
||||
|
||||
virtual void storeR0ToTOS() {
|
||||
Type* pPointerType = getTOSType();
|
||||
assert(pPointerType->tag == TY_POINTER);
|
||||
o4(0xE8BD0004); // ldmfd sp!,{r2}
|
||||
popType();
|
||||
|
@ -1027,7 +1044,8 @@ class Compiler : public ErrorSink {
|
|||
}
|
||||
}
|
||||
|
||||
virtual void loadR0FromR0(Type* pPointerType) {
|
||||
virtual void loadR0FromR0() {
|
||||
Type* pPointerType = getR0Type();
|
||||
assert(pPointerType->tag == TY_POINTER);
|
||||
switch (pPointerType->pHead->tag) {
|
||||
case TY_INT:
|
||||
|
@ -1149,7 +1167,7 @@ class Compiler : public ErrorSink {
|
|||
}
|
||||
}
|
||||
|
||||
virtual void loadR0(int ea, bool isIncDec, int op, Type* pType) {
|
||||
virtual void loadR0(int ea, Type* pType) {
|
||||
TypeTag tag = pType->tag;
|
||||
switch (tag) {
|
||||
case TY_CHAR:
|
||||
|
@ -1170,10 +1188,6 @@ class Compiler : public ErrorSink {
|
|||
o4(ea); // .L1: .word ea
|
||||
o4(0xE5D20000); // .L99: ldrb r0, [r2]
|
||||
}
|
||||
|
||||
if (isIncDec) {
|
||||
error("inc/dec not implemented for char.");
|
||||
}
|
||||
break;
|
||||
case TY_POINTER:
|
||||
case TY_INT:
|
||||
|
@ -1195,37 +1209,6 @@ class Compiler : public ErrorSink {
|
|||
o4(ea); // .L1: .word ea
|
||||
o4(0xE5920000); // .L99: ldr r0, [r2]
|
||||
}
|
||||
|
||||
if (isIncDec) {
|
||||
if (tag == TY_INT) {
|
||||
switch (op) {
|
||||
case OP_INCREMENT:
|
||||
o4(0xE2801001); // add r1, r0, #1
|
||||
break;
|
||||
case OP_DECREMENT:
|
||||
o4(0xE2401001); // sub r1, r0, #1
|
||||
break;
|
||||
default:
|
||||
error("unknown opcode: %d", op);
|
||||
}
|
||||
if (ea < LOCAL) {
|
||||
// Local, fp relative
|
||||
// Don't need range check, was already checked above
|
||||
if (ea < 0) {
|
||||
o4(0xE50B1000 | (0xfff & (-ea))); // str r1, [fp,#-ea]
|
||||
} else {
|
||||
o4(0xE58B1000 | (0xfff & ea)); // str r1, [fp,#ea]
|
||||
}
|
||||
} else{
|
||||
// Global, absolute
|
||||
// r2 is already set up from before.
|
||||
o4(0xE5821000); // str r1, [r2]
|
||||
}
|
||||
}
|
||||
else {
|
||||
error("inc/dec not implemented for float.");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TY_DOUBLE:
|
||||
if ((ea & 0x7) != 0) {
|
||||
|
@ -1563,6 +1546,12 @@ class Compiler : public ErrorSink {
|
|||
return reg;
|
||||
}
|
||||
|
||||
void setupIntPtrArgs() {
|
||||
o4(0xE8BD0002); // ldmfd sp!,{r1}
|
||||
mStackUse -= 4;
|
||||
popType();
|
||||
}
|
||||
|
||||
/* Pop TOS to R1
|
||||
* Make sure both R0 and TOS are floats. (Could be ints)
|
||||
* We know that at least one of R0 and TOS is already a float
|
||||
|
@ -1837,9 +1826,9 @@ class Compiler : public ErrorSink {
|
|||
}
|
||||
|
||||
/* load immediate value */
|
||||
virtual void li(int i, Type* pType) {
|
||||
virtual void li(int i) {
|
||||
oad(0xb8, i); /* mov $xx, %eax */
|
||||
setR0Type(pType);
|
||||
setR0Type(mkpInt);
|
||||
}
|
||||
|
||||
virtual void loadFloat(int address, Type* pType) {
|
||||
|
@ -1879,7 +1868,7 @@ class Compiler : public ErrorSink {
|
|||
return psym(0x84 + l, t);
|
||||
}
|
||||
|
||||
virtual void gcmp(int op, Type* pResultType) {
|
||||
virtual void gcmp(int op) {
|
||||
Type* pR0Type = getR0Type();
|
||||
Type* pTOSType = getTOSType();
|
||||
TypeTag tagR0 = pR0Type->tag;
|
||||
|
@ -1890,7 +1879,7 @@ class Compiler : public ErrorSink {
|
|||
int t = decodeOp(op);
|
||||
o(0x59); /* pop %ecx */
|
||||
o(0xc139); /* cmp %eax,%ecx */
|
||||
li(0, NULL);
|
||||
li(0);
|
||||
o(0x0f); /* setxx %al */
|
||||
o(t + 0x90);
|
||||
o(0xc0);
|
||||
|
@ -1945,7 +1934,7 @@ class Compiler : public ErrorSink {
|
|||
}
|
||||
o(0xc0b60f); // movzbl %al, %eax
|
||||
}
|
||||
setR0Type(pResultType);
|
||||
setR0Type(mkpInt);
|
||||
}
|
||||
|
||||
virtual void genOp(int op) {
|
||||
|
@ -1973,7 +1962,7 @@ class Compiler : public ErrorSink {
|
|||
int size = sizeOf(pR0Type->pHead);
|
||||
if (size != 1) {
|
||||
pushR0();
|
||||
li(size, mkpInt);
|
||||
li(size);
|
||||
// TODO: Optimize for power-of-two.
|
||||
genOp(OP_DIV);
|
||||
}
|
||||
|
@ -2028,7 +2017,7 @@ class Compiler : public ErrorSink {
|
|||
}
|
||||
}
|
||||
|
||||
virtual void gUnaryCmp(int op, Type* pResultType) {
|
||||
virtual void gUnaryCmp(int op) {
|
||||
if (op != OP_LOGICAL_NOT) {
|
||||
error("Unknown unary cmp %d", op);
|
||||
} else {
|
||||
|
@ -2039,7 +2028,7 @@ class Compiler : public ErrorSink {
|
|||
oad(0xb9, 0); /* movl $0, %ecx */
|
||||
int t = decodeOp(op);
|
||||
o(0xc139); /* cmp %eax,%ecx */
|
||||
li(0, NULL);
|
||||
li(0);
|
||||
o(0x0f); /* setxx %al */
|
||||
o(t + 0x90);
|
||||
o(0xc0);
|
||||
|
@ -2062,7 +2051,7 @@ class Compiler : public ErrorSink {
|
|||
break;
|
||||
}
|
||||
}
|
||||
setR0Type(pResultType);
|
||||
setR0Type(mkpInt);
|
||||
}
|
||||
|
||||
virtual void genUnaryOp(int op) {
|
||||
|
@ -2116,7 +2105,31 @@ class Compiler : public ErrorSink {
|
|||
pushType();
|
||||
}
|
||||
|
||||
virtual void storeR0ToTOS(Type* pPointerType) {
|
||||
virtual void popR0() {
|
||||
Type* pR0Type = getR0Type();
|
||||
TypeTag r0ct = collapseType(pR0Type->tag);
|
||||
switch(r0ct) {
|
||||
case TY_INT:
|
||||
o(0x58); /* popl %eax */
|
||||
break;
|
||||
case TY_FLOAT:
|
||||
o(0x2404d9); // flds (%esp)
|
||||
o(0x58); /* popl %eax */
|
||||
break;
|
||||
case TY_DOUBLE:
|
||||
o(0x2404dd); // fldl (%esp)
|
||||
o(0x58); /* popl %eax */
|
||||
o(0x58); /* popl %eax */
|
||||
break;
|
||||
default:
|
||||
error("pushR0 unsupported type %d", r0ct);
|
||||
break;
|
||||
}
|
||||
popType();
|
||||
}
|
||||
|
||||
virtual void storeR0ToTOS() {
|
||||
Type* pPointerType = getTOSType();
|
||||
assert(pPointerType->tag == TY_POINTER);
|
||||
Type* pTargetType = pPointerType->pHead;
|
||||
convertR0(pTargetType);
|
||||
|
@ -2141,7 +2154,8 @@ class Compiler : public ErrorSink {
|
|||
}
|
||||
}
|
||||
|
||||
virtual void loadR0FromR0(Type* pPointerType) {
|
||||
virtual void loadR0FromR0() {
|
||||
Type* pPointerType = getR0Type();
|
||||
assert(pPointerType->tag == TY_POINTER);
|
||||
switch (pPointerType->pHead->tag) {
|
||||
case TY_INT:
|
||||
|
@ -2204,7 +2218,7 @@ class Compiler : public ErrorSink {
|
|||
}
|
||||
}
|
||||
|
||||
virtual void loadR0(int ea, bool isIncDec, int op, Type* pType) {
|
||||
virtual void loadR0(int ea, Type* pType) {
|
||||
TypeTag tag = pType->tag;
|
||||
switch (tag) {
|
||||
case TY_CHAR:
|
||||
|
@ -2213,22 +2227,10 @@ class Compiler : public ErrorSink {
|
|||
} else {
|
||||
oad(0x85BE0F, ea); // movsbl ea(%ebp),%eax
|
||||
}
|
||||
if (isIncDec) {
|
||||
error("inc/dec not implemented for char.");
|
||||
}
|
||||
break;
|
||||
case TY_INT:
|
||||
case TY_POINTER:
|
||||
if (tag == TY_CHAR) {
|
||||
} else {
|
||||
gmov(8, ea); /* mov EA, %eax */
|
||||
}
|
||||
if (isIncDec) {
|
||||
/* Implement post-increment or post decrement.
|
||||
*/
|
||||
gmov(0, ea); /* 83 ADD */
|
||||
o(decodeOp(op));
|
||||
}
|
||||
gmov(8, ea); /* mov EA, %eax */
|
||||
break;
|
||||
case TY_FLOAT:
|
||||
if (ea < -LOCAL || ea > LOCAL) {
|
||||
|
@ -2236,9 +2238,6 @@ class Compiler : public ErrorSink {
|
|||
} 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) {
|
||||
|
@ -2246,9 +2245,6 @@ class Compiler : public ErrorSink {
|
|||
} 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);
|
||||
|
@ -2535,9 +2531,9 @@ class Compiler : public ErrorSink {
|
|||
}
|
||||
|
||||
/* load immediate value */
|
||||
virtual void li(int t, Type* pType) {
|
||||
virtual void li(int t) {
|
||||
fprintf(stderr, "li(%d)\n", t);
|
||||
mpBase->li(t, pType);
|
||||
mpBase->li(t);
|
||||
}
|
||||
|
||||
virtual void loadFloat(int address, Type* pType) {
|
||||
|
@ -2558,9 +2554,9 @@ class Compiler : public ErrorSink {
|
|||
return result;
|
||||
}
|
||||
|
||||
virtual void gcmp(int op, Type* pResultType) {
|
||||
fprintf(stderr, "gcmp(%d, pResultType)\n", op);
|
||||
mpBase->gcmp(op, pResultType);
|
||||
virtual void gcmp(int op) {
|
||||
fprintf(stderr, "gcmp(%d)\n", op);
|
||||
mpBase->gcmp(op);
|
||||
}
|
||||
|
||||
virtual void genOp(int op) {
|
||||
|
@ -2569,9 +2565,9 @@ class Compiler : public ErrorSink {
|
|||
}
|
||||
|
||||
|
||||
virtual void gUnaryCmp(int op, Type* pResultType) {
|
||||
fprintf(stderr, "gUnaryCmp(%d, pResultType)\n", op);
|
||||
mpBase->gUnaryCmp(op, pResultType);
|
||||
virtual void gUnaryCmp(int op) {
|
||||
fprintf(stderr, "gUnaryCmp(%d)\n", op);
|
||||
mpBase->gUnaryCmp(op);
|
||||
}
|
||||
|
||||
virtual void genUnaryOp(int op) {
|
||||
|
@ -2584,14 +2580,19 @@ class Compiler : public ErrorSink {
|
|||
mpBase->pushR0();
|
||||
}
|
||||
|
||||
virtual void storeR0ToTOS(Type* pPointerType) {
|
||||
fprintf(stderr, "storeR0ToTOS(%d)\n", pPointerType->pHead->tag);
|
||||
mpBase->storeR0ToTOS(pPointerType);
|
||||
virtual void popR0() {
|
||||
fprintf(stderr, "popR0()\n");
|
||||
mpBase->popR0();
|
||||
}
|
||||
|
||||
virtual void loadR0FromR0(Type* pPointerType) {
|
||||
fprintf(stderr, "loadR0FromR0(%d)\n", pPointerType->pHead->tag);
|
||||
mpBase->loadR0FromR0(pPointerType);
|
||||
virtual void storeR0ToTOS() {
|
||||
fprintf(stderr, "storeR0ToTOS()\n");
|
||||
mpBase->storeR0ToTOS();
|
||||
}
|
||||
|
||||
virtual void loadR0FromR0() {
|
||||
fprintf(stderr, "loadR0FromR0()\n");
|
||||
mpBase->loadR0FromR0();
|
||||
}
|
||||
|
||||
virtual void leaR0(int ea, Type* pPointerType) {
|
||||
|
@ -2604,9 +2605,9 @@ class Compiler : public ErrorSink {
|
|||
mpBase->storeR0(ea, pType);
|
||||
}
|
||||
|
||||
virtual void loadR0(int ea, bool isIncDec, int op, Type* pType) {
|
||||
fprintf(stderr, "loadR0(%d, %d, %d, pType)\n", ea, isIncDec, op);
|
||||
mpBase->loadR0(ea, isIncDec, op, pType);
|
||||
virtual void loadR0(int ea, Type* pType) {
|
||||
fprintf(stderr, "loadR0(%d, pType)\n", ea);
|
||||
mpBase->loadR0(ea, pType);
|
||||
}
|
||||
|
||||
virtual void convertR0(Type* pType){
|
||||
|
@ -3814,7 +3815,7 @@ class Compiler : public ErrorSink {
|
|||
|
||||
bool acceptStringLiteral() {
|
||||
if (tok == '"') {
|
||||
pGen->li((int) glo, mkpCharPtr);
|
||||
pGen->leaR0((int) glo, mkpCharPtr);
|
||||
// This while loop merges multiple adjacent string constants.
|
||||
while (tok == '"') {
|
||||
while (ch != '"' && ch != EOF) {
|
||||
|
@ -3869,7 +3870,7 @@ class Compiler : public ErrorSink {
|
|||
t = tok;
|
||||
next();
|
||||
if (t == TOK_NUM) {
|
||||
pGen->li(a, mkpInt);
|
||||
pGen->li(a);
|
||||
} else if (t == TOK_NUM_FLOAT) {
|
||||
// Align to 4-byte boundary
|
||||
glo = (char*) (((intptr_t) glo + 3) & -4);
|
||||
|
@ -3886,7 +3887,7 @@ class Compiler : public ErrorSink {
|
|||
/* -, +, !, ~ */
|
||||
unary(false);
|
||||
if (t == '!')
|
||||
pGen->gUnaryCmp(a, mkpInt);
|
||||
pGen->gUnaryCmp(a);
|
||||
else if (t == '+') {
|
||||
// ignore unary plus.
|
||||
} else {
|
||||
|
@ -3917,9 +3918,9 @@ class Compiler : public ErrorSink {
|
|||
if (accept('=')) {
|
||||
pGen->pushR0();
|
||||
expr();
|
||||
pGen->storeR0ToTOS(pR0Type);
|
||||
pGen->storeR0ToTOS();
|
||||
} else if (t) {
|
||||
pGen->loadR0FromR0(pR0Type);
|
||||
pGen->loadR0FromR0();
|
||||
}
|
||||
}
|
||||
// Else we fall through to the function call below, with
|
||||
|
@ -3965,8 +3966,14 @@ class Compiler : public ErrorSink {
|
|||
error("Undeclared variable %s\n", nameof(t));
|
||||
}
|
||||
}
|
||||
pGen->loadR0(n, tokl == 11, tokc, pVI->pType);
|
||||
// load a variable
|
||||
pGen->loadR0(n, pVI->pType);
|
||||
if (tokl == 11) {
|
||||
// post inc / post dec
|
||||
pGen->pushR0();
|
||||
impInc(tokc);
|
||||
pGen->storeR0(n, pVI->pType);
|
||||
pGen->popR0();
|
||||
next();
|
||||
}
|
||||
}
|
||||
|
@ -4037,6 +4044,28 @@ class Compiler : public ErrorSink {
|
|||
}
|
||||
}
|
||||
|
||||
/* Increment / decrement R0 */
|
||||
|
||||
void impInc(int op) {
|
||||
Type* pType = pGen->getR0Type();
|
||||
int lit = 1;
|
||||
if (op == OP_DECREMENT) {
|
||||
lit = -1;
|
||||
}
|
||||
switch (pType->tag) {
|
||||
case TY_INT:
|
||||
case TY_CHAR:
|
||||
case TY_POINTER:
|
||||
pGen->pushR0();
|
||||
pGen->li(lit);
|
||||
pGen->genOp(OP_PLUS);
|
||||
break;
|
||||
default:
|
||||
error("++/-- illegal for this type.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Recursive descent parser for binary operations.
|
||||
*/
|
||||
void binaryOp(int level) {
|
||||
|
@ -4061,10 +4090,10 @@ class Compiler : public ErrorSink {
|
|||
if (pGen->getR0Type() == NULL) {
|
||||
// We failed to parse a right-hand argument.
|
||||
// Push a dummy value so we don't fail
|
||||
pGen->li(0, mkpInt);
|
||||
pGen->li(0);
|
||||
}
|
||||
if ((level == 4) | (level == 5)) {
|
||||
pGen->gcmp(t, mkpInt);
|
||||
pGen->gcmp(t);
|
||||
} else {
|
||||
pGen->genOp(t);
|
||||
}
|
||||
|
@ -4073,10 +4102,10 @@ class Compiler : public ErrorSink {
|
|||
/* && and || output code generation */
|
||||
if (a && level > 8) {
|
||||
a = pGen->gtst(t == OP_LOGICAL_OR, a);
|
||||
pGen->li(t != OP_LOGICAL_OR, mkpInt);
|
||||
pGen->li(t != OP_LOGICAL_OR);
|
||||
pGen->gjmp(5); /* jmp $ + 5 (sizeof li, FIXME for ARM) */
|
||||
pGen->gsym(a);
|
||||
pGen->li(t == OP_LOGICAL_OR, mkpInt);
|
||||
pGen->li(t == OP_LOGICAL_OR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue