+2007-06-02 Maarten Brock <sourceforge.brock AT dse.nl>
+
+ * src/mcs51/gen.c (outBitC, genRet): used IS_OP_RUONLY,
+ (genNot, genXor): used toCarry, also fixes a bug for c = bit ^ val
+ * src/mcs51/ralloc.c: removed IS_OP_RUONLY + some cosmetic changes
+ * src/SDCCast.c (resultTypePropagate): propagate for '!',
+ (decorateType): also optimize comparisons with RESULT_TYPE_BIT,
+ bugfix: only use newBoolLink for bit result type
+ * src/SDCCicode.c (geniCodeLogic): added param tree,
+ bugfix: use newBoolLink if tree is bit type, bug appears when ruonly,
+ (geniCodeLogicAndOr): use IS_BIT,
+ (geniCodeJumpTable, geniCodeSwitch): added NULL param to geniCodeLogic,
+ (ast2iCode): added tree param to geniCodeLogic for comparisons
+ * src/SDCCsymt.h: added IS_OP_RUONLY and IS_OP_ACCUSE
+ * support/regression/tests/bug1723128.c: added test NotZero
+
2007-06-01 Borut Razem <borut.razem AT siol.net>
* SDCPP synchronized with GCC CPP release version 4.2.0,
* src/regression/Makefile,
* src/regression/pcodeopt.c: regression test for the above fix
-2007-05-08 Maarten Brock <sourceforge.brock AT dse.nl>
+2007-05-11 Maarten Brock <sourceforge.brock AT dse.nl>
* src/SDCCpeeph.c (labelIsUncondJump): ignore identical labels for
jumps to self, fixed bug 1717281
{
case AND_OP:
case OR_OP:
+ case '!':
return resultType;
case '=':
case '?':
if (IS_LITERAL(RTYPE(tree)) &&
floatFromVal (valFromType (RETYPE (tree))) == 0 &&
tree->opval.op == EQ_OP &&
- resultType == RESULT_TYPE_IFX)
+ (resultType == RESULT_TYPE_IFX || resultType == RESULT_TYPE_BIT))
{
tree->opval.op = '!';
tree->right = NULL;
}
LRVAL (tree) = RRVAL (tree) = 1;
- TTYPE (tree) = TETYPE (tree) = newBoolLink ();
+ TTYPE (tree) = TETYPE (tree) = (resultType == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
/* condition transformations */
{
root->right->opval.val : NULL);
/* if left is a BITVAR in BITSPACE */
- /* and right is a LITERAL then opt- */
- /* imize else do nothing */
+ /* and right is a LITERAL then */
+ /* optimize else do nothing */
if (vleft && vright &&
IS_BITVAR (vleft->etype) &&
IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
/* This seems very dangerous to me, since there are several */
/* optimizations (for example, gcse) that don't notice the */
- /* cast hidden in this assignement and may simplify an */
+ /* cast hidden in this assignment and may simplify an */
/* iCode to use the original (uncasted) operand. */
/* Unfortunately, other things break when this cast is */
/* made explicit. Need to fix this someday. */
/*-----------------------------------------------------------------*/
-/* geniCodeBitwise - gen int code for bitWise operators */
+/* geniCodeBitwise - gen int code for bitWise operators */
/*-----------------------------------------------------------------*/
operand *
geniCodeBitwise (operand * left, operand * right,
/* geniCodeLogic- logic code */
/*-----------------------------------------------------------------*/
static operand *
-geniCodeLogic (operand * left, operand * right, int op)
+geniCodeLogic (operand * left, operand * right, int op, ast *tree)
{
iCode *ic;
- sym_link *ctype;
+ sym_link *ctype, *ttype;
sym_link *rtype = operandType (right);
sym_link *ltype = operandType (left);
ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_BIT, 0);
ic = newiCode (op, left, right);
- IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
+ /* store 0 or 1 in result */
+ ttype = (tree && IS_BIT (tree->ftype)) ? newBoolLink() : newCharLink();
+ IC_RESULT (ic) = newiTempOperand (ttype, 1);
/* if comparing float
and not a '==' || '!=' || '&&' || '||' (these
ADDTOCHAIN (ic);
/* store 0 or 1 in result */
- type = (SPEC_NOUN(tree->ftype) == V_BIT) ? newBoolLink() : newCharLink();
+ type = (IS_BIT (tree->ftype)) ? newBoolLink() : newCharLink();
result = newiTempOperand (type, 1);
geniCodeLabel (falseLabel);
the condition is unsigned & minimum value is zero */
if (!(min == 0 && IS_UNSIGNED (cetype)))
{
- boundary = geniCodeLogic (cond, operandFromLit (min), '<');
+ boundary = geniCodeLogic (cond, operandFromLit (min), '<', NULL);
ic = newiCodeCondition (boundary, falseLabel, NULL);
ADDTOCHAIN (ic);
}
/* now for upper bounds */
- boundary = geniCodeLogic (cond, operandFromLit (max), '>');
+ boundary = geniCodeLogic (cond, operandFromLit (max), '>', NULL);
ic = newiCodeCondition (boundary, falseLabel, NULL);
ADDTOCHAIN (ic);
}
operand *compare = geniCodeLogic (cond,
operandFromValue (caseVals),
- EQ_OP);
+ EQ_OP, NULL);
SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
tree->values.switchVals.swNum,
leftOp = geniCodeRValue (left , FALSE);
rightOp = geniCodeRValue (right, FALSE);
- return geniCodeLogic (leftOp, rightOp, tree->opval.op);
+ return geniCodeLogic (leftOp, rightOp, tree->opval.op, tree);
}
case '?':
return geniCodeConditional (tree,lvl);
unsigned b_signed:1; /* just for sanity checks only*/
unsigned b_static:1; /* 1=static keyword found */
unsigned b_extern:1; /* 1=extern found */
- unsigned b_inline:1; /* inline function requested */
+ unsigned b_inline:1; /* inline function requested */
unsigned b_absadr:1; /* absolute address specfied */
unsigned b_volatile:1; /* is marked as volatile */
unsigned b_const:1; /* is a constant */
struct iCode *fuse; /* furthest use */
struct iCode *rematiCode; /* rematerialise with which instruction */
struct operand *reqv; /* register equivalent of a local variable */
- struct symbol *prereqv; /* symbol before register equiv. substituion */
+ struct symbol *prereqv; /* symbol before register equiv. substitution */
struct symbol *psbase; /* if pseudo symbol, the symbol it is based on */
union
{
const char *file,
unsigned line);
/* Easy Access Macros */
+#define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
+#define IS_OP_ACCUSE(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->accuse)
+
#define DCL_TYPE(l) validateLink(l, "DCL_TYPE", #l, DECLARATOR, __FILE__, __LINE__)->select.d.dcl_type
#define DCL_ELEM(l) validateLink(l, "DCL_ELEM", #l, DECLARATOR, __FILE__, __LINE__)->select.d.num_elem
#define DCL_PTR_CONST(l) validateLink(l, "DCL_PTR_CONST", #l, DECLARATOR, __FILE__, __LINE__)->select.d.ptr_const
static unsigned short rbank = -1;
-#define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
-
#define REG_WITH_INDEX mcs51_regWithIdx
#define AOP(op) op->aop
/* if the result is bit */
if (AOP_TYPE (result) == AOP_CRY)
{
- if (!OP_SYMBOL (result)->ruonly)
+ if (!IS_OP_RUONLY (result))
aopPut (result, "c", 0);
}
else
}
else
{
- emitcode ("mov", "c,%s", IC_LEFT (ic)->aop->aopu.aop_dir);
+ toCarry (IC_LEFT (ic));
emitcode ("cpl", "c");
outBitC (IC_RESULT (ic));
}
if (IS_BIT(_G.currentFunc->etype))
{
- if (!(IS_SYMOP (IC_LEFT (ic)) && OP_SYMBOL (IC_LEFT (ic))->ruonly))
+ if (!IS_OP_RUONLY (IC_LEFT (ic)))
toCarry (IC_LEFT (ic));
}
else
}
else
{
- int sizer = AOP_SIZE (right);
// c = bit ^ val
- // if val>>1 != 0, result = 1
- emitcode ("setb", "c");
- while (sizer)
- {
- MOVA (aopGet (right, sizer - 1, FALSE, FALSE));
- if (sizer == 1)
- // test the msb of the lsb
- emitcode ("anl", "a,#0xfe");
- emitcode ("jnz", "%05d$", tlbl->key + 100);
- sizer--;
- }
- // val = (0,1)
- emitcode ("rrc", "a");
+ toCarry (right);
}
emitcode ("jnb", "%s,%05d$", AOP (left)->aopu.aop_dir, (tlbl->key + 100));
emitcode ("cpl", "c");
/* Don't move an assignment out of a critical block */
if (dic->op == CRITICAL)
- {
- dic = NULL;
- break;
- }
+ {
+ dic = NULL;
+ break;
+ }
if (SKIP_IC2 (dic))
continue;
return 0;
}
-#define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
-
/*-----------------------------------------------------------------*/
/* packRegsForOneuse : - will reduce some registers for single Use */
}
else
{
- /* otherwise check that the definition does
- not contain any symbols in far space */
- if (isOperandInFarSpace (IC_LEFT (dic)) ||
- isOperandInFarSpace (IC_RIGHT (dic)) ||
- IS_OP_RUONLY (IC_LEFT (ic)) ||
- IS_OP_RUONLY (IC_RIGHT (ic)))
- {
- return NULL;
- }
+ /* otherwise check that the definition does
+ not contain any symbols in far space */
+ if (isOperandInFarSpace (IC_LEFT (dic)) ||
+ isOperandInFarSpace (IC_RIGHT (dic)) ||
+ IS_OP_RUONLY (IC_LEFT (ic)) ||
+ IS_OP_RUONLY (IC_RIGHT (ic)))
+ {
+ return NULL;
+ }
- /* if pointer set then make sure the pointer
- is one byte */
- if (POINTER_SET (dic) &&
- !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
- return NULL;
+ /* if pointer set then make sure the pointer
+ is one byte */
+ if (POINTER_SET (dic) &&
+ !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
+ return NULL;
- if (POINTER_GET (dic) &&
- !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
- return NULL;
+ if (POINTER_GET (dic) &&
+ !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
+ return NULL;
}
/* Make sure no overlapping liverange is already assigned to DPTR */
getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
return;
- /* if the usage is not is an assignment
+ /* if the usage is not an assignment
or an arithmetic / bitwise / shift operation then not */
if (uic->op != '=' &&
!IS_ARITHMETIC_OP (uic) &&
if (POINTER_SET (ic))
OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
- if (POINTER_GET (ic) &&
- IS_SYMOP(IC_LEFT (ic)))
+ if (POINTER_GET (ic) && IS_SYMOP(IC_LEFT (ic)))
OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
if (!SKIP_IC2 (ic))
}
else
{
- mcs51_nRegs = 8;
+ mcs51_nRegs = 8;
}
_G.allBitregs = findAllBitregs ();
for (i=0; i<(rx_index-1); i++)
crc = crc_table[rx_buffer[i] ^ crc] ;
- return (crc == rx_buffer[rx_index-1]) ;
+ return (crc == rx_buffer[rx_index-1]) ;
+}
+
+bool NotZero(unsigned int t)
+{
+ return (t != 0);
}
void
testBug(void)
{
- rx_index = 1;
- ASSERT (VerifyCRC());
+ rx_index = 1;
+ ASSERT (VerifyCRC());
+ ASSERT (NotZero(300));
}