aopPut(res->aop,zero,offset++);
}
+/*-----------------------------------------------------------------*/
+/* opIsGptr: returns non-zero if the passed operand is */
+/* a generic pointer type. */
+/*-----------------------------------------------------------------*/
+static int opIsGptr(operand *op)
+{
+ link *type = operandType(op);
+
+ if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
+ {
+ return 1;
+ }
+ return 0;
+}
+
/*-----------------------------------------------------------------*/
/* getDataSize - get the operand data size */
/*-----------------------------------------------------------------*/
{
int size;
size = AOP_SIZE(op);
- if(size == 3)
- /* pointer */
- size--;
+ if (size == GPTRSIZE)
+ {
+ link *type = operandType(op);
+ if (IS_GENPTR(type))
+ {
+ /* generic pointer; arithmetic operations
+ * should ignore the high byte (pointer type).
+ */
+ size--;
+ }
+ }
return size;
}
}
emitcode("inc","%s",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
- if(size == 4){
+ if (size > 2)
+ {
if(AOP_TYPE(IC_RESULT(ic)) == AOP_REG ||
IS_AOP_PREG(IC_RESULT(ic)))
emitcode("cjne","%s,#0x00,%05d$"
,tlbl->key+100);
emitcode("inc","%s",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
+ }
+ if (size > 3)
+ {
if(AOP_TYPE(IC_RESULT(ic)) == AOP_REG ||
IS_AOP_PREG(IC_RESULT(ic)))
emitcode("cjne","%s,#0x00,%05d$"
}
}
+#if 0
+/* This is the original version of this code.
+ *
+ * This is being kept around for reference,
+ * because I am not entirely sure I got it right...
+ */
+static void adjustArithmeticResult(iCode *ic)
+{
+ if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
+ AOP_SIZE(IC_LEFT(ic)) == 3 &&
+ !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
+ aopPut(AOP(IC_RESULT(ic)),
+ aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
+ 2);
+
+ if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
+ AOP_SIZE(IC_RIGHT(ic)) == 3 &&
+ !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
+ aopPut(AOP(IC_RESULT(ic)),
+ aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
+ 2);
+
+ if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
+ AOP_SIZE(IC_LEFT(ic)) < 3 &&
+ AOP_SIZE(IC_RIGHT(ic)) < 3 &&
+ !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
+ !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
+ char buffer[5];
+ sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
+ aopPut(AOP(IC_RESULT(ic)),buffer,2);
+ }
+}
+#else
+/* This is the pure and virtuous version of this code.
+ * I'm pretty certain it's right, but not enough to toss the old
+ * code just yet...
+ */
+static void adjustArithmeticResult(iCode *ic)
+{
+ if (opIsGptr(IC_RESULT(ic)) &&
+ opIsGptr(IC_LEFT(ic)) &&
+ !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
+ {
+ aopPut(AOP(IC_RESULT(ic)),
+ aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
+ GPTRSIZE - 1);
+ }
+
+ if (opIsGptr(IC_RESULT(ic)) &&
+ opIsGptr(IC_RIGHT(ic)) &&
+ !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
+ {
+ aopPut(AOP(IC_RESULT(ic)),
+ aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
+ GPTRSIZE - 1);
+ }
+
+ if (opIsGptr(IC_RESULT(ic)) &&
+ AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE &&
+ AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE &&
+ !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
+ !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
+ char buffer[5];
+ sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
+ aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
+ }
+}
+#endif
+
/*-----------------------------------------------------------------*/
/* genPlus - generates code for addition */
/*-----------------------------------------------------------------*/
aopPut(AOP(IC_RESULT(ic)),"a",offset++);
}
- if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
- AOP_SIZE(IC_LEFT(ic)) == 3 &&
- !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
- aopPut(AOP(IC_RESULT(ic)),
- aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
- 2);
+ adjustArithmeticResult(ic);
- if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
- AOP_SIZE(IC_RIGHT(ic)) == 3 &&
- !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
- aopPut(AOP(IC_RESULT(ic)),
- aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
- 2);
-
- if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
- AOP_SIZE(IC_LEFT(ic)) < 3 &&
- AOP_SIZE(IC_RIGHT(ic)) < 3 &&
- !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
- !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
- char buffer[5];
- sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
- aopPut(AOP(IC_RESULT(ic)),buffer,2);
- }
release:
freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
,tlbl->key+100);
}
emitcode("dec","%s",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
- if(size == 4){
+ if (size > 2)
+ {
if(AOP_TYPE(IC_RESULT(ic)) == AOP_REG ||
IS_AOP_PREG(IC_RESULT(ic)))
emitcode("cjne","%s,#0xff,%05d$"
,tlbl->key+100);
}
emitcode("dec","%s",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
+ }
+ if (size > 3)
+ {
if(AOP_TYPE(IC_RESULT(ic)) == AOP_REG ||
IS_AOP_PREG(IC_RESULT(ic)))
emitcode("cjne","%s,#0xff,%05d$"
}
aopPut(AOP(IC_RESULT(ic)),"a",offset++);
}
-
- if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
- AOP_SIZE(IC_LEFT(ic)) == 3 &&
- !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
- aopPut(AOP(IC_RESULT(ic)),
- aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
- 2);
- if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
- AOP_SIZE(IC_RIGHT(ic)) == 3 &&
- !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
- aopPut(AOP(IC_RESULT(ic)),
- aopGet(AOP(IC_RIGHT(ic)),2,FALSE,FALSE),
- 2);
-
- if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
- AOP_SIZE(IC_LEFT(ic)) < 3 &&
- AOP_SIZE(IC_RIGHT(ic)) < 3 &&
- !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
- !sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
- char buffer[5];
- sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
- aopPut(AOP(IC_RESULT(ic)),buffer,2);
- }
+ adjustArithmeticResult(ic);
+
release:
freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
/*-----------------------------------------------------------------*/
static void genlshTwo (operand *result,operand *left, int shCount)
{
- int size = AOP_SIZE(result);
-
- if (size == 3)
- size--;
+ int size;
+
+ size = getDataSize(result);
/* if shCount >= 8 */
if (shCount >= 8) {