+2007-07-13 Maarten Brock <sourceforge.brock AT dse.nl>
+
+ * src/SDCCcse.c (replaceAllSymBySym): renamed siaddr to isaddr,
+ (cseBBlock): remember aggr2ptr has been used
+ * src/SDCCicode.c (operandSize): added function to handle aggr2ptr,
+ (geniCodeAssign): fixed bug 868103
+ * src/SDCCicode.h: made operand.aggr2ptr 2 bits wide,
+ added operandSize prototype
+ * src/mcs51/gen.c (aopOp): use operandSize to fix bug 868103,
+ (genDataPointerSet): use size of result,
+ (gencjne): added parameter useCarry for optimization,
+ (genCmpEq): use carry if appropriate,
+ (genXor): check if operand already in carry
+ * support/regression/tests/bug-868103.c: enabled test
+
2007-07-12 Raphael Neider <rneider AT web.de>
* src/pic16/gen.c (genNearPointerSet): fixed handling of literals
#endif
for (lic = ic; lic; lic = lic->next)
{
- int siaddr;
+ int isaddr;
/* do the special cases first */
if (lic->op == IFX)
bitVectUnSetBit (OP_USES (from), lic->key);
OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
- siaddr = IC_COND (lic)->isaddr;
+ isaddr = IC_COND (lic)->isaddr;
IC_COND (lic) = operandFromOperand (to);
- IC_COND (lic)->isaddr = siaddr;
+ IC_COND (lic)->isaddr = isaddr;
}
continue;
bitVectUnSetBit (OP_USES (from), lic->key);
OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
- siaddr = IC_COND (lic)->isaddr;
+ isaddr = IC_COND (lic)->isaddr;
IC_JTCOND (lic) = operandFromOperand (to);
- IC_JTCOND (lic)->isaddr = siaddr;
+ IC_JTCOND (lic)->isaddr = isaddr;
}
continue;
bitVectUnSetBit (OP_DEFS (from), lic->key);
OP_DEFS(to)=bitVectSetBit (OP_DEFS (to), lic->key);
}
- siaddr = IC_RESULT (lic)->isaddr;
+ isaddr = IC_RESULT (lic)->isaddr;
IC_RESULT (lic) = operandFromOperand (to);
- IC_RESULT (lic)->isaddr = siaddr;
+ IC_RESULT (lic)->isaddr = isaddr;
}
if (IS_SYMOP (to) &&
{
bitVectUnSetBit (OP_USES (from), lic->key);
OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
- siaddr = IC_RIGHT (lic)->isaddr;
+ isaddr = IC_RIGHT (lic)->isaddr;
IC_RIGHT (lic) = operandFromOperand (to);
- IC_RIGHT (lic)->isaddr = siaddr;
+ IC_RIGHT (lic)->isaddr = isaddr;
}
if (IS_SYMOP (to) &&
{
bitVectUnSetBit (OP_USES (from), lic->key);
OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
- siaddr = IC_LEFT (lic)->isaddr;
+ isaddr = IC_LEFT (lic)->isaddr;
IC_LEFT (lic) = operandFromOperand (to);
- IC_LEFT (lic)->isaddr = siaddr;
+ IC_LEFT (lic)->isaddr = isaddr;
}
}
}
IC_LEFT (ic)->aggr2ptr = 0;
fixUpTypes (ic);
}
- else if (IC_LEFT (ic)->aggr2ptr)
+ else if (IC_LEFT (ic)->aggr2ptr == 1)
{/* band aid for kludge */
setOperandType (IC_LEFT (ic),
aggrToPtr (operandType (IC_LEFT (ic)), TRUE));
- IC_LEFT (ic)->aggr2ptr = 0;
+ IC_LEFT (ic)->aggr2ptr++;
fixUpTypes (ic);
}
}
aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
IC_RESULT (ic)->aggr2ptr = 0;
}
- else if (IC_RESULT (ic)->aggr2ptr)
+ else if (IC_RESULT (ic)->aggr2ptr == 1)
{/* band aid for kludge */
setOperandType (IC_RESULT (ic),
aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
- IC_RESULT (ic)->aggr2ptr = 0;
+ IC_RESULT (ic)->aggr2ptr++;
}
}
}
}
- /*right operand */
+ /* right operand */
if (IS_SYMOP (IC_RIGHT (ic)) && !computeOnly)
{
deleteItemIf (&cseSet, ifOperandsHave, IC_RESULT (ic));
/* delete any previous definitions */
ebb->defSet = bitVectCplAnd (ebb->defSet, OP_DEFS (IC_RESULT (ic)));
-
}
/* add the left & right to the defUse set */
OP_USES(IC_LEFT (ic))=
bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
-
}
if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
OP_USES(IC_RIGHT (ic))=
bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
-
}
/* for the result it is special case, put the result */
}
}
+/*-----------------------------------------------------------------*/
+/* operandSize - returns size of an operand in bytes */
+/*-----------------------------------------------------------------*/
+unsigned int
+operandSize (operand * op)
+{
+ sym_link *type;
+
+ /* if nothing return 0 */
+ if (!op)
+ return 0;
+
+ type = operandType (op);
+ if (op->aggr2ptr == 2)
+ type = type->next;
+ return getSize (type);
+}
+
/*-----------------------------------------------------------------*/
/* isParamterToCall - will return 1 if op is a parameter to args */
/*-----------------------------------------------------------------*/
if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
compareType (ltype, rtype) <= 0)
{
- if (compareType (ltype->next, rtype) < 0)
+ if (left->aggr2ptr)
+ right = geniCodeCast (ltype, right, TRUE);
+ else if (compareType (ltype->next, rtype) < 0)
right = geniCodeCast (ltype->next, right, TRUE);
}
else if (compareType (ltype, rtype) < 0)
tree->opval.op);
*/
{
- operand *leftOp, *rightOp;
+ operand *leftOp, *rightOp;
leftOp = geniCodeRValue (left , FALSE);
rightOp = geniCodeRValue (right, FALSE);
{
OPTYPE type; /* type of operand */
unsigned int isaddr:1; /* is an address */
- unsigned int aggr2ptr:1; /* must change aggregate to pointer to aggregate */
+ unsigned int aggr2ptr:2; /* 1: must change aggregate to pointer to aggregate */
+ /* 2: aggregate has been changed to pointer to aggregate */
unsigned int isvolatile:1; /* is a volatile operand */
unsigned int isGlobal:1; /* is a global operand */
unsigned int isPtr:1; /* is assigned a pointer */
symbol *newiTempLoopHeaderLabel (bool);
iCode *newiCode (int, operand *, operand *);
sym_link *operandType (operand *);
+unsigned int operandSize (operand *);
operand *operandFromValue (value *);
operand *operandFromSymbol (symbol *);
operand *operandFromLink (sym_link *);
if (sym->remat)
{
sym->aop = op->aop = aop = aopForRemat (sym);
- aop->size = getSize (sym->type);
+ aop->size = operandSize (op);
return;
}
/* gencjne - compare and jump if not equal */
/*-----------------------------------------------------------------*/
static void
-gencjne (operand * left, operand * right, symbol * lbl)
+gencjne (operand * left, operand * right, symbol * lbl, bool useCarry)
{
symbol *tlbl = newiTempLabel (NULL);
gencjneshort (left, right, lbl);
- emitcode ("mov", "a,%s", one);
+ if (useCarry)
+ SETC;
+ else
+ MOVA (one);
emitcode ("sjmp", "%05d$", tlbl->key + 100);
emitLabel (lbl);
- emitcode ("clr", "a");
+ if (useCarry)
+ CLRC;
+ else
+ MOVA (zero);
emitLabel (tlbl);
}
}
else
{
- gencjne (left, right, newiTempLabel (NULL));
if (AOP_TYPE (result) == AOP_CRY && AOP_SIZE (result))
{
- aopPut (result, "a", 0);
+ gencjne (left, right, newiTempLabel (NULL), TRUE);
+ aopPut (result, "c", 0);
goto release;
}
+ gencjne (left, right, newiTempLabel (NULL), FALSE);
if (ifx)
{
genIfxJump (ifx, "a", left, right, result);
if (AOP_TYPE (right) == AOP_CRY)
{
// c = bit ^ bit;
- emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
+ if (IS_SYMOP (left) && OP_SYMBOL (left) && OP_SYMBOL (left)->accuse)
+ {// left already is in the carry
+ operand *tmp = right;
+ right = left;
+ left = tmp;
+ }
+ else
+ {
+ emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
+ }
}
else
{
l = aopGet (result, 0, FALSE, TRUE);
l++; //remove #
- size = AOP_SIZE (right);
+ size = AOP_SIZE (result);
while (size--)
{
if (offset)
aopGet (right, offset++, FALSE, FALSE));
}
- freeAsmop (result, NULL, ic, TRUE);
freeAsmop (right, NULL, ic, TRUE);
+ freeAsmop (result, NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
}
/* done */
- if (pi) pi->generated = 1;
- freeAsmop (result, NULL, ic, TRUE);
+ if (pi)
+ pi->generated = 1;
freeAsmop (right, NULL, ic, TRUE);
+ freeAsmop (result, NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
#include <testfwk.h>
-#if defined(PORT_HOST) || defined(SDCC_z80) || defined(SDCC_gbz80)
-# define near
-# define far
-# define code
-#endif
-
typedef struct {
STORAGE1 char * bar[2];
} foo;
STORAGE1 char c = 'x';
STORAGE2 foo f;
-void bug868103(void)
+void
+testBug868103(void)
{
f.bar[1] = &c;
ASSERT(f.bar[1] == &c);