+2007-09-16 Borut Razem <borut.razem AT siol.net>
+
+ * src/SDCC.y, src/SDCCast.c, src/SDCCcse.c, src/SDCCglue.c, src/SDCCicode.c,
+ src/SDCCopt.c, src/SDCCsymt.c, src/SDCCval.c, src/SDCCval.h,
+ src/hc08/gen.c, src/avr/gen.c, src/ds390/gen.c, src/mcs51/gen.c,
+ src/pic/gen.c, src/pic/genarith.c, src/pic/glue.c, src/pic/ralloc.c,
+ src/pic16/gen.c, src/pic16/genarith.c, src/pic16/genutils.c,
+ src/pic16/glue.c, src/pic16/main.c, src/z80/gen.c, src/z80/ralloc.c:
+ fixed bug #1739860 - sdcc does not work correctly on some platforms
+ (not finished)
+ introduced and used ulFromVal(), double2ul(), used strtod() instead sscanf()
+
2007-09-17 Raphael Neider <rneider AT web.de>
* src/pic16/device.c: reverted to previous version
function_attributes
: USING constant_expr {
$$ = newLink(SPECIFIER) ;
- FUNC_REGBANK($$) = (int) floatFromVal(constExprValue($2,TRUE));
+ FUNC_REGBANK($$) = (int) ulFromVal(constExprValue($2,TRUE));
}
| REENTRANT { $$ = newLink (SPECIFIER);
FUNC_ISREENT($$)=1;
Interrupt_storage
: INTERRUPT { $$ = INTNO_UNSPEC ; }
| INTERRUPT constant_expr
- { int intno = (int) floatFromVal(constExprValue($2,TRUE));
+ { int intno = (int) ulFromVal(constExprValue($2,TRUE));
if ((intno >= 0) && (intno <= INTNO_MAX))
$$ = intno;
else
/* add this to the storage class specifier */
SPEC_ABSA($1) = 1; /* set the absolute addr flag */
/* now get the abs addr from value */
- SPEC_ADDR($1) = (unsigned) floatFromVal(constExprValue($3,TRUE)) ;
+ SPEC_ADDR($1) = (unsigned int) ulFromVal(constExprValue($3,TRUE)) ;
}
;
| ':' constant_expr {
unsigned int bitsize;
$$ = newSymbol (genSymName(NestLevel),NestLevel) ;
- bitsize= (unsigned int) floatFromVal(constExprValue($2,TRUE));
+ bitsize = (unsigned int) ulFromVal(constExprValue($2,TRUE));
if (bitsize > (port->s.int_size * 8)) {
bitsize = port->s.int_size * 8;
werror(E_BITFLD_SIZE, bitsize);
| declarator ':' constant_expr
{
unsigned int bitsize;
- bitsize= (unsigned int) floatFromVal(constExprValue($3,TRUE));
+ bitsize = (unsigned int) ulFromVal(constExprValue($3,TRUE));
if (bitsize > (port->s.int_size * 8)) {
bitsize = port->s.int_size * 8;
werror(E_BITFLD_SIZE, bitsize);
{
werror(E_ENUM_NON_INTEGER);
SNPRINTF(lbuff, sizeof(lbuff),
- "%d",(int) floatFromVal(val));
+ "%d", (int) ulFromVal(val));
val = constVal(lbuff);
}
$$ = cenum = val ;
| {
if (cenum) {
SNPRINTF(lbuff, sizeof(lbuff),
- "%d",(int) floatFromVal(cenum)+1);
+ "%d", (int) ulFromVal(cenum)+1);
$$ = cenum = constVal(lbuff);
}
else {
}
else
{
- if ((size = (int)floatFromVal(tval)) < 0)
+ if ((size = (int) ulFromVal(tval)) < 0)
{
werror(E_NEGATIVE_ARRAY_SIZE, $1->name);
size = 1;
value *val ;
$$ = newLink (DECLARATOR);
DCL_TYPE($$) = ARRAY ;
- DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($2,TRUE));
+ DCL_ELEM($$) = (int) ulFromVal(val = constExprValue($2,TRUE));
}
| abstract_declarator2 '[' ']' {
$$ = newLink (DECLARATOR);
value *val ;
$$ = newLink (DECLARATOR);
DCL_TYPE($$) = ARRAY ;
- DCL_ELEM($$) = (int) floatFromVal(val = constExprValue($3,TRUE));
+ DCL_ELEM($$) = (int) ulFromVal(val = constExprValue($3,TRUE));
$$->next = $1 ;
}
| '(' ')' { $$ = NULL;}
if (IS_LITERAL (RTYPE (tree)))
{
- int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
+ int arrayIndex = (int) ulFromVal (valFromType (RETYPE (tree)));
int arraySize = DCL_ELEM (LTYPE (tree));
if (arraySize && arrayIndex >= arraySize)
{
/* rearrange the tree */
if (IS_LITERAL (RTYPE (tree))
/* avoid infinite loop */
- && (TYPE_TARGET_ULONG) floatFromVal (tree->right->opval.val) != 1)
+ && (TYPE_TARGET_ULONG) ulFromVal (tree->right->opval.val) != 1)
{
ast *parent;
ast *litTree = searchLitOp (tree, &parent, "/");
/* rearrange the tree */
if (IS_LITERAL (RTYPE (tree))
/* avoid infinite loop */
- && (TYPE_TARGET_ULONG) floatFromVal (tree->right->opval.val) != 0)
+ && (TYPE_TARGET_ULONG) ulFromVal (tree->right->opval.val) != 0)
{
ast *litTree, *litParent;
litTree = searchLitOp (tree, &litParent, "+-");
/* if only the right side is a literal & we are
shifting more than size of the left operand then zero */
if (IS_LITERAL (RTYPE (tree)) &&
- ((TYPE_TARGET_ULONG) floatFromVal (valFromType (RETYPE (tree)))) >=
+ ((TYPE_TARGET_ULONG) ulFromVal (valFromType (RETYPE (tree)))) >=
(getSize (TETYPE (tree)) * 8))
{
if (tree->opval.op==LEFT_OP ||
TTYPE (tree) = tree->opval.val->type;
tree->values.literalFromCast = 1;
} else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
- ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
+ ((int) ulFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
sym_link *rest = LTYPE(tree)->next;
werrorfl (tree->filename, tree->lineno, W_LITERAL_GENERIC);
TTYPE(tree) = newLink(DECLARATOR);
if (tree->opval.op == '>' &&
SPEC_USIGN(LETYPE(tree)) &&
IS_LITERAL(RTYPE(tree)) &&
- ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
+ ((int) ulFromVal (valFromType (RETYPE (tree)))) == 0)
{
if ((resultType == RESULT_TYPE_IFX) || (resultType == RESULT_TYPE_BIT))
{
if (IS_LITERAL (RTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)) &&
/* the value range of a 'unsigned char' is 0...255;
if the actual value is < 128 it can be changed to signed */
- (int) floatFromVal (valFromType (RETYPE (tree))) < 128)
+ (int) ulFromVal (valFromType (RETYPE (tree))) < 128)
{
/* now we've got 2 'signed char'! */
SPEC_USIGN (RETYPE (tree)) = 0;
}
/* same test for the left operand: */
else if (IS_LITERAL (LTYPE (tree)) && IS_UNSIGNED (LTYPE (tree)) &&
- (int) floatFromVal (valFromType (LETYPE (tree))) < 128)
+ (int) ulFromVal (valFromType (LETYPE (tree))) < 128)
{
SPEC_USIGN (LETYPE (tree)) = 0;
}
but faster to do it here */
if (IS_LITERAL (LTYPE (tree)))
{
- if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
+ if (((int) ulFromVal (valFromType (LETYPE (tree)))) != 0)
return decorateType (tree->right->left, resultTypeProp);
else
return decorateType (tree->right->right, resultTypeProp);
{
/* also order the cases according to value */
value *pval = NULL;
- int cVal = (int) floatFromVal (caseVal->opval.val);
- while (val && (int) floatFromVal (val) < cVal)
+ int cVal = (int) ulFromVal (caseVal->opval.val);
+ while (val && (int) ulFromVal (val) < cVal)
{
pval = val;
val = val->next;
{
pval->next = caseVal->opval.val;
}
- else if ((int) floatFromVal (val) == cVal)
+ else if ((int) ulFromVal (val) == cVal)
{
werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
"case");
SNPRINTF(caseLbl, sizeof(caseLbl),
"_case_%d_%d",
swStat->values.switchVals.swNum,
- (int) floatFromVal (caseVal->opval.val));
+ (int) ulFromVal (caseVal->opval.val));
rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
rexpr->lineno = 0;
{
/* if right side > 1 then comparison may never succeed */
- if ((litValue = (int) floatFromVal (vright)) > 1)
+ if ((litValue = (int) ulFromVal (vright)) > 1)
{
werror (W_BAD_COMPARE);
goto noOptimize;
if (IS_LITERAL (tree->opval.val->etype)) {
fprintf(outfile,"CONSTANT (%p) value = ", tree);
if (SPEC_USIGN (tree->opval.val->etype))
- fprintf(outfile,"%u", (TYPE_TARGET_ULONG) floatFromVal(tree->opval.val));
+ fprintf(outfile,"%u", (TYPE_TARGET_ULONG) ulFromVal(tree->opval.val));
else
- fprintf(outfile,"%d", (TYPE_TARGET_LONG) floatFromVal(tree->opval.val));
- fprintf(outfile,", 0x%x, %f", (TYPE_TARGET_ULONG) floatFromVal(tree->opval.val),
+ fprintf(outfile,"%d", (TYPE_TARGET_LONG) ulFromVal(tree->opval.val));
+ fprintf(outfile,", 0x%x, %f", (TYPE_TARGET_ULONG) ulFromVal(tree->opval.val),
floatFromVal(tree->opval.val));
} else if (tree->opval.val->sym) {
/* if the undefined flag is set then give error message */
for (val = tree->values.switchVals.swVals; val ; val = val->next) {
INDENT(indent+2,outfile);
fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
- (int) floatFromVal(val),
+ (int) ulFromVal(val),
tree->values.switchVals.swNum,
- (int) floatFromVal(val));
+ (int) ulFromVal(val));
}
ast_print(tree->right,outfile,indent);
}
default:
return;
}
- if (((unsigned) operandLitValue (IC_RIGHT (ic)) & val) == val)
+ if (((unsigned) double2ul (operandLitValue (IC_RIGHT (ic))) & val) == val)
{
ic->op = '=';
IC_RIGHT (ic) = IC_LEFT (ic);
default:
return;
}
- if (((unsigned) operandLitValue (IC_RIGHT (ic)) & val) == val)
+ if (((unsigned) double2ul (operandLitValue (IC_RIGHT (ic))) & val) == val)
{
if (IS_OP_VOLATILE (IC_LEFT (ic)))
{
/* and also iTemps derived from globals */
deleteItemIf (&cseSet, ifFromGlobal);
-
+
/* Delete iTemps derived from symbols whose address */
/* has been taken */
deleteItemIf (&cseSet, ifFromAddrTaken);
mine and type is a pointer then delete
pointerGets to take care of aliasing */
if (ASSIGNMENT (ic) &&
- IS_SYMOP (IC_RESULT (ic)) &&
+ IS_SYMOP (IC_RESULT (ic)) &&
OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
IS_PTR (operandType (IC_RESULT (ic))))
{
/* if it is a float then it gets tricky */
/* otherwise it is fairly simple */
if (!IS_FLOAT (val->type)) {
- unsigned long v = (unsigned long) floatFromVal (val);
+ unsigned long v = ulFromVal (val);
v >>= (offset * 8);
switch (size) {
size = ((SPEC_BLEN (lsym->etype) / 8) +
(SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
}
- i = (unsigned long)floatFromVal(val);
+ i = ulFromVal(val);
i <<= SPEC_BSTR (lsym->etype);
ival |= i;
if (! ( lsym->next &&
switch (getSize (type))
{
case 1:
- dbuf_tprintf (oBuf, "\t!db !constbyte\n", (unsigned int) floatFromVal (val) & 0xff);
+ dbuf_tprintf (oBuf, "\t!db !constbyte\n", (unsigned int) ulFromVal (val) & 0xff);
break;
case 2:
if (port->use_dw_for_init)
else if (IS_FIXED16X16 (opetype))
dbuf_printf (dbuf, "%g {", doubleFromFixed16x16(SPEC_CVAL (opetype).v_fixed16x16));
else
- dbuf_printf (dbuf, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand));
+ dbuf_printf (dbuf, "0x%x {", (unsigned int) ulFromVal (op->operand.valOperand));
dbuf_printTypeChain (operandType (op), dbuf);
dbuf_append_char (dbuf, '}');
break;
/* signed and unsigned mul are the same, as long as the precision
of the result isn't bigger than the precision of the operands. */
retval = operandFromValue (valCastLiteral (type,
- (TYPE_TARGET_ULONG) operandLitValue (left) *
- (TYPE_TARGET_ULONG) operandLitValue (right)));
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue (left)) *
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue (right))));
else if (IS_UNSIGNED (type)) /* unsigned int */
{
/* unsigned int is handled here in order to detect overflow */
- TYPE_TARGET_ULONG ul = (TYPE_TARGET_UINT) operandLitValue (left) *
- (TYPE_TARGET_UINT) operandLitValue (right);
+ TYPE_TARGET_ULONG ul = (TYPE_TARGET_UINT) double2ul (operandLitValue (left)) *
+ (TYPE_TARGET_UINT) double2ul (operandLitValue (right));
retval = operandFromValue (valCastLiteral (type, (TYPE_TARGET_UINT) ul));
if (ul != (TYPE_TARGET_UINT) ul)
operandLitValue (right)));
break;
case '/':
- if ((TYPE_TARGET_ULONG) operandLitValue (right) == 0)
+ if ((TYPE_TARGET_ULONG) double2ul (operandLitValue (right)) == 0)
{
werror (E_DIVIDE_BY_ZERO);
retval = right;
SPEC_USIGN (let) = 1;
SPEC_USIGN (ret) = 1;
retval = operandFromValue (valCastLiteral (type,
- (TYPE_TARGET_ULONG) operandLitValue (left) /
- (TYPE_TARGET_ULONG) operandLitValue (right)));
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue (left)) /
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue (right))));
}
else
{
}
break;
case '%':
- if ((TYPE_TARGET_ULONG) operandLitValue (right) == 0)
+ if ((TYPE_TARGET_ULONG) double2ul (operandLitValue (right)) == 0)
{
werror (E_DIVIDE_BY_ZERO);
retval = right;
else
{
if (IS_UNSIGNED (type))
- retval = operandFromLit ((TYPE_TARGET_ULONG) operandLitValue (left) %
- (TYPE_TARGET_ULONG) operandLitValue (right));
+ retval = operandFromLit ((TYPE_TARGET_ULONG) double2ul (operandLitValue (left)) %
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue (right)));
else
retval = operandFromLit ((TYPE_TARGET_LONG) operandLitValue (left) %
(TYPE_TARGET_LONG) operandLitValue (right));
/* The number of left shifts is always unsigned. Signed doesn't make
sense here. Shifting by a negative number is impossible. */
retval = operandFromValue (valCastLiteral (type,
- ((TYPE_TARGET_ULONG) operandLitValue (left) <<
- (TYPE_TARGET_ULONG) operandLitValue (right))));
+ ((TYPE_TARGET_ULONG) double2ul (operandLitValue (left)) <<
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue (right)))));
break;
case RIGHT_OP:
/* The number of right shifts is always unsigned. Signed doesn't make
sense here. Shifting by a negative number is impossible. */
if (IS_UNSIGNED(let))
/* unsigned: logic shift right */
- retval = operandFromLit ((TYPE_TARGET_ULONG) operandLitValue (left) >>
- (TYPE_TARGET_ULONG) operandLitValue (right));
+ retval = operandFromLit ((TYPE_TARGET_ULONG) double2ul (operandLitValue (left)) >>
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue (right)));
else
/* signed: arithmetic shift right */
- retval = operandFromLit ((TYPE_TARGET_LONG ) operandLitValue (left) >>
- (TYPE_TARGET_ULONG) operandLitValue (right));
+ retval = operandFromLit ((TYPE_TARGET_LONG) operandLitValue (left) >>
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue (right)));
break;
case EQ_OP:
if (IS_FLOAT (let) || IS_FLOAT (ret))
/* this op doesn't care about signedness */
TYPE_TARGET_ULONG l, r;
- l = (TYPE_TARGET_ULONG) operandLitValue (left);
- r = (TYPE_TARGET_ULONG) operandLitValue (right);
+ l = (TYPE_TARGET_ULONG) double2ul (operandLitValue (left));
+ r = (TYPE_TARGET_ULONG) double2ul (operandLitValue (right));
/* In order to correctly compare 'signed int' and 'unsigned int' it's
neccessary to strip them to 16 bit.
Literals are reduced to their cheapest type, therefore left and
break;
case BITWISEAND:
retval = operandFromValue (valCastLiteral (type,
- (TYPE_TARGET_ULONG)operandLitValue(left) &
- (TYPE_TARGET_ULONG)operandLitValue(right)));
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) &
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue(right))));
break;
case '|':
retval = operandFromValue (valCastLiteral (type,
- (TYPE_TARGET_ULONG)operandLitValue(left) |
- (TYPE_TARGET_ULONG)operandLitValue(right)));
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) |
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue(right))));
break;
case '^':
retval = operandFromValue (valCastLiteral (type,
- (TYPE_TARGET_ULONG)operandLitValue(left) ^
- (TYPE_TARGET_ULONG)operandLitValue(right)));
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) ^
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue(right))));
break;
case AND_OP:
retval = operandFromLit (operandLitValue (left) &&
break;
case RRC:
{
- TYPE_TARGET_ULONG i = (TYPE_TARGET_ULONG) operandLitValue (left);
+ TYPE_TARGET_ULONG i = (TYPE_TARGET_ULONG) double2ul (operandLitValue (left));
retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
(i << 1));
break;
case RLC:
{
- TYPE_TARGET_ULONG i = (TYPE_TARGET_ULONG) operandLitValue (left);
+ TYPE_TARGET_ULONG i = (TYPE_TARGET_ULONG) double2ul (operandLitValue (left));
retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
(i >> 1));
}
break;
case GETABIT:
- retval = operandFromLit (((TYPE_TARGET_ULONG)operandLitValue(left) >>
- (TYPE_TARGET_ULONG)operandLitValue(right)) & 1);
+ retval = operandFromLit (((TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) >>
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue(right))) & 1);
break;
case GETBYTE:
- retval = operandFromLit (((TYPE_TARGET_ULONG)operandLitValue(left) >>
- (TYPE_TARGET_ULONG)operandLitValue(right)) & 0xFF);
+ retval = operandFromLit (((TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) >>
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue(right)) & 0xFF));
break;
case GETWORD:
- retval = operandFromLit (((TYPE_TARGET_ULONG)operandLitValue(left) >>
- (TYPE_TARGET_ULONG)operandLitValue(right)) & 0xFFFF);
+ retval = operandFromLit (((TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) >>
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue(right)) & 0xFFFF));
break;
case GETHBIT:
- retval = operandFromLit (((TYPE_TARGET_ULONG)operandLitValue(left) >>
+ retval = operandFromLit (((TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) >>
((getSize (let) * 8) - 1)) & 1);
break;
case '~':
retval = operandFromValue (valCastLiteral (type,
- ~((TYPE_TARGET_ULONG)
- operandLitValue (left))));
+ ~((TYPE_TARGET_ULONG) double2ul (operandLitValue (left)))));
break;
case '!':
right->operand.valOperand));
if (IS_LITERAL(retype)) {
- p2 = powof2 ((TYPE_TARGET_ULONG) floatFromVal (right->operand.valOperand));
+ p2 = powof2 ((TYPE_TARGET_ULONG) ulFromVal (right->operand.valOperand));
}
resType = usualBinaryConversions (&left, &right, resultType, '*');
!IS_FLOAT (letype) &&
!IS_FIXED (letype) &&
IS_UNSIGNED(letype) &&
- ((p2 = powof2 ((TYPE_TARGET_ULONG)
- floatFromVal (right->operand.valOperand))) > 0)) {
+ ((p2 = powof2 ((TYPE_TARGET_ULONG) ulFromVal (right->operand.valOperand))) > 0)) {
ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
}
else
/* If not all integer numbers are present the algorithm */
/* inserts jumps to the default label for the missing numbers */
/* and decides later whether it is worth it */
- min = (int) floatFromVal (vch = caseVals);
+ min = (int) ulFromVal (vch = caseVals);
while (vch->next)
{
cnt++;
vch = vch->next;
}
- max = (int) floatFromVal (vch);
+ max = (int) ulFromVal (vch);
/* Exit if the range is too large to handle with a jump table. */
if (1 + max - min > port->jumptableCost.maxCount)
/* Build the list of labels for the jump table. */
vch = caseVals;
- t = (int) floatFromVal (vch);
+ t = (int) ulFromVal (vch);
for (i=min; i<=max; i++)
{
if (vch && t==i)
addSet (&labels, newiTempLabel (buffer));
vch = vch->next;
if (vch)
- t = (int) floatFromVal (vch);
+ t = (int) ulFromVal (vch);
}
else
{
{
int switchVal, caseVal;
- switchVal = (int) floatFromVal (cond->operand.valOperand);
+ switchVal = (int) ulFromVal (cond->operand.valOperand);
while (caseVals)
{
- caseVal = (int) floatFromVal (caseVals);
+ caseVal = (int) ulFromVal (caseVals);
if (caseVal == switchVal)
{
SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
tree->values.switchVals.swNum,
- (int) floatFromVal (caseVals));
+ (int) ulFromVal (caseVals));
trueLabel = newiTempLabel (buffer);
ic = newiCodeCondition (compare, trueLabel, NULL);
tree->opval.op);
*/
{
- operand *leftOp, *rightOp;
+ operand *leftOp, *rightOp;
leftOp = geniCodeRValue (left , FALSE);
rightOp = geniCodeRValue (right, FALSE);
bitVectUnSetBit (OP_USES (left), ic->key);
if (IS_SYMOP (right))
bitVectUnSetBit (OP_USES (right), ic->key);
-
+
if (IS_FLOAT (operandType (right))) {
switch (ic->op)
{
break;
}
}
-
+
/* if float support routines NOT compiled as reentrant */
if (!options.float_rent)
if(!SPEC_EXTR(func->etype)) {
memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
- SPEC_EXTR(func->etype) = 1;
- seg = SPEC_OCLS( func->etype );
- addSet(&seg->syms, func);
+ SPEC_EXTR(func->etype) = 1;
+ seg = SPEC_OCLS( func->etype );
+ addSet(&seg->syms, func);
}
}
if (!options.float_rent)
{
/* first one */
- if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
+ if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
{
newic = newiCode (SEND, IC_RIGHT (ic), NULL);
newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
FUNC_HASFCALL (currFunc->type) = 1;
if(TARGET_IS_PIC16 || TARGET_IS_PIC) {
- /* normally these functions aren't marked external, so we can use their
- * _extern field to marked as already added to symbol table */
-
- if(!SPEC_EXTR(func->etype)) {
- memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
-
- SPEC_EXTR(func->etype) = 1;
- seg = SPEC_OCLS( func->etype );
- addSet(&seg->syms, func);
- }
+ /* normally these functions aren't marked external, so we can use their
+ * _extern field to marked as already added to symbol table */
+
+ if(!SPEC_EXTR(func->etype)) {
+ memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
+
+ SPEC_EXTR(func->etype) = 1;
+ seg = SPEC_OCLS( func->etype );
+ addSet(&seg->syms, func);
+ }
}
addiCodeToeBBlock (ebp, newic, ip);
/*----------------------------------------------------------------------*/
/* cnvToFixed16x16Cast - converts casts to fixed16x16 to function calls */
/*----------------------------------------------------------------------*/
-static void
+static void
cnvToFixed16x16Cast (iCode * ic, eBBlock * ebp)
{
iCode *ip, *newic;
for (bwd = 0; bwd < 3; bwd++)
{
for (su = 0; su < 2; su++)
- {
- if (compareType (type, __multypes[bwd][su]) == 1)
- {
- func = __fp16x16conv[0][bwd][su];
- goto found;
- }
- }
+ {
+ if (compareType (type, __multypes[bwd][su]) == 1)
+ {
+ func = __fp16x16conv[0][bwd][su];
+ goto found;
+ }
+ }
}
assert (0);
found:
/*--------------------------------------------------------------------------*/
/* cnvFromFixed16x16Cast - converts casts from fixed16x16 to function calls */
/*--------------------------------------------------------------------------*/
-static void
+static void
cnvFromFixed16x16Cast (iCode * ic, eBBlock * ebp)
{
iCode *ip, *newic;
}
}
}
-
+
if (compareType (type, floatType) == 1)
{
func = __fp16x16conv[1][3][0];
goto found;
}
-
+
assert (0);
found:
FUNC_HASFCALL (currFunc->type) = 1;
if(TARGET_IS_PIC16 || TARGET_IS_PIC) {
- /* normally these functions aren't marked external, so we can use their
- * _extern field to marked as already added to symbol table */
-
- if(!SPEC_EXTR(func->etype)) {
- memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
-
- SPEC_EXTR(func->etype) = 1;
- seg = SPEC_OCLS( func->etype );
- addSet(&seg->syms, func);
- }
+ /* normally these functions aren't marked external, so we can use their
+ * _extern field to marked as already added to symbol table */
+
+ if(!SPEC_EXTR(func->etype)) {
+ memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
+
+ SPEC_EXTR(func->etype) = 1;
+ seg = SPEC_OCLS( func->etype );
+ addSet(&seg->syms, func);
+ }
}
addiCodeToeBBlock (ebp, newic, ip);
cnvFromFloatCast (ic, ebbs[i]);
else if (IS_FLOAT (operandType (IC_LEFT (ic))))
cnvToFloatCast (ic, ebbs[i]);
- if (IS_FIXED16X16 (operandType (IC_RIGHT (ic))))
- cnvFromFixed16x16Cast (ic, ebbs[i]);
- else if (IS_FIXED16X16 (operandType (IC_LEFT (ic))))
- cnvToFixed16x16Cast (ic, ebbs[i]);
+ if (IS_FIXED16X16 (operandType (IC_RIGHT (ic))))
+ cnvFromFixed16x16Cast (ic, ebbs[i]);
+ else if (IS_FIXED16X16 (operandType (IC_LEFT (ic))))
+ cnvToFixed16x16Cast (ic, ebbs[i]);
}
// Easy special case which avoids function call: modulo by a literal power
if (ic->op == '%' && isOperandLiteral(IC_RIGHT(ic)) &&
IS_UNSIGNED(operandType(IC_LEFT(ic))))
{
- unsigned litVal = abs((unsigned)operandLitValue(IC_RIGHT(ic)));
+ unsigned litVal = abs((unsigned) double2ul (operandLitValue(IC_RIGHT(ic))));
/* modulo by 1: no remainder */
if (litVal == 1)
symbol * resultsym = OP_SYMBOL (IC_RESULT (ic));
symbol * prereqv = resultsym->prereqv;
- if (prereqv && prereqv->reqv && (OP_SYMBOL (prereqv->reqv) == resultsym))
+ if (prereqv && prereqv->reqv && (OP_SYMBOL (prereqv->reqv) == resultsym))
{
operand * newreqv;
} /* end of all instructions */
if (!ebbs[i]->sch && !ebbs[i]->noPath)
- disconBBlock (ebbs[i], ebbi);
+ disconBBlock (ebbs[i], ebbi);
} /* end of for all blocks */
/* replace the local variables with their
register equivalents : the liveRange computation
- along with the register allocation will determine
+ along with the register allocation will determine
if it finally stays in the registers */
replaceRegEqv (ebbi);
{
change += cseAllBlocks (ebbi, FALSE);
if (options.dump_gcse)
- dumpEbbsToFileExt (DUMP_GCSE, ebbi);
+ dumpEbbsToFileExt (DUMP_GCSE, ebbi);
}
else
{
computeDataFlow (ebbi);
change += cseAllBlocks (ebbi, FALSE);
if (options.dump_loop)
- dumpEbbsToFileExt (DUMP_LOOPG, ebbi);
+ dumpEbbsToFileExt (DUMP_LOOPG, ebbi);
/* if loop optimizations caused a change then do
dead code elimination once more : this will
killDeadCode (ebbi);
if (options.dump_loop)
- dumpEbbsToFileExt (DUMP_LOOPD, ebbi);
+ dumpEbbsToFileExt (DUMP_LOOPD, ebbi);
}
&& !FUNC_ISNAKED(currFunc->type)) {
eBBlock *bp;
// make sure all predecessors of the last block end in a return
- for (bp=setFirstItem(ebbi->bbOrder[ebbi->count-1]->predList);
+ for (bp=setFirstItem(ebbi->bbOrder[ebbi->count-1]->predList);
bp;
- bp=setNextItem(ebbi->bbOrder[ebbi->count-1]->predList)) {
+ bp=setNextItem(ebbi->bbOrder[ebbi->count-1]->predList)) {
if (bp->ech->op != RETURN) {
werrorfl (bp->ech->filename, bp->ech->lineno,
W_VOID_FUNC, currFunc->name);
/* Determine the range of the enumerated values */
sym = enumlist;
- min = max = (int) floatFromVal (valFromType (sym->type));
+ min = max = (int) ulFromVal (valFromType (sym->type));
for (sym = sym->next; sym; sym = sym->next)
{
- v = (int) floatFromVal (valFromType (sym->type));
+ v = (int) ulFromVal (valFromType (sym->type));
if (v<min)
min = v;
if (v>max)
{
/* make signed literal unsigned and
limit no of bits to size of return type */
- litVal = (TYPE_TARGET_ULONG) litVal & opBitsMask;
+ litVal = (TYPE_TARGET_ULONG) double2ul (litVal) & opBitsMask;
}
}
else /* SPEC_USIGN (lit) */
{
value *val = newValue ();
double sval;
+ char *p;
- if (sscanf (s, "%lf", &sval) != 1)
+ sval = strtod(s, &p);
+ if (p == s)
{
werror (E_INVALID_FLOAT_CONST, s);
return constVal ("0");
{
value *val = newValue ();
double sval;
+ char *p;
- if (sscanf (s, "%lf", &sval) != 1)
+ sval = strtod(s, &p);
+ if (p == s)
{
werror (E_INVALID_FLOAT_CONST, s);
return constVal ("0");
if (hex || octal) {
unsigned long sval;
sval = strtoul (s, NULL, 0);
- dval=sval;
+ dval = sval;
if (errno) {
dval = 4294967295.0;
werror (W_INVALID_INT_CONST, s, dval);
}
} else {
- sscanf (s, "%lf", &dval);
+ dval = strtod(s, NULL);
}
/* Setup the flags first */
{
if (SPEC_USIGN (val->type))
{
- SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG)dval;
+ SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) double2ul (dval);
}
else
{
- SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG)dval;
+ SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) double2ul (dval);
}
}
else
{
if (SPEC_USIGN (val->type))
{
- SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT)dval;
+ SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) double2ul (dval);
}
else
{
- SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT)dval;
+ SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) double2ul (dval);
}
}
/*------------------------------------------------------------------*/
/* floatFromVal - value to double float conversion */
/*------------------------------------------------------------------*/
+#if 0
+double
+floatFromVal (value * val)
+{
+ double res;
+
+ if (!val)
+ return 0;
+
+ if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
+ {
+ werror (E_CONST_EXPECTED, val->name);
+ return 0;
+ }
+
+ /* if it is not a specifier then we can assume that */
+ /* it will be an unsigned long */
+ if (!IS_SPEC (val->type)) {
+ //return (double) SPEC_CVAL (val->etype).v_ulong;
+ res =SPEC_CVAL (val->etype).v_ulong;
+ goto ret;
+ }
+
+ if (SPEC_NOUN (val->etype) == V_FLOAT) {
+ //return (double) SPEC_CVAL (val->etype).v_float;
+ res =SPEC_CVAL (val->etype).v_float;
+ goto ret;
+ }
+
+ if (SPEC_NOUN (val->etype) == V_FIXED16X16) {
+ res =doubleFromFixed16x16( SPEC_CVAL (val->etype).v_fixed16x16 );
+ goto ret;
+ }
+
+ if (SPEC_LONG (val->etype))
+ {
+ if (SPEC_USIGN (val->etype)) {
+ //return (double) SPEC_CVAL (val->etype).v_ulong;
+ res =SPEC_CVAL (val->etype).v_ulong;
+ goto ret;
+ }
+ else {
+ //return (double) SPEC_CVAL (val->etype).v_long;
+ res =SPEC_CVAL (val->etype).v_long;
+ goto ret;
+ }
+ }
+
+ if (SPEC_NOUN (val->etype) == V_INT) {
+ if (SPEC_USIGN (val->etype)) {
+ //return (double) SPEC_CVAL (val->etype).v_uint;
+ res =SPEC_CVAL (val->etype).v_uint;
+ goto ret;
+ }
+ else {
+ //return (double) SPEC_CVAL (val->etype).v_int;
+ res =SPEC_CVAL (val->etype).v_int;
+ goto ret;
+ }
+ }
+
+ if (SPEC_NOUN (val->etype) == V_CHAR) {
+ if (SPEC_USIGN (val->etype)) {
+ //return (double) (unsigned char)SPEC_CVAL (val->etype).v_uint;
+ res =(unsigned char)SPEC_CVAL (val->etype).v_uint;
+ goto ret;
+ }
+ else
+ {
+ res = (signed char)SPEC_CVAL (val->etype).v_int;
+ goto ret;
+ }
+ }
+
+ if (IS_BITVAR(val->etype)) {
+ //return (double) SPEC_CVAL (val->etype).v_uint;
+ res =SPEC_CVAL (val->etype).v_uint;
+ goto ret;
+ }
+
+ if (SPEC_NOUN (val->etype) == V_VOID) {
+ //return (double) SPEC_CVAL (val->etype).v_ulong;
+ res = SPEC_CVAL (val->etype).v_ulong;
+ goto ret;
+ }
+
+ // we are lost !
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "floatFromVal: unknown value");
+ return 0;
+
+ret:
+ printf("floatFromVal(%f)\n", res);
+ return res;
+}
+#endif
+
double
floatFromVal (value * val)
{
/* if it is not a specifier then we can assume that */
/* it will be an unsigned long */
if (!IS_SPEC (val->type))
- return (double) SPEC_CVAL (val->etype).v_ulong;
+ return SPEC_CVAL (val->etype).v_ulong;
if (SPEC_NOUN (val->etype) == V_FLOAT)
- return (double) SPEC_CVAL (val->etype).v_float;
+ return SPEC_CVAL (val->etype).v_float;
if (SPEC_NOUN (val->etype) == V_FIXED16X16)
- return (double) doubleFromFixed16x16( SPEC_CVAL (val->etype).v_fixed16x16 );
+ return doubleFromFixed16x16( SPEC_CVAL (val->etype).v_fixed16x16 );
if (SPEC_LONG (val->etype))
{
if (SPEC_USIGN (val->etype))
- return (double) SPEC_CVAL (val->etype).v_ulong;
+ return SPEC_CVAL (val->etype).v_ulong;
else
- return (double) SPEC_CVAL (val->etype).v_long;
+ return SPEC_CVAL (val->etype).v_long;
}
if (SPEC_NOUN (val->etype) == V_INT) {
if (SPEC_USIGN (val->etype))
- return (double) SPEC_CVAL (val->etype).v_uint;
+ return SPEC_CVAL (val->etype).v_uint;
else
- return (double) SPEC_CVAL (val->etype).v_int;
+ return SPEC_CVAL (val->etype).v_int;
}
if (SPEC_NOUN (val->etype) == V_CHAR) {
if (SPEC_USIGN (val->etype))
- return (double) (unsigned char)SPEC_CVAL (val->etype).v_uint;
+ return (unsigned char)SPEC_CVAL (val->etype).v_uint;
else
- return (double) (signed char)SPEC_CVAL (val->etype).v_int;
+ return (signed char)SPEC_CVAL (val->etype).v_int;
+ }
+
+ if (IS_BITVAR(val->etype))
+ return SPEC_CVAL (val->etype).v_uint;
+
+ if (SPEC_NOUN (val->etype) == V_VOID)
+ return SPEC_CVAL (val->etype).v_ulong;
+
+ // we are lost !
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "floatFromVal: unknown value");
+ return 0;
+}
+
+/*------------------------------------------------------------------*/
+/* ulFromVal - value to unsigned long conversion */
+/*------------------------------------------------------------------*/
+unsigned long
+ulFromVal (value * val)
+{
+ if (!val)
+ return 0;
+
+ if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
+ {
+ werror (E_CONST_EXPECTED, val->name);
+ return 0;
+ }
+
+ /* if it is not a specifier then we can assume that */
+ /* it will be an unsigned long */
+ if (!IS_SPEC (val->type))
+ return SPEC_CVAL (val->etype).v_ulong;
+
+ if (SPEC_NOUN (val->etype) == V_FLOAT)
+ return double2ul (SPEC_CVAL (val->etype).v_float);
+
+ if (SPEC_NOUN (val->etype) == V_FIXED16X16)
+ return double2ul (doubleFromFixed16x16( SPEC_CVAL (val->etype).v_fixed16x16 ));
+
+ if (SPEC_LONG (val->etype))
+ {
+ if (SPEC_USIGN (val->etype))
+ return SPEC_CVAL (val->etype).v_ulong;
+ else
+ return SPEC_CVAL (val->etype).v_long;
+ }
+
+ if (SPEC_NOUN (val->etype) == V_INT) {
+ if (SPEC_USIGN (val->etype))
+ return SPEC_CVAL (val->etype).v_uint;
+ else
+ return SPEC_CVAL (val->etype).v_int;
+ }
+
+ if (SPEC_NOUN (val->etype) == V_CHAR) {
+ if (SPEC_USIGN (val->etype))
+ return (unsigned char)SPEC_CVAL (val->etype).v_uint;
+ else
+ return (signed char)SPEC_CVAL (val->etype).v_int;
}
if (IS_BITVAR(val->etype)) {
- return (double) SPEC_CVAL (val->etype).v_uint;
+ return SPEC_CVAL (val->etype).v_uint;
}
if (SPEC_NOUN (val->etype) == V_VOID) {
- return (double) SPEC_CVAL (val->etype).v_ulong;
+ return SPEC_CVAL (val->etype).v_ulong;
}
// we are lost !
- werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "floatFromVal: unknown value");
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "ulFromVal: unknown value");
return 0;
}
return (res);
#else
- return (TYPE_TARGET_ULONG)(value * (double)(1UL << 16));
+ return double2ul (value * (double)(1UL << 16));
#endif
}
/* signed and unsigned mul are the same, as long as the precision of the
result isn't bigger than the precision of the operands. */
else if (SPEC_LONG (val->type))
- SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) *
- (TYPE_TARGET_ULONG) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) *
+ (TYPE_TARGET_ULONG) ulFromVal (rval);
else if (SPEC_USIGN (val->type)) /* unsigned int */
{
- TYPE_TARGET_ULONG ul = (TYPE_TARGET_UINT) floatFromVal (lval) *
- (TYPE_TARGET_UINT) floatFromVal (rval);
+ TYPE_TARGET_ULONG ul = (TYPE_TARGET_UINT) ulFromVal (lval) *
+ (TYPE_TARGET_UINT) ulFromVal (rval);
SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ul;
if (ul != (TYPE_TARGET_UINT) ul)
else if (SPEC_LONG (val->type))
{
if (SPEC_USIGN (val->type))
- SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) /
- (TYPE_TARGET_ULONG) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) /
+ (TYPE_TARGET_ULONG) ulFromVal (rval);
else
- SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) /
- (TYPE_TARGET_LONG) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) /
+ (TYPE_TARGET_LONG) ulFromVal (rval);
}
else
{
if (SPEC_USIGN (val->type))
- SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) /
- (TYPE_TARGET_UINT) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) /
+ (TYPE_TARGET_UINT) ulFromVal (rval);
else
- SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) floatFromVal (lval) /
- (TYPE_TARGET_INT) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) /
+ (TYPE_TARGET_INT) ulFromVal (rval);
}
return cheapestVal (val);
}
if (SPEC_LONG (val->type))
{
if (SPEC_USIGN (val->type))
- SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) %
- (TYPE_TARGET_ULONG) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) %
+ (TYPE_TARGET_ULONG) ulFromVal (rval);
else
- SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) %
- (TYPE_TARGET_LONG) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) %
+ (TYPE_TARGET_LONG) ulFromVal (rval);
}
else
{
if (SPEC_USIGN (val->type))
- SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) %
- (TYPE_TARGET_UINT) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) %
+ (TYPE_TARGET_UINT) ulFromVal (rval);
else
- SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) floatFromVal (lval) %
- (TYPE_TARGET_INT) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) %
+ (TYPE_TARGET_INT) ulFromVal (rval);
}
return cheapestVal (val);
}
else if (SPEC_LONG (val->type))
{
if (SPEC_USIGN (val->type))
- SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) +
- (TYPE_TARGET_ULONG) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) +
+ (TYPE_TARGET_ULONG) ulFromVal (rval);
else
- SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) +
- (TYPE_TARGET_LONG) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) +
+ (TYPE_TARGET_LONG) ulFromVal (rval);
}
else
{
if (SPEC_USIGN (val->type))
- SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) +
- (TYPE_TARGET_UINT) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) +
+ (TYPE_TARGET_UINT) ulFromVal (rval);
else
- SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) floatFromVal (lval) +
- (TYPE_TARGET_INT) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) +
+ (TYPE_TARGET_INT) ulFromVal (rval);
}
return cheapestVal (val);
}
else if (SPEC_LONG (val->type))
{
if (SPEC_USIGN (val->type))
- SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) -
- (TYPE_TARGET_ULONG) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) -
+ (TYPE_TARGET_ULONG) ulFromVal (rval);
else
- SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) -
- (TYPE_TARGET_LONG) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) -
+ (TYPE_TARGET_LONG) ulFromVal (rval);
}
else
{
if (SPEC_USIGN (val->type))
- SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) -
- (TYPE_TARGET_UINT) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) -
+ (TYPE_TARGET_UINT) ulFromVal (rval);
else
- SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) floatFromVal (lval) -
- (TYPE_TARGET_INT) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) -
+ (TYPE_TARGET_INT) ulFromVal (rval);
}
return cheapestVal (val);
}
'S');
SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
- if (getSize (val->type) * 8 <= (TYPE_TARGET_ULONG) floatFromVal (rval) &&
+ if (getSize (val->type) * 8 <= (TYPE_TARGET_ULONG) ulFromVal (rval) &&
/* left shift */
(lr ||
/* right shift and unsigned */
if (SPEC_USIGN (val->type))
{
SPEC_CVAL (val->type).v_ulong = lr ?
- (TYPE_TARGET_ULONG) floatFromVal (lval) << (TYPE_TARGET_ULONG) floatFromVal (rval) : \
- (TYPE_TARGET_ULONG) floatFromVal (lval) >> (TYPE_TARGET_ULONG) floatFromVal (rval);
+ (TYPE_TARGET_ULONG) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) : \
+ (TYPE_TARGET_ULONG) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
}
else
{
SPEC_CVAL (val->type).v_long = lr ?
- (TYPE_TARGET_LONG) floatFromVal (lval) << (TYPE_TARGET_ULONG) floatFromVal (rval) : \
- (TYPE_TARGET_LONG) floatFromVal (lval) >> (TYPE_TARGET_ULONG) floatFromVal (rval);
+ (TYPE_TARGET_LONG) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) : \
+ (TYPE_TARGET_LONG) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
}
}
else
if (SPEC_USIGN (val->type))
{
SPEC_CVAL (val->type).v_uint = lr ?
- (TYPE_TARGET_UINT) floatFromVal (lval) << (TYPE_TARGET_ULONG) floatFromVal (rval) : \
- (TYPE_TARGET_UINT) floatFromVal (lval) >> (TYPE_TARGET_ULONG) floatFromVal (rval);
+ (TYPE_TARGET_UINT) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) : \
+ (TYPE_TARGET_UINT) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
}
else
{
SPEC_CVAL (val->type).v_int = lr ?
- (TYPE_TARGET_INT) floatFromVal (lval) << (TYPE_TARGET_ULONG) floatFromVal (rval) : \
- (TYPE_TARGET_INT) floatFromVal (lval) >> (TYPE_TARGET_ULONG) floatFromVal (rval);
+ (TYPE_TARGET_INT) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) : \
+ (TYPE_TARGET_INT) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
}
}
return cheapestVal (val);
/* integrals: ignore signedness */
TYPE_TARGET_ULONG l, r;
- l = (TYPE_TARGET_ULONG) floatFromVal (lval);
- r = (TYPE_TARGET_ULONG) floatFromVal (rval);
+ l = (TYPE_TARGET_ULONG) ulFromVal (lval);
+ r = (TYPE_TARGET_ULONG) ulFromVal (rval);
/* In order to correctly compare 'signed int' and 'unsigned int' it's
neccessary to strip them to 16 bit.
Literals are reduced to their cheapest type, therefore left and
/* integrals: ignore signedness */
TYPE_TARGET_ULONG l, r;
- l = (TYPE_TARGET_ULONG) floatFromVal (lval);
- r = (TYPE_TARGET_ULONG) floatFromVal (rval);
+ l = (TYPE_TARGET_ULONG) ulFromVal (lval);
+ r = (TYPE_TARGET_ULONG) ulFromVal (rval);
/* In order to correctly compare 'signed int' and 'unsigned int' it's
neccessary to strip them to 16 bit.
Literals are reduced to their cheapest type, therefore left and
if (SPEC_LONG (val->type))
{
if (SPEC_USIGN (val->type))
- SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) &
- (TYPE_TARGET_ULONG) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) &
+ (TYPE_TARGET_ULONG) ulFromVal (rval);
else
- SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) &
- (TYPE_TARGET_LONG) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) &
+ (TYPE_TARGET_LONG) ulFromVal (rval);
}
else
{
if (SPEC_USIGN (val->type))
- SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) &
- (TYPE_TARGET_UINT) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) &
+ (TYPE_TARGET_UINT) ulFromVal (rval);
else
- SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) floatFromVal (lval) &
- (TYPE_TARGET_INT) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) &
+ (TYPE_TARGET_INT) ulFromVal (rval);
}
break;
if (SPEC_LONG (val->type))
{
if (SPEC_USIGN (val->type))
- SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) |
- (TYPE_TARGET_ULONG) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) |
+ (TYPE_TARGET_ULONG) ulFromVal (rval);
else
- SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) |
- (TYPE_TARGET_LONG) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) |
+ (TYPE_TARGET_LONG) ulFromVal (rval);
}
else
{
if (SPEC_USIGN (val->type))
- SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) |
- (TYPE_TARGET_UINT) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) |
+ (TYPE_TARGET_UINT) ulFromVal (rval);
else
SPEC_CVAL (val->type).v_int =
- (TYPE_TARGET_INT) floatFromVal (lval) | (TYPE_TARGET_INT) floatFromVal (rval);
+ (TYPE_TARGET_INT) ulFromVal (lval) | (TYPE_TARGET_INT) ulFromVal (rval);
}
break;
if (SPEC_LONG (val->type))
{
if (SPEC_USIGN (val->type))
- SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) ^
- (TYPE_TARGET_ULONG) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) ^
+ (TYPE_TARGET_ULONG) ulFromVal (rval);
else
- SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) ^
- (TYPE_TARGET_LONG) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) ^
+ (TYPE_TARGET_LONG) ulFromVal (rval);
}
else
{
if (SPEC_USIGN (val->type))
- SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) ^
- (TYPE_TARGET_UINT) floatFromVal (rval);
+ SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) ^
+ (TYPE_TARGET_UINT) ulFromVal (rval);
else
SPEC_CVAL (val->type).v_int =
- (TYPE_TARGET_INT) floatFromVal (lval) ^ (TYPE_TARGET_INT) floatFromVal (rval);
+ (TYPE_TARGET_INT) ulFromVal (lval) ^ (TYPE_TARGET_INT) ulFromVal (rval);
}
break;
}
/*------------------------------------------------------------------*/
/* valCastLiteral - casts a literal value to another type */
/*------------------------------------------------------------------*/
+#if 0
value *
valCastLiteral (sym_link * dtype, double fval)
{
value *val;
- TYPE_TARGET_ULONG l = (TYPE_TARGET_ULONG)fval;
+ unsigned long l = double2ul (fval);
if (!dtype)
return NULL;
(0xffffu >> (16 - SPEC_BLEN (val->etype)));
else if (SPEC_NOUN (val->etype) == V_CHAR) {
if (SPEC_USIGN (val->etype))
- SPEC_CVAL (val->etype).v_uint= (TYPE_UBYTE) l;
+ SPEC_CVAL (val->etype).v_uint= (TYPE_TARGET_UCHAR) l;
else
- SPEC_CVAL (val->etype).v_int = (TYPE_BYTE) l;
+ SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_CHAR) l;
} else {
if (SPEC_LONG (val->etype)) {
if (SPEC_USIGN (val->etype))
SPEC_CVAL (val->etype).v_long = (TYPE_TARGET_LONG) l;
} else {
if (SPEC_USIGN (val->etype))
- SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UINT)l;
+ SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UINT) l;
else
- SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_INT)l;
+ SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_INT) l;
}
}
return val;
}
+#endif
+
+value *
+valCastLiteral (sym_link * dtype, double fval)
+{
+ value *val;
+ unsigned long l = double2ul (fval);
+
+ if (!dtype)
+ return NULL;
+
+ val = newValue ();
+ if (dtype)
+ val->etype = getSpec (val->type = copyLinkChain (dtype));
+ else
+ {
+ val->etype = val->type = newLink (SPECIFIER);
+ SPEC_NOUN (val->etype) = V_VOID;
+ }
+ SPEC_SCLS (val->etype) = S_LITERAL;
+
+ /* if it is not a specifier then we can assume that */
+ /* it will be an unsigned long */
+ if (!IS_SPEC (val->type))
+ {
+ SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) l;
+ return val;
+ }
+
+ switch (SPEC_NOUN (val->etype))
+ {
+ case V_FLOAT:
+ SPEC_CVAL (val->etype).v_float = fval;
+ break;
+
+ case V_FIXED16X16:
+ SPEC_CVAL (val->etype).v_fixed16x16 = fixed16x16FromDouble (fval);
+ break;
+
+ case V_BIT:
+ case V_SBIT:
+ SPEC_CVAL (val->etype).v_uint = fval ? 1 : 0;
+ break;
+
+ case V_BITFIELD:
+ SPEC_CVAL (val->etype).v_uint = ((TYPE_TARGET_UINT) l) &
+ (0xffffu >> (16 - SPEC_BLEN (val->etype)));
+ break;
+
+ case V_CHAR:
+ if (SPEC_USIGN (val->etype))
+ SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UCHAR) l;
+ else
+ SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_CHAR) l;
+ break;
+
+ default:
+ if (SPEC_LONG (val->etype))
+ {
+ if (SPEC_USIGN (val->etype))
+ SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) l;
+ else
+ SPEC_CVAL (val->etype).v_long = (TYPE_TARGET_LONG) l;
+ }
+ else
+ {
+ if (SPEC_USIGN (val->etype))
+ SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UINT) l;
+ else
+ SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_INT) l;
+ }
+ }
+
+ return val;
+}
/*------------------------------------------------------------------*/
/* getNelements - determines # of elements from init list */
#include "SDCCsymt.h"
+
+/* double to unsigned long conversion */
+#define double2ul(val) (((val) < 0) ? (unsigned long) -((long) -(val)) : (unsigned long) (val))
+
/* value wrapper */
typedef struct value
{
- char name[SDCC_NAME_MAX + 1]; /* operand accessing this value */
- sym_link *type; /* start of type chain */
- sym_link *etype; /* end of type chain */
- symbol *sym; /* Original Symbol */
- struct value *next; /* used in initializer list */
- unsigned vArgs:1; /* arg list ended with variable arg */
+ char name[SDCC_NAME_MAX + 1]; /* operand accessing this value */
+ sym_link *type; /* start of type chain */
+ sym_link *etype; /* end of type chain */
+ symbol *sym; /* Original Symbol */
+ struct value *next; /* used in initializer list */
+ unsigned vArgs:1; /* arg list ended with variable arg */
}
value;
char *filename;
union
{
- struct ast *node;
- struct initList *deep;
+ struct ast *node;
+ struct initList *deep;
}
init;
}
CCR_RESULT;
-#define IS_VARG(x) (x->vArgs)
+#define IS_VARG(x) (x->vArgs)
/* forward definitions for the symbol table related functions */
void initValue ();
value *symbolVal (symbol *);
void printVal (value *);
double floatFromVal (value *);
+unsigned long ulFromVal (value *);
/* convert a fixed16x16 type to double */
double doubleFromFixed16x16(TYPE_TARGET_ULONG value);
static char *spname;
char *fReturnAVR[] = { "r16", "r17", "r18", "r19" };
-unsigned fAVRReturnSize = 4; /* shared with ralloc.c */
+unsigned fAVRReturnSize = 4; /* shared with ralloc.c */
char **fAVRReturn = fReturnAVR;
static char *larray[4] = { ">", "<", "hlo8", "hhi8" };
static struct {
- short xPushed;
- short zPushed;
- short accInUse;
- short inLine;
- short debugLine;
- short nRegsSaved;
- set *sendSet;
+ short xPushed;
+ short zPushed;
+ short accInUse;
+ short inLine;
+ short debugLine;
+ short nRegsSaved;
+ set *sendSet;
} _G;
extern int avr_ptrRegReq;
static void
reAdjustPreg (asmop * aop)
{
- int size;
-
- aop->coff = 0;
- if ((size = aop->size) <= 1)
- return;
- size--;
- switch (aop->type) {
- case AOP_X:
- case AOP_Z:
- emitcode ("sbiw", "%s,%d", aop->aopu.aop_ptr->name, size);
- break;
- }
+ int size;
+
+ aop->coff = 0;
+ if ((size = aop->size) <= 1)
+ return;
+ size--;
+ switch (aop->type) {
+ case AOP_X:
+ case AOP_Z:
+ emitcode ("sbiw", "%s,%d", aop->aopu.aop_ptr->name, size);
+ break;
+ }
}
static void
outBitC (operand * result)
{
- emitcode ("clr", "r0");
- emitcode ("rol", "r0");
- outAcc (result);
+ emitcode ("clr", "r0");
+ emitcode ("rol", "r0");
+ outAcc (result);
}
/*-----------------------------------------------------------------*/
static bool
inExcludeList (char *s)
{
- int i = 0;
-
- if (options.excludeRegs[i] &&
- STRCASECMP (options.excludeRegs[i], "none") == 0)
- return FALSE;
-
- for (i = 0; options.excludeRegs[i]; i++) {
- if (options.excludeRegs[i] &&
- STRCASECMP (s, options.excludeRegs[i]) == 0)
- return TRUE;
- }
- return FALSE;
+ int i = 0;
+
+ if (options.excludeRegs[i] &&
+ STRCASECMP (options.excludeRegs[i], "none") == 0)
+ return FALSE;
+
+ for (i = 0; options.excludeRegs[i]; i++) {
+ if (options.excludeRegs[i] &&
+ STRCASECMP (s, options.excludeRegs[i]) == 0)
+ return TRUE;
+ }
+ return FALSE;
}
/*-----------------------------------------------------------------*/
static int
findLabelBackwards (iCode * ic, int key)
{
- int count = 0;
+ int count = 0;
- while (ic->prev) {
- ic = ic->prev;
- count++;
+ while (ic->prev) {
+ ic = ic->prev;
+ count++;
- if (ic->op == LABEL && IC_LABEL (ic)->key == key) {
- /* printf("findLabelBackwards = %d\n", count); */
- return count;
- }
- }
+ if (ic->op == LABEL && IC_LABEL (ic)->key == key) {
+ /* printf("findLabelBackwards = %d\n", count); */
+ return count;
+ }
+ }
- return 0;
+ return 0;
}
/*-----------------------------------------------------------------*/
static void
addSign (operand * result, int offset, int sign)
{
- int size = (getDataSize (result) - offset);
- if (size > 0) {
- if (sign) {
- emitcode ("rlc", "a");
- emitcode ("subb", "a,acc");
- while (size--)
- aopPut (AOP (result), "a", offset++);
- }
- else
- while (size--)
- aopPut (AOP (result), zero, offset++);
- }
+ int size = (getDataSize (result) - offset);
+ if (size > 0) {
+ if (sign) {
+ emitcode ("rlc", "a");
+ emitcode ("subb", "a,acc");
+ while (size--)
+ aopPut (AOP (result), "a", offset++);
+ }
+ else
+ while (size--)
+ aopPut (AOP (result), zero, offset++);
+ }
}
/*-----------------------------------------------------------------*/
static int
isLiteralBit (unsigned long lit)
{
- unsigned long pw[32] = { 1L, 2L, 4L, 8L, 16L, 32L, 64L, 128L,
- 0x100L, 0x200L, 0x400L, 0x800L,
- 0x1000L, 0x2000L, 0x4000L, 0x8000L,
- 0x10000L, 0x20000L, 0x40000L, 0x80000L,
- 0x100000L, 0x200000L, 0x400000L, 0x800000L,
- 0x1000000L, 0x2000000L, 0x4000000L, 0x8000000L,
- 0x10000000L, 0x20000000L, 0x40000000L, 0x80000000L
- };
- int idx;
-
- for (idx = 0; idx < 32; idx++)
- if (lit == pw[idx])
- return idx + 1;
- return 0;
+ unsigned long pw[32] = { 1L, 2L, 4L, 8L, 16L, 32L, 64L, 128L,
+ 0x100L, 0x200L, 0x400L, 0x800L,
+ 0x1000L, 0x2000L, 0x4000L, 0x8000L,
+ 0x10000L, 0x20000L, 0x40000L, 0x80000L,
+ 0x100000L, 0x200000L, 0x400000L, 0x800000L,
+ 0x1000000L, 0x2000000L, 0x4000000L, 0x8000000L,
+ 0x10000000L, 0x20000000L, 0x40000000L, 0x80000000L
+ };
+ int idx;
+
+ for (idx = 0; idx < 32; idx++)
+ if (lit == pw[idx])
+ return idx + 1;
+ return 0;
}
/*-----------------------------------------------------------------*/
static void
outAcc (operand * result)
{
- int size, offset;
- size = getDataSize (result);
- if (size) {
- aopPut (AOP (result), "r0", 0);
- size--;
- offset = 1;
- /* unsigned or positive */
- while (size--) {
- aopPut (AOP (result), zero, offset++);
- }
- }
+ int size, offset;
+ size = getDataSize (result);
+ if (size) {
+ aopPut (AOP (result), "r0", 0);
+ size--;
+ offset = 1;
+ /* unsigned or positive */
+ while (size--) {
+ aopPut (AOP (result), zero, offset++);
+ }
+ }
}
-#endif // End Unused code section
+#endif // End Unused code section
/*-----------------------------------------------------------------*/
/* emitcode - writes the code into a file : for now it is simple */
static void
emitcode (char *inst, char *fmt, ...)
{
- va_list ap;
- char lb[INITIAL_INLINEASM];
- char *lbp = lb;
-
- va_start (ap, fmt);
-
- if (inst && *inst) {
- if (fmt && *fmt)
- sprintf (lb, "%s\t", inst);
- else
- sprintf (lb, "%s", inst);
- vsprintf (lb + (strlen (lb)), fmt, ap);
- }
- else
- vsprintf (lb, fmt, ap);
-
- while (isspace ((unsigned char)*lbp))
- lbp++;
-
- if (lbp && *lbp)
- lineCurr = (lineCurr ?
- connectLine (lineCurr, newLineNode (lb)) :
- (lineHead = newLineNode (lb)));
- lineCurr->isInline = _G.inLine;
- lineCurr->isDebug = _G.debugLine;
- va_end (ap);
+ va_list ap;
+ char lb[INITIAL_INLINEASM];
+ char *lbp = lb;
+
+ va_start (ap, fmt);
+
+ if (inst && *inst) {
+ if (fmt && *fmt)
+ sprintf (lb, "%s\t", inst);
+ else
+ sprintf (lb, "%s", inst);
+ vsprintf (lb + (strlen (lb)), fmt, ap);
+ }
+ else
+ vsprintf (lb, fmt, ap);
+
+ while (isspace ((unsigned char)*lbp))
+ lbp++;
+
+ if (lbp && *lbp)
+ lineCurr = (lineCurr ?
+ connectLine (lineCurr, newLineNode (lb)) :
+ (lineHead = newLineNode (lb)));
+ lineCurr->isInline = _G.inLine;
+ lineCurr->isDebug = _G.debugLine;
+ va_end (ap);
}
/*-----------------------------------------------------------------*/
static iCode *
hasInc (operand *op, iCode *ic)
{
- sym_link *type = operandType(op);
- sym_link *retype = getSpec (type);
- iCode *lic = ic->next;
- int isize ;
-
- if (IS_BITVAR(retype)||!IS_PTR(type)) return NULL;
- if (IS_AGGREGATE(type->next)) return NULL;
- isize = getSize(type->next);
- while (lic) {
- /* if operand of the form op = op + <sizeof *op> */
- if (lic->op == '+' && isOperandEqual(IC_LEFT(lic),op) &&
- isOperandEqual(IC_RESULT(lic),op) &&
- isOperandLiteral(IC_RIGHT(lic)) &&
- operandLitValue(IC_RIGHT(lic)) == isize) {
- return lic;
- }
- /* if the operand used or deffed */
- if (bitVectBitValue(OP_USES(op),lic->key) || (lic->defKey == op->key)) {
- return NULL;
- }
- lic = lic->next;
- }
- return NULL;
+ sym_link *type = operandType(op);
+ sym_link *retype = getSpec (type);
+ iCode *lic = ic->next;
+ int isize ;
+
+ if (IS_BITVAR(retype)||!IS_PTR(type)) return NULL;
+ if (IS_AGGREGATE(type->next)) return NULL;
+ isize = getSize(type->next);
+ while (lic) {
+ /* if operand of the form op = op + <sizeof *op> */
+ if (lic->op == '+' && isOperandEqual(IC_LEFT(lic),op) &&
+ isOperandEqual(IC_RESULT(lic),op) &&
+ isOperandLiteral(IC_RIGHT(lic)) &&
+ operandLitValue(IC_RIGHT(lic)) == isize) {
+ return lic;
+ }
+ /* if the operand used or deffed */
+ if (bitVectBitValue(OP_USES(op),lic->key) || (lic->defKey == op->key)) {
+ return NULL;
+ }
+ lic = lic->next;
+ }
+ return NULL;
}
/*-----------------------------------------------------------------*/
static regs *
getFreePtr (iCode * ic, asmop ** aopp, bool result, bool zonly)
{
- bool xiu = FALSE, ziu = FALSE;
- bool xou = FALSE, zou = FALSE;
-
- /* the logic: if x & z used in the instruction
- then we are in trouble otherwise */
-
- /* first check if x & z are used by this
- instruction, in which case we are in trouble */
- if ((xiu = bitVectBitValue (ic->rUsed, X_IDX)) &&
- (ziu = bitVectBitValue (ic->rUsed, Z_IDX))) {
- goto endOfWorld;
- }
-
- xou = bitVectBitValue (ic->rMask, X_IDX);
- zou = bitVectBitValue (ic->rMask, Z_IDX);
-
- /* if no usage of Z then return it */
- if (!ziu && !zou) {
- ic->rUsed = bitVectSetBit (ic->rUsed, Z_IDX);
- (*aopp)->type = AOP_Z;
-
- (*aopp)->aop_ptr2 = avr_regWithIdx (R31_IDX);
- return (*aopp)->aopu.aop_ptr = avr_regWithIdx (R30_IDX);
- }
-
- /* if no usage of X then return it */
- if (!xiu && !xou && !zonly) {
- ic->rUsed = bitVectSetBit (ic->rUsed, X_IDX);
- (*aopp)->type = AOP_X;
-
- (*aopp)->aop_ptr2 = avr_regWithIdx (R27_IDX);
- return (*aopp)->aopu.aop_ptr = avr_regWithIdx (R26_IDX);
- }
-
- /* if z not used then */
-
- if (!ziu) {
- /* push it if not already pushed */
- if (!_G.zPushed) {
- emitcode ("push", "%s",
- avr_regWithIdx (R30_IDX)->dname);
- emitcode ("push", "%s",
- avr_regWithIdx (R31_IDX)->dname);
- _G.zPushed++;
- }
-
- ic->rUsed = bitVectSetBit (ic->rUsed, Z_IDX);
- (*aopp)->type = AOP_Z;
- (*aopp)->aop_ptr2 = avr_regWithIdx (R31_IDX);
- return (*aopp)->aopu.aop_ptr = avr_regWithIdx (R30_IDX);
- }
-
- /* now we know they both have usage */
- /* if x not used in this instruction */
- if (!xiu && !zonly) {
- /* push it if not already pushed */
- if (!_G.xPushed) {
- emitcode ("push", "%s",
- avr_regWithIdx (R26_IDX)->dname);
- emitcode ("push", "%s",
- avr_regWithIdx (R27_IDX)->dname);
- _G.xPushed++;
- }
-
- ic->rUsed = bitVectSetBit (ic->rUsed, X_IDX);
- (*aopp)->type = AOP_X;
-
- (*aopp)->aop_ptr2 = avr_regWithIdx (R27_IDX);
- return (*aopp)->aopu.aop_ptr = avr_regWithIdx (R26_IDX);
- }
+ bool xiu = FALSE, ziu = FALSE;
+ bool xou = FALSE, zou = FALSE;
+
+ /* the logic: if x & z used in the instruction
+ then we are in trouble otherwise */
+
+ /* first check if x & z are used by this
+ instruction, in which case we are in trouble */
+ if ((xiu = bitVectBitValue (ic->rUsed, X_IDX)) &&
+ (ziu = bitVectBitValue (ic->rUsed, Z_IDX))) {
+ goto endOfWorld;
+ }
+
+ xou = bitVectBitValue (ic->rMask, X_IDX);
+ zou = bitVectBitValue (ic->rMask, Z_IDX);
+
+ /* if no usage of Z then return it */
+ if (!ziu && !zou) {
+ ic->rUsed = bitVectSetBit (ic->rUsed, Z_IDX);
+ (*aopp)->type = AOP_Z;
+
+ (*aopp)->aop_ptr2 = avr_regWithIdx (R31_IDX);
+ return (*aopp)->aopu.aop_ptr = avr_regWithIdx (R30_IDX);
+ }
+
+ /* if no usage of X then return it */
+ if (!xiu && !xou && !zonly) {
+ ic->rUsed = bitVectSetBit (ic->rUsed, X_IDX);
+ (*aopp)->type = AOP_X;
+
+ (*aopp)->aop_ptr2 = avr_regWithIdx (R27_IDX);
+ return (*aopp)->aopu.aop_ptr = avr_regWithIdx (R26_IDX);
+ }
+
+ /* if z not used then */
+
+ if (!ziu) {
+ /* push it if not already pushed */
+ if (!_G.zPushed) {
+ emitcode ("push", "%s",
+ avr_regWithIdx (R30_IDX)->dname);
+ emitcode ("push", "%s",
+ avr_regWithIdx (R31_IDX)->dname);
+ _G.zPushed++;
+ }
+
+ ic->rUsed = bitVectSetBit (ic->rUsed, Z_IDX);
+ (*aopp)->type = AOP_Z;
+ (*aopp)->aop_ptr2 = avr_regWithIdx (R31_IDX);
+ return (*aopp)->aopu.aop_ptr = avr_regWithIdx (R30_IDX);
+ }
+
+ /* now we know they both have usage */
+ /* if x not used in this instruction */
+ if (!xiu && !zonly) {
+ /* push it if not already pushed */
+ if (!_G.xPushed) {
+ emitcode ("push", "%s",
+ avr_regWithIdx (R26_IDX)->dname);
+ emitcode ("push", "%s",
+ avr_regWithIdx (R27_IDX)->dname);
+ _G.xPushed++;
+ }
+
+ ic->rUsed = bitVectSetBit (ic->rUsed, X_IDX);
+ (*aopp)->type = AOP_X;
+
+ (*aopp)->aop_ptr2 = avr_regWithIdx (R27_IDX);
+ return (*aopp)->aopu.aop_ptr = avr_regWithIdx (R26_IDX);
+ }
endOfWorld:
- /* I said end of world but not quite end of world yet */
- /* if this is a result then we can push it on the stack */
- if (result) {
- (*aopp)->type = AOP_STK;
- return NULL;
- }
-
- /* other wise this is true end of the world */
- werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "getFreePtr should never reach here");
- exit (0);
+ /* I said end of world but not quite end of world yet */
+ /* if this is a result then we can push it on the stack */
+ if (result) {
+ (*aopp)->type = AOP_STK;
+ return NULL;
+ }
+
+ /* other wise this is true end of the world */
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "getFreePtr should never reach here");
+ exit (0);
}
/*-----------------------------------------------------------------*/
static asmop *
newAsmop (short type)
{
- asmop *aop;
+ asmop *aop;
- aop = Safe_calloc (1, sizeof (asmop));
- aop->type = type;
- return aop;
+ aop = Safe_calloc (1, sizeof (asmop));
+ aop->type = type;
+ return aop;
}
/*-----------------------------------------------------------------*/
pointerCode (sym_link * etype)
{
- return PTR_TYPE (SPEC_OCLS (etype));
+ return PTR_TYPE (SPEC_OCLS (etype));
}
static asmop *
aopForSym (iCode * ic, symbol * sym, bool result)
{
- asmop *aop;
- memmap *space = SPEC_OCLS (sym->etype);
-
- /* if already has one */
- if (sym->aop)
- return sym->aop;
-
- /* assign depending on the storage class */
- /* if it is on the stack */
- if (sym->onStack) {
- sym->aop = aop = newAsmop (0);
- aop->size = getSize (sym->type);
-
- /* we can use std / ldd instruction */
- if (sym->stack > 0
- && (sym->stack + getSize (sym->type) - 1) <= 63) {
- aop->type = AOP_STK_D;
- aop->aopu.aop_stk = sym->stack;
- return aop;
- }
-
- /* otherwise get a free pointer register X/Z */
- aop->aopu.aop_ptr = getFreePtr (ic, &aop, result, FALSE);
-
- /* now assign the address of the variable to
- the pointer register */
- if (aop->type != AOP_STK) {
- emitcode ("movw", "%s,r28", aop->aopu.aop_ptr->name);
- if (sym->stack < 0) {
- if ((sym->stack - _G.nRegsSaved) > -63) {
- emitcode ("sbiw", "%s,0x%02x",
- aop->aopu.aop_ptr->name,
- (sym->stack -
- _G.nRegsSaved));
- }
- else {
- emitcode ("subi", "%s,<(%d)",
- aop->aopu.aop_ptr->name,
- sym->stack - _G.nRegsSaved);
- emitcode ("sbci", "%s,>(%d)",
- aop->aop_ptr2->name,
- sym->stack - _G.nRegsSaved);
- }
- }
- else {
- if (sym->stack <= 63) {
- emitcode ("adiw", "%s,0x%02x",
- aop->aopu.aop_ptr->name,
- sym->stack);
- }
- else {
- emitcode ("subi", "%s,<(-%d)",
- aop->aopu.aop_ptr->name,
- sym->stack);
- emitcode ("sbci", "%s,>(-%d)",
- aop->aop_ptr2->name,
- sym->stack);
- }
- }
- }
- return aop;
- }
-
- /* if in bit space */
- if (IN_BITSPACE (space)) {
- sym->aop = aop = newAsmop (AOP_CRY);
- aop->aopu.aop_dir = sym->rname;
- aop->size = getSize (sym->type);
- return aop;
- }
- /* if it is in direct space */
- if (IN_DIRSPACE (space)) {
- sym->aop = aop = newAsmop (AOP_DIR);
- aop->aopu.aop_dir = sym->rname;
- aop->size = getSize (sym->type);
- return aop;
- }
-
- /* special case for a function */
- if (IS_FUNC (sym->type)) {
- sym->aop = aop = newAsmop (AOP_IMMD);
- aop->aopu.aop_immd = Safe_calloc (1, strlen (sym->rname) + 1);
- strcpy (aop->aopu.aop_immd, sym->rname);
- aop->size = FPTRSIZE;
- return aop;
- }
-
- /* only remaining is code / eeprom which will need pointer reg */
- /* if it is in code space */
-
- sym->aop = aop = newAsmop (0);
-
- if (IN_CODESPACE (space))
- aop->code = 1;
-
- aop->aopu.aop_ptr = getFreePtr (ic, &aop, result, aop->code);
- aop->size = getSize (sym->type);
- emitcode ("ldi", "%s,<(%s)", aop->aopu.aop_ptr->name, sym->rname);
- emitcode ("ldi", "%s,>(%s)", aop->aop_ptr2);
-
- return aop;
+ asmop *aop;
+ memmap *space = SPEC_OCLS (sym->etype);
+
+ /* if already has one */
+ if (sym->aop)
+ return sym->aop;
+
+ /* assign depending on the storage class */
+ /* if it is on the stack */
+ if (sym->onStack) {
+ sym->aop = aop = newAsmop (0);
+ aop->size = getSize (sym->type);
+
+ /* we can use std / ldd instruction */
+ if (sym->stack > 0
+ && (sym->stack + getSize (sym->type) - 1) <= 63) {
+ aop->type = AOP_STK_D;
+ aop->aopu.aop_stk = sym->stack;
+ return aop;
+ }
+
+ /* otherwise get a free pointer register X/Z */
+ aop->aopu.aop_ptr = getFreePtr (ic, &aop, result, FALSE);
+
+ /* now assign the address of the variable to
+ the pointer register */
+ if (aop->type != AOP_STK) {
+ emitcode ("movw", "%s,r28", aop->aopu.aop_ptr->name);
+ if (sym->stack < 0) {
+ if ((sym->stack - _G.nRegsSaved) > -63) {
+ emitcode ("sbiw", "%s,0x%02x",
+ aop->aopu.aop_ptr->name,
+ (sym->stack -
+ _G.nRegsSaved));
+ }
+ else {
+ emitcode ("subi", "%s,<(%d)",
+ aop->aopu.aop_ptr->name,
+ sym->stack - _G.nRegsSaved);
+ emitcode ("sbci", "%s,>(%d)",
+ aop->aop_ptr2->name,
+ sym->stack - _G.nRegsSaved);
+ }
+ }
+ else {
+ if (sym->stack <= 63) {
+ emitcode ("adiw", "%s,0x%02x",
+ aop->aopu.aop_ptr->name,
+ sym->stack);
+ }
+ else {
+ emitcode ("subi", "%s,<(-%d)",
+ aop->aopu.aop_ptr->name,
+ sym->stack);
+ emitcode ("sbci", "%s,>(-%d)",
+ aop->aop_ptr2->name,
+ sym->stack);
+ }
+ }
+ }
+ return aop;
+ }
+
+ /* if in bit space */
+ if (IN_BITSPACE (space)) {
+ sym->aop = aop = newAsmop (AOP_CRY);
+ aop->aopu.aop_dir = sym->rname;
+ aop->size = getSize (sym->type);
+ return aop;
+ }
+ /* if it is in direct space */
+ if (IN_DIRSPACE (space)) {
+ sym->aop = aop = newAsmop (AOP_DIR);
+ aop->aopu.aop_dir = sym->rname;
+ aop->size = getSize (sym->type);
+ return aop;
+ }
+
+ /* special case for a function */
+ if (IS_FUNC (sym->type)) {
+ sym->aop = aop = newAsmop (AOP_IMMD);
+ aop->aopu.aop_immd = Safe_calloc (1, strlen (sym->rname) + 1);
+ strcpy (aop->aopu.aop_immd, sym->rname);
+ aop->size = FPTRSIZE;
+ return aop;
+ }
+
+ /* only remaining is code / eeprom which will need pointer reg */
+ /* if it is in code space */
+
+ sym->aop = aop = newAsmop (0);
+
+ if (IN_CODESPACE (space))
+ aop->code = 1;
+
+ aop->aopu.aop_ptr = getFreePtr (ic, &aop, result, aop->code);
+ aop->size = getSize (sym->type);
+ emitcode ("ldi", "%s,<(%s)", aop->aopu.aop_ptr->name, sym->rname);
+ emitcode ("ldi", "%s,>(%s)", aop->aop_ptr2);
+
+ return aop;
}
/*-----------------------------------------------------------------*/
static asmop *
aopForRemat (symbol * sym)
{
- iCode *ic = sym->rematiCode;
- asmop *aop = newAsmop (AOP_IMMD);
- int val = 0;
-
- for (;;) {
- if (ic->op == '+')
- val += (int) operandLitValue (IC_RIGHT (ic));
- else if (ic->op == '-')
- val -= (int) operandLitValue (IC_RIGHT (ic));
- else
- break;
-
- ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
- }
-
- if (val)
- sprintf (buffer, "(%s %c 0x%04x)",
- OP_SYMBOL (IC_LEFT (ic))->rname,
- val >= 0 ? '+' : '-', abs (val) & 0xffff);
- else
- strcpy (buffer, OP_SYMBOL (IC_LEFT (ic))->rname);
-
- aop->aopu.aop_immd = Safe_calloc (1, strlen (buffer) + 1);
- strcpy (aop->aopu.aop_immd, buffer);
- return aop;
+ iCode *ic = sym->rematiCode;
+ asmop *aop = newAsmop (AOP_IMMD);
+ int val = 0;
+
+ for (;;) {
+ if (ic->op == '+')
+ val += (int) operandLitValue (IC_RIGHT (ic));
+ else if (ic->op == '-')
+ val -= (int) operandLitValue (IC_RIGHT (ic));
+ else
+ break;
+
+ ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
+ }
+
+ if (val)
+ sprintf (buffer, "(%s %c 0x%04x)",
+ OP_SYMBOL (IC_LEFT (ic))->rname,
+ val >= 0 ? '+' : '-', abs (val) & 0xffff);
+ else
+ strcpy (buffer, OP_SYMBOL (IC_LEFT (ic))->rname);
+
+ aop->aopu.aop_immd = Safe_calloc (1, strlen (buffer) + 1);
+ strcpy (aop->aopu.aop_immd, buffer);
+ return aop;
}
/*-----------------------------------------------------------------*/
static bool
regsInCommon (operand * op1, operand * op2)
{
- symbol *sym1, *sym2;
- int i;
+ symbol *sym1, *sym2;
+ int i;
- /* if they have registers in common */
- if (!IS_SYMOP (op1) || !IS_SYMOP (op2))
- return FALSE;
+ /* if they have registers in common */
+ if (!IS_SYMOP (op1) || !IS_SYMOP (op2))
+ return FALSE;
- sym1 = OP_SYMBOL (op1);
- sym2 = OP_SYMBOL (op2);
+ sym1 = OP_SYMBOL (op1);
+ sym2 = OP_SYMBOL (op2);
- if (sym1->nRegs == 0 || sym2->nRegs == 0)
- return FALSE;
+ if (sym1->nRegs == 0 || sym2->nRegs == 0)
+ return FALSE;
- for (i = 0; i < sym1->nRegs; i++) {
- int j;
- if (!sym1->regs[i])
- continue;
+ for (i = 0; i < sym1->nRegs; i++) {
+ int j;
+ if (!sym1->regs[i])
+ continue;
- for (j = 0; j < sym2->nRegs; j++) {
- if (!sym2->regs[j])
- continue;
+ for (j = 0; j < sym2->nRegs; j++) {
+ if (!sym2->regs[j])
+ continue;
- if (sym2->regs[j] == sym1->regs[i])
- return TRUE;
- }
- }
+ if (sym2->regs[j] == sym1->regs[i])
+ return TRUE;
+ }
+ }
- return FALSE;
+ return FALSE;
}
/*-----------------------------------------------------------------*/
static bool
operandsEqu (operand * op1, operand * op2)
{
- symbol *sym1, *sym2;
+ symbol *sym1, *sym2;
- /* if they not symbols */
- if (!IS_SYMOP (op1) || !IS_SYMOP (op2))
- return FALSE;
+ /* if they not symbols */
+ if (!IS_SYMOP (op1) || !IS_SYMOP (op2))
+ return FALSE;
- sym1 = OP_SYMBOL (op1);
- sym2 = OP_SYMBOL (op2);
+ sym1 = OP_SYMBOL (op1);
+ sym2 = OP_SYMBOL (op2);
- /* if both are itemps & one is spilt
- and the other is not then false */
- if (IS_ITEMP (op1) && IS_ITEMP (op2) &&
- sym1->isspilt != sym2->isspilt) return FALSE;
+ /* if both are itemps & one is spilt
+ and the other is not then false */
+ if (IS_ITEMP (op1) && IS_ITEMP (op2) &&
+ sym1->isspilt != sym2->isspilt) return FALSE;
- /* if they are the same */
- if (sym1 == sym2)
- return TRUE;
+ /* if they are the same */
+ if (sym1 == sym2)
+ return TRUE;
- if (strcmp (sym1->rname, sym2->rname) == 0)
- return TRUE;
+ if (strcmp (sym1->rname, sym2->rname) == 0)
+ return TRUE;
- /* if left is a tmp & right is not */
- if (IS_ITEMP (op1) &&
- !IS_ITEMP (op2) && sym1->isspilt && (sym1->usl.spillLoc == sym2))
- return TRUE;
+ /* if left is a tmp & right is not */
+ if (IS_ITEMP (op1) &&
+ !IS_ITEMP (op2) && sym1->isspilt && (sym1->usl.spillLoc == sym2))
+ return TRUE;
- if (IS_ITEMP (op2) &&
- !IS_ITEMP (op1) &&
- sym2->isspilt && sym1->level > 0 && (sym2->usl.spillLoc == sym1))
- return TRUE;
+ if (IS_ITEMP (op2) &&
+ !IS_ITEMP (op1) &&
+ sym2->isspilt && sym1->level > 0 && (sym2->usl.spillLoc == sym1))
+ return TRUE;
- return FALSE;
+ return FALSE;
}
/*-----------------------------------------------------------------*/
static bool
sameRegs (asmop * aop1, asmop * aop2)
{
- int i;
+ int i;
- if (aop1 == aop2)
- return TRUE;
+ if (aop1 == aop2)
+ return TRUE;
- if (aop1->type != AOP_REG || aop2->type != AOP_REG)
- return FALSE;
+ if (aop1->type != AOP_REG || aop2->type != AOP_REG)
+ return FALSE;
- if (aop1->size != aop2->size)
- return FALSE;
+ if (aop1->size != aop2->size)
+ return FALSE;
- for (i = 0; i < aop1->size; i++)
- if (aop1->aopu.aop_reg[i] != aop2->aopu.aop_reg[i])
- return FALSE;
+ for (i = 0; i < aop1->size; i++)
+ if (aop1->aopu.aop_reg[i] != aop2->aopu.aop_reg[i])
+ return FALSE;
- return TRUE;
+ return TRUE;
}
/*-----------------------------------------------------------------*/
static int
isRegPair (asmop * aop)
{
- if (!aop || aop->size < 2)
- return 0;
- if (aop->type == AOP_X || aop->type == AOP_Z)
- return 1;
- if (aop->type != AOP_REG)
- return 0;
- if ( ((aop->aopu.aop_reg[1]->rIdx - aop->aopu.aop_reg[0]->rIdx) == 1) &&
- (aop->aopu.aop_reg[0]->rIdx & 1) == 0)
-
- return 1;
- return 0;
+ if (!aop || aop->size < 2)
+ return 0;
+ if (aop->type == AOP_X || aop->type == AOP_Z)
+ return 1;
+ if (aop->type != AOP_REG)
+ return 0;
+ if ( ((aop->aopu.aop_reg[1]->rIdx - aop->aopu.aop_reg[0]->rIdx) == 1) &&
+ (aop->aopu.aop_reg[0]->rIdx & 1) == 0)
+
+ return 1;
+ return 0;
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static int allHigh (asmop * aop)
{
- int i;
-
- if (aop->type == AOP_X || aop->type == AOP_Z)
- return 1;
- if (aop->type != AOP_REG)
- return 0;
- for (i=0; i < aop->size ; i++ )
- if (aop->aopu.aop_reg[i]->rIdx < R16_IDX) return 0;
- return 1;
+ int i;
+
+ if (aop->type == AOP_X || aop->type == AOP_Z)
+ return 1;
+ if (aop->type != AOP_REG)
+ return 0;
+ for (i=0; i < aop->size ; i++ )
+ if (aop->aopu.aop_reg[i]->rIdx < R16_IDX) return 0;
+ return 1;
}
/*-----------------------------------------------------------------*/
static void
aopOp (operand * op, iCode * ic, bool result)
{
- asmop *aop;
- symbol *sym;
- int i;
-
- if (!op)
- return;
-
- /* if this a literal */
- if (IS_OP_LITERAL (op)) {
- op->aop = aop = newAsmop (AOP_LIT);
- aop->aopu.aop_lit = op->operand.valOperand;
- aop->size = getSize (operandType (op));
- return;
- }
-
- /* if already has a asmop then continue */
- if (op->aop)
- return;
-
- /* if the underlying symbol has a aop */
- if (IS_SYMOP (op) && OP_SYMBOL (op)->aop) {
- op->aop = OP_SYMBOL (op)->aop;
- return;
- }
-
- /* if this is a true symbol */
- if (IS_TRUE_SYMOP (op)) {
- op->aop = aopForSym (ic, OP_SYMBOL (op), result);
- return;
- }
-
- /* this is a temporary : this has
- only four choices :
- a) register
- b) spillocation
- c) rematerialize
- d) conditional
- e) can be a return use only */
-
- sym = OP_SYMBOL (op);
-
-
- /* if the type is a conditional */
- if (sym->regType & REG_CND) {
- aop = op->aop = sym->aop = newAsmop (AOP_CRY);
- aop->size = 0;
- return;
- }
-
- /* if it is spilt then two situations
- a) is rematerialize
- b) has a spill location */
- if (sym->isspilt || sym->nRegs == 0) {
-
- asmop *oldAsmOp = NULL;
-
- /* rematerialize it NOW */
- if (sym->remat) {
- sym->aop = op->aop = aop = aopForRemat (sym);
- aop->size = getSize (sym->type);
- return;
- }
-
- if (sym->accuse) {
- assert ("ACC_USE cannot happen in AVR\n");
- }
-
- if (sym->ruonly) {
- int i;
- aop = op->aop = sym->aop = newAsmop (AOP_STR);
- aop->size = getSize (sym->type);
- for (i = 0; i < (int) fAVRReturnSize; i++)
- aop->aopu.aop_str[i] = fAVRReturn[i];
- return;
- }
-
- /* else spill location */
- if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
- /* force a new aop if sizes differ */
- oldAsmOp = sym->usl.spillLoc->aop;
- sym->usl.spillLoc->aop = NULL;
- }
- sym->aop = op->aop = aop =
- aopForSym (ic, sym->usl.spillLoc, result);
- if (getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
- /* Don't reuse the new aop, go with the last one */
- sym->usl.spillLoc->aop = oldAsmOp;
- }
- aop->size = getSize (sym->type);
- return;
- }
-
- /* must be in a register */
- sym->aop = op->aop = aop = newAsmop (AOP_REG);
- aop->size = sym->nRegs;
- for (i = 0; i < sym->nRegs; i++)
- aop->aopu.aop_reg[i] = sym->regs[i];
+ asmop *aop;
+ symbol *sym;
+ int i;
+
+ if (!op)
+ return;
+
+ /* if this a literal */
+ if (IS_OP_LITERAL (op)) {
+ op->aop = aop = newAsmop (AOP_LIT);
+ aop->aopu.aop_lit = op->operand.valOperand;
+ aop->size = getSize (operandType (op));
+ return;
+ }
+
+ /* if already has a asmop then continue */
+ if (op->aop)
+ return;
+
+ /* if the underlying symbol has a aop */
+ if (IS_SYMOP (op) && OP_SYMBOL (op)->aop) {
+ op->aop = OP_SYMBOL (op)->aop;
+ return;
+ }
+
+ /* if this is a true symbol */
+ if (IS_TRUE_SYMOP (op)) {
+ op->aop = aopForSym (ic, OP_SYMBOL (op), result);
+ return;
+ }
+
+ /* this is a temporary : this has
+ only four choices :
+ a) register
+ b) spillocation
+ c) rematerialize
+ d) conditional
+ e) can be a return use only */
+
+ sym = OP_SYMBOL (op);
+
+
+ /* if the type is a conditional */
+ if (sym->regType & REG_CND) {
+ aop = op->aop = sym->aop = newAsmop (AOP_CRY);
+ aop->size = 0;
+ return;
+ }
+
+ /* if it is spilt then two situations
+ a) is rematerialize
+ b) has a spill location */
+ if (sym->isspilt || sym->nRegs == 0) {
+
+ asmop *oldAsmOp = NULL;
+
+ /* rematerialize it NOW */
+ if (sym->remat) {
+ sym->aop = op->aop = aop = aopForRemat (sym);
+ aop->size = getSize (sym->type);
+ return;
+ }
+
+ if (sym->accuse) {
+ assert ("ACC_USE cannot happen in AVR\n");
+ }
+
+ if (sym->ruonly) {
+ int i;
+ aop = op->aop = sym->aop = newAsmop (AOP_STR);
+ aop->size = getSize (sym->type);
+ for (i = 0; i < (int) fAVRReturnSize; i++)
+ aop->aopu.aop_str[i] = fAVRReturn[i];
+ return;
+ }
+
+ /* else spill location */
+ if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
+ /* force a new aop if sizes differ */
+ oldAsmOp = sym->usl.spillLoc->aop;
+ sym->usl.spillLoc->aop = NULL;
+ }
+ sym->aop = op->aop = aop =
+ aopForSym (ic, sym->usl.spillLoc, result);
+ if (getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
+ /* Don't reuse the new aop, go with the last one */
+ sym->usl.spillLoc->aop = oldAsmOp;
+ }
+ aop->size = getSize (sym->type);
+ return;
+ }
+
+ /* must be in a register */
+ sym->aop = op->aop = aop = newAsmop (AOP_REG);
+ aop->size = sym->nRegs;
+ for (i = 0; i < sym->nRegs; i++)
+ aop->aopu.aop_reg[i] = sym->regs[i];
}
/*-----------------------------------------------------------------*/
static void
freeAsmop (operand * op, asmop * aaop, iCode * ic, bool pop)
{
- asmop *aop;
-
- if (!op)
- aop = aaop;
- else
- aop = op->aop;
-
- if (!aop)
- return;
-
- if (aop->freed)
- goto dealloc;
-
- aop->freed = 1;
-
- /* depending on the asmop type only three cases need work AOP_RO
- , AOP_R1 && AOP_STK */
- switch (aop->type) {
- case AOP_X:
- if (_G.xPushed) {
- if (pop) {
- emitcode ("pop", "r26");
- emitcode ("pop", "r27");
- _G.xPushed--;
- }
- }
- bitVectUnSetBit (ic->rUsed, X_IDX);
- break;
-
- case AOP_Z:
- if (_G.zPushed) {
- if (pop) {
- emitcode ("pop", "r30");
- emitcode ("pop", "r31");
- _G.zPushed--;
- }
- }
- bitVectUnSetBit (ic->rUsed, Z_IDX);
- break;
-
- case AOP_STK:
- {
- int sz = aop->size;
- int stk = aop->aopu.aop_stk + aop->size;
- bitVectUnSetBit (ic->rUsed, X_IDX);
- bitVectUnSetBit (ic->rUsed, Z_IDX);
-
- getFreePtr (ic, &aop, FALSE, 0);
-
- emitcode ("movw", "%s,r28");
- if (stk) {
- if (stk <= 63 && stk > 0) {
- emitcode ("adiw", "%s,0x%02x",
- aop->aopu.aop_ptr->name,
- stk + 1);
- }
- else {
- emitcode ("subi", "%s,<(%d)",
- aop->aopu.aop_ptr->name,
- -(stk + 1));
- emitcode ("sbci", "%s,>(%d)",
- aop->aop_ptr2->name,
- -(stk + 1));
- }
- }
-
- while (sz--) {
- emitcode ("pop", "r24");
- emitcode ("st", "-%s,r24",
- aop->type == AOP_X ? "X" : "Z");
- if (!sz)
- break;
- }
- op->aop = aop;
- freeAsmop (op, NULL, ic, TRUE);
- if (_G.xPushed) {
- emitcode ("pop", "r26");
- emitcode ("pop", "r27");
- _G.xPushed--;
- }
-
- if (_G.zPushed) {
- emitcode ("pop", "r30");
- emitcode ("pop", "r31");
- _G.zPushed--;
- }
- }
- }
+ asmop *aop;
+
+ if (!op)
+ aop = aaop;
+ else
+ aop = op->aop;
+
+ if (!aop)
+ return;
+
+ if (aop->freed)
+ goto dealloc;
+
+ aop->freed = 1;
+
+ /* depending on the asmop type only three cases need work AOP_RO
+ , AOP_R1 && AOP_STK */
+ switch (aop->type) {
+ case AOP_X:
+ if (_G.xPushed) {
+ if (pop) {
+ emitcode ("pop", "r26");
+ emitcode ("pop", "r27");
+ _G.xPushed--;
+ }
+ }
+ bitVectUnSetBit (ic->rUsed, X_IDX);
+ break;
+
+ case AOP_Z:
+ if (_G.zPushed) {
+ if (pop) {
+ emitcode ("pop", "r30");
+ emitcode ("pop", "r31");
+ _G.zPushed--;
+ }
+ }
+ bitVectUnSetBit (ic->rUsed, Z_IDX);
+ break;
+
+ case AOP_STK:
+ {
+ int sz = aop->size;
+ int stk = aop->aopu.aop_stk + aop->size;
+ bitVectUnSetBit (ic->rUsed, X_IDX);
+ bitVectUnSetBit (ic->rUsed, Z_IDX);
+
+ getFreePtr (ic, &aop, FALSE, 0);
+
+ emitcode ("movw", "%s,r28");
+ if (stk) {
+ if (stk <= 63 && stk > 0) {
+ emitcode ("adiw", "%s,0x%02x",
+ aop->aopu.aop_ptr->name,
+ stk + 1);
+ }
+ else {
+ emitcode ("subi", "%s,<(%d)",
+ aop->aopu.aop_ptr->name,
+ -(stk + 1));
+ emitcode ("sbci", "%s,>(%d)",
+ aop->aop_ptr2->name,
+ -(stk + 1));
+ }
+ }
+
+ while (sz--) {
+ emitcode ("pop", "r24");
+ emitcode ("st", "-%s,r24",
+ aop->type == AOP_X ? "X" : "Z");
+ if (!sz)
+ break;
+ }
+ op->aop = aop;
+ freeAsmop (op, NULL, ic, TRUE);
+ if (_G.xPushed) {
+ emitcode ("pop", "r26");
+ emitcode ("pop", "r27");
+ _G.xPushed--;
+ }
+
+ if (_G.zPushed) {
+ emitcode ("pop", "r30");
+ emitcode ("pop", "r31");
+ _G.zPushed--;
+ }
+ }
+ }
dealloc:
- /* all other cases just dealloc */
- if (op) {
- op->aop = NULL;
- if (IS_SYMOP (op)) {
- OP_SYMBOL (op)->aop = NULL;
- /* if the symbol has a spill */
- if (SPIL_LOC (op))
- SPIL_LOC (op)->aop = NULL;
- }
- }
+ /* all other cases just dealloc */
+ if (op) {
+ op->aop = NULL;
+ if (IS_SYMOP (op)) {
+ OP_SYMBOL (op)->aop = NULL;
+ /* if the symbol has a spill */
+ if (SPIL_LOC (op))
+ SPIL_LOC (op)->aop = NULL;
+ }
+ }
}
/*-----------------------------------------------------------------*/
static char *
aopGet (asmop * aop, int offset)
{
- char *s = buffer;
- char *rs;
-
- /* offset is greater than
- size then zero */
- if (offset > (aop->size - 1) && aop->type != AOP_LIT)
- return zero;
-
- /* depending on type */
- switch (aop->type) {
-
- case AOP_X:
- if (offset > aop->coff) {
- emitcode ("adiw", "%s,%d", aop->aopu.aop_ptr->name,
- offset - aop->coff);
- }
-
- if (offset < aop->coff) {
- emitcode ("sbiw", "%s,%d", aop->aopu.aop_ptr->name,
- aop->coff - offset);
- }
-
- aop->coff = offset;
- emitcode ("ld", "%s,x",
- (rs = ((offset & 1) ? "r25" : "r24")));
- return rs;
-
- case AOP_Z:
- if (aop->code) {
- if (offset > aop->coff) {
- emitcode ("adiw", "r30,%d",
- offset - aop->coff);
- }
- else {
- emitcode ("sbiw", "r30,%d",
- aop->coff - offset);
- }
- emitcode ("lpm", "%s,z",
- (rs = ((offset & 1) ? "r25" : "r24")));
- }
- else {
- /* we can use lds */
- if (offset > aop->coff) {
- emitcode ("ldd", "%s,z+%d",
- (rs =
- ((offset & 1) ? "r25" : "r24")),
- offset - aop->coff);
- }
- else {
- emitcode ("sbiw", "%s,%d",
- aop->aopu.aop_ptr->name,
- aop->coff - offset);
- aop->coff = offset;
- emitcode ("ld", "%s,z",
- (rs =
- ((offset & 1) ? "r25" : "r24")));
- }
- }
- return rs;
-
- case AOP_IMMD:
-
- emitcode ("lds", "%s,(%s)+%d",
- (rs = ((offset & 1) ? "r25" : "r24")),
- aop->aopu.aop_immd, offset);
- return rs;
-
- case AOP_DIR:
- emitcode ("lds", "%s,(%s)+%d",
- (rs = ((offset & 1) ? "r25" : "r24")),
- aop->aopu.aop_dir, offset);
- return rs;
-
- case AOP_REG:
- return aop->aopu.aop_reg[offset]->name;
-
- case AOP_CRY:
- assert ("cannot be in bit space AOP_CRY\n");
- break;
-
- case AOP_LIT:
- s = aopLiteral (aop->aopu.aop_lit, offset);
- emitcode ("ldi", "%s,<(%s)",
- (rs = ((offset & 1) ? "r24" : "r25")), s);
- return rs;
-
- case AOP_STR:
- aop->coff = offset;
- return aop->aopu.aop_str[offset];
-
- case AOP_STK_D:
- emitcode ("ldd", "%s,Y+%d",
- (rs = ((offset & 1) ? "r25" : "r24")),
- aop->aopu.aop_stk + offset);
- return rs;
- }
-
- werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "aopget got unsupported aop->type");
- exit (0);
+ char *s = buffer;
+ char *rs;
+
+ /* offset is greater than
+ size then zero */
+ if (offset > (aop->size - 1) && aop->type != AOP_LIT)
+ return zero;
+
+ /* depending on type */
+ switch (aop->type) {
+
+ case AOP_X:
+ if (offset > aop->coff) {
+ emitcode ("adiw", "%s,%d", aop->aopu.aop_ptr->name,
+ offset - aop->coff);
+ }
+
+ if (offset < aop->coff) {
+ emitcode ("sbiw", "%s,%d", aop->aopu.aop_ptr->name,
+ aop->coff - offset);
+ }
+
+ aop->coff = offset;
+ emitcode ("ld", "%s,x",
+ (rs = ((offset & 1) ? "r25" : "r24")));
+ return rs;
+
+ case AOP_Z:
+ if (aop->code) {
+ if (offset > aop->coff) {
+ emitcode ("adiw", "r30,%d",
+ offset - aop->coff);
+ }
+ else {
+ emitcode ("sbiw", "r30,%d",
+ aop->coff - offset);
+ }
+ emitcode ("lpm", "%s,z",
+ (rs = ((offset & 1) ? "r25" : "r24")));
+ }
+ else {
+ /* we can use lds */
+ if (offset > aop->coff) {
+ emitcode ("ldd", "%s,z+%d",
+ (rs =
+ ((offset & 1) ? "r25" : "r24")),
+ offset - aop->coff);
+ }
+ else {
+ emitcode ("sbiw", "%s,%d",
+ aop->aopu.aop_ptr->name,
+ aop->coff - offset);
+ aop->coff = offset;
+ emitcode ("ld", "%s,z",
+ (rs =
+ ((offset & 1) ? "r25" : "r24")));
+ }
+ }
+ return rs;
+
+ case AOP_IMMD:
+
+ emitcode ("lds", "%s,(%s)+%d",
+ (rs = ((offset & 1) ? "r25" : "r24")),
+ aop->aopu.aop_immd, offset);
+ return rs;
+
+ case AOP_DIR:
+ emitcode ("lds", "%s,(%s)+%d",
+ (rs = ((offset & 1) ? "r25" : "r24")),
+ aop->aopu.aop_dir, offset);
+ return rs;
+
+ case AOP_REG:
+ return aop->aopu.aop_reg[offset]->name;
+
+ case AOP_CRY:
+ assert ("cannot be in bit space AOP_CRY\n");
+ break;
+
+ case AOP_LIT:
+ s = aopLiteral (aop->aopu.aop_lit, offset);
+ emitcode ("ldi", "%s,<(%s)",
+ (rs = ((offset & 1) ? "r24" : "r25")), s);
+ return rs;
+
+ case AOP_STR:
+ aop->coff = offset;
+ return aop->aopu.aop_str[offset];
+
+ case AOP_STK_D:
+ emitcode ("ldd", "%s,Y+%d",
+ (rs = ((offset & 1) ? "r25" : "r24")),
+ aop->aopu.aop_stk + offset);
+ return rs;
+ }
+
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "aopget got unsupported aop->type");
+ exit (0);
}
/*-----------------------------------------------------------------*/
static void
aopPut (asmop * aop, char *s, int offset)
{
- char *d = buffer;
-
- if (aop->size && offset > (aop->size - 1)) {
- werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "aopPut got offset > aop->size");
- exit (0);
- }
-
- /* will assign value to value */
- /* depending on where it is ofcourse */
- switch (aop->type) {
- case AOP_DIR:
- if (offset) {
- sprintf (d, "(%s)+%d", aop->aopu.aop_dir, offset);
- }
- else {
- sprintf (d, "%s", aop->aopu.aop_dir);
- }
-
- emitcode ("sts", "%s,%s", d, s);
- break;
-
- case AOP_REG:
- if (toupper ((unsigned char)*s) != 'R') {
- if (s == zero) {
- emitcode ("clr", "%s",
- aop->aopu.aop_reg[offset]->name);
- }
- else {
- emitcode ("ldi", "r25,%s", s);
- emitcode ("mov", "%s,r35",
- aop->aopu.aop_reg[offset]->name);
- }
- }
- else {
- if (strcmp (aop->aopu.aop_reg[offset]->name, s)) {
- emitcode ("mov", "%s,%s",
- aop->aopu.aop_reg[offset]->name, s);
- }
- }
- break;
-
- case AOP_X:
- if (offset > aop->coff) {
- emitcode ("adiw", "%s,%d", aop->aopu.aop_ptr->name,
- offset - aop->coff);
- }
-
- if (offset < aop->coff) {
- emitcode ("sbiw", "%s,%d", aop->aopu.aop_ptr->name,
- aop->coff - offset);
- }
-
- aop->coff = offset;
- emitcode ("st", "x,%s", s);
- break;
-
- case AOP_Z:
- if (aop->code) {
- if (offset > aop->coff) {
- emitcode ("adiw", "r30,%d",
- offset - aop->coff);
- }
- else {
- emitcode ("sbiw", "r30,%d",
- aop->coff - offset);
- }
- emitcode ("lpm", "%s,z", s);
- }
- else {
- /* we can use lds */
- if (offset > aop->coff) {
- emitcode ("sdd", "z+%d,%s",
- offset - aop->coff, s);
- }
- else {
- emitcode ("sbiw", "%s,%d",
- aop->aopu.aop_ptr->name,
- aop->coff - offset);
- aop->coff = offset;
- emitcode ("ld", "%s,z", s);
- }
- }
- break;
-
- case AOP_STK:
- emitcode ("push", "%s", s);
- break;
-
- case AOP_CRY:
- /* if used only for a condition code check */
- assert (toupper ((unsigned char)*s) == 'R');
- if (offset == 0) {
- emitcode ("xrl", "r0,r0");
- emitcode ("cpi", "%s,0", s);
- }
- else {
- emitcode ("cpc", "r0,%s", s);
- }
- break;
-
- case AOP_STR:
- aop->coff = offset;
- if (strcmp (aop->aopu.aop_str[offset], s))
- emitcode ("mov", "%s,%s", aop->aopu.aop_str[offset],
- s);
- break;
-
- case AOP_STK_D:
- emitcode ("std", "y+%d,%s", offset, s);
- break;
-
- default:
- werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "aopPut got unsupported aop->type");
- exit (0);
- }
+ char *d = buffer;
+
+ if (aop->size && offset > (aop->size - 1)) {
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "aopPut got offset > aop->size");
+ exit (0);
+ }
+
+ /* will assign value to value */
+ /* depending on where it is ofcourse */
+ switch (aop->type) {
+ case AOP_DIR:
+ if (offset) {
+ sprintf (d, "(%s)+%d", aop->aopu.aop_dir, offset);
+ }
+ else {
+ sprintf (d, "%s", aop->aopu.aop_dir);
+ }
+
+ emitcode ("sts", "%s,%s", d, s);
+ break;
+
+ case AOP_REG:
+ if (toupper ((unsigned char)*s) != 'R') {
+ if (s == zero) {
+ emitcode ("clr", "%s",
+ aop->aopu.aop_reg[offset]->name);
+ }
+ else {
+ emitcode ("ldi", "r25,%s", s);
+ emitcode ("mov", "%s,r35",
+ aop->aopu.aop_reg[offset]->name);
+ }
+ }
+ else {
+ if (strcmp (aop->aopu.aop_reg[offset]->name, s)) {
+ emitcode ("mov", "%s,%s",
+ aop->aopu.aop_reg[offset]->name, s);
+ }
+ }
+ break;
+
+ case AOP_X:
+ if (offset > aop->coff) {
+ emitcode ("adiw", "%s,%d", aop->aopu.aop_ptr->name,
+ offset - aop->coff);
+ }
+
+ if (offset < aop->coff) {
+ emitcode ("sbiw", "%s,%d", aop->aopu.aop_ptr->name,
+ aop->coff - offset);
+ }
+
+ aop->coff = offset;
+ emitcode ("st", "x,%s", s);
+ break;
+
+ case AOP_Z:
+ if (aop->code) {
+ if (offset > aop->coff) {
+ emitcode ("adiw", "r30,%d",
+ offset - aop->coff);
+ }
+ else {
+ emitcode ("sbiw", "r30,%d",
+ aop->coff - offset);
+ }
+ emitcode ("lpm", "%s,z", s);
+ }
+ else {
+ /* we can use lds */
+ if (offset > aop->coff) {
+ emitcode ("sdd", "z+%d,%s",
+ offset - aop->coff, s);
+ }
+ else {
+ emitcode ("sbiw", "%s,%d",
+ aop->aopu.aop_ptr->name,
+ aop->coff - offset);
+ aop->coff = offset;
+ emitcode ("ld", "%s,z", s);
+ }
+ }
+ break;
+
+ case AOP_STK:
+ emitcode ("push", "%s", s);
+ break;
+
+ case AOP_CRY:
+ /* if used only for a condition code check */
+ assert (toupper ((unsigned char)*s) == 'R');
+ if (offset == 0) {
+ emitcode ("xrl", "r0,r0");
+ emitcode ("cpi", "%s,0", s);
+ }
+ else {
+ emitcode ("cpc", "r0,%s", s);
+ }
+ break;
+
+ case AOP_STR:
+ aop->coff = offset;
+ if (strcmp (aop->aopu.aop_str[offset], s))
+ emitcode ("mov", "%s,%s", aop->aopu.aop_str[offset],
+ s);
+ break;
+
+ case AOP_STK_D:
+ emitcode ("std", "y+%d,%s", offset, s);
+ break;
+
+ default:
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "aopPut got unsupported aop->type");
+ exit (0);
+ }
}
static void
genNotFloat (operand * op, operand * res)
{
- int size, offset;
- char *l;
- symbol *tlbl;
-
- /* we will put 127 in the first byte of
- the result */
- aopPut (AOP (res), "127", 0);
- size = AOP_SIZE (op) - 1;
- offset = 1;
-
- l = aopGet (op->aop, offset++);
- MOVR0 (l);
-
- while (size--) {
- emitcode ("or", "R0,%s", aopGet (op->aop, offset++));
- }
- tlbl = newiTempLabel (NULL);
-
- tlbl = newiTempLabel (NULL);
- aopPut (res->aop, zero, 1);
- emitcode ("cpi", "r0,0");
- emitcode ("breq", "L%05d", tlbl->key);
- aopPut (res->aop, one, 1);
- emitcode ("", "L%05d:", tlbl->key);
-
- size = res->aop->size - 2;
- offset = 2;
- /* put zeros in the rest */
- while (size--)
- aopPut (res->aop, zero, offset++);
+ int size, offset;
+ char *l;
+ symbol *tlbl;
+
+ /* we will put 127 in the first byte of
+ the result */
+ aopPut (AOP (res), "127", 0);
+ size = AOP_SIZE (op) - 1;
+ offset = 1;
+
+ l = aopGet (op->aop, offset++);
+ MOVR0 (l);
+
+ while (size--) {
+ emitcode ("or", "R0,%s", aopGet (op->aop, offset++));
+ }
+ tlbl = newiTempLabel (NULL);
+
+ tlbl = newiTempLabel (NULL);
+ aopPut (res->aop, zero, 1);
+ emitcode ("cpi", "r0,0");
+ emitcode ("breq", "L%05d", tlbl->key);
+ aopPut (res->aop, one, 1);
+ emitcode ("", "L%05d:", tlbl->key);
+
+ size = res->aop->size - 2;
+ offset = 2;
+ /* put zeros in the rest */
+ while (size--)
+ aopPut (res->aop, zero, offset++);
}
/*-----------------------------------------------------------------*/
static int
opIsGptr (operand * op)
{
- sym_link *type = operandType (op);
+ sym_link *type = operandType (op);
- if ((AOP_SIZE (op) == GPTRSIZE) && IS_GENPTR (type)) {
- return 1;
- }
- return 0;
+ if ((AOP_SIZE (op) == GPTRSIZE) && IS_GENPTR (type)) {
+ return 1;
+ }
+ return 0;
}
/*-----------------------------------------------------------------*/
static int
getDataSize (operand * op)
{
- int size;
- size = AOP_SIZE (op);
- if (size == GPTRSIZE) {
- sym_link *type = operandType (op);
- if (IS_GENPTR (type)) {
- /* generic pointer; arithmetic operations
- * should ignore the high byte (pointer type).
- */
- size--;
- }
- }
- return size;
+ int size;
+ size = AOP_SIZE (op);
+ if (size == GPTRSIZE) {
+ sym_link *type = operandType (op);
+ if (IS_GENPTR (type)) {
+ /* generic pointer; arithmetic operations
+ * should ignore the high byte (pointer type).
+ */
+ size--;
+ }
+ }
+ return size;
}
/*-----------------------------------------------------------------*/
static void
toBoolean (operand * oper, char *r, bool clr)
{
- int size = AOP_SIZE (oper);
- int offset = 0;
- if (clr) {
- emitcode ("clr", "%s", r);
- while (size--)
- emitcode ("or", "%s,%s", r, aopGet (AOP (oper), offset++));
- } else {
- size--;
- emitcode("mov","%s,%s",r,aopGet (AOP (oper), offset++));
- if (size) while (size--) emitcode ("or", "%s,%s", r, aopGet (AOP (oper), offset++));
- }
+ int size = AOP_SIZE (oper);
+ int offset = 0;
+ if (clr) {
+ emitcode ("clr", "%s", r);
+ while (size--)
+ emitcode ("or", "%s,%s", r, aopGet (AOP (oper), offset++));
+ } else {
+ size--;
+ emitcode("mov","%s,%s",r,aopGet (AOP (oper), offset++));
+ if (size) while (size--) emitcode ("or", "%s,%s", r, aopGet (AOP (oper), offset++));
+ }
}
static void
genNot (iCode * ic)
{
- symbol *tlbl;
- sym_link *optype = operandType (IC_LEFT (ic));
- int size, offset = 1;
-
- /* assign asmOps to operand & result */
- aopOp (IC_LEFT (ic), ic, FALSE);
- aopOp (IC_RESULT (ic), ic, TRUE);
-
- /* if type float then do float */
- if (IS_FLOAT (optype)) {
- genNotFloat (IC_LEFT (ic), IC_RESULT (ic));
- goto release;
- }
- emitcode ("clr", "r24");
- tlbl = newiTempLabel (NULL);
- size = AOP_SIZE (IC_LEFT (ic));
- offset = 0;
- if (size == 1) {
- emitcode ("cpse", "%s,r24", aopGet (AOP (IC_LEFT (ic)), 0));
- }
- else {
- while (size--) {
- if (offset)
- emitcode ("cpc", "%s,r24",
- aopGet (AOP (IC_LEFT (ic)),
- offset));
- else
- emitcode ("cpi", "%s,0",
- aopGet (AOP (IC_LEFT (ic)),
- offset));
- offset++;
- }
- emitcode ("bne", "L%05d", tlbl->key);
- }
- emitcode ("ldi", "r24,1");
- emitcode ("", "L%05d:", tlbl->key);
- aopPut (AOP (IC_RESULT (ic)), "r24", 0);
- size = AOP_SIZE (IC_RESULT (ic)) - 1;
- offset = 1;
- while (size--)
- aopPut (AOP (IC_RESULT (ic)), zero, offset++);
+ symbol *tlbl;
+ sym_link *optype = operandType (IC_LEFT (ic));
+ int size, offset = 1;
+
+ /* assign asmOps to operand & result */
+ aopOp (IC_LEFT (ic), ic, FALSE);
+ aopOp (IC_RESULT (ic), ic, TRUE);
+
+ /* if type float then do float */
+ if (IS_FLOAT (optype)) {
+ genNotFloat (IC_LEFT (ic), IC_RESULT (ic));
+ goto release;
+ }
+ emitcode ("clr", "r24");
+ tlbl = newiTempLabel (NULL);
+ size = AOP_SIZE (IC_LEFT (ic));
+ offset = 0;
+ if (size == 1) {
+ emitcode ("cpse", "%s,r24", aopGet (AOP (IC_LEFT (ic)), 0));
+ }
+ else {
+ while (size--) {
+ if (offset)
+ emitcode ("cpc", "%s,r24",
+ aopGet (AOP (IC_LEFT (ic)),
+ offset));
+ else
+ emitcode ("cpi", "%s,0",
+ aopGet (AOP (IC_LEFT (ic)),
+ offset));
+ offset++;
+ }
+ emitcode ("bne", "L%05d", tlbl->key);
+ }
+ emitcode ("ldi", "r24,1");
+ emitcode ("", "L%05d:", tlbl->key);
+ aopPut (AOP (IC_RESULT (ic)), "r24", 0);
+ size = AOP_SIZE (IC_RESULT (ic)) - 1;
+ offset = 1;
+ while (size--)
+ aopPut (AOP (IC_RESULT (ic)), zero, offset++);
release:
- /* release the aops */
- freeAsmop (IC_LEFT (ic), NULL, ic, (RESULTONSTACK (ic) ? 0 : 1));
- freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+ /* release the aops */
+ freeAsmop (IC_LEFT (ic), NULL, ic, (RESULTONSTACK (ic) ? 0 : 1));
+ freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
}
static void
genCpl (iCode * ic)
{
- int offset = 0;
- int size;
- int samer;
-
- /* assign asmOps to operand & result */
- aopOp (IC_LEFT (ic), ic, FALSE);
- aopOp (IC_RESULT (ic), ic, TRUE);
- samer = sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic)));
- size = AOP_SIZE (IC_RESULT (ic));
- while (size--) {
- char *l = aopGet (AOP (IC_LEFT (ic)), offset);
- if (samer) {
- emitcode ("com", "%s", l);
- }
- else {
- aopPut (AOP (IC_RESULT (ic)), l, offset);
- emitcode ("com", "%s",
- aopGet (AOP (IC_RESULT (ic)), offset));
- }
- offset++;
- }
-
- /* release the aops */
- freeAsmop (IC_LEFT (ic), NULL, ic, (RESULTONSTACK (ic) ? 0 : 1));
- freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+ int offset = 0;
+ int size;
+ int samer;
+
+ /* assign asmOps to operand & result */
+ aopOp (IC_LEFT (ic), ic, FALSE);
+ aopOp (IC_RESULT (ic), ic, TRUE);
+ samer = sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic)));
+ size = AOP_SIZE (IC_RESULT (ic));
+ while (size--) {
+ char *l = aopGet (AOP (IC_LEFT (ic)), offset);
+ if (samer) {
+ emitcode ("com", "%s", l);
+ }
+ else {
+ aopPut (AOP (IC_RESULT (ic)), l, offset);
+ emitcode ("com", "%s",
+ aopGet (AOP (IC_RESULT (ic)), offset));
+ }
+ offset++;
+ }
+
+ /* release the aops */
+ freeAsmop (IC_LEFT (ic), NULL, ic, (RESULTONSTACK (ic) ? 0 : 1));
+ freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
static void
genUminusFloat (operand * op, operand * result)
{
- int size, offset = 0;
- char *l;
- /* for this we just need to flip the
- first it then copy the rest in place */
- size = AOP_SIZE (op) - 1;
- l = aopGet (AOP (op), 3);
-
- emitcode ("ldi", "r24,0x80");
- if (sameRegs (AOP (op), AOP (result))) {
- emitcode ("eor", "%s,r24", l);
- }
- else {
- aopPut (AOP (result), l, 3);
- emitcode ("eor", "%s,r24", aopGet (AOP (result), 3));
- }
- while (size--) {
- aopPut (AOP (result), aopGet (AOP (op), offset), offset);
- offset++;
- }
+ int size, offset = 0;
+ char *l;
+ /* for this we just need to flip the
+ first it then copy the rest in place */
+ size = AOP_SIZE (op) - 1;
+ l = aopGet (AOP (op), 3);
+
+ emitcode ("ldi", "r24,0x80");
+ if (sameRegs (AOP (op), AOP (result))) {
+ emitcode ("eor", "%s,r24", l);
+ }
+ else {
+ aopPut (AOP (result), l, 3);
+ emitcode ("eor", "%s,r24", aopGet (AOP (result), 3));
+ }
+ while (size--) {
+ aopPut (AOP (result), aopGet (AOP (op), offset), offset);
+ offset++;
+ }
}
/*-----------------------------------------------------------------*/
static void
genUminus (iCode * ic)
{
- int offset, size;
- sym_link *optype, *rtype;
- int samer;
-
- /* assign asmops */
- aopOp (IC_LEFT (ic), ic, FALSE);
- aopOp (IC_RESULT (ic), ic, TRUE);
-
- optype = operandType (IC_LEFT (ic));
- rtype = operandType (IC_RESULT (ic));
-
- /* if float then do float stuff */
- if (IS_FLOAT (optype)) {
- genUminusFloat (IC_LEFT (ic), IC_RESULT (ic));
- goto release;
- }
-
- /* otherwise subtract from zero */
- size = AOP_SIZE (IC_LEFT (ic));
- offset = 0;
- samer = sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic)));
- if (size == 1) {
- if (samer) {
- emitcode ("neg", "%s",
- aopGet (AOP (IC_LEFT (ic)), 0));
- }
- else {
- aopPut (AOP (IC_RESULT (ic)),
- aopGet (AOP (IC_LEFT (ic)), 0), 0);
- emitcode ("neg", "%s",
- aopGet (AOP (IC_RESULT (ic)), 0));
- }
- }
- else {
- offset = size - 1;
- while (size--) {
- char *l = aopGet (AOP (IC_LEFT (ic)), offset);
- if (!samer) {
- aopPut (AOP (IC_RESULT (ic)), l, offset);
- l = aopGet (AOP (IC_RESULT (ic)), offset);
- }
- if (offset)
- emitcode ("com", "%s", l);
- else
- emitcode ("neg", "%s", l);
- offset--;
- }
- size = AOP_SIZE (IC_LEFT (ic)) - 1;
- offset = 1;
- while (size--) {
- emitcode ("sbci", "%s,0xff",
- aopGet (AOP (IC_RESULT (ic)), offset++));
- }
- }
-
- /* if any remaining bytes in the result */
- /* we just need to propagate the sign */
- if ((size = (AOP_SIZE (IC_RESULT (ic)) - AOP_SIZE (IC_LEFT (ic))))) {
- symbol *tlbl = newiTempLabel (NULL);
- emitcode ("clr", "r0");
- emitcode ("brcc", "L%05d", tlbl->key);
- emitcode ("com", "r0");
- emitcode ("", "L%05d:", tlbl->key);
- while (size--)
- aopPut (AOP (IC_RESULT (ic)), "r0", offset++);
- }
+ int offset, size;
+ sym_link *optype, *rtype;
+ int samer;
+
+ /* assign asmops */
+ aopOp (IC_LEFT (ic), ic, FALSE);
+ aopOp (IC_RESULT (ic), ic, TRUE);
+
+ optype = operandType (IC_LEFT (ic));
+ rtype = operandType (IC_RESULT (ic));
+
+ /* if float then do float stuff */
+ if (IS_FLOAT (optype)) {
+ genUminusFloat (IC_LEFT (ic), IC_RESULT (ic));
+ goto release;
+ }
+
+ /* otherwise subtract from zero */
+ size = AOP_SIZE (IC_LEFT (ic));
+ offset = 0;
+ samer = sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic)));
+ if (size == 1) {
+ if (samer) {
+ emitcode ("neg", "%s",
+ aopGet (AOP (IC_LEFT (ic)), 0));
+ }
+ else {
+ aopPut (AOP (IC_RESULT (ic)),
+ aopGet (AOP (IC_LEFT (ic)), 0), 0);
+ emitcode ("neg", "%s",
+ aopGet (AOP (IC_RESULT (ic)), 0));
+ }
+ }
+ else {
+ offset = size - 1;
+ while (size--) {
+ char *l = aopGet (AOP (IC_LEFT (ic)), offset);
+ if (!samer) {
+ aopPut (AOP (IC_RESULT (ic)), l, offset);
+ l = aopGet (AOP (IC_RESULT (ic)), offset);
+ }
+ if (offset)
+ emitcode ("com", "%s", l);
+ else
+ emitcode ("neg", "%s", l);
+ offset--;
+ }
+ size = AOP_SIZE (IC_LEFT (ic)) - 1;
+ offset = 1;
+ while (size--) {
+ emitcode ("sbci", "%s,0xff",
+ aopGet (AOP (IC_RESULT (ic)), offset++));
+ }
+ }
+
+ /* if any remaining bytes in the result */
+ /* we just need to propagate the sign */
+ if ((size = (AOP_SIZE (IC_RESULT (ic)) - AOP_SIZE (IC_LEFT (ic))))) {
+ symbol *tlbl = newiTempLabel (NULL);
+ emitcode ("clr", "r0");
+ emitcode ("brcc", "L%05d", tlbl->key);
+ emitcode ("com", "r0");
+ emitcode ("", "L%05d:", tlbl->key);
+ while (size--)
+ aopPut (AOP (IC_RESULT (ic)), "r0", offset++);
+ }
release:
- /* release the aops */
- freeAsmop (IC_LEFT (ic), NULL, ic, (RESULTONSTACK (ic) ? 0 : 1));
- freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+ /* release the aops */
+ freeAsmop (IC_LEFT (ic), NULL, ic, (RESULTONSTACK (ic) ? 0 : 1));
+ freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
static void
assignResultValue (operand * oper)
{
- int offset = 0;
- int size = AOP_SIZE (oper);
- while (size--) {
- aopPut (AOP (oper), fAVRReturn[offset], offset);
- offset++;
- }
+ int offset = 0;
+ int size = AOP_SIZE (oper);
+ while (size--) {
+ aopPut (AOP (oper), fAVRReturn[offset], offset);
+ offset++;
+ }
}
/*-----------------------------------------------------------------*/
static void
saveZreg (iCode * ic)
{
- /* only if live accross this call */
- if (ic->regsSaved == 0 &&
- (bitVectBitValue (ic->rMask, R30_IDX) ||
- bitVectBitValue (ic->rMask, R31_IDX))) {
- ic->regsSaved = 1;
- emitcode ("push", "r30");
- emitcode ("push", "r31");
- }
+ /* only if live accross this call */
+ if (ic->regsSaved == 0 &&
+ (bitVectBitValue (ic->rMask, R30_IDX) ||
+ bitVectBitValue (ic->rMask, R31_IDX))) {
+ ic->regsSaved = 1;
+ emitcode ("push", "r30");
+ emitcode ("push", "r31");
+ }
}
/*-----------------------------------------------------------------*/
static void
popZreg (iCode * ic)
{
- if (ic->regsSaved) {
- emitcode ("pop", "r31");
- emitcode ("pop", "r30");
- }
+ if (ic->regsSaved) {
+ emitcode ("pop", "r31");
+ emitcode ("pop", "r30");
+ }
}
/*-----------------------------------------------------------------*/
static void
genIpush (iCode * ic)
{
- int size, offset = 0;
- char *l;
-
-
- if (!ic->parmPush) {
- /* and the item is spilt then do nothing */
- if (OP_SYMBOL (IC_LEFT (ic))->isspilt)
- return;
- }
- else {
- iCode *lic;
- for (lic = ic->next; lic; lic = lic->next)
- if (lic->op == PCALL)
- break;
- if (lic)
- saveZreg (lic);
- }
-
- /* this is a paramter push */
- aopOp (IC_LEFT (ic), ic, FALSE);
- size = AOP_SIZE (IC_LEFT (ic));
- while (size--) {
- l = aopGet (AOP (IC_LEFT (ic)), offset++);
- emitcode ("push", "%s", l);
- }
-
- freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
+ int size, offset = 0;
+ char *l;
+
+
+ if (!ic->parmPush) {
+ /* and the item is spilt then do nothing */
+ if (OP_SYMBOL (IC_LEFT (ic))->isspilt)
+ return;
+ }
+ else {
+ iCode *lic;
+ for (lic = ic->next; lic; lic = lic->next)
+ if (lic->op == PCALL)
+ break;
+ if (lic)
+ saveZreg (lic);
+ }
+
+ /* this is a paramter push */
+ aopOp (IC_LEFT (ic), ic, FALSE);
+ size = AOP_SIZE (IC_LEFT (ic));
+ while (size--) {
+ l = aopGet (AOP (IC_LEFT (ic)), offset++);
+ emitcode ("push", "%s", l);
+ }
+
+ freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
static void
genIpop (iCode * ic)
{
- int size, offset;
+ int size, offset;
- /* if the temp was not pushed then */
- if (OP_SYMBOL (IC_LEFT (ic))->isspilt)
- return;
+ /* if the temp was not pushed then */
+ if (OP_SYMBOL (IC_LEFT (ic))->isspilt)
+ return;
- aopOp (IC_LEFT (ic), ic, FALSE);
- size = AOP_SIZE (IC_LEFT (ic));
- offset = (size - 1);
- while (size--)
- emitcode ("pop", "%s", aopGet (AOP (IC_LEFT (ic)), offset--));
+ aopOp (IC_LEFT (ic), ic, FALSE);
+ size = AOP_SIZE (IC_LEFT (ic));
+ offset = (size - 1);
+ while (size--)
+ emitcode ("pop", "%s", aopGet (AOP (IC_LEFT (ic)), offset--));
- freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
+ freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
genCall (iCode * ic)
{
- /* if send set is not empty then assign */
- if (_G.sendSet) {
- iCode *sic;
- int rnum = 16;
- for (sic = setFirstItem (_G.sendSet); sic;
- sic = setNextItem (_G.sendSet)) {
- int size, offset = 0;
- aopOp (IC_LEFT (sic), sic, FALSE);
- size = AOP_SIZE (IC_LEFT (sic));
- while (size--) {
- char *l =
- aopGet (AOP (IC_LEFT (sic)), offset);
- char *b = buffer;
- sprintf (buffer, "r%d", rnum++);
- if (strcmp (l, b))
- emitcode ("mov", "%s,%s", b, l);
- offset++;
- }
- freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
- }
- _G.sendSet = NULL;
- }
- /* make the call */
- emitcode ("call", "%s", (OP_SYMBOL (IC_LEFT (ic))->rname[0] ?
- OP_SYMBOL (IC_LEFT (ic))->rname :
- OP_SYMBOL (IC_LEFT (ic))->name));
-
- /* if we need assign a result value */
- if ((IS_ITEMP (IC_RESULT (ic)) &&
- (OP_SYMBOL (IC_RESULT (ic))->nRegs ||
- OP_SYMBOL (IC_RESULT (ic))->spildir)) ||
- IS_TRUE_SYMOP (IC_RESULT (ic))) {
-
- aopOp (IC_RESULT (ic), ic, FALSE);
- assignResultValue (IC_RESULT (ic));
- freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
- }
-
- /* adjust the stack for parameters if required */
- if (ic->parmBytes) {
- if (ic->parmBytes > 63) {
- emitcode ("sbiw", "r28,%d", ic->parmBytes);
- }
- else {
- emitcode ("subi", "r28,<(%d)",
- ic->parmBytes);
- emitcode ("sbci", "r29,>(%d)",
- ic->parmBytes);
- }
- }
+ /* if send set is not empty then assign */
+ if (_G.sendSet) {
+ iCode *sic;
+ int rnum = 16;
+ for (sic = setFirstItem (_G.sendSet); sic;
+ sic = setNextItem (_G.sendSet)) {
+ int size, offset = 0;
+ aopOp (IC_LEFT (sic), sic, FALSE);
+ size = AOP_SIZE (IC_LEFT (sic));
+ while (size--) {
+ char *l =
+ aopGet (AOP (IC_LEFT (sic)), offset);
+ char *b = buffer;
+ sprintf (buffer, "r%d", rnum++);
+ if (strcmp (l, b))
+ emitcode ("mov", "%s,%s", b, l);
+ offset++;
+ }
+ freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
+ }
+ _G.sendSet = NULL;
+ }
+ /* make the call */
+ emitcode ("call", "%s", (OP_SYMBOL (IC_LEFT (ic))->rname[0] ?
+ OP_SYMBOL (IC_LEFT (ic))->rname :
+ OP_SYMBOL (IC_LEFT (ic))->name));
+
+ /* if we need assign a result value */
+ if ((IS_ITEMP (IC_RESULT (ic)) &&
+ (OP_SYMBOL (IC_RESULT (ic))->nRegs ||
+ OP_SYMBOL (IC_RESULT (ic))->spildir)) ||
+ IS_TRUE_SYMOP (IC_RESULT (ic))) {
+
+ aopOp (IC_RESULT (ic), ic, FALSE);
+ assignResultValue (IC_RESULT (ic));
+ freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+ }
+
+ /* adjust the stack for parameters if required */
+ if (ic->parmBytes) {
+ if (ic->parmBytes > 63) {
+ emitcode ("sbiw", "r28,%d", ic->parmBytes);
+ }
+ else {
+ emitcode ("subi", "r28,<(%d)",
+ ic->parmBytes);
+ emitcode ("sbci", "r29,>(%d)",
+ ic->parmBytes);
+ }
+ }
}
genPcall (iCode * ic)
{
- if (!ic->regsSaved)
- saveZreg (ic);
-
- aopOp (IC_LEFT (ic), ic, FALSE);
- emitcode ("mov", "r30", aopGet (AOP (IC_LEFT (ic)), 0));
- emitcode ("mov", "r31", aopGet (AOP (IC_RIGHT (ic)), 0));
- freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
-
- /* if send set is not empty the assign */
- if (_G.sendSet) {
- iCode *sic;
- int rnum = 16;
- for (sic = setFirstItem (_G.sendSet); sic;
- sic = setNextItem (_G.sendSet)) {
- int size, offset = 0;
- aopOp (IC_LEFT (sic), sic, FALSE);
- size = AOP_SIZE (IC_LEFT (sic));
- while (size--) {
- char *l =
- aopGet (AOP (IC_LEFT (sic)), offset);
- char *b = buffer;
- sprintf (b, "r%d", rnum++);
- if (strcmp (l, b))
- emitcode ("mov", "%s,%s", b, l);
- offset++;
- }
- freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
- }
- _G.sendSet = NULL;
- }
-
- emitcode ("icall", "");
-
- /* if we need assign a result value */
- if ((IS_ITEMP (IC_RESULT (ic)) &&
- (OP_SYMBOL (IC_RESULT (ic))->nRegs ||
- OP_SYMBOL (IC_RESULT (ic))->spildir)) ||
- IS_TRUE_SYMOP (IC_RESULT (ic))) {
-
- aopOp (IC_RESULT (ic), ic, FALSE);
-
- assignResultValue (IC_RESULT (ic));
- freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
- }
-
- /* adjust the stack for parameters if
- required */
- if (ic->parmBytes) {
- int i;
- if (ic->parmBytes > 3) {
- emitcode ("mov", "a,%s", spname);
- emitcode ("add", "a,#0x%02x",
- (-ic->parmBytes) & 0xff);
- emitcode ("mov", "%s,a", spname);
- }
- else
- for (i = 0; i < ic->parmBytes; i++)
- emitcode ("dec", "%s", spname);
-
- }
-
- /* adjust the stack for parameters if required */
- if (ic->parmBytes) {
- if (ic->parmBytes > 63) {
- emitcode ("sbiw", "r28,%d", ic->parmBytes);
- }
- else {
- emitcode ("subi", "r28,<(%d)",
- ic->parmBytes);
- emitcode ("sbci", "r29,>(%d)",
- ic->parmBytes);
- }
- }
- if (ic->regsSaved)
- popZreg (ic);
+ if (!ic->regsSaved)
+ saveZreg (ic);
+
+ aopOp (IC_LEFT (ic), ic, FALSE);
+ emitcode ("mov", "r30", aopGet (AOP (IC_LEFT (ic)), 0));
+ emitcode ("mov", "r31", aopGet (AOP (IC_RIGHT (ic)), 0));
+ freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
+
+ /* if send set is not empty the assign */
+ if (_G.sendSet) {
+ iCode *sic;
+ int rnum = 16;
+ for (sic = setFirstItem (_G.sendSet); sic;
+ sic = setNextItem (_G.sendSet)) {
+ int size, offset = 0;
+ aopOp (IC_LEFT (sic), sic, FALSE);
+ size = AOP_SIZE (IC_LEFT (sic));
+ while (size--) {
+ char *l =
+ aopGet (AOP (IC_LEFT (sic)), offset);
+ char *b = buffer;
+ sprintf (b, "r%d", rnum++);
+ if (strcmp (l, b))
+ emitcode ("mov", "%s,%s", b, l);
+ offset++;
+ }
+ freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
+ }
+ _G.sendSet = NULL;
+ }
+
+ emitcode ("icall", "");
+
+ /* if we need assign a result value */
+ if ((IS_ITEMP (IC_RESULT (ic)) &&
+ (OP_SYMBOL (IC_RESULT (ic))->nRegs ||
+ OP_SYMBOL (IC_RESULT (ic))->spildir)) ||
+ IS_TRUE_SYMOP (IC_RESULT (ic))) {
+
+ aopOp (IC_RESULT (ic), ic, FALSE);
+
+ assignResultValue (IC_RESULT (ic));
+ freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+ }
+
+ /* adjust the stack for parameters if
+ required */
+ if (ic->parmBytes) {
+ int i;
+ if (ic->parmBytes > 3) {
+ emitcode ("mov", "a,%s", spname);
+ emitcode ("add", "a,#0x%02x",
+ (-ic->parmBytes) & 0xff);
+ emitcode ("mov", "%s,a", spname);
+ }
+ else
+ for (i = 0; i < ic->parmBytes; i++)
+ emitcode ("dec", "%s", spname);
+
+ }
+
+ /* adjust the stack for parameters if required */
+ if (ic->parmBytes) {
+ if (ic->parmBytes > 63) {
+ emitcode ("sbiw", "r28,%d", ic->parmBytes);
+ }
+ else {
+ emitcode ("subi", "r28,<(%d)",
+ ic->parmBytes);
+ emitcode ("sbci", "r29,>(%d)",
+ ic->parmBytes);
+ }
+ }
+ if (ic->regsSaved)
+ popZreg (ic);
}
/*-----------------------------------------------------------------*/
static int
resultRemat (iCode * ic)
{
- if (SKIP_IC (ic) || ic->op == IFX)
- return 0;
+ if (SKIP_IC (ic) || ic->op == IFX)
+ return 0;
- if (IC_RESULT (ic) && IS_ITEMP (IC_RESULT (ic))) {
- symbol *sym = OP_SYMBOL (IC_RESULT (ic));
- if (sym->remat && !POINTER_SET (ic))
- return 1;
- }
+ if (IC_RESULT (ic) && IS_ITEMP (IC_RESULT (ic))) {
+ symbol *sym = OP_SYMBOL (IC_RESULT (ic));
+ if (sym->remat && !POINTER_SET (ic))
+ return 1;
+ }
- return 0;
+ return 0;
}
/*-----------------------------------------------------------------*/
static void
genFunction (iCode * ic)
{
- symbol *sym;
- sym_link *ftype;
- int i = 0;
-
- _G.nRegsSaved = 0;
- /* create the function header */
- emitcode (";", "-----------------------------------------");
- emitcode (";", " function %s",
- (sym = OP_SYMBOL (IC_LEFT (ic)))->name);
- emitcode (";", "-----------------------------------------");
-
- emitcode ("", "%s:", sym->rname);
- ftype = operandType (IC_LEFT (ic));
-
- /* if critical function then turn interrupts off */
- if (IFFUNC_ISCRITICAL (ftype))
- emitcode ("cli", "");
-
- if (IFFUNC_ISISR (sym->type)) {
- }
-
- /* save the preserved registers that are used in this function */
- for (i = R2_IDX; i <= R15_IDX; i++) {
- if (bitVectBitValue (sym->regsUsed, i)) {
- _G.nRegsSaved++;
- emitcode ("push", "%s", avr_regWithIdx (i)->name);
- }
- }
- /* now for the pointer registers */
- if (bitVectBitValue (sym->regsUsed, R26_IDX)) {
- _G.nRegsSaved++;
- emitcode ("push", "r26");
- }
- if (bitVectBitValue (sym->regsUsed, R27_IDX)) {
- _G.nRegsSaved++;
- emitcode ("push", "r27");
- }
- if (bitVectBitValue (sym->regsUsed, R30_IDX)) {
- _G.nRegsSaved++;
- emitcode ("push", "r30");
- }
- if (bitVectBitValue (sym->regsUsed, R31_IDX)) {
- _G.nRegsSaved++;
- emitcode ("push", "r31");
- }
- /* adjust the stack for the function */
- if (sym->stack) {
- emitcode ("push", "r28");
- emitcode ("push", "r29");
- emitcode ("in", "r28,__SP_L__");
- emitcode ("in", "r29,__SP_H__");
- if (sym->stack <= 63) {
- emitcode ("sbiw", "r28,%d", sym->stack);
- }
- else {
- emitcode ("subi", "r28,<(%d)", sym->stack);
- emitcode ("sbci", "r29,>(%d)", sym->stack);
- }
- emitcode ("out", "__SP_L__,r28");
- emitcode ("out", "__SP_H__,r29");
- }
+ symbol *sym;
+ sym_link *ftype;
+ int i = 0;
+
+ _G.nRegsSaved = 0;
+ /* create the function header */
+ emitcode (";", "-----------------------------------------");
+ emitcode (";", " function %s",
+ (sym = OP_SYMBOL (IC_LEFT (ic)))->name);
+ emitcode (";", "-----------------------------------------");
+
+ emitcode ("", "%s:", sym->rname);
+ ftype = operandType (IC_LEFT (ic));
+
+ /* if critical function then turn interrupts off */
+ if (IFFUNC_ISCRITICAL (ftype))
+ emitcode ("cli", "");
+
+ if (IFFUNC_ISISR (sym->type)) {
+ }
+
+ /* save the preserved registers that are used in this function */
+ for (i = R2_IDX; i <= R15_IDX; i++) {
+ if (bitVectBitValue (sym->regsUsed, i)) {
+ _G.nRegsSaved++;
+ emitcode ("push", "%s", avr_regWithIdx (i)->name);
+ }
+ }
+ /* now for the pointer registers */
+ if (bitVectBitValue (sym->regsUsed, R26_IDX)) {
+ _G.nRegsSaved++;
+ emitcode ("push", "r26");
+ }
+ if (bitVectBitValue (sym->regsUsed, R27_IDX)) {
+ _G.nRegsSaved++;
+ emitcode ("push", "r27");
+ }
+ if (bitVectBitValue (sym->regsUsed, R30_IDX)) {
+ _G.nRegsSaved++;
+ emitcode ("push", "r30");
+ }
+ if (bitVectBitValue (sym->regsUsed, R31_IDX)) {
+ _G.nRegsSaved++;
+ emitcode ("push", "r31");
+ }
+ /* adjust the stack for the function */
+ if (sym->stack) {
+ emitcode ("push", "r28");
+ emitcode ("push", "r29");
+ emitcode ("in", "r28,__SP_L__");
+ emitcode ("in", "r29,__SP_H__");
+ if (sym->stack <= 63) {
+ emitcode ("sbiw", "r28,%d", sym->stack);
+ }
+ else {
+ emitcode ("subi", "r28,<(%d)", sym->stack);
+ emitcode ("sbci", "r29,>(%d)", sym->stack);
+ }
+ emitcode ("out", "__SP_L__,r28");
+ emitcode ("out", "__SP_H__,r29");
+ }
}
/*-----------------------------------------------------------------*/
static void
genEndFunction (iCode * ic)
{
- symbol *sym = OP_SYMBOL (IC_LEFT (ic));
- int i;
-
- /* restore stack pointer */
- if (sym->stack) {
- if (sym->stack <= 63) {
- emitcode ("adiw", "r28,%d", sym->stack);
- }
- else {
- emitcode ("subi", "r28,<(-%d)", sym->stack);
- emitcode ("sbci", "r29,>(-%d)", sym->stack);
- }
- emitcode ("out", "__SP_L__,r28");
- emitcode ("out", "__SP_H__,r29");
-
- /* pop frame pointer */
- emitcode ("pop", "r29");
- emitcode ("pop", "r28");
- }
- /* restore preserved registers */
- if (bitVectBitValue (sym->regsUsed, R31_IDX)) {
- _G.nRegsSaved--;
- emitcode ("pop", "r31");
- }
- if (bitVectBitValue (sym->regsUsed, R30_IDX)) {
- _G.nRegsSaved--;
- emitcode ("pop", "r30");
- }
- if (bitVectBitValue (sym->regsUsed, R27_IDX)) {
- _G.nRegsSaved--;
- emitcode ("pop", "r27");
- }
- if (bitVectBitValue (sym->regsUsed, R26_IDX)) {
- _G.nRegsSaved--;
- emitcode ("pop", "r26");
- }
- for (i = R15_IDX; i >= R2_IDX; i--) {
- if (bitVectBitValue (sym->regsUsed, i)) {
- _G.nRegsSaved--;
- emitcode ("pop", "%s", avr_regWithIdx (i)->name);
- }
- }
-
- if (IFFUNC_ISCRITICAL (sym->type))
- emitcode ("sti", "");
-
- if (options.debug && currFunc) {
- debugFile->writeEndFunction (currFunc, ic, 1);
- }
-
- if (IFFUNC_ISISR (sym->type)) {
- emitcode ("rti", "");
- }
- else {
- emitcode ("ret", "");
- }
+ symbol *sym = OP_SYMBOL (IC_LEFT (ic));
+ int i;
+
+ /* restore stack pointer */
+ if (sym->stack) {
+ if (sym->stack <= 63) {
+ emitcode ("adiw", "r28,%d", sym->stack);
+ }
+ else {
+ emitcode ("subi", "r28,<(-%d)", sym->stack);
+ emitcode ("sbci", "r29,>(-%d)", sym->stack);
+ }
+ emitcode ("out", "__SP_L__,r28");
+ emitcode ("out", "__SP_H__,r29");
+
+ /* pop frame pointer */
+ emitcode ("pop", "r29");
+ emitcode ("pop", "r28");
+ }
+ /* restore preserved registers */
+ if (bitVectBitValue (sym->regsUsed, R31_IDX)) {
+ _G.nRegsSaved--;
+ emitcode ("pop", "r31");
+ }
+ if (bitVectBitValue (sym->regsUsed, R30_IDX)) {
+ _G.nRegsSaved--;
+ emitcode ("pop", "r30");
+ }
+ if (bitVectBitValue (sym->regsUsed, R27_IDX)) {
+ _G.nRegsSaved--;
+ emitcode ("pop", "r27");
+ }
+ if (bitVectBitValue (sym->regsUsed, R26_IDX)) {
+ _G.nRegsSaved--;
+ emitcode ("pop", "r26");
+ }
+ for (i = R15_IDX; i >= R2_IDX; i--) {
+ if (bitVectBitValue (sym->regsUsed, i)) {
+ _G.nRegsSaved--;
+ emitcode ("pop", "%s", avr_regWithIdx (i)->name);
+ }
+ }
+
+ if (IFFUNC_ISCRITICAL (sym->type))
+ emitcode ("sti", "");
+
+ if (options.debug && currFunc) {
+ debugFile->writeEndFunction (currFunc, ic, 1);
+ }
+
+ if (IFFUNC_ISISR (sym->type)) {
+ emitcode ("rti", "");
+ }
+ else {
+ emitcode ("ret", "");
+ }
}
static void
genRet (iCode * ic)
{
- int size, offset = 0;
-
- /* if we have no return value then
- just generate the "ret" */
- if (!IC_LEFT (ic))
- goto jumpret;
-
- /* we have something to return then
- move the return value into place */
- aopOp (IC_LEFT (ic), ic, FALSE);
- size = AOP_SIZE (IC_LEFT (ic));
-
- while (size--) {
- if (AOP_TYPE (IC_LEFT (ic)) == AOP_LIT) {
- emitcode ("ldi", "%s,%s(%d)", fAVRReturn[offset],
- larray[offset],
- (int) floatFromVal (AOP (IC_LEFT (ic))->
- aopu.aop_lit), offset);
- }
- else {
- char *l;
- l = aopGet (AOP (IC_LEFT (ic)), offset);
- if (strcmp (fAVRReturn[offset], l))
- emitcode ("mov", "%s,%s", fAVRReturn[offset],
- l);
- }
- offset++;
- }
-
- freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
+ int size, offset = 0;
+
+ /* if we have no return value then
+ just generate the "ret" */
+ if (!IC_LEFT (ic))
+ goto jumpret;
+
+ /* we have something to return then
+ move the return value into place */
+ aopOp (IC_LEFT (ic), ic, FALSE);
+ size = AOP_SIZE (IC_LEFT (ic));
+
+ while (size--) {
+ if (AOP_TYPE (IC_LEFT (ic)) == AOP_LIT) {
+ emitcode ("ldi", "%s,%s(%d)", fAVRReturn[offset],
+ larray[offset],
+ (int) ulFromVal (AOP (IC_LEFT (ic))->
+ aopu.aop_lit), offset);
+ }
+ else {
+ char *l;
+ l = aopGet (AOP (IC_LEFT (ic)), offset);
+ if (strcmp (fAVRReturn[offset], l))
+ emitcode ("mov", "%s,%s", fAVRReturn[offset],
+ l);
+ }
+ offset++;
+ }
+
+ freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
jumpret:
- /* generate a jump to the return label
- if the next is not the return statement */
- if (!(ic->next && ic->next->op == LABEL &&
- IC_LABEL (ic->next) == returnLabel))
+ /* generate a jump to the return label
+ if the next is not the return statement */
+ if (!(ic->next && ic->next->op == LABEL &&
+ IC_LABEL (ic->next) == returnLabel))
- emitcode ("rjmp", "L%05d", returnLabel->key);
+ emitcode ("rjmp", "L%05d", returnLabel->key);
}
static void
genLabel (iCode * ic)
{
- /* special case never generate */
- if (IC_LABEL (ic) == entryLabel)
- return;
+ /* special case never generate */
+ if (IC_LABEL (ic) == entryLabel)
+ return;
- emitcode ("", "L%05d:", IC_LABEL (ic)->key);
+ emitcode ("", "L%05d:", IC_LABEL (ic)->key);
}
/*-----------------------------------------------------------------*/
static void
genGoto (iCode * ic)
{
- emitcode ("rjmp", "L%05d", (IC_LABEL (ic)->key));
+ emitcode ("rjmp", "L%05d", (IC_LABEL (ic)->key));
}
/*-----------------------------------------------------------------*/
static bool
genPlusIncr (iCode * ic)
{
- unsigned int icount;
- int offset = 0;
-
- /* will try to generate an increment */
- /* if the right side is not a literal
- we cannot */
- if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT)
- return FALSE;
-
- icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.
- aop_lit);
-
- /* if the sizes are greater than 2 or they are not the same regs
- then we cannot */
- if (!sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))))
- return FALSE;
-
- /* so we know LEFT & RESULT in the same registers and add
- amount <= 63 */
- /* for short & char types */
- if (AOP_SIZE (IC_RESULT (ic)) < 2) {
- if (icount == 1) {
- emitcode ("inc", "%s",
- aopGet (AOP (IC_LEFT (ic)), 0));
- return TRUE;
- }
- if (AOP_ISHIGHREG( AOP (IC_LEFT (ic)),0)) {
- emitcode ("subi", "%s,<(%d)",
- aopGet (AOP (IC_LEFT (ic)), 0), 0-icount);
- return TRUE;
- }
- }
-
- for (offset = 0 ; offset < AOP_SIZE(IC_RESULT(ic)) ; offset++) {
- if (!(AOP_ISHIGHREG(AOP(IC_RESULT(ic)),offset))) return FALSE;
- }
-
- if (AOP_SIZE (IC_RESULT (ic)) <= 3) {
- /* if register pair and starts with 26/30 then adiw */
- if (isRegPair (AOP (IC_RESULT (ic))) && icount > 0
- && icount < 64
- && (IS_REGIDX (AOP (IC_RESULT (ic)), R26_IDX) ||
- IS_REGIDX (AOP (IC_RESULT (ic)), R24_IDX) ||
- IS_REGIDX (AOP (IC_RESULT (ic)), R30_IDX))) {
- emitcode ("adiw", "%s,%d",
- aopGet (AOP (IC_RESULT (ic)), 0), icount);
- return TRUE;
- }
-
- /* use subi */
- emitcode ("subi", "%s,<(%d)",
- aopGet (AOP (IC_RESULT (ic)), 0), 0-icount);
- emitcode ("sbci", "%s,>(%d)",
- aopGet (AOP (IC_RESULT (ic)), 1), 0-icount);
- return TRUE;
- }
-
- /* for 32 bit longs */
- emitcode ("subi", "%s,<(%d)", aopGet (AOP (IC_RESULT (ic)), 0),
- 0-icount);
- emitcode ("sbci", "%s,>(%d)", aopGet (AOP (IC_RESULT (ic)), 1),
- 0-icount);
- emitcode ("sbci", "%s,hlo8(%d)", aopGet (AOP (IC_RESULT (ic)), 2),
- 0-icount);
- emitcode ("sbci", "%s,hhi8(%d)", aopGet (AOP (IC_RESULT (ic)), 3),
- 0-icount);
- return TRUE;
+ unsigned int icount;
+ int offset = 0;
+
+ /* will try to generate an increment */
+ /* if the right side is not a literal
+ we cannot */
+ if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT)
+ return FALSE;
+
+ icount = (unsigned int) ulFromVal (AOP (IC_RIGHT (ic))->aopu.
+ aop_lit);
+
+ /* if the sizes are greater than 2 or they are not the same regs
+ then we cannot */
+ if (!sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))))
+ return FALSE;
+
+ /* so we know LEFT & RESULT in the same registers and add
+ amount <= 63 */
+ /* for short & char types */
+ if (AOP_SIZE (IC_RESULT (ic)) < 2) {
+ if (icount == 1) {
+ emitcode ("inc", "%s",
+ aopGet (AOP (IC_LEFT (ic)), 0));
+ return TRUE;
+ }
+ if (AOP_ISHIGHREG( AOP (IC_LEFT (ic)),0)) {
+ emitcode ("subi", "%s,<(%d)",
+ aopGet (AOP (IC_LEFT (ic)), 0), 0-icount);
+ return TRUE;
+ }
+ }
+
+ for (offset = 0 ; offset < AOP_SIZE(IC_RESULT(ic)) ; offset++) {
+ if (!(AOP_ISHIGHREG(AOP(IC_RESULT(ic)),offset))) return FALSE;
+ }
+
+ if (AOP_SIZE (IC_RESULT (ic)) <= 3) {
+ /* if register pair and starts with 26/30 then adiw */
+ if (isRegPair (AOP (IC_RESULT (ic))) && icount > 0
+ && icount < 64
+ && (IS_REGIDX (AOP (IC_RESULT (ic)), R26_IDX) ||
+ IS_REGIDX (AOP (IC_RESULT (ic)), R24_IDX) ||
+ IS_REGIDX (AOP (IC_RESULT (ic)), R30_IDX))) {
+ emitcode ("adiw", "%s,%d",
+ aopGet (AOP (IC_RESULT (ic)), 0), icount);
+ return TRUE;
+ }
+
+ /* use subi */
+ emitcode ("subi", "%s,<(%d)",
+ aopGet (AOP (IC_RESULT (ic)), 0), 0-icount);
+ emitcode ("sbci", "%s,>(%d)",
+ aopGet (AOP (IC_RESULT (ic)), 1), 0-icount);
+ return TRUE;
+ }
+
+ /* for 32 bit longs */
+ emitcode ("subi", "%s,<(%d)", aopGet (AOP (IC_RESULT (ic)), 0),
+ 0-icount);
+ emitcode ("sbci", "%s,>(%d)", aopGet (AOP (IC_RESULT (ic)), 1),
+ 0-icount);
+ emitcode ("sbci", "%s,hlo8(%d)", aopGet (AOP (IC_RESULT (ic)), 2),
+ 0-icount);
+ emitcode ("sbci", "%s,hhi8(%d)", aopGet (AOP (IC_RESULT (ic)), 3),
+ 0-icount);
+ return TRUE;
}
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),
- 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),
- 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);
- }
+ 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),
+ 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),
+ 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);
+ }
}
/*-----------------------------------------------------------------*/
static void
genPlus (iCode * ic)
{
- int size, offset = 0;
- int samer;
- char *l;
-
- /* special cases :- */
-
- aopOp (IC_LEFT (ic), ic, FALSE);
- aopOp (IC_RIGHT (ic), ic, FALSE);
- aopOp (IC_RESULT (ic), ic, TRUE);
-
- /* if I can do an increment instead
- of add then GOOD for ME */
- if (genPlusIncr (ic) == TRUE)
- goto release;
-
- size = getDataSize (IC_RESULT (ic));
- samer = sameRegs (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic)));
-
- while (size--) {
- if (!samer)
- aopPut (AOP (IC_RESULT (ic)),
- aopGet (AOP (IC_LEFT (ic)), offset), offset);
-
- if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT) {
-
- if (offset == 0)
- l = "add";
- else
- l = "adc";
-
- emitcode (l, "%s,%s",
- aopGet (AOP (IC_RESULT (ic)), offset),
- aopGet (AOP (IC_RIGHT (ic)), offset));
- }
- else {
- if (AOP_ISHIGHREG( AOP( IC_RESULT(ic)),offset)) {
- if (offset == 0)
- l = "subi";
- else
- l = "sbci";
-
- emitcode (l, "%s,%s(-%d)",
- aopGet (AOP (IC_RESULT (ic)), offset),
- larray[offset],
- (int) floatFromVal (AOP (IC_RIGHT (ic))->
- aopu.aop_lit));
- } else {
- if (offset == 0)
- l = "add";
- else
- l = "adc";
-
- emitcode (l, "%s,%s",
- aopGet (AOP (IC_RESULT (ic)), offset),
- aopGet (AOP (IC_RIGHT (ic)), offset));
- }
- }
- offset++;
- }
-
- adjustArithmeticResult (ic);
+ int size, offset = 0;
+ int samer;
+ char *l;
+
+ /* special cases :- */
+
+ aopOp (IC_LEFT (ic), ic, FALSE);
+ aopOp (IC_RIGHT (ic), ic, FALSE);
+ aopOp (IC_RESULT (ic), ic, TRUE);
+
+ /* if I can do an increment instead
+ of add then GOOD for ME */
+ if (genPlusIncr (ic) == TRUE)
+ goto release;
+
+ size = getDataSize (IC_RESULT (ic));
+ samer = sameRegs (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic)));
+
+ while (size--) {
+ if (!samer)
+ aopPut (AOP (IC_RESULT (ic)),
+ aopGet (AOP (IC_LEFT (ic)), offset), offset);
+
+ if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT) {
+
+ if (offset == 0)
+ l = "add";
+ else
+ l = "adc";
+
+ emitcode (l, "%s,%s",
+ aopGet (AOP (IC_RESULT (ic)), offset),
+ aopGet (AOP (IC_RIGHT (ic)), offset));
+ }
+ else {
+ if (AOP_ISHIGHREG( AOP( IC_RESULT(ic)),offset)) {
+ if (offset == 0)
+ l = "subi";
+ else
+ l = "sbci";
+
+ emitcode (l, "%s,%s(-%d)",
+ aopGet (AOP (IC_RESULT (ic)), offset),
+ larray[offset],
+ (int) ulFromVal (AOP (IC_RIGHT (ic))->
+ aopu.aop_lit));
+ } else {
+ if (offset == 0)
+ l = "add";
+ else
+ l = "adc";
+
+ emitcode (l, "%s,%s",
+ aopGet (AOP (IC_RESULT (ic)), offset),
+ aopGet (AOP (IC_RIGHT (ic)), offset));
+ }
+ }
+ offset++;
+ }
+
+ adjustArithmeticResult (ic);
release:
- freeAsmop (IC_LEFT (ic), NULL, ic,
- (RESULTONSTACK (ic) ? FALSE : TRUE));
- freeAsmop (IC_RIGHT (ic), NULL, ic,
- (RESULTONSTACK (ic) ? FALSE : TRUE));
- freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+ freeAsmop (IC_LEFT (ic), NULL, ic,
+ (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (IC_RIGHT (ic), NULL, ic,
+ (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
static bool
genMinusDec (iCode * ic)
{
- unsigned int icount;
- int offset ;
-
- /* will try to generate an increment */
- /* if the right side is not a literal
- we cannot */
- if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT)
- return FALSE;
-
- icount =
- (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.
- aop_lit);
-
- /* if the sizes are greater than 2 or they are not the same regs
- then we cannot */
- if (!sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))))
- return FALSE;
-
- /* so we know LEFT & RESULT in the same registers and add
- amount <= 63 */
- /* for short & char types */
- if (AOP_SIZE (IC_RESULT (ic)) < 2) {
- if (icount == 1) {
- emitcode ("dec", "%s",
- aopGet (AOP (IC_LEFT (ic)), 0));
- return TRUE;
- }
- if (AOP_ISHIGHREG( AOP ( IC_LEFT(ic)),0)) {
- emitcode ("subi", "%s,<(%d)",
- aopGet (AOP (IC_LEFT (ic)), 0), icount);
- return TRUE;
- }
- }
-
- for (offset = 0 ; offset < AOP_SIZE(IC_RESULT(ic)) ; offset++) {
- if (!(AOP_ISHIGHREG(AOP(IC_RESULT(ic)),offset))) return FALSE;
- }
-
- if (AOP_SIZE (IC_RESULT (ic)) <= 3) {
- /* if register pair and starts with 26/30 then adiw */
- if (isRegPair (AOP (IC_RESULT (ic))) && icount > 0
- && icount < 64
- && (IS_REGIDX (AOP (IC_RESULT (ic)), R26_IDX) ||
- IS_REGIDX (AOP (IC_RESULT (ic)), R24_IDX) ||
- IS_REGIDX (AOP (IC_RESULT (ic)), R30_IDX))) {
- emitcode ("sbiw", "%s,%d",
- aopGet (AOP (IC_RESULT (ic)), 0), icount);
- return TRUE;
- }
-
- /* use subi */
- emitcode ("subi", "%s,<(%d)",
- aopGet (AOP (IC_RESULT (ic)), 0), icount);
- emitcode ("sbci", "%s,>(%d)",
- aopGet (AOP (IC_RESULT (ic)), 1), icount);
- return TRUE;
- }
- /* for 32 bit longs */
- emitcode ("subi", "%s,<(%d)", aopGet (AOP (IC_RESULT (ic)), 0),
- icount);
- emitcode ("sbci", "%s,>(%d)", aopGet (AOP (IC_RESULT (ic)), 1),
- icount);
- emitcode ("sbci", "%s,hlo8(%d)", aopGet (AOP (IC_RESULT (ic)), 2),
- icount);
- emitcode ("sbci", "%s,hhi8(%d)", aopGet (AOP (IC_RESULT (ic)), 3),
- icount);
- return TRUE;
+ unsigned int icount;
+ int offset ;
+
+ /* will try to generate an increment */
+ /* if the right side is not a literal
+ we cannot */
+ if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT)
+ return FALSE;
+
+ icount =
+ (unsigned int) ulFromVal (AOP (IC_RIGHT (ic))->aopu.
+ aop_lit);
+
+ /* if the sizes are greater than 2 or they are not the same regs
+ then we cannot */
+ if (!sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))))
+ return FALSE;
+
+ /* so we know LEFT & RESULT in the same registers and add
+ amount <= 63 */
+ /* for short & char types */
+ if (AOP_SIZE (IC_RESULT (ic)) < 2) {
+ if (icount == 1) {
+ emitcode ("dec", "%s",
+ aopGet (AOP (IC_LEFT (ic)), 0));
+ return TRUE;
+ }
+ if (AOP_ISHIGHREG( AOP ( IC_LEFT(ic)),0)) {
+ emitcode ("subi", "%s,<(%d)",
+ aopGet (AOP (IC_LEFT (ic)), 0), icount);
+ return TRUE;
+ }
+ }
+
+ for (offset = 0 ; offset < AOP_SIZE(IC_RESULT(ic)) ; offset++) {
+ if (!(AOP_ISHIGHREG(AOP(IC_RESULT(ic)),offset))) return FALSE;
+ }
+
+ if (AOP_SIZE (IC_RESULT (ic)) <= 3) {
+ /* if register pair and starts with 26/30 then adiw */
+ if (isRegPair (AOP (IC_RESULT (ic))) && icount > 0
+ && icount < 64
+ && (IS_REGIDX (AOP (IC_RESULT (ic)), R26_IDX) ||
+ IS_REGIDX (AOP (IC_RESULT (ic)), R24_IDX) ||
+ IS_REGIDX (AOP (IC_RESULT (ic)), R30_IDX))) {
+ emitcode ("sbiw", "%s,%d",
+ aopGet (AOP (IC_RESULT (ic)), 0), icount);
+ return TRUE;
+ }
+
+ /* use subi */
+ emitcode ("subi", "%s,<(%d)",
+ aopGet (AOP (IC_RESULT (ic)), 0), icount);
+ emitcode ("sbci", "%s,>(%d)",
+ aopGet (AOP (IC_RESULT (ic)), 1), icount);
+ return TRUE;
+ }
+ /* for 32 bit longs */
+ emitcode ("subi", "%s,<(%d)", aopGet (AOP (IC_RESULT (ic)), 0),
+ icount);
+ emitcode ("sbci", "%s,>(%d)", aopGet (AOP (IC_RESULT (ic)), 1),
+ icount);
+ emitcode ("sbci", "%s,hlo8(%d)", aopGet (AOP (IC_RESULT (ic)), 2),
+ icount);
+ emitcode ("sbci", "%s,hhi8(%d)", aopGet (AOP (IC_RESULT (ic)), 3),
+ icount);
+ return TRUE;
}
static void
genMinus (iCode * ic)
{
- int size, offset = 0, samer;
- char *l;
-
- aopOp (IC_LEFT (ic), ic, FALSE);
- aopOp (IC_RIGHT (ic), ic, FALSE);
- aopOp (IC_RESULT (ic), ic, TRUE);
-
- /* if I can do an decrement instead
- of subtract then GOOD for ME */
- if (genMinusDec (ic) == TRUE)
- goto release;
-
- size = getDataSize (IC_RESULT (ic));
- samer = sameRegs (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic)));
- while (size--) {
- if (!samer)
- aopPut (AOP (IC_RESULT (ic)),
- aopGet (AOP (IC_LEFT (ic)), offset), offset);
-
- if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT) {
-
- if (offset == 0)
- l = "sub";
- else
- l = "sbc";
-
- emitcode (l, "%s,%s",
- aopGet (AOP (IC_RESULT (ic)), offset),
- aopGet (AOP (IC_RIGHT (ic)), offset));
- }
- else {
- if (AOP_ISHIGHREG(AOP (IC_RESULT (ic)),offset)) {
- if (offset == 0)
- l = "subi";
- else
- l = "sbci";
-
- emitcode (l, "%s,%s(%d)",
- aopGet (AOP (IC_RESULT (ic)), offset),
- larray[offset],
- (int) floatFromVal (AOP (IC_RIGHT (ic))->
- aopu.aop_lit));
- } else {
- if (offset == 0)
- l = "sub";
- else
- l = "sbc";
-
- emitcode (l, "%s,%s",
- aopGet (AOP (IC_RESULT (ic)), offset),
- aopGet (AOP (IC_RIGHT (ic)), offset));
- }
- }
- offset++;
- }
-
- adjustArithmeticResult (ic);
+ int size, offset = 0, samer;
+ char *l;
+
+ aopOp (IC_LEFT (ic), ic, FALSE);
+ aopOp (IC_RIGHT (ic), ic, FALSE);
+ aopOp (IC_RESULT (ic), ic, TRUE);
+
+ /* if I can do an decrement instead
+ of subtract then GOOD for ME */
+ if (genMinusDec (ic) == TRUE)
+ goto release;
+
+ size = getDataSize (IC_RESULT (ic));
+ samer = sameRegs (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic)));
+ while (size--) {
+ if (!samer)
+ aopPut (AOP (IC_RESULT (ic)),
+ aopGet (AOP (IC_LEFT (ic)), offset), offset);
+
+ if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT) {
+
+ if (offset == 0)
+ l = "sub";
+ else
+ l = "sbc";
+
+ emitcode (l, "%s,%s",
+ aopGet (AOP (IC_RESULT (ic)), offset),
+ aopGet (AOP (IC_RIGHT (ic)), offset));
+ }
+ else {
+ if (AOP_ISHIGHREG(AOP (IC_RESULT (ic)),offset)) {
+ if (offset == 0)
+ l = "subi";
+ else
+ l = "sbci";
+
+ emitcode (l, "%s,%s(%d)",
+ aopGet (AOP (IC_RESULT (ic)), offset),
+ larray[offset],
+ (int) ulFromVal (AOP (IC_RIGHT (ic))->
+ aopu.aop_lit));
+ } else {
+ if (offset == 0)
+ l = "sub";
+ else
+ l = "sbc";
+
+ emitcode (l, "%s,%s",
+ aopGet (AOP (IC_RESULT (ic)), offset),
+ aopGet (AOP (IC_RIGHT (ic)), offset));
+ }
+ }
+ offset++;
+ }
+
+ adjustArithmeticResult (ic);
release:
- freeAsmop (IC_LEFT (ic), NULL, ic,
- (RESULTONSTACK (ic) ? FALSE : TRUE));
- freeAsmop (IC_RIGHT (ic), NULL, ic,
- (RESULTONSTACK (ic) ? FALSE : TRUE));
- freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+ freeAsmop (IC_LEFT (ic), NULL, ic,
+ (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (IC_RIGHT (ic), NULL, ic,
+ (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
static void
genMultOneByte (operand * left, operand * right, operand * result)
{
- sym_link *opetype = operandType (result);
- symbol *lbl;
- int size, offset;
-
- /* (if two literals, the value is computed before) */
- /* if one literal, literal on the right */
- if (AOP_TYPE (left) == AOP_LIT) {
- operand *t = right;
- right = left;
- left = t;
- }
-
- size = AOP_SIZE (result);
-
- if (SPEC_USIGN (opetype)) {
- emitcode ("mul", "%s,%s", aopGet (AOP (left), 0),
- aopGet (AOP (right), 0));
- }
- else {
- emitcode ("muls", "%s,%s", aopGet (AOP (left), 0),
- aopGet (AOP (right), 0));
- }
- aopPut (AOP (result), "r0", 0);
- if (size > 1) {
- aopPut (AOP (result), "r1", 1);
- offset = 2;
- size -= 2;
- if (SPEC_USIGN (opetype)) {
- while (size--) {
- aopPut (AOP (result), zero, offset++);
- }
- }
- else {
- if (size) {
- lbl = newiTempLabel (NULL);
- emitcode ("ldi", "r24,0");
- emitcode ("brcc", "L%05d", lbl->key);
- emitcode ("ldi", "r24,0xff)");
- emitcode ("", "L%05d:", lbl->key);
- while (size--)
- aopPut (AOP (result), "r24",
- offset++);
- }
- }
- }
- return;
+ sym_link *opetype = operandType (result);
+ symbol *lbl;
+ int size, offset;
+
+ /* (if two literals, the value is computed before) */
+ /* if one literal, literal on the right */
+ if (AOP_TYPE (left) == AOP_LIT) {
+ operand *t = right;
+ right = left;
+ left = t;
+ }
+
+ size = AOP_SIZE (result);
+
+ if (SPEC_USIGN (opetype)) {
+ emitcode ("mul", "%s,%s", aopGet (AOP (left), 0),
+ aopGet (AOP (right), 0));
+ }
+ else {
+ emitcode ("muls", "%s,%s", aopGet (AOP (left), 0),
+ aopGet (AOP (right), 0));
+ }
+ aopPut (AOP (result), "r0", 0);
+ if (size > 1) {
+ aopPut (AOP (result), "r1", 1);
+ offset = 2;
+ size -= 2;
+ if (SPEC_USIGN (opetype)) {
+ while (size--) {
+ aopPut (AOP (result), zero, offset++);
+ }
+ }
+ else {
+ if (size) {
+ lbl = newiTempLabel (NULL);
+ emitcode ("ldi", "r24,0");
+ emitcode ("brcc", "L%05d", lbl->key);
+ emitcode ("ldi", "r24,0xff)");
+ emitcode ("", "L%05d:", lbl->key);
+ while (size--)
+ aopPut (AOP (result), "r24",
+ offset++);
+ }
+ }
+ }
+ return;
}
/*-----------------------------------------------------------------*/
static void
genMult (iCode * ic)
{
- operand *left = IC_LEFT (ic);
- operand *right = IC_RIGHT (ic);
- operand *result = IC_RESULT (ic);
-
- /* assign the amsops */
- aopOp (left, ic, FALSE);
- aopOp (right, ic, FALSE);
- aopOp (result, ic, TRUE);
-
- /* if both are of size == 1 */
- if (AOP_SIZE (left) == 1 && AOP_SIZE (right) == 1) {
- genMultOneByte (left, right, result);
- goto release;
- }
+ operand *left = IC_LEFT (ic);
+ operand *right = IC_RIGHT (ic);
+ operand *result = IC_RESULT (ic);
+
+ /* assign the amsops */
+ aopOp (left, ic, FALSE);
+ aopOp (right, ic, FALSE);
+ aopOp (result, ic, TRUE);
+
+ /* if both are of size == 1 */
+ if (AOP_SIZE (left) == 1 && AOP_SIZE (right) == 1) {
+ genMultOneByte (left, right, result);
+ goto release;
+ }
- /* should have been converted to function call */
- assert (0);
+ /* should have been converted to function call */
+ assert (0);
release:
- freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
- freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
- freeAsmop (result, NULL, ic, TRUE);
+ freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (result, NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
static void
genDiv (iCode * ic)
{
- /* should have been converted to function call */
- assert (0);
+ /* should have been converted to function call */
+ assert (0);
}
/*-----------------------------------------------------------------*/
static void
genMod (iCode * ic)
{
- /* should have been converted to function call */
- assert (0);
+ /* should have been converted to function call */
+ assert (0);
}
enum {
- AVR_EQ = 0,
- AVR_NE,
- AVR_LT,
- AVR_GE
+ AVR_EQ = 0,
+ AVR_NE,
+ AVR_LT,
+ AVR_GE
};
/*-----------------------------------------------------------------*/
static int
revavrcnd (int type)
{
- static struct {
- int type, rtype;
- } rar[] = {
- {
- AVR_EQ, AVR_NE}
- , {
- AVR_LT, AVR_GE}
- };
- int i;
-
- for (i = 0; i < (sizeof (rar) / sizeof (rar[0])); i++) {
- if (rar[i].type == type)
- return rar[i].rtype;
- if (rar[i].rtype == type)
- return rar[i].type;
- }
- assert (0); /* cannot happen */
- return 0; /* makes the compiler happy */
+ static struct {
+ int type, rtype;
+ } rar[] = {
+ {
+ AVR_EQ, AVR_NE}
+ , {
+ AVR_LT, AVR_GE}
+ };
+ int i;
+
+ for (i = 0; i < (sizeof (rar) / sizeof (rar[0])); i++) {
+ if (rar[i].type == type)
+ return rar[i].rtype;
+ if (rar[i].rtype == type)
+ return rar[i].type;
+ }
+ assert (0); /* cannot happen */
+ return 0; /* makes the compiler happy */
}
static char *br_name[4] = { "breq", "brne", "brlt", "brge" };
static void
genBranch (iCode * ifx, int br_type, int sign)
{
- int tj = (IC_TRUE (ifx) ? 1 : 0);
-
- if (tj) { /* if true jump */
- char *nm = (sign ? br_name[br_type] : br_uname[br_type]);
- emitcode (nm, "L%05d", IC_TRUE (ifx)->key);
- }
- else { /* if false jump */
- int rtype = revavrcnd (br_type);
- char *nm = (sign ? br_name[rtype] : br_uname[rtype]);
- emitcode (nm, "L%05d", IC_FALSE (ifx)->key);
- }
- ifx->generated = 1;
+ int tj = (IC_TRUE (ifx) ? 1 : 0);
+
+ if (tj) { /* if true jump */
+ char *nm = (sign ? br_name[br_type] : br_uname[br_type]);
+ emitcode (nm, "L%05d", IC_TRUE (ifx)->key);
+ }
+ else { /* if false jump */
+ int rtype = revavrcnd (br_type);
+ char *nm = (sign ? br_name[rtype] : br_uname[rtype]);
+ emitcode (nm, "L%05d", IC_FALSE (ifx)->key);
+ }
+ ifx->generated = 1;
}
/*-----------------------------------------------------------------*/
static void
genCmp (iCode * ic, iCode * ifx, int br_type)
{
- operand *left, *right, *result;
- sym_link *letype, *retype;
- symbol *lbl;
- int sign, size, offset = 0;
-
- left = IC_LEFT (ic);
- right = IC_RIGHT (ic);
- result = IC_RESULT (ic);
-
- letype = getSpec (operandType (left));
- retype = getSpec (operandType (right));
- sign = !(SPEC_USIGN (letype) | SPEC_USIGN (retype));
-
- /* assign the amsops */
- aopOp (left, ic, FALSE);
- aopOp (right, ic, FALSE);
- aopOp (result, ic, TRUE);
- size = AOP_SIZE (left);
-
- if (ifx) {
- if (size == 1) {
- if (AOP_TYPE (right) == AOP_LIT) {
- emitcode ("cpi", "%s,<(%d)",
- aopGet (AOP (left), 0),
- (int)
- floatFromVal (AOP (IC_RIGHT (ic))->
- aopu.aop_lit));
- genBranch (ifx, br_type, sign);
- }
- else { /* right != literal */
- emitcode ("cp", "%s,%s",
- aopGet (AOP (left), 0),
- aopGet (AOP (right), 0));
- genBranch (ifx, br_type, sign);
- }
- }
- else { /* size != 1 */
- while (size--) {
- if (offset == 0)
- emitcode ("cp", "%s,%s",
- aopGet (AOP (left), 0),
- aopGet (AOP (right), 0));
- else
- emitcode ("cpc", "%s,%s",
- aopGet (AOP (left), offset),
- aopGet (AOP (right),
- offset));
- offset++;
- }
- genBranch (ifx, br_type, sign);
- }
- }
- else { /* no ifx */
- emitcode ("clr", "r0");
- while (size--) {
- if (offset == 0)
- emitcode ("cp", "%s,%s",
- aopGet (AOP (left), 0),
- aopGet (AOP (right), 0));
- else
- emitcode ("cpc", "%s,%s",
- aopGet (AOP (left), offset),
- aopGet (AOP (right), offset));
- offset++;
- }
- lbl = newiTempLabel (NULL);
- br_type = revavrcnd (br_type);
- if (sign)
- emitcode (br_uname[br_type], "L%05d", lbl->key);
- else
- emitcode (br_name[br_type], "L%05d", lbl->key);
- emitcode ("inc", "r0");
- emitcode ("", "L%05d:", lbl->key);
- aopPut (AOP (result), "r0", 0);
- size = AOP_SIZE (result) - 1;
- offset = 1;
- while (size--)
- aopPut (AOP (result), zero, offset++);
- }
-
- freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
- freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
- freeAsmop (result, NULL, ic, TRUE);
+ operand *left, *right, *result;
+ sym_link *letype, *retype;
+ symbol *lbl;
+ int sign, size, offset = 0;
+
+ left = IC_LEFT (ic);
+ right = IC_RIGHT (ic);
+ result = IC_RESULT (ic);
+
+ letype = getSpec (operandType (left));
+ retype = getSpec (operandType (right));
+ sign = !(SPEC_USIGN (letype) | SPEC_USIGN (retype));
+
+ /* assign the amsops */
+ aopOp (left, ic, FALSE);
+ aopOp (right, ic, FALSE);
+ aopOp (result, ic, TRUE);
+ size = AOP_SIZE (left);
+
+ if (ifx) {
+ if (size == 1) {
+ if (AOP_TYPE (right) == AOP_LIT) {
+ emitcode ("cpi", "%s,<(%d)",
+ aopGet (AOP (left), 0),
+ (int) ulFromVal (AOP (IC_RIGHT (ic))->
+ aopu.aop_lit));
+ genBranch (ifx, br_type, sign);
+ }
+ else { /* right != literal */
+ emitcode ("cp", "%s,%s",
+ aopGet (AOP (left), 0),
+ aopGet (AOP (right), 0));
+ genBranch (ifx, br_type, sign);
+ }
+ }
+ else { /* size != 1 */
+ while (size--) {
+ if (offset == 0)
+ emitcode ("cp", "%s,%s",
+ aopGet (AOP (left), 0),
+ aopGet (AOP (right), 0));
+ else
+ emitcode ("cpc", "%s,%s",
+ aopGet (AOP (left), offset),
+ aopGet (AOP (right),
+ offset));
+ offset++;
+ }
+ genBranch (ifx, br_type, sign);
+ }
+ }
+ else { /* no ifx */
+ emitcode ("clr", "r0");
+ while (size--) {
+ if (offset == 0)
+ emitcode ("cp", "%s,%s",
+ aopGet (AOP (left), 0),
+ aopGet (AOP (right), 0));
+ else
+ emitcode ("cpc", "%s,%s",
+ aopGet (AOP (left), offset),
+ aopGet (AOP (right), offset));
+ offset++;
+ }
+ lbl = newiTempLabel (NULL);
+ br_type = revavrcnd (br_type);
+ if (sign)
+ emitcode (br_uname[br_type], "L%05d", lbl->key);
+ else
+ emitcode (br_name[br_type], "L%05d", lbl->key);
+ emitcode ("inc", "r0");
+ emitcode ("", "L%05d:", lbl->key);
+ aopPut (AOP (result), "r0", 0);
+ size = AOP_SIZE (result) - 1;
+ offset = 1;
+ while (size--)
+ aopPut (AOP (result), zero, offset++);
+ }
+
+ freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (result, NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
static void
genCmpGt (iCode * ic, iCode * ifx)
{
- /* should have transformed by the parser */
- assert (0);
+ /* should have transformed by the parser */
+ assert (0);
}
/*-----------------------------------------------------------------*/
static void
genCmpLt (iCode * ic, iCode * ifx)
{
- genCmp (ic, ifx, AVR_LT);
+ genCmp (ic, ifx, AVR_LT);
}
/*-----------------------------------------------------------------*/
static void
genCmpEq (iCode * ic, iCode * ifx)
{
- genCmp (ic, ifx, AVR_EQ);
+ genCmp (ic, ifx, AVR_EQ);
}
/*-----------------------------------------------------------------*/
static void
genCmpNe (iCode * ic, iCode * ifx)
{
- genCmp (ic, ifx, AVR_NE);
+ genCmp (ic, ifx, AVR_NE);
}
/*-----------------------------------------------------------------*/
static void
genCmpGe (iCode * ic, iCode * ifx)
{
- genCmp (ic, ifx, AVR_GE);
+ genCmp (ic, ifx, AVR_GE);
}
/*-----------------------------------------------------------------*/
static void
genCmpLe (iCode * ic, iCode * ifx)
{
- operand *left = IC_LEFT (ic);
- operand *right = IC_RIGHT (ic);
+ operand *left = IC_LEFT (ic);
+ operand *right = IC_RIGHT (ic);
- IC_RIGHT (ic) = left;
- IC_LEFT (ic) = right;
- genCmp (ic, ifx, AVR_GE);
+ IC_RIGHT (ic) = left;
+ IC_LEFT (ic) = right;
+ genCmp (ic, ifx, AVR_GE);
}
/*-----------------------------------------------------------------*/
static iCode *
ifxForOp (operand * op, iCode * ic)
{
- /* if true symbol then needs to be assigned */
- if (IS_TRUE_SYMOP (op))
- return NULL;
-
- /* if this has register type condition and
- the next instruction is ifx with the same operand
- and live to of the operand is upto the ifx only then */
- if (ic->next &&
- ic->next->op == IFX &&
- IC_COND (ic->next)->key == op->key &&
- OP_SYMBOL (op)->liveTo <= ic->next->seq) return ic->next;
-
- return NULL;
+ /* if true symbol then needs to be assigned */
+ if (IS_TRUE_SYMOP (op))
+ return NULL;
+
+ /* if this has register type condition and
+ the next instruction is ifx with the same operand
+ and live to of the operand is upto the ifx only then */
+ if (ic->next &&
+ ic->next->op == IFX &&
+ IC_COND (ic->next)->key == op->key &&
+ OP_SYMBOL (op)->liveTo <= ic->next->seq) return ic->next;
+
+ return NULL;
}
/*-----------------------------------------------------------------*/
static void
genAndOp (iCode * ic)
{
- operand *left, *right, *result;
- symbol *tlbl;
- int size, offset;
-
- /* note here that && operations that are in an
- if statement are taken away by backPatchLabels
- only those used in arthmetic operations remain */
- aopOp ((left = IC_LEFT (ic)), ic, FALSE);
- aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
- aopOp ((result = IC_RESULT (ic)), ic, FALSE);
-
- tlbl = newiTempLabel (NULL);
- toBoolean (left, "r0", TRUE);
- toBoolean (right, "r1", TRUE);
- emitcode ("and", "r0,r1");
- emitcode ("ldi", "r24,1");
- emitcode ("breq", "L%05d", tlbl->key);
- emitcode ("dec", "r24");
- emitcode ("", "L%05d:", tlbl->key);
- aopPut (AOP (result), "r24", 0);
- size = AOP_SIZE (result) - 1;
- offset = 1;
- while (size--)
- aopPut (AOP (result), zero, offset++);
-
- freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
- freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
- freeAsmop (result, NULL, ic, TRUE);
+ operand *left, *right, *result;
+ symbol *tlbl;
+ int size, offset;
+
+ /* note here that && operations that are in an
+ if statement are taken away by backPatchLabels
+ only those used in arthmetic operations remain */
+ aopOp ((left = IC_LEFT (ic)), ic, FALSE);
+ aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
+ aopOp ((result = IC_RESULT (ic)), ic, FALSE);
+
+ tlbl = newiTempLabel (NULL);
+ toBoolean (left, "r0", TRUE);
+ toBoolean (right, "r1", TRUE);
+ emitcode ("and", "r0,r1");
+ emitcode ("ldi", "r24,1");
+ emitcode ("breq", "L%05d", tlbl->key);
+ emitcode ("dec", "r24");
+ emitcode ("", "L%05d:", tlbl->key);
+ aopPut (AOP (result), "r24", 0);
+ size = AOP_SIZE (result) - 1;
+ offset = 1;
+ while (size--)
+ aopPut (AOP (result), zero, offset++);
+
+ freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (result, NULL, ic, TRUE);
}
static void
genOrOp (iCode * ic)
{
- operand *left, *right, *result;
- symbol *tlbl;
- int size, offset;
-
- /* note here that || operations that are in an
- if statement are taken away by backPatchLabels
- only those used in arthmetic operations remain */
- aopOp ((left = IC_LEFT (ic)), ic, FALSE);
- aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
- aopOp ((result = IC_RESULT (ic)), ic, FALSE);
-
- tlbl = newiTempLabel (NULL);
- toBoolean (left, "r0", TRUE);
- toBoolean (right, "r0", FALSE);
- emitcode ("ldi", "r24,1");
- emitcode ("breq", "L%05d", tlbl->key);
- emitcode ("dec", "r24");
- emitcode ("", "L%05d:", tlbl->key);
- aopPut (AOP (result), "r24", 0);
- size = AOP_SIZE (result) - 1;
- offset = 1;
- while (size--)
- aopPut (AOP (result), zero, offset++);
-
- freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
- freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
- freeAsmop (result, NULL, ic, TRUE);
+ operand *left, *right, *result;
+ symbol *tlbl;
+ int size, offset;
+
+ /* note here that || operations that are in an
+ if statement are taken away by backPatchLabels
+ only those used in arthmetic operations remain */
+ aopOp ((left = IC_LEFT (ic)), ic, FALSE);
+ aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
+ aopOp ((result = IC_RESULT (ic)), ic, FALSE);
+
+ tlbl = newiTempLabel (NULL);
+ toBoolean (left, "r0", TRUE);
+ toBoolean (right, "r0", FALSE);
+ emitcode ("ldi", "r24,1");
+ emitcode ("breq", "L%05d", tlbl->key);
+ emitcode ("dec", "r24");
+ emitcode ("", "L%05d:", tlbl->key);
+ aopPut (AOP (result), "r24", 0);
+ size = AOP_SIZE (result) - 1;
+ offset = 1;
+ while (size--)
+ aopPut (AOP (result), zero, offset++);
+
+ freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (result, NULL, ic, TRUE);
}
enum {
- AVR_AND = 0, AVR_OR, AVR_XOR
+ AVR_AND = 0, AVR_OR, AVR_XOR
};
static char *bopnames_lit[] = { "andi", "ori" };
static char *bopnames[] = { "and", "or", "eor" };
static void
genBitWise (iCode * ic, iCode * ifx, int bitop)
{
- operand *left, *right, *result;
- int size, offset = 0;
- char *l;
- symbol *lbl, *lbl1;
- int samerl, samerr;
-
- aopOp ((left = IC_LEFT (ic)), ic, FALSE);
- aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
- aopOp ((result = IC_RESULT (ic)), ic, TRUE);
-
- size = AOP_SIZE (left);
- offset = 0;
- if (ifx) { /* used only for jumps */
- if (AOP_TYPE (right) == AOP_LIT &&
- (bitop == AVR_AND || bitop == AVR_OR)) {
- int lit =
- (int) floatFromVal (AOP (right)->aopu.
- aop_lit);
- int p2 = powof2 (lit);
- if (bitop == AVR_AND && (p2 >= 0)) { /* right side is a power of 2 */
- l = aopGet (AOP (left), p2 / 8);
- if (IC_TRUE (ifx)) {
- emitcode ("sbrc", "%s,%d", l,
- (p2 % 8));
- emitcode ("rjmp", "L%05d",
- IC_TRUE (ifx)->key);
- }
- else {
- emitcode ("sbrs", "%s,%d", l,
- (p2 % 8));
- emitcode ("rjmp", "L%05d",
- IC_FALSE (ifx)->key);
- }
- }
- else { /* right not power of two */
- int eh = OP_SYMBOL (left)->liveTo <= ic->seq;
- if (size == 1) {
- if (eh && AOP_ISHIGHREG(AOP(IC_LEFT(ic)),0)) {
- emitcode (bopnames_lit[bitop],
- "%s,<(%d)",
- aopGet (AOP (IC_LEFT (ic)), 0), lit);
- }
- else {
- MOVR24 (aopGet (AOP (IC_LEFT (ic)), 0));
- emitcode (bopnames_lit[bitop], "r24,<(%d)", lit);
- }
- lbl = newiTempLabel (NULL);
- if (IC_TRUE (ifx)) {
- emitcode ("breq", "L%05d", lbl->key);
- emitcode ("rjmp", "L%05d", IC_TRUE (ifx)->key);
- }
- else {
- emitcode ("brne", "L%05d", lbl->key);
- emitcode ("rjmp", "L%05d", IC_FALSE (ifx)-> key);
- }
- emitcode ("", "L%05d:", lbl->key);
- }
- else if (size == 2) {
- emitcode ("mov", "r24,%s", aopGet (AOP (IC_LEFT (ic)), 0));
- emitcode ("mov", "r25,%s", aopGet (AOP (IC_LEFT (ic)), 1));
- emitcode (bopnames_lit[bitop], "r24,<(%d)", lit);
- emitcode (bopnames_lit[bitop], "r25,>(%d)", lit);
- emitcode ("sbiw", "r24,0");
- lbl = newiTempLabel (NULL);
- if (IC_TRUE (ifx)) {
- emitcode ("breq", "L%05d", lbl->key);
- emitcode ("rjmp", "L%05d", IC_TRUE (ifx)->key);
- }
- else {
- emitcode ("brne", "L%05d", lbl->key);
- emitcode ("rjmp", "L%05d", IC_FALSE (ifx)->key);
- }
- emitcode ("", "L%05d:", lbl->key);
- }
- else {
- lbl = newiTempLabel (NULL);
- lbl1 = newiTempLabel (NULL);
- while (size--) {
- if (eh && AOP_ISHIGHREG(AOP(IC_LEFT(ic)),offset)) {
- emitcode (bopnames_lit [bitop], "%s,<(%d)",
- aopGet (AOP (IC_LEFT (ic)), offset),
- lit);
- }
- else {
- char *l = aopGet (AOP (IC_LEFT (ic)), offset);
- MOVR24 (l);
- emitcode ("andi", "r24,<(%d)", lit);
- }
- emitcode ("brne", "L%05d", lbl->key);
- offset++;
- }
- /* all are zero */
- if (IC_FALSE (ifx))
- emitcode ("rjmp", "L%05d", IC_FALSE (ifx)-> key);
- else
- emitcode ("rjmp", "L%05d", lbl1->key);
- emitcode ("", "L%05d:", lbl->key);
- /* not zero */
- if (IC_TRUE (ifx))
- emitcode ("rjmp", "L%05d", IC_TRUE (ifx)->key);
- emitcode ("", "L%05d:", lbl1->key);
-
- }
- }
- }
- else { /* right is not a literal */
- int eh = OP_SYMBOL (left)->liveTo <= ic->seq;
- int reh = OP_SYMBOL (right)->liveTo <= ic->seq;
- if (size == 1) {
- if (eh) {
- emitcode (bopnames[bitop], "%s,%s", aopGet (AOP (IC_LEFT (ic)), 0),
- aopGet (AOP (IC_RIGHT (ic)), 0));
- }
- else if (reh) {
- emitcode (bopnames[bitop], "%s,%s",
- aopGet (AOP (IC_RIGHT (ic)), 0),
- aopGet (AOP (IC_LEFT (ic)), 0));
- }
- else {
- MOVR0 (aopGet (AOP (IC_LEFT (ic)), 0));
- emitcode (bopnames[bitop], "r0,%s",
- aopGet (AOP (IC_RIGHT (ic)), 0));
- }
- lbl = newiTempLabel (NULL);
- if (IC_TRUE (ifx)) {
- emitcode ("breq", "L%05d", lbl->key);
- emitcode ("rjmp", "L%05d",
- IC_TRUE (ifx)->key);
- }
- else {
- emitcode ("brne", "L%05d", lbl->key);
- emitcode ("rjmp", "L%05d",
- IC_FALSE (ifx)->key);
- }
- emitcode ("", "L%05d:", lbl->key);
- }
- else if (size == 2) {
- emitcode ("mov", "r24,%s",
- aopGet (AOP (IC_LEFT (ic)), 0));
- emitcode ("mov", "r25,%s",
- aopGet (AOP (IC_LEFT (ic)), 1));
- emitcode (bopnames[bitop], "r24,%s",
- aopGet (AOP (IC_RIGHT (ic)), 0));
- emitcode (bopnames[bitop], "r25,%s",
- aopGet (AOP (IC_RIGHT (ic)), 1));
- emitcode ("sbiw", "r24,0");
- lbl = newiTempLabel (NULL);
- if (IC_TRUE (ifx)) {
- emitcode ("breq", "L%05d", lbl->key);
- emitcode ("rjmp", "L%05d", IC_TRUE (ifx)->key);
- }
- else {
- emitcode ("brne", "L%05d", lbl->key);
- emitcode ("rjmp", "L%05d", IC_FALSE (ifx)->key);
- }
- emitcode ("", "L%05d:", lbl->key);
- }
- else {
- lbl = newiTempLabel (NULL);
- lbl1 = newiTempLabel (NULL);
- while (size--) {
- if (eh) {
- emitcode (bopnames[bitop], "%s,%s",
- aopGet (AOP (IC_LEFT (ic)), offset),
- aopGet (AOP (IC_RIGHT (ic)), offset));
- }
- else if (reh) {
- emitcode (bopnames[bitop], "%s,%s",
- aopGet (AOP (IC_RIGHT (ic)), offset),
- aopGet (AOP (IC_LEFT (ic)), offset));
- }
- else {
- MOVR0 (aopGet (AOP (IC_LEFT (ic)), offset));
- emitcode (bopnames[bitop], "r0,%s",
- aopGet (AOP (IC_RIGHT (ic)), offset));
- }
- emitcode ("brne", "L%05d", lbl->key);
- offset++;
- }
- /* all are zero */
- if (IC_FALSE (ifx))
- emitcode ("rjmp", "L%05d", IC_FALSE (ifx)->key);
- else
- emitcode ("rjmp", "L%05d", lbl1->key);
- emitcode ("", "L%05d:", lbl->key);
- /* not zero */
- if (IC_TRUE (ifx))
- emitcode ("rjmp", "L%05d", IC_TRUE (ifx)->key);
- emitcode ("", "L%05d:", lbl1->key);
-
- }
- }
- goto release;
- }
-
- /* result needs to go a register */
- samerl = sameRegs (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic)));
- samerr = sameRegs (AOP (IC_RESULT (ic)), AOP (IC_RIGHT (ic)));
- while (size--) {
- if (AOP_TYPE (right) == AOP_LIT) {
- unsigned int lit =
- (int) floatFromVal (AOP (right)->aopu.
- aop_lit);
- if (((lit >> (8 * offset)) & 0xff) == 0) {
- if (bitop == AVR_AND) {
- aopPut (AOP (result), zero, offset++);
- continue;
- }
- else if (bitop == AVR_OR) {
- if (!samerl)
- aopPut (AOP (result),
- aopGet (AOP (left),
- offset),
- offset);
- offset++;
- continue;
- }
- }
- }
- if (samerl) {
- if (AOP_TYPE (IC_RIGHT (ic)) == AOP_LIT &&
- AOP_ISHIGHREG(AOP(IC_LEFT(ic)),offset) &&
- (bitop == AVR_AND || bitop == AVR_OR)) {
- emitcode (bopnames_lit[bitop], "%s,%s(%d)",
- aopGet (AOP (IC_LEFT (ic)), offset),
- larray[offset],
- (int) floatFromVal (AOP (right)-> aopu.aop_lit));
- }
- else {
- emitcode (bopnames[bitop], "%s,%s",
- aopGet (AOP (IC_LEFT (ic)), offset),
- aopGet (AOP (IC_RIGHT (ic)), offset));
- }
- }
- else if (samerr) {
- emitcode (bopnames[bitop], "%s,%s",
- aopGet (AOP (IC_RIGHT (ic)), offset),
- aopGet (AOP (IC_LEFT (ic)), offset));
- }
- else {
- aopPut (AOP (IC_RESULT (ic)),
- aopGet (AOP (IC_LEFT (ic)), offset), offset);
- emitcode (bopnames[bitop],
- aopGet (AOP (IC_RESULT (ic)), offset),
- aopGet (AOP (IC_RIGHT (ic)), offset));
- }
- offset++;
- }
+ operand *left, *right, *result;
+ int size, offset = 0;
+ char *l;
+ symbol *lbl, *lbl1;
+ int samerl, samerr;
+
+ aopOp ((left = IC_LEFT (ic)), ic, FALSE);
+ aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
+ aopOp ((result = IC_RESULT (ic)), ic, TRUE);
+
+ size = AOP_SIZE (left);
+ offset = 0;
+ if (ifx) { /* used only for jumps */
+ if (AOP_TYPE (right) == AOP_LIT &&
+ (bitop == AVR_AND || bitop == AVR_OR)) {
+ int lit =
+ (int) ulFromVal (AOP (right)->aopu.
+ aop_lit);
+ int p2 = powof2 (lit);
+ if (bitop == AVR_AND && (p2 >= 0)) { /* right side is a power of 2 */
+ l = aopGet (AOP (left), p2 / 8);
+ if (IC_TRUE (ifx)) {
+ emitcode ("sbrc", "%s,%d", l,
+ (p2 % 8));
+ emitcode ("rjmp", "L%05d",
+ IC_TRUE (ifx)->key);
+ }
+ else {
+ emitcode ("sbrs", "%s,%d", l,
+ (p2 % 8));
+ emitcode ("rjmp", "L%05d",
+ IC_FALSE (ifx)->key);
+ }
+ }
+ else { /* right not power of two */
+ int eh = OP_SYMBOL (left)->liveTo <= ic->seq;
+ if (size == 1) {
+ if (eh && AOP_ISHIGHREG(AOP(IC_LEFT(ic)),0)) {
+ emitcode (bopnames_lit[bitop],
+ "%s,<(%d)",
+ aopGet (AOP (IC_LEFT (ic)), 0), lit);
+ }
+ else {
+ MOVR24 (aopGet (AOP (IC_LEFT (ic)), 0));
+ emitcode (bopnames_lit[bitop], "r24,<(%d)", lit);
+ }
+ lbl = newiTempLabel (NULL);
+ if (IC_TRUE (ifx)) {
+ emitcode ("breq", "L%05d", lbl->key);
+ emitcode ("rjmp", "L%05d", IC_TRUE (ifx)->key);
+ }
+ else {
+ emitcode ("brne", "L%05d", lbl->key);
+ emitcode ("rjmp", "L%05d", IC_FALSE (ifx)-> key);
+ }
+ emitcode ("", "L%05d:", lbl->key);
+ }
+ else if (size == 2) {
+ emitcode ("mov", "r24,%s", aopGet (AOP (IC_LEFT (ic)), 0));
+ emitcode ("mov", "r25,%s", aopGet (AOP (IC_LEFT (ic)), 1));
+ emitcode (bopnames_lit[bitop], "r24,<(%d)", lit);
+ emitcode (bopnames_lit[bitop], "r25,>(%d)", lit);
+ emitcode ("sbiw", "r24,0");
+ lbl = newiTempLabel (NULL);
+ if (IC_TRUE (ifx)) {
+ emitcode ("breq", "L%05d", lbl->key);
+ emitcode ("rjmp", "L%05d", IC_TRUE (ifx)->key);
+ }
+ else {
+ emitcode ("brne", "L%05d", lbl->key);
+ emitcode ("rjmp", "L%05d", IC_FALSE (ifx)->key);
+ }
+ emitcode ("", "L%05d:", lbl->key);
+ }
+ else {
+ lbl = newiTempLabel (NULL);
+ lbl1 = newiTempLabel (NULL);
+ while (size--) {
+ if (eh && AOP_ISHIGHREG(AOP(IC_LEFT(ic)),offset)) {
+ emitcode (bopnames_lit [bitop], "%s,<(%d)",
+ aopGet (AOP (IC_LEFT (ic)), offset),
+ lit);
+ }
+ else {
+ char *l = aopGet (AOP (IC_LEFT (ic)), offset);
+ MOVR24 (l);
+ emitcode ("andi", "r24,<(%d)", lit);
+ }
+ emitcode ("brne", "L%05d", lbl->key);
+ offset++;
+ }
+ /* all are zero */
+ if (IC_FALSE (ifx))
+ emitcode ("rjmp", "L%05d", IC_FALSE (ifx)-> key);
+ else
+ emitcode ("rjmp", "L%05d", lbl1->key);
+ emitcode ("", "L%05d:", lbl->key);
+ /* not zero */
+ if (IC_TRUE (ifx))
+ emitcode ("rjmp", "L%05d", IC_TRUE (ifx)->key);
+ emitcode ("", "L%05d:", lbl1->key);
+
+ }
+ }
+ }
+ else { /* right is not a literal */
+ int eh = OP_SYMBOL (left)->liveTo <= ic->seq;
+ int reh = OP_SYMBOL (right)->liveTo <= ic->seq;
+ if (size == 1) {
+ if (eh) {
+ emitcode (bopnames[bitop], "%s,%s", aopGet (AOP (IC_LEFT (ic)), 0),
+ aopGet (AOP (IC_RIGHT (ic)), 0));
+ }
+ else if (reh) {
+ emitcode (bopnames[bitop], "%s,%s",
+ aopGet (AOP (IC_RIGHT (ic)), 0),
+ aopGet (AOP (IC_LEFT (ic)), 0));
+ }
+ else {
+ MOVR0 (aopGet (AOP (IC_LEFT (ic)), 0));
+ emitcode (bopnames[bitop], "r0,%s",
+ aopGet (AOP (IC_RIGHT (ic)), 0));
+ }
+ lbl = newiTempLabel (NULL);
+ if (IC_TRUE (ifx)) {
+ emitcode ("breq", "L%05d", lbl->key);
+ emitcode ("rjmp", "L%05d",
+ IC_TRUE (ifx)->key);
+ }
+ else {
+ emitcode ("brne", "L%05d", lbl->key);
+ emitcode ("rjmp", "L%05d",
+ IC_FALSE (ifx)->key);
+ }
+ emitcode ("", "L%05d:", lbl->key);
+ }
+ else if (size == 2) {
+ emitcode ("mov", "r24,%s",
+ aopGet (AOP (IC_LEFT (ic)), 0));
+ emitcode ("mov", "r25,%s",
+ aopGet (AOP (IC_LEFT (ic)), 1));
+ emitcode (bopnames[bitop], "r24,%s",
+ aopGet (AOP (IC_RIGHT (ic)), 0));
+ emitcode (bopnames[bitop], "r25,%s",
+ aopGet (AOP (IC_RIGHT (ic)), 1));
+ emitcode ("sbiw", "r24,0");
+ lbl = newiTempLabel (NULL);
+ if (IC_TRUE (ifx)) {
+ emitcode ("breq", "L%05d", lbl->key);
+ emitcode ("rjmp", "L%05d", IC_TRUE (ifx)->key);
+ }
+ else {
+ emitcode ("brne", "L%05d", lbl->key);
+ emitcode ("rjmp", "L%05d", IC_FALSE (ifx)->key);
+ }
+ emitcode ("", "L%05d:", lbl->key);
+ }
+ else {
+ lbl = newiTempLabel (NULL);
+ lbl1 = newiTempLabel (NULL);
+ while (size--) {
+ if (eh) {
+ emitcode (bopnames[bitop], "%s,%s",
+ aopGet (AOP (IC_LEFT (ic)), offset),
+ aopGet (AOP (IC_RIGHT (ic)), offset));
+ }
+ else if (reh) {
+ emitcode (bopnames[bitop], "%s,%s",
+ aopGet (AOP (IC_RIGHT (ic)), offset),
+ aopGet (AOP (IC_LEFT (ic)), offset));
+ }
+ else {
+ MOVR0 (aopGet (AOP (IC_LEFT (ic)), offset));
+ emitcode (bopnames[bitop], "r0,%s",
+ aopGet (AOP (IC_RIGHT (ic)), offset));
+ }
+ emitcode ("brne", "L%05d", lbl->key);
+ offset++;
+ }
+ /* all are zero */
+ if (IC_FALSE (ifx))
+ emitcode ("rjmp", "L%05d", IC_FALSE (ifx)->key);
+ else
+ emitcode ("rjmp", "L%05d", lbl1->key);
+ emitcode ("", "L%05d:", lbl->key);
+ /* not zero */
+ if (IC_TRUE (ifx))
+ emitcode ("rjmp", "L%05d", IC_TRUE (ifx)->key);
+ emitcode ("", "L%05d:", lbl1->key);
+
+ }
+ }
+ goto release;
+ }
+
+ /* result needs to go a register */
+ samerl = sameRegs (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic)));
+ samerr = sameRegs (AOP (IC_RESULT (ic)), AOP (IC_RIGHT (ic)));
+ while (size--) {
+ if (AOP_TYPE (right) == AOP_LIT) {
+ unsigned int lit =
+ (int) ulFromVal (AOP (right)->aopu.
+ aop_lit);
+ if (((lit >> (8 * offset)) & 0xff) == 0) {
+ if (bitop == AVR_AND) {
+ aopPut (AOP (result), zero, offset++);
+ continue;
+ }
+ else if (bitop == AVR_OR) {
+ if (!samerl)
+ aopPut (AOP (result),
+ aopGet (AOP (left),
+ offset),
+ offset);
+ offset++;
+ continue;
+ }
+ }
+ }
+ if (samerl) {
+ if (AOP_TYPE (IC_RIGHT (ic)) == AOP_LIT &&
+ AOP_ISHIGHREG(AOP(IC_LEFT(ic)),offset) &&
+ (bitop == AVR_AND || bitop == AVR_OR)) {
+ emitcode (bopnames_lit[bitop], "%s,%s(%d)",
+ aopGet (AOP (IC_LEFT (ic)), offset),
+ larray[offset],
+ (int) ulFromVal (AOP (right)-> aopu.aop_lit));
+ }
+ else {
+ emitcode (bopnames[bitop], "%s,%s",
+ aopGet (AOP (IC_LEFT (ic)), offset),
+ aopGet (AOP (IC_RIGHT (ic)), offset));
+ }
+ }
+ else if (samerr) {
+ emitcode (bopnames[bitop], "%s,%s",
+ aopGet (AOP (IC_RIGHT (ic)), offset),
+ aopGet (AOP (IC_LEFT (ic)), offset));
+ }
+ else {
+ aopPut (AOP (IC_RESULT (ic)),
+ aopGet (AOP (IC_LEFT (ic)), offset), offset);
+ emitcode (bopnames[bitop],
+ aopGet (AOP (IC_RESULT (ic)), offset),
+ aopGet (AOP (IC_RIGHT (ic)), offset));
+ }
+ offset++;
+ }
release:
- freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
- freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
- freeAsmop (result, NULL, ic, TRUE);
+ freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (result, NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
static void
genAnd (iCode * ic, iCode * ifx)
{
- genBitWise (ic, ifx, AVR_AND);
+ genBitWise (ic, ifx, AVR_AND);
}
/*-----------------------------------------------------------------*/
static void
genOr (iCode * ic, iCode * ifx)
{
- genBitWise (ic, ifx, AVR_OR);
+ genBitWise (ic, ifx, AVR_OR);
}
/*-----------------------------------------------------------------*/
static void
genXor (iCode * ic, iCode * ifx)
{
- genBitWise (ic, ifx, AVR_XOR);
+ genBitWise (ic, ifx, AVR_XOR);
}
/*-----------------------------------------------------------------*/
static void
genRotC (iCode * ic, int lr)
{
- operand *left, *result;
- int size, offset = 0;
-
- /* rotate right with carry */
- left = IC_LEFT (ic);
- result = IC_RESULT (ic);
- aopOp (left, ic, FALSE);
- aopOp (result, ic, FALSE);
-
- /* move it to the result */
- size = AOP_SIZE (result);
- if (!sameRegs (AOP (left), AOP (result))) {
- offset = 0;
- while (size--) {
- aopPut (AOP (result),
- aopGet (AOP (left), offset), offset);
- offset++;
- }
- size = AOP_SIZE (result);
- }
- if (lr)
- offset = size - 1;
- else
- offset = 0;
-
- CLRC;
- emitcode ("sbrc", "%s,%d", aopGet (AOP (result), offset),
- (lr ? 0 : 7));
- emitcode ("sec", "");
-
- while (size--) {
- emitcode ((lr ? "ror" : "rol"), "%s",
- aopGet (AOP (result), offset));
- if (lr)
- offset--;
- else
- offset++;
- }
- freeAsmop (left, NULL, ic, TRUE);
- freeAsmop (result, NULL, ic, TRUE);
+ operand *left, *result;
+ int size, offset = 0;
+
+ /* rotate right with carry */
+ left = IC_LEFT (ic);
+ result = IC_RESULT (ic);
+ aopOp (left, ic, FALSE);
+ aopOp (result, ic, FALSE);
+
+ /* move it to the result */
+ size = AOP_SIZE (result);
+ if (!sameRegs (AOP (left), AOP (result))) {
+ offset = 0;
+ while (size--) {
+ aopPut (AOP (result),
+ aopGet (AOP (left), offset), offset);
+ offset++;
+ }
+ size = AOP_SIZE (result);
+ }
+ if (lr)
+ offset = size - 1;
+ else
+ offset = 0;
+
+ CLRC;
+ emitcode ("sbrc", "%s,%d", aopGet (AOP (result), offset),
+ (lr ? 0 : 7));
+ emitcode ("sec", "");
+
+ while (size--) {
+ emitcode ((lr ? "ror" : "rol"), "%s",
+ aopGet (AOP (result), offset));
+ if (lr)
+ offset--;
+ else
+ offset++;
+ }
+ freeAsmop (left, NULL, ic, TRUE);
+ freeAsmop (result, NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
static void
genRRC (iCode * ic)
{
- genRotC (ic, 1);
+ genRotC (ic, 1);
}
/*-----------------------------------------------------------------*/
static void
genRLC (iCode * ic)
{
- genRotC (ic, 0);
+ genRotC (ic, 0);
}
/*-----------------------------------------------------------------*/
static void
genGetHbit (iCode * ic)
{
- operand *left, *result;
- int size, offset;
-
- left = IC_LEFT (ic);
- result = IC_RESULT (ic);
- aopOp (left, ic, FALSE);
- aopOp (result, ic, FALSE);
-
- size = AOP_SIZE (result);
- if (!sameRegs (AOP (left), AOP (result))) {
- emitcode ("clr", "%s", aopGet (AOP (result), size - 1));
- emitcode ("sbrc", "%s,7", aopGet (AOP (left), size - 1));
- emitcode ("subi", "%s,<(-1)",
- aopGet (AOP (result), size - 1));
- }
- else {
- emitcode ("clr", "r0");
- emitcode ("sbrc", "%s,7", aopGet (AOP (left), size - 1));
- emitcode ("subi", "r0,<(-1)");
- aopPut (AOP (result), "r0", 0);
- }
- offset = 1;
- size--;
- while (size--) {
- emitcode ("clr", aopGet (AOP (result), offset++));
- }
- freeAsmop (left, NULL, ic, TRUE);
- freeAsmop (result, NULL, ic, TRUE);
+ operand *left, *result;
+ int size, offset;
+
+ left = IC_LEFT (ic);
+ result = IC_RESULT (ic);
+ aopOp (left, ic, FALSE);
+ aopOp (result, ic, FALSE);
+
+ size = AOP_SIZE (result);
+ if (!sameRegs (AOP (left), AOP (result))) {
+ emitcode ("clr", "%s", aopGet (AOP (result), size - 1));
+ emitcode ("sbrc", "%s,7", aopGet (AOP (left), size - 1));
+ emitcode ("subi", "%s,<(-1)",
+ aopGet (AOP (result), size - 1));
+ }
+ else {
+ emitcode ("clr", "r0");
+ emitcode ("sbrc", "%s,7", aopGet (AOP (left), size - 1));
+ emitcode ("subi", "r0,<(-1)");
+ aopPut (AOP (result), "r0", 0);
+ }
+ offset = 1;
+ size--;
+ while (size--) {
+ emitcode ("clr", aopGet (AOP (result), offset++));
+ }
+ freeAsmop (left, NULL, ic, TRUE);
+ freeAsmop (result, NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
static void
genShiftLeftLit (iCode * ic)
{
- operand *left, *right, *result;
- int size, shCount, offset = 0;
- int lByteZ = 0;
-
- right = IC_RIGHT (ic);
- left = IC_LEFT (ic);
- result = IC_RESULT (ic);
-
- aopOp (left, ic, FALSE);
- aopOp (result, ic, FALSE);
- size = AOP_SIZE (result);
- shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit);
-
- if (shCount > (size * 8 - 1)) {
- while (size--)
- aopPut (AOP (result), zero, offset++);
- goto release;
- }
- switch (size) {
- case 1:
- if (!sameRegs (AOP (left), AOP (result)))
- aopPut (AOP (result), aopGet (AOP (left), 0), 0);
- if (shCount >= 4) {
- if (AOP_ISHIGHREG(AOP(result),0)) {
- emitcode ("swap", "%s", aopGet (AOP (result), 0));
- emitcode ("andi", "%s,0xf0");
- } else {
- emitcode ("ldi","r24,0xf0");
- emitcode ("swap", "%s", aopGet (AOP (result), 0));
- emitcode ("and", "%s,r24");
- }
- shCount -= 4;
- }
- if (shCount == 1) {
- emitcode ("add", "%s,%s", aopGet (AOP (result), 0),
- aopGet (AOP (result), 0));
- shCount--;
- }
- while (shCount--)
- emitcode ("lsl", "%s", aopGet (AOP (result), 0));
- break;
- case 2:
- if (shCount >= 12) {
- aopPut (AOP (result), aopGet (AOP (left), 0), 1);
- aopPut (AOP (result), zero, 0);
- emitcode ("swap", "%s", aopGet (AOP (result), 1));
- if (AOP_ISHIGHREG(AOP(result),1)) {
- emitcode ("andi", "%s,0xf0", aopGet (AOP (result), 1));
- } else {
- emitcode ("ldi","r24,0xf0");
- emitcode ("and", "%s,r24", aopGet (AOP (result), 1));
- }
- shCount -= 12;
- lByteZ = 1;
- }
- if (shCount >= 8) {
- aopPut (AOP (result), aopGet (AOP (left), 0), 1);
- aopPut (AOP (result), zero, 0);
- shCount -= 8;
- lByteZ = 1;
- }
- if (shCount >= 4) {
- shCount -= 4;
- if (!sameRegs (AOP (left), AOP (result))) {
- aopPut (AOP (result), aopGet (AOP (left), 0),
- 0);
- aopPut (AOP (result), aopGet (AOP (left), 1),
- 1);
- }
- emitcode ("mov", "r24,%s", aopGet (AOP (result), 0));
- emitcode ("andi", "r24,0x0f");
- if (!(AOP_ISHIGHREG(AOP(result),0) && AOP_ISHIGHREG(AOP(result),1))) {
- emitcode("ldi","r25,0xf0");
- }
- emitcode ("swap", "%s", aopGet (AOP (result), 0));
- if (AOP_ISHIGHREG(AOP(result),0)) {
- emitcode ("andi", "%s,0xf0", aopGet (AOP (result), 0));
- } else {
- emitcode ("and", "%s,r25", aopGet (AOP (result), 0));
- }
- emitcode ("swap", "%s", aopGet (AOP (result), 1));
- if (AOP_ISHIGHREG(AOP(result),1)) {
- emitcode ("andi", "%s,0xf0", aopGet (AOP (result), 1));
- } else {
- emitcode ("and", "%s,r25", aopGet (AOP (result), 1));
- }
- emitcode ("or", "%s,r24", aopGet (AOP (result), 1));
- while (shCount--) {
- emitcode ("lsl", "%s", aopGet (AOP (result), 0));
- emitcode ("rol", "%s", aopGet (AOP (result), 1));
- }
- }
- if (!lByteZ && !sameRegs (AOP (result), AOP (left))
- && shCount) {
- offset = 0;
- while (size--) {
- aopPut (AOP (result),
- aopGet (AOP (left), offset), offset);
- offset++;
- }
- }
- while (shCount--) {
- if (lByteZ) {
- emitcode ("lsl", "%s", aopGet (AOP (result), 1));
- }
- else {
- emitcode ("lsl", "%s", aopGet (AOP (result), 0));
- emitcode ("rol", "%s", aopGet (AOP (result), 1));
- }
- }
- break;
- case 3:
- assert ("shifting generic pointer ?\n");
- break;
- case 4:
- /* 32 bits we do only byte boundaries */
- if (shCount >= 24) {
- aopPut (AOP (result), aopGet (AOP (left), 0), 3);
- aopPut (AOP (result), zero, 2);
- aopPut (AOP (result), zero, 1);
- aopPut (AOP (result), zero, 0);
- lByteZ = 3;
- shCount -= 24;
- }
- if (shCount >= 16) {
- aopPut (AOP (result), aopGet (AOP (left), 0), 3);
- aopPut (AOP (result), aopGet (AOP (left), 1), 2);
- aopPut (AOP (result), zero, 1);
- aopPut (AOP (result), zero, 0);
- lByteZ = 2;
- shCount -= 16;
- }
- if (shCount >= 8) {
- aopPut (AOP (result), aopGet (AOP (left), 0), 3);
- aopPut (AOP (result), aopGet (AOP (left), 1), 2);
- aopPut (AOP (result), aopGet (AOP (left), 2), 1);
- aopPut (AOP (result), zero, 0);
- shCount -= 8;
- lByteZ = 1;
- }
- if (!lByteZ && !sameRegs (AOP (left), AOP (right))) {
- offset = 0;
- while (size--) {
- aopPut (AOP (result),
- aopGet (AOP (left), offset), offset);
- offset++;
- }
- offset = 0;
- size = AOP_SIZE (result);
- }
- if (shCount) {
- switch (lByteZ) {
- case 0:
- while (shCount--) {
- emitcode ("lsl", "%s", aopGet (AOP (result), 0));
- emitcode ("rol", "%s", aopGet (AOP (result), 1));
- emitcode ("rol", "%s", aopGet (AOP (result), 2));
- emitcode ("rol", "%s", aopGet (AOP (result), 3));
- }
- break;
- case 1:
- while (shCount--) {
- emitcode ("lsl", "%s", aopGet (AOP (result), 1));
- emitcode ("rol", "%s", aopGet (AOP (result), 2));
- emitcode ("rol", "%s", aopGet (AOP (result), 3));
- }
- break;
- case 2:
- while (shCount--) {
- emitcode ("lsl", "%s", aopGet (AOP (result), 2));
- emitcode ("rol", "%s", aopGet (AOP (result), 3));
- }
- break;
- case 3:
- while (shCount--) {
- emitcode ("lsl", "%s", aopGet (AOP (result), 3));
- }
- break;
- }
- }
- }
+ operand *left, *right, *result;
+ int size, shCount, offset = 0;
+ int lByteZ = 0;
+
+ right = IC_RIGHT (ic);
+ left = IC_LEFT (ic);
+ result = IC_RESULT (ic);
+
+ aopOp (left, ic, FALSE);
+ aopOp (result, ic, FALSE);
+ size = AOP_SIZE (result);
+ shCount = (int) ulFromVal (AOP (right)->aopu.aop_lit);
+
+ if (shCount > (size * 8 - 1)) {
+ while (size--)
+ aopPut (AOP (result), zero, offset++);
+ goto release;
+ }
+ switch (size) {
+ case 1:
+ if (!sameRegs (AOP (left), AOP (result)))
+ aopPut (AOP (result), aopGet (AOP (left), 0), 0);
+ if (shCount >= 4) {
+ if (AOP_ISHIGHREG(AOP(result),0)) {
+ emitcode ("swap", "%s", aopGet (AOP (result), 0));
+ emitcode ("andi", "%s,0xf0");
+ } else {
+ emitcode ("ldi","r24,0xf0");
+ emitcode ("swap", "%s", aopGet (AOP (result), 0));
+ emitcode ("and", "%s,r24");
+ }
+ shCount -= 4;
+ }
+ if (shCount == 1) {
+ emitcode ("add", "%s,%s", aopGet (AOP (result), 0),
+ aopGet (AOP (result), 0));
+ shCount--;
+ }
+ while (shCount--)
+ emitcode ("lsl", "%s", aopGet (AOP (result), 0));
+ break;
+ case 2:
+ if (shCount >= 12) {
+ aopPut (AOP (result), aopGet (AOP (left), 0), 1);
+ aopPut (AOP (result), zero, 0);
+ emitcode ("swap", "%s", aopGet (AOP (result), 1));
+ if (AOP_ISHIGHREG(AOP(result),1)) {
+ emitcode ("andi", "%s,0xf0", aopGet (AOP (result), 1));
+ } else {
+ emitcode ("ldi","r24,0xf0");
+ emitcode ("and", "%s,r24", aopGet (AOP (result), 1));
+ }
+ shCount -= 12;
+ lByteZ = 1;
+ }
+ if (shCount >= 8) {
+ aopPut (AOP (result), aopGet (AOP (left), 0), 1);
+ aopPut (AOP (result), zero, 0);
+ shCount -= 8;
+ lByteZ = 1;
+ }
+ if (shCount >= 4) {
+ shCount -= 4;
+ if (!sameRegs (AOP (left), AOP (result))) {
+ aopPut (AOP (result), aopGet (AOP (left), 0),
+ 0);
+ aopPut (AOP (result), aopGet (AOP (left), 1),
+ 1);
+ }
+ emitcode ("mov", "r24,%s", aopGet (AOP (result), 0));
+ emitcode ("andi", "r24,0x0f");
+ if (!(AOP_ISHIGHREG(AOP(result),0) && AOP_ISHIGHREG(AOP(result),1))) {
+ emitcode("ldi","r25,0xf0");
+ }
+ emitcode ("swap", "%s", aopGet (AOP (result), 0));
+ if (AOP_ISHIGHREG(AOP(result),0)) {
+ emitcode ("andi", "%s,0xf0", aopGet (AOP (result), 0));
+ } else {
+ emitcode ("and", "%s,r25", aopGet (AOP (result), 0));
+ }
+ emitcode ("swap", "%s", aopGet (AOP (result), 1));
+ if (AOP_ISHIGHREG(AOP(result),1)) {
+ emitcode ("andi", "%s,0xf0", aopGet (AOP (result), 1));
+ } else {
+ emitcode ("and", "%s,r25", aopGet (AOP (result), 1));
+ }
+ emitcode ("or", "%s,r24", aopGet (AOP (result), 1));
+ while (shCount--) {
+ emitcode ("lsl", "%s", aopGet (AOP (result), 0));
+ emitcode ("rol", "%s", aopGet (AOP (result), 1));
+ }
+ }
+ if (!lByteZ && !sameRegs (AOP (result), AOP (left))
+ && shCount) {
+ offset = 0;
+ while (size--) {
+ aopPut (AOP (result),
+ aopGet (AOP (left), offset), offset);
+ offset++;
+ }
+ }
+ while (shCount--) {
+ if (lByteZ) {
+ emitcode ("lsl", "%s", aopGet (AOP (result), 1));
+ }
+ else {
+ emitcode ("lsl", "%s", aopGet (AOP (result), 0));
+ emitcode ("rol", "%s", aopGet (AOP (result), 1));
+ }
+ }
+ break;
+ case 3:
+ assert ("shifting generic pointer ?\n");
+ break;
+ case 4:
+ /* 32 bits we do only byte boundaries */
+ if (shCount >= 24) {
+ aopPut (AOP (result), aopGet (AOP (left), 0), 3);
+ aopPut (AOP (result), zero, 2);
+ aopPut (AOP (result), zero, 1);
+ aopPut (AOP (result), zero, 0);
+ lByteZ = 3;
+ shCount -= 24;
+ }
+ if (shCount >= 16) {
+ aopPut (AOP (result), aopGet (AOP (left), 0), 3);
+ aopPut (AOP (result), aopGet (AOP (left), 1), 2);
+ aopPut (AOP (result), zero, 1);
+ aopPut (AOP (result), zero, 0);
+ lByteZ = 2;
+ shCount -= 16;
+ }
+ if (shCount >= 8) {
+ aopPut (AOP (result), aopGet (AOP (left), 0), 3);
+ aopPut (AOP (result), aopGet (AOP (left), 1), 2);
+ aopPut (AOP (result), aopGet (AOP (left), 2), 1);
+ aopPut (AOP (result), zero, 0);
+ shCount -= 8;
+ lByteZ = 1;
+ }
+ if (!lByteZ && !sameRegs (AOP (left), AOP (right))) {
+ offset = 0;
+ while (size--) {
+ aopPut (AOP (result),
+ aopGet (AOP (left), offset), offset);
+ offset++;
+ }
+ offset = 0;
+ size = AOP_SIZE (result);
+ }
+ if (shCount) {
+ switch (lByteZ) {
+ case 0:
+ while (shCount--) {
+ emitcode ("lsl", "%s", aopGet (AOP (result), 0));
+ emitcode ("rol", "%s", aopGet (AOP (result), 1));
+ emitcode ("rol", "%s", aopGet (AOP (result), 2));
+ emitcode ("rol", "%s", aopGet (AOP (result), 3));
+ }
+ break;
+ case 1:
+ while (shCount--) {
+ emitcode ("lsl", "%s", aopGet (AOP (result), 1));
+ emitcode ("rol", "%s", aopGet (AOP (result), 2));
+ emitcode ("rol", "%s", aopGet (AOP (result), 3));
+ }
+ break;
+ case 2:
+ while (shCount--) {
+ emitcode ("lsl", "%s", aopGet (AOP (result), 2));
+ emitcode ("rol", "%s", aopGet (AOP (result), 3));
+ }
+ break;
+ case 3:
+ while (shCount--) {
+ emitcode ("lsl", "%s", aopGet (AOP (result), 3));
+ }
+ break;
+ }
+ }
+ }
release:
- freeAsmop (left, NULL, ic, TRUE);
- freeAsmop (right, NULL, ic, TRUE);
- freeAsmop (result, NULL, ic, TRUE);
+ freeAsmop (left, NULL, ic, TRUE);
+ freeAsmop (right, NULL, ic, TRUE);
+ freeAsmop (result, NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
static void
genLeftShift (iCode * ic)
{
- operand *left, *right, *result;
- int size, offset;
- symbol *tlbl;
-
- right = IC_RIGHT (ic);
- left = IC_LEFT (ic);
- result = IC_RESULT (ic);
-
- aopOp (right, ic, FALSE);
-
- if (AOP_TYPE (right) == AOP_LIT) {
- genShiftLeftLit (ic);
- return;
- }
-
- /* unknown count */
- aopOp (left, ic, FALSE);
- aopOp (result, ic, FALSE);
- size = AOP_SIZE (result);
- offset = 0;
- if (AOP_SIZE (right) > 1) {
- if (isRegPair (AOP (right))) {
- emitcode ("movw", "r24,%s", aopGet (AOP (right), 0));
- }
- else {
- emitcode ("mov", "r24,%s", aopGet (AOP (right), 0));
- emitcode ("mov", "r25,%s", aopGet (AOP (right), 1));
- }
- }
- else {
- emitcode ("mov", "r24,%s", aopGet (AOP (right), 0));
- }
- if (!sameRegs (AOP (left), AOP (result))) {
- while (size--) {
- aopPut (AOP (result), aopGet (AOP (left), offset),
- offset);
- offset++;
- }
- size = AOP_SIZE (result);
- }
- tlbl = newiTempLabel (NULL);
- emitcode ("", "L%05d:", tlbl->key);
- offset = 0;
- while (size--) {
- if (offset)
- emitcode ("rol", "%s", aopGet (AOP (result), offset));
- else
- emitcode ("lsl", "%s", aopGet (AOP (result), 0));
- offset++;
- }
- if (AOP_SIZE (right) > 1)
- emitcode ("sbiw", "r24,1");
- else
- emitcode ("dec", "r24");
- emitcode ("brne", "L%05d", tlbl->key);
-
- freeAsmop (left, NULL, ic, TRUE);
- freeAsmop (right, NULL, ic, TRUE);
- freeAsmop (result, NULL, ic, TRUE);
+ operand *left, *right, *result;
+ int size, offset;
+ symbol *tlbl;
+
+ right = IC_RIGHT (ic);
+ left = IC_LEFT (ic);
+ result = IC_RESULT (ic);
+
+ aopOp (right, ic, FALSE);
+
+ if (AOP_TYPE (right) == AOP_LIT) {
+ genShiftLeftLit (ic);
+ return;
+ }
+
+ /* unknown count */
+ aopOp (left, ic, FALSE);
+ aopOp (result, ic, FALSE);
+ size = AOP_SIZE (result);
+ offset = 0;
+ if (AOP_SIZE (right) > 1) {
+ if (isRegPair (AOP (right))) {
+ emitcode ("movw", "r24,%s", aopGet (AOP (right), 0));
+ }
+ else {
+ emitcode ("mov", "r24,%s", aopGet (AOP (right), 0));
+ emitcode ("mov", "r25,%s", aopGet (AOP (right), 1));
+ }
+ }
+ else {
+ emitcode ("mov", "r24,%s", aopGet (AOP (right), 0));
+ }
+ if (!sameRegs (AOP (left), AOP (result))) {
+ while (size--) {
+ aopPut (AOP (result), aopGet (AOP (left), offset),
+ offset);
+ offset++;
+ }
+ size = AOP_SIZE (result);
+ }
+ tlbl = newiTempLabel (NULL);
+ emitcode ("", "L%05d:", tlbl->key);
+ offset = 0;
+ while (size--) {
+ if (offset)
+ emitcode ("rol", "%s", aopGet (AOP (result), offset));
+ else
+ emitcode ("lsl", "%s", aopGet (AOP (result), 0));
+ offset++;
+ }
+ if (AOP_SIZE (right) > 1)
+ emitcode ("sbiw", "r24,1");
+ else
+ emitcode ("dec", "r24");
+ emitcode ("brne", "L%05d", tlbl->key);
+
+ freeAsmop (left, NULL, ic, TRUE);
+ freeAsmop (right, NULL, ic, TRUE);
+ freeAsmop (result, NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
static void
genShiftRightLit (iCode * ic)
{
- operand *left = IC_LEFT (ic)
- , *right = IC_RIGHT (ic)
- , *result = IC_RESULT (ic);
- int size, shCount, offset = 0;
- int hByteZ = 0;
- sym_link *letype = getSpec (operandType (left));
- int sign = !SPEC_USIGN (letype);
-
- right = IC_RIGHT (ic);
- left = IC_LEFT (ic);
- result = IC_RESULT (ic);
-
- aopOp (left, ic, FALSE);
- aopOp (result, ic, FALSE);
- size = AOP_SIZE (result);
- shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit);
-
- /* if signed then give up and use a loop to shift */
- if (sign) {
- symbol *tlbl;
- if (!sameRegs (AOP (left), AOP (result))) {
- while (size--) {
- aopPut (AOP (result),
- aopGet (AOP (left), offset), offset);
- offset++;
- }
- size = AOP_SIZE (result);
- offset = 0;
- }
- /* be as economical as possible */
- if (shCount <= 4) {
- while (shCount--) {
- size = AOP_SIZE (result);
- offset = size - 1;
- while (size--) {
- /* highest order byte */
- if (offset == (AOP_SIZE(result)-1))
- emitcode ("asr", "%s", aopGet (AOP (result), offset));
- else
- emitcode ("ror", "%s", aopGet (AOP (result), offset));
- offset--;
- }
- }
- }
- else {
- emitcode ("ldi", "r24,<(%d)", shCount);
- tlbl = newiTempLabel (NULL);
- emitcode ("", "L%05d:", tlbl->key);
- offset = size - 1;
- while (size--) {
- if (offset == (AOP_SIZE(result) - 1))
- emitcode ("asr", "%s", aopGet (AOP (result), offset));
- else
- emitcode ("ror", "%s", aopGet (AOP (result), offset));
- offset--;
- }
- emitcode ("dec", "r24");
- emitcode ("brne", "L%05d", tlbl->key);
- }
- goto release;
- }
- if (shCount > (size * 8 - 1)) {
- while (size--)
- aopPut (AOP (result), zero, offset++);
- goto release;
- }
- /* for unsigned we can much more efficient */
- switch (size) {
- case 1:
- if (!sameRegs (AOP (left), AOP (result)))
- aopPut (AOP (result), aopGet (AOP (left), 0), 0);
- if (shCount >= 4) {
- emitcode ("swap", "%s", aopGet (AOP (result), 0));
- if (AOP_ISHIGHREG(AOP(result),0)) {
- emitcode ("andi", "%s,0x0f",aopGet(AOP(result),0));
- } else {
- emitcode ("ldi","r24,0x0f");
- emitcode ("and", "%s,r24",aopGet(AOP(result),0));
- }
- shCount -= 4;
- }
- while (shCount--)
- emitcode ("lsr", "%s", aopGet (AOP (result), 0));
- break;
- case 2:
- if (shCount >= 12) {
- aopPut (AOP (result), aopGet (AOP (left), 1), 0);
- aopPut (AOP (result), zero, 1);
- emitcode ("swap", "%s", aopGet (AOP (result), 0));
- if (AOP_ISHIGHREG(AOP(result),0)) {
- emitcode ("andi", "%s,0x0f", aopGet (AOP (result), 0));
- } else {
- emitcode ("ldi","r24,0x0f");
- emitcode ("and", "%s,r24",aopGet(AOP(result),0));
- }
- shCount -= 12;
- hByteZ = 1;
- }
- if (shCount >= 8) {
- aopPut (AOP (result), aopGet (AOP (left), 1), 0);
- aopPut (AOP (result), zero, 1);
- shCount -= 8;
- hByteZ = 1;
- }
- if (shCount >= 4) {
- shCount -= 4;
- if (!sameRegs (AOP (left), AOP (result))) {
- aopPut (AOP (result), aopGet (AOP (left), 0), 0);
- aopPut (AOP (result), aopGet (AOP (left), 1), 1);
- }
- if (!(AOP_ISHIGHREG(AOP(result),0) && AOP_ISHIGHREG(AOP(result),1))) {
- emitcode("ldi","r25,0x0f");
- }
- emitcode ("mov", "r24,%s", aopGet (AOP (result), 1));
- emitcode ("andi", "r24,0xf0");
- emitcode ("swap", "%s", aopGet (AOP (result), 0));
- if (AOP_ISHIGHREG(AOP(result),0)) {
- emitcode ("andi", "%s,0x0f", aopGet (AOP (result), 0));
- } else {
- emitcode ("and", "%s,r25", aopGet (AOP (result), 0));
- }
- emitcode ("or", "%s,r24", aopGet (AOP (result), 0));
- emitcode ("swap", "%s", aopGet (AOP (result), 1));
- if (AOP_ISHIGHREG(AOP(result),1)) {
- emitcode ("andi", "%s,0x0f", aopGet (AOP (result), 1));
- } else {
- emitcode ("and", "%s,r24", aopGet (AOP (result), 1));
- }
- while (shCount--) {
- emitcode ("lsr", "%s", aopGet (AOP (result), 1));
- emitcode ("ror", "%s", aopGet (AOP (result), 0));
- }
-
- }
- if (!hByteZ && !sameRegs (AOP (result), AOP (left))
- && shCount) {
- offset = 0;
- while (size--) {
- aopPut (AOP (result), aopGet (AOP (left), offset), offset);
- offset++;
- }
- }
- while (shCount--) {
- if (hByteZ) {
- emitcode ("lsr", "%s", aopGet (AOP (result), 0));
- }
- else {
- emitcode ("lsr", "%s", aopGet (AOP (result), 1));
- emitcode ("ror", "%s", aopGet (AOP (result), 0));
- }
- }
- break;
-
- case 3:
- assert ("shifting generic pointer ?\n");
- break;
- case 4:
- /* 32 bits we do only byte boundaries */
- if (shCount >= 24) {
- aopPut (AOP (result), aopGet (AOP (left), 3), 0);
- aopPut (AOP (result), zero, 1);
- aopPut (AOP (result), zero, 2);
- aopPut (AOP (result), zero, 3);
- hByteZ = 3;
- shCount -= 24;
- }
- if (shCount >= 16) {
- aopPut (AOP (result), aopGet (AOP (left), 3), 1);
- aopPut (AOP (result), aopGet (AOP (left), 2), 0);
- aopPut (AOP (result), zero, 2);
- aopPut (AOP (result), zero, 3);
- hByteZ = 2;
- shCount -= 16;
- }
- if (shCount >= 8) {
- aopPut (AOP (result), aopGet (AOP (left), 1), 0);
- aopPut (AOP (result), aopGet (AOP (left), 2), 1);
- aopPut (AOP (result), aopGet (AOP (left), 3), 2);
- aopPut (AOP (result), zero, 3);
- shCount -= 8;
- hByteZ = 1;
- }
- if (!hByteZ && !sameRegs (AOP (left), AOP (right))) {
- offset = 0;
- while (size--) {
- aopPut (AOP (result),
- aopGet (AOP (left), offset), offset);
- offset++;
- }
- offset = 0;
- size = AOP_SIZE (result);
- }
- if (shCount) {
- switch (hByteZ) {
- case 0:
- while (shCount--) {
- emitcode ("lsr", "%s", aopGet (AOP (result), 3));
- emitcode ("ror", "%s", aopGet (AOP (result), 2));
- emitcode ("ror", "%s", aopGet (AOP (result), 1));
- emitcode ("ror", "%s", aopGet (AOP (result), 0));
- }
- break;
- case 1:
- while (shCount--) {
- emitcode ("lsr", "%s", aopGet (AOP (result), 2));
- emitcode ("ror", "%s", aopGet (AOP (result), 1));
- emitcode ("ror", "%s", aopGet (AOP (result), 0));
- }
- break;
- case 2:
- while (shCount--) {
- emitcode ("lsr", "%s", aopGet (AOP (result), 1));
- emitcode ("ror", "%s", aopGet (AOP (result), 0));
- }
- break;
- case 3:
- while (shCount--) {
- emitcode ("lsr", "%s", aopGet (AOP (result), 0));
- }
- break;
- }
- }
- }
+ operand *left = IC_LEFT (ic)
+ , *right = IC_RIGHT (ic)
+ , *result = IC_RESULT (ic);
+ int size, shCount, offset = 0;
+ int hByteZ = 0;
+ sym_link *letype = getSpec (operandType (left));
+ int sign = !SPEC_USIGN (letype);
+
+ right = IC_RIGHT (ic);
+ left = IC_LEFT (ic);
+ result = IC_RESULT (ic);
+
+ aopOp (left, ic, FALSE);
+ aopOp (result, ic, FALSE);
+ size = AOP_SIZE (result);
+ shCount = (int) ulFromVal (AOP (right)->aopu.aop_lit);
+
+ /* if signed then give up and use a loop to shift */
+ if (sign) {
+ symbol *tlbl;
+ if (!sameRegs (AOP (left), AOP (result))) {
+ while (size--) {
+ aopPut (AOP (result),
+ aopGet (AOP (left), offset), offset);
+ offset++;
+ }
+ size = AOP_SIZE (result);
+ offset = 0;
+ }
+ /* be as economical as possible */
+ if (shCount <= 4) {
+ while (shCount--) {
+ size = AOP_SIZE (result);
+ offset = size - 1;
+ while (size--) {
+ /* highest order byte */
+ if (offset == (AOP_SIZE(result)-1))
+ emitcode ("asr", "%s", aopGet (AOP (result), offset));
+ else
+ emitcode ("ror", "%s", aopGet (AOP (result), offset));
+ offset--;
+ }
+ }
+ }
+ else {
+ emitcode ("ldi", "r24,<(%d)", shCount);
+ tlbl = newiTempLabel (NULL);
+ emitcode ("", "L%05d:", tlbl->key);
+ offset = size - 1;
+ while (size--) {
+ if (offset == (AOP_SIZE(result) - 1))
+ emitcode ("asr", "%s", aopGet (AOP (result), offset));
+ else
+ emitcode ("ror", "%s", aopGet (AOP (result), offset));
+ offset--;
+ }
+ emitcode ("dec", "r24");
+ emitcode ("brne", "L%05d", tlbl->key);
+ }
+ goto release;
+ }
+ if (shCount > (size * 8 - 1)) {
+ while (size--)
+ aopPut (AOP (result), zero, offset++);
+ goto release;
+ }
+ /* for unsigned we can much more efficient */
+ switch (size) {
+ case 1:
+ if (!sameRegs (AOP (left), AOP (result)))
+ aopPut (AOP (result), aopGet (AOP (left), 0), 0);
+ if (shCount >= 4) {
+ emitcode ("swap", "%s", aopGet (AOP (result), 0));
+ if (AOP_ISHIGHREG(AOP(result),0)) {
+ emitcode ("andi", "%s,0x0f",aopGet(AOP(result),0));
+ } else {
+ emitcode ("ldi","r24,0x0f");
+ emitcode ("and", "%s,r24",aopGet(AOP(result),0));
+ }
+ shCount -= 4;
+ }
+ while (shCount--)
+ emitcode ("lsr", "%s", aopGet (AOP (result), 0));
+ break;
+ case 2:
+ if (shCount >= 12) {
+ aopPut (AOP (result), aopGet (AOP (left), 1), 0);
+ aopPut (AOP (result), zero, 1);
+ emitcode ("swap", "%s", aopGet (AOP (result), 0));
+ if (AOP_ISHIGHREG(AOP(result),0)) {
+ emitcode ("andi", "%s,0x0f", aopGet (AOP (result), 0));
+ } else {
+ emitcode ("ldi","r24,0x0f");
+ emitcode ("and", "%s,r24",aopGet(AOP(result),0));
+ }
+ shCount -= 12;
+ hByteZ = 1;
+ }
+ if (shCount >= 8) {
+ aopPut (AOP (result), aopGet (AOP (left), 1), 0);
+ aopPut (AOP (result), zero, 1);
+ shCount -= 8;
+ hByteZ = 1;
+ }
+ if (shCount >= 4) {
+ shCount -= 4;
+ if (!sameRegs (AOP (left), AOP (result))) {
+ aopPut (AOP (result), aopGet (AOP (left), 0), 0);
+ aopPut (AOP (result), aopGet (AOP (left), 1), 1);
+ }
+ if (!(AOP_ISHIGHREG(AOP(result),0) && AOP_ISHIGHREG(AOP(result),1))) {
+ emitcode("ldi","r25,0x0f");
+ }
+ emitcode ("mov", "r24,%s", aopGet (AOP (result), 1));
+ emitcode ("andi", "r24,0xf0");
+ emitcode ("swap", "%s", aopGet (AOP (result), 0));
+ if (AOP_ISHIGHREG(AOP(result),0)) {
+ emitcode ("andi", "%s,0x0f", aopGet (AOP (result), 0));
+ } else {
+ emitcode ("and", "%s,r25", aopGet (AOP (result), 0));
+ }
+ emitcode ("or", "%s,r24", aopGet (AOP (result), 0));
+ emitcode ("swap", "%s", aopGet (AOP (result), 1));
+ if (AOP_ISHIGHREG(AOP(result),1)) {
+ emitcode ("andi", "%s,0x0f", aopGet (AOP (result), 1));
+ } else {
+ emitcode ("and", "%s,r24", aopGet (AOP (result), 1));
+ }
+ while (shCount--) {
+ emitcode ("lsr", "%s", aopGet (AOP (result), 1));
+ emitcode ("ror", "%s", aopGet (AOP (result), 0));
+ }
+
+ }
+ if (!hByteZ && !sameRegs (AOP (result), AOP (left))
+ && shCount) {
+ offset = 0;
+ while (size--) {
+ aopPut (AOP (result), aopGet (AOP (left), offset), offset);
+ offset++;
+ }
+ }
+ while (shCount--) {
+ if (hByteZ) {
+ emitcode ("lsr", "%s", aopGet (AOP (result), 0));
+ }
+ else {
+ emitcode ("lsr", "%s", aopGet (AOP (result), 1));
+ emitcode ("ror", "%s", aopGet (AOP (result), 0));
+ }
+ }
+ break;
+
+ case 3:
+ assert ("shifting generic pointer ?\n");
+ break;
+ case 4:
+ /* 32 bits we do only byte boundaries */
+ if (shCount >= 24) {
+ aopPut (AOP (result), aopGet (AOP (left), 3), 0);
+ aopPut (AOP (result), zero, 1);
+ aopPut (AOP (result), zero, 2);
+ aopPut (AOP (result), zero, 3);
+ hByteZ = 3;
+ shCount -= 24;
+ }
+ if (shCount >= 16) {
+ aopPut (AOP (result), aopGet (AOP (left), 3), 1);
+ aopPut (AOP (result), aopGet (AOP (left), 2), 0);
+ aopPut (AOP (result), zero, 2);
+ aopPut (AOP (result), zero, 3);
+ hByteZ = 2;
+ shCount -= 16;
+ }
+ if (shCount >= 8) {
+ aopPut (AOP (result), aopGet (AOP (left), 1), 0);
+ aopPut (AOP (result), aopGet (AOP (left), 2), 1);
+ aopPut (AOP (result), aopGet (AOP (left), 3), 2);
+ aopPut (AOP (result), zero, 3);
+ shCount -= 8;
+ hByteZ = 1;
+ }
+ if (!hByteZ && !sameRegs (AOP (left), AOP (right))) {
+ offset = 0;
+ while (size--) {
+ aopPut (AOP (result),
+ aopGet (AOP (left), offset), offset);
+ offset++;
+ }
+ offset = 0;
+ size = AOP_SIZE (result);
+ }
+ if (shCount) {
+ switch (hByteZ) {
+ case 0:
+ while (shCount--) {
+ emitcode ("lsr", "%s", aopGet (AOP (result), 3));
+ emitcode ("ror", "%s", aopGet (AOP (result), 2));
+ emitcode ("ror", "%s", aopGet (AOP (result), 1));
+ emitcode ("ror", "%s", aopGet (AOP (result), 0));
+ }
+ break;
+ case 1:
+ while (shCount--) {
+ emitcode ("lsr", "%s", aopGet (AOP (result), 2));
+ emitcode ("ror", "%s", aopGet (AOP (result), 1));
+ emitcode ("ror", "%s", aopGet (AOP (result), 0));
+ }
+ break;
+ case 2:
+ while (shCount--) {
+ emitcode ("lsr", "%s", aopGet (AOP (result), 1));
+ emitcode ("ror", "%s", aopGet (AOP (result), 0));
+ }
+ break;
+ case 3:
+ while (shCount--) {
+ emitcode ("lsr", "%s", aopGet (AOP (result), 0));
+ }
+ break;
+ }
+ }
+ }
release:
- freeAsmop (left, NULL, ic, TRUE);
- freeAsmop (right, NULL, ic, TRUE);
- freeAsmop (result, NULL, ic, TRUE);
+ freeAsmop (left, NULL, ic, TRUE);
+ freeAsmop (right, NULL, ic, TRUE);
+ freeAsmop (result, NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
static void
genRightShift (iCode * ic)
{
- operand *right, *left, *result;
- sym_link *letype;
- int size, offset;
- int sign = 0, first = 1;
- symbol *tlbl;
-
- aopOp (right = IC_RIGHT (ic), ic, FALSE);
-
- if (AOP_TYPE (right) == AOP_LIT) {
- genShiftRightLit (ic);
- return;
- }
- /* unknown count */
- if (AOP_SIZE (right) > 1) {
- if (isRegPair (AOP (right))) {
- emitcode ("movw", "r24,%s", aopGet (AOP (right), 0));
- }
- else {
- emitcode ("mov", "r24,%s", aopGet (AOP (right), 0));
- emitcode ("mov", "r25,%s", aopGet (AOP (right), 1));
- }
- }
- else {
- emitcode ("mov", "r24,%s", aopGet (AOP (right), 0));
- }
- aopOp (left = IC_LEFT (ic), ic, FALSE);
- aopOp (result = IC_RESULT (ic), ic, FALSE);
- size = AOP_SIZE (result);
- tlbl = newiTempLabel (NULL);
- emitcode ("", "L%05d:", tlbl->key);
- offset = size - 1;
- letype = getSpec (operandType (left));
- sign = !SPEC_USIGN (letype);
- if (!sameRegs (AOP (left), AOP (result))) {
- while (size--) {
- aopPut (AOP (result), aopGet (AOP (left), offset), offset);
- offset++;
- }
- size = AOP_SIZE (result);
- }
- size = AOP_SIZE (result);
- while (size--) {
- if (first) {
- if (sign)
- emitcode ("asr", "%s", aopGet (AOP (result), offset));
- else
- emitcode ("lsr", "%s", aopGet (AOP (result), offset));
- first = 0;
- }
- else
- emitcode ("ror", "%s", aopGet (AOP (result), offset));
- offset--;
- }
- if (AOP_SIZE (right) > 1)
- emitcode ("sbiw", "r24,1");
- else
- emitcode ("dec", "r24");
- emitcode ("brne", "L%05d", tlbl->key);
-
- freeAsmop (left, NULL, ic, TRUE);
- freeAsmop (result, NULL, ic, TRUE);
+ operand *right, *left, *result;
+ sym_link *letype;
+ int size, offset;
+ int sign = 0, first = 1;
+ symbol *tlbl;
+
+ aopOp (right = IC_RIGHT (ic), ic, FALSE);
+
+ if (AOP_TYPE (right) == AOP_LIT) {
+ genShiftRightLit (ic);
+ return;
+ }
+ /* unknown count */
+ if (AOP_SIZE (right) > 1) {
+ if (isRegPair (AOP (right))) {
+ emitcode ("movw", "r24,%s", aopGet (AOP (right), 0));
+ }
+ else {
+ emitcode ("mov", "r24,%s", aopGet (AOP (right), 0));
+ emitcode ("mov", "r25,%s", aopGet (AOP (right), 1));
+ }
+ }
+ else {
+ emitcode ("mov", "r24,%s", aopGet (AOP (right), 0));
+ }
+ aopOp (left = IC_LEFT (ic), ic, FALSE);
+ aopOp (result = IC_RESULT (ic), ic, FALSE);
+ size = AOP_SIZE (result);
+ tlbl = newiTempLabel (NULL);
+ emitcode ("", "L%05d:", tlbl->key);
+ offset = size - 1;
+ letype = getSpec (operandType (left));
+ sign = !SPEC_USIGN (letype);
+ if (!sameRegs (AOP (left), AOP (result))) {
+ while (size--) {
+ aopPut (AOP (result), aopGet (AOP (left), offset), offset);
+ offset++;
+ }
+ size = AOP_SIZE (result);
+ }
+ size = AOP_SIZE (result);
+ while (size--) {
+ if (first) {
+ if (sign)
+ emitcode ("asr", "%s", aopGet (AOP (result), offset));
+ else
+ emitcode ("lsr", "%s", aopGet (AOP (result), offset));
+ first = 0;
+ }
+ else
+ emitcode ("ror", "%s", aopGet (AOP (result), offset));
+ offset--;
+ }
+ if (AOP_SIZE (right) > 1)
+ emitcode ("sbiw", "r24,1");
+ else
+ emitcode ("dec", "r24");
+ emitcode ("brne", "L%05d", tlbl->key);
+
+ freeAsmop (left, NULL, ic, TRUE);
+ freeAsmop (result, NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
static void
RRsh (int shCount,int reg)
{
- shCount &= 0x0007; // shCount : 0..7
-
- switch (shCount) {
- case 0:
- break;
- case 1:
- emitcode ("lsr", "r%d",reg);
- break;
- case 2:
- emitcode ("lsr", "r%d",reg);
- emitcode ("lsr", "r%d",reg);
- break;
- case 3:
- emitcode ("swap", "r%d",reg);
- emitcode ("lsl", "r%d",reg);
- break;
- case 4:
- emitcode ("swap", "r%d",reg);
- break;
- case 5:
- emitcode ("swap", "r%d",reg);
- emitcode ("lsr", "r%d",reg);
- break;
- case 6:
- emitcode ("swap","r%d",reg);
- emitcode ("lsr", "r%d",reg);
- emitcode ("lsr", "r%d",reg);
- break;
- case 7:
- emitcode ("swap","r%d",reg);
- emitcode ("lsr", "r%d",reg);
- emitcode ("lsr", "r%d",reg);
- emitcode ("lsr", "r%d",reg);
- break;
- }
+ shCount &= 0x0007; // shCount : 0..7
+
+ switch (shCount) {
+ case 0:
+ break;
+ case 1:
+ emitcode ("lsr", "r%d",reg);
+ break;
+ case 2:
+ emitcode ("lsr", "r%d",reg);
+ emitcode ("lsr", "r%d",reg);
+ break;
+ case 3:
+ emitcode ("swap", "r%d",reg);
+ emitcode ("lsl", "r%d",reg);
+ break;
+ case 4:
+ emitcode ("swap", "r%d",reg);
+ break;
+ case 5:
+ emitcode ("swap", "r%d",reg);
+ emitcode ("lsr", "r%d",reg);
+ break;
+ case 6:
+ emitcode ("swap","r%d",reg);
+ emitcode ("lsr", "r%d",reg);
+ emitcode ("lsr", "r%d",reg);
+ break;
+ case 7:
+ emitcode ("swap","r%d",reg);
+ emitcode ("lsr", "r%d",reg);
+ emitcode ("lsr", "r%d",reg);
+ emitcode ("lsr", "r%d",reg);
+ break;
+ }
}
/*-----------------------------------------------------------------*/
static void
RLsh (int shCount, int reg)
{
- shCount &= 0x0007; // shCount : 0..7
-
- switch (shCount) {
- case 0:
- break;
- case 1:
- emitcode ("lsl", "r%d",reg);
- break;
- case 2:
- emitcode ("lsl", "r%d",reg);
- emitcode ("lsl", "r%d",reg);
- break;
- case 3:
- emitcode ("swap","r%d",reg);
- emitcode ("lsr", "r%d",reg);
- break;
- case 4:
- emitcode ("swap", "r%d",reg);
- break;
- case 5:
- emitcode ("swap","r%d",reg);
- emitcode ("lsl", "r%d",reg);
- break;
- case 6:
- emitcode ("swap","r%d",reg);
- emitcode ("lsl", "r%d",reg);
- emitcode ("lsl", "r%d",reg);
- break;
- case 7:
- emitcode ("swap","r%d",reg);
- emitcode ("lsl", "r%d",reg);
- emitcode ("lsl", "r%d",reg);
- emitcode ("lsl", "r%d",reg);
- break;
- }
+ shCount &= 0x0007; // shCount : 0..7
+
+ switch (shCount) {
+ case 0:
+ break;
+ case 1:
+ emitcode ("lsl", "r%d",reg);
+ break;
+ case 2:
+ emitcode ("lsl", "r%d",reg);
+ emitcode ("lsl", "r%d",reg);
+ break;
+ case 3:
+ emitcode ("swap","r%d",reg);
+ emitcode ("lsr", "r%d",reg);
+ break;
+ case 4:
+ emitcode ("swap", "r%d",reg);
+ break;
+ case 5:
+ emitcode ("swap","r%d",reg);
+ emitcode ("lsl", "r%d",reg);
+ break;
+ case 6:
+ emitcode ("swap","r%d",reg);
+ emitcode ("lsl", "r%d",reg);
+ emitcode ("lsl", "r%d",reg);
+ break;
+ case 7:
+ emitcode ("swap","r%d",reg);
+ emitcode ("lsl", "r%d",reg);
+ emitcode ("lsl", "r%d",reg);
+ emitcode ("lsl", "r%d",reg);
+ break;
+ }
}
/*-----------------------------------------------------------------*/
static void
genUnpackBits (operand * result, char *rname, int ptype)
{
- int shCnt;
- int rlen = 0;
- sym_link *etype;
- int offset = 0;
- int rsize;
-
- etype = getSpec (operandType (result));
- rsize = getSize (operandType (result));
- /* read the first byte */
- switch (ptype) {
-
- case POINTER:
- case IPOINTER:
- case PPOINTER:
- case FPOINTER:
- emitcode ("ld", "r24,%s+", rname);
- break;
-
- case CPOINTER:
- emitcode ("lpm", "r24,%s+", rname);
- break;
-
- case GPOINTER:
- emitcode ("call","__gptrget_pi");
- emitcode ("mov","r24,r0");
- break;
- }
-
- rlen = SPEC_BLEN (etype);
-
- /* if we have bitdisplacement then it fits */
- /* into this byte completely or if length is */
- /* less than a byte */
- if ((shCnt = SPEC_BSTR (etype)) || (SPEC_BLEN (etype) <= 8)) {
-
- /* shift right acc */
- RRsh (shCnt,24);
-
- emitcode ("andi", "r24,lo(0x%x)",
- ((unsigned char) -1) >> (8 - SPEC_BLEN (etype)));
- aopPut (AOP (result), "r24", offset++);
- goto finish;
- }
-
- /* bit field did not fit in a byte */
- aopPut (AOP (result), "r24", offset++);
-
- while (1) {
-
- switch (ptype) {
-
- case POINTER:
- case IPOINTER:
- case PPOINTER:
- case FPOINTER:
- emitcode ("ld", "r24,%s+");
- break;
-
- case CPOINTER:
- emitcode ("lpm", "r24,%s+");
- break;
-
- case GPOINTER:
- emitcode ("call", "__gptrget_pi");
- break;
- }
-
- rlen -= 8;
- /* if we are done */
- if (rlen < 8)
- break;
-
- aopPut (AOP (result), "r24", offset++);
-
- }
-
- if (rlen) {
- aopPut (AOP (result), "r24", offset++);
- }
+ int shCnt;
+ int rlen = 0;
+ sym_link *etype;
+ int offset = 0;
+ int rsize;
+
+ etype = getSpec (operandType (result));
+ rsize = getSize (operandType (result));
+ /* read the first byte */
+ switch (ptype) {
+
+ case POINTER:
+ case IPOINTER:
+ case PPOINTER:
+ case FPOINTER:
+ emitcode ("ld", "r24,%s+", rname);
+ break;
+
+ case CPOINTER:
+ emitcode ("lpm", "r24,%s+", rname);
+ break;
+
+ case GPOINTER:
+ emitcode ("call","__gptrget_pi");
+ emitcode ("mov","r24,r0");
+ break;
+ }
+
+ rlen = SPEC_BLEN (etype);
+
+ /* if we have bitdisplacement then it fits */
+ /* into this byte completely or if length is */
+ /* less than a byte */
+ if ((shCnt = SPEC_BSTR (etype)) || (SPEC_BLEN (etype) <= 8)) {
+
+ /* shift right acc */
+ RRsh (shCnt,24);
+
+ emitcode ("andi", "r24,lo(0x%x)",
+ ((unsigned char) -1) >> (8 - SPEC_BLEN (etype)));
+ aopPut (AOP (result), "r24", offset++);
+ goto finish;
+ }
+
+ /* bit field did not fit in a byte */
+ aopPut (AOP (result), "r24", offset++);
+
+ while (1) {
+
+ switch (ptype) {
+
+ case POINTER:
+ case IPOINTER:
+ case PPOINTER:
+ case FPOINTER:
+ emitcode ("ld", "r24,%s+");
+ break;
+
+ case CPOINTER:
+ emitcode ("lpm", "r24,%s+");
+ break;
+
+ case GPOINTER:
+ emitcode ("call", "__gptrget_pi");
+ break;
+ }
+
+ rlen -= 8;
+ /* if we are done */
+ if (rlen < 8)
+ break;
+
+ aopPut (AOP (result), "r24", offset++);
+
+ }
+
+ if (rlen) {
+ aopPut (AOP (result), "r24", offset++);
+ }
finish:
- if (offset < rsize) {
- rsize -= offset;
- while (rsize--)
- aopPut (AOP (result), zero, offset++);
- }
- return;
+ if (offset < rsize) {
+ rsize -= offset;
+ while (rsize--)
+ aopPut (AOP (result), zero, offset++);
+ }
+ return;
}
/*-----------------------------------------------------------------*/
static void
genDataPointerGet (operand * left, operand * result, iCode * ic)
{
- char *l;
- char buffer[256];
- int size, offset = 0;
- aopOp (result, ic, TRUE);
-
- /* get the string representation of the name */
- l = aopGet (AOP (left), 0);
- size = AOP_SIZE (result);
- while (size--) {
- if (offset)
- sprintf (buffer, "(%s + %d)", l, offset);
- else
- sprintf (buffer, "%s", l);
- emitcode ("lds", "%s,%s", aopGet (AOP (result), offset++),
- buffer);
- }
-
- freeAsmop (left, NULL, ic, TRUE);
- freeAsmop (result, NULL, ic, TRUE);
+ char *l;
+ char buffer[256];
+ int size, offset = 0;
+ aopOp (result, ic, TRUE);
+
+ /* get the string representation of the name */
+ l = aopGet (AOP (left), 0);
+ size = AOP_SIZE (result);
+ while (size--) {
+ if (offset)
+ sprintf (buffer, "(%s + %d)", l, offset);
+ else
+ sprintf (buffer, "%s", l);
+ emitcode ("lds", "%s,%s", aopGet (AOP (result), offset++),
+ buffer);
+ }
+
+ freeAsmop (left, NULL, ic, TRUE);
+ freeAsmop (result, NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
static void
genMemPointerGet (operand * left, operand * result, iCode * ic, iCode *pi)
{
- asmop *aop = NULL;
- regs *preg = NULL;
- int gotFreePtr = 0;
- char *rname, *frname = NULL;
- sym_link *rtype, *retype;
- sym_link *ltype = operandType (left);
-
- rtype = operandType (result);
- retype = getSpec (rtype);
-
- aopOp (left, ic, FALSE);
-
- /* if left is rematerialisable and
- result is not bit variable type and
- the left is pointer to data space i.e
- lower 128 bytes of space */
- if (AOP_TYPE (left) == AOP_IMMD &&
- !IS_BITVAR (retype) && DCL_TYPE (ltype) == POINTER) {
- genDataPointerGet (left, result, ic);
- return;
- }
-
- /* if the value is already in a pointer register
- then don't need anything more */
- if (!AOP_INPREG (AOP (left))) {
- /* otherwise get a free pointer register */
- aop = newAsmop (0);
- preg = getFreePtr (ic, &aop, FALSE, 0);
- if (isRegPair (AOP (left) )) {
- emitcode ("movw", "%s,%s",
- aop->aopu.aop_ptr->name,
- aopGet(AOP(left),0));
- } else {
- emitcode ("mov", "%s,%s", aop->aopu.aop_ptr->name,
- aopGet (AOP (left), 0));
- emitcode ("mov", "%s,%s", aop->aop_ptr2->name,
- aopGet (AOP (left), 1));
- }
- gotFreePtr = 1;
- }
- else {
- aop = AOP(left);
- frname = aopGet(aop,0);
- }
- if (AOP_ISX(aop)) {
- rname = "X";
- } else if (AOP_ISZ(aop)) {
- rname = "Z";
- } else {
- werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "pointer not in correct register");
- exit (0);
- }
-
- aopOp (result, ic, FALSE);
-
- /* if bitfield then unpack the bits */
- if (IS_BITVAR (retype))
- genUnpackBits (result, rname, POINTER);
- else {
- /* we have can just get the values */
- int size = AOP_SIZE (result);
- int offset = 0;
-
- while (size--) {
- if (size || pi) {
- emitcode ("ld","%s,%s+",aopGet(AOP(result),offset), rname);
- } else {
- emitcode ("ld","%s,%s",aopGet(AOP(result),offset), rname);
- }
- }
- }
-
- /* now some housekeeping stuff */
- if (gotFreePtr) {
- /* we had to allocate for this iCode */
- if (pi) {
- if (isRegPair (AOP (left) )) {
- emitcode ("movw", "%s,%s",
- aopGet (AOP(left),0),
- aop->aopu.aop_ptr->name);
- } else {
- emitcode ("mov", "%s,%s",
- aopGet (AOP (left), 0),
- aop->aopu.aop_ptr->name);
- emitcode ("mov", "%s,%s",
- aopGet (AOP (left), 1),
- aop->aop_ptr2->name);
- }
- }
- freeAsmop (NULL, aop, ic, TRUE);
- } else {
-
- /* we did not allocate which means left
- already in a pointer register, then
- if size > 0 && this could be used again
- we have to point it back to where it
- belongs */
- if ((AOP_SIZE (result) > 1 &&
- !OP_SYMBOL (left)->remat &&
- (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) && !pi) {
- int size = AOP_SIZE (result) - 1;
- emitcode ("sbiw", "%s,%d",frname,size);
- }
- }
-
- /* done */
- if (pi) pi->generated = 1;
- freeAsmop (left, NULL, ic, TRUE);
- freeAsmop (result, NULL, ic, TRUE);
+ asmop *aop = NULL;
+ regs *preg = NULL;
+ int gotFreePtr = 0;
+ char *rname, *frname = NULL;
+ sym_link *rtype, *retype;
+ sym_link *ltype = operandType (left);
+
+ rtype = operandType (result);
+ retype = getSpec (rtype);
+
+ aopOp (left, ic, FALSE);
+
+ /* if left is rematerialisable and
+ result is not bit variable type and
+ the left is pointer to data space i.e
+ lower 128 bytes of space */
+ if (AOP_TYPE (left) == AOP_IMMD &&
+ !IS_BITVAR (retype) && DCL_TYPE (ltype) == POINTER) {
+ genDataPointerGet (left, result, ic);
+ return;
+ }
+
+ /* if the value is already in a pointer register
+ then don't need anything more */
+ if (!AOP_INPREG (AOP (left))) {
+ /* otherwise get a free pointer register */
+ aop = newAsmop (0);
+ preg = getFreePtr (ic, &aop, FALSE, 0);
+ if (isRegPair (AOP (left) )) {
+ emitcode ("movw", "%s,%s",
+ aop->aopu.aop_ptr->name,
+ aopGet(AOP(left),0));
+ } else {
+ emitcode ("mov", "%s,%s", aop->aopu.aop_ptr->name,
+ aopGet (AOP (left), 0));
+ emitcode ("mov", "%s,%s", aop->aop_ptr2->name,
+ aopGet (AOP (left), 1));
+ }
+ gotFreePtr = 1;
+ }
+ else {
+ aop = AOP(left);
+ frname = aopGet(aop,0);
+ }
+ if (AOP_ISX(aop)) {
+ rname = "X";
+ } else if (AOP_ISZ(aop)) {
+ rname = "Z";
+ } else {
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "pointer not in correct register");
+ exit (0);
+ }
+
+ aopOp (result, ic, FALSE);
+
+ /* if bitfield then unpack the bits */
+ if (IS_BITVAR (retype))
+ genUnpackBits (result, rname, POINTER);
+ else {
+ /* we have can just get the values */
+ int size = AOP_SIZE (result);
+ int offset = 0;
+
+ while (size--) {
+ if (size || pi) {
+ emitcode ("ld","%s,%s+",aopGet(AOP(result),offset), rname);
+ } else {
+ emitcode ("ld","%s,%s",aopGet(AOP(result),offset), rname);
+ }
+ }
+ }
+
+ /* now some housekeeping stuff */
+ if (gotFreePtr) {
+ /* we had to allocate for this iCode */
+ if (pi) {
+ if (isRegPair (AOP (left) )) {
+ emitcode ("movw", "%s,%s",
+ aopGet (AOP(left),0),
+ aop->aopu.aop_ptr->name);
+ } else {
+ emitcode ("mov", "%s,%s",
+ aopGet (AOP (left), 0),
+ aop->aopu.aop_ptr->name);
+ emitcode ("mov", "%s,%s",
+ aopGet (AOP (left), 1),
+ aop->aop_ptr2->name);
+ }
+ }
+ freeAsmop (NULL, aop, ic, TRUE);
+ } else {
+
+ /* we did not allocate which means left
+ already in a pointer register, then
+ if size > 0 && this could be used again
+ we have to point it back to where it
+ belongs */
+ if ((AOP_SIZE (result) > 1 &&
+ !OP_SYMBOL (left)->remat &&
+ (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) && !pi) {
+ int size = AOP_SIZE (result) - 1;
+ emitcode ("sbiw", "%s,%d",frname,size);
+ }
+ }
+
+ /* done */
+ if (pi) pi->generated = 1;
+ freeAsmop (left, NULL, ic, TRUE);
+ freeAsmop (result, NULL, ic, TRUE);
}
static void
genCodePointerGet (operand * left, operand * result, iCode * ic, iCode *pi)
{
- int size, offset;
- sym_link *retype = getSpec (operandType (result));
- asmop *aop = NULL;
- int gotFreePtr = 0;
-
- aopOp (left, ic, FALSE);
-
- /* if the operand is already in Z register
- then we do nothing else we move the value to Z register */
- if (AOP_ISZ(AOP(left))) {
- aop = AOP (left);
- } else {
- aop = newAsmop(0);
- getFreePtr(ic,&aop,FALSE,TRUE);
- if (isRegPair(AOP (left))) {
- emitcode ("movw","r30,%s",aopGet (AOP (left), 0));
- } else {
- emitcode ("mov", "r30,%s", aopGet (AOP (left), 0));
- emitcode ("mov", "r31,%s", aopGet (AOP (left), 1));
- }
- gotFreePtr = 1;
- }
-
- aopOp (result, ic, FALSE);
-
- /* if bit then unpack */
- if (IS_BITVAR (retype))
- genUnpackBits (result, "Z", CPOINTER);
- else {
- size = AOP_SIZE (result);
- offset = 0;
-
- while (size--) {
- if (size || pi) {
- emitcode ("lpm","%s,Z+",aopGet(AOP(result),offset++));
- } else {
- emitcode ("lpm","%s,Z",aopGet(AOP(result),offset++));
- }
- }
- }
-
- /* now some housekeeping stuff */
- if (gotFreePtr) {
- /* we had to allocate for this iCode */
- if (pi) {
- if (isRegPair(AOP (left))) {
- emitcode ("movw","%s,r30",aopGet (AOP (left), 0));
- } else {
- emitcode ("mov", "%s,r30", aopGet (AOP (left), 0));
- emitcode ("mov", "%s,r31", aopGet (AOP (left), 1));
- }
- }
- freeAsmop (NULL, aop, ic, TRUE);
- } else {
-
- /* we did not allocate which means left
- already in a pointer register, then
- if size > 0 && this could be used again
- we have to point it back to where it
- belongs */
- if ((AOP_SIZE (result) > 1 &&
- !OP_SYMBOL (left)->remat &&
- (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) &&
- !pi) {
- int size = AOP_SIZE (result) - 1;
- emitcode ("sbiw", "r30,%d",size);
- }
- }
-
- /* done */
- if (pi) pi->generated=1;
- freeAsmop (left, NULL, ic, TRUE);
- freeAsmop (result, NULL, ic, TRUE);
+ int size, offset;
+ sym_link *retype = getSpec (operandType (result));
+ asmop *aop = NULL;
+ int gotFreePtr = 0;
+
+ aopOp (left, ic, FALSE);
+
+ /* if the operand is already in Z register
+ then we do nothing else we move the value to Z register */
+ if (AOP_ISZ(AOP(left))) {
+ aop = AOP (left);
+ } else {
+ aop = newAsmop(0);
+ getFreePtr(ic,&aop,FALSE,TRUE);
+ if (isRegPair(AOP (left))) {
+ emitcode ("movw","r30,%s",aopGet (AOP (left), 0));
+ } else {
+ emitcode ("mov", "r30,%s", aopGet (AOP (left), 0));
+ emitcode ("mov", "r31,%s", aopGet (AOP (left), 1));
+ }
+ gotFreePtr = 1;
+ }
+
+ aopOp (result, ic, FALSE);
+
+ /* if bit then unpack */
+ if (IS_BITVAR (retype))
+ genUnpackBits (result, "Z", CPOINTER);
+ else {
+ size = AOP_SIZE (result);
+ offset = 0;
+
+ while (size--) {
+ if (size || pi) {
+ emitcode ("lpm","%s,Z+",aopGet(AOP(result),offset++));
+ } else {
+ emitcode ("lpm","%s,Z",aopGet(AOP(result),offset++));
+ }
+ }
+ }
+
+ /* now some housekeeping stuff */
+ if (gotFreePtr) {
+ /* we had to allocate for this iCode */
+ if (pi) {
+ if (isRegPair(AOP (left))) {
+ emitcode ("movw","%s,r30",aopGet (AOP (left), 0));
+ } else {
+ emitcode ("mov", "%s,r30", aopGet (AOP (left), 0));
+ emitcode ("mov", "%s,r31", aopGet (AOP (left), 1));
+ }
+ }
+ freeAsmop (NULL, aop, ic, TRUE);
+ } else {
+
+ /* we did not allocate which means left
+ already in a pointer register, then
+ if size > 0 && this could be used again
+ we have to point it back to where it
+ belongs */
+ if ((AOP_SIZE (result) > 1 &&
+ !OP_SYMBOL (left)->remat &&
+ (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) &&
+ !pi) {
+ int size = AOP_SIZE (result) - 1;
+ emitcode ("sbiw", "r30,%d",size);
+ }
+ }
+
+ /* done */
+ if (pi) pi->generated=1;
+ freeAsmop (left, NULL, ic, TRUE);
+ freeAsmop (result, NULL, ic, TRUE);
}
static void
genGenPointerGet (operand * left, operand * result, iCode * ic, iCode *pi)
{
- int size, offset;
- int gotFreePtr = 0;
- sym_link *retype = getSpec (operandType (result));
- asmop *aop = NULL;
-
- aopOp (left, ic, FALSE);
-
- /* if the operand is already in dptr
- then we do nothing else we move the value to dptr */
- if (AOP_ISZ(AOP(left))) {
- aop = AOP(left);
- } else {
- aop = newAsmop(0);
- getFreePtr(ic,&aop,FALSE,TRUE);
- if (isRegPair(AOP(left))) {
- emitcode ("movw", "r30,%s", aopGet (AOP (left), 0));
- } else {
- emitcode ("mov", "r30,%s", aopGet (AOP (left), 0));
- emitcode ("mov", "r31,%s", aopGet (AOP (left), 1));
- }
- emitcode ("mov", "r24,%s", aopGet (AOP (left), 2));
- gotFreePtr=1;
- }
-
- /* so Z register now contains the address */
-
- aopOp (result, ic, FALSE);
-
- /* if bit then unpack */
- if (IS_BITVAR (retype))
- genUnpackBits (result, "Z", GPOINTER);
- else {
- size = AOP_SIZE (result);
- offset = 0;
-
- while (size--) {
- if (size || pi)
- emitcode ("call", "__gptrget_pi");
- else
- emitcode ("call", "__gptrget");
- aopPut (AOP (result), "r0", offset++);
- }
- }
-
-
- /* now some housekeeping stuff */
- if (gotFreePtr) {
- /* we had to allocate for this iCode */
- if (pi) {
- if (isRegPair(AOP (left))) {
- emitcode ("movw","%s,r30",aopGet (AOP (left), 0));
- } else {
- emitcode ("mov", "%s,r30", aopGet (AOP (left), 0));
- emitcode ("mov", "%s,r31", aopGet (AOP (left), 1));
- }
- }
- freeAsmop (NULL, aop, ic, TRUE);
- } else {
-
- /* we did not allocate which means left
- already in a pointer register, then
- if size > 0 && this could be used again
- we have to point it back to where it
- belongs */
- if ((AOP_SIZE (result) > 1 &&
- !OP_SYMBOL (left)->remat &&
- (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) &&
- !pi) {
- int size = AOP_SIZE (result) - 1;
- emitcode ("sbiw", "r30,%d",size);
- }
- }
- if (pi) pi->generated=1;
- freeAsmop (left, NULL, ic, TRUE);
- freeAsmop (result, NULL, ic, TRUE);
+ int size, offset;
+ int gotFreePtr = 0;
+ sym_link *retype = getSpec (operandType (result));
+ asmop *aop = NULL;
+
+ aopOp (left, ic, FALSE);
+
+ /* if the operand is already in dptr
+ then we do nothing else we move the value to dptr */
+ if (AOP_ISZ(AOP(left))) {
+ aop = AOP(left);
+ } else {
+ aop = newAsmop(0);
+ getFreePtr(ic,&aop,FALSE,TRUE);
+ if (isRegPair(AOP(left))) {
+ emitcode ("movw", "r30,%s", aopGet (AOP (left), 0));
+ } else {
+ emitcode ("mov", "r30,%s", aopGet (AOP (left), 0));
+ emitcode ("mov", "r31,%s", aopGet (AOP (left), 1));
+ }
+ emitcode ("mov", "r24,%s", aopGet (AOP (left), 2));
+ gotFreePtr=1;
+ }
+
+ /* so Z register now contains the address */
+
+ aopOp (result, ic, FALSE);
+
+ /* if bit then unpack */
+ if (IS_BITVAR (retype))
+ genUnpackBits (result, "Z", GPOINTER);
+ else {
+ size = AOP_SIZE (result);
+ offset = 0;
+
+ while (size--) {
+ if (size || pi)
+ emitcode ("call", "__gptrget_pi");
+ else
+ emitcode ("call", "__gptrget");
+ aopPut (AOP (result), "r0", offset++);
+ }
+ }
+
+
+ /* now some housekeeping stuff */
+ if (gotFreePtr) {
+ /* we had to allocate for this iCode */
+ if (pi) {
+ if (isRegPair(AOP (left))) {
+ emitcode ("movw","%s,r30",aopGet (AOP (left), 0));
+ } else {
+ emitcode ("mov", "%s,r30", aopGet (AOP (left), 0));
+ emitcode ("mov", "%s,r31", aopGet (AOP (left), 1));
+ }
+ }
+ freeAsmop (NULL, aop, ic, TRUE);
+ } else {
+
+ /* we did not allocate which means left
+ already in a pointer register, then
+ if size > 0 && this could be used again
+ we have to point it back to where it
+ belongs */
+ if ((AOP_SIZE (result) > 1 &&
+ !OP_SYMBOL (left)->remat &&
+ (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) &&
+ !pi) {
+ int size = AOP_SIZE (result) - 1;
+ emitcode ("sbiw", "r30,%d",size);
+ }
+ }
+ if (pi) pi->generated=1;
+ freeAsmop (left, NULL, ic, TRUE);
+ freeAsmop (result, NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
static void
genPointerGet (iCode * ic, iCode *pi)
{
- operand *left, *result;
- sym_link *type, *etype;
- int p_type;
-
- left = IC_LEFT (ic);
- result = IC_RESULT (ic);
-
- /* depending on the type of pointer we need to
- move it to the correct pointer register */
- type = operandType (left);
- etype = getSpec (type);
- /* if left is of type of pointer then it is simple */
- if (IS_PTR (type) && !IS_FUNC (type->next))
- p_type = DCL_TYPE (type);
- else {
- /* we have to go by the storage class */
- p_type = PTR_TYPE (SPEC_OCLS (etype));
-
-
- }
-
- /* now that we have the pointer type we assign
- the pointer values */
- switch (p_type) {
-
- case POINTER:
- case IPOINTER:
- case PPOINTER:
- case FPOINTER:
- genMemPointerGet (left, result, ic, pi);
- break;
-
- case CPOINTER:
- genCodePointerGet (left, result, ic, pi);
- break;
-
- case GPOINTER:
- genGenPointerGet (left, result, ic, pi);
- break;
- }
+ operand *left, *result;
+ sym_link *type, *etype;
+ int p_type;
+
+ left = IC_LEFT (ic);
+ result = IC_RESULT (ic);
+
+ /* depending on the type of pointer we need to
+ move it to the correct pointer register */
+ type = operandType (left);
+ etype = getSpec (type);
+ /* if left is of type of pointer then it is simple */
+ if (IS_PTR (type) && !IS_FUNC (type->next))
+ p_type = DCL_TYPE (type);
+ else {
+ /* we have to go by the storage class */
+ p_type = PTR_TYPE (SPEC_OCLS (etype));
+
+
+ }
+
+ /* now that we have the pointer type we assign
+ the pointer values */
+ switch (p_type) {
+
+ case POINTER:
+ case IPOINTER:
+ case PPOINTER:
+ case FPOINTER:
+ genMemPointerGet (left, result, ic, pi);
+ break;
+
+ case CPOINTER:
+ genCodePointerGet (left, result, ic, pi);
+ break;
+
+ case GPOINTER:
+ genGenPointerGet (left, result, ic, pi);
+ break;
+ }
}
/*-----------------------------------------------------------------*/
static void
genPackBits (sym_link * etype,
- operand * right,
- char *rname, int p_type)
+ operand * right,
+ char *rname, int p_type)
{
- int shCount = 0;
- int offset = 0;
- int rLen = 0;
- int blen, bstr;
- char *l;
-
- blen = SPEC_BLEN (etype);
- bstr = SPEC_BSTR (etype);
-
- l = aopGet (AOP (right), offset++);
- MOVR24 (l);
-
- /* if the bit lenth is less than or */
- /* it exactly fits a byte then */
- if (SPEC_BLEN (etype) <= 8) {
- shCount = SPEC_BSTR (etype);
-
- /* shift left acc */
- RLsh (shCount,24);
-
- if (SPEC_BLEN (etype) < 8) { /* if smaller than a byte */
-
- switch (p_type) {
- case POINTER:
- case IPOINTER:
- case PPOINTER:
- case FPOINTER:
- emitcode ("ld", "r1,%s",rname);
- break;
-
- case GPOINTER:
- emitcode ("push", "r1");
- emitcode ("push", "r24");
- emitcode ("call", "__gptrget");
- emitcode ("pop", "r1");
- emitcode ("mov","r24,r0");
- break;
- }
-
- emitcode ("andi", "r24,#0x%02x", (unsigned char)
- ((unsigned char) (0xFF << (blen + bstr)) |
- (unsigned char) (0xFF >> (8 - bstr))));
- emitcode ("or", "r24,r1");
- if (p_type == GPOINTER)
- emitcode ("pop", "r1");
- }
- }
-
- switch (p_type) {
- case POINTER:
- case IPOINTER:
- case PPOINTER:
- case FPOINTER:
- emitcode("st","%s+,r24");
- break;
-
- case GPOINTER:
- emitcode("mov","r0,r24");
- emitcode ("call", "__gptrput_pi");
- break;
- }
-
- /* if we r done */
- if (SPEC_BLEN (etype) <= 8)
- return;
-
- rLen = SPEC_BLEN (etype);
-
- /* now generate for lengths greater than one byte */
- while (1) {
-
- l = aopGet (AOP (right), offset++);
-
- rLen -= 8;
- if (rLen < 8)
- break;
-
- switch (p_type) {
- case POINTER:
- case IPOINTER:
- case PPOINTER:
- case FPOINTER:
- emitcode ("st", "%s+,%s",rname,l);
- break;
-
- case GPOINTER:
- MOVR0 (l);
- emitcode ("lcall", "__gptrput_pi");
- break;
- }
- }
-
- MOVR24 (l);
-
- /* last last was not complete */
- if (rLen) {
- /* save the byte & read byte */
- switch (p_type) {
- case POINTER:
- case IPOINTER:
- case PPOINTER:
- case FPOINTER:
- emitcode ("st","%s+,r24",rname);
- break;
- case GPOINTER:
- emitcode ("push", "r1");
- emitcode ("push", "r24");
- emitcode ("lcall", "__gptrget");
- emitcode ("mov","r24,r0");
- emitcode ("pop", "r1");
- break;
- }
-
- emitcode ("andi", "r24,0x%02x", (((unsigned char) -1 << rLen) & 0xff));
- emitcode ("or", "r24,r1");
- }
-
- if (p_type == GPOINTER)
- emitcode ("pop", "r1");
-
- switch (p_type) {
-
- case POINTER:
- case IPOINTER:
- case PPOINTER:
- case FPOINTER:
- emitcode ("st", "%s,r24", rname);
- break;
-
- case GPOINTER:
- emitcode ("mov","r0,r24");
- emitcode ("call", "__gptrput");
- break;
- }
+ int shCount = 0;
+ int offset = 0;
+ int rLen = 0;
+ int blen, bstr;
+ char *l;
+
+ blen = SPEC_BLEN (etype);
+ bstr = SPEC_BSTR (etype);
+
+ l = aopGet (AOP (right), offset++);
+ MOVR24 (l);
+
+ /* if the bit lenth is less than or */
+ /* it exactly fits a byte then */
+ if (SPEC_BLEN (etype) <= 8) {
+ shCount = SPEC_BSTR (etype);
+
+ /* shift left acc */
+ RLsh (shCount,24);
+
+ if (SPEC_BLEN (etype) < 8) { /* if smaller than a byte */
+
+ switch (p_type) {
+ case POINTER:
+ case IPOINTER:
+ case PPOINTER:
+ case FPOINTER:
+ emitcode ("ld", "r1,%s",rname);
+ break;
+
+ case GPOINTER:
+ emitcode ("push", "r1");
+ emitcode ("push", "r24");
+ emitcode ("call", "__gptrget");
+ emitcode ("pop", "r1");
+ emitcode ("mov","r24,r0");
+ break;
+ }
+
+ emitcode ("andi", "r24,#0x%02x", (unsigned char)
+ ((unsigned char) (0xFF << (blen + bstr)) |
+ (unsigned char) (0xFF >> (8 - bstr))));
+ emitcode ("or", "r24,r1");
+ if (p_type == GPOINTER)
+ emitcode ("pop", "r1");
+ }
+ }
+
+ switch (p_type) {
+ case POINTER:
+ case IPOINTER:
+ case PPOINTER:
+ case FPOINTER:
+ emitcode("st","%s+,r24");
+ break;
+
+ case GPOINTER:
+ emitcode("mov","r0,r24");
+ emitcode ("call", "__gptrput_pi");
+ break;
+ }
+
+ /* if we r done */
+ if (SPEC_BLEN (etype) <= 8)
+ return;
+
+ rLen = SPEC_BLEN (etype);
+
+ /* now generate for lengths greater than one byte */
+ while (1) {
+
+ l = aopGet (AOP (right), offset++);
+
+ rLen -= 8;
+ if (rLen < 8)
+ break;
+
+ switch (p_type) {
+ case POINTER:
+ case IPOINTER:
+ case PPOINTER:
+ case FPOINTER:
+ emitcode ("st", "%s+,%s",rname,l);
+ break;
+
+ case GPOINTER:
+ MOVR0 (l);
+ emitcode ("lcall", "__gptrput_pi");
+ break;
+ }
+ }
+
+ MOVR24 (l);
+
+ /* last last was not complete */
+ if (rLen) {
+ /* save the byte & read byte */
+ switch (p_type) {
+ case POINTER:
+ case IPOINTER:
+ case PPOINTER:
+ case FPOINTER:
+ emitcode ("st","%s+,r24",rname);
+ break;
+ case GPOINTER:
+ emitcode ("push", "r1");
+ emitcode ("push", "r24");
+ emitcode ("lcall", "__gptrget");
+ emitcode ("mov","r24,r0");
+ emitcode ("pop", "r1");
+ break;
+ }
+
+ emitcode ("andi", "r24,0x%02x", (((unsigned char) -1 << rLen) & 0xff));
+ emitcode ("or", "r24,r1");
+ }
+
+ if (p_type == GPOINTER)
+ emitcode ("pop", "r1");
+
+ switch (p_type) {
+
+ case POINTER:
+ case IPOINTER:
+ case PPOINTER:
+ case FPOINTER:
+ emitcode ("st", "%s,r24", rname);
+ break;
+
+ case GPOINTER:
+ emitcode ("mov","r0,r24");
+ emitcode ("call", "__gptrput");
+ break;
+ }
}
/*-----------------------------------------------------------------*/
static void
genDataPointerSet (operand * right, operand * result, iCode * ic)
{
- int size, offset = 0;
- char *l, buffer[256];
-
- aopOp (right, ic, FALSE);
-
- l = aopGet (AOP (result), 0);
- size = AOP_SIZE (right);
- while (size--) {
- if (offset)
- sprintf (buffer, "(%s + %d)", l, offset);
- else
- sprintf (buffer, "%s", l);
- emitcode ("sts", "%s,%s", buffer,
- aopGet (AOP (right), offset++));
- }
-
- freeAsmop (right, NULL, ic, TRUE);
- freeAsmop (result, NULL, ic, TRUE);
+ int size, offset = 0;
+ char *l, buffer[256];
+
+ aopOp (right, ic, FALSE);
+
+ l = aopGet (AOP (result), 0);
+ size = AOP_SIZE (right);
+ while (size--) {
+ if (offset)
+ sprintf (buffer, "(%s + %d)", l, offset);
+ else
+ sprintf (buffer, "%s", l);
+ emitcode ("sts", "%s,%s", buffer,
+ aopGet (AOP (right), offset++));
+ }
+
+ freeAsmop (right, NULL, ic, TRUE);
+ freeAsmop (result, NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
static void
genMemPointerSet (operand * right, operand * result, iCode * ic, iCode *pi)
{
- asmop *aop = NULL;
- char *frname = NULL, *rname, *l;
- int gotFreePtr = 0;
- sym_link *retype;
- sym_link *ptype = operandType (result);
-
- retype = getSpec (operandType (right));
-
- aopOp (result, ic, FALSE);
-
- /* if the result is rematerializable &
- in data space & not a bit variable */
- if (AOP_TYPE (result) == AOP_IMMD &&
- DCL_TYPE (ptype) == POINTER && !IS_BITVAR (retype)) {
- genDataPointerSet (right, result, ic);
- return;
- }
- if (!AOP_INPREG(AOP(result))) {
- /* otherwise get a free pointer register */
- aop = newAsmop (0);
- getFreePtr (ic, &aop, FALSE, 0);
- if (isRegPair (AOP (result) )) {
- emitcode ("movw", "%s,%s",aop->aopu.aop_ptr->name,
- aopGet(AOP (result), 0));
- } else {
- emitcode ("mov", "%s,%s", aop->aopu.aop_ptr->name,
- aopGet (AOP (result), 0));
- emitcode ("mov", "%s,%s", aop->aop_ptr2->name,
- aopGet (AOP (result), 1));
- }
- gotFreePtr = 1;
- } else {
- aop = AOP(result);
- frname = aopGet(aop,0);
- }
-
- aopOp (right, ic, FALSE);
- if (AOP_ISX(aop)) {
- rname = "X";
- } else if (AOP_ISZ(aop)) {
- rname = "Z";
- } else {
- werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "pointer not in correct register");
- exit (0);
- }
- /* if bitfield then unpack the bits */
- if (IS_BITVAR (retype))
- genPackBits (retype, right, rname, POINTER);
- else {
- /* we have can just get the values */
- int size = AOP_SIZE (right);
- int offset = 0;
-
- while (size--) {
- l = aopGet (AOP (right), offset);
- if (size || pi)
- emitcode ("st", "%s+,%s", rname,l);
- else
- emitcode ("st", "%s,%s", rname,l);
- offset++;
- }
- }
-
- /* now some housekeeping stuff */
- if (gotFreePtr) {
- /* we had to allocate for this iCode */
- if (pi) {
- if (isRegPair (AOP (result) )) {
- emitcode ("movw", "%s,%s",
- aopGet(AOP(result),0),
- aop->aopu.aop_ptr->name);
- } else {
- emitcode ("mov", "%s,%s", aop->aopu.aop_ptr->name,
- aopGet (AOP (result), 0));
- emitcode ("mov", "%s,%s", aop->aop_ptr2->name,
- aopGet (AOP (result), 1));
- }
- }
- freeAsmop (NULL, aop, ic, TRUE);
- } else {
-
- /* we did not allocate which means left
- already in a pointer register, then
- if size > 0 && this could be used again
- we have to point it back to where it
- belongs */
- if ((AOP_SIZE (right) > 1 &&
- !OP_SYMBOL (result)->remat &&
- (OP_SYMBOL (right)->liveTo > ic->seq || ic->depth)) && !pi) {
- int size = AOP_SIZE (right) - 1;
- emitcode ("sbiw", "%s,%d",frname,size);
- }
- }
-
- /* done */
- if (pi) pi->generated = 1;
- freeAsmop (result, NULL, ic, TRUE);
- freeAsmop (right, NULL, ic, TRUE);
+ asmop *aop = NULL;
+ char *frname = NULL, *rname, *l;
+ int gotFreePtr = 0;
+ sym_link *retype;
+ sym_link *ptype = operandType (result);
+
+ retype = getSpec (operandType (right));
+
+ aopOp (result, ic, FALSE);
+
+ /* if the result is rematerializable &
+ in data space & not a bit variable */
+ if (AOP_TYPE (result) == AOP_IMMD &&
+ DCL_TYPE (ptype) == POINTER && !IS_BITVAR (retype)) {
+ genDataPointerSet (right, result, ic);
+ return;
+ }
+ if (!AOP_INPREG(AOP(result))) {
+ /* otherwise get a free pointer register */
+ aop = newAsmop (0);
+ getFreePtr (ic, &aop, FALSE, 0);
+ if (isRegPair (AOP (result) )) {
+ emitcode ("movw", "%s,%s",aop->aopu.aop_ptr->name,
+ aopGet(AOP (result), 0));
+ } else {
+ emitcode ("mov", "%s,%s", aop->aopu.aop_ptr->name,
+ aopGet (AOP (result), 0));
+ emitcode ("mov", "%s,%s", aop->aop_ptr2->name,
+ aopGet (AOP (result), 1));
+ }
+ gotFreePtr = 1;
+ } else {
+ aop = AOP(result);
+ frname = aopGet(aop,0);
+ }
+
+ aopOp (right, ic, FALSE);
+ if (AOP_ISX(aop)) {
+ rname = "X";
+ } else if (AOP_ISZ(aop)) {
+ rname = "Z";
+ } else {
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "pointer not in correct register");
+ exit (0);
+ }
+ /* if bitfield then unpack the bits */
+ if (IS_BITVAR (retype))
+ genPackBits (retype, right, rname, POINTER);
+ else {
+ /* we have can just get the values */
+ int size = AOP_SIZE (right);
+ int offset = 0;
+
+ while (size--) {
+ l = aopGet (AOP (right), offset);
+ if (size || pi)
+ emitcode ("st", "%s+,%s", rname,l);
+ else
+ emitcode ("st", "%s,%s", rname,l);
+ offset++;
+ }
+ }
+
+ /* now some housekeeping stuff */
+ if (gotFreePtr) {
+ /* we had to allocate for this iCode */
+ if (pi) {
+ if (isRegPair (AOP (result) )) {
+ emitcode ("movw", "%s,%s",
+ aopGet(AOP(result),0),
+ aop->aopu.aop_ptr->name);
+ } else {
+ emitcode ("mov", "%s,%s", aop->aopu.aop_ptr->name,
+ aopGet (AOP (result), 0));
+ emitcode ("mov", "%s,%s", aop->aop_ptr2->name,
+ aopGet (AOP (result), 1));
+ }
+ }
+ freeAsmop (NULL, aop, ic, TRUE);
+ } else {
+
+ /* we did not allocate which means left
+ already in a pointer register, then
+ if size > 0 && this could be used again
+ we have to point it back to where it
+ belongs */
+ if ((AOP_SIZE (right) > 1 &&
+ !OP_SYMBOL (result)->remat &&
+ (OP_SYMBOL (right)->liveTo > ic->seq || ic->depth)) && !pi) {
+ int size = AOP_SIZE (right) - 1;
+ emitcode ("sbiw", "%s,%d",frname,size);
+ }
+ }
+
+ /* done */
+ if (pi) pi->generated = 1;
+ freeAsmop (result, NULL, ic, TRUE);
+ freeAsmop (right, NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
static void
genGenPointerSet (operand * right, operand * result, iCode * ic, iCode *pi)
{
- int size, offset;
- int gotFreePtr = 0;
- sym_link *retype = getSpec (operandType (right));
- asmop *aop = NULL;
-
- aopOp (result, ic, FALSE);
-
- /* if the operand is already in dptr
- then we do nothing else we move the value to dptr */
- if (AOP_ISZ(AOP(result))) {
- aop = AOP(right);
- } else {
- aop = newAsmop(0);
- getFreePtr(ic,&aop,FALSE,TRUE);
- if (isRegPair(AOP(result))) {
- emitcode ("movw", "r30,%s", aopGet (AOP (result), 0));
- } else {
- emitcode ("mov", "r30,%s", aopGet (AOP (result), 0));
- emitcode ("mov", "r31,%s", aopGet (AOP (result), 1));
- }
- emitcode ("mov", "r24,%s", aopGet (AOP (result), 2));
- gotFreePtr=1;
- }
-
- /* so Z register now contains the address */
- aopOp (right, ic, FALSE);
-
- /* if bit then unpack */
- if (IS_BITVAR (retype))
- genUnpackBits (result, "Z", GPOINTER);
- else {
- size = AOP_SIZE (right);
- offset = 0;
-
- while (size--) {
- char *l = aopGet(AOP (right), offset++);
- MOVR0(l);
-
- if (size || pi)
- emitcode ("call", "__gptrput_pi");
- else
- emitcode ("call", "__gptrput");
- }
- }
-
- /* now some housekeeping stuff */
- if (gotFreePtr) {
- /* we had to allocate for this iCode */
- if (pi) {
- if (isRegPair(AOP(result))) {
- emitcode ("movw", "%s,r30", aopGet (AOP (result), 0));
- } else {
- emitcode ("mov", "%s,r30", aopGet (AOP (result), 0));
- emitcode ("mov", "%s,r31", aopGet (AOP (result), 1));
- }
- }
- freeAsmop (NULL, aop, ic, TRUE);
- } else {
-
- /* we did not allocate which means left
- already in a pointer register, then
- if size > 0 && this could be used again
- we have to point it back to where it
- belongs */
- if ((AOP_SIZE (right) > 1 &&
- !OP_SYMBOL (result)->remat &&
- (OP_SYMBOL (result)->liveTo > ic->seq || ic->depth)) && !pi) {
- int size = AOP_SIZE (right) - 1;
- emitcode ("sbiw", "r30,%d",size);
- }
- }
- if (pi) pi->generated = 1;
- freeAsmop (right, NULL, ic, TRUE);
- freeAsmop (result, NULL, ic, TRUE);
+ int size, offset;
+ int gotFreePtr = 0;
+ sym_link *retype = getSpec (operandType (right));
+ asmop *aop = NULL;
+
+ aopOp (result, ic, FALSE);
+
+ /* if the operand is already in dptr
+ then we do nothing else we move the value to dptr */
+ if (AOP_ISZ(AOP(result))) {
+ aop = AOP(right);
+ } else {
+ aop = newAsmop(0);
+ getFreePtr(ic,&aop,FALSE,TRUE);
+ if (isRegPair(AOP(result))) {
+ emitcode ("movw", "r30,%s", aopGet (AOP (result), 0));
+ } else {
+ emitcode ("mov", "r30,%s", aopGet (AOP (result), 0));
+ emitcode ("mov", "r31,%s", aopGet (AOP (result), 1));
+ }
+ emitcode ("mov", "r24,%s", aopGet (AOP (result), 2));
+ gotFreePtr=1;
+ }
+
+ /* so Z register now contains the address */
+ aopOp (right, ic, FALSE);
+
+ /* if bit then unpack */
+ if (IS_BITVAR (retype))
+ genUnpackBits (result, "Z", GPOINTER);
+ else {
+ size = AOP_SIZE (right);
+ offset = 0;
+
+ while (size--) {
+ char *l = aopGet(AOP (right), offset++);
+ MOVR0(l);
+
+ if (size || pi)
+ emitcode ("call", "__gptrput_pi");
+ else
+ emitcode ("call", "__gptrput");
+ }
+ }
+
+ /* now some housekeeping stuff */
+ if (gotFreePtr) {
+ /* we had to allocate for this iCode */
+ if (pi) {
+ if (isRegPair(AOP(result))) {
+ emitcode ("movw", "%s,r30", aopGet (AOP (result), 0));
+ } else {
+ emitcode ("mov", "%s,r30", aopGet (AOP (result), 0));
+ emitcode ("mov", "%s,r31", aopGet (AOP (result), 1));
+ }
+ }
+ freeAsmop (NULL, aop, ic, TRUE);
+ } else {
+
+ /* we did not allocate which means left
+ already in a pointer register, then
+ if size > 0 && this could be used again
+ we have to point it back to where it
+ belongs */
+ if ((AOP_SIZE (right) > 1 &&
+ !OP_SYMBOL (result)->remat &&
+ (OP_SYMBOL (result)->liveTo > ic->seq || ic->depth)) && !pi) {
+ int size = AOP_SIZE (right) - 1;
+ emitcode ("sbiw", "r30,%d",size);
+ }
+ }
+ if (pi) pi->generated = 1;
+ freeAsmop (right, NULL, ic, TRUE);
+ freeAsmop (result, NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
static void
genPointerSet (iCode * ic, iCode *pi)
{
- operand *right, *result;
- sym_link *type, *etype;
- int p_type;
-
- right = IC_RIGHT (ic);
- result = IC_RESULT (ic);
-
- /* depending on the type of pointer we need to
- move it to the correct pointer register */
- type = operandType (result);
- etype = getSpec (type);
- /* if left is of type of pointer then it is simple */
- if (IS_PTR (type) && !IS_FUNC (type->next)) {
- p_type = DCL_TYPE (type);
- }
- else {
- /* we have to go by the storage class */
- p_type = PTR_TYPE (SPEC_OCLS (etype));
-
- }
-
- /* now that we have the pointer type we assign
- the pointer values */
- switch (p_type) {
-
- case POINTER:
- case IPOINTER:
- case PPOINTER:
- case FPOINTER:
- genMemPointerSet (right, result, ic, pi);
- break;
-
- case GPOINTER:
- genGenPointerSet (right, result, ic, pi);
- break;
-
- default:
- werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "genPointerSet: illegal pointer type");
- }
+ operand *right, *result;
+ sym_link *type, *etype;
+ int p_type;
+
+ right = IC_RIGHT (ic);
+ result = IC_RESULT (ic);
+
+ /* depending on the type of pointer we need to
+ move it to the correct pointer register */
+ type = operandType (result);
+ etype = getSpec (type);
+ /* if left is of type of pointer then it is simple */
+ if (IS_PTR (type) && !IS_FUNC (type->next)) {
+ p_type = DCL_TYPE (type);
+ }
+ else {
+ /* we have to go by the storage class */
+ p_type = PTR_TYPE (SPEC_OCLS (etype));
+
+ }
+
+ /* now that we have the pointer type we assign
+ the pointer values */
+ switch (p_type) {
+
+ case POINTER:
+ case IPOINTER:
+ case PPOINTER:
+ case FPOINTER:
+ genMemPointerSet (right, result, ic, pi);
+ break;
+
+ case GPOINTER:
+ genGenPointerSet (right, result, ic, pi);
+ break;
+
+ default:
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "genPointerSet: illegal pointer type");
+ }
}
static void
genIfx (iCode * ic, iCode * popIc)
{
- operand *cond = IC_COND (ic);
- char *cname ;
- symbol *lbl;
- int tob = 0;
-
- aopOp (cond, ic, FALSE);
-
- /* get the value into acc */
- if (AOP_SIZE(cond) == 1 && AOP_ISHIGHREG(AOP(cond),0)) {
- cname = aopGet(AOP(cond),0);
- } else {
- toBoolean (cond, "r24", 0);
- tob = 1;
- cname = "r24";
- }
- /* the result is now in the accumulator */
- freeAsmop (cond, NULL, ic, TRUE);
-
- /* if there was something to be popped then do it */
- if (popIc) {
- genIpop (popIc);
- emitcode("cpi","%s,0",cname);
- } else if (!tob) emitcode("cpi","%s,0",cname);
-
- lbl = newiTempLabel(NULL);
- if (IC_TRUE(ic)) {
- emitcode ("breq","L%05d",lbl->key);
- emitcode ("jmp","L%05d",IC_TRUE(ic)->key);
- emitcode ("","L%05d:",lbl->key);
- } else {
- emitcode ("brne","L%05d",lbl->key);
- emitcode ("jmp","L%05d",IC_FALSE(ic)->key);
- emitcode ("","L%05d:",lbl->key);
- }
- ic->generated = 1;
+ operand *cond = IC_COND (ic);
+ char *cname ;
+ symbol *lbl;
+ int tob = 0;
+
+ aopOp (cond, ic, FALSE);
+
+ /* get the value into acc */
+ if (AOP_SIZE(cond) == 1 && AOP_ISHIGHREG(AOP(cond),0)) {
+ cname = aopGet(AOP(cond),0);
+ } else {
+ toBoolean (cond, "r24", 0);
+ tob = 1;
+ cname = "r24";
+ }
+ /* the result is now in the accumulator */
+ freeAsmop (cond, NULL, ic, TRUE);
+
+ /* if there was something to be popped then do it */
+ if (popIc) {
+ genIpop (popIc);
+ emitcode("cpi","%s,0",cname);
+ } else if (!tob) emitcode("cpi","%s,0",cname);
+
+ lbl = newiTempLabel(NULL);
+ if (IC_TRUE(ic)) {
+ emitcode ("breq","L%05d",lbl->key);
+ emitcode ("jmp","L%05d",IC_TRUE(ic)->key);
+ emitcode ("","L%05d:",lbl->key);
+ } else {
+ emitcode ("brne","L%05d",lbl->key);
+ emitcode ("jmp","L%05d",IC_FALSE(ic)->key);
+ emitcode ("","L%05d:",lbl->key);
+ }
+ ic->generated = 1;
}
/*-----------------------------------------------------------------*/
static void
genAddrOf (iCode * ic)
{
- symbol *sym = OP_SYMBOL (IC_LEFT (ic));
- int size, offset;
-
- aopOp (IC_RESULT (ic), ic, FALSE);
- assert(AOP_SIZE(IC_RESULT(ic)) >= 2);
- /* if the operand is on the stack then we
- need to get the stack offset of this
- variable */
- if (sym->onStack) {
- /* if it has an offset then we need to compute it */
- if (sym->stack) {
- if (allHigh(AOP(IC_RESULT(ic)))) {
- if (isRegPair (AOP(IC_RESULT(ic)))) {
- emitcode ("movw","%s,r28",aopGet(AOP(IC_RESULT(ic)),0));
- } else {
- emitcode ("mov","%s,r28",aopGet(AOP(IC_RESULT(ic)),0));
- emitcode ("mov","%s,r29",aopGet(AOP(IC_RESULT(ic)),1));
- }
- if (sym->stack < 0) {
- emitcode("subi","%s,<(%d)",aopGet(AOP(IC_RESULT(ic)),0),-sym->stack);
- emitcode("sbci","%s,>(%d)",aopGet(AOP(IC_RESULT(ic)),1),-sym->stack);
- } else {
- emitcode("subi","%s,<(-%d)",aopGet(AOP(IC_RESULT(ic)),0),sym->stack);
- emitcode("sbci","%s,>(-%d)",aopGet(AOP(IC_RESULT(ic)),1),sym->stack);
- }
- } else {
- emitcode("movw","r24,r28");
- if (sym->stack > -63 && sym->stack < 63) {
- if (sym->stack < 0)
- emitcode("sbiw","r24,%d",-sym->stack);
- else
- emitcode("sbiw","r24,%d",sym->stack);
- } else {
- if (sym->stack < 0) {
- emitcode("subi","r24,<(%d)",-sym->stack);
- emitcode("sbci","r25,>(%d)",-sym->stack);
- } else {
- emitcode("subi","r24,<(-%d)",sym->stack);
- emitcode("sbci","r25,>(-%d)",sym->stack);
- }
- }
-
- aopPut(AOP(IC_RESULT(ic)),"r24",0);
- aopPut(AOP(IC_RESULT(ic)),"r25",1);
- }
- }
- else {
- aopPut(AOP(IC_RESULT(ic)),"r28",0);
- aopPut(AOP(IC_RESULT(ic)),"r29",1);
- }
- /* fill the result with zero */
- size = AOP_SIZE (IC_RESULT (ic)) - 2;
- offset = 2;
- while (size--) {
- aopPut (AOP (IC_RESULT (ic)), zero, offset++);
- }
-
- goto release;
- }
-
- /* object not on stack then we need the name */
- size = AOP_SIZE (IC_RESULT (ic));
- offset = 0;
- assert(size<=2);
- while (size--) {
- char s[SDCC_NAME_MAX];
- if (offset)
- sprintf (s, ">(%s)", sym->rname);
- else
- sprintf (s, "<(%s)", sym->rname);
- aopPut (AOP (IC_RESULT (ic)), s, offset++);
- }
+ symbol *sym = OP_SYMBOL (IC_LEFT (ic));
+ int size, offset;
+
+ aopOp (IC_RESULT (ic), ic, FALSE);
+ assert(AOP_SIZE(IC_RESULT(ic)) >= 2);
+ /* if the operand is on the stack then we
+ need to get the stack offset of this
+ variable */
+ if (sym->onStack) {
+ /* if it has an offset then we need to compute it */
+ if (sym->stack) {
+ if (allHigh(AOP(IC_RESULT(ic)))) {
+ if (isRegPair (AOP(IC_RESULT(ic)))) {
+ emitcode ("movw","%s,r28",aopGet(AOP(IC_RESULT(ic)),0));
+ } else {
+ emitcode ("mov","%s,r28",aopGet(AOP(IC_RESULT(ic)),0));
+ emitcode ("mov","%s,r29",aopGet(AOP(IC_RESULT(ic)),1));
+ }
+ if (sym->stack < 0) {
+ emitcode("subi","%s,<(%d)",aopGet(AOP(IC_RESULT(ic)),0),-sym->stack);
+ emitcode("sbci","%s,>(%d)",aopGet(AOP(IC_RESULT(ic)),1),-sym->stack);
+ } else {
+ emitcode("subi","%s,<(-%d)",aopGet(AOP(IC_RESULT(ic)),0),sym->stack);
+ emitcode("sbci","%s,>(-%d)",aopGet(AOP(IC_RESULT(ic)),1),sym->stack);
+ }
+ } else {
+ emitcode("movw","r24,r28");
+ if (sym->stack > -63 && sym->stack < 63) {
+ if (sym->stack < 0)
+ emitcode("sbiw","r24,%d",-sym->stack);
+ else
+ emitcode("sbiw","r24,%d",sym->stack);
+ } else {
+ if (sym->stack < 0) {
+ emitcode("subi","r24,<(%d)",-sym->stack);
+ emitcode("sbci","r25,>(%d)",-sym->stack);
+ } else {
+ emitcode("subi","r24,<(-%d)",sym->stack);
+ emitcode("sbci","r25,>(-%d)",sym->stack);
+ }
+ }
+
+ aopPut(AOP(IC_RESULT(ic)),"r24",0);
+ aopPut(AOP(IC_RESULT(ic)),"r25",1);
+ }
+ }
+ else {
+ aopPut(AOP(IC_RESULT(ic)),"r28",0);
+ aopPut(AOP(IC_RESULT(ic)),"r29",1);
+ }
+ /* fill the result with zero */
+ size = AOP_SIZE (IC_RESULT (ic)) - 2;
+ offset = 2;
+ while (size--) {
+ aopPut (AOP (IC_RESULT (ic)), zero, offset++);
+ }
+
+ goto release;
+ }
+
+ /* object not on stack then we need the name */
+ size = AOP_SIZE (IC_RESULT (ic));
+ offset = 0;
+ assert(size<=2);
+ while (size--) {
+ char s[SDCC_NAME_MAX];
+ if (offset)
+ sprintf (s, ">(%s)", sym->rname);
+ else
+ sprintf (s, "<(%s)", sym->rname);
+ aopPut (AOP (IC_RESULT (ic)), s, offset++);
+ }
release:
- freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+ freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
}
static void
genFarFarAssign (operand * result, operand * right, iCode * ic)
{
- int size = AOP_SIZE (right);
- int offset = 0;
- char *l;
- /* first push the right side on to the stack */
- while (size--) {
- l = aopGet (AOP (right), offset++);
- MOVA (l);
- emitcode ("push", "acc");
- }
-
- freeAsmop (right, NULL, ic, FALSE);
- /* now assign DPTR to result */
- aopOp (result, ic, FALSE);
- size = AOP_SIZE (result);
- while (size--) {
- emitcode ("pop", "acc");
- aopPut (AOP (result), "a", --offset);
- }
- freeAsmop (result, NULL, ic, FALSE);
+ int size = AOP_SIZE (right);
+ int offset = 0;
+ char *l;
+ /* first push the right side on to the stack */
+ while (size--) {
+ l = aopGet (AOP (right), offset++);
+ MOVA (l);
+ emitcode ("push", "acc");
+ }
+
+ freeAsmop (right, NULL, ic, FALSE);
+ /* now assign DPTR to result */
+ aopOp (result, ic, FALSE);
+ size = AOP_SIZE (result);
+ while (size--) {
+ emitcode ("pop", "acc");
+ aopPut (AOP (result), "a", --offset);
+ }
+ freeAsmop (result, NULL, ic, FALSE);
}
static void
genAssign (iCode * ic)
{
- operand *result, *right;
- int size, offset;
- unsigned long lit = 0L;
-
- result = IC_RESULT (ic);
- right = IC_RIGHT (ic);
-
- /* if they are the same */
- if (operandsEqu (IC_RESULT (ic), IC_RIGHT (ic)))
- return;
-
- aopOp (right, ic, FALSE);
-
- /* special case both in far space */
- if (AOP_TYPE (right) == AOP_DPTR &&
- IS_TRUE_SYMOP (result) && isOperandInFarSpace (result)) {
-
- genFarFarAssign (result, right, ic);
- return;
- }
-
- aopOp (result, ic, TRUE);
-
- /* if they are the same registers */
- if (sameRegs (AOP (right), AOP (result)))
- goto release;
-
- /* if the result is a bit */
- if (AOP_TYPE (result) == AOP_CRY) {
-
- /* if the right size is a literal then
- we know what the value is */
- if (AOP_TYPE (right) == AOP_LIT) {
- if (((int) operandLitValue (right)))
- aopPut (AOP (result), one, 0);
- else
- aopPut (AOP (result), zero, 0);
- goto release;
- }
-
- /* the right is also a bit variable */
- if (AOP_TYPE (right) == AOP_CRY) {
- emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
- aopPut (AOP (result), "c", 0);
- goto release;
- }
-
- /* we need to or */
- toBoolean (right, "", 0);
- aopPut (AOP (result), "a", 0);
- goto release;
- }
-
- /* bit variables done */
- /* general case */
- size = AOP_SIZE (result);
- offset = 0;
- if (AOP_TYPE (right) == AOP_LIT)
- lit =
- (unsigned long) floatFromVal (AOP (right)->aopu.
- aop_lit);
- if ((size > 1) && (AOP_TYPE (result) != AOP_REG)
- && (AOP_TYPE (right) == AOP_LIT)
- && !IS_FLOAT (operandType (right)) && (lit < 256L)) {
- emitcode ("clr", "a");
- while (size--) {
- if ((unsigned int) ((lit >> (size * 8)) & 0x0FFL) ==
- 0) aopPut (AOP (result), "a", size);
- else
- aopPut (AOP (result),
- aopGet (AOP (right), size), size);
- }
- }
- else {
- while (size--) {
- aopPut (AOP (result),
- aopGet (AOP (right), offset), offset);
- offset++;
- }
- }
+ operand *result, *right;
+ int size, offset;
+ unsigned long lit = 0L;
+
+ result = IC_RESULT (ic);
+ right = IC_RIGHT (ic);
+
+ /* if they are the same */
+ if (operandsEqu (IC_RESULT (ic), IC_RIGHT (ic)))
+ return;
+
+ aopOp (right, ic, FALSE);
+
+ /* special case both in far space */
+ if (AOP_TYPE (right) == AOP_DPTR &&
+ IS_TRUE_SYMOP (result) && isOperandInFarSpace (result)) {
+
+ genFarFarAssign (result, right, ic);
+ return;
+ }
+
+ aopOp (result, ic, TRUE);
+
+ /* if they are the same registers */
+ if (sameRegs (AOP (right), AOP (result)))
+ goto release;
+
+ /* if the result is a bit */
+ if (AOP_TYPE (result) == AOP_CRY) {
+
+ /* if the right size is a literal then
+ we know what the value is */
+ if (AOP_TYPE (right) == AOP_LIT) {
+ if (((int) operandLitValue (right)))
+ aopPut (AOP (result), one, 0);
+ else
+ aopPut (AOP (result), zero, 0);
+ goto release;
+ }
+
+ /* the right is also a bit variable */
+ if (AOP_TYPE (right) == AOP_CRY) {
+ emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
+ aopPut (AOP (result), "c", 0);
+ goto release;
+ }
+
+ /* we need to or */
+ toBoolean (right, "", 0);
+ aopPut (AOP (result), "a", 0);
+ goto release;
+ }
+
+ /* bit variables done */
+ /* general case */
+ size = AOP_SIZE (result);
+ offset = 0;
+ if (AOP_TYPE (right) == AOP_LIT)
+ lit = ulFromVal (AOP (right)->aopu.
+ aop_lit);
+ if ((size > 1) && (AOP_TYPE (result) != AOP_REG)
+ && (AOP_TYPE (right) == AOP_LIT)
+ && !IS_FLOAT (operandType (right)) && (lit < 256L)) {
+ emitcode ("clr", "a");
+ while (size--) {
+ if ((unsigned int) ((lit >> (size * 8)) & 0x0FFL) ==
+ 0) aopPut (AOP (result), "a", size);
+ else
+ aopPut (AOP (result),
+ aopGet (AOP (right), size), size);
+ }
+ }
+ else {
+ while (size--) {
+ aopPut (AOP (result),
+ aopGet (AOP (right), offset), offset);
+ offset++;
+ }
+ }
release:
- freeAsmop (right, NULL, ic, FALSE);
- freeAsmop (result, NULL, ic, TRUE);
+ freeAsmop (right, NULL, ic, FALSE);
+ freeAsmop (result, NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
static void
genJumpTab (iCode * ic)
{
- symbol *jtab;
- char *l;
-
- aopOp (IC_JTCOND (ic), ic, FALSE);
- /* get the condition into accumulator */
- l = aopGet (AOP (IC_JTCOND (ic)), 0);
- MOVA (l);
- /* multiply by three */
- emitcode ("add", "a,acc");
- emitcode ("add", "a,%s", aopGet (AOP (IC_JTCOND (ic)), 0));
- freeAsmop (IC_JTCOND (ic), NULL, ic, TRUE);
-
- jtab = newiTempLabel (NULL);
- emitcode ("mov", "dptr,#%05d$", jtab->key + 100);
- emitcode ("jmp", "@a+dptr");
- emitcode ("", "%05d$:", jtab->key + 100);
- /* now generate the jump labels */
- for (jtab = setFirstItem (IC_JTLABELS (ic)); jtab;
- jtab = setNextItem (IC_JTLABELS (ic)))
- emitcode ("ljmp", "%05d$", jtab->key + 100);
+ symbol *jtab;
+ char *l;
+
+ aopOp (IC_JTCOND (ic), ic, FALSE);
+ /* get the condition into accumulator */
+ l = aopGet (AOP (IC_JTCOND (ic)), 0);
+ MOVA (l);
+ /* multiply by three */
+ emitcode ("add", "a,acc");
+ emitcode ("add", "a,%s", aopGet (AOP (IC_JTCOND (ic)), 0));
+ freeAsmop (IC_JTCOND (ic), NULL, ic, TRUE);
+
+ jtab = newiTempLabel (NULL);
+ emitcode ("mov", "dptr,#%05d$", jtab->key + 100);
+ emitcode ("jmp", "@a+dptr");
+ emitcode ("", "%05d$:", jtab->key + 100);
+ /* now generate the jump labels */
+ for (jtab = setFirstItem (IC_JTLABELS (ic)); jtab;
+ jtab = setNextItem (IC_JTLABELS (ic)))
+ emitcode ("ljmp", "%05d$", jtab->key + 100);
}
static void
genCast (iCode * ic)
{
- operand *result = IC_RESULT (ic);
- sym_link *ctype = operandType (IC_LEFT (ic));
- sym_link *rtype = operandType (IC_RIGHT (ic));
- operand *right = IC_RIGHT (ic);
- int size, offset;
-
- /* if they are equivalent then do nothing */
- if (operandsEqu (IC_RESULT (ic), IC_RIGHT (ic)))
- return;
-
- aopOp (right, ic, FALSE);
- aopOp (result, ic, FALSE);
-
- /* if the result is a bit */
- if (AOP_TYPE (result) == AOP_CRY) {
- /* if the right size is a literal then
- we know what the value is */
- if (AOP_TYPE (right) == AOP_LIT) {
- if (((int) operandLitValue (right)))
- aopPut (AOP (result), one, 0);
- else
- aopPut (AOP (result), zero, 0);
-
- goto release;
- }
-
- /* the right is also a bit variable */
- if (AOP_TYPE (right) == AOP_CRY) {
- emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
- aopPut (AOP (result), "c", 0);
- goto release;
- }
-
- /* we need to or */
- toBoolean (right, "", 0);
- aopPut (AOP (result), "a", 0);
- goto release;
- }
-
- /* if they are the same size : or less */
- if (AOP_SIZE (result) <= AOP_SIZE (right)) {
-
- /* if they are in the same place */
- if (sameRegs (AOP (right), AOP (result)))
- goto release;
-
- /* if they in different places then copy */
- size = AOP_SIZE (result);
- offset = 0;
- while (size--) {
- aopPut (AOP (result),
- aopGet (AOP (right), offset), offset);
- offset++;
- }
- goto release;
- }
-
-
- /* if the result is of type pointer */
- if (IS_PTR (ctype)) {
-
- int p_type;
- sym_link *type = operandType (right);
- sym_link *etype = getSpec (type);
-
- /* pointer to generic pointer */
- if (IS_GENPTR (ctype)) {
- if (IS_PTR (type))
- p_type = DCL_TYPE (type);
- else {
- /* we have to go by the storage class */
- p_type = PTR_TYPE (SPEC_OCLS (etype));
- }
-
- /* the first two bytes are known */
- size = GPTRSIZE - 1;
- offset = 0;
- while (size--) {
- aopPut (AOP (result),
- aopGet (AOP (right), offset), offset);
- offset++;
- }
-
- /* the last byte depending on type */
- {
- int gpVal = pointerTypeToGPByte(p_type, NULL, NULL);
- char gpValStr[10];
-
- if (gpVal == -1)
- {
- // pointerTypeToGPByte will have bitched.
- exit(1);
- }
-
- sprintf(gpValStr, "#0x%x", gpVal);
- aopPut (AOP (result), gpValStr, GPTRSIZE - 1);
- }
- goto release;
- }
-
- /* just copy the pointers */
- size = AOP_SIZE (result);
- offset = 0;
- while (size--) {
- aopPut (AOP (result),
- aopGet (AOP (right), offset), offset);
- offset++;
- }
- goto release;
- }
-
- /* so we now know that the size of destination is greater
- than the size of the source */
- /* we move to result for the size of source */
- size = AOP_SIZE (right);
- offset = 0;
- while (size--) {
- aopPut (AOP (result), aopGet (AOP (right), offset), offset);
- offset++;
- }
-
- /* now depending on the sign of the source && destination */
- size = AOP_SIZE (result) - AOP_SIZE (right);
- /* if unsigned or not an integral type */
- if (SPEC_USIGN (rtype) || !IS_SPEC (rtype)) {
- while (size--)
- aopPut (AOP (result), zero, offset++);
- }
- else {
- /* we need to extend the sign :{ */
+ operand *result = IC_RESULT (ic);
+ sym_link *ctype = operandType (IC_LEFT (ic));
+ sym_link *rtype = operandType (IC_RIGHT (ic));
+ operand *right = IC_RIGHT (ic);
+ int size, offset;
+
+ /* if they are equivalent then do nothing */
+ if (operandsEqu (IC_RESULT (ic), IC_RIGHT (ic)))
+ return;
+
+ aopOp (right, ic, FALSE);
+ aopOp (result, ic, FALSE);
+
+ /* if the result is a bit */
+ if (AOP_TYPE (result) == AOP_CRY) {
+ /* if the right size is a literal then
+ we know what the value is */
+ if (AOP_TYPE (right) == AOP_LIT) {
+ if (((int) operandLitValue (right)))
+ aopPut (AOP (result), one, 0);
+ else
+ aopPut (AOP (result), zero, 0);
+
+ goto release;
+ }
+
+ /* the right is also a bit variable */
+ if (AOP_TYPE (right) == AOP_CRY) {
+ emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
+ aopPut (AOP (result), "c", 0);
+ goto release;
+ }
+
+ /* we need to or */
+ toBoolean (right, "", 0);
+ aopPut (AOP (result), "a", 0);
+ goto release;
+ }
+
+ /* if they are the same size : or less */
+ if (AOP_SIZE (result) <= AOP_SIZE (right)) {
+
+ /* if they are in the same place */
+ if (sameRegs (AOP (right), AOP (result)))
+ goto release;
+
+ /* if they in different places then copy */
+ size = AOP_SIZE (result);
+ offset = 0;
+ while (size--) {
+ aopPut (AOP (result),
+ aopGet (AOP (right), offset), offset);
+ offset++;
+ }
+ goto release;
+ }
+
+
+ /* if the result is of type pointer */
+ if (IS_PTR (ctype)) {
+
+ int p_type;
+ sym_link *type = operandType (right);
+ sym_link *etype = getSpec (type);
+
+ /* pointer to generic pointer */
+ if (IS_GENPTR (ctype)) {
+ if (IS_PTR (type))
+ p_type = DCL_TYPE (type);
+ else {
+ /* we have to go by the storage class */
+ p_type = PTR_TYPE (SPEC_OCLS (etype));
+ }
+
+ /* the first two bytes are known */
+ size = GPTRSIZE - 1;
+ offset = 0;
+ while (size--) {
+ aopPut (AOP (result),
+ aopGet (AOP (right), offset), offset);
+ offset++;
+ }
+
+ /* the last byte depending on type */
+ {
+ int gpVal = pointerTypeToGPByte(p_type, NULL, NULL);
+ char gpValStr[10];
+
+ if (gpVal == -1)
+ {
+ // pointerTypeToGPByte will have bitched.
+ exit(1);
+ }
+
+ sprintf(gpValStr, "#0x%x", gpVal);
+ aopPut (AOP (result), gpValStr, GPTRSIZE - 1);
+ }
+ goto release;
+ }
+
+ /* just copy the pointers */
+ size = AOP_SIZE (result);
+ offset = 0;
+ while (size--) {
+ aopPut (AOP (result),
+ aopGet (AOP (right), offset), offset);
+ offset++;
+ }
+ goto release;
+ }
+
+ /* so we now know that the size of destination is greater
+ than the size of the source */
+ /* we move to result for the size of source */
+ size = AOP_SIZE (right);
+ offset = 0;
+ while (size--) {
+ aopPut (AOP (result), aopGet (AOP (right), offset), offset);
+ offset++;
+ }
+
+ /* now depending on the sign of the source && destination */
+ size = AOP_SIZE (result) - AOP_SIZE (right);
+ /* if unsigned or not an integral type */
+ if (SPEC_USIGN (rtype) || !IS_SPEC (rtype)) {
+ while (size--)
+ aopPut (AOP (result), zero, offset++);
+ }
+ else {
+ /* we need to extend the sign :{ */
// PENDING: Does nothing on avr
#if 0
- char *l = aopGet (AOP (right), AOP_SIZE (right) - 1);
- MOVA (l);
+ char *l = aopGet (AOP (right), AOP_SIZE (right) - 1);
+ MOVA (l);
#endif
- emitcode ("rlc", "a");
- emitcode ("subb", "a,acc");
- while (size--)
- aopPut (AOP (result), "a", offset++);
- }
+ emitcode ("rlc", "a");
+ emitcode ("subb", "a,acc");
+ while (size--)
+ aopPut (AOP (result), "a", offset++);
+ }
- /* we are done hurray !!!! */
+ /* we are done hurray !!!! */
release:
- freeAsmop (right, NULL, ic, TRUE);
- freeAsmop (result, NULL, ic, TRUE);
+ freeAsmop (right, NULL, ic, TRUE);
+ freeAsmop (result, NULL, ic, TRUE);
}
static int
genDjnz (iCode * ic, iCode * ifx)
{
- symbol *lbl, *lbl1;
- if (!ifx)
- return 0;
-
- /* if the if condition has a false label
- then we cannot save */
- if (IC_FALSE (ifx))
- return 0;
-
- /* if the minus is not of the form
- a = a - 1 */
- if (!isOperandEqual (IC_RESULT (ic), IC_LEFT (ic)) ||
- !IS_OP_LITERAL (IC_RIGHT (ic)))
- return 0;
-
- if (operandLitValue (IC_RIGHT (ic)) != 1)
- return 0;
-
- /* if the size of this greater than one then no
- saving */
- if (getSize (operandType (IC_RESULT (ic))) > 1)
- return 0;
-
- /* otherwise we can save BIG */
- lbl = newiTempLabel (NULL);
- lbl1 = newiTempLabel (NULL);
-
- aopOp (IC_RESULT (ic), ic, FALSE);
-
- if (IS_AOP_PREG (IC_RESULT (ic))) {
- emitcode ("dec", "%s", aopGet (AOP (IC_RESULT (ic)), 0));
- emitcode ("mov", "a,%s", aopGet (AOP (IC_RESULT (ic)), 0));
- emitcode ("jnz", "%05d$", lbl->key + 100);
- }
- else {
- emitcode ("djnz", "%s,%05d$",
- aopGet (AOP (IC_RESULT (ic)), 0), lbl->key + 100);
- }
- emitcode ("sjmp", "%05d$", lbl1->key + 100);
- emitcode ("", "%05d$:", lbl->key + 100);
- emitcode ("ljmp", "%05d$", IC_TRUE (ifx)->key + 100);
- emitcode ("", "%05d$:", lbl1->key + 100);
-
- freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
- ifx->generated = 1;
- return 1;
+ symbol *lbl, *lbl1;
+ if (!ifx)
+ return 0;
+
+ /* if the if condition has a false label
+ then we cannot save */
+ if (IC_FALSE (ifx))
+ return 0;
+
+ /* if the minus is not of the form
+ a = a - 1 */
+ if (!isOperandEqual (IC_RESULT (ic), IC_LEFT (ic)) ||
+ !IS_OP_LITERAL (IC_RIGHT (ic)))
+ return 0;
+
+ if (operandLitValue (IC_RIGHT (ic)) != 1)
+ return 0;
+
+ /* if the size of this greater than one then no
+ saving */
+ if (getSize (operandType (IC_RESULT (ic))) > 1)
+ return 0;
+
+ /* otherwise we can save BIG */
+ lbl = newiTempLabel (NULL);
+ lbl1 = newiTempLabel (NULL);
+
+ aopOp (IC_RESULT (ic), ic, FALSE);
+
+ if (IS_AOP_PREG (IC_RESULT (ic))) {
+ emitcode ("dec", "%s", aopGet (AOP (IC_RESULT (ic)), 0));
+ emitcode ("mov", "a,%s", aopGet (AOP (IC_RESULT (ic)), 0));
+ emitcode ("jnz", "%05d$", lbl->key + 100);
+ }
+ else {
+ emitcode ("djnz", "%s,%05d$",
+ aopGet (AOP (IC_RESULT (ic)), 0), lbl->key + 100);
+ }
+ emitcode ("sjmp", "%05d$", lbl1->key + 100);
+ emitcode ("", "%05d$:", lbl->key + 100);
+ emitcode ("ljmp", "%05d$", IC_TRUE (ifx)->key + 100);
+ emitcode ("", "%05d$:", lbl1->key + 100);
+
+ freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+ ifx->generated = 1;
+ return 1;
}
static char *recvregs[8] = {
- "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23"
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23"
};
static int recvCnt = 0;
static void
genReceive (iCode * ic)
{
- int size, offset = 0;
- aopOp (IC_RESULT (ic), ic, FALSE);
- size = AOP_SIZE (IC_RESULT (ic));
- while (size--) {
- aopPut (AOP (IC_RESULT (ic)), recvregs[recvCnt++], offset);
- offset++;
- }
- freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+ int size, offset = 0;
+ aopOp (IC_RESULT (ic), ic, FALSE);
+ size = AOP_SIZE (IC_RESULT (ic));
+ while (size--) {
+ aopPut (AOP (IC_RESULT (ic)), recvregs[recvCnt++], offset);
+ offset++;
+ }
+ freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
void
genAVRCode (iCode * lic)
{
- iCode *ic;
- int cln = 0;
-
- lineHead = lineCurr = NULL;
- recvCnt = 0;
- /* print the allocation information */
- if (allocInfo)
- printAllocInfo (currFunc, codeOutBuf);
- /* if debug information required */
- if (options.debug && currFunc) {
- debugFile->writeFunction (currFunc, lic);
- }
- /* stack pointer name */
- spname = "sp";
-
-
- for (ic = lic; ic; ic = ic->next) {
-
- if (cln != ic->lineno) {
- if (options.debug) {
- debugFile->writeCLine (ic);
- }
- emitcode (";", "%s %d", ic->filename, ic->lineno);
- cln = ic->lineno;
- }
- /* if the result is marked as
- spilt and rematerializable or code for
- this has already been generated then
- do nothing */
- if (resultRemat (ic) || ic->generated)
- continue;
-
- /* depending on the operation */
- switch (ic->op) {
- case '!':
- genNot (ic);
- break;
-
- case '~':
- genCpl (ic);
- break;
-
- case UNARYMINUS:
- genUminus (ic);
- break;
-
- case IPUSH:
- genIpush (ic);
- break;
-
- case IPOP:
- /* IPOP happens only when trying to restore a
- spilt live range, if there is an ifx statement
- following this pop then the if statement might
- be using some of the registers being popped which
- would destory the contents of the register so
- we need to check for this condition and handle it */
- if (ic->next &&
- ic->next->op == IFX &&
- regsInCommon (IC_LEFT (ic), IC_COND (ic->next)))
- genIfx (ic->next, ic);
- else
- genIpop (ic);
- break;
-
- case CALL:
- genCall (ic);
- break;
-
- case PCALL:
- genPcall (ic);
- break;
-
- case FUNCTION:
- genFunction (ic);
- break;
-
- case ENDFUNCTION:
- genEndFunction (ic);
- break;
-
- case RETURN:
- genRet (ic);
- break;
-
- case LABEL:
- genLabel (ic);
- break;
-
- case GOTO:
- genGoto (ic);
- break;
-
- case '+':
- genPlus (ic);
- break;
-
- case '-':
- if (!genDjnz (ic, ifxForOp (IC_RESULT (ic), ic)))
- genMinus (ic);
- break;
-
- case '*':
- genMult (ic);
- break;
-
- case '/':
- genDiv (ic);
- break;
-
- case '%':
- genMod (ic);
- break;
-
- case '>':
- genCmpGt (ic, ifxForOp (IC_RESULT (ic), ic));
- break;
-
- case '<':
- genCmpLt (ic, ifxForOp (IC_RESULT (ic), ic));
- break;
-
- case LE_OP:
- genCmpLe (ic, ifxForOp (IC_RESULT (ic), ic));
- break;
-
- case GE_OP:
- genCmpGe (ic, ifxForOp (IC_RESULT (ic), ic));
- break;
-
- case NE_OP:
- genCmpNe (ic, ifxForOp (IC_RESULT (ic), ic));
- break;
-
- case EQ_OP:
- genCmpEq (ic, ifxForOp (IC_RESULT (ic), ic));
- break;
-
- case AND_OP:
- genAndOp (ic);
- break;
-
- case OR_OP:
- genOrOp (ic);
- break;
-
- case '^':
- genXor (ic, ifxForOp (IC_RESULT (ic), ic));
- break;
-
- case '|':
- genOr (ic, ifxForOp (IC_RESULT (ic), ic));
- break;
-
- case BITWISEAND:
- genAnd (ic, ifxForOp (IC_RESULT (ic), ic));
- break;
-
- case INLINEASM:
- genInline (ic);
- break;
-
- case RRC:
- genRRC (ic);
- break;
-
- case RLC:
- genRLC (ic);
- break;
-
- case GETHBIT:
- genGetHbit (ic);
- break;
-
- case LEFT_OP:
- genLeftShift (ic);
- break;
-
- case RIGHT_OP:
- genRightShift (ic);
- break;
-
- case GET_VALUE_AT_ADDRESS:
- genPointerGet (ic, hasInc(IC_LEFT(ic),ic));
- break;
-
- case '=':
- if (POINTER_SET (ic))
- genPointerSet (ic, hasInc(IC_RESULT(ic),ic));
- else
- genAssign (ic);
- break;
-
- case IFX:
- genIfx (ic, NULL);
- break;
-
- case ADDRESS_OF:
- genAddrOf (ic);
- break;
-
- case JUMPTABLE:
- genJumpTab (ic);
- break;
-
- case CAST:
- genCast (ic);
- break;
-
- case RECEIVE:
- genReceive (ic);
- break;
-
- case SEND:
- addSet (&_G.sendSet, ic);
- break;
+ iCode *ic;
+ int cln = 0;
+
+ lineHead = lineCurr = NULL;
+ recvCnt = 0;
+ /* print the allocation information */
+ if (allocInfo)
+ printAllocInfo (currFunc, codeOutBuf);
+ /* if debug information required */
+ if (options.debug && currFunc) {
+ debugFile->writeFunction (currFunc, lic);
+ }
+ /* stack pointer name */
+ spname = "sp";
+
+
+ for (ic = lic; ic; ic = ic->next) {
+
+ if (cln != ic->lineno) {
+ if (options.debug) {
+ debugFile->writeCLine (ic);
+ }
+ emitcode (";", "%s %d", ic->filename, ic->lineno);
+ cln = ic->lineno;
+ }
+ /* if the result is marked as
+ spilt and rematerializable or code for
+ this has already been generated then
+ do nothing */
+ if (resultRemat (ic) || ic->generated)
+ continue;
+
+ /* depending on the operation */
+ switch (ic->op) {
+ case '!':
+ genNot (ic);
+ break;
+
+ case '~':
+ genCpl (ic);
+ break;
+
+ case UNARYMINUS:
+ genUminus (ic);
+ break;
+
+ case IPUSH:
+ genIpush (ic);
+ break;
+
+ case IPOP:
+ /* IPOP happens only when trying to restore a
+ spilt live range, if there is an ifx statement
+ following this pop then the if statement might
+ be using some of the registers being popped which
+ would destory the contents of the register so
+ we need to check for this condition and handle it */
+ if (ic->next &&
+ ic->next->op == IFX &&
+ regsInCommon (IC_LEFT (ic), IC_COND (ic->next)))
+ genIfx (ic->next, ic);
+ else
+ genIpop (ic);
+ break;
+
+ case CALL:
+ genCall (ic);
+ break;
+
+ case PCALL:
+ genPcall (ic);
+ break;
+
+ case FUNCTION:
+ genFunction (ic);
+ break;
+
+ case ENDFUNCTION:
+ genEndFunction (ic);
+ break;
+
+ case RETURN:
+ genRet (ic);
+ break;
+
+ case LABEL:
+ genLabel (ic);
+ break;
+
+ case GOTO:
+ genGoto (ic);
+ break;
+
+ case '+':
+ genPlus (ic);
+ break;
+
+ case '-':
+ if (!genDjnz (ic, ifxForOp (IC_RESULT (ic), ic)))
+ genMinus (ic);
+ break;
+
+ case '*':
+ genMult (ic);
+ break;
+
+ case '/':
+ genDiv (ic);
+ break;
+
+ case '%':
+ genMod (ic);
+ break;
+
+ case '>':
+ genCmpGt (ic, ifxForOp (IC_RESULT (ic), ic));
+ break;
+
+ case '<':
+ genCmpLt (ic, ifxForOp (IC_RESULT (ic), ic));
+ break;
+
+ case LE_OP:
+ genCmpLe (ic, ifxForOp (IC_RESULT (ic), ic));
+ break;
+
+ case GE_OP:
+ genCmpGe (ic, ifxForOp (IC_RESULT (ic), ic));
+ break;
+
+ case NE_OP:
+ genCmpNe (ic, ifxForOp (IC_RESULT (ic), ic));
+ break;
+
+ case EQ_OP:
+ genCmpEq (ic, ifxForOp (IC_RESULT (ic), ic));
+ break;
+
+ case AND_OP:
+ genAndOp (ic);
+ break;
+
+ case OR_OP:
+ genOrOp (ic);
+ break;
+
+ case '^':
+ genXor (ic, ifxForOp (IC_RESULT (ic), ic));
+ break;
+
+ case '|':
+ genOr (ic, ifxForOp (IC_RESULT (ic), ic));
+ break;
+
+ case BITWISEAND:
+ genAnd (ic, ifxForOp (IC_RESULT (ic), ic));
+ break;
+
+ case INLINEASM:
+ genInline (ic);
+ break;
+
+ case RRC:
+ genRRC (ic);
+ break;
+
+ case RLC:
+ genRLC (ic);
+ break;
+
+ case GETHBIT:
+ genGetHbit (ic);
+ break;
+
+ case LEFT_OP:
+ genLeftShift (ic);
+ break;
+
+ case RIGHT_OP:
+ genRightShift (ic);
+ break;
+
+ case GET_VALUE_AT_ADDRESS:
+ genPointerGet (ic, hasInc(IC_LEFT(ic),ic));
+ break;
+
+ case '=':
+ if (POINTER_SET (ic))
+ genPointerSet (ic, hasInc(IC_RESULT(ic),ic));
+ else
+ genAssign (ic);
+ break;
+
+ case IFX:
+ genIfx (ic, NULL);
+ break;
+
+ case ADDRESS_OF:
+ genAddrOf (ic);
+ break;
+
+ case JUMPTABLE:
+ genJumpTab (ic);
+ break;
+
+ case CAST:
+ genCast (ic);
+ break;
+
+ case RECEIVE:
+ genReceive (ic);
+ break;
+
+ case SEND:
+ addSet (&_G.sendSet, ic);
+ break;
+
+ case DUMMY_READ_VOLATILE:
+ genDummyRead (ic);
+ break;
+
+ default:
+ ic = ic;
+ }
+ }
- case DUMMY_READ_VOLATILE:
- genDummyRead (ic);
- break;
- default:
- ic = ic;
- }
- }
+ /* now we are ready to call the
+ peep hole optimizer */
+ if (!options.nopeep)
+ peepHole (&lineHead);
-
- /* now we are ready to call the
- peep hole optimizer */
- if (!options.nopeep)
- peepHole (&lineHead);
-
- /* now do the actual printing */
- printLine (lineHead, codeOutBuf);
- return;
+ /* now do the actual printing */
+ printLine (lineHead, codeOutBuf);
+ return;
}
/* if the literal value of the right hand side
is greater than 4 then it is not worth it */
- if ((icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 4)
+ if ((icount = (unsigned int) ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 4)
return FALSE;
if (size == 1 && AOP(IC_LEFT(ic)) == AOP(IC_RESULT(ic)) &&
if ( AOP_IS_STR (IC_LEFT (ic)) &&
isOperandLiteral (IC_RIGHT (ic)) && OP_SYMBOL (IC_RESULT (ic))->ruonly) {
aopOp (IC_RIGHT (ic), ic, TRUE, FALSE);
- size = (int)floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
+ size = (int) ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
if (size <= 9) {
while (size--) emitcode ("inc","dptr");
} else {
/* if result in bit space */
if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY)
{
- if ((unsigned long) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit) != 0L)
+ if (ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit) != 0L)
emitcode ("cpl", "c");
outBitC (IC_RESULT (ic));
}
/* if the literal value of the right hand side
is greater than 4 then it is not worth it */
- if ((icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 4)
+ if ((icount = (unsigned int) ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 4)
return FALSE;
if (size == 1 && AOP(IC_LEFT(ic)) == AOP(IC_RESULT(ic)) &&
}
else
{
- lit = (long) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
+ lit = (long) ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
lit = -lit;
}
if (AOP_TYPE(left) == AOP_LIT)
{
/* signed literal */
- signed char val = (char) floatFromVal (AOP (left)->aopu.aop_lit);
+ signed char val = (char) ulFromVal (AOP (left)->aopu.aop_lit);
if (val < 0)
compiletimeSign = TRUE;
}
if (AOP_TYPE(right) == AOP_LIT)
{
/* signed literal */
- signed char val = (char) floatFromVal (AOP (right)->aopu.aop_lit);
+ signed char val = (char) ulFromVal (AOP (right)->aopu.aop_lit);
if (val < 0)
compiletimeSign ^= TRUE;
}
/* save the signs of the operands */
if (AOP_TYPE(right) == AOP_LIT)
{
- signed char val = (char) floatFromVal (AOP (right)->aopu.aop_lit);
+ signed char val = (char) ulFromVal (AOP (right)->aopu.aop_lit);
if (!rUnsigned && val < 0)
emitcode ("mov", "b,#!constbyte", -val);
if (AOP_TYPE(left) == AOP_LIT)
{
- signed char val = (char) floatFromVal (AOP (left)->aopu.aop_lit);
+ signed char val = (char) ulFromVal (AOP (left)->aopu.aop_lit);
if (!lUnsigned && val < 0)
emitcode ("mov", "a,#!constbyte", -val);
if (!umult) {
emitcode("clr","F0");
if (AOP_TYPE(right) == AOP_LIT) {
- int val=(int)floatFromVal (AOP (right)->aopu.aop_lit);
+ int val=(int) ulFromVal (AOP (right)->aopu.aop_lit);
if (val < 0) {
emitcode("setb","F0");
val = -val;
if (AOP_TYPE(left) == AOP_LIT)
{
/* signed literal */
- signed char val = (char) floatFromVal (AOP (left)->aopu.aop_lit);
+ signed char val = (char) ulFromVal (AOP (left)->aopu.aop_lit);
if (val < 0)
compiletimeSign = TRUE;
}
if (AOP_TYPE(right) == AOP_LIT)
{
/* signed literal */
- signed char val = (char) floatFromVal (AOP (right)->aopu.aop_lit);
+ signed char val = (char) ulFromVal (AOP (right)->aopu.aop_lit);
if (val < 0)
compiletimeSign ^= TRUE;
}
/* save the signs of the operands */
if (AOP_TYPE(right) == AOP_LIT)
{
- signed char val = (char) floatFromVal (AOP (right)->aopu.aop_lit);
+ signed char val = (char) ulFromVal (AOP (right)->aopu.aop_lit);
if (!rUnsigned && val < 0)
emitcode ("mov", "b,#0x%02x", -val);
if (AOP_TYPE(left) == AOP_LIT)
{
- signed char val = (char) floatFromVal (AOP (left)->aopu.aop_lit);
+ signed char val = (char) ulFromVal (AOP (left)->aopu.aop_lit);
if (!lUnsigned && val < 0)
emitcode ("mov", "a,#0x%02x", -val);
/* load up MB with right */
if (!umult) {
if (AOP_TYPE(right) == AOP_LIT) {
- int val=(int)floatFromVal (AOP (right)->aopu.aop_lit);
+ int val=(int) ulFromVal (AOP (right)->aopu.aop_lit);
if (val < 0) {
lbl = newiTempLabel(NULL);
emitcode ("jbc","F0,!tlabel",lbl->key+100);
/* modulus: sign of the right operand has no influence on the result! */
if (AOP_TYPE(right) == AOP_LIT)
{
- signed char val = (char) floatFromVal (AOP (right)->aopu.aop_lit);
+ signed char val = (char) ulFromVal (AOP (right)->aopu.aop_lit);
if (!rUnsigned && val < 0)
emitcode ("mov", "b,#0x%02x", -val);
/* sign adjust left side */
if (AOP_TYPE(left) == AOP_LIT)
{
- signed char val = (char) floatFromVal (AOP (left)->aopu.aop_lit);
+ signed char val = (char) ulFromVal (AOP (left)->aopu.aop_lit);
if (!lUnsigned && val < 0)
{
/* load up MB with right */
if (!umult) {
if (AOP_TYPE(right) == AOP_LIT) {
- int val=(int)floatFromVal (AOP (right)->aopu.aop_lit);
+ int val=(int) ulFromVal (AOP (right)->aopu.aop_lit);
if (val < 0) {
val = -val;
}
{
if (AOP_TYPE (right) == AOP_LIT)
{
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+ lit = ulFromVal (AOP (right)->aopu.aop_lit);
/* optimize if(x < 0) or if(x >= 0) */
if (lit == 0L)
{
emitcode ("xrl", "a,#!constbyte",0x80);
if (AOP_TYPE (right) == AOP_LIT)
{
- unsigned long lit = (unsigned long)
- floatFromVal (AOP (right)->aopu.aop_lit);
+ unsigned long lit = ulFromVal (AOP (right)->aopu.aop_lit);
// emitcode (";", "genCmp #3.1");
emitcode ("subb", "a,#!constbyte",
0x80 ^ (unsigned int) ((lit >> (offset * 8)) & 0x0FFL));
}
if (AOP_TYPE (right) == AOP_LIT)
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+ lit = ulFromVal (AOP (right)->aopu.aop_lit);
if (opIsGptr (left) || opIsGptr (right))
{
{
if (AOP_TYPE (right) == AOP_LIT)
{
- unsigned long lit = (unsigned long) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
+ unsigned long lit = ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
if (lit == 0L)
{
emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
{
if (AOP_TYPE (right) == AOP_LIT)
{
- unsigned long lit = (unsigned long) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
+ unsigned long lit = ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
if (lit == 0L)
{
emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
left = tmp;
}
if (AOP_TYPE (right) == AOP_LIT)
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+ lit = ulFromVal (AOP (right)->aopu.aop_lit);
size = AOP_SIZE (result);
left = tmp;
}
if (AOP_TYPE (right) == AOP_LIT)
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+ lit = ulFromVal (AOP (right)->aopu.aop_lit);
size = AOP_SIZE (result);
left = tmp;
}
if (AOP_TYPE (right) == AOP_LIT)
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+ lit = ulFromVal (AOP (right)->aopu.aop_lit);
size = AOP_SIZE (result);
operand * result,
iCode * ic)
{
- int shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+ int shCount = (int) ulFromVal (AOP (right)->aopu.aop_lit);
int size;
size = getSize (operandType (result));
* some small improvement.
*/
emitcode("mov", "b,#!constbyte",
- ((int) floatFromVal (AOP (right)->aopu.aop_lit)) + 1);
+ ((int) ulFromVal (AOP (right)->aopu.aop_lit)) + 1);
}
else
{
iCode * ic,
int sign)
{
- int shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+ int shCount = (int) ulFromVal (AOP (right)->aopu.aop_lit);
int size;
size = getSize (operandType (result));
* some small improvement.
*/
emitcode("mov", "b,#!constbyte",
- ((int) floatFromVal (AOP (right)->aopu.aop_lit)) + 1);
+ ((int) ulFromVal (AOP (right)->aopu.aop_lit)) + 1);
}
else
{
* some small improvement.
*/
emitcode("mov", "b,#!constbyte",
- ((int) floatFromVal (AOP (right)->aopu.aop_lit)) + 1);
+ ((int) ulFromVal (AOP (right)->aopu.aop_lit)) + 1);
}
else
{
{
/* Case with a bitfield length <8 and literal source
*/
- litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+ litval = (int) ulFromVal (AOP (right)->aopu.aop_lit);
litval <<= bstr;
litval &= (~mask) & 0xff;
emitPtrByteGet (rname, p_type, FALSE);
{
/* Case with partial byte and literal source
*/
- litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+ litval = (int) ulFromVal (AOP (right)->aopu.aop_lit);
litval >>= (blen-rlen);
litval &= (~mask) & 0xff;
emitPtrByteGet (rname, p_type, FALSE);
size = AOP_SIZE (result);
offset = 0;
if (AOP_TYPE (right) == AOP_LIT)
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+ lit = ulFromVal (AOP (right)->aopu.aop_lit);
if ((size > 1) &&
(AOP_TYPE (result) != AOP_REG) &&
/* now for the actual copy */
if (AOP_TYPE(count) == AOP_LIT &&
- (int)floatFromVal (AOP(count)->aopu.aop_lit) <= 256) {
+ (int) ulFromVal (AOP(count)->aopu.aop_lit) <= 256) {
emitcode ("mov", "b,%s",aopGet(count,0,FALSE,FALSE,NULL));
if (fromc) {
emitcode ("lcall","__bi_memcpyc2x_s");
/* now for the actual compare */
if (AOP_TYPE(count) == AOP_LIT &&
- (int)floatFromVal (AOP(count)->aopu.aop_lit) <= 256) {
+ (int) ulFromVal (AOP(count)->aopu.aop_lit) <= 256) {
emitcode ("mov", "b,%s",aopGet(count,0,FALSE,FALSE,NULL));
if (fromc)
emitcode("lcall","__bi_memcmpc2x_s");
/* now for the actual copy */
if (AOP_TYPE(count) == AOP_LIT &&
- (int)floatFromVal (AOP(count)->aopu.aop_lit) <= 256) {
+ (int) ulFromVal (AOP(count)->aopu.aop_lit) <= 256) {
emitcode (";","OH JOY auto increment with djnz (very fast)");
emitcode ("mov", "dps,#!constbyte",0x1); /* Select DPTR2 */
emitcode ("mov", "b,%s",aopGet(count,0,FALSE,FALSE,NULL));
/* now for the actual copy */
if (AOP_TYPE(count) == AOP_LIT &&
- (int)floatFromVal (AOP(count)->aopu.aop_lit) <= 256) {
+ (int) ulFromVal (AOP(count)->aopu.aop_lit) <= 256) {
emitcode (";","OH JOY auto increment with djnz (very fast)");
emitcode ("mov", "dps,#!constbyte",0x0); /* Select DPTR */
emitcode ("mov", "b,%s",aopGet(count,0,FALSE,FALSE,NULL));
lbl =newiTempLabel(NULL);
/* now for the actual copy */
if (AOP_TYPE(count) == AOP_LIT &&
- (int)floatFromVal (AOP(count)->aopu.aop_lit) <= 256) {
+ (int) ulFromVal (AOP(count)->aopu.aop_lit) <= 256) {
l = aopGet(val, 0, FALSE, FALSE, NULL);
emitcode ("mov", "b,%s",aopGet(count,0,FALSE,FALSE,NULL));
MOVA(l);
#endif
default:
- /* This should never happen, right? */
- fprintf(stderr, "*** Probable error: unsupported op 0x%x (%c) in %s @ %d\n",
- ic->op, ic->op, __FILE__, __LINE__);
- ic = ic;
- }
+ /* This should never happen, right? */
+ fprintf(stderr, "*** Probable error: unsupported op 0x%x (%c) in %s @ %d\n",
+ ic->op, ic->op, __FILE__, __LINE__);
+ ic = ic;
+ }
}
char *fReturnhc08[] =
{"a", "x", "_ret2", "_ret3"};
-unsigned fReturnSizeHC08 = 4; /* shared with ralloc.c */
+unsigned fReturnSizeHC08 = 4; /* shared with ralloc.c */
char **fReturn2 = fReturnhc08;
if (inst && *inst)
{
if (fmt && *fmt)
- sprintf (lb, "%s\t", inst);
+ sprintf (lb, "%s\t", inst);
else
- sprintf (lb, "%s", inst);
+ sprintf (lb, "%s", inst);
vsprintf (lb + (strlen (lb)), fmt, ap);
}
else
if (lbp && *lbp)
lineCurr = (lineCurr ?
- connectLine (lineCurr, newLineNode (lb)) :
- (lineHead = newLineNode (lb)));
+ connectLine (lineCurr, newLineNode (lb)) :
+ (lineHead = newLineNode (lb)));
lineCurr->isInline = _G.inLine;
lineCurr->isDebug = _G.debugLine;
lineCurr->ic = _G.current_iCode;
if (!sreg)
{
werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "NULL sreg in transferRegReg");
+ "NULL sreg in transferRegReg");
return;
}
switch (srcidx)
{
case H_IDX: /* H to A */
- pushReg (hc08_reg_h, FALSE);
- pullReg (hc08_reg_a);
+ pushReg (hc08_reg_h, FALSE);
+ pullReg (hc08_reg_a);
break;
case X_IDX: /* X to A */
emitcode ("txa", "");
switch (srcidx)
{
case A_IDX: /* A to H */
- pushReg (hc08_reg_a, FALSE);
- pullReg (hc08_reg_h);
+ pushReg (hc08_reg_a, FALSE);
+ pullReg (hc08_reg_h);
break;
case X_IDX: /* X to H */
- pushReg (hc08_reg_x, FALSE);
- pullReg (hc08_reg_h);
+ pushReg (hc08_reg_x, FALSE);
+ pullReg (hc08_reg_h);
break;
default:
error=1;
emitcode ("tax", "");
break;
case H_IDX: /* H to X */
- pushReg (hc08_reg_h, FALSE);
- pullReg (hc08_reg_x);
+ pushReg (hc08_reg_h, FALSE);
+ pullReg (hc08_reg_x);
break;
default:
error=1;
switch (srcidx)
{
case XA_IDX: /* XA to HX */
- pushReg (hc08_reg_x, FALSE);
- pullReg (hc08_reg_h);
+ pushReg (hc08_reg_x, FALSE);
+ pullReg (hc08_reg_h);
emitcode ("tax", "");
break;
default:
{
case HX_IDX: /* HX to XA */
emitcode ("txa", "");
- pushReg (hc08_reg_h, FALSE);
- pullReg (hc08_reg_x);
+ pushReg (hc08_reg_h, FALSE);
+ pullReg (hc08_reg_x);
break;
default:
error=1;
return;
debugFile->writeFrameAddress (NULL, hc08_reg_sp,
- 1 + _G.stackOfs + _G.stackPushes);
+ 1 + _G.stackOfs + _G.stackPushes);
}
/*--------------------------------------------------------------------------*/
case A_IDX:
emitcode ("psha", "");
_G.stackPushes++;
- updateCFA();
+ updateCFA();
break;
case X_IDX:
emitcode ("pshx", "");
_G.stackPushes++;
- updateCFA();
+ updateCFA();
break;
case H_IDX:
emitcode ("pshh", "");
_G.stackPushes++;
- updateCFA();
+ updateCFA();
break;
case HX_IDX:
emitcode ("pshx", "");
_G.stackPushes++;
- updateCFA();
+ updateCFA();
emitcode ("pshh", "");
_G.stackPushes++;
- updateCFA();
+ updateCFA();
break;
case XA_IDX:
emitcode ("psha", "");
- updateCFA();
+ updateCFA();
_G.stackPushes++;
emitcode ("pshx", "");
- updateCFA();
+ updateCFA();
_G.stackPushes++;
break;
default:
case A_IDX:
emitcode ("pula", "");
_G.stackPushes--;
- updateCFA();
+ updateCFA();
break;
case X_IDX:
emitcode ("pulx", "");
_G.stackPushes--;
- updateCFA();
+ updateCFA();
break;
case H_IDX:
emitcode ("pulh", "");
_G.stackPushes--;
- updateCFA();
+ updateCFA();
break;
case HX_IDX:
emitcode ("pulh", "");
_G.stackPushes--;
- updateCFA();
+ updateCFA();
emitcode ("pulx", "");
_G.stackPushes--;
- updateCFA();
+ updateCFA();
break;
case XA_IDX:
emitcode ("pulx", "");
_G.stackPushes--;
- updateCFA();
+ updateCFA();
emitcode ("pula", "");
_G.stackPushes--;
- updateCFA();
+ updateCFA();
break;
default:
break;
{
emitcode ("ais","#127");
n -= 127;
- _G.stackPushes -= 127;
- updateCFA();
+ _G.stackPushes -= 127;
+ updateCFA();
}
else if (n<-128)
{
emitcode ("ais","#-128");
n += 128;
- _G.stackPushes += 128;
- updateCFA();
+ _G.stackPushes += 128;
+ updateCFA();
}
else
{
emitcode ("ais", "#%d", n);
- _G.stackPushes -= n;
+ _G.stackPushes -= n;
n = 0;
- updateCFA();
+ updateCFA();
}
}
}
DD(emitcode ("", "; loadRegFromAop (%s, %s, %d)",
reg->name, aopName (aop), loffset));
-
+
/* If operand is volatile, we cannot optimize. */
if (!aop->op || isOperandVolatile (aop->op, FALSE))
goto forceload;
{
for (loffset=0; loffset < newaop->size; loffset++)
{
- transferAopAop (aop, loffset, newaop, loffset);
- }
+ transferAopAop (aop, loffset, newaop, loffset);
+ }
}
return newaop;
break;
default:
werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "Bad rIdx in loadRegFromConst");
- return;
+ "Bad rIdx in loadRegFromConst");
+ return;
}
hc08_useReg (reg);
}
unsigned long lit;
unsigned long bytemask;
- lit = (unsigned long) floatFromVal (srcaop->aopu.aop_lit);
+ lit = ulFromVal (srcaop->aopu.aop_lit);
bytemask = (lit >> (srcofs*8)) & 0xff;
if (bytemask == 0)
werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "aopForSym should never reach here");
+ "aopForSym should never reach here");
exit(1);
for (;;)
{
if (ic->op == '+')
- val += (int) operandLitValue (IC_RIGHT (ic));
+ val += (int) operandLitValue (IC_RIGHT (ic));
else if (ic->op == '-')
- val -= (int) operandLitValue (IC_RIGHT (ic));
+ val -= (int) operandLitValue (IC_RIGHT (ic));
else if (IS_CAST_ICODE(ic)) {
- sym_link *from_type = operandType(IC_RIGHT(ic));
- aop->aopu.aop_immd.from_cast_remat = 1;
- ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
- ptr_type = DCL_TYPE(from_type);
- if (ptr_type == IPOINTER) {
- // bug #481053
- ptr_type = POINTER;
- }
- continue ;
+ sym_link *from_type = operandType(IC_RIGHT(ic));
+ aop->aopu.aop_immd.from_cast_remat = 1;
+ ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
+ ptr_type = DCL_TYPE(from_type);
+ if (ptr_type == IPOINTER) {
+ // bug #481053
+ ptr_type = POINTER;
+ }
+ continue ;
} else break;
ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
{
if (val)
sprintf (buffer, "(%s %c 0x%04x)",
- OP_SYMBOL (IC_LEFT (ic))->rname,
- val >= 0 ? '+' : '-',
- abs (val) & 0xffff);
+ OP_SYMBOL (IC_LEFT (ic))->rname,
+ val >= 0 ? '+' : '-',
+ abs (val) & 0xffff);
else
strcpy (buffer, OP_SYMBOL (IC_LEFT (ic))->rname);
strcpy (aop->aopu.aop_immd.aop_immd1, buffer);
/* set immd2 field if required */
if (aop->aopu.aop_immd.from_cast_remat)
- {
- sprintf(buffer,"#0x%02x",ptr_type);
- aop->aopu.aop_immd.aop_immd2 = Safe_calloc (1, strlen (buffer) + 1);
- strcpy (aop->aopu.aop_immd.aop_immd2, buffer);
- }
+ {
+ sprintf(buffer,"#0x%02x",ptr_type);
+ aop->aopu.aop_immd.aop_immd2 = Safe_calloc (1, strlen (buffer) + 1);
+ strcpy (aop->aopu.aop_immd.aop_immd2, buffer);
+ }
}
else if (ic->op == '=')
{
}
else
werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "unexpected rematerialization");
+ "unexpected rematerialization");
{
int j;
if (!sym1->regs[i])
- continue;
+ continue;
for (j = 0; j < sym2->nRegs; j++)
- {
- if (!sym2->regs[j])
- continue;
+ {
+ if (!sym2->regs[j])
+ continue;
- if (sym2->regs[j] == sym1->regs[i])
- return TRUE;
- }
+ if (sym2->regs[j] == sym1->regs[i])
+ return TRUE;
+ }
}
return FALSE;
// printf("checking remat\n");
/* rematerialize it NOW */
if (sym->remat)
- {
- sym->aop = op->aop = aop =
- aopForRemat (sym);
- aop->size = getSize (sym->type);
+ {
+ sym->aop = op->aop = aop =
+ aopForRemat (sym);
+ aop->size = getSize (sym->type);
aop->op = op;
aop->isaddr = op->isaddr;
/* if (aop->isaddr & IS_ITEMP (op))
aop->psize=aop->size;
aop->size = getSize( operandType (op)->next);
} */
- return;
- }
+ return;
+ }
// printf("checking accuse\n");
if (sym->accuse)
- {
- aop = op->aop = sym->aop = newAsmop (AOP_REG);
- aop->size = getSize (sym->type);
- switch (sym->accuse)
- {
- case ACCUSE_XA:
+ {
+ aop = op->aop = sym->aop = newAsmop (AOP_REG);
+ aop->size = getSize (sym->type);
+ switch (sym->accuse)
+ {
+ case ACCUSE_XA:
aop->aopu.aop_reg[0] = hc08_reg_a;
aop->aopu.aop_reg[1] = hc08_reg_x;
break;
- case ACCUSE_HX:
+ case ACCUSE_HX:
aop->aopu.aop_reg[0] = hc08_reg_x;
aop->aopu.aop_reg[1] = hc08_reg_h;
break;
}
aop->op = op;
aop->isaddr = op->isaddr;
- return;
- }
+ return;
+ }
// printf("checking ruonly\n");
#if 1
if (sym->ruonly)
- {
- unsigned i;
+ {
+ unsigned i;
- aop = op->aop = sym->aop = newAsmop (AOP_STR);
- aop->size = getSize (sym->type);
- for (i = 0; i < fReturnSizeHC08; i++)
- aop->aopu.aop_str[i] = fReturn2[i];
+ aop = op->aop = sym->aop = newAsmop (AOP_STR);
+ aop->size = getSize (sym->type);
+ for (i = 0; i < fReturnSizeHC08; i++)
+ aop->aopu.aop_str[i] = fReturn2[i];
aop->op = op;
aop->isaddr = op->isaddr;
- return;
- }
+ return;
+ }
#endif
/* else spill location */
if (sym->usl.spillLoc)
if (sym->usl.spillLoc->aop
&& sym->usl.spillLoc->aop->size != getSize (sym->type))
{
- /* force a new aop if sizes differ */
+ /* force a new aop if sizes differ */
oldAsmOp = sym->usl.spillLoc->aop;
- sym->usl.spillLoc->aop = NULL;
- //printf ("forcing new aop\n");
+ sym->usl.spillLoc->aop = NULL;
+ //printf ("forcing new aop\n");
}
- sym->aop = op->aop = aop = aopForSym (ic, sym->usl.spillLoc, result);
+ sym->aop = op->aop = aop = aopForSym (ic, sym->usl.spillLoc, result);
if (sym->usl.spillLoc->aop->size != getSize (sym->type))
{
/* Don't reuse the new aop, go with the last one */
sym->usl.spillLoc->aop = oldAsmOp;
}
- aop->size = getSize (sym->type);
- aop->op = op;
- aop->isaddr = op->isaddr;
- //printf ("spill symbol %s\n", OP_SYMBOL (op)->name);
- //printf (" with size = %d\n", aop->size);
- return;
- }
+ aop->size = getSize (sym->type);
+ aop->op = op;
+ aop->isaddr = op->isaddr;
+ //printf ("spill symbol %s\n", OP_SYMBOL (op)->name);
+ //printf (" with size = %d\n", aop->size);
+ return;
+ }
/* else must be a dummy iTemp */
sym->aop = op->aop = aop = newAsmop (AOP_DUMMY);
{
op->aop = NULL;
if (IS_SYMOP (op))
- {
- OP_SYMBOL (op)->aop = NULL;
- /* if the symbol has a spill */
- if (SPIL_LOC (op))
- SPIL_LOC (op)->aop = NULL;
- }
+ {
+ OP_SYMBOL (op)->aop = NULL;
+ /* if the symbol has a spill */
+ if (SPIL_LOC (op))
+ SPIL_LOC (op)->aop = NULL;
+ }
}
}
newaop->aopu.aop_dir = aop->aopu.aop_immd.aop_immd1;
break;
case AOP_LIT:
- adr = (int) floatFromVal (aop->aopu.aop_lit);
+ adr = (int) ulFromVal (aop->aopu.aop_lit);
if (p_type == POINTER)
adr &= 0xff;
case AOP_IMMD:
if (aop->aopu.aop_immd.from_cast_remat && (loffset == (aop->size-1))) {
- sprintf(s,"%s",aop->aopu.aop_immd.aop_immd2);
+ sprintf(s,"%s",aop->aopu.aop_immd.aop_immd2);
} else if (bit16)
- sprintf (s, "#%s", aop->aopu.aop_immd.aop_immd1);
+ sprintf (s, "#%s", aop->aopu.aop_immd.aop_immd1);
else if (loffset)
{
if (loffset!=1)
- sprintf (s, "#(%s >> %d)",
- aop->aopu.aop_immd.aop_immd1,
- loffset * 8);
- else
- sprintf (s, "#>%s",
- aop->aopu.aop_immd.aop_immd1);
+ sprintf (s, "#(%s >> %d)",
+ aop->aopu.aop_immd.aop_immd1,
+ loffset * 8);
+ else
+ sprintf (s, "#>%s",
+ aop->aopu.aop_immd.aop_immd1);
}
else
- sprintf (s, "#%s",
- aop->aopu.aop_immd.aop_immd1);
+ sprintf (s, "#%s",
+ aop->aopu.aop_immd.aop_immd1);
rs = Safe_calloc (1, strlen (s) + 1);
strcpy (rs, s);
return rs;
case AOP_DIR:
if (offset)
- sprintf (s, "*(%s + %d)",
- aop->aopu.aop_dir,
- offset);
+ sprintf (s, "*(%s + %d)",
+ aop->aopu.aop_dir,
+ offset);
else
- sprintf (s, "*%s", aop->aopu.aop_dir);
+ sprintf (s, "*%s", aop->aopu.aop_dir);
rs = Safe_calloc (1, strlen (s) + 1);
strcpy (rs, s);
return rs;
case AOP_EXT:
if (offset)
- sprintf (s, "(%s + %d)",
- aop->aopu.aop_dir,
- offset);
+ sprintf (s, "(%s + %d)",
+ aop->aopu.aop_dir,
+ offset);
else
- sprintf (s, "%s", aop->aopu.aop_dir);
+ sprintf (s, "%s", aop->aopu.aop_dir);
rs = Safe_calloc (1, strlen (s) + 1);
strcpy (rs, s);
return rs;
return aop->aopu.aop_str[loffset];
case AOP_SOF:
- sprintf (s, "%d,s", _G.stackOfs + _G.stackPushes + aop->aopu.aop_stk
- + offset + 1);
+ sprintf (s, "%d,s", _G.stackOfs + _G.stackPushes + aop->aopu.aop_stk
+ + offset + 1);
rs = Safe_calloc (1, strlen (s) + 1);
strcpy (rs, s);
return rs;
}
werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "aopAdrStr got unsupported aop->type");
+ "aopAdrStr got unsupported aop->type");
exit (1);
}
break;
case AOP_LIT:
/* Higher levels should optimize this case away but let's be safe */
- if ((unsigned long) floatFromVal (aop->aopu.aop_lit))
+ if (ulFromVal (aop->aopu.aop_lit))
loadRegFromConst (hc08_reg_a, one);
else
loadRegFromConst (hc08_reg_a, zero);
int size;
regs* reg = hc08_reg_a;
-// symbol *tlbl;
-
D(emitcode ("; genCpl",""));
/* assign asmOps to operand & result */
result = forceStackedAop (AOP (IC_RESULT (ic)), FALSE);
else
result = AOP (IC_RESULT (ic));
-
+
needpula = pushRegIfUsed (hc08_reg_a);
sub="sub";
while (size--)
/* safe the registers in use at this time but skip the
ones for the result */
rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
- hc08_rUmaskForOp (IC_RESULT(ic)));
+ hc08_rUmaskForOp (IC_RESULT(ic)));
ic->regsSaved = 1;
for (i = 0; i < hc08_nRegs; i++)
/* restore the registers in use at this time but skip the
ones for the result */
rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
- hc08_rUmaskForOp (IC_RESULT(ic)));
+ hc08_rUmaskForOp (IC_RESULT(ic)));
for (i = hc08_nRegs; i >= 0; i--)
{
genIpush (iCode * ic)
{
int size, offset = 0;
-// char *l;
D(emitcode ("; genIpush",""));
/* and the item is spilt then do nothing */
if (OP_SYMBOL (IC_LEFT (ic))->isspilt)
- return;
+ return;
aopOp (IC_LEFT (ic), ic, FALSE);
size = AOP_SIZE (IC_LEFT (ic));
/*-----------------------------------------------------------------*/
-/* genSend - gen code for SEND */
+/* genSend - gen code for SEND */
/*-----------------------------------------------------------------*/
static void genSend(set *sendSet)
{
for (sic = setFirstItem (sendSet); sic;
sic = setNextItem (sendSet)) {
- int size, offset = 0;
- aopOp (IC_LEFT (sic), sic, FALSE);
- size = AOP_SIZE (IC_LEFT (sic));
+ int size, offset = 0;
+ aopOp (IC_LEFT (sic), sic, FALSE);
+ size = AOP_SIZE (IC_LEFT (sic));
if (sic->argreg) {
- offset = size-1;
- while (size--) {
- transferAopAop( AOP (IC_LEFT (sic)), offset,
- hc08_aop_pass[offset+(sic->argreg-1)], 0);
- offset--;
- }
- }
- freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
+ offset = size-1;
+ while (size--) {
+ transferAopAop( AOP (IC_LEFT (sic)), offset,
+ hc08_aop_pass[offset+(sic->argreg-1)], 0);
+ offset--;
+ }
+ }
+ freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
}
}
/* if send set is not empty then assign */
if (_G.sendSet)
{
- if (IFFUNC_ISREENT(dtype)) { /* need to reverse the send set */
- genSend(reverseSet(_G.sendSet));
- } else {
- genSend(_G.sendSet);
- }
+ if (IFFUNC_ISREENT(dtype)) { /* need to reverse the send set */
+ genSend(reverseSet(_G.sendSet));
+ } else {
+ genSend(_G.sendSet);
+ }
_G.sendSet = NULL;
}
/* make the call */
emitcode ("jsr", "%s", (OP_SYMBOL (IC_LEFT (ic))->rname[0] ?
- OP_SYMBOL (IC_LEFT (ic))->rname :
- OP_SYMBOL (IC_LEFT (ic))->name));
+ OP_SYMBOL (IC_LEFT (ic))->rname :
+ OP_SYMBOL (IC_LEFT (ic))->name));
/* if we need assign a result value */
if ((IS_ITEMP (IC_RESULT (ic)) &&
(OP_SYMBOL (IC_RESULT (ic))->nRegs ||
- OP_SYMBOL (IC_RESULT (ic))->accuse ||
- OP_SYMBOL (IC_RESULT (ic))->spildir)) ||
+ OP_SYMBOL (IC_RESULT (ic))->accuse ||
+ OP_SYMBOL (IC_RESULT (ic))->spildir)) ||
IS_TRUE_SYMOP (IC_RESULT (ic)))
{
/* if send set is not empty the assign */
if (_G.sendSet)
{
- genSend(reverseSet(_G.sendSet));
- _G.sendSet = NULL;
+ genSend(reverseSet(_G.sendSet));
+ _G.sendSet = NULL;
}
/* if we need assign a result value */
if ((IS_ITEMP (IC_RESULT (ic)) &&
(OP_SYMBOL (IC_RESULT (ic))->nRegs ||
- OP_SYMBOL (IC_RESULT (ic))->spildir)) ||
+ OP_SYMBOL (IC_RESULT (ic))->spildir)) ||
IS_TRUE_SYMOP (IC_RESULT (ic)))
{
{
symbol *sym = OP_SYMBOL (IC_RESULT (ic));
if (sym->remat && !POINTER_SET (ic))
- return 1;
+ return 1;
}
return 0;
/* if debug then send end of function */
if (options.debug && currFunc)
- {
- debugFile->writeEndFunction (currFunc, ic, 1);
- }
+ {
+ debugFile->writeEndFunction (currFunc, ic, 1);
+ }
emitcode ("rti", "");
}
else
{
if (IFFUNC_CALLEESAVES(sym->type))
- {
- int i;
-
- /* if any registers used */
- if (sym->regsUsed)
- {
- /* save the registers used */
- for (i = sym->regsUsed->size; i >= 0; i--)
- {
- if (bitVectBitValue (sym->regsUsed, i) ||
- (hc08_ptrRegReq && (i == HX_IDX || i == HX_IDX)))
- emitcode ("pop", "%s", hc08_regWithIdx (i)->name);
- }
- }
-
- }
+ {
+ int i;
+
+ /* if any registers used */
+ if (sym->regsUsed)
+ {
+ /* save the registers used */
+ for (i = sym->regsUsed->size; i >= 0; i--)
+ {
+ if (bitVectBitValue (sym->regsUsed, i) ||
+ (hc08_ptrRegReq && (i == HX_IDX || i == HX_IDX)))
+ emitcode ("pop", "%s", hc08_regWithIdx (i)->name);
+ }
+ }
+
+ }
/* if debug then send end of function */
if (options.debug && currFunc)
- {
- debugFile->writeEndFunction (currFunc, ic, 1);
- }
+ {
+ debugFile->writeEndFunction (currFunc, ic, 1);
+ }
emitcode ("rts", "");
}
/* generate a jump to the return label
if the next is not the return statement */
if (!(ic->next && ic->next->op == LABEL &&
- IC_LABEL (ic->next) == returnLabel))
+ IC_LABEL (ic->next) == returnLabel))
emitcode ("jmp", "%05d$", (returnLabel->key + 100));
/* special case never generate */
if (IC_LABEL (ic) == entryLabel)
return;
-
+
debugFile->writeLabel(IC_LABEL (ic), ic);
emitLabel (IC_LABEL (ic));
count++;
/* If we have any pushes or pops, we cannot predict the distance.
- I don't like this at all, this should be dealt with in the
- back-end */
+ I don't like this at all, this should be dealt with in the
+ back-end */
if (ic->op == IPUSH || ic->op == IPOP) {
- return 0;
+ return 0;
}
if (ic->op == LABEL && IC_LABEL (ic)->key == key)
- {
- return count;
- }
+ {
+ return count;
+ }
}
return 0;
if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT)
return FALSE;
- icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
+ icount = (unsigned int) ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
DD(emitcode ("", "; IS_AOP_HX = %d", IS_AOP_HX (AOP (left))));
if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT)
return FALSE;
- icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
+ icount = (unsigned int) ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
if ((AOP_TYPE (left) == AOP_DIR) && (AOP_TYPE (result) == AOP_DIR)
&& (icount>=-127) && (icount<=128) && (size==2))
if (size > 0)
{
if (sign)
- {
- emitcode ("rola", "");
- emitcode ("clra", "");
- emitcode ("sbc", zero);
- while (size--)
- storeRegToAop (hc08_reg_a, AOP (result), offset++);
- }
+ {
+ emitcode ("rola", "");
+ emitcode ("clra", "");
+ emitcode ("sbc", zero);
+ while (size--)
+ storeRegToAop (hc08_reg_a, AOP (result), offset++);
+ }
else
- while (size--)
- storeConstToAop (zero, AOP (result), offset++);
+ while (size--)
+ storeConstToAop (zero, AOP (result), offset++);
}
}
/*-----------------------------------------------------------------*/
static void
genMultOneByte (operand * left,
- operand * right,
- operand * result)
+ operand * right,
+ operand * result)
{
/* sym_link *opetype = operandType (result); */
symbol *tlbl1, *tlbl2, *tlbl3, *tlbl4;
if (size<1 || size>2) {
// this should never happen
fprintf (stderr, "size!=1||2 (%d) in %s at line:%d \n",
- AOP_SIZE(result), __FILE__, lineno);
+ AOP_SIZE(result), __FILE__, lineno);
exit (1);
}
/* left unsigned, right signed literal -- literal determines sign handling */
if (AOP_TYPE(right)==AOP_LIT && lUnsigned && !rUnsigned)
{
- signed char val=(signed char)floatFromVal (AOP (right)->aopu.aop_lit);
+ signed char val=(signed char) ulFromVal (AOP (right)->aopu.aop_lit);
loadRegFromAop (hc08_reg_a, AOP (left), 0);
if (val < 0)
if (AOP_TYPE(right)==AOP_LIT && !rUnsigned)
{
- signed char val=(signed char)floatFromVal (AOP (right)->aopu.aop_lit);
+ signed char val=(signed char) ulFromVal (AOP (right)->aopu.aop_lit);
/* AND literal negative */
if (val < 0) {
emitcode ("ldx", "#0x%02x", -val);
/* should have been converted to function call */
fprintf (stderr, "left: %d right: %d\n", getSize(OP_SYMBOL(left)->type),
- getSize(OP_SYMBOL(right)->type));
+ getSize(OP_SYMBOL(right)->type));
fprintf (stderr, "left: %d right: %d\n", AOP_SIZE (left),
- AOP_SIZE (right));
+ AOP_SIZE (right));
assert (0);
release:
/*-----------------------------------------------------------------*/
static void
genDivOneByte (operand * left,
- operand * right,
- operand * result)
+ operand * right,
+ operand * result)
{
symbol *tlbl1, *tlbl2, *tlbl3;
int size;
if (AOP_TYPE(left) == AOP_LIT)
{
/* signed literal */
- signed char val = (char) floatFromVal (AOP (left)->aopu.aop_lit);
+ signed char val = (char) ulFromVal (AOP (left)->aopu.aop_lit);
if (val < 0)
compiletimeSign = TRUE;
}
if (AOP_TYPE(right) == AOP_LIT)
{
/* signed literal */
- signed char val = (char) floatFromVal (AOP (right)->aopu.aop_lit);
+ signed char val = (char) ulFromVal (AOP (right)->aopu.aop_lit);
if (val < 0)
compiletimeSign ^= TRUE;
}
/* save the signs of the operands */
if (AOP_TYPE(right) == AOP_LIT)
{
- signed char val = (char) floatFromVal (AOP (right)->aopu.aop_lit);
+ signed char val = (char) ulFromVal (AOP (right)->aopu.aop_lit);
if (!rUnsigned && val < 0)
emitcode ("ldx", "#0x%02x", -val);
if (AOP_TYPE(left) == AOP_LIT)
{
- signed char val = (char) floatFromVal (AOP (left)->aopu.aop_lit);
+ signed char val = (char) ulFromVal (AOP (left)->aopu.aop_lit);
if (!lUnsigned && val < 0)
emitcode ("lda", "#0x%02x", -val);
/*-----------------------------------------------------------------*/
static void
genModOneByte (operand * left,
- operand * right,
- operand * result)
+ operand * right,
+ operand * result)
{
symbol *tlbl1, *tlbl2, *tlbl3;
int size;
if (AOP_TYPE(right) == AOP_LIT)
{
- signed char val = (char) floatFromVal (AOP (right)->aopu.aop_lit);
+ signed char val = (char) ulFromVal (AOP (right)->aopu.aop_lit);
if (!rUnsigned && val < 0)
emitcode ("ldx", "#0x%02x", -val);
/* sign adjust left side */
if (AOP_TYPE(left) == AOP_LIT)
{
- signed char val = (char) floatFromVal (AOP (left)->aopu.aop_lit);
+ signed char val = (char) ulFromVal (AOP (left)->aopu.aop_lit);
if (!lUnsigned && val < 0)
{
return EQ_OP;
default:
werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "opcode not a comparison");
+ "opcode not a comparison");
}
return EQ_OP; /* shouldn't happen, but need to return something */
}
return NE_OP;
default:
werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "opcode not a comparison");
+ "opcode not a comparison");
}
return EQ_OP; /* shouldn't happen, but need to return something */
}
if (sign)
return "blt";
else
- return "bcs"; /* same as blo */
+ return "bcs"; /* same as blo */
case '>':
if (sign)
return "bgt";
if (sign)
return "bge";
else
- return "bcc"; /* same as bhs */
+ return "bcc"; /* same as bhs */
case NE_OP:
return "bne";
case EQ_OP:
return "beq";
default:
werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "opcode not a comparison");
+ "opcode not a comparison");
}
return "brn";
}
if ((AOP_TYPE (right) == AOP_LIT) && !isOperandVolatile (left, FALSE))
{
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+ lit = ulFromVal (AOP (right)->aopu.aop_lit);
while ((size > 1) && (((lit >> (8*offset)) & 0xff) == 0))
{
offset++;
while (lic) {
/* if operand of the form op = op + <sizeof *op> */
if (lic->op == '+' && isOperandEqual(IC_LEFT(lic),op) &&
- isOperandEqual(IC_RESULT(lic),op) &&
- isOperandLiteral(IC_RIGHT(lic)) &&
- operandLitValue(IC_RIGHT(lic)) == isize) {
+ isOperandEqual(IC_RESULT(lic),op) &&
+ isOperandLiteral(IC_RIGHT(lic)) &&
+ operandLitValue(IC_RIGHT(lic)) == isize) {
return lic;
}
/* if the operand used or deffed */
#ifdef DEBUG_TYPE
DD(emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
- AOP_TYPE (result),
- AOP_TYPE (left), AOP_TYPE (right)));
+ AOP_TYPE (result),
+ AOP_TYPE (left), AOP_TYPE (right)));
DD(emitcode ("", "; Size res[%d] = l[%d]&r[%d]",
- AOP_SIZE (result),
- AOP_SIZE (left), AOP_SIZE (right)));
+ AOP_SIZE (result),
+ AOP_SIZE (left), AOP_SIZE (right)));
#endif
/* if left is a literal & right is not then exchange them */
}
if (AOP_TYPE (right) == AOP_LIT)
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+ lit = ulFromVal (AOP (right)->aopu.aop_lit);
size = (AOP_SIZE (left) >= AOP_SIZE (right)) ? AOP_SIZE (left) : AOP_SIZE (right);
#ifdef DEBUG_TYPE
DD(emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
- AOP_TYPE (result),
- AOP_TYPE (left), AOP_TYPE (right)));
+ AOP_TYPE (result),
+ AOP_TYPE (left), AOP_TYPE (right)));
DD(emitcode ("", "; Size res[%d] = l[%d]&r[%d]",
- AOP_SIZE (result),
- AOP_SIZE (left), AOP_SIZE (right)));
+ AOP_SIZE (result),
+ AOP_SIZE (left), AOP_SIZE (right)));
#endif
/* if left is a literal & right is not then exchange them */
}
if (AOP_TYPE (right) == AOP_LIT)
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+ lit = ulFromVal (AOP (right)->aopu.aop_lit);
size = (AOP_SIZE (left) >= AOP_SIZE (right)) ? AOP_SIZE (left) : AOP_SIZE (right);
}
if (AOP_TYPE (right) == AOP_LIT)
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+ lit = ulFromVal (AOP (right)->aopu.aop_lit);
size = AOP_SIZE (result);
#ifdef DEBUG_TYPE
DD(emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
- AOP_TYPE (result),
- AOP_TYPE (left), AOP_TYPE (right)));
+ AOP_TYPE (result),
+ AOP_TYPE (left), AOP_TYPE (right)));
DD(emitcode ("", "; Size res[%d] = l[%d]&r[%d]",
- AOP_SIZE (result),
- AOP_SIZE (left), AOP_SIZE (right)));
+ AOP_SIZE (result),
+ AOP_SIZE (left), AOP_SIZE (right)));
#endif
/* if left is a literal & right is not ||
}
if (AOP_TYPE (right) == AOP_LIT)
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+ lit = ulFromVal (AOP (right)->aopu.aop_lit);
size = AOP_SIZE (result);
offset = 0;
static void
AccRol (int shCount)
{
- shCount &= 0x0007; // shCount : 0..7
+ shCount &= 0x0007; // shCount : 0..7
switch (shCount)
{
case 0:
break;
case 1:
- emitcode ("rola", ""); /* 1 cycle */
+ emitcode ("rola", ""); /* 1 cycle */
break;
case 2:
- emitcode ("rola", ""); /* 1 cycle */
- emitcode ("rola", ""); /* 1 cycle */
+ emitcode ("rola", ""); /* 1 cycle */
+ emitcode ("rola", ""); /* 1 cycle */
break;
case 3:
emitcode ("nsa", "");
emitcode ("rora", "");
break;
case 4:
- emitcode ("nsa", ""); /* 3 cycles */
+ emitcode ("nsa", ""); /* 3 cycles */
break;
case 5:
- emitcode ("nsa", ""); /* 3 cycles */
- emitcode ("rola", ""); /* 1 cycle */
+ emitcode ("nsa", ""); /* 3 cycles */
+ emitcode ("rola", ""); /* 1 cycle */
break;
case 6:
- emitcode ("nsa", ""); /* 3 cycles */
- emitcode ("rola", ""); /* 1 cycle */
- emitcode ("rola", ""); /* 1 cycle */
+ emitcode ("nsa", ""); /* 3 cycles */
+ emitcode ("rola", ""); /* 1 cycle */
+ emitcode ("rola", ""); /* 1 cycle */
break;
case 7:
- emitcode ("nsa", ""); /* 3 cycles */
- emitcode ("rola", ""); /* 1 cycle */
- emitcode ("rola", ""); /* 1 cycle */
- emitcode ("rola", ""); /* 1 cycle */
+ emitcode ("nsa", ""); /* 3 cycles */
+ emitcode ("rola", ""); /* 1 cycle */
+ emitcode ("rola", ""); /* 1 cycle */
+ emitcode ("rola", ""); /* 1 cycle */
break;
}
}
{
int i;
- shCount &= 0x0007; // shCount : 0..7
+ shCount &= 0x0007; // shCount : 0..7
/* Shift counts of 4 and 5 are currently optimized for code size. */
/* Falling through to the unrolled loop would be optimal for code speed. */
{
int i;
- shCount &= 0x0007; // shCount : 0..7
+ shCount &= 0x0007; // shCount : 0..7
if (shCount == 7)
{
return;
}
- shCount &= 0x0007; // shCount : 0..7
+ shCount &= 0x0007; // shCount : 0..7
/* Shift counts of 4 and 5 are currently optimized for code size. */
/* Falling through to the unrolled loop would be optimal for code speed. */
{
int i;
- shCount &= 0x000f; // shCount : 0..15
+ shCount &= 0x000f; // shCount : 0..15
if (shCount>=8)
{
{
int i;
- shCount &= 0x000f; // shCount : 0..7
+ shCount &= 0x000f; // shCount : 0..7
/* if we can beat 2n cycles or bytes for some special case, do it here */
switch (shCount)
return;
}
- shCount &= 0x000f; // shCount : 0..f
+ shCount &= 0x000f; // shCount : 0..f
/* if we can beat 2n cycles or bytes for some special case, do it here */
switch (shCount)
/*-----------------------------------------------------------------*/
static void
shiftR1Left2Result (operand * left, int offl,
- operand * result, int offr,
- int shCount, int sign)
+ operand * result, int offr,
+ int shCount, int sign)
{
loadRegFromAop (hc08_reg_a, AOP (left), offl);
/* shift right accumulator */
/*-----------------------------------------------------------------*/
static void
shiftL1Left2Result (operand * left, int offl,
- operand * result, int offr, int shCount)
+ operand * result, int offr, int shCount)
{
loadRegFromAop (hc08_reg_a, AOP (left), offl);
/* shift left accumulator */
/*-----------------------------------------------------------------*/
static void
movLeft2Result (operand * left, int offl,
- operand * result, int offr, int sign)
+ operand * result, int offr, int sign)
{
if (!sameRegs (AOP (left), AOP (result)) || (offl != offr))
{
/*-----------------------------------------------------------------*/
static void
shiftL2Left2Result (operand * left, int offl,
- operand * result, int offr, int shCount)
+ operand * result, int offr, int shCount)
{
int i;
bool needpula = FALSE;
/*-----------------------------------------------------------------*/
static void
shiftR2Left2Result (operand * left, int offl,
- operand * result, int offr,
- int shCount, int sign)
+ operand * result, int offr,
+ int shCount, int sign)
{
int i;
bool needpula = FALSE;
/*-----------------------------------------------------------------*/
static void
shiftLLeftOrResult (operand * left, int offl,
- operand * result, int offr, int shCount)
+ operand * result, int offr, int shCount)
{
loadRegFromAop (hc08_reg_a, AOP (left), offl);
/* shift left accumulator */
/*-----------------------------------------------------------------*/
static void
shiftRLeftOrResult (operand * left, int offl,
- operand * result, int offr, int shCount)
+ operand * result, int offr, int shCount)
{
loadRegFromAop (hc08_reg_a, AOP (left), offl);
/* shift left accumulator */
shCount -= 8;
if (size > 1)
- {
+ {
loadRegFromAop (hc08_reg_a, AOP (left), 0);
AccLsh (shCount);
- storeRegToAop (hc08_reg_a, AOP (result), 1);
- }
+ storeRegToAop (hc08_reg_a, AOP (result), 1);
+ }
storeConstToAop(zero, AOP (result), LSB);
}
{
shCount -= 24;
if (shCount)
- /* lowest order of left goes to the highest
- order of the destination */
- shiftL1Left2Result (left, LSB, result, MSB32, shCount);
+ /* lowest order of left goes to the highest
+ order of the destination */
+ shiftL1Left2Result (left, LSB, result, MSB32, shCount);
else
- movLeft2Result (left, LSB, result, MSB32, 0);
+ movLeft2Result (left, LSB, result, MSB32, 0);
storeConstToAop (zero, AOP (result), LSB);
storeConstToAop (zero, AOP (result), MSB16);
storeConstToAop (zero, AOP (result), MSB24);
shCount -= 16;
/* if some more remaining */
if (shCount)
- shiftL2Left2Result (left, LSB, result, MSB24, shCount);
+ shiftL2Left2Result (left, LSB, result, MSB24, shCount);
else
- {
- movLeft2Result (left, MSB16, result, MSB32, 0);
- movLeft2Result (left, LSB, result, MSB24, 0);
- }
+ {
+ movLeft2Result (left, MSB16, result, MSB32, 0);
+ movLeft2Result (left, LSB, result, MSB24, 0);
+ }
storeConstToAop (zero, AOP (result), LSB);
storeConstToAop (zero, AOP (result), MSB16);
return;
/* lower order three bytes goes to higher order three bytes */
shCount -= 8;
if (size == 2)
- {
- if (shCount)
- shiftL1Left2Result (left, LSB, result, MSB16, shCount);
- else
- movLeft2Result (left, LSB, result, MSB16, 0);
- }
+ {
+ if (shCount)
+ shiftL1Left2Result (left, LSB, result, MSB16, shCount);
+ else
+ movLeft2Result (left, LSB, result, MSB16, 0);
+ }
else
- { /* size = 4 */
- if (shCount == 0)
- {
- movLeft2Result (left, MSB24, result, MSB32, 0);
- movLeft2Result (left, MSB16, result, MSB24, 0);
- movLeft2Result (left, LSB, result, MSB16, 0);
+ { /* size = 4 */
+ if (shCount == 0)
+ {
+ movLeft2Result (left, MSB24, result, MSB32, 0);
+ movLeft2Result (left, MSB16, result, MSB24, 0);
+ movLeft2Result (left, LSB, result, MSB16, 0);
storeConstToAop (zero, AOP (result), LSB);
- }
- else if (shCount == 1)
- shiftLLong (left, result, MSB16);
- else
- {
- shiftL2Left2Result (left, MSB16, result, MSB24, shCount);
- shiftL1Left2Result (left, LSB, result, MSB16, shCount);
- shiftRLeftOrResult (left, LSB, result, MSB24, 8 - shCount);
+ }
+ else if (shCount == 1)
+ shiftLLong (left, result, MSB16);
+ else
+ {
+ shiftL2Left2Result (left, MSB16, result, MSB24, shCount);
+ shiftL1Left2Result (left, LSB, result, MSB16, shCount);
+ shiftRLeftOrResult (left, LSB, result, MSB24, 8 - shCount);
storeConstToAop (zero, AOP (result), LSB);
- }
- }
+ }
+ }
}
/* 1 <= shCount <= 7 */
{
shiftLLong (left, result, LSB);
if (shCount == 2)
- shiftLLong (result, result, LSB);
+ shiftLLong (result, result, LSB);
}
/* 3 <= shCount <= 7, optimize */
else
/*-----------------------------------------------------------------*/
static void
genLeftShiftLiteral (operand * left,
- operand * right,
- operand * result,
- iCode * ic)
+ operand * right,
+ operand * result,
+ iCode * ic)
{
- int shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+ int shCount = (int) ulFromVal (AOP (right)->aopu.aop_lit);
int size;
D(emitcode ("; genLeftShiftLiteral",""));
#if VIEW_SIZE
DD(emitcode ("; shift left ", "result %d, left %d", size,
- AOP_SIZE (left)));
+ AOP_SIZE (left)));
#endif
if (shCount == 0)
else
{
switch (size)
- {
- case 1:
- genlshOne (result, left, shCount);
- break;
-
- case 2:
- genlshTwo (result, left, shCount);
- break;
-
- case 4:
- genlshFour (result, left, shCount);
- break;
- default:
- werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "*** ack! mystery literal shift!\n");
- break;
- }
+ {
+ case 1:
+ genlshOne (result, left, shCount);
+ break;
+
+ case 2:
+ genlshTwo (result, left, shCount);
+ break;
+
+ case 4:
+ genlshFour (result, left, shCount);
+ break;
+ default:
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "*** ack! mystery literal shift!\n");
+ break;
+ }
}
freeAsmop (left, NULL, ic, TRUE);
freeAsmop (result, NULL, ic, TRUE);
size = AOP_SIZE (result);
offset = 0;
while (size--)
- {
- transferAopAop (AOP (left), offset, aopResult, offset);
- offset++;
- }
+ {
+ transferAopAop (AOP (left), offset, aopResult, offset);
+ offset++;
+ }
}
freeAsmop (left, NULL, ic, TRUE);
AOP (result) = aopResult;
/*-----------------------------------------------------------------*/
static void
genrshOne (operand * result, operand * left,
- int shCount, int sign)
+ int shCount, int sign)
{
D(emitcode ("; genrshOne",""));
/*-----------------------------------------------------------------*/
static void
genrshTwo (operand * result, operand * left,
- int shCount, int sign)
+ int shCount, int sign)
{
D(emitcode ("; genrshTwo",""));
/*-----------------------------------------------------------------*/
static void
shiftRLong (operand * left, int offl,
- operand * result, int sign)
+ operand * result, int sign)
{
// char *l;
// int size = AOP_SIZE (result);
/*-----------------------------------------------------------------*/
static void
genrshFour (operand * result, operand * left,
- int shCount, int sign)
+ int shCount, int sign)
{
/* TODO: handle cases where left == result */
else if (shCount >= 8)
{
if (shCount == 1)
- shiftRLong (left, MSB16, result, sign);
+ shiftRLong (left, MSB16, result, sign);
else if (shCount == 8)
- {
- transferAopAop (AOP (left), 1, AOP (result), 0);
- transferAopAop (AOP (left), 2, AOP (result), 1);
- loadRegFromAop (hc08_reg_a, AOP (left), 3);
+ {
+ transferAopAop (AOP (left), 1, AOP (result), 0);
+ transferAopAop (AOP (left), 2, AOP (result), 1);
+ loadRegFromAop (hc08_reg_a, AOP (left), 3);
storeRegToAop (hc08_reg_a, AOP (result), 2);
storeRegSignToUpperAop (hc08_reg_a, AOP(result), 3, sign);
- }
+ }
else if (shCount == 9)
{
- shiftRLong (left, MSB16, result, sign);
+ shiftRLong (left, MSB16, result, sign);
}
else
- {
- loadRegFromAop (hc08_reg_xa, AOP (left), 1);
- XAccRsh (shCount-8, FALSE);
- storeRegToAop (hc08_reg_xa, AOP (result), 0);
- loadRegFromAop (hc08_reg_x, AOP (left), 3);
- loadRegFromConst (hc08_reg_a, zero);
- XAccRsh (shCount-8, sign);
- accopWithAop ("ora", AOP (result), 1);
- storeRegToAop (hc08_reg_xa, AOP (result), 1);
+ {
+ loadRegFromAop (hc08_reg_xa, AOP (left), 1);
+ XAccRsh (shCount-8, FALSE);
+ storeRegToAop (hc08_reg_xa, AOP (result), 0);
+ loadRegFromAop (hc08_reg_x, AOP (left), 3);
+ loadRegFromConst (hc08_reg_a, zero);
+ XAccRsh (shCount-8, sign);
+ accopWithAop ("ora", AOP (result), 1);
+ storeRegToAop (hc08_reg_xa, AOP (result), 1);
storeRegSignToUpperAop (hc08_reg_x, AOP(result), 3, sign);
- }
+ }
}
else
- { /* 1 <= shCount <= 7 */
+ { /* 1 <= shCount <= 7 */
if (shCount == 1)
- {
- shiftRLong (left, LSB, result, sign);
- }
+ {
+ shiftRLong (left, LSB, result, sign);
+ }
else
- {
- loadRegFromAop (hc08_reg_xa, AOP (left), 0);
- XAccRsh (shCount, FALSE);
- storeRegToAop (hc08_reg_xa, AOP (result), 0);
- loadRegFromAop (hc08_reg_a, AOP (left), 2);
- AccLsh (8-shCount);
- accopWithAop ("ora", AOP (result), 1);
- storeRegToAop (hc08_reg_a, AOP (result), 1);
- loadRegFromAop (hc08_reg_xa, AOP (left), 2);
- XAccRsh (shCount, sign);
- storeRegToAop (hc08_reg_xa, AOP (result), 2);
- }
+ {
+ loadRegFromAop (hc08_reg_xa, AOP (left), 0);
+ XAccRsh (shCount, FALSE);
+ storeRegToAop (hc08_reg_xa, AOP (result), 0);
+ loadRegFromAop (hc08_reg_a, AOP (left), 2);
+ AccLsh (8-shCount);
+ accopWithAop ("ora", AOP (result), 1);
+ storeRegToAop (hc08_reg_a, AOP (result), 1);
+ loadRegFromAop (hc08_reg_xa, AOP (left), 2);
+ XAccRsh (shCount, sign);
+ storeRegToAop (hc08_reg_xa, AOP (result), 2);
+ }
}
}
/*-----------------------------------------------------------------*/
static void
genRightShiftLiteral (operand * left,
- operand * right,
- operand * result,
- iCode * ic,
- int sign)
+ operand * right,
+ operand * result,
+ iCode * ic,
+ int sign)
{
- int shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+ int shCount = (int) ulFromVal (AOP (right)->aopu.aop_lit);
int size;
D(emitcode ("; genRightShiftLiteral",""));
#if VIEW_SIZE
DD(emitcode ("; shift right ", "result %d, left %d", AOP_SIZE (result),
- AOP_SIZE (left)));
+ AOP_SIZE (left)));
#endif
size = getDataSize (left);
{
size = getDataSize (result);
while (size--)
- transferAopAop (AOP (left), size, AOP(result), size);
+ transferAopAop (AOP (left), size, AOP(result), size);
}
else if (shCount >= (size * 8))
{
if (sign) {
- /* get sign in acc.7 */
- loadRegFromAop (hc08_reg_a, AOP (left), size -1);
+ /* get sign in acc.7 */
+ loadRegFromAop (hc08_reg_a, AOP (left), size -1);
}
addSign (result, LSB, sign);
}
else
{
switch (size)
- {
- case 1:
- genrshOne (result, left, shCount, sign);
- break;
-
- case 2:
- genrshTwo (result, left, shCount, sign);
- break;
-
- case 4:
- genrshFour (result, left, shCount, sign);
- break;
- default:
- break;
- }
+ {
+ case 1:
+ genrshOne (result, left, shCount, sign);
+ break;
+
+ case 2:
+ genrshTwo (result, left, shCount, sign);
+ break;
+
+ case 4:
+ genrshFour (result, left, shCount, sign);
+ break;
+ default:
+ break;
+ }
}
freeAsmop (left, NULL, ic, TRUE);
freeAsmop (result, NULL, ic, TRUE);
size = AOP_SIZE (result);
offset = 0;
while (size--)
- {
- transferAopAop (AOP (left), offset, aopResult, offset);
- offset++;
- }
+ {
+ transferAopAop (AOP (left), offset, aopResult, offset);
+ offset++;
+ }
}
freeAsmop (left, NULL, ic, TRUE);
AOP (result) = aopResult;
static void
genUnpackBits (operand * result, iCode *ifx)
{
- int offset = 0; /* result byte offset */
- int rsize; /* result size */
- int rlen = 0; /* remaining bitfield length */
- sym_link *etype; /* bitfield type information */
- int blen; /* bitfield length */
- int bstr; /* bitfield starting bit within byte */
+ int offset = 0; /* result byte offset */
+ int rsize; /* result size */
+ int rlen = 0; /* remaining bitfield length */
+ sym_link *etype; /* bitfield type information */
+ int blen; /* bitfield length */
+ int bstr; /* bitfield starting bit within byte */
D(emitcode ("; genUnpackBits",""));
iCode *ifx)
{
int size;
- int offset = 0; /* result byte offset */
- int rsize; /* result size */
- int rlen = 0; /* remaining bitfield length */
- sym_link *etype; /* bitfield type information */
- int blen; /* bitfield length */
- int bstr; /* bitfield starting bit within byte */
+ int offset = 0; /* result byte offset */
+ int rsize; /* result size */
+ int rlen = 0; /* remaining bitfield length */
+ sym_link *etype; /* bitfield type information */
+ int blen; /* bitfield length */
+ int bstr; /* bitfield starting bit within byte */
asmop *derefaop;
D(emitcode ("; genUnpackBitsImmed",""));
/*-----------------------------------------------------------------*/
static void
genDataPointerGet (operand * left,
- operand * result,
- iCode * ic,
+ operand * result,
+ iCode * ic,
iCode * ifx)
{
int size;
offset = size-1;
while (size--)
- {
- accopWithMisc ("lda", ",x");
- if (size || pi)
+ {
+ accopWithMisc ("lda", ",x");
+ if (size || pi)
{
- emitcode ("aix", "#1");
- hc08_dirtyReg (hc08_reg_hx, FALSE);
+ emitcode ("aix", "#1");
+ hc08_dirtyReg (hc08_reg_hx, FALSE);
}
if (!ifx)
storeRegToAop (hc08_reg_a, AOP (result), offset);
offset--;
hc08_freeReg (hc08_reg_a);
- }
+ }
}
freeAsmop (left, NULL, ic, TRUE);
/*-----------------------------------------------------------------*/
static void
genPackBits (sym_link * etype,
- operand * right)
-{
- int offset = 0; /* source byte offset */
- int rlen = 0; /* remaining bitfield length */
- int blen; /* bitfield length */
- int bstr; /* bitfield starting bit within byte */
- int litval; /* source literal value (if AOP_LIT) */
- unsigned char mask; /* bitmask within current byte */
+ operand * right)
+{
+ int offset = 0; /* source byte offset */
+ int rlen = 0; /* remaining bitfield length */
+ int blen; /* bitfield length */
+ int bstr; /* bitfield starting bit within byte */
+ int litval; /* source literal value (if AOP_LIT) */
+ unsigned char mask; /* bitmask within current byte */
int xoffset = 0;
D(emitcode ("; genPackBits",""));
if (blen < 8)
{
mask = ((unsigned char) (0xFF << (blen + bstr)) |
- (unsigned char) (0xFF >> (8 - bstr)));
+ (unsigned char) (0xFF >> (8 - bstr)));
if (AOP_TYPE (right) == AOP_LIT)
{
/* Case with a bitfield length <8 and literal source
*/
- litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+ litval = (int) ulFromVal (AOP (right)->aopu.aop_lit);
litval <<= bstr;
litval &= (~mask) & 0xff;
if (AOP (right)->type == AOP_DIR)
{
emitcode ("mov", "%s,x+", aopAdrStr(AOP (right), offset, FALSE));
- xoffset++;
+ xoffset++;
}
else
{
{
/* Case with partial byte and literal source
*/
- litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+ litval = (int) ulFromVal (AOP (right)->aopu.aop_lit);
litval >>= (blen-rlen);
litval &= (~mask) & 0xff;
emitcode ("lda", "%d,x", offset - xoffset);
{
asmop *derefaop;
int size;
- int offset = 0; /* source byte offset */
- int rlen = 0; /* remaining bitfield length */
- int blen; /* bitfield length */
- int bstr; /* bitfield starting bit within byte */
- int litval; /* source literal value (if AOP_LIT) */
- unsigned char mask; /* bitmask within current byte */
+ int offset = 0; /* source byte offset */
+ int rlen = 0; /* remaining bitfield length */
+ int blen; /* bitfield length */
+ int bstr; /* bitfield starting bit within byte */
+ int litval; /* source literal value (if AOP_LIT) */
+ unsigned char mask; /* bitmask within current byte */
D(emitcode ("; genPackBitsImmed",""));
{
if (AOP_TYPE (right) == AOP_LIT)
{
- litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+ litval = (int) ulFromVal (AOP (right)->aopu.aop_lit);
emitcode ((litval & 1) ? "bset" : "bclr",
"#%d,%s", bstr, aopAdrStr (derefaop, 0, FALSE));
if (blen < 8)
{
mask = ((unsigned char) (0xFF << (blen + bstr)) |
- (unsigned char) (0xFF >> (8 - bstr)));
+ (unsigned char) (0xFF >> (8 - bstr)));
if (AOP_TYPE (right) == AOP_LIT)
{
/* Case with a bitfield length <8 and literal source
*/
- litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+ litval = (int) ulFromVal (AOP (right)->aopu.aop_lit);
litval <<= bstr;
litval &= (~mask) & 0xff;
{
/* Case with partial byte and literal source
*/
- litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+ litval = (int) ulFromVal (AOP (right)->aopu.aop_lit);
litval >>= (blen-rlen);
litval &= (~mask) & 0xff;
loadRegFromAop (hc08_reg_a, derefaop, size-offset-1);
/*-----------------------------------------------------------------*/
static void
genDataPointerSet (operand * right,
- operand * result,
- iCode * ic)
+ operand * result,
+ iCode * ic)
{
int size;
asmop *derefaop;
offset = size-1;
while (size--)
- {
+ {
loadRegFromAop (hc08_reg_a, AOP (right), offset--);
- accopWithMisc ("sta", ",x");
- if (size || pi)
- {
- emitcode ("aix", "#1");
- }
+ accopWithMisc ("sta", ",x");
+ if (size || pi)
+ {
+ emitcode ("aix", "#1");
+ }
hc08_freeReg (hc08_reg_a);
- }
+ }
}
freeAsmop (result, NULL, ic, TRUE);
/* branch or no branch */
if (AOP_TYPE (cond) == AOP_LIT)
{
- unsigned long lit = (unsigned long) floatFromVal (AOP (cond)->aopu.aop_lit);
+ unsigned long lit = ulFromVal (AOP (cond)->aopu.aop_lit);
freeAsmop (cond, NULL, ic, TRUE);
/* if there was something to be popped then do it */
char s[SDCC_NAME_MAX+10];
switch (offset) {
case 0:
- sprintf (s, "#%s", sym->rname);
- break;
+ sprintf (s, "#%s", sym->rname);
+ break;
case 1:
- sprintf (s, "#>%s", sym->rname);
- break;
+ sprintf (s, "#>%s", sym->rname);
+ break;
default:
- sprintf (s, "#(%s >> %d)",
- sym->rname,
- offset * 8);
+ sprintf (s, "#(%s >> %d)",
+ sym->rname,
+ offset * 8);
}
storeConstToAop(s, AOP (IC_RESULT (ic)), offset++);
}
/* if they are in the same place */
#if 0
if (sameRegs (AOP (right), AOP (result)))
- goto release;
+ goto release;
#endif
/* if they in different places then copy */
size = AOP_SIZE (result);
offset = 0;
while (size--)
- {
- transferAopAop(AOP (right), offset, AOP (result), offset);
- offset++;
- }
+ {
+ transferAopAop(AOP (right), offset, AOP (result), offset);
+ offset++;
+ }
goto release;
}
/* pointer to generic pointer */
if (IS_GENPTR (ctype))
- {
- if (IS_PTR (type))
- p_type = DCL_TYPE (type);
- else
- {
- if (SPEC_SCLS(etype)==S_REGISTER) {
- // let's assume it is a generic pointer
- p_type=GPOINTER;
- } else {
- /* we have to go by the storage class */
- p_type = PTR_TYPE (SPEC_OCLS (etype));
- }
- }
-
- /* the first two bytes are known */
- size = GPTRSIZE - 1;
- offset = 0;
- while (size--)
- {
+ {
+ if (IS_PTR (type))
+ p_type = DCL_TYPE (type);
+ else
+ {
+ if (SPEC_SCLS(etype)==S_REGISTER) {
+ // let's assume it is a generic pointer
+ p_type=GPOINTER;
+ } else {
+ /* we have to go by the storage class */
+ p_type = PTR_TYPE (SPEC_OCLS (etype));
+ }
+ }
+
+ /* the first two bytes are known */
+ size = GPTRSIZE - 1;
+ offset = 0;
+ while (size--)
+ {
transferAopAop(AOP (right), offset, AOP (result), offset);
- offset++;
- }
- /* the last byte depending on type */
+ offset++;
+ }
+ /* the last byte depending on type */
#if 0
- {
- int gpVal = pointerTypeToGPByte(p_type, NULL, NULL);
- char gpValStr[10];
-
- if (gpVal == -1)
- {
- // pointerTypeToGPByte will have bitched.
- exit(1);
- }
-
- sprintf(gpValStr, "#0x%x", gpVal);
- aopPut (AOP (result), gpValStr, GPTRSIZE - 1);
- }
+ {
+ int gpVal = pointerTypeToGPByte(p_type, NULL, NULL);
+ char gpValStr[10];
+
+ if (gpVal == -1)
+ {
+ // pointerTypeToGPByte will have bitched.
+ exit(1);
+ }
+
+ sprintf(gpValStr, "#0x%x", gpVal);
+ aopPut (AOP (result), gpValStr, GPTRSIZE - 1);
+ }
#endif
- goto release;
- }
+ goto release;
+ }
/* just copy the pointers */
size = AOP_SIZE (result);
offset = 0;
while (size--)
- {
+ {
transferAopAop(AOP (right), offset, AOP (result), offset);
- offset++;
- }
+ offset++;
+ }
goto release;
}
accopWithMisc ("clra", "");
accopWithMisc ("sbc", zero);
while (size--)
- storeRegToAop (hc08_reg_a, AOP (result), offset++);
+ storeRegToAop (hc08_reg_a, AOP (result), offset++);
}
/* we are done hurray !!!! */
emitcode ("dbnz", "%s,%05d$", aopAdrStr (AOP (IC_RESULT (ic)), 0, FALSE),
- lbl->key + 100);
+ lbl->key + 100);
emitBranch ("bra", lbl1);
emitLabel (lbl);
if (ic->argreg) {
while (size--) {
- transferAopAop( hc08_aop_pass[offset+(ic->argreg-1)], 0,
- AOP (IC_RESULT (ic)), offset);
- if (hc08_aop_pass[offset]->type == AOP_REG)
- hc08_freeReg (hc08_aop_pass[offset]->aopu.aop_reg[0]);
- offset++;
+ transferAopAop( hc08_aop_pass[offset+(ic->argreg-1)], 0,
+ AOP (IC_RESULT (ic)), offset);
+ if (hc08_aop_pass[offset]->type == AOP_REG)
+ hc08_freeReg (hc08_aop_pass[offset]->aopu.aop_reg[0]);
+ offset++;
}
- }
+ }
freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
}
#if 0
_G.debugLine = 1;
if (IS_STATIC (currFunc->etype))
- emitcode ("", "F%s$%s$0$0 ==.", moduleName, currFunc->name);
+ emitcode ("", "F%s$%s$0$0 ==.", moduleName, currFunc->name);
else
- emitcode ("", "G$%s$0$0 ==.", currFunc->name);
+ emitcode ("", "G$%s$0$0 ==.", currFunc->name);
_G.debugLine = 0;
#endif
}
_G.current_iCode = ic;
if (ic->level != clevel || ic->block != cblock)
- {
- if (options.debug)
- {
- debugFile->writeScope(ic);
- }
- clevel = ic->level;
- cblock = ic->block;
- }
-
+ {
+ if (options.debug)
+ {
+ debugFile->writeScope(ic);
+ }
+ clevel = ic->level;
+ cblock = ic->block;
+ }
+
if (ic->lineno && cln != ic->lineno)
- {
- if (options.debug)
- {
- debugFile->writeCLine(ic);
- #if 0
- _G.debugLine = 1;
- emitcode ("", "C$%s$%d$%d$%d ==.",
- FileBaseName (ic->filename), ic->lineno,
- ic->level, ic->block);
- _G.debugLine = 0;
- #endif
- }
- if (!options.noCcodeInAsm) {
- emitcode ("", ";%s:%d: %s", ic->filename, ic->lineno,
- printCLine(ic->filename, ic->lineno));
- }
- cln = ic->lineno;
- }
+ {
+ if (options.debug)
+ {
+ debugFile->writeCLine(ic);
+ #if 0
+ _G.debugLine = 1;
+ emitcode ("", "C$%s$%d$%d$%d ==.",
+ FileBaseName (ic->filename), ic->lineno,
+ ic->level, ic->block);
+ _G.debugLine = 0;
+ #endif
+ }
+ if (!options.noCcodeInAsm) {
+ emitcode ("", ";%s:%d: %s", ic->filename, ic->lineno,
+ printCLine(ic->filename, ic->lineno));
+ }
+ cln = ic->lineno;
+ }
if (options.iCodeInAsm) {
- char regsInUse[80];
- int i;
+ char regsInUse[80];
+ int i;
char *iLine;
- for (i=0; i<6; i++) {
- sprintf (®sInUse[i],
- "%c", ic->riu & (1<<i) ? i+'0' : '-');
- }
- regsInUse[i]=0;
+ for (i=0; i<6; i++) {
+ sprintf (®sInUse[i],
+ "%c", ic->riu & (1<<i) ? i+'0' : '-');
+ }
+ regsInUse[i]=0;
iLine = printILine(ic);
- emitcode("", "; [%s] ic:%d: %s", regsInUse, ic->seq, printILine(ic));
+ emitcode("", "; [%s] ic:%d: %s", regsInUse, ic->seq, printILine(ic));
dbuf_free(iLine);
}
/* if the result is marked as
this has already been generated then
do nothing */
if (resultRemat (ic) || ic->generated)
- continue;
+ continue;
{
int i;
/* depending on the operation */
switch (ic->op)
- {
- case '!':
- genNot (ic);
- break;
-
- case '~':
- genCpl (ic);
- break;
-
- case UNARYMINUS:
- genUminus (ic);
- break;
-
- case IPUSH:
- genIpush (ic);
- break;
-
- case IPOP:
- /* IPOP happens only when trying to restore a
- spilt live range, if there is an ifx statement
- following this pop then the if statement might
- be using some of the registers being popped which
- would destory the contents of the register so
- we need to check for this condition and handle it */
- if (ic->next &&
- ic->next->op == IFX &&
- regsInCommon (IC_LEFT (ic), IC_COND (ic->next)))
- genIfx (ic->next, ic);
- else
- genIpop (ic);
- break;
-
- case CALL:
- genCall (ic);
- break;
-
- case PCALL:
- genPcall (ic);
- break;
-
- case FUNCTION:
- genFunction (ic);
- break;
-
- case ENDFUNCTION:
- genEndFunction (ic);
- break;
-
- case RETURN:
- genRet (ic);
- break;
-
- case LABEL:
- genLabel (ic);
- break;
-
- case GOTO:
- genGoto (ic);
- break;
-
- case '+':
+ {
+ case '!':
+ genNot (ic);
+ break;
+
+ case '~':
+ genCpl (ic);
+ break;
+
+ case UNARYMINUS:
+ genUminus (ic);
+ break;
+
+ case IPUSH:
+ genIpush (ic);
+ break;
+
+ case IPOP:
+ /* IPOP happens only when trying to restore a
+ spilt live range, if there is an ifx statement
+ following this pop then the if statement might
+ be using some of the registers being popped which
+ would destory the contents of the register so
+ we need to check for this condition and handle it */
+ if (ic->next &&
+ ic->next->op == IFX &&
+ regsInCommon (IC_LEFT (ic), IC_COND (ic->next)))
+ genIfx (ic->next, ic);
+ else
+ genIpop (ic);
+ break;
+
+ case CALL:
+ genCall (ic);
+ break;
+
+ case PCALL:
+ genPcall (ic);
+ break;
+
+ case FUNCTION:
+ genFunction (ic);
+ break;
+
+ case ENDFUNCTION:
+ genEndFunction (ic);
+ break;
+
+ case RETURN:
+ genRet (ic);
+ break;
+
+ case LABEL:
+ genLabel (ic);
+ break;
+
+ case GOTO:
+ genGoto (ic);
+ break;
+
+ case '+':
if (!genPointerGetSetOfs (ic))
- genPlus (ic);
- break;
-
- case '-':
- if (!genDjnz (ic, ifxForOp (IC_RESULT (ic), ic)))
- genMinus (ic);
- break;
-
- case '*':
- genMult (ic);
- break;
-
- case '/':
- genDiv (ic);
- break;
-
- case '%':
- genMod (ic);
- break;
-
- case '>':
- case '<':
- case LE_OP:
- case GE_OP:
+ genPlus (ic);
+ break;
+
+ case '-':
+ if (!genDjnz (ic, ifxForOp (IC_RESULT (ic), ic)))
+ genMinus (ic);
+ break;
+
+ case '*':
+ genMult (ic);
+ break;
+
+ case '/':
+ genDiv (ic);
+ break;
+
+ case '%':
+ genMod (ic);
+ break;
+
+ case '>':
+ case '<':
+ case LE_OP:
+ case GE_OP:
genCmp (ic, ifxForOp (IC_RESULT (ic), ic));
break;
case NE_OP:
- case EQ_OP:
+ case EQ_OP:
genCmpEQorNE (ic, ifxForOp (IC_RESULT (ic), ic));
break;
- case AND_OP:
- genAndOp (ic);
- break;
+ case AND_OP:
+ genAndOp (ic);
+ break;
- case OR_OP:
- genOrOp (ic);
- break;
+ case OR_OP:
+ genOrOp (ic);
+ break;
- case '^':
- genXor (ic, ifxForOp (IC_RESULT (ic), ic));
- break;
+ case '^':
+ genXor (ic, ifxForOp (IC_RESULT (ic), ic));
+ break;
- case '|':
- genOr (ic, ifxForOp (IC_RESULT (ic), ic));
- break;
+ case '|':
+ genOr (ic, ifxForOp (IC_RESULT (ic), ic));
+ break;
- case BITWISEAND:
- genAnd (ic, ifxForOp (IC_RESULT (ic), ic));
- break;
+ case BITWISEAND:
+ genAnd (ic, ifxForOp (IC_RESULT (ic), ic));
+ break;
- case INLINEASM:
- genInline (ic);
- break;
+ case INLINEASM:
+ genInline (ic);
+ break;
- case RRC:
- genRRC (ic);
- break;
+ case RRC:
+ genRRC (ic);
+ break;
- case RLC:
- genRLC (ic);
- break;
+ case RLC:
+ genRLC (ic);
+ break;
- case GETHBIT:
- genGetHbit (ic);
- break;
+ case GETHBIT:
+ genGetHbit (ic);
+ break;
- case LEFT_OP:
- genLeftShift (ic);
- break;
+ case LEFT_OP:
+ genLeftShift (ic);
+ break;
- case RIGHT_OP:
- genRightShift (ic);
- break;
+ case RIGHT_OP:
+ genRightShift (ic);
+ break;
- case GET_VALUE_AT_ADDRESS:
- genPointerGet (ic,
+ case GET_VALUE_AT_ADDRESS:
+ genPointerGet (ic,
hasInc (IC_LEFT (ic), ic,
getSize (operandType (IC_RESULT (ic)))),
ifxForOp (IC_RESULT (ic), ic) );
- break;
-
- case '=':
- if (POINTER_SET (ic))
- genPointerSet (ic, hasInc (IC_RESULT(ic),ic,getSize(operandType(IC_RIGHT(ic)))));
- else
- genAssign (ic);
- break;
-
- case IFX:
- genIfx (ic, NULL);
- break;
-
- case ADDRESS_OF:
- genAddrOf (ic);
- break;
-
- case JUMPTABLE:
- genJumpTab (ic);
- break;
-
- case CAST:
- genCast (ic);
- break;
-
- case RECEIVE:
- genReceive (ic);
- break;
-
- case SEND:
- addSet (&_G.sendSet, ic);
- break;
-
- case DUMMY_READ_VOLATILE:
- genDummyRead (ic);
- break;
-
- case CRITICAL:
- genCritical (ic);
- break;
-
- case ENDCRITICAL:
- genEndCritical (ic);
- break;
-
+ break;
+
+ case '=':
+ if (POINTER_SET (ic))
+ genPointerSet (ic, hasInc (IC_RESULT(ic),ic,getSize(operandType(IC_RIGHT(ic)))));
+ else
+ genAssign (ic);
+ break;
+
+ case IFX:
+ genIfx (ic, NULL);
+ break;
+
+ case ADDRESS_OF:
+ genAddrOf (ic);
+ break;
+
+ case JUMPTABLE:
+ genJumpTab (ic);
+ break;
+
+ case CAST:
+ genCast (ic);
+ break;
+
+ case RECEIVE:
+ genReceive (ic);
+ break;
+
+ case SEND:
+ addSet (&_G.sendSet, ic);
+ break;
+
+ case DUMMY_READ_VOLATILE:
+ genDummyRead (ic);
+ break;
+
+ case CRITICAL:
+ genCritical (ic);
+ break;
+
+ case ENDCRITICAL:
+ genEndCritical (ic);
+ break;
+
case SWAP:
- genSwap (ic);
+ genSwap (ic);
break;
- default:
- ic = ic;
- }
+ default:
+ ic = ic;
+ }
if (!hc08_reg_a->isFree)
DD(emitcode("","; forgot to free a"));
if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT)
return FALSE;
- icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
+ icount = (unsigned int) ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
D(emitcode (";","genPlusIncr"));
/* if result in bit space */
if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY)
{
- if ((unsigned long) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit) != 0L)
+ if (ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit) != 0L)
emitcode ("cpl", "c");
outBitC (IC_RESULT (ic));
}
/* if the lower bytes of a literal are zero skip the addition */
if (AOP_TYPE (IC_RIGHT (ic)) == AOP_LIT )
{
- while ((0 == ((unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit) & (0xff << skip_bytes*8))) &&
+ while ((0 == ((unsigned int) ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit) & (0xff << skip_bytes*8))) &&
(skip_bytes+1 < size))
{
skip_bytes++;
/* if the literal value of the right hand side
is greater than 4 then it is not worth it */
- if ((icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 4)
+ if ((icount = (unsigned int) ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 4)
return FALSE;
D (emitcode (";", "genMinusDec"));
unsigned long lit = 0L;
bool useCarry = FALSE;
- lit = (unsigned long) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
+ lit = ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
lit = -(long) lit;
while (size--)
if (AOP_TYPE(left) == AOP_LIT)
{
/* signed literal */
- signed char val = (char) floatFromVal (AOP (left)->aopu.aop_lit);
+ signed char val = (char) ulFromVal (AOP (left)->aopu.aop_lit);
if (val < 0)
compiletimeSign = TRUE;
}
if (AOP_TYPE(right) == AOP_LIT)
{
/* signed literal */
- signed char val = (char) floatFromVal (AOP (right)->aopu.aop_lit);
+ signed char val = (char) ulFromVal (AOP (right)->aopu.aop_lit);
if (val < 0)
compiletimeSign ^= TRUE;
}
/* save the signs of the operands */
if (AOP_TYPE(right) == AOP_LIT)
{
- signed char val = (char) floatFromVal (AOP (right)->aopu.aop_lit);
+ signed char val = (char) ulFromVal (AOP (right)->aopu.aop_lit);
if (!rUnsigned && val < 0)
emitcode ("mov", "b,#0x%02x", -val);
if (AOP_TYPE(left) == AOP_LIT)
{
- signed char val = (char) floatFromVal (AOP (left)->aopu.aop_lit);
+ signed char val = (char) ulFromVal (AOP (left)->aopu.aop_lit);
if (!lUnsigned && val < 0)
emitcode ("mov", "a,#0x%02x", -val);
if (AOP_TYPE(left) == AOP_LIT)
{
/* signed literal */
- signed char val = (char) floatFromVal (AOP (left)->aopu.aop_lit);
+ signed char val = (char) ulFromVal (AOP (left)->aopu.aop_lit);
if (val < 0)
compiletimeSign = TRUE;
}
if (AOP_TYPE(right) == AOP_LIT)
{
/* signed literal */
- signed char val = (char) floatFromVal (AOP (right)->aopu.aop_lit);
+ signed char val = (char) ulFromVal (AOP (right)->aopu.aop_lit);
if (val < 0)
compiletimeSign ^= TRUE;
}
/* save the signs of the operands */
if (AOP_TYPE(right) == AOP_LIT)
{
- signed char val = (char) floatFromVal (AOP (right)->aopu.aop_lit);
+ signed char val = (char) ulFromVal (AOP (right)->aopu.aop_lit);
if (!rUnsigned && val < 0)
emitcode ("mov", "b,#0x%02x", -val);
if (AOP_TYPE(left) == AOP_LIT)
{
- signed char val = (char) floatFromVal (AOP (left)->aopu.aop_lit);
+ signed char val = (char) ulFromVal (AOP (left)->aopu.aop_lit);
if (!lUnsigned && val < 0)
emitcode ("mov", "a,#0x%02x", -val);
/* sign adjust left side */
if (AOP_TYPE(left) == AOP_LIT)
{
- signed char val = (char) floatFromVal (AOP (left)->aopu.aop_lit);
+ signed char val = (char) ulFromVal (AOP (left)->aopu.aop_lit);
if (!lUnsigned && val < 0)
{
{
if (AOP_TYPE (right) == AOP_LIT)
{
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+ lit = ulFromVal (AOP (right)->aopu.aop_lit);
/* optimize if(x < 0) or if(x >= 0) */
if (lit == 0L)
{
}
if (AOP_TYPE (right) == AOP_LIT)
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+ lit = ulFromVal (AOP (right)->aopu.aop_lit);
/* if the right side is a literal then anything goes */
if (AOP_TYPE (right) == AOP_LIT &&
{
if (AOP_TYPE (right) == AOP_LIT)
{
- unsigned long lit = (unsigned long) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
+ unsigned long lit = ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
if (lit == 0L)
{
emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
{
if (AOP_TYPE (right) == AOP_LIT)
{
- unsigned long lit = (unsigned long) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
+ unsigned long lit = ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
if (lit == 0L)
{
emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
left = tmp;
}
if (AOP_TYPE (right) == AOP_LIT)
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+ lit = ulFromVal (AOP (right)->aopu.aop_lit);
size = AOP_SIZE (result);
left = tmp;
}
if (AOP_TYPE (right) == AOP_LIT)
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+ lit = ulFromVal (AOP (right)->aopu.aop_lit);
size = AOP_SIZE (result);
}
if (AOP_TYPE (right) == AOP_LIT)
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+ lit = ulFromVal (AOP (right)->aopu.aop_lit);
size = AOP_SIZE (result);
aopOp (right, ic, FALSE);
aopOp (result, ic, FALSE);
- shCount = (int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
+ shCount = (int) ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
/* get the needed byte into a */
MOVA (aopGet (left, shCount / 8, FALSE, FALSE));
aopOp (right, ic, FALSE);
aopOp (result, ic, FALSE);
- offset = (int)floatFromVal (AOP (right)->aopu.aop_lit) / 8;
+ offset = (int) ulFromVal (AOP (right)->aopu.aop_lit) / 8;
aopPut (result,
aopGet (left, offset, FALSE, FALSE),
0);
aopOp (right, ic, FALSE);
aopOp (result, ic, FALSE);
- offset = (int)floatFromVal (AOP (right)->aopu.aop_lit) / 8;
+ offset = (int) ulFromVal (AOP (right)->aopu.aop_lit) / 8;
aopPut (result,
aopGet (left, offset, FALSE, FALSE),
0);
operand * result,
iCode * ic)
{
- int shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+ int shCount = (int) ulFromVal (AOP (right)->aopu.aop_lit);
int size;
D (emitcode (";", "genLeftShiftLiteral"));
iCode * ic,
int sign)
{
- int shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+ int shCount = (int) ulFromVal (AOP (right)->aopu.aop_lit);
int size;
D (emitcode (";", "genRightShiftLiteral"));
{
/* Case with a bitfield length <8 and literal source
*/
- litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+ litval = (int) ulFromVal (AOP (right)->aopu.aop_lit);
litval <<= bstr;
litval &= (~mask) & 0xff;
emitPtrByteGet (rname, p_type, FALSE);
{
/* Case with partial byte and literal source
*/
- litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+ litval = (int) ulFromVal (AOP (right)->aopu.aop_lit);
litval >>= (blen-rlen);
litval &= (~mask) & 0xff;
emitPtrByteGet (rname, p_type, FALSE);
size = AOP_SIZE (result);
offset = 0;
if (AOP_TYPE (right) == AOP_LIT)
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+ lit = ulFromVal (AOP (right)->aopu.aop_lit);
if ((size > 1) &&
(AOP_TYPE (result) != AOP_REG) &&
/*-------------------------------------------------------------------------
gen.c - source file for code generation for pic
-
+
Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
and - Jean-Louis VERN.jlvern@writeme.com (1999)
Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a)
PIC port - Scott Dattalo scott@dattalo.com (2000)
cont'd - Raphael Neider <rneider AT web.de> (2005)
-
+
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+
In other words, you are welcome to use, share and improve this program.
You are forbidden to forbid anyone else to use, share and improve
what you give them. Help stamp out software-hoarding!
-
+
Notes:
000123 mlh Moved aopLiteral to SDCCglue.c to help the split
Made everything static
#include <string.h>
#include <ctype.h>
#include "SDCCglobl.h"
-#include "newalloc.h"
+#include "newalloc.h"
#include "common.h"
#include "SDCCpeeph.h"
#include "glue.h"
/* The PIC port(s) need not differentiate between POINTER and FPOINTER. */
-#define PIC_IS_DATA_PTR(x) (IS_DATA_PTR(x) || IS_FARPTR(x))
-#define PIC_IS_FARPTR(x) (PIC_IS_DATA_PTR(x))
+#define PIC_IS_DATA_PTR(x) (IS_DATA_PTR(x) || IS_FARPTR(x))
+#define PIC_IS_FARPTR(x) (PIC_IS_DATA_PTR(x))
extern void genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
extern int pic14_hasInterrupt;
//static int optimized_for_speed = 0;
-/* max_key keeps track of the largest label number used in
+/* max_key keeps track of the largest label number used in
a function. This is then used to adjust the label offset
for the next function.
*/
#define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0x00ff)
-/* this is the down and dirty file with all kinds of
+/* this is the down and dirty file with all kinds of
kludgy & hacky stuff. This is what it is all about
CODE GENERATION for a specific MCU . some of the
routines may be reusable, will have to see */
//static short rbank = -1;
static struct {
- short r0Pushed;
- short r1Pushed;
- short accInUse;
- short inLine;
- short debugLine;
- short nRegsSaved;
- set *sendSet;
+ short r0Pushed;
+ short r1Pushed;
+ short accInUse;
+ short inLine;
+ short debugLine;
+ short nRegsSaved;
+ set *sendSet;
} _G;
/* Resolved ifx structure. This structure stores information
about an iCode ifx that makes it easier to generate code.
*/
typedef struct resolvedIfx {
- symbol *lbl; /* pointer to a label */
- int condition; /* true or false ifx */
- int generated; /* set true when the code associated with the ifx
- * is generated */
+ symbol *lbl; /* pointer to a label */
+ int condition; /* true or false ifx */
+ int generated; /* set true when the code associated with the ifx
+ * is generated */
} resolvedIfx;
extern int pic14_ptrRegReq ;
0x07, 0x03, 0x01, 0x00};
#endif
-static pBlock *pb;
+static pBlock *pb;
/*-----------------------------------------------------------------*/
-/* my_powof2(n) - If `n' is an integaer power of 2, then the */
-/* exponent of 2 is returned, otherwise -1 is */
-/* returned. */
+/* my_powof2(n) - If `n' is an integaer power of 2, then the */
+/* exponent of 2 is returned, otherwise -1 is */
+/* returned. */
/* note that this is similar to the function `powof2' in SDCCsymt */
-/* if(n == 2^y) */
-/* return y; */
-/* return -1; */
+/* if(n == 2^y) */
+/* return y; */
+/* return -1; */
/*-----------------------------------------------------------------*/
static int my_powof2 (unsigned long num)
{
- if(num) {
- if( (num & (num-1)) == 0) {
- int nshifts = -1;
- while(num) {
- num>>=1;
- nshifts++;
- }
- return nshifts;
- }
- }
-
- return -1;
+ if(num) {
+ if( (num & (num-1)) == 0) {
+ int nshifts = -1;
+ while(num) {
+ num>>=1;
+ nshifts++;
+ }
+ return nshifts;
+ }
+ }
+
+ return -1;
}
void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
{
-
- DEBUGpic14_emitcode ("; ","line = %d result %s=%s, size=%d, left %s=%s, size=%d, right %s=%s, size=%d",
- line_no,
- ((result) ? AopType(AOP_TYPE(result)) : "-"),
- ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
- ((result) ? AOP_SIZE(result) : 0),
- ((left) ? AopType(AOP_TYPE(left)) : "-"),
- ((left) ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
- ((left) ? AOP_SIZE(left) : 0),
- ((right) ? AopType(AOP_TYPE(right)) : "-"),
- ((right) ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
- ((right) ? AOP_SIZE(right) : 0));
-
+
+ DEBUGpic14_emitcode ("; ","line = %d result %s=%s, size=%d, left %s=%s, size=%d, right %s=%s, size=%d",
+ line_no,
+ ((result) ? AopType(AOP_TYPE(result)) : "-"),
+ ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
+ ((result) ? AOP_SIZE(result) : 0),
+ ((left) ? AopType(AOP_TYPE(left)) : "-"),
+ ((left) ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
+ ((left) ? AOP_SIZE(left) : 0),
+ ((right) ? AopType(AOP_TYPE(right)) : "-"),
+ ((right) ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
+ ((right) ? AOP_SIZE(right) : 0));
+
}
void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
{
-
- DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
- line_no,
- ((result) ? AopType(AOP_TYPE(result)) : "-"),
- ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
- ((left) ? AopType(AOP_TYPE(left)) : "-"),
- ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
- ((right) ? AopType(AOP_TYPE(right)) : "-"),
- ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
-
+
+ DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
+ line_no,
+ ((result) ? AopType(AOP_TYPE(result)) : "-"),
+ ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
+ ((left) ? AopType(AOP_TYPE(left)) : "-"),
+ ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
+ ((right) ? AopType(AOP_TYPE(right)) : "-"),
+ ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
+
}
void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
{
- va_list ap;
- char lb[INITIAL_INLINEASM];
- unsigned char *lbp = (unsigned char *)lb;
-
- if(!debug_verbose && !options.debug)
- return;
-
- va_start(ap,fmt);
-
- if (inst && *inst) {
- if (fmt && *fmt)
- sprintf(lb,"%s\t",inst);
- else
- sprintf(lb,"%s",inst);
- vsprintf(lb+(strlen(lb)),fmt,ap);
- } else
- vsprintf(lb,fmt,ap);
-
- while (isspace(*lbp)) lbp++;
-
- if (lbp && *lbp)
- lineCurr = (lineCurr ?
- connectLine(lineCurr,newLineNode(lb)) :
- (lineHead = newLineNode(lb)));
- lineCurr->isInline = _G.inLine;
- lineCurr->isDebug = _G.debugLine;
-
- addpCode2pBlock(pb,newpCodeCharP(lb));
-
- va_end(ap);
+ va_list ap;
+ char lb[INITIAL_INLINEASM];
+ unsigned char *lbp = (unsigned char *)lb;
+
+ if(!debug_verbose && !options.debug)
+ return;
+
+ va_start(ap,fmt);
+
+ if (inst && *inst) {
+ if (fmt && *fmt)
+ sprintf(lb,"%s\t",inst);
+ else
+ sprintf(lb,"%s",inst);
+ vsprintf(lb+(strlen(lb)),fmt,ap);
+ } else
+ vsprintf(lb,fmt,ap);
+
+ while (isspace(*lbp)) lbp++;
+
+ if (lbp && *lbp)
+ lineCurr = (lineCurr ?
+ connectLine(lineCurr,newLineNode(lb)) :
+ (lineHead = newLineNode(lb)));
+ lineCurr->isInline = _G.inLine;
+ lineCurr->isDebug = _G.debugLine;
+
+ addpCode2pBlock(pb,newpCodeCharP(lb));
+
+ va_end(ap);
}
static void Safe_vsnprintf (char *buf, size_t size, const char *fmt, va_list ap)
{
va_list va;
char buffer[4096];
-
+
va_start (va, fmt);
if (pb) {
Safe_vsnprintf (buffer, 4096, fmt, va);
void emitpLabel(int key)
{
- addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
+ addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
}
/* gen.h defines a macro emitpcode that should be used to call emitpcode
* this instruction geenrated? Here is the answer... */
void emitpcode_real(PIC_OPCODE poc, pCodeOp *pcop)
{
- if(pcop)
- addpCode2pBlock(pb,newpCode(poc,pcop));
- else {
- static int has_warned = 0;
-
- DEBUGpic14_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
- if (!has_warned) {
- has_warned = 1;
- fprintf( stderr, "WARNING: encountered NULL pcop--this is probably a compiler bug...\n" );
- }
- }
+ if(pcop)
+ addpCode2pBlock(pb,newpCode(poc,pcop));
+ else {
+ static int has_warned = 0;
+
+ DEBUGpic14_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
+ if (!has_warned) {
+ has_warned = 1;
+ fprintf( stderr, "WARNING: encountered NULL pcop--this is probably a compiler bug...\n" );
+ }
+ }
}
void emitpcodeNULLop(PIC_OPCODE poc)
{
-
- addpCode2pBlock(pb,newpCode(poc,NULL));
-
+
+ addpCode2pBlock(pb,newpCode(poc,NULL));
+
}
/*-----------------------------------------------------------------*/
-/* pic14_emitcode - writes the code into a file : for now it is simple */
+/* pic14_emitcode - writes the code into a file : for now it is simple */
/*-----------------------------------------------------------------*/
void pic14_emitcode (char *inst,char *fmt, ...)
{
- va_list ap;
- char lb[INITIAL_INLINEASM];
- char *lbp = lb;
-
- va_start(ap,fmt);
-
- if (inst && *inst) {
- if (fmt && *fmt)
- sprintf(lb,"%s\t",inst);
- else
- sprintf(lb,"%s",inst);
- vsprintf(lb+(strlen(lb)),fmt,ap);
- } else
- vsprintf(lb,fmt,ap);
-
- while (isspace(*lbp)) lbp++;
-
- if (lbp && *lbp)
- lineCurr = (lineCurr ?
- connectLine(lineCurr,newLineNode(lb)) :
- (lineHead = newLineNode(lb)));
- lineCurr->isInline = _G.inLine;
- lineCurr->isDebug = _G.debugLine;
- lineCurr->isLabel = (lbp[strlen (lbp) - 1] == ':');
-
- if(debug_verbose)
- addpCode2pBlock(pb,newpCodeCharP(lb));
-
- va_end(ap);
+ va_list ap;
+ char lb[INITIAL_INLINEASM];
+ char *lbp = lb;
+
+ va_start(ap,fmt);
+
+ if (inst && *inst) {
+ if (fmt && *fmt)
+ sprintf(lb,"%s\t",inst);
+ else
+ sprintf(lb,"%s",inst);
+ vsprintf(lb+(strlen(lb)),fmt,ap);
+ } else
+ vsprintf(lb,fmt,ap);
+
+ while (isspace(*lbp)) lbp++;
+
+ if (lbp && *lbp)
+ lineCurr = (lineCurr ?
+ connectLine(lineCurr,newLineNode(lb)) :
+ (lineHead = newLineNode(lb)));
+ lineCurr->isInline = _G.inLine;
+ lineCurr->isDebug = _G.debugLine;
+ lineCurr->isLabel = (lbp[strlen (lbp) - 1] == ':');
+
+ if(debug_verbose)
+ addpCode2pBlock(pb,newpCodeCharP(lb));
+
+ va_end(ap);
}
/*-----------------------------------------------------------------*/
/* pic14_emitDebuggerSymbol - associate the current code location */
-/* with a debugger symbol */
+/* with a debugger symbol */
/*-----------------------------------------------------------------*/
void
pic14_emitDebuggerSymbol (char * debugSym)
{
- _G.debugLine = 1;
- pic14_emitcode ("", ";%s ==.", debugSym);
- _G.debugLine = 0;
+ _G.debugLine = 1;
+ pic14_emitcode ("", ";%s ==.", debugSym);
+ _G.debugLine = 0;
}
#if 0
/*-----------------------------------------------------------------*/
static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
{
- bool r0iu = FALSE , r1iu = FALSE;
- bool r0ou = FALSE , r1ou = FALSE;
-
- /* the logic: if r0 & r1 used in the instruction
- then we are in trouble otherwise */
-
- /* first check if r0 & r1 are used by this
- instruction, in which case we are in trouble */
- if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
- (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
- {
- goto endOfWorld;
- }
-
- r0ou = bitVectBitValue(ic->rMask,R0_IDX);
- r1ou = bitVectBitValue(ic->rMask,R1_IDX);
-
- /* if no usage of r0 then return it */
- if (!r0iu && !r0ou) {
- ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
- (*aopp)->type = AOP_R0;
-
- return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
- }
-
- /* if no usage of r1 then return it */
- if (!r1iu && !r1ou) {
- ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
- (*aopp)->type = AOP_R1;
-
- return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
- }
-
- /* now we know they both have usage */
- /* if r0 not used in this instruction */
- if (!r0iu) {
- /* push it if not already pushed */
- if (!_G.r0Pushed) {
- //pic14_emitcode ("push","%s",
- // pic14_regWithIdx(R0_IDX)->dname);
- _G.r0Pushed++ ;
- }
-
- ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
- (*aopp)->type = AOP_R0;
-
- return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
- }
-
- /* if r1 not used then */
-
- if (!r1iu) {
- /* push it if not already pushed */
- if (!_G.r1Pushed) {
- //pic14_emitcode ("push","%s",
- // pic14_regWithIdx(R1_IDX)->dname);
- _G.r1Pushed++ ;
- }
-
- ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
- (*aopp)->type = AOP_R1;
- return pic14_regWithIdx(R1_IDX);
- }
-
+ bool r0iu = FALSE , r1iu = FALSE;
+ bool r0ou = FALSE , r1ou = FALSE;
+
+ /* the logic: if r0 & r1 used in the instruction
+ then we are in trouble otherwise */
+
+ /* first check if r0 & r1 are used by this
+ instruction, in which case we are in trouble */
+ if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
+ (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
+ {
+ goto endOfWorld;
+ }
+
+ r0ou = bitVectBitValue(ic->rMask,R0_IDX);
+ r1ou = bitVectBitValue(ic->rMask,R1_IDX);
+
+ /* if no usage of r0 then return it */
+ if (!r0iu && !r0ou) {
+ ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
+ (*aopp)->type = AOP_R0;
+
+ return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
+ }
+
+ /* if no usage of r1 then return it */
+ if (!r1iu && !r1ou) {
+ ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
+ (*aopp)->type = AOP_R1;
+
+ return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
+ }
+
+ /* now we know they both have usage */
+ /* if r0 not used in this instruction */
+ if (!r0iu) {
+ /* push it if not already pushed */
+ if (!_G.r0Pushed) {
+ //pic14_emitcode ("push","%s",
+ // pic14_regWithIdx(R0_IDX)->dname);
+ _G.r0Pushed++ ;
+ }
+
+ ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
+ (*aopp)->type = AOP_R0;
+
+ return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
+ }
+
+ /* if r1 not used then */
+
+ if (!r1iu) {
+ /* push it if not already pushed */
+ if (!_G.r1Pushed) {
+ //pic14_emitcode ("push","%s",
+ // pic14_regWithIdx(R1_IDX)->dname);
+ _G.r1Pushed++ ;
+ }
+
+ ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
+ (*aopp)->type = AOP_R1;
+ return pic14_regWithIdx(R1_IDX);
+ }
+
endOfWorld :
- /* I said end of world but not quite end of world yet */
- /* if this is a result then we can push it on the stack*/
- if (result) {
- (*aopp)->type = AOP_STK;
- return NULL;
- }
-
- /* other wise this is true end of the world */
- werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
- "getFreePtr should never reach here");
- exit(0);
+ /* I said end of world but not quite end of world yet */
+ /* if this is a result then we can push it on the stack*/
+ if (result) {
+ (*aopp)->type = AOP_STK;
+ return NULL;
+ }
+
+ /* other wise this is true end of the world */
+ werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
+ "getFreePtr should never reach here");
+ exit(0);
}
#endif
/*-----------------------------------------------------------------*/
-/* newAsmop - creates a new asmOp */
+/* newAsmop - creates a new asmOp */
/*-----------------------------------------------------------------*/
asmop *newAsmop (short type)
{
- asmop *aop;
-
- aop = Safe_calloc(1,sizeof(asmop));
- aop->type = type;
- return aop;
+ asmop *aop;
+
+ aop = Safe_calloc(1,sizeof(asmop));
+ aop->type = type;
+ return aop;
}
static void genSetDPTR(int n)
{
- if (!n)
- {
- pic14_emitcode(";", "Select standard DPTR");
- pic14_emitcode("mov", "dps, #0x00");
- }
- else
- {
- pic14_emitcode(";", "Select alternate DPTR");
- pic14_emitcode("mov", "dps, #0x01");
- }
+ if (!n)
+ {
+ pic14_emitcode(";", "Select standard DPTR");
+ pic14_emitcode("mov", "dps, #0x00");
+ }
+ else
+ {
+ pic14_emitcode(";", "Select alternate DPTR");
+ pic14_emitcode("mov", "dps, #0x01");
+ }
}
/*-----------------------------------------------------------------*/
/* resolveIfx - converts an iCode ifx into a form more useful for */
-/* generating code */
+/* generating code */
/*-----------------------------------------------------------------*/
static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
{
- if(!resIfx)
- return;
-
- // DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
-
- resIfx->condition = 1; /* assume that the ifx is true */
- resIfx->generated = 0; /* indicate that the ifx has not been used */
-
- if(!ifx) {
- resIfx->lbl = NULL; /* this is wrong: newiTempLabel(NULL); / * oops, there is no ifx. so create a label */
- /*
- DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
- __FUNCTION__,__LINE__,resIfx->lbl->key);
- */
- } else {
- if(IC_TRUE(ifx)) {
- resIfx->lbl = IC_TRUE(ifx);
- } else {
- resIfx->lbl = IC_FALSE(ifx);
- resIfx->condition = 0;
- }
- /*
- if(IC_TRUE(ifx))
- DEBUGpic14_emitcode("; ***","ifx true is non-null");
- if(IC_FALSE(ifx))
- DEBUGpic14_emitcode("; ***","ifx false is non-null");
- */
- }
-
- // DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
-
-}
-/*-----------------------------------------------------------------*/
-/* pointerCode - returns the code for a pointer type */
+ if(!resIfx)
+ return;
+
+ // DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ resIfx->condition = 1; /* assume that the ifx is true */
+ resIfx->generated = 0; /* indicate that the ifx has not been used */
+
+ if(!ifx) {
+ resIfx->lbl = NULL; /* this is wrong: newiTempLabel(NULL); / * oops, there is no ifx. so create a label */
+ /*
+ DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
+ __FUNCTION__,__LINE__,resIfx->lbl->key);
+ */
+ } else {
+ if(IC_TRUE(ifx)) {
+ resIfx->lbl = IC_TRUE(ifx);
+ } else {
+ resIfx->lbl = IC_FALSE(ifx);
+ resIfx->condition = 0;
+ }
+ /*
+ if(IC_TRUE(ifx))
+ DEBUGpic14_emitcode("; ***","ifx true is non-null");
+ if(IC_FALSE(ifx))
+ DEBUGpic14_emitcode("; ***","ifx false is non-null");
+ */
+ }
+
+ // DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
+
+}
+/*-----------------------------------------------------------------*/
+/* pointerCode - returns the code for a pointer type */
/*-----------------------------------------------------------------*/
#if 0
static int pointerCode (sym_link *etype)
{
-
- return PTR_TYPE(SPEC_OCLS(etype));
-
+
+ return PTR_TYPE(SPEC_OCLS(etype));
+
}
#endif
/*-----------------------------------------------------------------*/
-/* aopForSym - for a true symbol */
+/* aopForSym - for a true symbol */
/*-----------------------------------------------------------------*/
static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
{
- asmop *aop;
- memmap *space= SPEC_OCLS(sym->etype);
-
- DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
- /* if already has one */
- if (sym->aop)
- return sym->aop;
-
- //DEBUGpic14_emitcode(";","%d",__LINE__);
- /* if it is in direct space */
- if (IN_DIRSPACE(space)) {
- sym->aop = aop = newAsmop (AOP_DIR);
- aop->aopu.aop_dir = sym->rname ;
- aop->size = getSize(sym->type);
- DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
- return aop;
- }
-
- /* special case for a function */
- if (IS_FUNC(sym->type)) {
-
- sym->aop = aop = newAsmop(AOP_PCODE);
- aop->aopu.pcop = popGetImmd(sym->rname,0,0,1);
- PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
- PCOI(aop->aopu.pcop)->_function = 1;
- PCOI(aop->aopu.pcop)->index = 0;
- aop->size = FPTRSIZE;
- /*
- sym->aop = aop = newAsmop(AOP_IMMD);
- aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
- strcpy(aop->aopu.aop_immd,sym->rname);
- aop->size = FPTRSIZE;
- */
- DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
- return aop;
- }
-
- if (IS_ARRAY(sym->type)) {
- sym->aop = aop = newAsmop(AOP_PCODE);
- aop->aopu.pcop = popGetImmd(sym->rname,0,0,1);
- PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
- PCOI(aop->aopu.pcop)->_function = 0;
- PCOI(aop->aopu.pcop)->index = 0;
- aop->size = getSize(sym->etype) * DCL_ELEM(sym->type);
-
- DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
- return aop;
- }
-
- /* only remaining is far space */
- /* in which case DPTR gets the address */
- sym->aop = aop = newAsmop(AOP_PCODE);
-
- aop->aopu.pcop = popGetImmd(sym->rname,0,0,0);
- PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
- PCOI(aop->aopu.pcop)->index = 0;
-
- DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
- __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
-
- allocDirReg (IC_LEFT(ic));
-
- aop->size = FPTRSIZE;
- /*
- DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
- sym->aop = aop = newAsmop(AOP_DPTR);
- pic14_emitcode ("mov","dptr,#%s", sym->rname);
- aop->size = getSize(sym->type);
-
- DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
- */
-
- /* if it is in code space */
- if (IN_CODESPACE(space))
- aop->code = 1;
-
- return aop;
-}
-
-/*-----------------------------------------------------------------*/
-/* aopForRemat - rematerialzes an object */
+ asmop *aop;
+ memmap *space= SPEC_OCLS(sym->etype);
+
+ DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* if already has one */
+ if (sym->aop)
+ return sym->aop;
+
+ //DEBUGpic14_emitcode(";","%d",__LINE__);
+ /* if it is in direct space */
+ if (IN_DIRSPACE(space)) {
+ sym->aop = aop = newAsmop (AOP_DIR);
+ aop->aopu.aop_dir = sym->rname ;
+ aop->size = getSize(sym->type);
+ DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
+ return aop;
+ }
+
+ /* special case for a function */
+ if (IS_FUNC(sym->type)) {
+
+ sym->aop = aop = newAsmop(AOP_PCODE);
+ aop->aopu.pcop = popGetImmd(sym->rname,0,0,1);
+ PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
+ PCOI(aop->aopu.pcop)->_function = 1;
+ PCOI(aop->aopu.pcop)->index = 0;
+ aop->size = FPTRSIZE;
+ /*
+ sym->aop = aop = newAsmop(AOP_IMMD);
+ aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
+ strcpy(aop->aopu.aop_immd,sym->rname);
+ aop->size = FPTRSIZE;
+ */
+ DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
+ return aop;
+ }
+
+ if (IS_ARRAY(sym->type)) {
+ sym->aop = aop = newAsmop(AOP_PCODE);
+ aop->aopu.pcop = popGetImmd(sym->rname,0,0,1);
+ PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
+ PCOI(aop->aopu.pcop)->_function = 0;
+ PCOI(aop->aopu.pcop)->index = 0;
+ aop->size = getSize(sym->etype) * DCL_ELEM(sym->type);
+
+ DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
+ return aop;
+ }
+
+ /* only remaining is far space */
+ /* in which case DPTR gets the address */
+ sym->aop = aop = newAsmop(AOP_PCODE);
+
+ aop->aopu.pcop = popGetImmd(sym->rname,0,0,0);
+ PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
+ PCOI(aop->aopu.pcop)->index = 0;
+
+ DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
+ __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
+
+ allocDirReg (IC_LEFT(ic));
+
+ aop->size = FPTRSIZE;
+ /*
+ DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
+ sym->aop = aop = newAsmop(AOP_DPTR);
+ pic14_emitcode ("mov","dptr,#%s", sym->rname);
+ aop->size = getSize(sym->type);
+
+ DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
+ */
+
+ /* if it is in code space */
+ if (IN_CODESPACE(space))
+ aop->code = 1;
+
+ return aop;
+}
+
+/*-----------------------------------------------------------------*/
+/* aopForRemat - rematerialzes an object */
/*-----------------------------------------------------------------*/
static asmop *aopForRemat (operand *op) // x symbol *sym)
{
- symbol *sym = OP_SYMBOL(op);
- iCode *ic = NULL;
- asmop *aop = newAsmop(AOP_PCODE);
- int val = 0;
- int offset = 0;
-
- ic = sym->rematiCode;
-
- DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
- if(IS_OP_POINTER(op)) {
- DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
- }
- for (;;) {
- if (ic->op == '+') {
- val += (int) operandLitValue(IC_RIGHT(ic));
- } else if (ic->op == '-') {
- val -= (int) operandLitValue(IC_RIGHT(ic));
- } else
- break;
-
- ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
- }
-
- offset = OP_SYMBOL(IC_LEFT(ic))->offset;
- aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val,0);
- PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
- PCOI(aop->aopu.pcop)->index = val;
-
- DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
- __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
- val, IS_PTR_CONST(operandType(op)));
-
- // DEBUGpic14_emitcode(";","aop type %s",AopType(AOP_TYPE(IC_LEFT(ic))));
-
- allocDirReg (IC_LEFT(ic));
-
- return aop;
+ symbol *sym = OP_SYMBOL(op);
+ iCode *ic = NULL;
+ asmop *aop = newAsmop(AOP_PCODE);
+ int val = 0;
+ int offset = 0;
+
+ ic = sym->rematiCode;
+
+ DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
+ if(IS_OP_POINTER(op)) {
+ DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
+ }
+ for (;;) {
+ if (ic->op == '+') {
+ val += (int) operandLitValue(IC_RIGHT(ic));
+ } else if (ic->op == '-') {
+ val -= (int) operandLitValue(IC_RIGHT(ic));
+ } else
+ break;
+
+ ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
+ }
+
+ offset = OP_SYMBOL(IC_LEFT(ic))->offset;
+ aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val,0);
+ PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
+ PCOI(aop->aopu.pcop)->index = val;
+
+ DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
+ __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
+ val, IS_PTR_CONST(operandType(op)));
+
+ // DEBUGpic14_emitcode(";","aop type %s",AopType(AOP_TYPE(IC_LEFT(ic))));
+
+ allocDirReg (IC_LEFT(ic));
+
+ return aop;
}
int aopIdx (asmop *aop, int offset)
{
- if(!aop)
- return -1;
-
- if(aop->type != AOP_REG)
- return -2;
-
- return aop->aopu.aop_reg[offset]->rIdx;
-
+ if(!aop)
+ return -1;
+
+ if(aop->type != AOP_REG)
+ return -2;
+
+ return aop->aopu.aop_reg[offset]->rIdx;
+
}
/*-----------------------------------------------------------------*/
-/* regsInCommon - two operands have some registers in common */
+/* regsInCommon - two operands have some registers in common */
/*-----------------------------------------------------------------*/
static bool regsInCommon (operand *op1, operand *op2)
{
- symbol *sym1, *sym2;
- int i;
-
- /* if they have registers in common */
- if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
- return FALSE ;
-
- sym1 = OP_SYMBOL(op1);
- sym2 = OP_SYMBOL(op2);
-
- if (sym1->nRegs == 0 || sym2->nRegs == 0)
- return FALSE ;
-
- for (i = 0 ; i < sym1->nRegs ; i++) {
- int j;
- if (!sym1->regs[i])
- continue ;
-
- for (j = 0 ; j < sym2->nRegs ;j++ ) {
- if (!sym2->regs[j])
- continue ;
-
- if (sym2->regs[j] == sym1->regs[i])
- return TRUE ;
- }
- }
-
- return FALSE ;
-}
-
-/*-----------------------------------------------------------------*/
-/* operandsEqu - equivalent */
+ symbol *sym1, *sym2;
+ int i;
+
+ /* if they have registers in common */
+ if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
+ return FALSE ;
+
+ sym1 = OP_SYMBOL(op1);
+ sym2 = OP_SYMBOL(op2);
+
+ if (sym1->nRegs == 0 || sym2->nRegs == 0)
+ return FALSE ;
+
+ for (i = 0 ; i < sym1->nRegs ; i++) {
+ int j;
+ if (!sym1->regs[i])
+ continue ;
+
+ for (j = 0 ; j < sym2->nRegs ;j++ ) {
+ if (!sym2->regs[j])
+ continue ;
+
+ if (sym2->regs[j] == sym1->regs[i])
+ return TRUE ;
+ }
+ }
+
+ return FALSE ;
+}
+
+/*-----------------------------------------------------------------*/
+/* operandsEqu - equivalent */
/*-----------------------------------------------------------------*/
static bool operandsEqu ( operand *op1, operand *op2)
{
- symbol *sym1, *sym2;
-
- /* if they not symbols */
- if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
- return FALSE;
-
- sym1 = OP_SYMBOL(op1);
- sym2 = OP_SYMBOL(op2);
-
- /* if both are itemps & one is spilt
- and the other is not then false */
- if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
- sym1->isspilt != sym2->isspilt )
- return FALSE ;
-
- /* if they are the same */
- if (sym1 == sym2)
- return TRUE ;
-
- if (sym1->rname[0] && sym2->rname[0]
- && strcmp (sym1->rname, sym2->rname) == 0)
- return TRUE;
-
-
- /* if left is a tmp & right is not */
- if (IS_ITEMP(op1) &&
- !IS_ITEMP(op2) &&
- sym1->isspilt &&
- (sym1->usl.spillLoc == sym2))
- return TRUE;
-
- if (IS_ITEMP(op2) &&
- !IS_ITEMP(op1) &&
- sym2->isspilt &&
- sym1->level > 0 &&
- (sym2->usl.spillLoc == sym1))
- return TRUE ;
-
- return FALSE ;
+ symbol *sym1, *sym2;
+
+ /* if they not symbols */
+ if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
+ return FALSE;
+
+ sym1 = OP_SYMBOL(op1);
+ sym2 = OP_SYMBOL(op2);
+
+ /* if both are itemps & one is spilt
+ and the other is not then false */
+ if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
+ sym1->isspilt != sym2->isspilt )
+ return FALSE ;
+
+ /* if they are the same */
+ if (sym1 == sym2)
+ return TRUE ;
+
+ if (sym1->rname[0] && sym2->rname[0]
+ && strcmp (sym1->rname, sym2->rname) == 0)
+ return TRUE;
+
+
+ /* if left is a tmp & right is not */
+ if (IS_ITEMP(op1) &&
+ !IS_ITEMP(op2) &&
+ sym1->isspilt &&
+ (sym1->usl.spillLoc == sym2))
+ return TRUE;
+
+ if (IS_ITEMP(op2) &&
+ !IS_ITEMP(op1) &&
+ sym2->isspilt &&
+ sym1->level > 0 &&
+ (sym2->usl.spillLoc == sym1))
+ return TRUE ;
+
+ return FALSE ;
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
{
- int i;
-
- if (aop1 == aop2)
- return TRUE ;
-
- if (aop1->type != AOP_REG ||
- aop2->type != AOP_REG )
- return FALSE ;
-
- if (aop1->size != aop2->size )
- return FALSE ;
-
- for (i = 0 ; i < aop1->size ; i++ )
- if (aop1->aopu.aop_reg[i] !=
- aop2->aopu.aop_reg[i] )
- return FALSE ;
-
- return TRUE ;
+ int i;
+
+ if (aop1 == aop2)
+ return TRUE ;
+
+ if (aop1->type != AOP_REG ||
+ aop2->type != AOP_REG )
+ return FALSE ;
+
+ if (aop1->size != aop2->size )
+ return FALSE ;
+
+ for (i = 0 ; i < aop1->size ; i++ )
+ if (aop1->aopu.aop_reg[i] !=
+ aop2->aopu.aop_reg[i] )
+ return FALSE ;
+
+ return TRUE ;
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
void aopOp (operand *op, iCode *ic, bool result)
{
- asmop *aop;
- symbol *sym;
- int i;
-
- if (!op)
- return ;
-
- /* if this a literal */
- if (IS_OP_LITERAL(op)) {
- op->aop = aop = newAsmop(AOP_LIT);
- aop->aopu.aop_lit = op->operand.valOperand;
- aop->size = getSize(operandType(op));
- return;
- }
-
- {
- sym_link *type = operandType(op);
- if(IS_PTR_CONST(type))
- DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
- }
-
- /* if already has a asmop then continue */
- if (op->aop)
- return ;
-
- /* if the underlying symbol has a aop */
- if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
- DEBUGpic14_emitcode(";","%d",__LINE__);
- op->aop = OP_SYMBOL(op)->aop;
- return;
- }
-
- /* if this is a true symbol */
- if (IS_TRUE_SYMOP(op)) {
- //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
- op->aop = aopForSym(ic,OP_SYMBOL(op),result);
- return ;
- }
-
- /* this is a temporary : this has
- only four choices :
- a) register
- b) spillocation
- c) rematerialize
- d) conditional
- e) can be a return use only */
-
- sym = OP_SYMBOL(op);
-
-
- /* if the type is a conditional */
- if (sym->regType == REG_CND) {
- aop = op->aop = sym->aop = newAsmop(AOP_CRY);
- aop->size = 0;
- return;
- }
-
- /* if it is spilt then two situations
- a) is rematerialize
- b) has a spill location */
- if (sym->isspilt || sym->nRegs == 0) {
-
- DEBUGpic14_emitcode(";","%d",__LINE__);
- /* rematerialize it NOW */
- if (sym->remat) {
-
- sym->aop = op->aop = aop = aopForRemat (op);
- aop->size = getSize(sym->type);
- //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
- return;
- }
-
+ asmop *aop;
+ symbol *sym;
+ int i;
+
+ if (!op)
+ return ;
+
+ /* if this a literal */
+ if (IS_OP_LITERAL(op)) {
+ op->aop = aop = newAsmop(AOP_LIT);
+ aop->aopu.aop_lit = op->operand.valOperand;
+ aop->size = getSize(operandType(op));
+ return;
+ }
+
+ {
+ sym_link *type = operandType(op);
+ if(IS_PTR_CONST(type))
+ DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
+ }
+
+ /* if already has a asmop then continue */
+ if (op->aop)
+ return ;
+
+ /* if the underlying symbol has a aop */
+ if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
+ DEBUGpic14_emitcode(";","%d",__LINE__);
+ op->aop = OP_SYMBOL(op)->aop;
+ return;
+ }
+
+ /* if this is a true symbol */
+ if (IS_TRUE_SYMOP(op)) {
+ //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
+ op->aop = aopForSym(ic,OP_SYMBOL(op),result);
+ return ;
+ }
+
+ /* this is a temporary : this has
+ only four choices :
+ a) register
+ b) spillocation
+ c) rematerialize
+ d) conditional
+ e) can be a return use only */
+
+ sym = OP_SYMBOL(op);
+
+
+ /* if the type is a conditional */
+ if (sym->regType == REG_CND) {
+ aop = op->aop = sym->aop = newAsmop(AOP_CRY);
+ aop->size = 0;
+ return;
+ }
+
+ /* if it is spilt then two situations
+ a) is rematerialize
+ b) has a spill location */
+ if (sym->isspilt || sym->nRegs == 0) {
+
+ DEBUGpic14_emitcode(";","%d",__LINE__);
+ /* rematerialize it NOW */
+ if (sym->remat) {
+
+ sym->aop = op->aop = aop = aopForRemat (op);
+ aop->size = getSize(sym->type);
+ //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
+ return;
+ }
+
#if 0
- /* WREG is not usable as an ordinary operand with PIC architecture,
- * one might introduce a scratch register that can be used to make
- * WREG accesible as an operand... disable WREG for now */
- if (sym->accuse) {
- int i;
- aop = op->aop = sym->aop = newAsmop(AOP_ACC);
- aop->size = getSize(sym->type);
- for ( i = 0 ; i < 2 ; i++ )
- aop->aopu.aop_str[i] = accUse[i];
- DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
- return;
- }
+ /* WREG is not usable as an ordinary operand with PIC architecture,
+ * one might introduce a scratch register that can be used to make
+ * WREG accesible as an operand... disable WREG for now */
+ if (sym->accuse) {
+ int i;
+ aop = op->aop = sym->aop = newAsmop(AOP_ACC);
+ aop->size = getSize(sym->type);
+ for ( i = 0 ; i < 2 ; i++ )
+ aop->aopu.aop_str[i] = accUse[i];
+ DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
+ return;
+ }
#endif
-
- if (sym->ruonly ) {
- if(sym->isptr) { // && sym->uptr
- aop = op->aop = sym->aop = newAsmop(AOP_PCODE);
- aop->aopu.pcop = newpCodeOp(NULL,PO_GPR_POINTER); //popCopyReg(&pc_fsr);
-
- //PCOI(aop->aopu.pcop)->_const = 0;
- //PCOI(aop->aopu.pcop)->index = 0;
- /*
- DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
- __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
- */
- //allocDirReg (IC_LEFT(ic));
-
- aop->size = getSize(sym->type);
- DEBUGpic14_emitcode(";","%d",__LINE__);
- return;
-
- } else {
-
- unsigned i;
-
- aop = op->aop = sym->aop = newAsmop(AOP_STR);
- aop->size = getSize(sym->type);
- for ( i = 0 ; i < fReturnSizePic ; i++ )
- aop->aopu.aop_str[i] = fReturn[i];
-
- DEBUGpic14_emitcode(";","%d",__LINE__);
- return;
- }
- }
-
- /* else spill location */
- if (sym->usl.spillLoc)
- {
- asmop *oldAsmOp = NULL;
-
- if (getSize(sym->type) != getSize(sym->usl.spillLoc->type))
- {
- /* force a new aop if sizes differ */
- oldAsmOp = sym->usl.spillLoc->aop;
- sym->usl.spillLoc->aop = NULL;
- }
- DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
- __FUNCTION__,__LINE__,
- sym->usl.spillLoc->rname,
- sym->rname, sym->usl.spillLoc->offset);
-
- sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
- if (getSize(sym->type) != getSize(sym->usl.spillLoc->type))
- {
- /* Don't reuse the new aop, go with the last one */
- sym->usl.spillLoc->aop = oldAsmOp;
- }
- //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
- aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
- getSize(sym->type),
- sym->usl.spillLoc->offset);
- aop->size = getSize(sym->type);
-
- return;
- }
- }
-
- {
- sym_link *type = operandType(op);
- if(IS_PTR_CONST(type))
- DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
- }
-
- /* must be in a register */
- DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
- sym->aop = op->aop = aop = newAsmop(AOP_REG);
- aop->size = sym->nRegs;
- for ( i = 0 ; i < sym->nRegs ;i++)
- aop->aopu.aop_reg[i] = sym->regs[i];
-}
-
-/*-----------------------------------------------------------------*/
-/* freeAsmop - free up the asmop given to an operand */
+
+ if (sym->ruonly ) {
+ if(sym->isptr) { // && sym->uptr
+ aop = op->aop = sym->aop = newAsmop(AOP_PCODE);
+ aop->aopu.pcop = newpCodeOp(NULL,PO_GPR_POINTER); //popCopyReg(&pc_fsr);
+
+ //PCOI(aop->aopu.pcop)->_const = 0;
+ //PCOI(aop->aopu.pcop)->index = 0;
+ /*
+ DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
+ __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
+ */
+ //allocDirReg (IC_LEFT(ic));
+
+ aop->size = getSize(sym->type);
+ DEBUGpic14_emitcode(";","%d",__LINE__);
+ return;
+
+ } else {
+
+ unsigned i;
+
+ aop = op->aop = sym->aop = newAsmop(AOP_STR);
+ aop->size = getSize(sym->type);
+ for ( i = 0 ; i < fReturnSizePic ; i++ )
+ aop->aopu.aop_str[i] = fReturn[i];
+
+ DEBUGpic14_emitcode(";","%d",__LINE__);
+ return;
+ }
+ }
+
+ /* else spill location */
+ if (sym->usl.spillLoc)
+ {
+ asmop *oldAsmOp = NULL;
+
+ if (getSize(sym->type) != getSize(sym->usl.spillLoc->type))
+ {
+ /* force a new aop if sizes differ */
+ oldAsmOp = sym->usl.spillLoc->aop;
+ sym->usl.spillLoc->aop = NULL;
+ }
+ DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
+ __FUNCTION__,__LINE__,
+ sym->usl.spillLoc->rname,
+ sym->rname, sym->usl.spillLoc->offset);
+
+ sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
+ if (getSize(sym->type) != getSize(sym->usl.spillLoc->type))
+ {
+ /* Don't reuse the new aop, go with the last one */
+ sym->usl.spillLoc->aop = oldAsmOp;
+ }
+ //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
+ aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
+ getSize(sym->type),
+ sym->usl.spillLoc->offset);
+ aop->size = getSize(sym->type);
+
+ return;
+ }
+ }
+
+ {
+ sym_link *type = operandType(op);
+ if(IS_PTR_CONST(type))
+ DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
+ }
+
+ /* must be in a register */
+ DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
+ sym->aop = op->aop = aop = newAsmop(AOP_REG);
+ aop->size = sym->nRegs;
+ for ( i = 0 ; i < sym->nRegs ;i++)
+ aop->aopu.aop_reg[i] = sym->regs[i];
+}
+
+/*-----------------------------------------------------------------*/
+/* freeAsmop - free up the asmop given to an operand */
/*----------------------------------------------------------------*/
void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
-{
- asmop *aop ;
-
- if (!op)
- aop = aaop;
- else
- aop = op->aop;
-
- if (!aop)
- return ;
-
- if (aop->freed)
- goto dealloc;
-
- aop->freed = 1;
-
- /* depending on the asmop type only three cases need work AOP_RO
- , AOP_R1 && AOP_STK */
+{
+ asmop *aop ;
+
+ if (!op)
+ aop = aaop;
+ else
+ aop = op->aop;
+
+ if (!aop)
+ return ;
+
+ if (aop->freed)
+ goto dealloc;
+
+ aop->freed = 1;
+
+ /* depending on the asmop type only three cases need work AOP_RO
+ , AOP_R1 && AOP_STK */
#if 0
- switch (aop->type) {
- case AOP_R0 :
- if (_G.r0Pushed ) {
- if (pop) {
- pic14_emitcode ("pop","ar0");
- _G.r0Pushed--;
- }
- }
- bitVectUnSetBit(ic->rUsed,R0_IDX);
- break;
-
- case AOP_R1 :
- if (_G.r1Pushed ) {
- if (pop) {
- pic14_emitcode ("pop","ar1");
- _G.r1Pushed--;
- }
- }
- bitVectUnSetBit(ic->rUsed,R1_IDX);
- break;
-
- case AOP_STK :
- {
- int sz = aop->size;
- int stk = aop->aopu.aop_stk + aop->size;
- bitVectUnSetBit(ic->rUsed,R0_IDX);
- bitVectUnSetBit(ic->rUsed,R1_IDX);
-
- getFreePtr(ic,&aop,FALSE);
-
- if (options.stack10bit)
- {
- /* I'm not sure what to do here yet... */
- /* #STUB */
- fprintf(stderr,
- "*** Warning: probably generating bad code for "
- "10 bit stack mode.\n");
- }
-
- if (stk) {
- pic14_emitcode ("mov","a,_bp");
- pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
- pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
- } else {
- pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
- }
-
- while (sz--) {
- pic14_emitcode("pop","acc");
- pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
- if (!sz) break;
- pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
- }
- op->aop = aop;
- freeAsmop(op,NULL,ic,TRUE);
- if (_G.r0Pushed) {
- pic14_emitcode("pop","ar0");
- _G.r0Pushed--;
- }
-
- if (_G.r1Pushed) {
- pic14_emitcode("pop","ar1");
- _G.r1Pushed--;
- }
- }
- }
+ switch (aop->type) {
+ case AOP_R0 :
+ if (_G.r0Pushed ) {
+ if (pop) {
+ pic14_emitcode ("pop","ar0");
+ _G.r0Pushed--;
+ }
+ }
+ bitVectUnSetBit(ic->rUsed,R0_IDX);
+ break;
+
+ case AOP_R1 :
+ if (_G.r1Pushed ) {
+ if (pop) {
+ pic14_emitcode ("pop","ar1");
+ _G.r1Pushed--;
+ }
+ }
+ bitVectUnSetBit(ic->rUsed,R1_IDX);
+ break;
+
+ case AOP_STK :
+ {
+ int sz = aop->size;
+ int stk = aop->aopu.aop_stk + aop->size;
+ bitVectUnSetBit(ic->rUsed,R0_IDX);
+ bitVectUnSetBit(ic->rUsed,R1_IDX);
+
+ getFreePtr(ic,&aop,FALSE);
+
+ if (options.stack10bit)
+ {
+ /* I'm not sure what to do here yet... */
+ /* #STUB */
+ fprintf(stderr,
+ "*** Warning: probably generating bad code for "
+ "10 bit stack mode.\n");
+ }
+
+ if (stk) {
+ pic14_emitcode ("mov","a,_bp");
+ pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
+ pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
+ } else {
+ pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
+ }
+
+ while (sz--) {
+ pic14_emitcode("pop","acc");
+ pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
+ if (!sz) break;
+ pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
+ }
+ op->aop = aop;
+ freeAsmop(op,NULL,ic,TRUE);
+ if (_G.r0Pushed) {
+ pic14_emitcode("pop","ar0");
+ _G.r0Pushed--;
+ }
+
+ if (_G.r1Pushed) {
+ pic14_emitcode("pop","ar1");
+ _G.r1Pushed--;
+ }
+ }
+ }
#endif
-
+
dealloc:
- /* all other cases just dealloc */
- if (op ) {
- op->aop = NULL;
- if (IS_SYMOP(op)) {
- OP_SYMBOL(op)->aop = NULL;
- /* if the symbol has a spill */
- if (SPIL_LOC(op))
- SPIL_LOC(op)->aop = NULL;
- }
- }
+ /* all other cases just dealloc */
+ if (op ) {
+ op->aop = NULL;
+ if (IS_SYMOP(op)) {
+ OP_SYMBOL(op)->aop = NULL;
+ /* if the symbol has a spill */
+ if (SPIL_LOC(op))
+ SPIL_LOC(op)->aop = NULL;
+ }
+ }
}
/*-----------------------------------------------------------------*/
-/* aopGet - for fetching value of the aop */
+/* aopGet - for fetching value of the aop */
/*-----------------------------------------------------------------*/
char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
{
- char *s = buffer ;
- char *rs;
-
- //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- /* offset is greater than
- size then zero */
- assert(aop);
- if (offset > (aop->size - 1) &&
- aop->type != AOP_LIT)
- return zero;
-
- /* depending on type */
- switch (aop->type) {
-
- case AOP_R0:
- case AOP_R1:
- DEBUGpic14_emitcode(";","%d",__LINE__);
- /* if we need to increment it */
- while (offset > aop->coff) {
- pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
- aop->coff++;
- }
-
- while (offset < aop->coff) {
- pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
- aop->coff--;
- }
-
- aop->coff = offset ;
- if (aop->paged) {
- pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
- return (dname ? "acc" : "a");
- }
- sprintf(s,"@%s",aop->aopu.aop_ptr->name);
- rs = Safe_calloc(1,strlen(s)+1);
- strcpy(rs,s);
- return rs;
-
- case AOP_DPTR:
- case AOP_DPTR2:
- DEBUGpic14_emitcode(";","%d",__LINE__);
- if (aop->type == AOP_DPTR2)
- {
- genSetDPTR(1);
- }
-
- while (offset > aop->coff) {
- pic14_emitcode ("inc","dptr");
- aop->coff++;
- }
-
- while (offset < aop->coff) {
- pic14_emitcode("lcall","__decdptr");
- aop->coff--;
- }
-
- aop->coff = offset;
- if (aop->code) {
- pic14_emitcode("clr","a");
- pic14_emitcode("movc","a,@a+dptr");
- }
- else {
- pic14_emitcode("movx","a,@dptr");
- }
-
- if (aop->type == AOP_DPTR2)
- {
- genSetDPTR(0);
- }
-
- return (dname ? "acc" : "a");
-
-
- case AOP_IMMD:
- if (bit16)
- sprintf (s,"%s",aop->aopu.aop_immd);
- else
- if (offset)
- sprintf(s,"(%s >> %d)",
- aop->aopu.aop_immd,
- offset*8);
- else
- sprintf(s,"%s",
- aop->aopu.aop_immd);
- DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
- rs = Safe_calloc(1,strlen(s)+1);
- strcpy(rs,s);
- return rs;
-
- case AOP_DIR:
- if (offset) {
- sprintf(s,"(%s + %d)",
- aop->aopu.aop_dir,
- offset);
- DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
- } else
- sprintf(s,"%s",aop->aopu.aop_dir);
- rs = Safe_calloc(1,strlen(s)+1);
- strcpy(rs,s);
- return rs;
-
- case AOP_REG:
- //if (dname)
- // return aop->aopu.aop_reg[offset]->dname;
- //else
- return aop->aopu.aop_reg[offset]->name;
-
- case AOP_CRY:
- //pic14_emitcode(";","%d",__LINE__);
- return aop->aopu.aop_dir;
-
- case AOP_ACC:
- DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
- return "AOP_accumulator_bug";
-
- case AOP_LIT:
- sprintf(s, "0x%02x", pic14aopLiteral (aop->aopu.aop_lit, offset));
- rs = Safe_strdup(s);
- return rs;
-
- case AOP_STR:
- aop->coff = offset ;
- if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
- dname)
- return "acc";
- DEBUGpic14_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
-
- return aop->aopu.aop_str[offset];
-
- case AOP_PCODE:
- {
- pCodeOp *pcop = aop->aopu.pcop;
- DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
- if(pcop->name) {
- if (pcop->type == PO_IMMEDIATE) {
- offset += PCOI(pcop)->index;
- }
- if (offset) {
- DEBUGpic14_emitcode(";","%s offset %d",pcop->name,offset);
- sprintf(s,"(%s+%d)", pcop->name,offset);
- } else {
- DEBUGpic14_emitcode(";","%s",pcop->name);
- sprintf(s,"%s", pcop->name);
- }
- } else
- sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
-
- }
- rs = Safe_calloc(1,strlen(s)+1);
- strcpy(rs,s);
- return rs;
-
+ char *s = buffer ;
+ char *rs;
+
+ //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* offset is greater than
+ size then zero */
+ assert(aop);
+ if (offset > (aop->size - 1) &&
+ aop->type != AOP_LIT)
+ return zero;
+
+ /* depending on type */
+ switch (aop->type) {
+
+ case AOP_R0:
+ case AOP_R1:
+ DEBUGpic14_emitcode(";","%d",__LINE__);
+ /* if we need to increment it */
+ while (offset > aop->coff) {
+ pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
+ aop->coff++;
+ }
+
+ while (offset < aop->coff) {
+ pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
+ aop->coff--;
+ }
+
+ aop->coff = offset ;
+ if (aop->paged) {
+ pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
+ return (dname ? "acc" : "a");
+ }
+ sprintf(s,"@%s",aop->aopu.aop_ptr->name);
+ rs = Safe_calloc(1,strlen(s)+1);
+ strcpy(rs,s);
+ return rs;
+
+ case AOP_DPTR:
+ case AOP_DPTR2:
+ DEBUGpic14_emitcode(";","%d",__LINE__);
+ if (aop->type == AOP_DPTR2)
+ {
+ genSetDPTR(1);
+ }
+
+ while (offset > aop->coff) {
+ pic14_emitcode ("inc","dptr");
+ aop->coff++;
+ }
+
+ while (offset < aop->coff) {
+ pic14_emitcode("lcall","__decdptr");
+ aop->coff--;
+ }
+
+ aop->coff = offset;
+ if (aop->code) {
+ pic14_emitcode("clr","a");
+ pic14_emitcode("movc","a,@a+dptr");
+ }
+ else {
+ pic14_emitcode("movx","a,@dptr");
+ }
+
+ if (aop->type == AOP_DPTR2)
+ {
+ genSetDPTR(0);
+ }
+
+ return (dname ? "acc" : "a");
+
+
+ case AOP_IMMD:
+ if (bit16)
+ sprintf (s,"%s",aop->aopu.aop_immd);
+ else
+ if (offset)
+ sprintf(s,"(%s >> %d)",
+ aop->aopu.aop_immd,
+ offset*8);
+ else
+ sprintf(s,"%s",
+ aop->aopu.aop_immd);
+ DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
+ rs = Safe_calloc(1,strlen(s)+1);
+ strcpy(rs,s);
+ return rs;
+
+ case AOP_DIR:
+ if (offset) {
+ sprintf(s,"(%s + %d)",
+ aop->aopu.aop_dir,
+ offset);
+ DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
+ } else
+ sprintf(s,"%s",aop->aopu.aop_dir);
+ rs = Safe_calloc(1,strlen(s)+1);
+ strcpy(rs,s);
+ return rs;
+
+ case AOP_REG:
+ //if (dname)
+ // return aop->aopu.aop_reg[offset]->dname;
+ //else
+ return aop->aopu.aop_reg[offset]->name;
+
+ case AOP_CRY:
+ //pic14_emitcode(";","%d",__LINE__);
+ return aop->aopu.aop_dir;
+
+ case AOP_ACC:
+ DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
+ return "AOP_accumulator_bug";
+
+ case AOP_LIT:
+ sprintf(s, "0x%02x", pic14aopLiteral (aop->aopu.aop_lit, offset));
+ rs = Safe_strdup(s);
+ return rs;
+
+ case AOP_STR:
+ aop->coff = offset ;
+ if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
+ dname)
+ return "acc";
+ DEBUGpic14_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
+
+ return aop->aopu.aop_str[offset];
+
+ case AOP_PCODE:
+ {
+ pCodeOp *pcop = aop->aopu.pcop;
+ DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
+ if(pcop->name) {
+ if (pcop->type == PO_IMMEDIATE) {
+ offset += PCOI(pcop)->index;
+ }
+ if (offset) {
+ DEBUGpic14_emitcode(";","%s offset %d",pcop->name,offset);
+ sprintf(s,"(%s+%d)", pcop->name,offset);
+ } else {
+ DEBUGpic14_emitcode(";","%s",pcop->name);
+ sprintf(s,"%s", pcop->name);
+ }
+ } else
+ sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
+
+ }
+ rs = Safe_calloc(1,strlen(s)+1);
+ strcpy(rs,s);
+ return rs;
+
}
-
+
werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
- "aopget got unsupported aop->type");
+ "aopget got unsupported aop->type");
exit(0);
}
/*-----------------------------------------------------------------*/
-/* popGetTempReg - create a new temporary pCodeOp */
+/* popGetTempReg - create a new temporary pCodeOp */
/*-----------------------------------------------------------------*/
pCodeOp *popGetTempReg(void)
{
-
- pCodeOp *pcop;
-
- pcop = newpCodeOp(NULL, PO_GPR_TEMP);
- if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
- PCOR(pcop)->r->wasUsed=1;
- PCOR(pcop)->r->isFree=0;
- }
-
- return pcop;
+
+ pCodeOp *pcop;
+
+ pcop = newpCodeOp(NULL, PO_GPR_TEMP);
+ if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
+ PCOR(pcop)->r->wasUsed=1;
+ PCOR(pcop)->r->isFree=0;
+ }
+
+ return pcop;
}
/*-----------------------------------------------------------------*/
-/* popReleaseTempReg - create a new temporary pCodeOp */
+/* popReleaseTempReg - create a new temporary pCodeOp */
/*-----------------------------------------------------------------*/
void popReleaseTempReg(pCodeOp *pcop)
{
-
- if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
- PCOR(pcop)->r->isFree = 1;
-
+
+ if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
+ PCOR(pcop)->r->isFree = 1;
+
}
/*-----------------------------------------------------------------*/
-/* popGetLabel - create a new pCodeOp of type PO_LABEL */
+/* popGetLabel - create a new pCodeOp of type PO_LABEL */
/*-----------------------------------------------------------------*/
pCodeOp *popGetLabel(unsigned int key)
{
-
- DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
-
- if(key>(unsigned int)max_key)
- max_key = key;
-
- return newpCodeOpLabel(NULL,key+100+labelOffset);
+
+ DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
+
+ if(key>(unsigned int)max_key)
+ max_key = key;
+
+ return newpCodeOpLabel(NULL,key+100+labelOffset);
}
/*-------------------------------------------------------------------*/
/*-------------------------------------------------------------------*/
pCodeOp *popGetHighLabel(unsigned int key)
{
- pCodeOp *pcop;
- pcop = popGetLabel(key);
- PCOLAB(pcop)->offset = 1;
- return pcop;
+ pCodeOp *pcop;
+ pcop = popGetLabel(key);
+ PCOLAB(pcop)->offset = 1;
+ return pcop;
}
/*-----------------------------------------------------------------*/
-/* popGetLit - asm operator to pcode operator conversion */
+/* popGetLit - asm operator to pcode operator conversion */
/*-----------------------------------------------------------------*/
pCodeOp *popGetLit(unsigned int lit)
{
-
- return newpCodeOpLit((unsigned char)lit);
+
+ return newpCodeOpLit((unsigned char)lit);
}
/*-----------------------------------------------------------------*/
-/* popGetImmd - asm operator to pcode immediate conversion */
+/* popGetImmd - asm operator to pcode immediate conversion */
/*-----------------------------------------------------------------*/
pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func)
{
-
- return newpCodeOpImmd(name, offset,index, 0, is_func);
+
+ return newpCodeOpImmd(name, offset,index, 0, is_func);
}
extern set *externs;
/*-----------------------------------------------------------------*/
-/* popGetWithString - asm operator to pcode operator conversion */
+/* popGetWithString - asm operator to pcode operator conversion */
/*-----------------------------------------------------------------*/
pCodeOp *popGetWithString(char *str, int isExtern)
{
- pCodeOp *pcop;
-
-
- if(!str) {
- fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
- exit (1);
- }
-
- pcop = newpCodeOp(str,PO_STR);
- PCOS(pcop)->isPublic = isExtern ? 1 : 0;
+ pCodeOp *pcop;
+
- return pcop;
+ if(!str) {
+ fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
+ exit (1);
+ }
+
+ pcop = newpCodeOp(str,PO_STR);
+ PCOS(pcop)->isPublic = isExtern ? 1 : 0;
+
+ return pcop;
}
pCodeOp *popGetExternal (char *str, int isReg)
{
- pCodeOp *pcop;
-
- if (isReg) {
- pcop = newpCodeOpRegFromStr(str);
- } else {
- pcop = popGetWithString (str, 1);
- }
-
- if (str) {
- symbol *sym;
-
- for (sym = setFirstItem (externs); sym; sym = setNextItem (externs))
- {
- if (!strcmp (str, sym->rname)) break;
- }
-
- if (!sym)
- {
- sym = newSymbol(str, 0);
- strncpy(sym->rname, str, SDCC_NAME_MAX);
- addSet (&externs, sym);
- } // if
- sym->used++;
- }
- return pcop;
-}
-
-/*-----------------------------------------------------------------*/
-/* popRegFromString - */
+ pCodeOp *pcop;
+
+ if (isReg) {
+ pcop = newpCodeOpRegFromStr(str);
+ } else {
+ pcop = popGetWithString (str, 1);
+ }
+
+ if (str) {
+ symbol *sym;
+
+ for (sym = setFirstItem (externs); sym; sym = setNextItem (externs))
+ {
+ if (!strcmp (str, sym->rname)) break;
+ }
+
+ if (!sym)
+ {
+ sym = newSymbol(str, 0);
+ strncpy(sym->rname, str, SDCC_NAME_MAX);
+ addSet (&externs, sym);
+ } // if
+ sym->used++;
+ }
+ return pcop;
+}
+
+/*-----------------------------------------------------------------*/
+/* popRegFromString - */
/*-----------------------------------------------------------------*/
pCodeOp *popRegFromString(char *str, int size, int offset)
{
-
- pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
- pcop->type = PO_DIR;
-
- DEBUGpic14_emitcode(";","%d",__LINE__);
-
- if(!str)
- str = "BAD_STRING";
-
- pcop->name = Safe_calloc(1,strlen(str)+1);
- strcpy(pcop->name,str);
-
- //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
-
- PCOR(pcop)->r = dirregWithName(pcop->name);
- if(PCOR(pcop)->r == NULL) {
- //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
- PCOR(pcop)->r = allocRegByName (pcop->name,size);
- DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
- } else {
- DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
- }
- PCOR(pcop)->instance = offset;
-
- return pcop;
+
+ pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
+ pcop->type = PO_DIR;
+
+ DEBUGpic14_emitcode(";","%d",__LINE__);
+
+ if(!str)
+ str = "BAD_STRING";
+
+ pcop->name = Safe_calloc(1,strlen(str)+1);
+ strcpy(pcop->name,str);
+
+ //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
+
+ PCOR(pcop)->r = dirregWithName(pcop->name);
+ if(PCOR(pcop)->r == NULL) {
+ //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
+ PCOR(pcop)->r = allocRegByName (pcop->name,size);
+ DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
+ } else {
+ DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
+ }
+ PCOR(pcop)->instance = offset;
+
+ return pcop;
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
pCodeOp *popRegFromIdx(int rIdx)
{
- pCodeOp *pcop;
-
- DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
- __FUNCTION__,__LINE__,rIdx);
-
- pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
-
- PCOR(pcop)->rIdx = rIdx;
- PCOR(pcop)->r = typeRegWithIdx(rIdx,REG_STK,1);
- PCOR(pcop)->r->isFree = 0;
- PCOR(pcop)->r->wasUsed = 1;
-
- pcop->type = PCOR(pcop)->r->pc_type;
-
-
- return pcop;
+ pCodeOp *pcop;
+
+ DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
+ __FUNCTION__,__LINE__,rIdx);
+
+ pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
+
+ PCOR(pcop)->rIdx = rIdx;
+ PCOR(pcop)->r = typeRegWithIdx(rIdx,REG_STK,1);
+ PCOR(pcop)->r->isFree = 0;
+ PCOR(pcop)->r->wasUsed = 1;
+
+ pcop->type = PCOR(pcop)->r->pc_type;
+
+
+ return pcop;
}
/*-----------------------------------------------------------------*/
-/* popGet - asm operator to pcode operator conversion */
+/* popGet - asm operator to pcode operator conversion */
/*-----------------------------------------------------------------*/
pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
{
- //char *s = buffer ;
- //char *rs;
-
- pCodeOp *pcop;
-
- //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- /* offset is greater than
- size then zero */
-
- assert (aop);
-
-
- /* XXX: still needed for BIT operands (AOP_CRY) */
- if (offset > (aop->size - 1) &&
- aop->type != AOP_LIT &&
- aop->type != AOP_PCODE)
- {
- printf( "%s: (offset[%d] > AOP_SIZE(op)[%d]-1) && AOP_TYPE(op) != AOP_LIT)\n", __FUNCTION__, offset, aop->size);
- return NULL; //zero;
- }
-
- /* depending on type */
- switch (aop->type) {
-
- case AOP_R0:
- case AOP_R1:
- case AOP_DPTR:
- case AOP_DPTR2:
- case AOP_ACC:
- DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
- return NULL;
-
- case AOP_IMMD:
- DEBUGpic14_emitcode(";","%d",__LINE__);
- return popGetImmd(aop->aopu.aop_immd,offset,0,0);
-
- case AOP_DIR:
- return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
+ //char *s = buffer ;
+ //char *rs;
+
+ pCodeOp *pcop;
+
+ //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* offset is greater than
+ size then zero */
+
+ assert (aop);
+
+
+ /* XXX: still needed for BIT operands (AOP_CRY) */
+ if (offset > (aop->size - 1) &&
+ aop->type != AOP_LIT &&
+ aop->type != AOP_PCODE)
+ {
+ printf( "%s: (offset[%d] > AOP_SIZE(op)[%d]-1) && AOP_TYPE(op) != AOP_LIT)\n", __FUNCTION__, offset, aop->size);
+ return NULL; //zero;
+ }
+
+ /* depending on type */
+ switch (aop->type) {
+
+ case AOP_R0:
+ case AOP_R1:
+ case AOP_DPTR:
+ case AOP_DPTR2:
+ case AOP_ACC:
+ DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
+ return NULL;
+
+ case AOP_IMMD:
+ DEBUGpic14_emitcode(";","%d",__LINE__);
+ return popGetImmd(aop->aopu.aop_immd,offset,0,0);
+
+ case AOP_DIR:
+ return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
#if 0
- pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
- pcop->type = PO_DIR;
-
- pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
- strcpy(pcop->name,aop->aopu.aop_dir);
- PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
- if(PCOR(pcop)->r == NULL) {
- //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
- PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
- DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
- } else {
- DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
- }
- PCOR(pcop)->instance = offset;
-
- return pcop;
+ pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
+ pcop->type = PO_DIR;
+
+ pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
+ strcpy(pcop->name,aop->aopu.aop_dir);
+ PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
+ if(PCOR(pcop)->r == NULL) {
+ //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
+ PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
+ DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
+ } else {
+ DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
+ }
+ PCOR(pcop)->instance = offset;
+
+ return pcop;
#endif
-
- case AOP_REG:
- {
- int rIdx;
- assert (offset < aop->size);
- rIdx = aop->aopu.aop_reg[offset]->rIdx;
-
- pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
- PCOR(pcop)->rIdx = rIdx;
- PCOR(pcop)->r = pic14_regWithIdx(rIdx);
- PCOR(pcop)->r->wasUsed=1;
- PCOR(pcop)->r->isFree=0;
-
- PCOR(pcop)->instance = offset;
- pcop->type = PCOR(pcop)->r->pc_type;
- //rs = aop->aopu.aop_reg[offset]->name;
- DEBUGpic14_emitcode(";","%d rIdx = r0x%X ",__LINE__,rIdx);
- return pcop;
- }
-
- case AOP_CRY:
- pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
- PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
- //if(PCOR(pcop)->r == NULL)
- //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
- return pcop;
-
- case AOP_LIT:
- return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
-
- case AOP_STR:
- DEBUGpic14_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]);
- return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
- /*
- pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
- PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
- PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
- pcop->type = PCOR(pcop)->r->pc_type;
- pcop->name = PCOR(pcop)->r->name;
-
- return pcop;
- */
-
- case AOP_PCODE:
- pcop = NULL;
- DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s + %i) %d %s",pCodeOpType(aop->aopu.pcop), offset,
- __LINE__,
- ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
- //emitpComment ("popGet; name %s, offset: %i, pcop-type: %s\n", aop->aopu.pcop->name, offset, pCodeOpType (aop->aopu.pcop));
- switch (aop->aopu.pcop->type)
- {
- case PO_IMMEDIATE:
- pcop = pCodeOpCopy (aop->aopu.pcop);
- /* usually we want to access the memory at "<symbol> + offset" (using ->index),
- * but sometimes we want to access the high byte of the symbol's address (using ->offset) */
- PCOI(pcop)->index += offset;
- //PCOI(pcop)->offset = 0;
- break;
- case PO_DIR:
- pcop = pCodeOpCopy (aop->aopu.pcop);
- PCOR(pcop)->instance = offset;
- break;
- default:
- assert ( !"unhandled pCode type" );
- break;
- } // switch
- return pcop;
- }
-
- werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
- "popGet got unsupported aop->type");
- exit(0);
+
+ case AOP_REG:
+ {
+ int rIdx;
+ assert (offset < aop->size);
+ rIdx = aop->aopu.aop_reg[offset]->rIdx;
+
+ pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
+ PCOR(pcop)->rIdx = rIdx;
+ PCOR(pcop)->r = pic14_regWithIdx(rIdx);
+ PCOR(pcop)->r->wasUsed=1;
+ PCOR(pcop)->r->isFree=0;
+
+ PCOR(pcop)->instance = offset;
+ pcop->type = PCOR(pcop)->r->pc_type;
+ //rs = aop->aopu.aop_reg[offset]->name;
+ DEBUGpic14_emitcode(";","%d rIdx = r0x%X ",__LINE__,rIdx);
+ return pcop;
+ }
+
+ case AOP_CRY:
+ pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
+ PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
+ //if(PCOR(pcop)->r == NULL)
+ //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
+ return pcop;
+
+ case AOP_LIT:
+ return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
+
+ case AOP_STR:
+ DEBUGpic14_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]);
+ return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
+ /*
+ pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
+ PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
+ PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
+ pcop->type = PCOR(pcop)->r->pc_type;
+ pcop->name = PCOR(pcop)->r->name;
+
+ return pcop;
+ */
+
+ case AOP_PCODE:
+ pcop = NULL;
+ DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s + %i) %d %s",pCodeOpType(aop->aopu.pcop), offset,
+ __LINE__,
+ ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
+ //emitpComment ("popGet; name %s, offset: %i, pcop-type: %s\n", aop->aopu.pcop->name, offset, pCodeOpType (aop->aopu.pcop));
+ switch (aop->aopu.pcop->type)
+ {
+ case PO_IMMEDIATE:
+ pcop = pCodeOpCopy (aop->aopu.pcop);
+ /* usually we want to access the memory at "<symbol> + offset" (using ->index),
+ * but sometimes we want to access the high byte of the symbol's address (using ->offset) */
+ PCOI(pcop)->index += offset;
+ //PCOI(pcop)->offset = 0;
+ break;
+ case PO_DIR:
+ pcop = pCodeOpCopy (aop->aopu.pcop);
+ PCOR(pcop)->instance = offset;
+ break;
+ default:
+ assert ( !"unhandled pCode type" );
+ break;
+ } // switch
+ return pcop;
+ }
+
+ werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
+ "popGet got unsupported aop->type");
+ exit(0);
}
/*-----------------------------------------------------------------*/
pcop = popGetLit (aop->code ? GPTRTAG_CODE : GPTRTAG_DATA);
return pcop;
}
-
+
pcop = pCodeOpCopy (pcop);
/* usually we want to access the memory at "<symbol> + offset" (using ->index),
* but sometimes we want to access the high byte of the symbol's address (using ->offset) */
}
/*-----------------------------------------------------------------*/
-/* aopPut - puts a string for a aop */
+/* aopPut - puts a string for a aop */
/*-----------------------------------------------------------------*/
void aopPut (asmop *aop, char *s, int offset)
{
- char *d = buffer ;
- symbol *lbl ;
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- if (aop->size && offset > ( aop->size - 1)) {
- werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
- "aopPut got offset > aop->size");
- exit(0);
- }
-
- /* will assign value to value */
- /* depending on where it is ofcourse */
- switch (aop->type) {
- case AOP_DIR:
- if (offset) {
- sprintf(d,"(%s + %d)",
- aop->aopu.aop_dir,offset);
- fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
-
- } else
- sprintf(d,"%s",aop->aopu.aop_dir);
-
- if (strcmp(d,s)) {
- DEBUGpic14_emitcode(";","%d",__LINE__);
- if(strcmp(s,"W"))
- pic14_emitcode("movf","%s,w",s);
- pic14_emitcode("movwf","%s",d);
-
- if(strcmp(s,"W")) {
- pic14_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
- if(offset >= aop->size) {
- emitpcode(POC_CLRF,popGet(aop,offset));
- break;
- } else {
- emitpcode(POC_MOVFW, popGetImmd(s,0,offset,0));
- }
- }
- emitpcode(POC_MOVWF,popGet(aop,offset));
-
- }
- break;
-
- case AOP_REG:
- if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) {
- //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
- /*
- if (*s == '@' ||
- strcmp(s,"r0") == 0 ||
- strcmp(s,"r1") == 0 ||
- strcmp(s,"r2") == 0 ||
- strcmp(s,"r3") == 0 ||
- strcmp(s,"r4") == 0 ||
- strcmp(s,"r5") == 0 ||
- strcmp(s,"r6") == 0 ||
- strcmp(s,"r7") == 0 )
- pic14_emitcode("mov","%s,%s ; %d",
- aop->aopu.aop_reg[offset]->dname,s,__LINE__);
- else
- */
-
- if(strcmp(s,"W")==0 )
- pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
-
- pic14_emitcode("movwf","%s",
- aop->aopu.aop_reg[offset]->name);
-
- if(strcmp(s,zero)==0) {
- emitpcode(POC_CLRF,popGet(aop,offset));
-
- } else if(strcmp(s,"W")==0) {
- pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
- pcop->type = PO_GPR_REGISTER;
-
- PCOR(pcop)->rIdx = -1;
- PCOR(pcop)->r = NULL;
-
- DEBUGpic14_emitcode(";","%d",__LINE__);
- pcop->name = Safe_strdup(s);
- emitpcode(POC_MOVFW,pcop);
- emitpcode(POC_MOVWF,popGet(aop,offset));
- } else if(strcmp(s,one)==0) {
- emitpcode(POC_CLRF,popGet(aop,offset));
- emitpcode(POC_INCF,popGet(aop,offset));
- } else {
- emitpcode(POC_MOVWF,popGet(aop,offset));
- }
- }
- break;
-
- case AOP_DPTR:
- case AOP_DPTR2:
-
- if (aop->type == AOP_DPTR2)
- {
- genSetDPTR(1);
- }
-
- if (aop->code) {
- werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
- "aopPut writting to code space");
- exit(0);
- }
-
- while (offset > aop->coff) {
- aop->coff++;
- pic14_emitcode ("inc","dptr");
- }
-
- while (offset < aop->coff) {
- aop->coff-- ;
- pic14_emitcode("lcall","__decdptr");
- }
-
- aop->coff = offset;
-
- /* if not in accumulater */
- MOVA(s);
-
- pic14_emitcode ("movx","@dptr,a");
-
- if (aop->type == AOP_DPTR2)
- {
- genSetDPTR(0);
- }
- break;
-
- case AOP_R0:
- case AOP_R1:
- while (offset > aop->coff) {
- aop->coff++;
- pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
- }
- while (offset < aop->coff) {
- aop->coff-- ;
- pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
- }
- aop->coff = offset;
-
- if (aop->paged) {
- MOVA(s);
- pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
-
- } else
- if (*s == '@') {
- MOVA(s);
- pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
- } else
- if (strcmp(s,"r0") == 0 ||
- strcmp(s,"r1") == 0 ||
- strcmp(s,"r2") == 0 ||
- strcmp(s,"r3") == 0 ||
- strcmp(s,"r4") == 0 ||
- strcmp(s,"r5") == 0 ||
- strcmp(s,"r6") == 0 ||
- strcmp(s,"r7") == 0 ) {
- char buffer[10];
- sprintf(buffer,"a%s",s);
- pic14_emitcode("mov","@%s,%s",
- aop->aopu.aop_ptr->name,buffer);
- } else
- pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
-
- break;
-
- case AOP_STK:
- if (strcmp(s,"a") == 0)
- pic14_emitcode("push","acc");
- else
- pic14_emitcode("push","%s",s);
-
- break;
-
- case AOP_CRY:
- /* if bit variable */
- if (!aop->aopu.aop_dir) {
- pic14_emitcode("clr","a");
- pic14_emitcode("rlc","a");
- } else {
- if (s == zero)
- pic14_emitcode("clr","%s",aop->aopu.aop_dir);
- else
- if (s == one)
- pic14_emitcode("setb","%s",aop->aopu.aop_dir);
- else
- if (!strcmp(s,"c"))
- pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
- else {
- lbl = newiTempLabel(NULL);
-
- if (strcmp(s,"a")) {
- MOVA(s);
- }
- pic14_emitcode("clr","c");
- pic14_emitcode("jz","%05d_DS_",lbl->key+100);
- pic14_emitcode("cpl","c");
- pic14_emitcode("","%05d_DS_:",lbl->key+100);
- pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
- }
- }
- break;
-
- case AOP_STR:
- aop->coff = offset;
- if (strcmp(aop->aopu.aop_str[offset],s))
- pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
- break;
-
- case AOP_ACC:
- aop->coff = offset;
- if (!offset && (strcmp(s,"acc") == 0))
- break;
-
- if (strcmp(aop->aopu.aop_str[offset],s))
- pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
- break;
-
- default :
- werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
- "aopPut got unsupported aop->type");
- exit(0);
- }
-
+ char *d = buffer ;
+ symbol *lbl ;
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ if (aop->size && offset > ( aop->size - 1)) {
+ werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
+ "aopPut got offset > aop->size");
+ exit(0);
+ }
+
+ /* will assign value to value */
+ /* depending on where it is ofcourse */
+ switch (aop->type) {
+ case AOP_DIR:
+ if (offset) {
+ sprintf(d,"(%s + %d)",
+ aop->aopu.aop_dir,offset);
+ fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
+
+ } else
+ sprintf(d,"%s",aop->aopu.aop_dir);
+
+ if (strcmp(d,s)) {
+ DEBUGpic14_emitcode(";","%d",__LINE__);
+ if(strcmp(s,"W"))
+ pic14_emitcode("movf","%s,w",s);
+ pic14_emitcode("movwf","%s",d);
+
+ if(strcmp(s,"W")) {
+ pic14_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
+ if(offset >= aop->size) {
+ emitpcode(POC_CLRF,popGet(aop,offset));
+ break;
+ } else {
+ emitpcode(POC_MOVFW, popGetImmd(s,0,offset,0));
+ }
+ }
+ emitpcode(POC_MOVWF,popGet(aop,offset));
+
+ }
+ break;
+
+ case AOP_REG:
+ if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) {
+ //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
+ /*
+ if (*s == '@' ||
+ strcmp(s,"r0") == 0 ||
+ strcmp(s,"r1") == 0 ||
+ strcmp(s,"r2") == 0 ||
+ strcmp(s,"r3") == 0 ||
+ strcmp(s,"r4") == 0 ||
+ strcmp(s,"r5") == 0 ||
+ strcmp(s,"r6") == 0 ||
+ strcmp(s,"r7") == 0 )
+ pic14_emitcode("mov","%s,%s ; %d",
+ aop->aopu.aop_reg[offset]->dname,s,__LINE__);
+ else
+ */
+
+ if(strcmp(s,"W")==0 )
+ pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
+
+ pic14_emitcode("movwf","%s",
+ aop->aopu.aop_reg[offset]->name);
+
+ if(strcmp(s,zero)==0) {
+ emitpcode(POC_CLRF,popGet(aop,offset));
+
+ } else if(strcmp(s,"W")==0) {
+ pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
+ pcop->type = PO_GPR_REGISTER;
+
+ PCOR(pcop)->rIdx = -1;
+ PCOR(pcop)->r = NULL;
+
+ DEBUGpic14_emitcode(";","%d",__LINE__);
+ pcop->name = Safe_strdup(s);
+ emitpcode(POC_MOVFW,pcop);
+ emitpcode(POC_MOVWF,popGet(aop,offset));
+ } else if(strcmp(s,one)==0) {
+ emitpcode(POC_CLRF,popGet(aop,offset));
+ emitpcode(POC_INCF,popGet(aop,offset));
+ } else {
+ emitpcode(POC_MOVWF,popGet(aop,offset));
+ }
+ }
+ break;
+
+ case AOP_DPTR:
+ case AOP_DPTR2:
+
+ if (aop->type == AOP_DPTR2)
+ {
+ genSetDPTR(1);
+ }
+
+ if (aop->code) {
+ werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
+ "aopPut writting to code space");
+ exit(0);
+ }
+
+ while (offset > aop->coff) {
+ aop->coff++;
+ pic14_emitcode ("inc","dptr");
+ }
+
+ while (offset < aop->coff) {
+ aop->coff-- ;
+ pic14_emitcode("lcall","__decdptr");
+ }
+
+ aop->coff = offset;
+
+ /* if not in accumulater */
+ MOVA(s);
+
+ pic14_emitcode ("movx","@dptr,a");
+
+ if (aop->type == AOP_DPTR2)
+ {
+ genSetDPTR(0);
+ }
+ break;
+
+ case AOP_R0:
+ case AOP_R1:
+ while (offset > aop->coff) {
+ aop->coff++;
+ pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
+ }
+ while (offset < aop->coff) {
+ aop->coff-- ;
+ pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
+ }
+ aop->coff = offset;
+
+ if (aop->paged) {
+ MOVA(s);
+ pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
+
+ } else
+ if (*s == '@') {
+ MOVA(s);
+ pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
+ } else
+ if (strcmp(s,"r0") == 0 ||
+ strcmp(s,"r1") == 0 ||
+ strcmp(s,"r2") == 0 ||
+ strcmp(s,"r3") == 0 ||
+ strcmp(s,"r4") == 0 ||
+ strcmp(s,"r5") == 0 ||
+ strcmp(s,"r6") == 0 ||
+ strcmp(s,"r7") == 0 ) {
+ char buffer[10];
+ sprintf(buffer,"a%s",s);
+ pic14_emitcode("mov","@%s,%s",
+ aop->aopu.aop_ptr->name,buffer);
+ } else
+ pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
+
+ break;
+
+ case AOP_STK:
+ if (strcmp(s,"a") == 0)
+ pic14_emitcode("push","acc");
+ else
+ pic14_emitcode("push","%s",s);
+
+ break;
+
+ case AOP_CRY:
+ /* if bit variable */
+ if (!aop->aopu.aop_dir) {
+ pic14_emitcode("clr","a");
+ pic14_emitcode("rlc","a");
+ } else {
+ if (s == zero)
+ pic14_emitcode("clr","%s",aop->aopu.aop_dir);
+ else
+ if (s == one)
+ pic14_emitcode("setb","%s",aop->aopu.aop_dir);
+ else
+ if (!strcmp(s,"c"))
+ pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
+ else {
+ lbl = newiTempLabel(NULL);
+
+ if (strcmp(s,"a")) {
+ MOVA(s);
+ }
+ pic14_emitcode("clr","c");
+ pic14_emitcode("jz","%05d_DS_",lbl->key+100);
+ pic14_emitcode("cpl","c");
+ pic14_emitcode("","%05d_DS_:",lbl->key+100);
+ pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
+ }
+ }
+ break;
+
+ case AOP_STR:
+ aop->coff = offset;
+ if (strcmp(aop->aopu.aop_str[offset],s))
+ pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
+ break;
+
+ case AOP_ACC:
+ aop->coff = offset;
+ if (!offset && (strcmp(s,"acc") == 0))
+ break;
+
+ if (strcmp(aop->aopu.aop_str[offset],s))
+ pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
+ break;
+
+ default :
+ werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
+ "aopPut got unsupported aop->type");
+ exit(0);
+ }
+
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static void mov2w_op (operand *op, int offset)
{
- assert (op);
- FENTRY;
+ assert (op);
+ FENTRY;
- /* for PO_IMMEDIATEs: use address or value? */
- if (op_isLitLike (op))
- {
- /* access address of op */
- if (AOP_TYPE(op) != AOP_LIT) { assert (offset < 3); }
- if (IS_SYMOP(op) && IS_GENPTR(OP_SYM_TYPE(op)) && AOP_SIZE(op) < offset)
- {
- if (offset == GPTRSIZE-1)
- emitpcode (POC_MOVLW, popGetLit (GPTRTAG_DATA));
- else
- emitpcode (POC_MOVLW, popGetLit (0));
- }
- else
- emitpcode (POC_MOVLW, popGetAddr(AOP(op), offset, 0));
- } else {
- /* access value stored in op */
- mov2w (AOP(op), offset);
- }
+ /* for PO_IMMEDIATEs: use address or value? */
+ if (op_isLitLike (op))
+ {
+ /* access address of op */
+ if (AOP_TYPE(op) != AOP_LIT) { assert (offset < 3); }
+ if (IS_SYMOP(op) && IS_GENPTR(OP_SYM_TYPE(op)) && AOP_SIZE(op) < offset)
+ {
+ if (offset == GPTRSIZE-1)
+ emitpcode (POC_MOVLW, popGetLit (GPTRTAG_DATA));
+ else
+ emitpcode (POC_MOVLW, popGetLit (0));
+ }
+ else
+ emitpcode (POC_MOVLW, popGetAddr(AOP(op), offset, 0));
+ } else {
+ /* access value stored in op */
+ mov2w (AOP(op), offset);
+ }
}
/*-----------------------------------------------------------------*/
void mov2w (asmop *aop, int offset)
{
-
- if(!aop)
- return;
-
- DEBUGpic14_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
-
- if ( aop_isLitLike (aop) )
- emitpcode(POC_MOVLW,popGetAddr(aop,offset,0));
- else
- emitpcode(POC_MOVFW,popGet(aop,offset));
-
+
+ if(!aop)
+ return;
+
+ DEBUGpic14_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
+
+ if ( aop_isLitLike (aop) )
+ emitpcode(POC_MOVLW,popGetAddr(aop,offset,0));
+ else
+ emitpcode(POC_MOVFW,popGet(aop,offset));
+
}
static void movwf (asmop *op, int offset)
{
- emitpcode (POC_MOVWF, popGet(op, offset));
+ emitpcode (POC_MOVWF, popGet(op, offset));
}
static pCodeOp *get_argument_pcop (int idx)
{
- assert (idx > 0 && "the 0th (first) argument is passed via WREG");
- return popRegFromIdx (Gstack_base_addr - (idx - 1));
+ assert (idx > 0 && "the 0th (first) argument is passed via WREG");
+ return popRegFromIdx (Gstack_base_addr - (idx - 1));
}
static pCodeOp *get_return_val_pcop (int offset)
{
- assert (offset > 0 && "the most significant byte is returned via WREG");
- return popRegFromIdx (Gstack_base_addr - (offset - 1));
+ assert (offset > 0 && "the most significant byte is returned via WREG");
+ return popRegFromIdx (Gstack_base_addr - (offset - 1));
}
static void pass_argument (operand *op, int offset, int idx)
{
- if (op)
- mov2w_op (op, offset);
- if (idx != 0)
- emitpcode(POC_MOVWF, get_argument_pcop (idx));
+ if (op)
+ mov2w_op (op, offset);
+ if (idx != 0)
+ emitpcode(POC_MOVWF, get_argument_pcop (idx));
}
static void get_returnvalue (operand *op, int offset, int idx)
{
- if (idx != 0)
- emitpcode(POC_MOVFW, get_return_val_pcop (idx));
- movwf(AOP(op), offset);
+ if (idx != 0)
+ emitpcode(POC_MOVFW, get_return_val_pcop (idx));
+ movwf(AOP(op), offset);
}
static void call_libraryfunc (char *name)
/* create symbol, mark it as `extern' */
sym = findSym(SymbolTab, NULL, name);
if (!sym) {
- sym = newSymbol(name, 0);
- strncpy(sym->rname, name, SDCC_NAME_MAX);
- addSym(SymbolTab, sym, sym->rname, 0, 0, 0);
- addSet(&externs, sym);
+ sym = newSymbol(name, 0);
+ strncpy(sym->rname, name, SDCC_NAME_MAX);
+ addSym(SymbolTab, sym, sym->rname, 0, 0, 0);
+ addSet(&externs, sym);
} // if
sym->used++;
}
/*-----------------------------------------------------------------*/
static void reAdjustPreg (asmop *aop)
{
- int size ;
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- aop->coff = 0;
- if ((size = aop->size) <= 1)
- return ;
- size-- ;
- switch (aop->type) {
- case AOP_R0 :
- case AOP_R1 :
- while (size--)
- pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
- break;
- case AOP_DPTR :
- case AOP_DPTR2:
- if (aop->type == AOP_DPTR2)
- {
- genSetDPTR(1);
- }
- while (size--)
- {
- pic14_emitcode("lcall","__decdptr");
- }
-
- if (aop->type == AOP_DPTR2)
- {
- genSetDPTR(0);
- }
- break;
-
- }
-
+ int size ;
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ aop->coff = 0;
+ if ((size = aop->size) <= 1)
+ return ;
+ size-- ;
+ switch (aop->type) {
+ case AOP_R0 :
+ case AOP_R1 :
+ while (size--)
+ pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
+ break;
+ case AOP_DPTR :
+ case AOP_DPTR2:
+ if (aop->type == AOP_DPTR2)
+ {
+ genSetDPTR(1);
+ }
+ while (size--)
+ {
+ pic14_emitcode("lcall","__decdptr");
+ }
+
+ if (aop->type == AOP_DPTR2)
+ {
+ genSetDPTR(0);
+ }
+ break;
+
+ }
+
}
#endif
/*-----------------------------------------------------------------*/
/* opIsGptr: returns non-zero if the passed operand is */
/* a generic pointer type. */
-/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
static int opIsGptr(operand *op)
{
- sym_link *type = operandType(op);
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
- {
- return 1;
- }
- return 0;
+ sym_link *type = operandType(op);
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
+ {
+ return 1;
+ }
+ return 0;
}
#endif
/*-----------------------------------------------------------------*/
int pic14_getDataSize(operand *op)
{
- int size;
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
+ int size;
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
#if 0
- size = getSize(OP_SYM_ETYPE(op));
- return size;
- //return AOP_SIZE(op);
-
- // tsd- in the pic port, the genptr size is 1, so this code here
- // fails. ( in the 8051 port, the size was 4).
+ size = getSize(OP_SYM_ETYPE(op));
+ return size;
+ //return AOP_SIZE(op);
+
+ // tsd- in the pic port, the genptr size is 1, so this code here
+ // fails. ( in the 8051 port, the size was 4).
#else
- size = AOP_SIZE(op);
- if (IS_GENPTR(OP_SYM_TYPE(op)))
- {
- sym_link *type = operandType(op);
- if (IS_GENPTR(type))
- {
- /* generic pointer; arithmetic operations
- * should ignore the high byte (pointer type).
- */
- size--;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- }
- }
- return size;
+ size = AOP_SIZE(op);
+ if (IS_GENPTR(OP_SYM_TYPE(op)))
+ {
+ sym_link *type = operandType(op);
+ if (IS_GENPTR(type))
+ {
+ /* generic pointer; arithmetic operations
+ * should ignore the high byte (pointer type).
+ */
+ size--;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ }
+ }
+ return size;
#endif
}
/*-----------------------------------------------------------------*/
void pic14_outAcc(operand *result)
{
- int size,offset;
- DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
- DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
-
-
- size = pic14_getDataSize(result);
- if(size){
- emitpcode(POC_MOVWF,popGet(AOP(result),0));
- size--;
- offset = 1;
- /* unsigned or positive */
- while(size--)
- emitpcode(POC_CLRF,popGet(AOP(result),offset++));
- }
-
+ int size,offset;
+ DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
+ DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
+
+
+ size = pic14_getDataSize(result);
+ if(size){
+ emitpcode(POC_MOVWF,popGet(AOP(result),0));
+ size--;
+ offset = 1;
+ /* unsigned or positive */
+ while(size--)
+ emitpcode(POC_CLRF,popGet(AOP(result),offset++));
+ }
+
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
void pic14_outBitC(operand *result)
{
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- /* if the result is bit */
- if (AOP_TYPE(result) == AOP_CRY)
- aopPut(AOP(result),"c",0);
- else {
- pic14_emitcode("clr","a ; %d", __LINE__);
- pic14_emitcode("rlc","a");
- pic14_outAcc(result);
- }
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* if the result is bit */
+ if (AOP_TYPE(result) == AOP_CRY)
+ aopPut(AOP(result),"c",0);
+ else {
+ pic14_emitcode("clr","a ; %d", __LINE__);
+ pic14_emitcode("rlc","a");
+ pic14_outAcc(result);
+ }
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
void pic14_toBoolean(operand *oper)
{
- int size = AOP_SIZE(oper);
- int offset = 0;
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- assert (size > 0);
-
- if (size == 1) {
- /* MOVFW does not load the flags... */
- if (AOP_TYPE(oper) == AOP_ACC) {
- emitpcode(POC_IORLW, popGetLit(0));
- offset = 1;
- } else {
- emitpcode(POC_MOVLW, popGetLit(0));
- offset = 0;
- }
- } else {
- if ( AOP_TYPE(oper) != AOP_ACC) {
- emitpcode(POC_MOVFW,popGet(AOP(oper),0));
- offset = 1;
- }
- }
-
- while (offset < size) {
- emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
- }
- /* Z is set iff (oper == 0) */
+ int size = AOP_SIZE(oper);
+ int offset = 0;
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ assert (size > 0);
+
+ if (size == 1) {
+ /* MOVFW does not load the flags... */
+ if (AOP_TYPE(oper) == AOP_ACC) {
+ emitpcode(POC_IORLW, popGetLit(0));
+ offset = 1;
+ } else {
+ emitpcode(POC_MOVLW, popGetLit(0));
+ offset = 0;
+ }
+ } else {
+ if ( AOP_TYPE(oper) != AOP_ACC) {
+ emitpcode(POC_MOVFW,popGet(AOP(oper),0));
+ offset = 1;
+ }
+ }
+
+ while (offset < size) {
+ emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
+ }
+ /* Z is set iff (oper == 0) */
}
/*-----------------------------------------------------------------*/
static void genNot (iCode *ic)
{
- //symbol *tlbl;
- int size;
-
- FENTRY;
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- /* assign asmOps to operand & result */
- aopOp (IC_LEFT(ic),ic,FALSE);
- aopOp (IC_RESULT(ic),ic,TRUE);
-
- DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
- /* if in bit space then a special case */
- if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
- if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
- emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
- emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
- } else {
- emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
- emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
- emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
- }
- goto release;
- }
-
- size = AOP_SIZE(IC_LEFT(ic));
- mov2w (AOP(IC_LEFT(ic)),0);
- while (--size > 0)
- {
- if (op_isLitLike (IC_LEFT(ic)))
- emitpcode (POC_IORLW, popGetAddr (AOP(IC_LEFT(ic)), size, 0));
- else
- emitpcode (POC_IORFW, popGet (AOP(IC_LEFT(ic)), size));
- }
- emitpcode(POC_MOVLW, popGetLit (0));
- emitSKPNZ;
- emitpcode(POC_MOVLW, popGetLit (1));
- movwf(AOP(IC_RESULT(ic)), 0);
-
- for (size = 1; size < AOP_SIZE(IC_RESULT(ic)); size++)
- {
- emitpcode(POC_CLRF, popGet (AOP(IC_RESULT(ic)), size));
- }
- goto release;
-
-release:
- /* release the aops */
- freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
- freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
-}
-
-
-/*-----------------------------------------------------------------*/
-/* genCpl - generate code for complement */
+ //symbol *tlbl;
+ int size;
+
+ FENTRY;
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* assign asmOps to operand & result */
+ aopOp (IC_LEFT(ic),ic,FALSE);
+ aopOp (IC_RESULT(ic),ic,TRUE);
+
+ DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
+ /* if in bit space then a special case */
+ if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
+ if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
+ emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
+ emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
+ } else {
+ emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
+ emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
+ emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
+ }
+ goto release;
+ }
+
+ size = AOP_SIZE(IC_LEFT(ic));
+ mov2w (AOP(IC_LEFT(ic)),0);
+ while (--size > 0)
+ {
+ if (op_isLitLike (IC_LEFT(ic)))
+ emitpcode (POC_IORLW, popGetAddr (AOP(IC_LEFT(ic)), size, 0));
+ else
+ emitpcode (POC_IORFW, popGet (AOP(IC_LEFT(ic)), size));
+ }
+ emitpcode(POC_MOVLW, popGetLit (0));
+ emitSKPNZ;
+ emitpcode(POC_MOVLW, popGetLit (1));
+ movwf(AOP(IC_RESULT(ic)), 0);
+
+ for (size = 1; size < AOP_SIZE(IC_RESULT(ic)); size++)
+ {
+ emitpcode(POC_CLRF, popGet (AOP(IC_RESULT(ic)), size));
+ }
+ goto release;
+
+release:
+ /* release the aops */
+ freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
+ freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
+}
+
+
+/*-----------------------------------------------------------------*/
+/* genCpl - generate code for complement */
/*-----------------------------------------------------------------*/
static void genCpl (iCode *ic)
{
- operand *left, *result;
- int size, offset=0;
-
- FENTRY;
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- aopOp((left = IC_LEFT(ic)),ic,FALSE);
- aopOp((result=IC_RESULT(ic)),ic,TRUE);
-
- /* if both are in bit space then
- a special case */
- if (AOP_TYPE(result) == AOP_CRY &&
- AOP_TYPE(left) == AOP_CRY ) {
-
- pic14_emitcode("mov","c,%s",left->aop->aopu.aop_dir);
- pic14_emitcode("cpl","c");
- pic14_emitcode("mov","%s,c",result->aop->aopu.aop_dir);
- goto release;
- }
-
- size = AOP_SIZE(result);
- if (AOP_SIZE(left) < size) size = AOP_SIZE(left);
- while (size--) {
-
- if(AOP_TYPE(left) == AOP_ACC)
- emitpcode(POC_XORLW, popGetLit(0xff));
- else
- emitpcode(POC_COMFW,popGet(AOP(left),offset));
-
- emitpcode(POC_MOVWF,popGet(AOP(result),offset));
- offset++;
- }
- addSign (result, AOP_SIZE(left), !SPEC_USIGN(operandType(result)));
-
-
+ operand *left, *result;
+ int size, offset=0;
+
+ FENTRY;
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ aopOp((left = IC_LEFT(ic)),ic,FALSE);
+ aopOp((result=IC_RESULT(ic)),ic,TRUE);
+
+ /* if both are in bit space then
+ a special case */
+ if (AOP_TYPE(result) == AOP_CRY &&
+ AOP_TYPE(left) == AOP_CRY ) {
+
+ pic14_emitcode("mov","c,%s",left->aop->aopu.aop_dir);
+ pic14_emitcode("cpl","c");
+ pic14_emitcode("mov","%s,c",result->aop->aopu.aop_dir);
+ goto release;
+ }
+
+ size = AOP_SIZE(result);
+ if (AOP_SIZE(left) < size) size = AOP_SIZE(left);
+ while (size--) {
+
+ if(AOP_TYPE(left) == AOP_ACC)
+ emitpcode(POC_XORLW, popGetLit(0xff));
+ else
+ emitpcode(POC_COMFW,popGet(AOP(left),offset));
+
+ emitpcode(POC_MOVWF,popGet(AOP(result),offset));
+ offset++;
+ }
+ addSign (result, AOP_SIZE(left), !SPEC_USIGN(operandType(result)));
+
+
release:
- /* release the aops */
- freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
- freeAsmop(result,NULL,ic,TRUE);
+ /* release the aops */
+ freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
+ freeAsmop(result,NULL,ic,TRUE);
}
/*-----------------------------------------------------------------*/
-/* genUminusFloat - unary minus for floating points */
+/* genUminusFloat - unary minus for floating points */
/*-----------------------------------------------------------------*/
static void genUminusFloat(operand *op,operand *result)
{
- int size ,offset =0 ;
- char *l;
-
- FENTRY;
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- /* for this we just need to flip the
- first it then copy the rest in place */
- size = AOP_SIZE(op) - 1;
- l = aopGet(AOP(op),3,FALSE,FALSE);
-
- MOVA(l);
-
- pic14_emitcode("cpl","acc.7");
- aopPut(AOP(result),"a",3);
-
- while(size--) {
- aopPut(AOP(result),
- aopGet(AOP(op),offset,FALSE,FALSE),
- offset);
- offset++;
- }
-}
-
-/*-----------------------------------------------------------------*/
-/* genUminus - unary minus code generation */
+ int size ,offset =0 ;
+ char *l;
+
+ FENTRY;
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* for this we just need to flip the
+ first it then copy the rest in place */
+ size = AOP_SIZE(op) - 1;
+ l = aopGet(AOP(op),3,FALSE,FALSE);
+
+ MOVA(l);
+
+ pic14_emitcode("cpl","acc.7");
+ aopPut(AOP(result),"a",3);
+
+ while(size--) {
+ aopPut(AOP(result),
+ aopGet(AOP(op),offset,FALSE,FALSE),
+ offset);
+ offset++;
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* genUminus - unary minus code generation */
/*-----------------------------------------------------------------*/
static void genUminus (iCode *ic)
{
- int size, i;
- sym_link *optype, *rtype;
-
- FENTRY;
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- /* assign asmops */
- aopOp(IC_LEFT(ic),ic,FALSE);
- aopOp(IC_RESULT(ic),ic,TRUE);
-
- /* if both in bit space then special
- case */
- if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
- AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
-
- emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
- emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
- emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
-
- goto release;
- }
-
- optype = operandType(IC_LEFT(ic));
- rtype = operandType(IC_RESULT(ic));
-
- /* if float then do float stuff */
- if (IS_FLOAT(optype)) {
- genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
- goto release;
- }
-
- /* otherwise subtract from zero by taking the 2's complement */
- size = AOP_SIZE(IC_LEFT(ic));
-
- for(i=0; i<size; i++) {
- if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
- emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
- else {
- emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
- emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
- }
- }
-
- emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
- for(i=1; i<size; i++) {
- emitSKPNZ;
- emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
- }
-
+ int size, i;
+ sym_link *optype, *rtype;
+
+ FENTRY;
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* assign asmops */
+ aopOp(IC_LEFT(ic),ic,FALSE);
+ aopOp(IC_RESULT(ic),ic,TRUE);
+
+ /* if both in bit space then special
+ case */
+ if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
+ AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
+
+ emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
+ emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
+ emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
+
+ goto release;
+ }
+
+ optype = operandType(IC_LEFT(ic));
+ rtype = operandType(IC_RESULT(ic));
+
+ /* if float then do float stuff */
+ if (IS_FLOAT(optype)) {
+ genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
+ goto release;
+ }
+
+ /* otherwise subtract from zero by taking the 2's complement */
+ size = AOP_SIZE(IC_LEFT(ic));
+
+ for(i=0; i<size; i++) {
+ if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
+ emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
+ else {
+ emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
+ emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
+ }
+ }
+
+ emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
+ for(i=1; i<size; i++) {
+ emitSKPNZ;
+ emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
+ }
+
release:
- /* release the aops */
- freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
- freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
-}
-
-/*-----------------------------------------------------------------*/
-/* saveRegisters - will look for a call and save the registers */
-/*-----------------------------------------------------------------*/
-static void saveRegisters(iCode *lic)
-{
- int i;
- iCode *ic;
- bitVect *rsave;
- sym_link *dtype;
-
- FENTRY;
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- /* look for call */
- for (ic = lic ; ic ; ic = ic->next)
- if (ic->op == CALL || ic->op == PCALL)
- break;
-
- if (!ic) {
- fprintf(stderr,"found parameter push with no function call\n");
- return ;
- }
-
- /* if the registers have been saved already then
- do nothing */
- if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
- return ;
-
- /* find the registers in use at this time
- and push them away to safety */
- rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
- ic->rUsed);
-
- ic->regsSaved = 1;
- if (options.useXstack) {
- if (bitVectBitValue(rsave,R0_IDX))
- pic14_emitcode("mov","b,r0");
- pic14_emitcode("mov","r0,%s",spname);
- for (i = 0 ; i < pic14_nRegs ; i++) {
- if (bitVectBitValue(rsave,i)) {
- if (i == R0_IDX)
- pic14_emitcode("mov","a,b");
- else
- pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
- pic14_emitcode("movx","@r0,a");
- pic14_emitcode("inc","r0");
- }
- }
- pic14_emitcode("mov","%s,r0",spname);
- if (bitVectBitValue(rsave,R0_IDX))
- pic14_emitcode("mov","r0,b");
- }// else
- //for (i = 0 ; i < pic14_nRegs ; i++) {
- // if (bitVectBitValue(rsave,i))
- // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
- //}
-
- dtype = operandType(IC_LEFT(ic));
- if (currFunc && dtype &&
- (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
- IFFUNC_ISISR(currFunc->type) &&
- !ic->bankSaved)
-
- saverbank(FUNC_REGBANK(dtype),ic,TRUE);
-
-}
-/*-----------------------------------------------------------------*/
-/* unsaveRegisters - pop the pushed registers */
+ /* release the aops */
+ freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
+ freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
+}
+
/*-----------------------------------------------------------------*/
-static void unsaveRegisters (iCode *ic)
-{
- int i;
- bitVect *rsave;
-
- FENTRY;
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- /* find the registers in use at this time
- and push them away to safety */
- rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
- ic->rUsed);
-
- if (options.useXstack) {
- pic14_emitcode("mov","r0,%s",spname);
- for (i = pic14_nRegs ; i >= 0 ; i--) {
- if (bitVectBitValue(rsave,i)) {
- pic14_emitcode("dec","r0");
- pic14_emitcode("movx","a,@r0");
- if (i == R0_IDX)
- pic14_emitcode("mov","b,a");
- else
- pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
- }
-
- }
- pic14_emitcode("mov","%s,r0",spname);
- if (bitVectBitValue(rsave,R0_IDX))
- pic14_emitcode("mov","r0,b");
- } //else
- //for (i = pic14_nRegs ; i >= 0 ; i--) {
- // if (bitVectBitValue(rsave,i))
- // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
- //}
-
-}
-
-
-/*-----------------------------------------------------------------*/
-/* pushSide - */
+/* saveRegisters - will look for a call and save the registers */
/*-----------------------------------------------------------------*/
-static void pushSide(operand * oper, int size)
+static void saveRegisters(iCode *lic)
{
-#if 0
- int offset = 0;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- while (size--) {
- char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
- if (AOP_TYPE(oper) != AOP_REG &&
- AOP_TYPE(oper) != AOP_DIR &&
- strcmp(l,"a") ) {
- pic14_emitcode("mov","a,%s",l);
- pic14_emitcode("push","acc");
- } else
- pic14_emitcode("push","%s",l);
- }
-#endif
-}
+ int i;
+ iCode *ic;
+ bitVect *rsave;
+ sym_link *dtype;
+
+ FENTRY;
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* look for call */
+ for (ic = lic ; ic ; ic = ic->next)
+ if (ic->op == CALL || ic->op == PCALL)
+ break;
+
+ if (!ic) {
+ fprintf(stderr,"found parameter push with no function call\n");
+ return ;
+ }
+ /* if the registers have been saved already then
+ do nothing */
+ if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
+ return ;
+
+ /* find the registers in use at this time
+ and push them away to safety */
+ rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
+ ic->rUsed);
+
+ ic->regsSaved = 1;
+ if (options.useXstack) {
+ if (bitVectBitValue(rsave,R0_IDX))
+ pic14_emitcode("mov","b,r0");
+ pic14_emitcode("mov","r0,%s",spname);
+ for (i = 0 ; i < pic14_nRegs ; i++) {
+ if (bitVectBitValue(rsave,i)) {
+ if (i == R0_IDX)
+ pic14_emitcode("mov","a,b");
+ else
+ pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
+ pic14_emitcode("movx","@r0,a");
+ pic14_emitcode("inc","r0");
+ }
+ }
+ pic14_emitcode("mov","%s,r0",spname);
+ if (bitVectBitValue(rsave,R0_IDX))
+ pic14_emitcode("mov","r0,b");
+ }// else
+ //for (i = 0 ; i < pic14_nRegs ; i++) {
+ // if (bitVectBitValue(rsave,i))
+ // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
+ //}
+
+ dtype = operandType(IC_LEFT(ic));
+ if (currFunc && dtype &&
+ (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
+ IFFUNC_ISISR(currFunc->type) &&
+ !ic->bankSaved)
+
+ saverbank(FUNC_REGBANK(dtype),ic,TRUE);
+
+}
/*-----------------------------------------------------------------*/
-/* assignResultValue - */
+/* unsaveRegisters - pop the pushed registers */
/*-----------------------------------------------------------------*/
-static void assignResultValue(operand * oper)
+static void unsaveRegisters (iCode *ic)
{
- int size = AOP_SIZE(oper);
- int offset = 0;
-
- FENTRY;
+ int i;
+ bitVect *rsave;
+
+ FENTRY;
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* find the registers in use at this time
+ and push them away to safety */
+ rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
+ ic->rUsed);
+
+ if (options.useXstack) {
+ pic14_emitcode("mov","r0,%s",spname);
+ for (i = pic14_nRegs ; i >= 0 ; i--) {
+ if (bitVectBitValue(rsave,i)) {
+ pic14_emitcode("dec","r0");
+ pic14_emitcode("movx","a,@r0");
+ if (i == R0_IDX)
+ pic14_emitcode("mov","b,a");
+ else
+ pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
+ }
+
+ }
+ pic14_emitcode("mov","%s,r0",spname);
+ if (bitVectBitValue(rsave,R0_IDX))
+ pic14_emitcode("mov","r0,b");
+ } //else
+ //for (i = pic14_nRegs ; i >= 0 ; i--) {
+ // if (bitVectBitValue(rsave,i))
+ // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
+ //}
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
-
- /* assign MSB first (passed via WREG) */
- while (size--) {
- get_returnvalue (oper, size, offset + GpsuedoStkPtr);
- GpsuedoStkPtr++;
- }
}
/*-----------------------------------------------------------------*/
-/* genIpush - genrate code for pushing this gets a little complex */
+/* pushSide - */
/*-----------------------------------------------------------------*/
-static void genIpush (iCode *ic)
+static void pushSide(operand * oper, int size)
{
- FENTRY;
-
- DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
#if 0
- int size, offset = 0 ;
- char *l;
-
-
- /* if this is not a parm push : ie. it is spill push
- and spill push is always done on the local stack */
- if (!ic->parmPush) {
-
- /* and the item is spilt then do nothing */
- if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
- return ;
-
- aopOp(IC_LEFT(ic),ic,FALSE);
- size = AOP_SIZE(IC_LEFT(ic));
- /* push it on the stack */
- while(size--) {
- l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
- if (*l == '#') {
- MOVA(l);
- l = "acc";
- }
- pic14_emitcode("push","%s",l);
- }
- return ;
- }
-
- /* this is a paramter push: in this case we call
- the routine to find the call and save those
- registers that need to be saved */
- saveRegisters(ic);
-
- /* then do the push */
- aopOp(IC_LEFT(ic),ic,FALSE);
-
-
- // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
- size = AOP_SIZE(IC_LEFT(ic));
-
- while (size--) {
- l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
- if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
- AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
- strcmp(l,"a") ) {
- pic14_emitcode("mov","a,%s",l);
- pic14_emitcode("push","acc");
- } else
- pic14_emitcode("push","%s",l);
- }
-
- freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
+ int offset = 0;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ while (size--) {
+ char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
+ if (AOP_TYPE(oper) != AOP_REG &&
+ AOP_TYPE(oper) != AOP_DIR &&
+ strcmp(l,"a") ) {
+ pic14_emitcode("mov","a,%s",l);
+ pic14_emitcode("push","acc");
+ } else
+ pic14_emitcode("push","%s",l);
+ }
#endif
}
/*-----------------------------------------------------------------*/
-/* genIpop - recover the registers: can happen only for spilling */
+/* assignResultValue - */
/*-----------------------------------------------------------------*/
-static void genIpop (iCode *ic)
+static void assignResultValue(operand * oper)
{
- FENTRY;
+ int size = AOP_SIZE(oper);
+ int offset = 0;
- DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
- assert (!"genIpop -- unimplemented");
-#if 0
- int size,offset ;
-
-
- /* if the temp was not pushed then */
- if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
- return ;
-
- aopOp(IC_LEFT(ic),ic,FALSE);
- size = AOP_SIZE(IC_LEFT(ic));
- offset = (size-1);
- while (size--)
- pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
- FALSE,TRUE));
-
- freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
-#endif
+ FENTRY;
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
+
+ /* assign MSB first (passed via WREG) */
+ while (size--) {
+ get_returnvalue (oper, size, offset + GpsuedoStkPtr);
+ GpsuedoStkPtr++;
+ }
}
+
/*-----------------------------------------------------------------*/
-/* unsaverbank - restores the resgister bank from stack */
+/* genIpush - genrate code for pushing this gets a little complex */
+/*-----------------------------------------------------------------*/
+static void genIpush (iCode *ic)
+{
+ FENTRY;
+
+ DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
+#if 0
+ int size, offset = 0 ;
+ char *l;
+
+
+ /* if this is not a parm push : ie. it is spill push
+ and spill push is always done on the local stack */
+ if (!ic->parmPush) {
+
+ /* and the item is spilt then do nothing */
+ if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
+ return ;
+
+ aopOp(IC_LEFT(ic),ic,FALSE);
+ size = AOP_SIZE(IC_LEFT(ic));
+ /* push it on the stack */
+ while(size--) {
+ l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
+ if (*l == '#') {
+ MOVA(l);
+ l = "acc";
+ }
+ pic14_emitcode("push","%s",l);
+ }
+ return ;
+ }
+
+ /* this is a paramter push: in this case we call
+ the routine to find the call and save those
+ registers that need to be saved */
+ saveRegisters(ic);
+
+ /* then do the push */
+ aopOp(IC_LEFT(ic),ic,FALSE);
+
+
+ // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
+ size = AOP_SIZE(IC_LEFT(ic));
+
+ while (size--) {
+ l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
+ if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
+ AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
+ strcmp(l,"a") ) {
+ pic14_emitcode("mov","a,%s",l);
+ pic14_emitcode("push","acc");
+ } else
+ pic14_emitcode("push","%s",l);
+ }
+
+ freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
+#endif
+}
+
+/*-----------------------------------------------------------------*/
+/* genIpop - recover the registers: can happen only for spilling */
+/*-----------------------------------------------------------------*/
+static void genIpop (iCode *ic)
+{
+ FENTRY;
+
+ DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
+ assert (!"genIpop -- unimplemented");
+#if 0
+ int size,offset ;
+
+
+ /* if the temp was not pushed then */
+ if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
+ return ;
+
+ aopOp(IC_LEFT(ic),ic,FALSE);
+ size = AOP_SIZE(IC_LEFT(ic));
+ offset = (size-1);
+ while (size--)
+ pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
+ FALSE,TRUE));
+
+ freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
+#endif
+}
+
+/*-----------------------------------------------------------------*/
+/* unsaverbank - restores the resgister bank from stack */
/*-----------------------------------------------------------------*/
static void unsaverbank (int bank,iCode *ic,bool popPsw)
{
- FENTRY;
+ FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
+ DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
#if 0
- int i;
- asmop *aop ;
- regs *r = NULL;
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if (popPsw) {
- if (options.useXstack) {
- aop = newAsmop(0);
- r = getFreePtr(ic,&aop,FALSE);
-
-
- pic14_emitcode("mov","%s,_spx",r->name);
- pic14_emitcode("movx","a,@%s",r->name);
- pic14_emitcode("mov","psw,a");
- pic14_emitcode("dec","%s",r->name);
-
- }else
- pic14_emitcode ("pop","psw");
- }
-
- for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
- if (options.useXstack) {
- pic14_emitcode("movx","a,@%s",r->name);
- //pic14_emitcode("mov","(%s+%d),a",
- // regspic14[i].base,8*bank+regspic14[i].offset);
- pic14_emitcode("dec","%s",r->name);
-
- } else
- pic14_emitcode("pop",""); //"(%s+%d)",
- //regspic14[i].base,8*bank); //+regspic14[i].offset);
- }
-
- if (options.useXstack) {
-
- pic14_emitcode("mov","_spx,%s",r->name);
- freeAsmop(NULL,aop,ic,TRUE);
-
- }
-#endif
-}
-
-/*-----------------------------------------------------------------*/
-/* saverbank - saves an entire register bank on the stack */
+ int i;
+ asmop *aop ;
+ regs *r = NULL;
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ if (popPsw) {
+ if (options.useXstack) {
+ aop = newAsmop(0);
+ r = getFreePtr(ic,&aop,FALSE);
+
+
+ pic14_emitcode("mov","%s,_spx",r->name);
+ pic14_emitcode("movx","a,@%s",r->name);
+ pic14_emitcode("mov","psw,a");
+ pic14_emitcode("dec","%s",r->name);
+
+ }else
+ pic14_emitcode ("pop","psw");
+ }
+
+ for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
+ if (options.useXstack) {
+ pic14_emitcode("movx","a,@%s",r->name);
+ //pic14_emitcode("mov","(%s+%d),a",
+ // regspic14[i].base,8*bank+regspic14[i].offset);
+ pic14_emitcode("dec","%s",r->name);
+
+ } else
+ pic14_emitcode("pop",""); //"(%s+%d)",
+ //regspic14[i].base,8*bank); //+regspic14[i].offset);
+ }
+
+ if (options.useXstack) {
+
+ pic14_emitcode("mov","_spx,%s",r->name);
+ freeAsmop(NULL,aop,ic,TRUE);
+
+ }
+#endif
+}
+
+/*-----------------------------------------------------------------*/
+/* saverbank - saves an entire register bank on the stack */
/*-----------------------------------------------------------------*/
static void saverbank (int bank, iCode *ic, bool pushPsw)
{
- FENTRY;
+ FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
+ DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
#if 0
- int i;
- asmop *aop ;
- regs *r = NULL;
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if (options.useXstack) {
-
- aop = newAsmop(0);
- r = getFreePtr(ic,&aop,FALSE);
- pic14_emitcode("mov","%s,_spx",r->name);
-
- }
-
- for (i = 0 ; i < pic14_nRegs ;i++) {
- if (options.useXstack) {
- pic14_emitcode("inc","%s",r->name);
- //pic14_emitcode("mov","a,(%s+%d)",
- // regspic14[i].base,8*bank+regspic14[i].offset);
- pic14_emitcode("movx","@%s,a",r->name);
- } else
- pic14_emitcode("push","");// "(%s+%d)",
- //regspic14[i].base,8*bank+regspic14[i].offset);
- }
-
- if (pushPsw) {
- if (options.useXstack) {
- pic14_emitcode("mov","a,psw");
- pic14_emitcode("movx","@%s,a",r->name);
- pic14_emitcode("inc","%s",r->name);
- pic14_emitcode("mov","_spx,%s",r->name);
- freeAsmop (NULL,aop,ic,TRUE);
-
- } else
- pic14_emitcode("push","psw");
-
- pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
- }
- ic->bankSaved = 1;
+ int i;
+ asmop *aop ;
+ regs *r = NULL;
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ if (options.useXstack) {
+
+ aop = newAsmop(0);
+ r = getFreePtr(ic,&aop,FALSE);
+ pic14_emitcode("mov","%s,_spx",r->name);
+
+ }
+
+ for (i = 0 ; i < pic14_nRegs ;i++) {
+ if (options.useXstack) {
+ pic14_emitcode("inc","%s",r->name);
+ //pic14_emitcode("mov","a,(%s+%d)",
+ // regspic14[i].base,8*bank+regspic14[i].offset);
+ pic14_emitcode("movx","@%s,a",r->name);
+ } else
+ pic14_emitcode("push","");// "(%s+%d)",
+ //regspic14[i].base,8*bank+regspic14[i].offset);
+ }
+
+ if (pushPsw) {
+ if (options.useXstack) {
+ pic14_emitcode("mov","a,psw");
+ pic14_emitcode("movx","@%s,a",r->name);
+ pic14_emitcode("inc","%s",r->name);
+ pic14_emitcode("mov","_spx,%s",r->name);
+ freeAsmop (NULL,aop,ic,TRUE);
+
+ } else
+ pic14_emitcode("push","psw");
+
+ pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
+ }
+ ic->bankSaved = 1;
#endif
}
/*-----------------------------------------------------------------*/
-/* genCall - generates a call statement */
+/* genCall - generates a call statement */
/*-----------------------------------------------------------------*/
static void genCall (iCode *ic)
{
- sym_link *dtype;
- symbol *sym;
- char *name;
- int isExtern;
-
- FENTRY;
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- /* if caller saves & we have not saved then */
- if (!ic->regsSaved)
- saveRegisters(ic);
-
- /* if we are calling a function that is not using
- the same register bank then we need to save the
- destination registers on the stack */
- dtype = operandType(IC_LEFT(ic));
- if (currFunc && dtype &&
- (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
- IFFUNC_ISISR(currFunc->type) &&
- !ic->bankSaved)
-
- saverbank(FUNC_REGBANK(dtype),ic,TRUE);
-
- /* if send set is not empty the assign */
- if (_G.sendSet) {
- iCode *sic;
- /* For the Pic port, there is no data stack.
- * So parameters passed to functions are stored
- * in registers. (The pCode optimizer will get
- * rid of most of these :).
- */
- int psuedoStkPtr=-1;
- int firstTimeThruLoop = 1;
-
- _G.sendSet = reverseSet(_G.sendSet);
-
- /* First figure how many parameters are getting passed */
- for (sic = setFirstItem(_G.sendSet) ; sic ;
- sic = setNextItem(_G.sendSet)) {
-
- aopOp(IC_LEFT(sic),sic,FALSE);
- psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
- freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
- }
-
- for (sic = setFirstItem(_G.sendSet) ; sic ;
- sic = setNextItem(_G.sendSet)) {
- int size, offset = 0;
-
- aopOp(IC_LEFT(sic),sic,FALSE);
- size = AOP_SIZE(IC_LEFT(sic));
-
- while (size--) {
- DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
- AopType(AOP_TYPE(IC_LEFT(sic))));
-
- if(!firstTimeThruLoop) {
- /* If this is not the first time we've been through the loop
- * then we need to save the parameter in a temporary
- * register. The last byte of the last parameter is
- * passed in W. */
- emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr - --psuedoStkPtr));
-
- }
- firstTimeThruLoop=0;
-
- mov2w_op (IC_LEFT(sic), offset);
- offset++;
- }
- freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
- }
- _G.sendSet = NULL;
- }
- /* make the call */
- sym = OP_SYMBOL(IC_LEFT(ic));
- name = sym->rname[0] ? sym->rname : sym->name;
- /*
- * As SDCC emits code as soon as it reaches the end of each
- * function's definition, prototyped functions that are implemented
- * after the current one are always considered EXTERN, which
- * introduces many unneccessary PAGESEL instructions.
- * XXX: Use a post pass to iterate over all `CALL _name' statements
- * and insert `PAGESEL _name' and `PAGESEL $' around the CALL
- * only iff there is no definition of the function in the whole
- * file (might include this in the PAGESEL pass).
- */
- isExtern = IS_EXTERN(sym->etype) || pic14_inISR;
- if (isExtern) {
- /* Extern functions and ISRs maybe on a different page;
- * must call pagesel */
- emitpcode(POC_PAGESEL,popGetWithString(name,1));
- }
- emitpcode(POC_CALL,popGetWithString(name,isExtern));
- if (isExtern) {
- /* May have returned from a different page;
- * must use pagesel to restore PCLATH before next
- * goto or call instruction */
- emitpcode(POC_PAGESEL,popGetWithString("$",0));
- }
- GpsuedoStkPtr=0;
- /* if we need assign a result value */
- if ((IS_ITEMP(IC_RESULT(ic)) &&
- (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
- OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
- IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
-
- _G.accInUse++;
- aopOp(IC_RESULT(ic),ic,FALSE);
- _G.accInUse--;
-
- assignResultValue(IC_RESULT(ic));
-
- DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
- AopType(AOP_TYPE(IC_RESULT(ic))));
-
- freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
- }
-
- /* if register bank was saved then pop them */
- if (ic->bankSaved)
- unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
-
- /* if we hade saved some registers then unsave them */
- if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
- unsaveRegisters (ic);
-
-
-}
-
-/*-----------------------------------------------------------------*/
-/* genPcall - generates a call by pointer statement */
+ sym_link *dtype;
+ symbol *sym;
+ char *name;
+ int isExtern;
+
+ FENTRY;
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ /* if caller saves & we have not saved then */
+ if (!ic->regsSaved)
+ saveRegisters(ic);
+
+ /* if we are calling a function that is not using
+ the same register bank then we need to save the
+ destination registers on the stack */
+ dtype = operandType(IC_LEFT(ic));
+ if (currFunc && dtype &&
+ (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
+ IFFUNC_ISISR(currFunc->type) &&
+ !ic->bankSaved)
+
+ saverbank(FUNC_REGBANK(dtype),ic,TRUE);
+
+ /* if send set is not empty the assign */
+ if (_G.sendSet) {
+ iCode *sic;
+ /* For the Pic port, there is no data stack.
+ * So parameters passed to functions are stored
+ * in registers. (The pCode optimizer will get
+ * rid of most of these :).
+ */
+ int psuedoStkPtr=-1;
+ int firstTimeThruLoop = 1;
+
+ _G.sendSet = reverseSet(_G.sendSet);
+
+ /* First figure how many parameters are getting passed */
+ for (sic = setFirstItem(_G.sendSet) ; sic ;
+ sic = setNextItem(_G.sendSet)) {
+
+ aopOp(IC_LEFT(sic),sic,FALSE);
+ psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
+ freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
+ }
+
+ for (sic = setFirstItem(_G.sendSet) ; sic ;
+ sic = setNextItem(_G.sendSet)) {
+ int size, offset = 0;
+
+ aopOp(IC_LEFT(sic),sic,FALSE);
+ size = AOP_SIZE(IC_LEFT(sic));
+
+ while (size--) {
+ DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
+ AopType(AOP_TYPE(IC_LEFT(sic))));
+
+ if(!firstTimeThruLoop) {
+ /* If this is not the first time we've been through the loop
+ * then we need to save the parameter in a temporary
+ * register. The last byte of the last parameter is
+ * passed in W. */
+ emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr - --psuedoStkPtr));
+
+ }
+ firstTimeThruLoop=0;
+
+ mov2w_op (IC_LEFT(sic), offset);
+ offset++;
+ }
+ freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
+ }
+ _G.sendSet = NULL;
+ }
+ /* make the call */
+ sym = OP_SYMBOL(IC_LEFT(ic));
+ name = sym->rname[0] ? sym->rname : sym->name;
+ /*
+ * As SDCC emits code as soon as it reaches the end of each
+ * function's definition, prototyped functions that are implemented
+ * after the current one are always considered EXTERN, which
+ * introduces many unneccessary PAGESEL instructions.
+ * XXX: Use a post pass to iterate over all `CALL _name' statements
+ * and insert `PAGESEL _name' and `PAGESEL $' around the CALL
+ * only iff there is no definition of the function in the whole
+ * file (might include this in the PAGESEL pass).
+ */
+ isExtern = IS_EXTERN(sym->etype) || pic14_inISR;
+ if (isExtern) {
+ /* Extern functions and ISRs maybe on a different page;
+ * must call pagesel */
+ emitpcode(POC_PAGESEL,popGetWithString(name,1));
+ }
+ emitpcode(POC_CALL,popGetWithString(name,isExtern));
+ if (isExtern) {
+ /* May have returned from a different page;
+ * must use pagesel to restore PCLATH before next
+ * goto or call instruction */
+ emitpcode(POC_PAGESEL,popGetWithString("$",0));
+ }
+ GpsuedoStkPtr=0;
+ /* if we need assign a result value */
+ if ((IS_ITEMP(IC_RESULT(ic)) &&
+ (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
+ OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
+ IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
+
+ _G.accInUse++;
+ aopOp(IC_RESULT(ic),ic,FALSE);
+ _G.accInUse--;
+
+ assignResultValue(IC_RESULT(ic));
+
+ DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
+ AopType(AOP_TYPE(IC_RESULT(ic))));
+
+ freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
+ }
+
+ /* if register bank was saved then pop them */
+ if (ic->bankSaved)
+ unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
+
+ /* if we hade saved some registers then unsave them */
+ if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
+ unsaveRegisters (ic);
+
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genPcall - generates a call by pointer statement */
/*-----------------------------------------------------------------*/
static void genPcall (iCode *ic)
{
- sym_link *dtype;
- symbol *albl = newiTempLabel(NULL);
- symbol *blbl = newiTempLabel(NULL);
- PIC_OPCODE poc;
- pCodeOp *pcop;
- operand *left;
-
- FENTRY;
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- /* if caller saves & we have not saved then */
- if (!ic->regsSaved)
- saveRegisters(ic);
-
- /* if we are calling a function that is not using
- the same register bank then we need to save the
- destination registers on the stack */
- dtype = operandType(IC_LEFT(ic));
- if (currFunc && dtype &&
- IFFUNC_ISISR(currFunc->type) &&
- (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
- saverbank(FUNC_REGBANK(dtype),ic,TRUE);
-
- left = IC_LEFT(ic);
- aopOp(left,ic,FALSE);
- DEBUGpic14_AopType(__LINE__,left,NULL,NULL);
-
- poc = ( op_isLitLike (IC_LEFT(ic)) ? POC_MOVLW : POC_MOVFW );
-
- pushSide(IC_LEFT(ic), FPTRSIZE);
-
- /* if send set is not empty, assign parameters */
- if (_G.sendSet) {
-
- DEBUGpic14_emitcode ("; ***","%s %d - WARNING arg-passing to indirect call not supported",__FUNCTION__,__LINE__);
- /* no way to pass args - W always gets used to make the call */
- }
- /* first idea - factor out a common helper function and call it.
- But don't know how to get it generated only once in its own block
-
- if(AOP_TYPE(IC_LEFT(ic)) == AOP_DIR) {
- char *rname;
- char *buffer;
- rname = IC_LEFT(ic)->aop->aopu.aop_dir;
- DEBUGpic14_emitcode ("; ***","%s %d AOP_DIR %s",__FUNCTION__,__LINE__,rname);
- buffer = Safe_calloc(1,strlen(rname)+16);
- sprintf(buffer, "%s_goto_helper", rname);
- addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp(buffer,PO_STR)));
- free(buffer);
- }
- */
- emitpcode(POC_CALL,popGetLabel(albl->key));
- pcop = popGetLabel(blbl->key);
- emitpcode(POC_PAGESEL,pcop); /* Must restore PCLATH before goto, without destroying W */
- emitpcode(POC_GOTO,pcop);
- emitpLabel(albl->key);
-
- emitpcode(poc,popGetAddr(AOP(left),1,0));
- emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
- emitpcode(poc,popGetAddr(AOP(left),0,0));
- emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
-
- emitpLabel(blbl->key);
-
- freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
-
- /* if we need to assign a result value */
- if ((IS_ITEMP(IC_RESULT(ic)) &&
- (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
- OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
- IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
-
- _G.accInUse++;
- aopOp(IC_RESULT(ic),ic,FALSE);
- _G.accInUse--;
-
- GpsuedoStkPtr = 0;
-
- assignResultValue(IC_RESULT(ic));
-
- freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
- }
-
- /* if register bank was saved then unsave them */
- if (currFunc && dtype &&
- (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
- unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
-
- /* if we hade saved some registers then
- unsave them */
- if (ic->regsSaved)
- unsaveRegisters (ic);
-
-}
-
-/*-----------------------------------------------------------------*/
-/* resultRemat - result is rematerializable */
+ sym_link *dtype;
+ symbol *albl = newiTempLabel(NULL);
+ symbol *blbl = newiTempLabel(NULL);
+ PIC_OPCODE poc;
+ pCodeOp *pcop;
+ operand *left;
+
+ FENTRY;
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* if caller saves & we have not saved then */
+ if (!ic->regsSaved)
+ saveRegisters(ic);
+
+ /* if we are calling a function that is not using
+ the same register bank then we need to save the
+ destination registers on the stack */
+ dtype = operandType(IC_LEFT(ic));
+ if (currFunc && dtype &&
+ IFFUNC_ISISR(currFunc->type) &&
+ (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
+ saverbank(FUNC_REGBANK(dtype),ic,TRUE);
+
+ left = IC_LEFT(ic);
+ aopOp(left,ic,FALSE);
+ DEBUGpic14_AopType(__LINE__,left,NULL,NULL);
+
+ poc = ( op_isLitLike (IC_LEFT(ic)) ? POC_MOVLW : POC_MOVFW );
+
+ pushSide(IC_LEFT(ic), FPTRSIZE);
+
+ /* if send set is not empty, assign parameters */
+ if (_G.sendSet) {
+
+ DEBUGpic14_emitcode ("; ***","%s %d - WARNING arg-passing to indirect call not supported",__FUNCTION__,__LINE__);
+ /* no way to pass args - W always gets used to make the call */
+ }
+ /* first idea - factor out a common helper function and call it.
+ But don't know how to get it generated only once in its own block
+
+ if(AOP_TYPE(IC_LEFT(ic)) == AOP_DIR) {
+ char *rname;
+ char *buffer;
+ rname = IC_LEFT(ic)->aop->aopu.aop_dir;
+ DEBUGpic14_emitcode ("; ***","%s %d AOP_DIR %s",__FUNCTION__,__LINE__,rname);
+ buffer = Safe_calloc(1,strlen(rname)+16);
+ sprintf(buffer, "%s_goto_helper", rname);
+ addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp(buffer,PO_STR)));
+ free(buffer);
+ }
+ */
+ emitpcode(POC_CALL,popGetLabel(albl->key));
+ pcop = popGetLabel(blbl->key);
+ emitpcode(POC_PAGESEL,pcop); /* Must restore PCLATH before goto, without destroying W */
+ emitpcode(POC_GOTO,pcop);
+ emitpLabel(albl->key);
+
+ emitpcode(poc,popGetAddr(AOP(left),1,0));
+ emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
+ emitpcode(poc,popGetAddr(AOP(left),0,0));
+ emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
+
+ emitpLabel(blbl->key);
+
+ freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
+
+ /* if we need to assign a result value */
+ if ((IS_ITEMP(IC_RESULT(ic)) &&
+ (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
+ OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
+ IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
+
+ _G.accInUse++;
+ aopOp(IC_RESULT(ic),ic,FALSE);
+ _G.accInUse--;
+
+ GpsuedoStkPtr = 0;
+
+ assignResultValue(IC_RESULT(ic));
+
+ freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
+ }
+
+ /* if register bank was saved then unsave them */
+ if (currFunc && dtype &&
+ (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
+ unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
+
+ /* if we hade saved some registers then
+ unsave them */
+ if (ic->regsSaved)
+ unsaveRegisters (ic);
+
+}
+
+/*-----------------------------------------------------------------*/
+/* resultRemat - result is rematerializable */
/*-----------------------------------------------------------------*/
static int resultRemat (iCode *ic)
{
- // DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- FENTRY;
+ // DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ FENTRY;
+
+ if (SKIP_IC(ic) || ic->op == IFX)
+ return 0;
+
+ if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
+ symbol *sym = OP_SYMBOL(IC_RESULT(ic));
+ if (sym->remat && !POINTER_SET(ic))
+ return 1;
+ }
- if (SKIP_IC(ic) || ic->op == IFX)
- return 0;
-
- if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
- symbol *sym = OP_SYMBOL(IC_RESULT(ic));
- if (sym->remat && !POINTER_SET(ic))
- return 1;
- }
-
- return 0;
+ return 0;
}
#if 0
/*-----------------------------------------------------------------*/
static bool inExcludeList(char *s)
{
- DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
- int i =0;
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if (options.excludeRegs[i] &&
- STRCASECMP(options.excludeRegs[i],"none") == 0)
- return FALSE ;
-
- for ( i = 0 ; options.excludeRegs[i]; i++) {
- if (options.excludeRegs[i] &&
- STRCASECMP(s,options.excludeRegs[i]) == 0)
- return TRUE;
- }
- return FALSE ;
+ DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
+ int i =0;
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ if (options.excludeRegs[i] &&
+ STRCASECMP(options.excludeRegs[i],"none") == 0)
+ return FALSE ;
+
+ for ( i = 0 ; options.excludeRegs[i]; i++) {
+ if (options.excludeRegs[i] &&
+ STRCASECMP(s,options.excludeRegs[i]) == 0)
+ return TRUE;
+ }
+ return FALSE ;
}
#endif
/*-----------------------------------------------------------------*/
-/* genFunction - generated code for function entry */
+/* genFunction - generated code for function entry */
/*-----------------------------------------------------------------*/
static void genFunction (iCode *ic)
{
- symbol *sym;
- sym_link *ftype;
-
- FENTRY;
-
- DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
-
- labelOffset += (max_key+4);
- max_key=0;
- GpsuedoStkPtr=0;
- _G.nRegsSaved = 0;
- /* create the function header */
- pic14_emitcode(";","-----------------------------------------");
- pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
- pic14_emitcode(";","-----------------------------------------");
-
- /* prevent this symbol from being emitted as 'extern' */
- pic14_stringInSet(sym->rname, &pic14_localFunctions, 1);
-
- pic14_emitcode("","%s:",sym->rname);
- addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname,!IS_STATIC (sym->etype)));
-
- /* mark symbol as NOT extern (even if it was declared so previously) */
- assert(IS_SPEC(sym->etype));
- SPEC_EXTR(sym->etype) = 0;
- sym->cdef = 0;
- if (!SPEC_OCLS(sym->etype)) SPEC_OCLS(sym->etype) = code;
- addSetIfnotP(&SPEC_OCLS(sym->etype)->syms, sym);
-
- ftype = operandType(IC_LEFT(ic));
-
- /* if critical function then turn interrupts off */
- if (IFFUNC_ISCRITICAL(ftype))
- pic14_emitcode("clr","ea");
-
- /* here we need to generate the equates for the
- register bank if required */
+ symbol *sym;
+ sym_link *ftype;
+
+ FENTRY;
+
+ DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
+
+ labelOffset += (max_key+4);
+ max_key=0;
+ GpsuedoStkPtr=0;
+ _G.nRegsSaved = 0;
+ /* create the function header */
+ pic14_emitcode(";","-----------------------------------------");
+ pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
+ pic14_emitcode(";","-----------------------------------------");
+
+ /* prevent this symbol from being emitted as 'extern' */
+ pic14_stringInSet(sym->rname, &pic14_localFunctions, 1);
+
+ pic14_emitcode("","%s:",sym->rname);
+ addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname,!IS_STATIC (sym->etype)));
+
+ /* mark symbol as NOT extern (even if it was declared so previously) */
+ assert(IS_SPEC(sym->etype));
+ SPEC_EXTR(sym->etype) = 0;
+ sym->cdef = 0;
+ if (!SPEC_OCLS(sym->etype)) SPEC_OCLS(sym->etype) = code;
+ addSetIfnotP(&SPEC_OCLS(sym->etype)->syms, sym);
+
+ ftype = operandType(IC_LEFT(ic));
+
+ /* if critical function then turn interrupts off */
+ if (IFFUNC_ISCRITICAL(ftype))
+ pic14_emitcode("clr","ea");
+
+ /* here we need to generate the equates for the
+ register bank if required */
#if 0
- if (FUNC_REGBANK(ftype) != rbank) {
- int i ;
-
- rbank = FUNC_REGBANK(ftype);
- for ( i = 0 ; i < pic14_nRegs ; i++ ) {
- if (strcmp(regspic14[i].base,"0") == 0)
- pic14_emitcode("","%s = 0x%02x",
- regspic14[i].dname,
- 8*rbank+regspic14[i].offset);
- else
- pic14_emitcode ("","%s = %s + 0x%02x",
- regspic14[i].dname,
- regspic14[i].base,
- 8*rbank+regspic14[i].offset);
- }
- }
+ if (FUNC_REGBANK(ftype) != rbank) {
+ int i ;
+
+ rbank = FUNC_REGBANK(ftype);
+ for ( i = 0 ; i < pic14_nRegs ; i++ ) {
+ if (strcmp(regspic14[i].base,"0") == 0)
+ pic14_emitcode("","%s = 0x%02x",
+ regspic14[i].dname,
+ 8*rbank+regspic14[i].offset);
+ else
+ pic14_emitcode ("","%s = %s + 0x%02x",
+ regspic14[i].dname,
+ regspic14[i].base,
+ 8*rbank+regspic14[i].offset);
+ }
+ }
#endif
-
- /* if this is an interrupt service routine */
- pic14_inISR = 0;
- if (IFFUNC_ISISR(sym->type)) {
- pic14_inISR = 1;
- emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
- emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
- /* XXX: Why? Does this assume that ssave and psave reside
- * in a shared bank or bank0? We cannot guarantee the
- * latter...
- */
- emitpcode(POC_CLRF, popCopyReg(&pc_status));
- emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
- //emitpcode(POC_MOVWF, popGetExternal("___sdcc_saved_status",1 ));
- emitpcode(POC_MOVFW, popCopyReg(&pc_pclath));
- /* during an interrupt PCLATH must be cleared before a goto or call statement */
- emitpcode(POC_CLRF, popCopyReg(&pc_pclath));
- emitpcode(POC_MOVWF, popCopyReg(&pc_psave));
- //emitpcode(POC_MOVWF, popGetExternal("___sdcc_saved_pclath", 1));
- emitpcode(POC_MOVFW, popCopyReg(&pc_fsr));
- emitpcode(POC_MOVWF, popGetExternal("___sdcc_saved_fsr", 1));
-
- pBlockConvert2ISR(pb);
- pic14_hasInterrupt = 1;
- } else {
- /* if callee-save to be used for this function
- then save the registers being used in this function */
- if (IFFUNC_CALLEESAVES(sym->type)) {
- int i;
-
- /* if any registers used */
- if (sym->regsUsed) {
- /* save the registers used */
- for ( i = 0 ; i < sym->regsUsed->size ; i++) {
- if (bitVectBitValue(sym->regsUsed,i) ||
- (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
- //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
- _G.nRegsSaved++;
- }
- }
- }
- }
- }
-
- /* set the register bank to the desired value */
- if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
- pic14_emitcode("push","psw");
- pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
- }
-
- if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
-
- if (options.useXstack) {
- pic14_emitcode("mov","r0,%s",spname);
- pic14_emitcode("mov","a,_bp");
- pic14_emitcode("movx","@r0,a");
- pic14_emitcode("inc","%s",spname);
- }
- else
- {
- /* set up the stack */
- pic14_emitcode ("push","_bp"); /* save the callers stack */
- }
- pic14_emitcode ("mov","_bp,%s",spname);
- }
-
- /* adjust the stack for the function */
- if (sym->stack) {
-
- int i = sym->stack;
- if (i > 256 )
- werror(W_STACK_OVERFLOW,sym->name);
-
- if (i > 3 && sym->recvSize < 4) {
-
- pic14_emitcode ("mov","a,sp");
- pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
- pic14_emitcode ("mov","sp,a");
-
- }
- else
- while(i--)
- pic14_emitcode("inc","sp");
- }
-
- if (sym->xstack) {
-
- pic14_emitcode ("mov","a,_spx");
- pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
- pic14_emitcode ("mov","_spx,a");
- }
-
-}
-
-/*-----------------------------------------------------------------*/
-/* genEndFunction - generates epilogue for functions */
+
+ /* if this is an interrupt service routine */
+ pic14_inISR = 0;
+ if (IFFUNC_ISISR(sym->type)) {
+ pic14_inISR = 1;
+ emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
+ emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
+ /* XXX: Why? Does this assume that ssave and psave reside
+ * in a shared bank or bank0? We cannot guarantee the
+ * latter...
+ */
+ emitpcode(POC_CLRF, popCopyReg(&pc_status));
+ emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
+ //emitpcode(POC_MOVWF, popGetExternal("___sdcc_saved_status",1 ));
+ emitpcode(POC_MOVFW, popCopyReg(&pc_pclath));
+ /* during an interrupt PCLATH must be cleared before a goto or call statement */
+ emitpcode(POC_CLRF, popCopyReg(&pc_pclath));
+ emitpcode(POC_MOVWF, popCopyReg(&pc_psave));
+ //emitpcode(POC_MOVWF, popGetExternal("___sdcc_saved_pclath", 1));
+ emitpcode(POC_MOVFW, popCopyReg(&pc_fsr));
+ emitpcode(POC_MOVWF, popGetExternal("___sdcc_saved_fsr", 1));
+
+ pBlockConvert2ISR(pb);
+ pic14_hasInterrupt = 1;
+ } else {
+ /* if callee-save to be used for this function
+ then save the registers being used in this function */
+ if (IFFUNC_CALLEESAVES(sym->type)) {
+ int i;
+
+ /* if any registers used */
+ if (sym->regsUsed) {
+ /* save the registers used */
+ for ( i = 0 ; i < sym->regsUsed->size ; i++) {
+ if (bitVectBitValue(sym->regsUsed,i) ||
+ (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
+ //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
+ _G.nRegsSaved++;
+ }
+ }
+ }
+ }
+ }
+
+ /* set the register bank to the desired value */
+ if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
+ pic14_emitcode("push","psw");
+ pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
+ }
+
+ if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
+
+ if (options.useXstack) {
+ pic14_emitcode("mov","r0,%s",spname);
+ pic14_emitcode("mov","a,_bp");
+ pic14_emitcode("movx","@r0,a");
+ pic14_emitcode("inc","%s",spname);
+ }
+ else
+ {
+ /* set up the stack */
+ pic14_emitcode ("push","_bp"); /* save the callers stack */
+ }
+ pic14_emitcode ("mov","_bp,%s",spname);
+ }
+
+ /* adjust the stack for the function */
+ if (sym->stack) {
+
+ int i = sym->stack;
+ if (i > 256 )
+ werror(W_STACK_OVERFLOW,sym->name);
+
+ if (i > 3 && sym->recvSize < 4) {
+
+ pic14_emitcode ("mov","a,sp");
+ pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
+ pic14_emitcode ("mov","sp,a");
+
+ }
+ else
+ while(i--)
+ pic14_emitcode("inc","sp");
+ }
+
+ if (sym->xstack) {
+
+ pic14_emitcode ("mov","a,_spx");
+ pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
+ pic14_emitcode ("mov","_spx,a");
+ }
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genEndFunction - generates epilogue for functions */
/*-----------------------------------------------------------------*/
static void genEndFunction (iCode *ic)
{
- symbol *sym = OP_SYMBOL(IC_LEFT(ic));
-
- FENTRY;
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
- {
- pic14_emitcode ("mov","%s,_bp",spname);
- }
-
- /* if use external stack but some variables were
- added to the local stack then decrement the
- local stack */
- if (options.useXstack && sym->stack) {
- pic14_emitcode("mov","a,sp");
- pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
- pic14_emitcode("mov","sp,a");
- }
-
-
- if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
- if (options.useXstack) {
- pic14_emitcode("mov","r0,%s",spname);
- pic14_emitcode("movx","a,@r0");
- pic14_emitcode("mov","_bp,a");
- pic14_emitcode("dec","%s",spname);
- }
- else
- {
- pic14_emitcode ("pop","_bp");
- }
- }
-
- /* restore the register bank */
- if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
- pic14_emitcode ("pop","psw");
-
- if (IFFUNC_ISISR(sym->type)) {
-
- /* now we need to restore the registers */
- /* if this isr has no bank i.e. is going to
- run with bank 0 , then we need to save more
+ symbol *sym = OP_SYMBOL(IC_LEFT(ic));
+
+ FENTRY;
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
+ {
+ pic14_emitcode ("mov","%s,_bp",spname);
+ }
+
+ /* if use external stack but some variables were
+ added to the local stack then decrement the
+ local stack */
+ if (options.useXstack && sym->stack) {
+ pic14_emitcode("mov","a,sp");
+ pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
+ pic14_emitcode("mov","sp,a");
+ }
+
+
+ if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
+ if (options.useXstack) {
+ pic14_emitcode("mov","r0,%s",spname);
+ pic14_emitcode("movx","a,@r0");
+ pic14_emitcode("mov","_bp,a");
+ pic14_emitcode("dec","%s",spname);
+ }
+ else
+ {
+ pic14_emitcode ("pop","_bp");
+ }
+ }
+
+ /* restore the register bank */
+ if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
+ pic14_emitcode ("pop","psw");
+
+ if (IFFUNC_ISISR(sym->type)) {
+
+ /* now we need to restore the registers */
+ /* if this isr has no bank i.e. is going to
+ run with bank 0 , then we need to save more
registers :-) */
- if (!FUNC_REGBANK(sym->type)) {
-
- /* if this function does not call any other
- function then we can be economical and
- save only those registers that are used */
- if (! IFFUNC_HASFCALL(sym->type)) {
- int i;
-
- /* if any registers used */
- if (sym->regsUsed) {
- /* save the registers used */
- for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
- if (bitVectBitValue(sym->regsUsed,i) ||
- (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
- pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
- }
- }
-
- } else {
- /* this function has a function call cannot
- determines register usage so we will have the
- entire bank */
- unsaverbank(0,ic,FALSE);
- }
- }
-
- /* if debug then send end of function */
- if (options.debug && debugFile && currFunc) {
- debugFile->writeEndFunction (currFunc, ic, 1);
- }
-
- emitpcode(POC_MOVFW, popGetExternal("___sdcc_saved_fsr", 1));
- emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
- //emitpcode(POC_MOVFW, popGetExternal("___sdcc_saved_pclath", 1));
- emitpcode(POC_MOVFW, popCopyReg(&pc_psave));
- emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
- emitpcode(POC_CLRF, popCopyReg(&pc_status)); // see genFunction
- //emitpcode(POC_SWAPFW, popGetExternal("___sdcc_saved_status", 1));
- emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
- emitpcode(POC_MOVWF, popCopyReg(&pc_status));
- emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
- emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
- addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
- emitpcodeNULLop(POC_RETFIE);
- }
- else {
- if (IFFUNC_ISCRITICAL(sym->type))
- pic14_emitcode("setb","ea");
-
- if (IFFUNC_CALLEESAVES(sym->type)) {
- int i;
-
- /* if any registers used */
- if (sym->regsUsed) {
- /* save the registers used */
- for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
- if (bitVectBitValue(sym->regsUsed,i) ||
- (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
- pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
- }
- }
-
- }
-
- /* if debug then send end of function */
- if (options.debug && debugFile && currFunc) {
- debugFile->writeEndFunction (currFunc, ic, 1);
- }
-
- pic14_emitcode ("return","");
- emitpcodeNULLop(POC_RETURN);
-
- /* Mark the end of a function */
- addpCode2pBlock(pb,newpCodeFunction(NULL,NULL,0));
- }
-
-}
-
-/*-----------------------------------------------------------------*/
-/* genRet - generate code for return statement */
+ if (!FUNC_REGBANK(sym->type)) {
+
+ /* if this function does not call any other
+ function then we can be economical and
+ save only those registers that are used */
+ if (! IFFUNC_HASFCALL(sym->type)) {
+ int i;
+
+ /* if any registers used */
+ if (sym->regsUsed) {
+ /* save the registers used */
+ for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
+ if (bitVectBitValue(sym->regsUsed,i) ||
+ (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
+ pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
+ }
+ }
+
+ } else {
+ /* this function has a function call cannot
+ determines register usage so we will have the
+ entire bank */
+ unsaverbank(0,ic,FALSE);
+ }
+ }
+
+ /* if debug then send end of function */
+ if (options.debug && debugFile && currFunc) {
+ debugFile->writeEndFunction (currFunc, ic, 1);
+ }
+
+ emitpcode(POC_MOVFW, popGetExternal("___sdcc_saved_fsr", 1));
+ emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
+ //emitpcode(POC_MOVFW, popGetExternal("___sdcc_saved_pclath", 1));
+ emitpcode(POC_MOVFW, popCopyReg(&pc_psave));
+ emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
+ emitpcode(POC_CLRF, popCopyReg(&pc_status)); // see genFunction
+ //emitpcode(POC_SWAPFW, popGetExternal("___sdcc_saved_status", 1));
+ emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
+ emitpcode(POC_MOVWF, popCopyReg(&pc_status));
+ emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
+ emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
+ addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
+ emitpcodeNULLop(POC_RETFIE);
+ }
+ else {
+ if (IFFUNC_ISCRITICAL(sym->type))
+ pic14_emitcode("setb","ea");
+
+ if (IFFUNC_CALLEESAVES(sym->type)) {
+ int i;
+
+ /* if any registers used */
+ if (sym->regsUsed) {
+ /* save the registers used */
+ for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
+ if (bitVectBitValue(sym->regsUsed,i) ||
+ (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
+ pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
+ }
+ }
+
+ }
+
+ /* if debug then send end of function */
+ if (options.debug && debugFile && currFunc) {
+ debugFile->writeEndFunction (currFunc, ic, 1);
+ }
+
+ pic14_emitcode ("return","");
+ emitpcodeNULLop(POC_RETURN);
+
+ /* Mark the end of a function */
+ addpCode2pBlock(pb,newpCodeFunction(NULL,NULL,0));
+ }
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genRet - generate code for return statement */
/*-----------------------------------------------------------------*/
static void genRet (iCode *ic)
{
- int size,offset = 0;
-
- FENTRY;
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- /* if we have no return value then
- just generate the "ret" */
- if (!IC_LEFT(ic))
- goto jumpret;
-
- /* we have something to return then
- move the return value into place */
- aopOp(IC_LEFT(ic),ic,FALSE);
- size = AOP_SIZE(IC_LEFT(ic));
-
- for (offset = 0; offset < size; offset++)
- {
- pass_argument (IC_LEFT(ic), offset, size - 1 - offset);
- }
-
- freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
-
+ int size,offset = 0;
+
+ FENTRY;
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* if we have no return value then
+ just generate the "ret" */
+ if (!IC_LEFT(ic))
+ goto jumpret;
+
+ /* we have something to return then
+ move the return value into place */
+ aopOp(IC_LEFT(ic),ic,FALSE);
+ size = AOP_SIZE(IC_LEFT(ic));
+
+ for (offset = 0; offset < size; offset++)
+ {
+ pass_argument (IC_LEFT(ic), offset, size - 1 - offset);
+ }
+
+ freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
+
jumpret:
- /* generate a jump to the return label
- if the next is not the return statement */
- if (!(ic->next && ic->next->op == LABEL &&
- IC_LABEL(ic->next) == returnLabel)) {
-
- emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
- }
-
+ /* generate a jump to the return label
+ if the next is not the return statement */
+ if (!(ic->next && ic->next->op == LABEL &&
+ IC_LABEL(ic->next) == returnLabel)) {
+
+ emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
+ }
+
}
/*-----------------------------------------------------------------*/
-/* genLabel - generates a label */
+/* genLabel - generates a label */
/*-----------------------------------------------------------------*/
static void genLabel (iCode *ic)
{
- FENTRY;
+ FENTRY;
+
+ /* special case never generate */
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ if (IC_LABEL(ic) == entryLabel)
+ return ;
- /* special case never generate */
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if (IC_LABEL(ic) == entryLabel)
- return ;
-
- emitpLabel(IC_LABEL(ic)->key);
- pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
+ emitpLabel(IC_LABEL(ic)->key);
+ pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
}
/*-----------------------------------------------------------------*/
-/* genGoto - generates a goto */
+/* genGoto - generates a goto */
/*-----------------------------------------------------------------*/
//tsd
static void genGoto (iCode *ic)
{
- FENTRY;
+ FENTRY;
- emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
- pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
+ emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
+ pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
}
/*-----------------------------------------------------------------*/
-/* genMultbits :- multiplication of bits */
+/* genMultbits :- multiplication of bits */
/*-----------------------------------------------------------------*/
-static void genMultbits (operand *left,
- operand *right,
- operand *result)
+static void genMultbits (operand *left,
+ operand *right,
+ operand *result)
{
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- if(!pic14_sameRegs(AOP(result),AOP(right)))
- emitpcode(POC_BSF, popGet(AOP(result),0));
-
- emitpcode(POC_BTFSC,popGet(AOP(right),0));
- emitpcode(POC_BTFSS,popGet(AOP(left),0));
- emitpcode(POC_BCF, popGet(AOP(result),0));
-
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ if(!pic14_sameRegs(AOP(result),AOP(right)))
+ emitpcode(POC_BSF, popGet(AOP(result),0));
+
+ emitpcode(POC_BTFSC,popGet(AOP(right),0));
+ emitpcode(POC_BTFSS,popGet(AOP(left),0));
+ emitpcode(POC_BCF, popGet(AOP(result),0));
+
}
/*-----------------------------------------------------------------*/
-/* genMultOneByte : 8 bit multiplication & division */
+/* genMultOneByte : 8 bit multiplication & division */
/*-----------------------------------------------------------------*/
static void genMultOneByte (operand *left,
- operand *right,
- operand *result)
-{
- char *func[] = { NULL, "__mulchar", "__mulint", NULL, "__mullong" };
-
- // symbol *lbl ;
- int size,offset,i;
-
-
- FENTRY;
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- DEBUGpic14_AopType(__LINE__,left,right,result);
- DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
-
- /* (if two literals, the value is computed before) */
- /* if one literal, literal on the right */
- if (AOP_TYPE(left) == AOP_LIT){
- operand *t = right;
- right = left;
- left = t;
- }
-
- assert (AOP_SIZE(left) == AOP_SIZE(right));
-
- size = min(AOP_SIZE(result),AOP_SIZE(left));
- offset = Gstack_base_addr - (2*size - 1);
-
- /* pass right operand as argument */
- for (i=0; i < size; i++)
- {
- mov2w (AOP(right), i);
- emitpcode(POC_MOVWF, popRegFromIdx (++offset));
- } // for
-
- /* pass left operand as argument */
- for (i=0; i < size; i++)
- {
- mov2w (AOP(left), i);
- if (i != size-1) emitpcode(POC_MOVWF, popRegFromIdx (++offset));
- } // for
- assert (offset == Gstack_base_addr);
-
- /* call library routine */
- assert (size > 0 && size <= 4);
- call_libraryfunc (func[size]);
-
- /* assign result */
- movwf (AOP(result), size-1);
- for (i=0; i < size - 1; i++)
- {
- emitpcode(POC_MOVFW, popRegFromIdx (Gstack_base_addr - i));
- movwf (AOP(result), size - 2 - i);
- } // for
-
- /* now (zero-/sign) extend the result to its size */
- addSign (result, AOP_SIZE(left), !SPEC_USIGN(operandType(result)));
-}
-
-/*-----------------------------------------------------------------*/
-/* genMult - generates code for multiplication */
+ operand *right,
+ operand *result)
+{
+ char *func[] = { NULL, "__mulchar", "__mulint", NULL, "__mullong" };
+
+ // symbol *lbl ;
+ int size,offset,i;
+
+
+ FENTRY;
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ DEBUGpic14_AopType(__LINE__,left,right,result);
+ DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
+
+ /* (if two literals, the value is computed before) */
+ /* if one literal, literal on the right */
+ if (AOP_TYPE(left) == AOP_LIT){
+ operand *t = right;
+ right = left;
+ left = t;
+ }
+
+ assert (AOP_SIZE(left) == AOP_SIZE(right));
+
+ size = min(AOP_SIZE(result),AOP_SIZE(left));
+ offset = Gstack_base_addr - (2*size - 1);
+
+ /* pass right operand as argument */
+ for (i=0; i < size; i++)
+ {
+ mov2w (AOP(right), i);
+ emitpcode(POC_MOVWF, popRegFromIdx (++offset));
+ } // for
+
+ /* pass left operand as argument */
+ for (i=0; i < size; i++)
+ {
+ mov2w (AOP(left), i);
+ if (i != size-1) emitpcode(POC_MOVWF, popRegFromIdx (++offset));
+ } // for
+ assert (offset == Gstack_base_addr);
+
+ /* call library routine */
+ assert (size > 0 && size <= 4);
+ call_libraryfunc (func[size]);
+
+ /* assign result */
+ movwf (AOP(result), size-1);
+ for (i=0; i < size - 1; i++)
+ {
+ emitpcode(POC_MOVFW, popRegFromIdx (Gstack_base_addr - i));
+ movwf (AOP(result), size - 2 - i);
+ } // for
+
+ /* now (zero-/sign) extend the result to its size */
+ addSign (result, AOP_SIZE(left), !SPEC_USIGN(operandType(result)));
+}
+
+/*-----------------------------------------------------------------*/
+/* genMult - generates code for multiplication */
/*-----------------------------------------------------------------*/
static void genMult (iCode *ic)
{
- operand *left = IC_LEFT(ic);
- operand *right = IC_RIGHT(ic);
- operand *result= IC_RESULT(ic);
-
- FENTRY;
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- /* assign the amsops */
- aopOp (left,ic,FALSE);
- aopOp (right,ic,FALSE);
- aopOp (result,ic,TRUE);
-
- DEBUGpic14_AopType(__LINE__,left,right,result);
-
- /* special cases first */
- /* both are bits */
- if (AOP_TYPE(left) == AOP_CRY &&
- AOP_TYPE(right)== AOP_CRY) {
- genMultbits(left,right,result);
- goto release ;
- }
-
- /* if both are of size == 1 */
- if (AOP_SIZE(left) == 1 &&
- AOP_SIZE(right) == 1 ) {
- genMultOneByte(left,right,result);
- goto release ;
- }
-
- /* should have been converted to function call */
- assert(0) ;
-
+ operand *left = IC_LEFT(ic);
+ operand *right = IC_RIGHT(ic);
+ operand *result= IC_RESULT(ic);
+
+ FENTRY;
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* assign the amsops */
+ aopOp (left,ic,FALSE);
+ aopOp (right,ic,FALSE);
+ aopOp (result,ic,TRUE);
+
+ DEBUGpic14_AopType(__LINE__,left,right,result);
+
+ /* special cases first */
+ /* both are bits */
+ if (AOP_TYPE(left) == AOP_CRY &&
+ AOP_TYPE(right)== AOP_CRY) {
+ genMultbits(left,right,result);
+ goto release ;
+ }
+
+ /* if both are of size == 1 */
+ if (AOP_SIZE(left) == 1 &&
+ AOP_SIZE(right) == 1 ) {
+ genMultOneByte(left,right,result);
+ goto release ;
+ }
+
+ /* should have been converted to function call */
+ assert(0) ;
+
release :
- freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- freeAsmop(result,NULL,ic,TRUE);
+ freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(result,NULL,ic,TRUE);
}
/*-----------------------------------------------------------------*/
-/* genDivbits :- division of bits */
+/* genDivbits :- division of bits */
/*-----------------------------------------------------------------*/
-static void genDivbits (operand *left,
- operand *right,
- operand *result)
+static void genDivbits (operand *left,
+ operand *right,
+ operand *result)
{
-
- char *l;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- /* the result must be bit */
- pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
- l = aopGet(AOP(left),0,FALSE,FALSE);
-
- MOVA(l);
-
- pic14_emitcode("div","ab");
- pic14_emitcode("rrc","a");
- aopPut(AOP(result),"c",0);
-}
+ char *l;
+
+ FENTRY;
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* the result must be bit */
+ pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
+ l = aopGet(AOP(left),0,FALSE,FALSE);
+
+ MOVA(l);
+
+ pic14_emitcode("div","ab");
+ pic14_emitcode("rrc","a");
+ aopPut(AOP(result),"c",0);
+}
+
+/*-----------------------------------------------------------------*/
+/* genDivOneByte : 8 bit division */
+/*-----------------------------------------------------------------*/
+static void genDivOneByte (operand *left,
+ operand *right,
+ operand *result)
+{
+ int size;
+ int sign;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ assert (AOP_SIZE(right) == 1);
+ assert (AOP_SIZE(left) == 1);
+
+ size = min(AOP_SIZE(result),AOP_SIZE(left));
+ sign = !(SPEC_USIGN(operandType(left))
+ && SPEC_USIGN(operandType(right)));
+
+ if (AOP_TYPE(right) == AOP_LIT)
+ {
+ /* XXX: might add specialized code */
+ }
+
+ if (!sign)
+ {
+ /* unsigned division */
+ #if 1
+ mov2w(AOP(right),0);
+ emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
+ mov2w(AOP(left),0);
+ call_libraryfunc("__divuchar");
+ movwf(AOP(result),0);
+ #else
+ pCodeOp *temp;
+ symbol *lbl;
+
+ temp = popGetTempReg();
+ lbl = newiTempLabel(NULL);
+
+ /* XXX: improve this naive approach:
+ [result] = [a] / [b]
+ ::= [result] = 0; while ([a] > [b]) do [a] -= [b]; [result]++ done
+
+ In PIC assembler:
+ movf left,W
+ movwf temp // temp <-- left
+ movf right,W // W <-- right
+ clrf result
+ label1:
+ incf result
+ subwf temp,F // temp <-- temp - W
+ skipNC // subwf clears CARRY (i.e. sets BORROW) if temp < W
+ goto label1
+ decf result // we just subtract once too often
+ */
+
+ /* XXX: This loops endlessly on DIVIDE BY ZERO */
+ /* We need 1..128 iterations of the loop body (`4 / 5' .. `255 / 2'). */
+
+ mov2w(AOP(left),0);
+ emitpcode(POC_MOVWF, temp);
+ mov2w(AOP(right),0);
+ emitpcode(POC_CLRF, popGet(AOP(result),0));
+
+ emitpLabel(lbl->key);
+ emitpcode(POC_INCF, popGet(AOP(result),0));
+ emitpcode(POC_SUBWF, temp);
+ emitSKPNC;
+ emitpcode(POC_GOTO, popGetLabel(lbl->key));
+ emitpcode(POC_DECF, popGet(AOP(result),0));
+ popReleaseTempReg(temp);
+ #endif
+ }
+ else
+ {
+ /* signed division */
+ mov2w(AOP(right),0);
+ emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
+ mov2w(AOP(left),0);
+ call_libraryfunc("__divschar");
+ movwf(AOP(result),0);
+ }
+
+ /* now performed the signed/unsigned division -- extend result */
+ addSign(result, 1, sign);
+}
+
+/*-----------------------------------------------------------------*/
+/* genDiv - generates code for division */
+/*-----------------------------------------------------------------*/
+static void genDiv (iCode *ic)
+{
+ operand *left = IC_LEFT(ic);
+ operand *right = IC_RIGHT(ic);
+ operand *result= IC_RESULT(ic);
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* assign the amsops */
+ aopOp (left,ic,FALSE);
+ aopOp (right,ic,FALSE);
+ aopOp (result,ic,TRUE);
+
+ /* special cases first */
+ /* both are bits */
+ if (AOP_TYPE(left) == AOP_CRY &&
+ AOP_TYPE(right)== AOP_CRY) {
+ genDivbits(left,right,result);
+ goto release ;
+ }
+
+ /* if both are of size == 1 */
+ if (AOP_SIZE(left) == 1 &&
+ AOP_SIZE(right) == 1 ) {
+ genDivOneByte(left,right,result);
+ goto release ;
+ }
+
+ /* should have been converted to function call */
+ assert(0);
+release :
+ freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(result,NULL,ic,TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genModOneByte : 8 bit modulus */
+/*-----------------------------------------------------------------*/
+static void genModOneByte (operand *left,
+ operand *right,
+ operand *result)
+{
+ int size;
+ int sign;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ assert (AOP_SIZE(right) == 1);
+ assert (AOP_SIZE(left) == 1);
+
+ size = min(AOP_SIZE(result),AOP_SIZE(left));
+ sign = !(SPEC_USIGN(operandType(left))
+ && SPEC_USIGN(operandType(right)));
+
+ if (AOP_TYPE(right) == AOP_LIT)
+ {
+ /* XXX: might add specialized code */
+ }
+
+ if (!sign)
+ {
+ /* unsigned division */
+ #if 1
+ mov2w(AOP(right),0);
+ emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
+ mov2w(AOP(left),0);
+ call_libraryfunc("__moduchar");
+ movwf(AOP(result),0);
+ #else
+ pCodeOp *temp;
+ symbol *lbl;
+
+ lbl = newiTempLabel(NULL);
+
+ assert(!pic14_sameRegs(AOP(right),AOP(result)));
+
+ /* XXX: improve this naive approach:
+ [result] = [a] % [b]
+ ::= [result] = [a]; while ([result] > [b]) do [result] -= [b]; done
+
+ In PIC assembler:
+ movf left,W
+ movwf result // result <-- left
+ movf right,W // W <-- right
+ label1:
+ subwf result,F // result <-- result - W
+ skipNC // subwf clears CARRY (i.e. sets BORROW) if result < W
+ goto label1
+ addwf result, F // we just subtract once too often
+ */
+
+ /* XXX: This loops endlessly on DIVIDE BY ZERO */
+ /* We need 1..128 iterations of the loop body (`4 % 5' .. `255 % 2'). */
+
+ if (!pic14_sameRegs(AOP(left), AOP(result)))
+ {
+ mov2w(AOP(left),0);
+ emitpcode(POC_MOVWF, popGet(AOP(result),0));
+ }
+ mov2w(AOP(right),0);
+
+ emitpLabel(lbl->key);
+ emitpcode(POC_SUBWF, popGet(AOP(result),0));
+ emitSKPNC;
+ emitpcode(POC_GOTO, popGetLabel(lbl->key));
+ emitpcode(POC_ADDWF, popGet(AOP(result),0));
+ #endif
+ }
+ else
+ {
+ /* signed division */
+ mov2w(AOP(right),0);
+ emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
+ mov2w(AOP(left),0);
+ call_libraryfunc("__modschar");
+ movwf(AOP(result),0);
+ }
-/*-----------------------------------------------------------------*/
-/* genDivOneByte : 8 bit division */
-/*-----------------------------------------------------------------*/
-static void genDivOneByte (operand *left,
- operand *right,
- operand *result)
-{
- int size;
- int sign;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- assert (AOP_SIZE(right) == 1);
- assert (AOP_SIZE(left) == 1);
-
- size = min(AOP_SIZE(result),AOP_SIZE(left));
- sign = !(SPEC_USIGN(operandType(left))
- && SPEC_USIGN(operandType(right)));
-
- if (AOP_TYPE(right) == AOP_LIT)
- {
- /* XXX: might add specialized code */
- }
-
- if (!sign)
- {
- /* unsigned division */
- #if 1
- mov2w(AOP(right),0);
- emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
- mov2w(AOP(left),0);
- call_libraryfunc("__divuchar");
- movwf(AOP(result),0);
- #else
- pCodeOp *temp;
- symbol *lbl;
-
- temp = popGetTempReg();
- lbl = newiTempLabel(NULL);
-
- /* XXX: improve this naive approach:
- [result] = [a] / [b]
- ::= [result] = 0; while ([a] > [b]) do [a] -= [b]; [result]++ done
-
- In PIC assembler:
- movf left,W
- movwf temp // temp <-- left
- movf right,W // W <-- right
- clrf result
- label1:
- incf result
- subwf temp,F // temp <-- temp - W
- skipNC // subwf clears CARRY (i.e. sets BORROW) if temp < W
- goto label1
- decf result // we just subtract once too often
- */
-
- /* XXX: This loops endlessly on DIVIDE BY ZERO */
- /* We need 1..128 iterations of the loop body (`4 / 5' .. `255 / 2'). */
-
- mov2w(AOP(left),0);
- emitpcode(POC_MOVWF, temp);
- mov2w(AOP(right),0);
- emitpcode(POC_CLRF, popGet(AOP(result),0));
-
- emitpLabel(lbl->key);
- emitpcode(POC_INCF, popGet(AOP(result),0));
- emitpcode(POC_SUBWF, temp);
- emitSKPNC;
- emitpcode(POC_GOTO, popGetLabel(lbl->key));
- emitpcode(POC_DECF, popGet(AOP(result),0));
- popReleaseTempReg(temp);
- #endif
- }
- else
- {
- /* signed division */
- mov2w(AOP(right),0);
- emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
- mov2w(AOP(left),0);
- call_libraryfunc("__divschar");
- movwf(AOP(result),0);
- }
-
- /* now performed the signed/unsigned division -- extend result */
- addSign(result, 1, sign);
-}
-
-/*-----------------------------------------------------------------*/
-/* genDiv - generates code for division */
-/*-----------------------------------------------------------------*/
-static void genDiv (iCode *ic)
-{
- operand *left = IC_LEFT(ic);
- operand *right = IC_RIGHT(ic);
- operand *result= IC_RESULT(ic);
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- /* assign the amsops */
- aopOp (left,ic,FALSE);
- aopOp (right,ic,FALSE);
- aopOp (result,ic,TRUE);
-
- /* special cases first */
- /* both are bits */
- if (AOP_TYPE(left) == AOP_CRY &&
- AOP_TYPE(right)== AOP_CRY) {
- genDivbits(left,right,result);
- goto release ;
- }
-
- /* if both are of size == 1 */
- if (AOP_SIZE(left) == 1 &&
- AOP_SIZE(right) == 1 ) {
- genDivOneByte(left,right,result);
- goto release ;
- }
-
- /* should have been converted to function call */
- assert(0);
-release :
- freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- freeAsmop(result,NULL,ic,TRUE);
+ /* now we performed the signed/unsigned modulus -- extend result */
+ addSign(result, 1, sign);
}
/*-----------------------------------------------------------------*/
-/* genModOneByte : 8 bit modulus */
-/*-----------------------------------------------------------------*/
-static void genModOneByte (operand *left,
- operand *right,
- operand *result)
-{
- int size;
- int sign;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- assert (AOP_SIZE(right) == 1);
- assert (AOP_SIZE(left) == 1);
-
- size = min(AOP_SIZE(result),AOP_SIZE(left));
- sign = !(SPEC_USIGN(operandType(left))
- && SPEC_USIGN(operandType(right)));
-
- if (AOP_TYPE(right) == AOP_LIT)
- {
- /* XXX: might add specialized code */
- }
-
- if (!sign)
- {
- /* unsigned division */
- #if 1
- mov2w(AOP(right),0);
- emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
- mov2w(AOP(left),0);
- call_libraryfunc("__moduchar");
- movwf(AOP(result),0);
- #else
- pCodeOp *temp;
- symbol *lbl;
-
- lbl = newiTempLabel(NULL);
-
- assert(!pic14_sameRegs(AOP(right),AOP(result)));
-
- /* XXX: improve this naive approach:
- [result] = [a] % [b]
- ::= [result] = [a]; while ([result] > [b]) do [result] -= [b]; done
-
- In PIC assembler:
- movf left,W
- movwf result // result <-- left
- movf right,W // W <-- right
- label1:
- subwf result,F // result <-- result - W
- skipNC // subwf clears CARRY (i.e. sets BORROW) if result < W
- goto label1
- addwf result, F // we just subtract once too often
- */
-
- /* XXX: This loops endlessly on DIVIDE BY ZERO */
- /* We need 1..128 iterations of the loop body (`4 % 5' .. `255 % 2'). */
-
- if (!pic14_sameRegs(AOP(left), AOP(result)))
- {
- mov2w(AOP(left),0);
- emitpcode(POC_MOVWF, popGet(AOP(result),0));
- }
- mov2w(AOP(right),0);
-
- emitpLabel(lbl->key);
- emitpcode(POC_SUBWF, popGet(AOP(result),0));
- emitSKPNC;
- emitpcode(POC_GOTO, popGetLabel(lbl->key));
- emitpcode(POC_ADDWF, popGet(AOP(result),0));
- #endif
- }
- else
- {
- /* signed division */
- mov2w(AOP(right),0);
- emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
- mov2w(AOP(left),0);
- call_libraryfunc("__modschar");
- movwf(AOP(result),0);
- }
-
- /* now we performed the signed/unsigned modulus -- extend result */
- addSign(result, 1, sign);
-}
-
-/*-----------------------------------------------------------------*/
-/* genMod - generates code for division */
+/* genMod - generates code for division */
/*-----------------------------------------------------------------*/
static void genMod (iCode *ic)
{
- operand *left = IC_LEFT(ic);
- operand *right = IC_RIGHT(ic);
- operand *result= IC_RESULT(ic);
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- /* assign the amsops */
- aopOp (left,ic,FALSE);
- aopOp (right,ic,FALSE);
- aopOp (result,ic,TRUE);
-
- /* if both are of size == 1 */
- if (AOP_SIZE(left) == 1 &&
- AOP_SIZE(right) == 1 ) {
- genModOneByte(left,right,result);
- goto release ;
- }
-
- /* should have been converted to function call */
- assert(0);
-
+ operand *left = IC_LEFT(ic);
+ operand *right = IC_RIGHT(ic);
+ operand *result= IC_RESULT(ic);
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* assign the amsops */
+ aopOp (left,ic,FALSE);
+ aopOp (right,ic,FALSE);
+ aopOp (result,ic,TRUE);
+
+ /* if both are of size == 1 */
+ if (AOP_SIZE(left) == 1 &&
+ AOP_SIZE(right) == 1 ) {
+ genModOneByte(left,right,result);
+ goto release ;
+ }
+
+ /* should have been converted to function call */
+ assert(0);
+
release :
- freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- freeAsmop(result,NULL,ic,TRUE);
+ freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(result,NULL,ic,TRUE);
}
/*-----------------------------------------------------------------*/
-/* genIfxJump :- will create a jump depending on the ifx */
+/* genIfxJump :- will create a jump depending on the ifx */
/*-----------------------------------------------------------------*/
/*
note: May need to add parameter to indicate when a variable is in bit space.
*/
static void genIfxJump (iCode *ic, char *jval)
{
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- /* if true label then we jump if condition
- supplied is true */
- if ( IC_TRUE(ic) ) {
-
- if(strcmp(jval,"a") == 0)
- emitSKPZ;
- else if (strcmp(jval,"c") == 0)
- emitSKPC;
- else {
- DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
- emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
- }
-
- emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
- pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
-
- }
- else {
- /* false label is present */
- if(strcmp(jval,"a") == 0)
- emitSKPNZ;
- else if (strcmp(jval,"c") == 0)
- emitSKPNC;
- else {
- DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
- emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
- }
-
- emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
- pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
-
- }
-
-
- /* mark the icode as generated */
- ic->generated = 1;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* if true label then we jump if condition
+ supplied is true */
+ if ( IC_TRUE(ic) ) {
+
+ if(strcmp(jval,"a") == 0)
+ emitSKPZ;
+ else if (strcmp(jval,"c") == 0)
+ emitSKPC;
+ else {
+ DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
+ emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
+ }
+
+ emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
+ pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
+
+ }
+ else {
+ /* false label is present */
+ if(strcmp(jval,"a") == 0)
+ emitSKPNZ;
+ else if (strcmp(jval,"c") == 0)
+ emitSKPNC;
+ else {
+ DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
+ emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
+ }
+
+ emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
+ pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
+
+ }
+
+
+ /* mark the icode as generated */
+ ic->generated = 1;
}
#if 0
/*-----------------------------------------------------------------*/
-/* genSkip */
+/* genSkip */
/*-----------------------------------------------------------------*/
static void genSkip(iCode *ifx,int status_bit)
{
- FENTRY;
- if(!ifx)
- return;
-
- if ( IC_TRUE(ifx) ) {
- switch(status_bit) {
- case 'z':
- emitSKPNZ;
- break;
-
- case 'c':
- emitSKPNC;
- break;
-
- case 'd':
- emitSKPDC;
- break;
-
- }
-
- emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
- pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
-
- } else {
-
- switch(status_bit) {
-
- case 'z':
- emitSKPZ;
- break;
-
- case 'c':
- emitSKPC;
- break;
-
- case 'd':
- emitSKPDC;
- break;
- }
- emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
- pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
-
- }
-
+ FENTRY;
+ if(!ifx)
+ return;
+
+ if ( IC_TRUE(ifx) ) {
+ switch(status_bit) {
+ case 'z':
+ emitSKPNZ;
+ break;
+
+ case 'c':
+ emitSKPNC;
+ break;
+
+ case 'd':
+ emitSKPDC;
+ break;
+
+ }
+
+ emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
+ pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
+
+ } else {
+
+ switch(status_bit) {
+
+ case 'z':
+ emitSKPZ;
+ break;
+
+ case 'c':
+ emitSKPC;
+ break;
+
+ case 'd':
+ emitSKPDC;
+ break;
+ }
+ emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
+ pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
+
+ }
+
}
#endif
/*-----------------------------------------------------------------*/
-/* genSkipc */
+/* genSkipc */
/*-----------------------------------------------------------------*/
static void genSkipc(resolvedIfx *rifx)
{
- FENTRY;
- if(!rifx)
- return;
-
- if(rifx->condition)
- emitSKPNC;
- else
- emitSKPC;
-
- emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
- emitpComment ("%s:%u: created from rifx:%p", __FUNCTION__, __LINE__, rifx);
- rifx->generated = 1;
+ FENTRY;
+ if(!rifx)
+ return;
+
+ if(rifx->condition)
+ emitSKPNC;
+ else
+ emitSKPC;
+
+ emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
+ emitpComment ("%s:%u: created from rifx:%p", __FUNCTION__, __LINE__, rifx);
+ rifx->generated = 1;
}
#if 0
/*-----------------------------------------------------------------*/
-/* genSkipz2 */
+/* genSkipz2 */
/*-----------------------------------------------------------------*/
static void genSkipz2(resolvedIfx *rifx, int invert_condition)
{
- FENTRY;
- if(!rifx)
- return;
-
- if( (rifx->condition ^ invert_condition) & 1)
- emitSKPZ;
- else
- emitSKPNZ;
-
- emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
- rifx->generated = 1;
+ FENTRY;
+ if(!rifx)
+ return;
+
+ if( (rifx->condition ^ invert_condition) & 1)
+ emitSKPZ;
+ else
+ emitSKPNZ;
+
+ emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
+ rifx->generated = 1;
}
#endif
/*-----------------------------------------------------------------*/
static void genSkipz(iCode *ifx, int condition)
{
- FENTRY;
- assert (ifx != NULL);
-
- if(condition)
- emitSKPNZ;
- else
- emitSKPZ;
-
- if ( IC_TRUE(ifx) )
- emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
- else
- emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
-
- if ( IC_TRUE(ifx) )
- pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
- else
- pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
-
+ FENTRY;
+ assert (ifx != NULL);
+
+ if(condition)
+ emitSKPNZ;
+ else
+ emitSKPZ;
+
+ if ( IC_TRUE(ifx) )
+ emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
+ else
+ emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
+
+ if ( IC_TRUE(ifx) )
+ pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
+ else
+ pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
+
}
#endif
/*-----------------------------------------------------------------*/
static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
{
- FENTRY;
- if(!rifx)
- return;
-
- if(rifx->condition)
- emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
- else
- emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
-
-
- emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
- rifx->generated = 1;
+ FENTRY;
+ if(!rifx)
+ return;
+
+ if(rifx->condition)
+ emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
+ else
+ emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
+
+
+ emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
+ rifx->generated = 1;
}
#endif
/*-----------------------------------------------------------------*/
static int genChkZeroes(operand *op, int lit, int size)
{
-
- int i;
- int flag =1;
-
- while(size--) {
- i = (lit >> (size*8)) & 0xff;
-
- if(i==0) {
- if(flag)
- emitpcode(POC_MOVFW, popGet(AOP(op),size));
- else
- emitpcode(POC_IORFW, popGet(AOP(op),size));
- flag = 0;
- }
- }
-
- return (flag==0);
+
+ int i;
+ int flag =1;
+
+ while(size--) {
+ i = (lit >> (size*8)) & 0xff;
+
+ if(i==0) {
+ if(flag)
+ emitpcode(POC_MOVFW, popGet(AOP(op),size));
+ else
+ emitpcode(POC_IORFW, popGet(AOP(op),size));
+ flag = 0;
+ }
+ }
+
+ return (flag==0);
}
#endif
int invert_result = 0;
FENTRY;
-
+
assert (AOP_SIZE(left) == AOP_SIZE(right));
assert (left && right);
performedLt = 1;
templbl = NULL;
lit = 0;
-
+
resolveIfx (&rIfx, ifx);
/**********************************************************************
assert (isAOP_REGlike(right));
// swap left and right
// left < right <==> right > left <==> (right >= left + 1)
- lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
+ lit = ulFromVal(AOP(left)->aopu.aop_lit);
if ( (!sign && (lit & mask) == mask) || (sign && (lit & mask) == (mask >> 1)) ) {
// MAXVALUE < right? always false
performedLt ^= 1; // instead of "left < right" we check for "right >= left+1, i.e. "right < left+1"
} else if (isAOP_LIT(right)) {
- lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
+ lit = ulFromVal(AOP(right)->aopu.aop_lit);
} // if
assert (isAOP_REGlike(left)); // left must be register or the like
// unsigned comparison to a literal
DEBUGpc ("unsigned compare: left %s lit(0x%X=%lu), size=%d", performedLt ? "<" : ">=", lit, lit, size+1);
if (lit == 0) {
- // unsigned left < 0? always false
- if (performedLt) emitCLRC; else emitSETC;
- goto correct_result_in_carry;
+ // unsigned left < 0? always false
+ if (performedLt) emitCLRC; else emitSETC;
+ goto correct_result_in_carry;
}
} else {
// signed comparison to a literal
DEBUGpc ("signed compare: left %s lit(0x%X=%ld), size=%d, mask=%x", performedLt ? "<" : ">=", lit, lit, size+1, mask);
if ((lit & mask) == ((0x80 << (size*8)) & mask)) {
- // signed left < 0x80000000? always false
- if (performedLt) emitCLRC; else emitSETC;
- goto correct_result_in_carry;
+ // signed left < 0x80000000? always false
+ if (performedLt) emitCLRC; else emitSETC;
+ goto correct_result_in_carry;
} else if (lit == 0) {
- // compare left < 0; set CARRY if SIGNBIT(left) is set
- if (performedLt) emitSETC; else emitCLRC;
- emitpcode (POC_BTFSS, newpCodeOpBit (aopGet (AOP(left), size, FALSE, FALSE), 7, 0));
- if (performedLt) emitCLRC; else emitSETC;
- goto correct_result_in_carry;
+ // compare left < 0; set CARRY if SIGNBIT(left) is set
+ if (performedLt) emitSETC; else emitCLRC;
+ emitpcode (POC_BTFSS, newpCodeOpBit (aopGet (AOP(left), size, FALSE, FALSE), 7, 0));
+ if (performedLt) emitCLRC; else emitSETC;
+ goto correct_result_in_carry;
}
} // if (!sign)
} // right is literal
// left >= LIT <-> LIT-left <= 0 <-> LIT-left == 0 OR !(LIT-left >= 0)
unsigned char litbyte = (lit >> (8*size)) & 0xFF;
- if (litbyte == 0x80) {
- // left >= 0x80 -- always true, but more bytes to come
- mov2w (AOP(left), size);
- emitpcode (POC_XORLW, popGetLit (0x80)); // set ZERO flag
- emitSETC;
- } else {
- // left >= LIT <-> left + (-LIT) >= 0 <-> left + (0x100-LIT) >= 0x100
- mov2w (AOP(left), size);
- emitpcode (POC_ADDLW, popGetLit (0x80));
- emitpcode (POC_ADDLW, popGetLit ((0x100 - (litbyte + 0x80)) & 0x00FF));
- } // if
- } else {
- pCodeOp *pctemp = popGetTempReg();
- mov2w (AOP(left), size);
- emitpcode (POC_ADDLW, popGetLit (0x80));
- emitpcode (POC_MOVWF, pctemp);
- mov2w (AOP(right), size);
- emitpcode (POC_ADDLW, popGetLit (0x80));
- emitpcode (POC_SUBFW, pctemp);
- popReleaseTempReg(pctemp);
- }
- } // if (!sign)
+ if (litbyte == 0x80) {
+ // left >= 0x80 -- always true, but more bytes to come
+ mov2w (AOP(left), size);
+ emitpcode (POC_XORLW, popGetLit (0x80)); // set ZERO flag
+ emitSETC;
+ } else {
+ // left >= LIT <-> left + (-LIT) >= 0 <-> left + (0x100-LIT) >= 0x100
+ mov2w (AOP(left), size);
+ emitpcode (POC_ADDLW, popGetLit (0x80));
+ emitpcode (POC_ADDLW, popGetLit ((0x100 - (litbyte + 0x80)) & 0x00FF));
+ } // if
+ } else {
+ pCodeOp *pctemp = popGetTempReg();
+ mov2w (AOP(left), size);
+ emitpcode (POC_ADDLW, popGetLit (0x80));
+ emitpcode (POC_MOVWF, pctemp);
+ mov2w (AOP(right), size);
+ emitpcode (POC_ADDLW, popGetLit (0x80));
+ emitpcode (POC_SUBFW, pctemp);
+ popReleaseTempReg(pctemp);
+ }
+ } // if (!sign)
+
+ // compare remaining bytes (treat as unsigned case from above)
+ templbl = newiTempLabel ( NULL );
+ offs = size;
+ while (offs--) {
+ //DEBUGpc ("comparing bytes at offset %d", offs);
+ emitSKPZ;
+ emitpcode (POC_GOTO, popGetLabel (templbl->key));
+ pic14_mov2w_regOrLit (AOP(right), lit, offs);
+ emitpcode (POC_SUBFW, popGet (AOP(left), offs));
+ } // while (offs)
+ emitpLabel (templbl->key);
+ goto result_in_carry;
+
+result_in_carry:
+
+ /****************************************************
+ * now CARRY contains the result of the comparison: *
+ * SUBWF sets CARRY iff *
+ * F-W >= 0 <==> F >= W <==> !(F < W) *
+ * (F=left, W=right) *
+ ****************************************************/
+
+ if (performedLt) {
+ invert_result = 1;
+ // value will be used in the following genSkipc()
+ rIfx.condition ^= 1;
+ } // if
+
+correct_result_in_carry:
+
+ // assign result to variable (if neccessary)
+ if (result && AOP_TYPE(result) != AOP_CRY) {
+ //DEBUGpc ("assign result");
+ size = AOP_SIZE(result);
+ while (size--) {
+ emitpcode (POC_CLRF, popGet (AOP(result), size));
+ } // while
+ if (invert_result) {
+ emitSKPC;
+ emitpcode (POC_BSF, newpCodeOpBit (aopGet (AOP(result), 0, FALSE, FALSE), 0, 0));
+ } else {
+ emitpcode (POC_RLF, popGet (AOP(result), 0));
+ }
+ } // if (result)
+
+ // perform conditional jump
+ if (ifx) {
+ //DEBUGpc ("generate control flow");
+ genSkipc (&rIfx);
+ ifx->generated = 1;
+ } // if
+}
+
+
+#if 0
+/* OLD VERSION -- BUGGY, DO NOT USE */
+
+/*-----------------------------------------------------------------*/
+/* genCmp :- greater or less than comparison */
+/*-----------------------------------------------------------------*/
+static void genCmp (operand *left,operand *right,
+ operand *result, iCode *ifx, int sign)
+{
+ int size; //, offset = 0 ;
+ unsigned long lit = 0L,i = 0;
+ resolvedIfx rFalseIfx;
+ // resolvedIfx rTrueIfx;
+ symbol *truelbl;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ /*
+ if(ifx) {
+ DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
+ DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
+ }
+ */
+
+ resolveIfx(&rFalseIfx,ifx);
+ truelbl = newiTempLabel(NULL);
+ size = max(AOP_SIZE(left),AOP_SIZE(right));
+
+ DEBUGpic14_AopType(__LINE__,left,right,result);
+
+#define _swapp
+
+ /* if literal is on the right then swap with left */
+ if ((AOP_TYPE(right) == AOP_LIT)) {
+ operand *tmp = right ;
+ unsigned long mask = (0x100 << (8*(size-1))) - 1;
+ lit = ulFromVal(AOP(right)->aopu.aop_lit);
+#ifdef _swapp
+
+ lit = (lit - 1) & mask;
+ right = left;
+ left = tmp;
+ rFalseIfx.condition ^= 1;
+#endif
+
+ } else if ((AOP_TYPE(left) == AOP_LIT)) {
+ lit = ulFromVal(AOP(left)->aopu.aop_lit);
+ }
+
+
+ //if(IC_TRUE(ifx) == NULL)
+ /* if left & right are bit variables */
+ if (AOP_TYPE(left) == AOP_CRY &&
+ AOP_TYPE(right) == AOP_CRY ) {
+ pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
+ pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
+ } else {
+ /* subtract right from left if at the
+ end the carry flag is set then we know that
+ left is greater than right */
+
+ symbol *lbl = newiTempLabel(NULL);
+
+#ifndef _swapp
+ if(AOP_TYPE(right) == AOP_LIT) {
+
+ //lit = ulFromVal(AOP(right)->aopu.aop_lit);
+
+ DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
+
+ /* special cases */
+
+ if(lit == 0) {
+
+ if(sign != 0)
+ genSkipCond(&rFalseIfx,left,size-1,7);
+ else
+ /* no need to compare to 0...*/
+ /* NOTE: this is a de-generate compare that most certainly
+ * creates some dead code. */
+ emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
+
+ if(ifx) ifx->generated = 1;
+ return;
+
+ }
+ size--;
+
+ if(size == 0) {
+ //i = (lit >> (size*8)) & 0xff;
+ DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
+
+ emitpcode(POC_MOVFW, popGet(AOP(left),size));
+
+ i = ((0-lit) & 0xff);
+ if(sign) {
+ if( i == 0x81) {
+ /* lit is 0x7f, all signed chars are less than
+ * this except for 0x7f itself */
+ emitpcode(POC_XORLW, popGetLit(0x7f));
+ genSkipz2(&rFalseIfx,0);
+ } else {
+ emitpcode(POC_ADDLW, popGetLit(0x80));
+ emitpcode(POC_ADDLW, popGetLit(i^0x80));
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
+ }
+
+ } else {
+ if(lit == 1) {
+ genSkipz2(&rFalseIfx,1);
+ } else {
+ emitpcode(POC_ADDLW, popGetLit(i));
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
+ }
+ }
+
+ if(ifx) ifx->generated = 1;
+ return;
+ }
+
+ /* chars are out of the way. now do ints and longs */
+
+
+ DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
+
+ /* special cases */
+
+ if(sign) {
+
+ if(lit == 0) {
+ genSkipCond(&rFalseIfx,left,size,7);
+ if(ifx) ifx->generated = 1;
+ return;
+ }
+
+ if(lit <0x100) {
+ DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
+
+ //rFalseIfx.condition ^= 1;
+ //genSkipCond(&rFalseIfx,left,size,7);
+ //rFalseIfx.condition ^= 1;
+
+ emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
+ if(rFalseIfx.condition)
+ emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
+ else
+ emitpcode(POC_GOTO, popGetLabel(truelbl->key));
+
+ emitpcode(POC_MOVLW, popGetLit(0x100-lit));
+ emitpcode(POC_ADDFW, popGet(AOP(left),0));
+ emitpcode(POC_MOVFW, popGet(AOP(left),1));
+
+ while(size > 1)
+ emitpcode(POC_IORFW, popGet(AOP(left),size--));
+
+ if(rFalseIfx.condition) {
+ emitSKPZ;
+ emitpcode(POC_GOTO, popGetLabel(truelbl->key));
+
+ } else {
+ emitSKPNZ;
+ }
+
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
+ emitpLabel(truelbl->key);
+ if(ifx) ifx->generated = 1;
+ return;
+
+ }
+
+ if(size == 1) {
+
+ if( (lit & 0xff) == 0) {
+ /* lower byte is zero */
+ DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
+ i = ((lit >> 8) & 0xff) ^0x80;
+ emitpcode(POC_MOVFW, popGet(AOP(left),size));
+ emitpcode(POC_ADDLW, popGetLit( 0x80));
+ emitpcode(POC_ADDLW, popGetLit(0x100-i));
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
+
+
+ if(ifx) ifx->generated = 1;
+ return;
+
+ }
+ } else {
+ /* Special cases for signed longs */
+ if( (lit & 0xffffff) == 0) {
+ /* lower byte is zero */
+ DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
+ i = ((lit >> 8*3) & 0xff) ^0x80;
+ emitpcode(POC_MOVFW, popGet(AOP(left),size));
+ emitpcode(POC_ADDLW, popGetLit( 0x80));
+ emitpcode(POC_ADDLW, popGetLit(0x100-i));
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
+
+
+ if(ifx) ifx->generated = 1;
+ return;
+
+ }
+
+ }
+
+
+ if(lit & (0x80 << (size*8))) {
+ /* lit is negative */
+ DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
+
+ //genSkipCond(&rFalseIfx,left,size,7);
+
+ emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
+
+ if(rFalseIfx.condition)
+ emitpcode(POC_GOTO, popGetLabel(truelbl->key));
+ else
+ emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
+
+
+ } else {
+ /* lit is positive */
+ DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
+ emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
+ if(rFalseIfx.condition)
+ emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
+ else
+ emitpcode(POC_GOTO, popGetLabel(truelbl->key));
+
+ }
+
+ /* There are no more special cases, so perform a general compare */
+
+ emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
+ emitpcode(POC_SUBFW, popGet(AOP(left),size));
+
+ while(size--) {
+
+ emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
+ emitSKPNZ;
+ emitpcode(POC_SUBFW, popGet(AOP(left),size));
+ }
+ //rFalseIfx.condition ^= 1;
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
+
+ emitpLabel(truelbl->key);
+
+ if(ifx) ifx->generated = 1;
+ return;
+
+
+ }
+
+
+ /* sign is out of the way. So now do an unsigned compare */
+ DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
+
+
+ /* General case - compare to an unsigned literal on the right.*/
+
+ i = (lit >> (size*8)) & 0xff;
+ emitpcode(POC_MOVLW, popGetLit(i));
+ emitpcode(POC_SUBFW, popGet(AOP(left),size));
+ while(size--) {
+ i = (lit >> (size*8)) & 0xff;
+
+ if(i) {
+ emitpcode(POC_MOVLW, popGetLit(i));
+ emitSKPNZ;
+ emitpcode(POC_SUBFW, popGet(AOP(left),size));
+ } else {
+ /* this byte of the lit is zero,
+ *if it's not the last then OR in the variable */
+ if(size)
+ emitpcode(POC_IORFW, popGet(AOP(left),size));
+ }
+ }
+
+
+ emitpLabel(lbl->key);
+ //if(emitFinalCheck)
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
+ if(sign)
+ emitpLabel(truelbl->key);
+
+ if(ifx) ifx->generated = 1;
+ return;
+
+
+ }
+#endif // _swapp
+
+ if(AOP_TYPE(left) == AOP_LIT) {
+ //symbol *lbl = newiTempLabel(NULL);
+
+ //EXPERIMENTAL lit = ulFromVal(AOP(left)->aopu.aop_lit);
+
+
+ DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
+
+ /* Special cases */
+ if((lit == 0) && (sign == 0)){
+
+ size--;
+ emitpcode(POC_MOVFW, popGet(AOP(right),size));
+ while(size)
+ emitpcode(POC_IORFW, popGet(AOP(right),--size));
+
+ genSkipz2(&rFalseIfx,0);
+ if(ifx) ifx->generated = 1;
+ return;
+ }
+
+ if(size==1) {
+ /* Special cases */
+ lit &= 0xff;
+ if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
+ /* degenerate compare can never be true */
+ if(rFalseIfx.condition == 0)
+ emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
+
+ if(ifx) ifx->generated = 1;
+ return;
+ }
+
+ if(sign) {
+ /* signed comparisons to a literal byte */
+
+ int lp1 = (lit+1) & 0xff;
+
+ DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
+ switch (lp1) {
+ case 0:
+ rFalseIfx.condition ^= 1;
+ genSkipCond(&rFalseIfx,right,0,7);
+ break;
+ case 0x7f:
+ emitpcode(POC_MOVFW, popGet(AOP(right),0));
+ emitpcode(POC_XORLW, popGetLit(0x7f));
+ genSkipz2(&rFalseIfx,1);
+ break;
+ default:
+ emitpcode(POC_MOVFW, popGet(AOP(right),0));
+ emitpcode(POC_ADDLW, popGetLit(0x80));
+ emitpcode(POC_ADDLW, popGetLit(((0-(lit+1)) & 0xff) ^ 0x80));
+ rFalseIfx.condition ^= 1;
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
+ break;
+ }
+ if(ifx) ifx->generated = 1;
+ } else {
+ /* unsigned comparisons to a literal byte */
+
+ switch(lit & 0xff ) {
+ case 0:
+ emitpcode(POC_MOVFW, popGet(AOP(right),0));
+ genSkipz2(&rFalseIfx,0);
+ if(ifx) ifx->generated = 1;
+ break;
+ case 0x7f:
+ genSkipCond(&rFalseIfx,right,0,7);
+ if(ifx) ifx->generated = 1;
+ break;
+
+ default:
+ emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
+ emitpcode(POC_SUBFW, popGet(AOP(right),0));
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ rFalseIfx.condition ^= 1;
+ if (AOP_TYPE(result) == AOP_CRY) {
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
+ if(ifx) ifx->generated = 1;
+ } else {
+ DEBUGpic14_emitcode ("; ***","%s %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
+ emitpcode(POC_CLRF, popGet(AOP(result),0));
+ emitpcode(POC_RLF, popGet(AOP(result),0));
+ emitpcode(POC_MOVLW, popGetLit(0x01));
+ emitpcode(POC_XORWF, popGet(AOP(result),0));
+ }
+ break;
+ }
+ }
+
+ //goto check_carry;
+ return;
+
+ } else {
+
+ /* Size is greater than 1 */
+
+ if(sign) {
+ int lp1 = lit+1;
+
+ size--;
+
+ if(lp1 == 0) {
+ /* this means lit = 0xffffffff, or -1 */
+
+
+ DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
+ rFalseIfx.condition ^= 1;
+ genSkipCond(&rFalseIfx,right,size,7);
+ if(ifx) ifx->generated = 1;
+ return;
+ }
+
+ if(lit == 0) {
+ int s = size;
+
+ if(rFalseIfx.condition) {
+ emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
+ emitpcode(POC_GOTO, popGetLabel(truelbl->key));
+ }
+
+ emitpcode(POC_MOVFW, popGet(AOP(right),size));
+ while(size--)
+ emitpcode(POC_IORFW, popGet(AOP(right),size));
+
+
+ emitSKPZ;
+ if(rFalseIfx.condition) {
+ emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
+ emitpLabel(truelbl->key);
+ }else {
+ rFalseIfx.condition ^= 1;
+ genSkipCond(&rFalseIfx,right,s,7);
+ }
+
+ if(ifx) ifx->generated = 1;
+ return;
+ }
+
+ if((size == 1) && (0 == (lp1&0xff))) {
+ /* lower byte of signed word is zero */
+ DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
+ i = ((lp1 >> 8) & 0xff) ^0x80;
+ emitpcode(POC_MOVFW, popGet(AOP(right),size));
+ emitpcode(POC_ADDLW, popGetLit( 0x80));
+ emitpcode(POC_ADDLW, popGetLit(0x100-i));
+ rFalseIfx.condition ^= 1;
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
+
+
+ if(ifx) ifx->generated = 1;
+ return;
+ }
+
+ if(lit & (0x80 << (size*8))) {
+ /* Lit is less than zero */
+ DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
+ //rFalseIfx.condition ^= 1;
+ //genSkipCond(&rFalseIfx,left,size,7);
+ //rFalseIfx.condition ^= 1;
+ emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
+ //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
+
+ if(rFalseIfx.condition)
+ emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
+ else
+ emitpcode(POC_GOTO, popGetLabel(truelbl->key));
+
+
+ } else {
+ /* Lit is greater than or equal to zero */
+ DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
+ //rFalseIfx.condition ^= 1;
+ //genSkipCond(&rFalseIfx,right,size,7);
+ //rFalseIfx.condition ^= 1;
+
+ //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
+ //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
+
+ emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
+ if(rFalseIfx.condition)
+ emitpcode(POC_GOTO, popGetLabel(truelbl->key));
+ else
+ emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
+
+ }
+
+
+ emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
+ emitpcode(POC_SUBFW, popGet(AOP(right),size));
+
+ while(size--) {
+
+ emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
+ emitSKPNZ;
+ emitpcode(POC_SUBFW, popGet(AOP(right),size));
+ }
+ rFalseIfx.condition ^= 1;
+ //rFalseIfx.condition = 1;
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
+
+ emitpLabel(truelbl->key);
+
+ if(ifx) ifx->generated = 1;
+ return;
+ // end of if (sign)
+ } else {
+
+ /* compare word or long to an unsigned literal on the right.*/
+
+
+ size--;
+ if(lit < 0xff) {
+ DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
+ switch (lit) {
+ case 0:
+ break; /* handled above */
+ /*
+ case 0xff:
+ emitpcode(POC_MOVFW, popGet(AOP(right),size));
+ while(size--)
+ emitpcode(POC_IORFW, popGet(AOP(right),size));
+ genSkipz2(&rFalseIfx,0);
+ break;
+ */
+ default:
+ emitpcode(POC_MOVFW, popGet(AOP(right),size));
+ while(--size)
+ emitpcode(POC_IORFW, popGet(AOP(right),size));
+
+ emitSKPZ;
+ if(rFalseIfx.condition)
+ emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
+ else
+ emitpcode(POC_GOTO, popGetLabel(truelbl->key));
+
+
+ emitpcode(POC_MOVLW, popGetLit(lit+1));
+ emitpcode(POC_SUBFW, popGet(AOP(right),0));
+
+ rFalseIfx.condition ^= 1;
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
+ }
+
+ emitpLabel(truelbl->key);
+
+ if(ifx) ifx->generated = 1;
+ return;
+ }
+
+
+ lit++;
+ DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
+ i = (lit >> (size*8)) & 0xff;
+
+ emitpcode(POC_MOVLW, popGetLit(i));
+ emitpcode(POC_SUBFW, popGet(AOP(right),size));
+
+ while(size--) {
+ i = (lit >> (size*8)) & 0xff;
+
+ if(i) {
+ emitpcode(POC_MOVLW, popGetLit(i));
+ emitSKPNZ;
+ emitpcode(POC_SUBFW, popGet(AOP(right),size));
+ } else {
+ /* this byte of the lit is zero,
+ *if it's not the last then OR in the variable */
+ if(size)
+ emitpcode(POC_IORFW, popGet(AOP(right),size));
+ }
+ }
+
- // compare remaining bytes (treat as unsigned case from above)
- templbl = newiTempLabel ( NULL );
- offs = size;
- while (offs--) {
- //DEBUGpc ("comparing bytes at offset %d", offs);
- emitSKPZ;
- emitpcode (POC_GOTO, popGetLabel (templbl->key));
- pic14_mov2w_regOrLit (AOP(right), lit, offs);
- emitpcode (POC_SUBFW, popGet (AOP(left), offs));
- } // while (offs)
- emitpLabel (templbl->key);
- goto result_in_carry;
+ emitpLabel(lbl->key);
-result_in_carry:
-
- /****************************************************
- * now CARRY contains the result of the comparison: *
- * SUBWF sets CARRY iff *
- * F-W >= 0 <==> F >= W <==> !(F < W) *
- * (F=left, W=right) *
- ****************************************************/
+ rFalseIfx.condition ^= 1;
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
+ }
+
+ if(sign)
+ emitpLabel(truelbl->key);
+ if(ifx) ifx->generated = 1;
+ return;
+ }
+ }
+ /* Compare two variables */
+
+ DEBUGpic14_emitcode(";sign","%d",sign);
+
+ size--;
+ if(sign) {
+ /* Sigh. thus sucks... */
+ if(size) {
+ emitpcode(POC_MOVFW, popGet(AOP(left),size));
+ emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
+ emitpcode(POC_MOVLW, popGetLit(0x80));
+ emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
+ emitpcode(POC_XORFW, popGet(AOP(right),size));
+ emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
+ } else {
+ /* Signed char comparison */
+ /* Special thanks to Nikolai Golovchenko for this snippet */
+ emitpcode(POC_MOVFW, popGet(AOP(right),0));
+ emitpcode(POC_SUBFW, popGet(AOP(left),0));
+ emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
+ emitpcode(POC_XORFW, popGet(AOP(left),0));
+ emitpcode(POC_XORFW, popGet(AOP(right),0));
+ emitpcode(POC_ADDLW, popGetLit(0x80));
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
+
+ if(ifx) ifx->generated = 1;
+ return;
+ }
- if (performedLt) {
- invert_result = 1;
- // value will be used in the following genSkipc()
- rIfx.condition ^= 1;
- } // if
+ } else {
-correct_result_in_carry:
+ emitpcode(POC_MOVFW, popGet(AOP(right),size));
+ emitpcode(POC_SUBFW, popGet(AOP(left),size));
+ }
- // assign result to variable (if neccessary)
- if (result && AOP_TYPE(result) != AOP_CRY) {
- //DEBUGpc ("assign result");
- size = AOP_SIZE(result);
- while (size--) {
- emitpcode (POC_CLRF, popGet (AOP(result), size));
- } // while
- if (invert_result) {
- emitSKPC;
- emitpcode (POC_BSF, newpCodeOpBit (aopGet (AOP(result), 0, FALSE, FALSE), 0, 0));
- } else {
- emitpcode (POC_RLF, popGet (AOP(result), 0));
- }
- } // if (result)
- // perform conditional jump
- if (ifx) {
- //DEBUGpc ("generate control flow");
- genSkipc (&rIfx);
- ifx->generated = 1;
- } // if
-}
+ /* The rest of the bytes of a multi-byte compare */
+ while (size) {
+ emitSKPZ;
+ emitpcode(POC_GOTO, popGetLabel(lbl->key));
+ size--;
-#if 0
-/* OLD VERSION -- BUGGY, DO NOT USE */
+ emitpcode(POC_MOVFW, popGet(AOP(right),size));
+ emitpcode(POC_SUBFW, popGet(AOP(left),size));
-/*-----------------------------------------------------------------*/
-/* genCmp :- greater or less than comparison */
-/*-----------------------------------------------------------------*/
-static void genCmp (operand *left,operand *right,
- operand *result, iCode *ifx, int sign)
-{
- int size; //, offset = 0 ;
- unsigned long lit = 0L,i = 0;
- resolvedIfx rFalseIfx;
- // resolvedIfx rTrueIfx;
- symbol *truelbl;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- /*
- if(ifx) {
- DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
- DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
- }
- */
-
- resolveIfx(&rFalseIfx,ifx);
- truelbl = newiTempLabel(NULL);
- size = max(AOP_SIZE(left),AOP_SIZE(right));
-
- DEBUGpic14_AopType(__LINE__,left,right,result);
-
-#define _swapp
-
- /* if literal is on the right then swap with left */
- if ((AOP_TYPE(right) == AOP_LIT)) {
- operand *tmp = right ;
- unsigned long mask = (0x100 << (8*(size-1))) - 1;
- lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
-#ifdef _swapp
-
- lit = (lit - 1) & mask;
- right = left;
- left = tmp;
- rFalseIfx.condition ^= 1;
-#endif
-
- } else if ((AOP_TYPE(left) == AOP_LIT)) {
- lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
- }
-
-
- //if(IC_TRUE(ifx) == NULL)
- /* if left & right are bit variables */
- if (AOP_TYPE(left) == AOP_CRY &&
- AOP_TYPE(right) == AOP_CRY ) {
- pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
- pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
- } else {
- /* subtract right from left if at the
- end the carry flag is set then we know that
- left is greater than right */
-
- symbol *lbl = newiTempLabel(NULL);
-
-#ifndef _swapp
- if(AOP_TYPE(right) == AOP_LIT) {
-
- //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
-
- DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
-
- /* special cases */
-
- if(lit == 0) {
-
- if(sign != 0)
- genSkipCond(&rFalseIfx,left,size-1,7);
- else
- /* no need to compare to 0...*/
- /* NOTE: this is a de-generate compare that most certainly
- * creates some dead code. */
- emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
-
- if(ifx) ifx->generated = 1;
- return;
-
- }
- size--;
-
- if(size == 0) {
- //i = (lit >> (size*8)) & 0xff;
- DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
-
- emitpcode(POC_MOVFW, popGet(AOP(left),size));
-
- i = ((0-lit) & 0xff);
- if(sign) {
- if( i == 0x81) {
- /* lit is 0x7f, all signed chars are less than
- * this except for 0x7f itself */
- emitpcode(POC_XORLW, popGetLit(0x7f));
- genSkipz2(&rFalseIfx,0);
- } else {
- emitpcode(POC_ADDLW, popGetLit(0x80));
- emitpcode(POC_ADDLW, popGetLit(i^0x80));
- genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
- }
-
- } else {
- if(lit == 1) {
- genSkipz2(&rFalseIfx,1);
- } else {
- emitpcode(POC_ADDLW, popGetLit(i));
- genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
- }
- }
-
- if(ifx) ifx->generated = 1;
- return;
- }
-
- /* chars are out of the way. now do ints and longs */
-
-
- DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
-
- /* special cases */
-
- if(sign) {
-
- if(lit == 0) {
- genSkipCond(&rFalseIfx,left,size,7);
- if(ifx) ifx->generated = 1;
- return;
- }
-
- if(lit <0x100) {
- DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
-
- //rFalseIfx.condition ^= 1;
- //genSkipCond(&rFalseIfx,left,size,7);
- //rFalseIfx.condition ^= 1;
-
- emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
- if(rFalseIfx.condition)
- emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
- else
- emitpcode(POC_GOTO, popGetLabel(truelbl->key));
-
- emitpcode(POC_MOVLW, popGetLit(0x100-lit));
- emitpcode(POC_ADDFW, popGet(AOP(left),0));
- emitpcode(POC_MOVFW, popGet(AOP(left),1));
-
- while(size > 1)
- emitpcode(POC_IORFW, popGet(AOP(left),size--));
-
- if(rFalseIfx.condition) {
- emitSKPZ;
- emitpcode(POC_GOTO, popGetLabel(truelbl->key));
-
- } else {
- emitSKPNZ;
- }
-
- genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
- emitpLabel(truelbl->key);
- if(ifx) ifx->generated = 1;
- return;
-
- }
-
- if(size == 1) {
-
- if( (lit & 0xff) == 0) {
- /* lower byte is zero */
- DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
- i = ((lit >> 8) & 0xff) ^0x80;
- emitpcode(POC_MOVFW, popGet(AOP(left),size));
- emitpcode(POC_ADDLW, popGetLit( 0x80));
- emitpcode(POC_ADDLW, popGetLit(0x100-i));
- genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
-
-
- if(ifx) ifx->generated = 1;
- return;
-
- }
- } else {
- /* Special cases for signed longs */
- if( (lit & 0xffffff) == 0) {
- /* lower byte is zero */
- DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
- i = ((lit >> 8*3) & 0xff) ^0x80;
- emitpcode(POC_MOVFW, popGet(AOP(left),size));
- emitpcode(POC_ADDLW, popGetLit( 0x80));
- emitpcode(POC_ADDLW, popGetLit(0x100-i));
- genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
-
-
- if(ifx) ifx->generated = 1;
- return;
-
- }
-
- }
-
-
- if(lit & (0x80 << (size*8))) {
- /* lit is negative */
- DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
-
- //genSkipCond(&rFalseIfx,left,size,7);
-
- emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
-
- if(rFalseIfx.condition)
- emitpcode(POC_GOTO, popGetLabel(truelbl->key));
- else
- emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
-
-
- } else {
- /* lit is positive */
- DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
- emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
- if(rFalseIfx.condition)
- emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
- else
- emitpcode(POC_GOTO, popGetLabel(truelbl->key));
-
- }
-
- /* There are no more special cases, so perform a general compare */
-
- emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
- emitpcode(POC_SUBFW, popGet(AOP(left),size));
-
- while(size--) {
-
- emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
- emitSKPNZ;
- emitpcode(POC_SUBFW, popGet(AOP(left),size));
- }
- //rFalseIfx.condition ^= 1;
- genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
-
- emitpLabel(truelbl->key);
-
- if(ifx) ifx->generated = 1;
- return;
-
-
- }
-
-
- /* sign is out of the way. So now do an unsigned compare */
- DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
-
-
- /* General case - compare to an unsigned literal on the right.*/
-
- i = (lit >> (size*8)) & 0xff;
- emitpcode(POC_MOVLW, popGetLit(i));
- emitpcode(POC_SUBFW, popGet(AOP(left),size));
- while(size--) {
- i = (lit >> (size*8)) & 0xff;
-
- if(i) {
- emitpcode(POC_MOVLW, popGetLit(i));
- emitSKPNZ;
- emitpcode(POC_SUBFW, popGet(AOP(left),size));
- } else {
- /* this byte of the lit is zero,
- *if it's not the last then OR in the variable */
- if(size)
- emitpcode(POC_IORFW, popGet(AOP(left),size));
- }
- }
-
-
- emitpLabel(lbl->key);
- //if(emitFinalCheck)
- genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
- if(sign)
- emitpLabel(truelbl->key);
-
- if(ifx) ifx->generated = 1;
- return;
-
-
- }
-#endif // _swapp
- if(AOP_TYPE(left) == AOP_LIT) {
- //symbol *lbl = newiTempLabel(NULL);
-
- //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
-
-
- DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
-
- /* Special cases */
- if((lit == 0) && (sign == 0)){
-
- size--;
- emitpcode(POC_MOVFW, popGet(AOP(right),size));
- while(size)
- emitpcode(POC_IORFW, popGet(AOP(right),--size));
-
- genSkipz2(&rFalseIfx,0);
- if(ifx) ifx->generated = 1;
- return;
- }
-
- if(size==1) {
- /* Special cases */
- lit &= 0xff;
- if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
- /* degenerate compare can never be true */
- if(rFalseIfx.condition == 0)
- emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
-
- if(ifx) ifx->generated = 1;
- return;
- }
-
- if(sign) {
- /* signed comparisons to a literal byte */
-
- int lp1 = (lit+1) & 0xff;
-
- DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
- switch (lp1) {
- case 0:
- rFalseIfx.condition ^= 1;
- genSkipCond(&rFalseIfx,right,0,7);
- break;
- case 0x7f:
- emitpcode(POC_MOVFW, popGet(AOP(right),0));
- emitpcode(POC_XORLW, popGetLit(0x7f));
- genSkipz2(&rFalseIfx,1);
- break;
- default:
- emitpcode(POC_MOVFW, popGet(AOP(right),0));
- emitpcode(POC_ADDLW, popGetLit(0x80));
- emitpcode(POC_ADDLW, popGetLit(((0-(lit+1)) & 0xff) ^ 0x80));
- rFalseIfx.condition ^= 1;
- genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
- break;
- }
- if(ifx) ifx->generated = 1;
- } else {
- /* unsigned comparisons to a literal byte */
-
- switch(lit & 0xff ) {
- case 0:
- emitpcode(POC_MOVFW, popGet(AOP(right),0));
- genSkipz2(&rFalseIfx,0);
- if(ifx) ifx->generated = 1;
- break;
- case 0x7f:
- genSkipCond(&rFalseIfx,right,0,7);
- if(ifx) ifx->generated = 1;
- break;
-
- default:
- emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
- emitpcode(POC_SUBFW, popGet(AOP(right),0));
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- rFalseIfx.condition ^= 1;
- if (AOP_TYPE(result) == AOP_CRY) {
- genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
- if(ifx) ifx->generated = 1;
- } else {
- DEBUGpic14_emitcode ("; ***","%s %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
- emitpcode(POC_CLRF, popGet(AOP(result),0));
- emitpcode(POC_RLF, popGet(AOP(result),0));
- emitpcode(POC_MOVLW, popGetLit(0x01));
- emitpcode(POC_XORWF, popGet(AOP(result),0));
- }
- break;
- }
- }
-
- //goto check_carry;
- return;
-
- } else {
-
- /* Size is greater than 1 */
-
- if(sign) {
- int lp1 = lit+1;
-
- size--;
-
- if(lp1 == 0) {
- /* this means lit = 0xffffffff, or -1 */
-
-
- DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
- rFalseIfx.condition ^= 1;
- genSkipCond(&rFalseIfx,right,size,7);
- if(ifx) ifx->generated = 1;
- return;
- }
-
- if(lit == 0) {
- int s = size;
-
- if(rFalseIfx.condition) {
- emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
- emitpcode(POC_GOTO, popGetLabel(truelbl->key));
- }
-
- emitpcode(POC_MOVFW, popGet(AOP(right),size));
- while(size--)
- emitpcode(POC_IORFW, popGet(AOP(right),size));
-
-
- emitSKPZ;
- if(rFalseIfx.condition) {
- emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
- emitpLabel(truelbl->key);
- }else {
- rFalseIfx.condition ^= 1;
- genSkipCond(&rFalseIfx,right,s,7);
- }
-
- if(ifx) ifx->generated = 1;
- return;
- }
-
- if((size == 1) && (0 == (lp1&0xff))) {
- /* lower byte of signed word is zero */
- DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
- i = ((lp1 >> 8) & 0xff) ^0x80;
- emitpcode(POC_MOVFW, popGet(AOP(right),size));
- emitpcode(POC_ADDLW, popGetLit( 0x80));
- emitpcode(POC_ADDLW, popGetLit(0x100-i));
- rFalseIfx.condition ^= 1;
- genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
-
-
- if(ifx) ifx->generated = 1;
- return;
- }
-
- if(lit & (0x80 << (size*8))) {
- /* Lit is less than zero */
- DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
- //rFalseIfx.condition ^= 1;
- //genSkipCond(&rFalseIfx,left,size,7);
- //rFalseIfx.condition ^= 1;
- emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
- //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
-
- if(rFalseIfx.condition)
- emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
- else
- emitpcode(POC_GOTO, popGetLabel(truelbl->key));
-
-
- } else {
- /* Lit is greater than or equal to zero */
- DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
- //rFalseIfx.condition ^= 1;
- //genSkipCond(&rFalseIfx,right,size,7);
- //rFalseIfx.condition ^= 1;
-
- //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
- //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
-
- emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
- if(rFalseIfx.condition)
- emitpcode(POC_GOTO, popGetLabel(truelbl->key));
- else
- emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
-
- }
-
-
- emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
- emitpcode(POC_SUBFW, popGet(AOP(right),size));
-
- while(size--) {
-
- emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
- emitSKPNZ;
- emitpcode(POC_SUBFW, popGet(AOP(right),size));
- }
- rFalseIfx.condition ^= 1;
- //rFalseIfx.condition = 1;
- genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
-
- emitpLabel(truelbl->key);
-
- if(ifx) ifx->generated = 1;
- return;
- // end of if (sign)
- } else {
-
- /* compare word or long to an unsigned literal on the right.*/
-
-
- size--;
- if(lit < 0xff) {
- DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
- switch (lit) {
- case 0:
- break; /* handled above */
- /*
- case 0xff:
- emitpcode(POC_MOVFW, popGet(AOP(right),size));
- while(size--)
- emitpcode(POC_IORFW, popGet(AOP(right),size));
- genSkipz2(&rFalseIfx,0);
- break;
- */
- default:
- emitpcode(POC_MOVFW, popGet(AOP(right),size));
- while(--size)
- emitpcode(POC_IORFW, popGet(AOP(right),size));
-
- emitSKPZ;
- if(rFalseIfx.condition)
- emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
- else
- emitpcode(POC_GOTO, popGetLabel(truelbl->key));
-
-
- emitpcode(POC_MOVLW, popGetLit(lit+1));
- emitpcode(POC_SUBFW, popGet(AOP(right),0));
-
- rFalseIfx.condition ^= 1;
- genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
- }
-
- emitpLabel(truelbl->key);
-
- if(ifx) ifx->generated = 1;
- return;
- }
-
-
- lit++;
- DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
- i = (lit >> (size*8)) & 0xff;
-
- emitpcode(POC_MOVLW, popGetLit(i));
- emitpcode(POC_SUBFW, popGet(AOP(right),size));
-
- while(size--) {
- i = (lit >> (size*8)) & 0xff;
-
- if(i) {
- emitpcode(POC_MOVLW, popGetLit(i));
- emitSKPNZ;
- emitpcode(POC_SUBFW, popGet(AOP(right),size));
- } else {
- /* this byte of the lit is zero,
- *if it's not the last then OR in the variable */
- if(size)
- emitpcode(POC_IORFW, popGet(AOP(right),size));
- }
- }
-
-
- emitpLabel(lbl->key);
-
- rFalseIfx.condition ^= 1;
- genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
- }
-
- if(sign)
- emitpLabel(truelbl->key);
- if(ifx) ifx->generated = 1;
- return;
- }
- }
- /* Compare two variables */
-
- DEBUGpic14_emitcode(";sign","%d",sign);
-
- size--;
- if(sign) {
- /* Sigh. thus sucks... */
- if(size) {
- emitpcode(POC_MOVFW, popGet(AOP(left),size));
- emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
- emitpcode(POC_MOVLW, popGetLit(0x80));
- emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
- emitpcode(POC_XORFW, popGet(AOP(right),size));
- emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
- } else {
- /* Signed char comparison */
- /* Special thanks to Nikolai Golovchenko for this snippet */
- emitpcode(POC_MOVFW, popGet(AOP(right),0));
- emitpcode(POC_SUBFW, popGet(AOP(left),0));
- emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
- emitpcode(POC_XORFW, popGet(AOP(left),0));
- emitpcode(POC_XORFW, popGet(AOP(right),0));
- emitpcode(POC_ADDLW, popGetLit(0x80));
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
-
- if(ifx) ifx->generated = 1;
- return;
- }
-
- } else {
-
- emitpcode(POC_MOVFW, popGet(AOP(right),size));
- emitpcode(POC_SUBFW, popGet(AOP(left),size));
- }
-
-
- /* The rest of the bytes of a multi-byte compare */
- while (size) {
-
- emitSKPZ;
- emitpcode(POC_GOTO, popGetLabel(lbl->key));
- size--;
-
- emitpcode(POC_MOVFW, popGet(AOP(right),size));
- emitpcode(POC_SUBFW, popGet(AOP(left),size));
-
-
- }
-
- emitpLabel(lbl->key);
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
- (AOP_TYPE(result) == AOP_REG)) {
- emitpcode(POC_CLRF, popGet(AOP(result),0));
- emitpcode(POC_RLF, popGet(AOP(result),0));
- } else {
- genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
- }
- //genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
- if(ifx) ifx->generated = 1;
-
- return;
-
- }
-
- // check_carry:
- if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- pic14_outBitC(result);
- } else {
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- /* if the result is used in the next
- ifx conditional branch then generate
- code a little differently */
- if (ifx )
- genIfxJump (ifx,"c");
- else
- pic14_outBitC(result);
- /* leave the result in acc */
- }
-
+ }
+
+ emitpLabel(lbl->key);
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
+ (AOP_TYPE(result) == AOP_REG)) {
+ emitpcode(POC_CLRF, popGet(AOP(result),0));
+ emitpcode(POC_RLF, popGet(AOP(result),0));
+ } else {
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
+ }
+ //genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
+ if(ifx) ifx->generated = 1;
+
+ return;
+
+ }
+
+ // check_carry:
+ if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ pic14_outBitC(result);
+ } else {
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* if the result is used in the next
+ ifx conditional branch then generate
+ code a little differently */
+ if (ifx )
+ genIfxJump (ifx,"c");
+ else
+ pic14_outBitC(result);
+ /* leave the result in acc */
+ }
+
}
#endif
/*-----------------------------------------------------------------*/
static void genCmpGt (iCode *ic, iCode *ifx)
{
- operand *left, *right, *result;
- sym_link *letype , *retype;
- int sign ;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- left = IC_LEFT(ic);
- right= IC_RIGHT(ic);
- result = IC_RESULT(ic);
-
- letype = getSpec(operandType(left));
- retype =getSpec(operandType(right));
- sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
- /* assign the amsops */
- aopOp (left,ic,FALSE);
- aopOp (right,ic,FALSE);
- aopOp (result,ic,TRUE);
-
- genCmp(right, left, result, ifx, sign);
-
- freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- freeAsmop(result,NULL,ic,TRUE);
+ operand *left, *right, *result;
+ sym_link *letype , *retype;
+ int sign ;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ left = IC_LEFT(ic);
+ right= IC_RIGHT(ic);
+ result = IC_RESULT(ic);
+
+ letype = getSpec(operandType(left));
+ retype =getSpec(operandType(right));
+ sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
+ /* assign the amsops */
+ aopOp (left,ic,FALSE);
+ aopOp (right,ic,FALSE);
+ aopOp (result,ic,TRUE);
+
+ genCmp(right, left, result, ifx, sign);
+
+ freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(result,NULL,ic,TRUE);
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static void genCmpLt (iCode *ic, iCode *ifx)
{
- operand *left, *right, *result;
- sym_link *letype , *retype;
- int sign ;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- left = IC_LEFT(ic);
- right= IC_RIGHT(ic);
- result = IC_RESULT(ic);
-
- letype = getSpec(operandType(left));
- retype =getSpec(operandType(right));
- sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
-
- /* assign the amsops */
- aopOp (left,ic,FALSE);
- aopOp (right,ic,FALSE);
- aopOp (result,ic,TRUE);
-
- genCmp(left, right, result, ifx, sign);
-
- freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- freeAsmop(result,NULL,ic,TRUE);
+ operand *left, *right, *result;
+ sym_link *letype , *retype;
+ int sign ;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ left = IC_LEFT(ic);
+ right= IC_RIGHT(ic);
+ result = IC_RESULT(ic);
+
+ letype = getSpec(operandType(left));
+ retype =getSpec(operandType(right));
+ sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
+
+ /* assign the amsops */
+ aopOp (left,ic,FALSE);
+ aopOp (right,ic,FALSE);
+ aopOp (result,ic,TRUE);
+
+ genCmp(left, right, result, ifx, sign);
+
+ freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(result,NULL,ic,TRUE);
}
#if 0
/*-----------------------------------------------------------------*/
static void genc16bit2lit(operand *op, int lit, int offset)
{
- int i;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
- if( (lit&0xff) == 0)
- i=1;
- else
- i=0;
-
- switch( BYTEofLONG(lit,i)) {
- case 0:
- emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
- break;
- case 1:
- emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
- break;
- case 0xff:
- emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
- break;
- default:
- emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
- emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
- }
-
- i ^= 1;
-
- switch( BYTEofLONG(lit,i)) {
- case 0:
- emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
- break;
- case 1:
- emitSKPNZ;
- emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
- break;
- case 0xff:
- emitSKPNZ;
- emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
- break;
- default:
- emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
- emitSKPNZ;
- emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
-
- }
-
+ int i;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
+ if( (lit&0xff) == 0)
+ i=1;
+ else
+ i=0;
+
+ switch( BYTEofLONG(lit,i)) {
+ case 0:
+ emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
+ break;
+ case 1:
+ emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
+ break;
+ case 0xff:
+ emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
+ break;
+ default:
+ emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
+ emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
+ }
+
+ i ^= 1;
+
+ switch( BYTEofLONG(lit,i)) {
+ case 0:
+ emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
+ break;
+ case 1:
+ emitSKPNZ;
+ emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
+ break;
+ case 0xff:
+ emitSKPNZ;
+ emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
+ break;
+ default:
+ emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
+ emitSKPNZ;
+ emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
+
+ }
+
}
#endif
/*-----------------------------------------------------------------*/
static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
{
- int size = min(AOP_SIZE(left),AOP_SIZE(right));
- int offset = 0;
- //resolvedIfx rIfx;
- symbol *lbl;
-
- //unsigned long lit = 0L;
- FENTRY;
- if (!ifx && (!result || AOP_TYPE(result) == AOP_CRY)) {
- emitpComment ("gencjne: no ifx, no (real) result -- comparison ignored");
- return;
- }
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- DEBUGpic14_AopType(__LINE__,left,right,result);
-
- assert (!pic14_sameRegs (AOP(left), AOP(result)));
- assert (!pic14_sameRegs (AOP(right), AOP(result)));
- if (AOP_SIZE(result)) {
- for (offset = 0; offset < AOP_SIZE(result); offset++)
- emitpcode (POC_CLRF, popGet (AOP(result), offset));
- }
-
- assert (AOP_SIZE(left) == AOP_SIZE(right));
- //resolveIfx(&rIfx,ifx);
- lbl = newiTempLabel (NULL);
- while (size--)
- {
- mov2w (AOP(right),size);
- emitpcode (POC_XORFW, popGet (AOP(left), size));
- if (size)
- {
- emitSKPZ;
- emitpcode (POC_GOTO, popGetLabel (lbl->key));
- }
- } // while
- emitpLabel (lbl->key);
- if (AOP_SIZE(result)) {
- emitSKPNZ;
- emitpcode (POC_INCF, popGet (AOP(result), 0));
- } else {
- assert (ifx);
- genSkipz (ifx, NULL != IC_TRUE(ifx));
- ifx->generated = 1;
- }
- return;
-#if 0
- if(result)
- {
- DEBUGpic14_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
- assert (!pic14_sameRegs (AOP(result), AOP(left)));
- assert (!pic14_sameRegs (AOP(result), AOP(right)));
- for (offset=0; offset < AOP_SIZE(result); offset++)
- {
- emitpcode (POC_CLRF, popGet (AOP(result), offset));
- } // for offset
- }
-
-
- /* if the left side is a literal or
- if the right is in a pointer register and left
- is not */
- if ((AOP_TYPE(left) == AOP_LIT) ||
- (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
- operand *t = right;
- right = left;
- left = t;
- }
- if(AOP_TYPE(right) == AOP_LIT)
- lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
-
- /* if the right side is a literal then anything goes */
- if (AOP_TYPE(right) == AOP_LIT &&
- AOP_TYPE(left) != AOP_DIR ) {
- switch(size) {
- case 2:
- genc16bit2lit(left, lit, 0);
- emitSKPNZ;
- emitpcode(POC_GOTO,popGetLabel(lbl->key));
- break;
- default:
- offset = 0;
- while (size--) {
- if(lit & 0xff) {
- emitpcode(POC_MOVFW,popGet(AOP(left),offset));
- emitpcode(POC_XORLW,popGetLit(lit & 0xff));
- } else {
- emitpcode(POC_MOVF,popGet(AOP(left),offset));
- }
-
- emitSKPNZ;
- emitpcode(POC_GOTO,popGetLabel(lbl->key));
- offset++;
- lit >>= 8;
- }
- break;
- }
- }
-
- /* if the right side is in a register or in direct space or
- if the left is a pointer register & right is not */
- else if (AOP_TYPE(right) == AOP_REG ||
- AOP_TYPE(right) == AOP_DIR ||
- (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
- (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
- //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
- int lbl_key = lbl->key;
-
- if(!result) {
- DEBUGpic14_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
- fprintf(stderr, "%s %d error - expecting result to be non_null\n",
- __FUNCTION__,__LINE__);
- return;
- }
-
- /* switch(size) { */
- /* case 2: */
- /* genc16bit2lit(left, lit, 0); */
- /* emitSKPNZ; */
- /* emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
- /* break; */
- /* default: */
- offset = 0;
- while (size--) {
- int emit_skip=1;
- if((AOP_TYPE(left) == AOP_DIR) &&
- ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
-
- emitpcode(POC_MOVFW,popGet(AOP(left),offset));
- emitpcode(POC_XORFW,popGet(AOP(right),offset));
-
- } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
-
- switch (lit & 0xff) {
- case 0:
- emitpcode(POC_MOVFW,popGet(AOP(left),offset));
- break;
- case 1:
- emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
- //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
- emitpcode(POC_GOTO,popGetLabel(lbl->key));
- emit_skip=0;
- break;
- case 0xff:
- emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
- //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
- //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
- emitpcode(POC_GOTO,popGetLabel(lbl_key));
- emit_skip=0;
- break;
- default:
- emitpcode(POC_MOVFW,popGet(AOP(left),offset));
- emitpcode(POC_XORLW,popGetLit(lit & 0xff));
- }
- lit >>= 8;
-
- } else {
- emitpcode(POC_MOVF,popGet(AOP(left),offset));
- }
- if(emit_skip) {
- if(AOP_TYPE(result) == AOP_CRY) {
- pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
- if(rIfx.condition)
- emitSKPNZ;
- else
- emitSKPZ;
- emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
- } else {
- /* fix me. probably need to check result size too */
- //emitpcode(POC_CLRF,popGet(AOP(result),0));
- if(rIfx.condition)
- emitSKPZ;
- else
- emitSKPNZ;
- emitpcode(POC_GOTO,popGetLabel(lbl_key));
- }
- if(ifx)
- ifx->generated=1;
- }
- emit_skip++;
- offset++;
- }
- /* break; */
- /* } */
- } else if(AOP_TYPE(right) == AOP_REG &&
- AOP_TYPE(left) != AOP_DIR){
-
- offset = 0;
- while(size--) {
- emitpcode(POC_MOVFW,popGet(AOP(left),offset));
- emitpcode(POC_XORFW,popGet(AOP(right),offset));
- pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
- if(rIfx.condition)
- emitSKPNZ;
- else
- emitSKPZ;
- emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
- offset++;
- }
-
- }else{
- /* right is a pointer reg need both a & b */
- offset = 0;
- while(size--) {
- char *l = aopGet(AOP(left),offset,FALSE,FALSE);
- if(strcmp(l,"b"))
- pic14_emitcode("mov","b,%s",l);
- MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
- pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
- offset++;
- }
- }
-
- emitpcode(POC_INCF,popGet(AOP(result),0));
- if(!rIfx.condition)
- emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
-
- emitpLabel(lbl->key);
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- if(ifx)
- ifx->generated = 1;
+ int size = min(AOP_SIZE(left),AOP_SIZE(right));
+ int offset = 0;
+ //resolvedIfx rIfx;
+ symbol *lbl;
+
+ //unsigned long lit = 0L;
+ FENTRY;
+ if (!ifx && (!result || AOP_TYPE(result) == AOP_CRY)) {
+ emitpComment ("gencjne: no ifx, no (real) result -- comparison ignored");
+ return;
+ }
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ DEBUGpic14_AopType(__LINE__,left,right,result);
+
+ assert (!pic14_sameRegs (AOP(left), AOP(result)));
+ assert (!pic14_sameRegs (AOP(right), AOP(result)));
+ if (AOP_SIZE(result)) {
+ for (offset = 0; offset < AOP_SIZE(result); offset++)
+ emitpcode (POC_CLRF, popGet (AOP(result), offset));
+ }
+
+ assert (AOP_SIZE(left) == AOP_SIZE(right));
+ //resolveIfx(&rIfx,ifx);
+ lbl = newiTempLabel (NULL);
+ while (size--)
+ {
+ mov2w (AOP(right),size);
+ emitpcode (POC_XORFW, popGet (AOP(left), size));
+ if (size)
+ {
+ emitSKPZ;
+ emitpcode (POC_GOTO, popGetLabel (lbl->key));
+ }
+ } // while
+ emitpLabel (lbl->key);
+ if (AOP_SIZE(result)) {
+ emitSKPNZ;
+ emitpcode (POC_INCF, popGet (AOP(result), 0));
+ } else {
+ assert (ifx);
+ genSkipz (ifx, NULL != IC_TRUE(ifx));
+ ifx->generated = 1;
+ }
+ return;
+#if 0
+ if(result)
+ {
+ DEBUGpic14_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
+ assert (!pic14_sameRegs (AOP(result), AOP(left)));
+ assert (!pic14_sameRegs (AOP(result), AOP(right)));
+ for (offset=0; offset < AOP_SIZE(result); offset++)
+ {
+ emitpcode (POC_CLRF, popGet (AOP(result), offset));
+ } // for offset
+ }
+
+
+ /* if the left side is a literal or
+ if the right is in a pointer register and left
+ is not */
+ if ((AOP_TYPE(left) == AOP_LIT) ||
+ (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
+ operand *t = right;
+ right = left;
+ left = t;
+ }
+ if(AOP_TYPE(right) == AOP_LIT)
+ lit = ulFromVal(AOP(right)->aopu.aop_lit);
+
+ /* if the right side is a literal then anything goes */
+ if (AOP_TYPE(right) == AOP_LIT &&
+ AOP_TYPE(left) != AOP_DIR ) {
+ switch(size) {
+ case 2:
+ genc16bit2lit(left, lit, 0);
+ emitSKPNZ;
+ emitpcode(POC_GOTO,popGetLabel(lbl->key));
+ break;
+ default:
+ offset = 0;
+ while (size--) {
+ if(lit & 0xff) {
+ emitpcode(POC_MOVFW,popGet(AOP(left),offset));
+ emitpcode(POC_XORLW,popGetLit(lit & 0xff));
+ } else {
+ emitpcode(POC_MOVF,popGet(AOP(left),offset));
+ }
+
+ emitSKPNZ;
+ emitpcode(POC_GOTO,popGetLabel(lbl->key));
+ offset++;
+ lit >>= 8;
+ }
+ break;
+ }
+ }
+
+ /* if the right side is in a register or in direct space or
+ if the left is a pointer register & right is not */
+ else if (AOP_TYPE(right) == AOP_REG ||
+ AOP_TYPE(right) == AOP_DIR ||
+ (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
+ (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
+ //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
+ int lbl_key = lbl->key;
+
+ if(!result) {
+ DEBUGpic14_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
+ fprintf(stderr, "%s %d error - expecting result to be non_null\n",
+ __FUNCTION__,__LINE__);
+ return;
+ }
+
+ /* switch(size) { */
+ /* case 2: */
+ /* genc16bit2lit(left, lit, 0); */
+ /* emitSKPNZ; */
+ /* emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
+ /* break; */
+ /* default: */
+ offset = 0;
+ while (size--) {
+ int emit_skip=1;
+ if((AOP_TYPE(left) == AOP_DIR) &&
+ ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
+
+ emitpcode(POC_MOVFW,popGet(AOP(left),offset));
+ emitpcode(POC_XORFW,popGet(AOP(right),offset));
+
+ } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
+
+ switch (lit & 0xff) {
+ case 0:
+ emitpcode(POC_MOVFW,popGet(AOP(left),offset));
+ break;
+ case 1:
+ emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
+ //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
+ emitpcode(POC_GOTO,popGetLabel(lbl->key));
+ emit_skip=0;
+ break;
+ case 0xff:
+ emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
+ //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
+ //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
+ emitpcode(POC_GOTO,popGetLabel(lbl_key));
+ emit_skip=0;
+ break;
+ default:
+ emitpcode(POC_MOVFW,popGet(AOP(left),offset));
+ emitpcode(POC_XORLW,popGetLit(lit & 0xff));
+ }
+ lit >>= 8;
+
+ } else {
+ emitpcode(POC_MOVF,popGet(AOP(left),offset));
+ }
+ if(emit_skip) {
+ if(AOP_TYPE(result) == AOP_CRY) {
+ pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
+ if(rIfx.condition)
+ emitSKPNZ;
+ else
+ emitSKPZ;
+ emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
+ } else {
+ /* fix me. probably need to check result size too */
+ //emitpcode(POC_CLRF,popGet(AOP(result),0));
+ if(rIfx.condition)
+ emitSKPZ;
+ else
+ emitSKPNZ;
+ emitpcode(POC_GOTO,popGetLabel(lbl_key));
+ }
+ if(ifx)
+ ifx->generated=1;
+ }
+ emit_skip++;
+ offset++;
+ }
+ /* break; */
+ /* } */
+ } else if(AOP_TYPE(right) == AOP_REG &&
+ AOP_TYPE(left) != AOP_DIR){
+
+ offset = 0;
+ while(size--) {
+ emitpcode(POC_MOVFW,popGet(AOP(left),offset));
+ emitpcode(POC_XORFW,popGet(AOP(right),offset));
+ pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
+ if(rIfx.condition)
+ emitSKPNZ;
+ else
+ emitSKPZ;
+ emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
+ offset++;
+ }
+
+ }else{
+ /* right is a pointer reg need both a & b */
+ offset = 0;
+ while(size--) {
+ char *l = aopGet(AOP(left),offset,FALSE,FALSE);
+ if(strcmp(l,"b"))
+ pic14_emitcode("mov","b,%s",l);
+ MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
+ pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
+ offset++;
+ }
+ }
+
+ emitpcode(POC_INCF,popGet(AOP(result),0));
+ if(!rIfx.condition)
+ emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
+
+ emitpLabel(lbl->key);
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ if(ifx)
+ ifx->generated = 1;
#endif
}
#endif
/*-----------------------------------------------------------------*/
static void gencjne(operand *left, operand *right, iCode *ifx)
{
- symbol *tlbl = newiTempLabel(NULL);
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- gencjneshort(left, right, lbl);
-
- pic14_emitcode("mov","a,%s",one);
- pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
- pic14_emitcode("","%05d_DS_:",lbl->key+100);
- pic14_emitcode("clr","a");
- pic14_emitcode("","%05d_DS_:",tlbl->key+100);
-
- emitpLabel(lbl->key);
- emitpLabel(tlbl->key);
-
+ symbol *tlbl = newiTempLabel(NULL);
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ gencjneshort(left, right, lbl);
+
+ pic14_emitcode("mov","a,%s",one);
+ pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
+ pic14_emitcode("","%05d_DS_:",lbl->key+100);
+ pic14_emitcode("clr","a");
+ pic14_emitcode("","%05d_DS_:",tlbl->key+100);
+
+ emitpLabel(lbl->key);
+ emitpLabel(tlbl->key);
+
}
#endif
DEBUGpic14_AopType(__LINE__,left,right,result);
- /* if literal, move literal to right */
+ /* if literal, move literal to right */
if (op_isLitLike (IC_LEFT(ic))) {
operand *tmp = right ;
right = left;
if (AOP_TYPE(right) == AOP_LIT)
{
- unsigned long lit = (unsigned long) floatFromVal (AOP(right)->aopu.aop_lit);
+ unsigned long lit = ulFromVal (AOP(right)->aopu.aop_lit);
int i;
size = AOP_SIZE(left);
assert(!op_isLitLike(left));
{
case 0:
mov2w(AOP(left), 0);
- for (i=1; i < size; i++)
- emitpcode(POC_IORFW,popGet(AOP(left),i));
- /* now Z is set iff `left == right' */
- emitSKPZ;
- if (!false_label) false_label = newiTempLabel(NULL);
- emitpcode(POC_GOTO, popGetLabel(false_label->key));
- break;
+ for (i=1; i < size; i++)
+ emitpcode(POC_IORFW,popGet(AOP(left),i));
+ /* now Z is set iff `left == right' */
+ emitSKPZ;
+ if (!false_label) false_label = newiTempLabel(NULL);
+ emitpcode(POC_GOTO, popGetLabel(false_label->key));
+ break;
default:
- for (i=0; i < size; i++)
- {
- mov2w(AOP(left),i);
- emitpcode(POC_XORLW, popGetLit(lit >> (8*i)));
- /* now Z is cleared if `left != right' */
- emitSKPZ;
- if (!false_label) false_label = newiTempLabel(NULL);
- emitpcode(POC_GOTO, popGetLabel(false_label->key));
- } // for i
- break;
+ for (i=0; i < size; i++)
+ {
+ mov2w(AOP(left),i);
+ emitpcode(POC_XORLW, popGetLit(lit >> (8*i)));
+ /* now Z is cleared if `left != right' */
+ emitSKPZ;
+ if (!false_label) false_label = newiTempLabel(NULL);
+ emitpcode(POC_GOTO, popGetLabel(false_label->key));
+ } // for i
+ break;
} // switch (lit)
}
else
/*-----------------------------------------------------------------*/
static iCode *ifxForOp ( operand *op, iCode *ic )
{
- FENTRY;
- /* if true symbol then needs to be assigned */
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if (IS_TRUE_SYMOP(op))
- return NULL ;
-
- /* if this has register type condition and
- the next instruction is ifx with the same operand
- and live to of the operand is upto the ifx only then */
- if (ic->next &&
- ic->next->op == IFX &&
- IC_COND(ic->next)->key == op->key &&
- OP_SYMBOL(op)->liveTo <= ic->next->seq )
- return ic->next;
-
- if (ic->next &&
- ic->next->op == IFX &&
- IC_COND(ic->next)->key == op->key) {
- DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
- return ic->next;
- }
-
- DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
- if (ic->next &&
- ic->next->op == IFX)
- DEBUGpic14_emitcode ("; ic-next"," is an IFX");
-
- if (ic->next &&
- ic->next->op == IFX &&
- IC_COND(ic->next)->key == op->key) {
- DEBUGpic14_emitcode ("; "," key is okay");
- DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
- OP_SYMBOL(op)->liveTo,
- ic->next->seq);
- }
-
-
- return NULL;
+ FENTRY;
+ /* if true symbol then needs to be assigned */
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ if (IS_TRUE_SYMOP(op))
+ return NULL ;
+
+ /* if this has register type condition and
+ the next instruction is ifx with the same operand
+ and live to of the operand is upto the ifx only then */
+ if (ic->next &&
+ ic->next->op == IFX &&
+ IC_COND(ic->next)->key == op->key &&
+ OP_SYMBOL(op)->liveTo <= ic->next->seq )
+ return ic->next;
+
+ if (ic->next &&
+ ic->next->op == IFX &&
+ IC_COND(ic->next)->key == op->key) {
+ DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
+ return ic->next;
+ }
+
+ DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
+ if (ic->next &&
+ ic->next->op == IFX)
+ DEBUGpic14_emitcode ("; ic-next"," is an IFX");
+
+ if (ic->next &&
+ ic->next->op == IFX &&
+ IC_COND(ic->next)->key == op->key) {
+ DEBUGpic14_emitcode ("; "," key is okay");
+ DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
+ OP_SYMBOL(op)->liveTo,
+ ic->next->seq);
+ }
+
+
+ return NULL;
}
/*-----------------------------------------------------------------*/
/* genAndOp - for && operation */
/*-----------------------------------------------------------------*/
static void genAndOp (iCode *ic)
{
- operand *left,*right, *result;
- /* symbol *tlbl; */
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- /* note here that && operations that are in an
- if statement are taken away by backPatchLabels
- only those used in arthmetic operations remain */
- aopOp((left=IC_LEFT(ic)),ic,FALSE);
- aopOp((right=IC_RIGHT(ic)),ic,FALSE);
- aopOp((result=IC_RESULT(ic)),ic,FALSE);
-
- DEBUGpic14_AopType(__LINE__,left,right,result);
-
- emitpcode(POC_MOVFW,popGet(AOP(left),0));
- emitpcode(POC_ANDFW,popGet(AOP(right),0));
- emitpcode(POC_MOVWF,popGet(AOP(result),0));
-
- /* if both are bit variables */
- /* if (AOP_TYPE(left) == AOP_CRY && */
- /* AOP_TYPE(right) == AOP_CRY ) { */
- /* pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
- /* pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
- /* pic14_outBitC(result); */
- /* } else { */
- /* tlbl = newiTempLabel(NULL); */
- /* pic14_toBoolean(left); */
- /* pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
- /* pic14_toBoolean(right); */
- /* pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
- /* pic14_outBitAcc(result); */
- /* } */
-
- freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- freeAsmop(result,NULL,ic,TRUE);
+ operand *left,*right, *result;
+ /* symbol *tlbl; */
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* note here that && operations that are in an
+ if statement are taken away by backPatchLabels
+ only those used in arthmetic operations remain */
+ aopOp((left=IC_LEFT(ic)),ic,FALSE);
+ aopOp((right=IC_RIGHT(ic)),ic,FALSE);
+ aopOp((result=IC_RESULT(ic)),ic,FALSE);
+
+ DEBUGpic14_AopType(__LINE__,left,right,result);
+
+ emitpcode(POC_MOVFW,popGet(AOP(left),0));
+ emitpcode(POC_ANDFW,popGet(AOP(right),0));
+ emitpcode(POC_MOVWF,popGet(AOP(result),0));
+
+ /* if both are bit variables */
+ /* if (AOP_TYPE(left) == AOP_CRY && */
+ /* AOP_TYPE(right) == AOP_CRY ) { */
+ /* pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
+ /* pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
+ /* pic14_outBitC(result); */
+ /* } else { */
+ /* tlbl = newiTempLabel(NULL); */
+ /* pic14_toBoolean(left); */
+ /* pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
+ /* pic14_toBoolean(right); */
+ /* pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
+ /* pic14_outBitAcc(result); */
+ /* } */
+
+ freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(result,NULL,ic,TRUE);
}
static void genOrOp (iCode *ic)
{
- operand *left,*right, *result;
- symbol *tlbl;
- int i;
-
- /* note here that || operations that are in an
- if statement are taken away by backPatchLabels
- only those used in arthmetic operations remain */
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- aopOp((left=IC_LEFT(ic)),ic,FALSE);
- aopOp((right=IC_RIGHT(ic)),ic,FALSE);
- aopOp((result=IC_RESULT(ic)),ic,FALSE);
-
- DEBUGpic14_AopType(__LINE__,left,right,result);
-
- for (i=0; i < AOP_SIZE(result); i++)
- {
- emitpcode(POC_CLRF, popGet(AOP(result), i));
- } // for i
-
- tlbl = newiTempLabel(NULL);
- pic14_toBoolean(left);
- emitSKPZ;
- emitpcode(POC_GOTO, popGetLabel(tlbl->key));
- pic14_toBoolean(right);
- emitpLabel(tlbl->key);
- /* here Z is clear IFF `left || right' */
- emitSKPZ;
- emitpcode(POC_INCF, popGet(AOP(result), 0));
-
- freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- freeAsmop(result,NULL,ic,TRUE);
+ operand *left,*right, *result;
+ symbol *tlbl;
+ int i;
+
+ /* note here that || operations that are in an
+ if statement are taken away by backPatchLabels
+ only those used in arthmetic operations remain */
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ aopOp((left=IC_LEFT(ic)),ic,FALSE);
+ aopOp((right=IC_RIGHT(ic)),ic,FALSE);
+ aopOp((result=IC_RESULT(ic)),ic,FALSE);
+
+ DEBUGpic14_AopType(__LINE__,left,right,result);
+
+ for (i=0; i < AOP_SIZE(result); i++)
+ {
+ emitpcode(POC_CLRF, popGet(AOP(result), i));
+ } // for i
+
+ tlbl = newiTempLabel(NULL);
+ pic14_toBoolean(left);
+ emitSKPZ;
+ emitpcode(POC_GOTO, popGetLabel(tlbl->key));
+ pic14_toBoolean(right);
+ emitpLabel(tlbl->key);
+ /* here Z is clear IFF `left || right' */
+ emitSKPZ;
+ emitpcode(POC_INCF, popGet(AOP(result), 0));
+
+ freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(result,NULL,ic,TRUE);
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static int isLiteralBit(unsigned long lit)
{
- unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
- 0x100L,0x200L,0x400L,0x800L,
- 0x1000L,0x2000L,0x4000L,0x8000L,
- 0x10000L,0x20000L,0x40000L,0x80000L,
- 0x100000L,0x200000L,0x400000L,0x800000L,
- 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
- 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
- int idx;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- for(idx = 0; idx < 32; idx++)
- if(lit == pw[idx])
- return idx+1;
- return 0;
+ unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
+ 0x100L,0x200L,0x400L,0x800L,
+ 0x1000L,0x2000L,0x4000L,0x8000L,
+ 0x10000L,0x20000L,0x40000L,0x80000L,
+ 0x100000L,0x200000L,0x400000L,0x800000L,
+ 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
+ 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
+ int idx;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ for(idx = 0; idx < 32; idx++)
+ if(lit == pw[idx])
+ return idx+1;
+ return 0;
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static void continueIfTrue (iCode *ic)
{
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if(IC_TRUE(ic))
- {
- // Why +100?!?
- emitpcode(POC_GOTO, popGetLabel(IC_TRUE(ic)->key+100));
- pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
- }
- ic->generated = 1;
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ if(IC_TRUE(ic))
+ {
+ // Why +100?!?
+ emitpcode(POC_GOTO, popGetLabel(IC_TRUE(ic)->key+100));
+ pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
+ }
+ ic->generated = 1;
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static void jumpIfTrue (iCode *ic)
{
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if(!IC_TRUE(ic))
- {
- // Why +100?!?
- emitpcode(POC_GOTO, popGetLabel(IC_TRUE(ic)->key+100));
- pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
- }
- ic->generated = 1;
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ if(!IC_TRUE(ic))
+ {
+ // Why +100?!?
+ emitpcode(POC_GOTO, popGetLabel(IC_TRUE(ic)->key+100));
+ pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
+ }
+ ic->generated = 1;
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
{
- FENTRY;
- // ugly but optimized by peephole
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if(IC_TRUE(ic)){
- symbol *nlbl = newiTempLabel(NULL);
- pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
- pic14_emitcode("","%05d_DS_:",tlbl->key+100);
- pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
- pic14_emitcode("","%05d_DS_:",nlbl->key+100);
- }
- else{
- pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
- pic14_emitcode("","%05d_DS_:",tlbl->key+100);
- }
- ic->generated = 1;
+ FENTRY;
+ // ugly but optimized by peephole
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ if(IC_TRUE(ic)){
+ symbol *nlbl = newiTempLabel(NULL);
+ pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
+ pic14_emitcode("","%05d_DS_:",tlbl->key+100);
+ pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
+ pic14_emitcode("","%05d_DS_:",nlbl->key+100);
+ }
+ else{
+ pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
+ pic14_emitcode("","%05d_DS_:",tlbl->key+100);
+ }
+ ic->generated = 1;
+}
+
+/*-----------------------------------------------------------------*/
+/* genAnd - code for and */
+/*-----------------------------------------------------------------*/
+static void genAnd (iCode *ic, iCode *ifx)
+{
+ operand *left, *right, *result;
+ int size, offset=0;
+ unsigned long lit = 0L;
+ int bytelit = 0;
+ resolvedIfx rIfx;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ aopOp((left = IC_LEFT(ic)),ic,FALSE);
+ aopOp((right= IC_RIGHT(ic)),ic,FALSE);
+ aopOp((result=IC_RESULT(ic)),ic,TRUE);
+
+ resolveIfx(&rIfx,ifx);
+
+ /* if left is a literal & right is not then exchange them */
+ if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
+ AOP_NEEDSACC(left)) {
+ operand *tmp = right ;
+ right = left;
+ left = tmp;
+ }
+
+ /* if result = right then exchange them */
+ if(pic14_sameRegs(AOP(result),AOP(right))){
+ operand *tmp = right ;
+ right = left;
+ left = tmp;
+ }
+
+ /* if right is bit then exchange them */
+ if (AOP_TYPE(right) == AOP_CRY &&
+ AOP_TYPE(left) != AOP_CRY){
+ operand *tmp = right ;
+ right = left;
+ left = tmp;
+ }
+ if(AOP_TYPE(right) == AOP_LIT)
+ lit = ulFromVal (AOP(right)->aopu.aop_lit);
+
+ size = AOP_SIZE(result);
+
+ DEBUGpic14_AopType(__LINE__,left,right,result);
+
+ // if(bit & yy)
+ // result = bit & yy;
+ if (AOP_TYPE(left) == AOP_CRY){
+ // c = bit & literal;
+ if(AOP_TYPE(right) == AOP_LIT){
+ if(lit & 1) {
+ if(size && pic14_sameRegs(AOP(result),AOP(left)))
+ // no change
+ goto release;
+ pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
+ } else {
+ // bit(result) = 0;
+ if(size && (AOP_TYPE(result) == AOP_CRY)){
+ pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
+ goto release;
+ }
+ if((AOP_TYPE(result) == AOP_CRY) && ifx){
+ jumpIfTrue(ifx);
+ goto release;
+ }
+ pic14_emitcode("clr","c");
+ }
+ } else {
+ if (AOP_TYPE(right) == AOP_CRY){
+ // c = bit & bit;
+ pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
+ pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
+ } else {
+ // c = bit & val;
+ MOVA(aopGet(AOP(right),0,FALSE,FALSE));
+ // c = lsb
+ pic14_emitcode("rrc","a");
+ pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
+ }
+ }
+ // bit = c
+ // val = c
+ if(size)
+ pic14_outBitC(result);
+ // if(bit & ...)
+ else if((AOP_TYPE(result) == AOP_CRY) && ifx)
+ genIfxJump(ifx, "c");
+ goto release ;
+ }
+
+ // if(val & 0xZZ) - size = 0, ifx != FALSE -
+ // bit = val & 0xZZ - size = 1, ifx = FALSE -
+ if((AOP_TYPE(right) == AOP_LIT) &&
+ (AOP_TYPE(result) == AOP_CRY) &&
+ (AOP_TYPE(left) != AOP_CRY)){
+ int posbit = isLiteralBit(lit);
+ /* left & 2^n */
+ if(posbit){
+ posbit--;
+ //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
+ // bit = left & 2^n
+ if(size)
+ pic14_emitcode("mov","c,acc.%d",posbit&0x07);
+ // if(left & 2^n)
+ else{
+ if(ifx){
+ int offset = 0;
+ while (posbit > 7) {
+ posbit -= 8;
+ offset++;
+ }
+ emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
+ newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit,0));
+ emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
+
+ ifx->generated = 1;
+ }
+ goto release;
+ }
+ } else {
+ symbol *tlbl = newiTempLabel(NULL);
+ int sizel = AOP_SIZE(left);
+ if(size)
+ pic14_emitcode("setb","c");
+ while(sizel--){
+ if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
+ mov2w( AOP(left), offset);
+ // byte == 2^n ?
+ if((posbit = isLiteralBit(bytelit)) != 0) {
+ emitpcode(rIfx.condition ? POC_BTFSC : POC_BTFSS, // XXX: or the other way round?
+ newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit - 1, 0));
+ pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
+ }
+ else{
+ emitpcode(POC_ANDLW, newpCodeOpLit(bytelit & 0x0ff));
+ if (rIfx.condition) emitSKPZ;
+ else emitSKPNZ;
+
+ if(bytelit != 0x0FFL)
+ {
+ pic14_emitcode("anl","a,%s",
+ aopGet(AOP(right),offset,FALSE,TRUE));
+ }
+ pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
+ }
+
+ emitpcode(POC_GOTO, popGetLabel(rIfx.lbl->key));
+ ifx->generated = 1;
+
+ }
+ offset++;
+ }
+ // bit = left & literal
+ if(size){
+ pic14_emitcode("clr","c");
+ pic14_emitcode("","%05d_DS_:",tlbl->key+100);
+ }
+ // if(left & literal)
+ else{
+ if(ifx)
+ jmpTrueOrFalse(ifx, tlbl);
+ goto release ;
+ }
+ }
+ pic14_outBitC(result);
+ goto release ;
+ }
+
+ /* if left is same as result */
+ if(pic14_sameRegs(AOP(result),AOP(left))){
+ int know_W = -1;
+ for(;size--; offset++,lit>>=8) {
+ if(AOP_TYPE(right) == AOP_LIT){
+ switch(lit & 0xff) {
+ case 0x00:
+ /* and'ing with 0 has clears the result */
+ emitpcode(POC_CLRF,popGet(AOP(result),offset));
+ break;
+ case 0xff:
+ /* and'ing with 0xff is a nop when the result and left are the same */
+ break;
+
+ default:
+ {
+ int p = my_powof2( (~lit) & 0xff );
+ if(p>=0) {
+ /* only one bit is set in the literal, so use a bcf instruction */
+ emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
+
+ } else {
+ if(know_W != (int)(lit&0xff))
+ emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
+ know_W = lit &0xff;
+ emitpcode(POC_ANDWF,popGet(AOP(left),offset));
+ }
+ }
+ }
+ } else {
+ if (AOP_TYPE(left) == AOP_ACC) {
+ emitpcode(POC_ANDFW,popGet(AOP(right),offset));
+ } else {
+ emitpcode(POC_MOVFW,popGet(AOP(right),offset));
+ emitpcode(POC_ANDWF,popGet(AOP(left),offset));
+
+ }
+ }
+ }
+
+ } else {
+ // left & result in different registers
+ if(AOP_TYPE(result) == AOP_CRY){
+ // result = bit
+ // if(size), result in bit
+ // if(!size && ifx), conditional oper: if(left & right)
+ symbol *tlbl = newiTempLabel(NULL);
+ int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
+ if(size)
+ pic14_emitcode("setb","c");
+ while(sizer--){
+ MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
+ pic14_emitcode("anl","a,%s",
+ aopGet(AOP(left),offset,FALSE,FALSE));
+ pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
+ offset++;
+ }
+ if(size){
+ CLRC;
+ pic14_emitcode("","%05d_DS_:",tlbl->key+100);
+ pic14_outBitC(result);
+ } else if(ifx)
+ jmpTrueOrFalse(ifx, tlbl);
+ } else {
+ for(;(size--);offset++) {
+ // normal case
+ // result = left & right
+ if(AOP_TYPE(right) == AOP_LIT){
+ int t = (lit >> (offset*8)) & 0x0FFL;
+ switch(t) {
+ case 0x00:
+ emitpcode(POC_CLRF,popGet(AOP(result),offset));
+ break;
+ case 0xff:
+ if(AOP_TYPE(left) != AOP_ACC) {
+ emitpcode(POC_MOVFW,popGet(AOP(left),offset));
+ }
+ emitpcode(POC_MOVWF,popGet(AOP(result),offset));
+ break;
+ default:
+ if(AOP_TYPE(left) == AOP_ACC) {
+ emitpcode(POC_ANDLW, popGetLit(t));
+ } else {
+ emitpcode(POC_MOVLW, popGetLit(t));
+ emitpcode(POC_ANDFW,popGet(AOP(left),offset));
+ }
+ emitpcode(POC_MOVWF,popGet(AOP(result),offset));
+ }
+ continue;
+ }
+
+ if (AOP_TYPE(left) == AOP_ACC) {
+ emitpcode(POC_ANDFW,popGet(AOP(right),offset));
+ } else {
+ emitpcode(POC_MOVFW,popGet(AOP(right),offset));
+ emitpcode(POC_ANDFW,popGet(AOP(left),offset));
+ }
+ emitpcode(POC_MOVWF,popGet(AOP(result),offset));
+ }
+ }
+ }
+
+release :
+ freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(result,NULL,ic,TRUE);
}
-/*-----------------------------------------------------------------*/
-/* genAnd - code for and */
-/*-----------------------------------------------------------------*/
-static void genAnd (iCode *ic, iCode *ifx)
-{
- operand *left, *right, *result;
- int size, offset=0;
- unsigned long lit = 0L;
- int bytelit = 0;
- resolvedIfx rIfx;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- aopOp((left = IC_LEFT(ic)),ic,FALSE);
- aopOp((right= IC_RIGHT(ic)),ic,FALSE);
- aopOp((result=IC_RESULT(ic)),ic,TRUE);
-
- resolveIfx(&rIfx,ifx);
-
- /* if left is a literal & right is not then exchange them */
- if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
- AOP_NEEDSACC(left)) {
- operand *tmp = right ;
- right = left;
- left = tmp;
- }
-
- /* if result = right then exchange them */
- if(pic14_sameRegs(AOP(result),AOP(right))){
- operand *tmp = right ;
- right = left;
- left = tmp;
- }
-
- /* if right is bit then exchange them */
- if (AOP_TYPE(right) == AOP_CRY &&
- AOP_TYPE(left) != AOP_CRY){
- operand *tmp = right ;
- right = left;
- left = tmp;
- }
- if(AOP_TYPE(right) == AOP_LIT)
- lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
-
- size = AOP_SIZE(result);
-
- DEBUGpic14_AopType(__LINE__,left,right,result);
-
- // if(bit & yy)
- // result = bit & yy;
- if (AOP_TYPE(left) == AOP_CRY){
- // c = bit & literal;
- if(AOP_TYPE(right) == AOP_LIT){
- if(lit & 1) {
- if(size && pic14_sameRegs(AOP(result),AOP(left)))
- // no change
- goto release;
- pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
- } else {
- // bit(result) = 0;
- if(size && (AOP_TYPE(result) == AOP_CRY)){
- pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
- goto release;
- }
- if((AOP_TYPE(result) == AOP_CRY) && ifx){
- jumpIfTrue(ifx);
- goto release;
- }
- pic14_emitcode("clr","c");
- }
- } else {
- if (AOP_TYPE(right) == AOP_CRY){
- // c = bit & bit;
- pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
- pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
- } else {
- // c = bit & val;
- MOVA(aopGet(AOP(right),0,FALSE,FALSE));
- // c = lsb
- pic14_emitcode("rrc","a");
- pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
- }
- }
- // bit = c
- // val = c
- if(size)
- pic14_outBitC(result);
- // if(bit & ...)
- else if((AOP_TYPE(result) == AOP_CRY) && ifx)
- genIfxJump(ifx, "c");
- goto release ;
- }
-
- // if(val & 0xZZ) - size = 0, ifx != FALSE -
- // bit = val & 0xZZ - size = 1, ifx = FALSE -
- if((AOP_TYPE(right) == AOP_LIT) &&
- (AOP_TYPE(result) == AOP_CRY) &&
- (AOP_TYPE(left) != AOP_CRY)){
- int posbit = isLiteralBit(lit);
- /* left & 2^n */
- if(posbit){
- posbit--;
- //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
- // bit = left & 2^n
- if(size)
- pic14_emitcode("mov","c,acc.%d",posbit&0x07);
- // if(left & 2^n)
- else{
- if(ifx){
- int offset = 0;
- while (posbit > 7) {
- posbit -= 8;
- offset++;
- }
- emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
- newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit,0));
- emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
-
- ifx->generated = 1;
- }
- goto release;
- }
- } else {
- symbol *tlbl = newiTempLabel(NULL);
- int sizel = AOP_SIZE(left);
- if(size)
- pic14_emitcode("setb","c");
- while(sizel--){
- if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
- mov2w( AOP(left), offset);
- // byte == 2^n ?
- if((posbit = isLiteralBit(bytelit)) != 0) {
- emitpcode(rIfx.condition ? POC_BTFSC : POC_BTFSS, // XXX: or the other way round?
- newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit - 1, 0));
- pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
- }
- else{
- emitpcode(POC_ANDLW, newpCodeOpLit(bytelit & 0x0ff));
- if (rIfx.condition) emitSKPZ;
- else emitSKPNZ;
-
- if(bytelit != 0x0FFL)
- {
- pic14_emitcode("anl","a,%s",
- aopGet(AOP(right),offset,FALSE,TRUE));
- }
- pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
- }
-
- emitpcode(POC_GOTO, popGetLabel(rIfx.lbl->key));
- ifx->generated = 1;
-
- }
- offset++;
- }
- // bit = left & literal
- if(size){
- pic14_emitcode("clr","c");
- pic14_emitcode("","%05d_DS_:",tlbl->key+100);
- }
- // if(left & literal)
- else{
- if(ifx)
- jmpTrueOrFalse(ifx, tlbl);
- goto release ;
- }
- }
- pic14_outBitC(result);
- goto release ;
- }
-
- /* if left is same as result */
- if(pic14_sameRegs(AOP(result),AOP(left))){
- int know_W = -1;
- for(;size--; offset++,lit>>=8) {
- if(AOP_TYPE(right) == AOP_LIT){
- switch(lit & 0xff) {
- case 0x00:
- /* and'ing with 0 has clears the result */
- emitpcode(POC_CLRF,popGet(AOP(result),offset));
- break;
- case 0xff:
- /* and'ing with 0xff is a nop when the result and left are the same */
- break;
-
- default:
- {
- int p = my_powof2( (~lit) & 0xff );
- if(p>=0) {
- /* only one bit is set in the literal, so use a bcf instruction */
- emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
-
- } else {
- if(know_W != (int)(lit&0xff))
- emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
- know_W = lit &0xff;
- emitpcode(POC_ANDWF,popGet(AOP(left),offset));
- }
- }
- }
- } else {
- if (AOP_TYPE(left) == AOP_ACC) {
- emitpcode(POC_ANDFW,popGet(AOP(right),offset));
- } else {
- emitpcode(POC_MOVFW,popGet(AOP(right),offset));
- emitpcode(POC_ANDWF,popGet(AOP(left),offset));
-
- }
- }
- }
-
- } else {
- // left & result in different registers
- if(AOP_TYPE(result) == AOP_CRY){
- // result = bit
- // if(size), result in bit
- // if(!size && ifx), conditional oper: if(left & right)
- symbol *tlbl = newiTempLabel(NULL);
- int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
- if(size)
- pic14_emitcode("setb","c");
- while(sizer--){
- MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
- pic14_emitcode("anl","a,%s",
- aopGet(AOP(left),offset,FALSE,FALSE));
- pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
- offset++;
- }
- if(size){
- CLRC;
- pic14_emitcode("","%05d_DS_:",tlbl->key+100);
- pic14_outBitC(result);
- } else if(ifx)
- jmpTrueOrFalse(ifx, tlbl);
- } else {
- for(;(size--);offset++) {
- // normal case
- // result = left & right
- if(AOP_TYPE(right) == AOP_LIT){
- int t = (lit >> (offset*8)) & 0x0FFL;
- switch(t) {
- case 0x00:
- emitpcode(POC_CLRF,popGet(AOP(result),offset));
- break;
- case 0xff:
- if(AOP_TYPE(left) != AOP_ACC) {
- emitpcode(POC_MOVFW,popGet(AOP(left),offset));
- }
- emitpcode(POC_MOVWF,popGet(AOP(result),offset));
- break;
- default:
- if(AOP_TYPE(left) == AOP_ACC) {
- emitpcode(POC_ANDLW, popGetLit(t));
- } else {
- emitpcode(POC_MOVLW, popGetLit(t));
- emitpcode(POC_ANDFW,popGet(AOP(left),offset));
- }
- emitpcode(POC_MOVWF,popGet(AOP(result),offset));
- }
- continue;
- }
-
- if (AOP_TYPE(left) == AOP_ACC) {
- emitpcode(POC_ANDFW,popGet(AOP(right),offset));
- } else {
- emitpcode(POC_MOVFW,popGet(AOP(right),offset));
- emitpcode(POC_ANDFW,popGet(AOP(left),offset));
- }
- emitpcode(POC_MOVWF,popGet(AOP(result),offset));
- }
- }
- }
-
-release :
- freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- freeAsmop(result,NULL,ic,TRUE);
-}
+/*-----------------------------------------------------------------*/
+/* genOr - code for or */
+/*-----------------------------------------------------------------*/
+static void genOr (iCode *ic, iCode *ifx)
+{
+ operand *left, *right, *result;
+ int size, offset=0;
+ unsigned long lit = 0L;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ aopOp((left = IC_LEFT(ic)),ic,FALSE);
+ aopOp((right= IC_RIGHT(ic)),ic,FALSE);
+ aopOp((result=IC_RESULT(ic)),ic,TRUE);
+
+ DEBUGpic14_AopType(__LINE__,left,right,result);
+
+ /* if left is a literal & right is not then exchange them */
+ if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
+ AOP_NEEDSACC(left)) {
+ operand *tmp = right ;
+ right = left;
+ left = tmp;
+ }
+
+ /* if result = right then exchange them */
+ if(pic14_sameRegs(AOP(result),AOP(right))){
+ operand *tmp = right ;
+ right = left;
+ left = tmp;
+ }
+
+ /* if right is bit then exchange them */
+ if (AOP_TYPE(right) == AOP_CRY &&
+ AOP_TYPE(left) != AOP_CRY){
+ operand *tmp = right ;
+ right = left;
+ left = tmp;
+ }
+
+ DEBUGpic14_AopType(__LINE__,left,right,result);
+
+ if(AOP_TYPE(right) == AOP_LIT)
+ lit = ulFromVal (AOP(right)->aopu.aop_lit);
+
+ size = AOP_SIZE(result);
+
+ // if(bit | yy)
+ // xx = bit | yy;
+ if (AOP_TYPE(left) == AOP_CRY){
+ if(AOP_TYPE(right) == AOP_LIT){
+ // c = bit & literal;
+ if(lit){
+ // lit != 0 => result = 1
+ if(AOP_TYPE(result) == AOP_CRY){
+ if(size)
+ emitpcode(POC_BSF, popGet(AOP(result),0));
+ //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
+ // AOP(result)->aopu.aop_dir,
+ // AOP(result)->aopu.aop_dir);
+ else if(ifx)
+ continueIfTrue(ifx);
+ goto release;
+ }
+ } else {
+ // lit == 0 => result = left
+ if(size && pic14_sameRegs(AOP(result),AOP(left)))
+ goto release;
+ pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
+ }
+ } else {
+ if (AOP_TYPE(right) == AOP_CRY){
+ if(pic14_sameRegs(AOP(result),AOP(left))){
+ // c = bit | bit;
+ emitpcode(POC_BCF, popGet(AOP(result),0));
+ emitpcode(POC_BTFSC, popGet(AOP(right),0));
+ emitpcode(POC_BSF, popGet(AOP(result),0));
+
+ pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
+ AOP(result)->aopu.aop_dir,
+ AOP(result)->aopu.aop_dir);
+ pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
+ AOP(right)->aopu.aop_dir,
+ AOP(right)->aopu.aop_dir);
+ pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
+ AOP(result)->aopu.aop_dir,
+ AOP(result)->aopu.aop_dir);
+ } else {
+ if( AOP_TYPE(result) == AOP_ACC) {
+ emitpcode(POC_MOVLW, popGetLit(0));
+ emitpcode(POC_BTFSS, popGet(AOP(right),0));
+ emitpcode(POC_BTFSC, popGet(AOP(left),0));
+ emitpcode(POC_MOVLW, popGetLit(1));
+
+ } else {
+
+ emitpcode(POC_BCF, popGet(AOP(result),0));
+ emitpcode(POC_BTFSS, popGet(AOP(right),0));
+ emitpcode(POC_BTFSC, popGet(AOP(left),0));
+ emitpcode(POC_BSF, popGet(AOP(result),0));
+
+ pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
+ AOP(result)->aopu.aop_dir,
+ AOP(result)->aopu.aop_dir);
+ pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
+ AOP(right)->aopu.aop_dir,
+ AOP(right)->aopu.aop_dir);
+ pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
+ AOP(left)->aopu.aop_dir,
+ AOP(left)->aopu.aop_dir);
+ pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
+ AOP(result)->aopu.aop_dir,
+ AOP(result)->aopu.aop_dir);
+ }
+ }
+ } else {
+ // c = bit | val;
+ symbol *tlbl = newiTempLabel(NULL);
+ pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
+
+
+ emitpcode(POC_BCF, popGet(AOP(result),0));
+ if( AOP_TYPE(right) == AOP_ACC) {
+ emitpcode(POC_IORLW, popGetLit(0));
+ emitSKPNZ;
+ emitpcode(POC_BTFSC, popGet(AOP(left),0));
+ emitpcode(POC_BSF, popGet(AOP(result),0));
+ }
+
+
+
+ if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
+ pic14_emitcode(";XXX setb","c");
+ pic14_emitcode(";XXX jb","%s,%05d_DS_",
+ AOP(left)->aopu.aop_dir,tlbl->key+100);
+ pic14_toBoolean(right);
+ pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
+ if((AOP_TYPE(result) == AOP_CRY) && ifx){
+ jmpTrueOrFalse(ifx, tlbl);
+ goto release;
+ } else {
+ CLRC;
+ pic14_emitcode("","%05d_DS_:",tlbl->key+100);
+ }
+ }
+ }
+ // bit = c
+ // val = c
+ if(size)
+ pic14_outBitC(result);
+ // if(bit | ...)
+ else if((AOP_TYPE(result) == AOP_CRY) && ifx)
+ genIfxJump(ifx, "c");
+ goto release ;
+ }
+
+ // if(val | 0xZZ) - size = 0, ifx != FALSE -
+ // bit = val | 0xZZ - size = 1, ifx = FALSE -
+ if((AOP_TYPE(right) == AOP_LIT) &&
+ (AOP_TYPE(result) == AOP_CRY) &&
+ (AOP_TYPE(left) != AOP_CRY)){
+ if(lit){
+ pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
+ // result = 1
+ if(size)
+ pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
+ else
+ continueIfTrue(ifx);
+ goto release;
+ } else {
+ pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
+ // lit = 0, result = boolean(left)
+ if(size)
+ pic14_emitcode(";XXX setb","c");
+ pic14_toBoolean(right);
+ if(size){
+ symbol *tlbl = newiTempLabel(NULL);
+ pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
+ CLRC;
+ pic14_emitcode("","%05d_DS_:",tlbl->key+100);
+ } else {
+ genIfxJump (ifx,"a");
+ goto release;
+ }
+ }
+ pic14_outBitC(result);
+ goto release ;
+ }
-/*-----------------------------------------------------------------*/
-/* genOr - code for or */
-/*-----------------------------------------------------------------*/
-static void genOr (iCode *ic, iCode *ifx)
-{
- operand *left, *right, *result;
- int size, offset=0;
- unsigned long lit = 0L;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- aopOp((left = IC_LEFT(ic)),ic,FALSE);
- aopOp((right= IC_RIGHT(ic)),ic,FALSE);
- aopOp((result=IC_RESULT(ic)),ic,TRUE);
-
- DEBUGpic14_AopType(__LINE__,left,right,result);
-
- /* if left is a literal & right is not then exchange them */
- if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
- AOP_NEEDSACC(left)) {
- operand *tmp = right ;
- right = left;
- left = tmp;
- }
-
- /* if result = right then exchange them */
- if(pic14_sameRegs(AOP(result),AOP(right))){
- operand *tmp = right ;
- right = left;
- left = tmp;
- }
-
- /* if right is bit then exchange them */
- if (AOP_TYPE(right) == AOP_CRY &&
- AOP_TYPE(left) != AOP_CRY){
- operand *tmp = right ;
- right = left;
- left = tmp;
- }
-
- DEBUGpic14_AopType(__LINE__,left,right,result);
-
- if(AOP_TYPE(right) == AOP_LIT)
- lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
-
- size = AOP_SIZE(result);
-
- // if(bit | yy)
- // xx = bit | yy;
- if (AOP_TYPE(left) == AOP_CRY){
- if(AOP_TYPE(right) == AOP_LIT){
- // c = bit & literal;
- if(lit){
- // lit != 0 => result = 1
- if(AOP_TYPE(result) == AOP_CRY){
- if(size)
- emitpcode(POC_BSF, popGet(AOP(result),0));
- //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
- // AOP(result)->aopu.aop_dir,
- // AOP(result)->aopu.aop_dir);
- else if(ifx)
- continueIfTrue(ifx);
- goto release;
- }
- } else {
- // lit == 0 => result = left
- if(size && pic14_sameRegs(AOP(result),AOP(left)))
- goto release;
- pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
- }
- } else {
- if (AOP_TYPE(right) == AOP_CRY){
- if(pic14_sameRegs(AOP(result),AOP(left))){
- // c = bit | bit;
- emitpcode(POC_BCF, popGet(AOP(result),0));
- emitpcode(POC_BTFSC, popGet(AOP(right),0));
- emitpcode(POC_BSF, popGet(AOP(result),0));
-
- pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
- AOP(result)->aopu.aop_dir,
- AOP(result)->aopu.aop_dir);
- pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
- AOP(right)->aopu.aop_dir,
- AOP(right)->aopu.aop_dir);
- pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
- AOP(result)->aopu.aop_dir,
- AOP(result)->aopu.aop_dir);
- } else {
- if( AOP_TYPE(result) == AOP_ACC) {
- emitpcode(POC_MOVLW, popGetLit(0));
- emitpcode(POC_BTFSS, popGet(AOP(right),0));
- emitpcode(POC_BTFSC, popGet(AOP(left),0));
- emitpcode(POC_MOVLW, popGetLit(1));
-
- } else {
-
- emitpcode(POC_BCF, popGet(AOP(result),0));
- emitpcode(POC_BTFSS, popGet(AOP(right),0));
- emitpcode(POC_BTFSC, popGet(AOP(left),0));
- emitpcode(POC_BSF, popGet(AOP(result),0));
-
- pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
- AOP(result)->aopu.aop_dir,
- AOP(result)->aopu.aop_dir);
- pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
- AOP(right)->aopu.aop_dir,
- AOP(right)->aopu.aop_dir);
- pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
- AOP(left)->aopu.aop_dir,
- AOP(left)->aopu.aop_dir);
- pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
- AOP(result)->aopu.aop_dir,
- AOP(result)->aopu.aop_dir);
- }
- }
- } else {
- // c = bit | val;
- symbol *tlbl = newiTempLabel(NULL);
- pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
-
-
- emitpcode(POC_BCF, popGet(AOP(result),0));
- if( AOP_TYPE(right) == AOP_ACC) {
- emitpcode(POC_IORLW, popGetLit(0));
- emitSKPNZ;
- emitpcode(POC_BTFSC, popGet(AOP(left),0));
- emitpcode(POC_BSF, popGet(AOP(result),0));
- }
-
-
-
- if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
- pic14_emitcode(";XXX setb","c");
- pic14_emitcode(";XXX jb","%s,%05d_DS_",
- AOP(left)->aopu.aop_dir,tlbl->key+100);
- pic14_toBoolean(right);
- pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
- if((AOP_TYPE(result) == AOP_CRY) && ifx){
- jmpTrueOrFalse(ifx, tlbl);
- goto release;
- } else {
- CLRC;
- pic14_emitcode("","%05d_DS_:",tlbl->key+100);
- }
- }
- }
- // bit = c
- // val = c
- if(size)
- pic14_outBitC(result);
- // if(bit | ...)
- else if((AOP_TYPE(result) == AOP_CRY) && ifx)
- genIfxJump(ifx, "c");
- goto release ;
- }
-
- // if(val | 0xZZ) - size = 0, ifx != FALSE -
- // bit = val | 0xZZ - size = 1, ifx = FALSE -
- if((AOP_TYPE(right) == AOP_LIT) &&
- (AOP_TYPE(result) == AOP_CRY) &&
- (AOP_TYPE(left) != AOP_CRY)){
- if(lit){
- pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
- // result = 1
- if(size)
- pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
- else
- continueIfTrue(ifx);
- goto release;
- } else {
- pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
- // lit = 0, result = boolean(left)
- if(size)
- pic14_emitcode(";XXX setb","c");
- pic14_toBoolean(right);
- if(size){
- symbol *tlbl = newiTempLabel(NULL);
- pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
- CLRC;
- pic14_emitcode("","%05d_DS_:",tlbl->key+100);
- } else {
- genIfxJump (ifx,"a");
- goto release;
- }
- }
- pic14_outBitC(result);
- goto release ;
- }
-
- /* if left is same as result */
- if(pic14_sameRegs(AOP(result),AOP(left))){
- int know_W = -1;
- for(;size--; offset++,lit>>=8) {
- if(AOP_TYPE(right) == AOP_LIT){
- if((lit & 0xff) == 0)
- /* or'ing with 0 has no effect */
- continue;
- else {
- int p = my_powof2(lit & 0xff);
- if(p>=0) {
- /* only one bit is set in the literal, so use a bsf instruction */
- emitpcode(POC_BSF,
- newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
- } else {
- if(know_W != (int)(lit & 0xff))
- emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
- know_W = lit & 0xff;
- emitpcode(POC_IORWF, popGet(AOP(left),offset));
- }
-
- }
- } else {
- if (AOP_TYPE(left) == AOP_ACC) {
- emitpcode(POC_IORFW, popGet(AOP(right),offset));
- pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
- } else {
- emitpcode(POC_MOVFW, popGet(AOP(right),offset));
- emitpcode(POC_IORWF, popGet(AOP(left),offset));
-
- pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
- pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
-
- }
- }
- }
- } else {
- // left & result in different registers
- if(AOP_TYPE(result) == AOP_CRY){
- // result = bit
- // if(size), result in bit
- // if(!size && ifx), conditional oper: if(left | right)
- symbol *tlbl = newiTempLabel(NULL);
- int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
- pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
-
-
- if(size)
- pic14_emitcode(";XXX setb","c");
- while(sizer--){
- MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
- pic14_emitcode(";XXX orl","a,%s",
- aopGet(AOP(left),offset,FALSE,FALSE));
- pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
- offset++;
- }
- if(size){
- CLRC;
- pic14_emitcode("","%05d_DS_:",tlbl->key+100);
- pic14_outBitC(result);
- } else if(ifx)
- jmpTrueOrFalse(ifx, tlbl);
- } else for(;(size--);offset++){
- // normal case
- // result = left | right
- if(AOP_TYPE(right) == AOP_LIT){
- int t = (lit >> (offset*8)) & 0x0FFL;
- switch(t) {
- case 0x00:
- if (AOP_TYPE(left) != AOP_ACC) {
- emitpcode(POC_MOVFW, popGet(AOP(left),offset));
- }
- emitpcode(POC_MOVWF, popGet(AOP(result),offset));
-
- break;
- default:
- if (AOP_TYPE(left) == AOP_ACC) {
- emitpcode(POC_IORLW, popGetLit(t));
- } else {
- emitpcode(POC_MOVLW, popGetLit(t));
- emitpcode(POC_IORFW, popGet(AOP(left),offset));
- }
- emitpcode(POC_MOVWF, popGet(AOP(result),offset));
- }
- continue;
- }
-
- // faster than result <- left, anl result,right
- // and better if result is SFR
- if (AOP_TYPE(left) == AOP_ACC) {
- emitpcode(POC_IORFW,popGet(AOP(right),offset));
- } else {
- emitpcode(POC_MOVFW,popGet(AOP(right),offset));
- emitpcode(POC_IORFW,popGet(AOP(left),offset));
- }
- emitpcode(POC_MOVWF, popGet(AOP(result),offset));
- }
- }
+ /* if left is same as result */
+ if(pic14_sameRegs(AOP(result),AOP(left))){
+ int know_W = -1;
+ for(;size--; offset++,lit>>=8) {
+ if(AOP_TYPE(right) == AOP_LIT){
+ if((lit & 0xff) == 0)
+ /* or'ing with 0 has no effect */
+ continue;
+ else {
+ int p = my_powof2(lit & 0xff);
+ if(p>=0) {
+ /* only one bit is set in the literal, so use a bsf instruction */
+ emitpcode(POC_BSF,
+ newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
+ } else {
+ if(know_W != (int)(lit & 0xff))
+ emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
+ know_W = lit & 0xff;
+ emitpcode(POC_IORWF, popGet(AOP(left),offset));
+ }
+
+ }
+ } else {
+ if (AOP_TYPE(left) == AOP_ACC) {
+ emitpcode(POC_IORFW, popGet(AOP(right),offset));
+ pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
+ } else {
+ emitpcode(POC_MOVFW, popGet(AOP(right),offset));
+ emitpcode(POC_IORWF, popGet(AOP(left),offset));
+
+ pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
+ pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
+
+ }
+ }
+ }
+ } else {
+ // left & result in different registers
+ if(AOP_TYPE(result) == AOP_CRY){
+ // result = bit
+ // if(size), result in bit
+ // if(!size && ifx), conditional oper: if(left | right)
+ symbol *tlbl = newiTempLabel(NULL);
+ int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
+ pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
+
+
+ if(size)
+ pic14_emitcode(";XXX setb","c");
+ while(sizer--){
+ MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
+ pic14_emitcode(";XXX orl","a,%s",
+ aopGet(AOP(left),offset,FALSE,FALSE));
+ pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
+ offset++;
+ }
+ if(size){
+ CLRC;
+ pic14_emitcode("","%05d_DS_:",tlbl->key+100);
+ pic14_outBitC(result);
+ } else if(ifx)
+ jmpTrueOrFalse(ifx, tlbl);
+ } else for(;(size--);offset++){
+ // normal case
+ // result = left | right
+ if(AOP_TYPE(right) == AOP_LIT){
+ int t = (lit >> (offset*8)) & 0x0FFL;
+ switch(t) {
+ case 0x00:
+ if (AOP_TYPE(left) != AOP_ACC) {
+ emitpcode(POC_MOVFW, popGet(AOP(left),offset));
+ }
+ emitpcode(POC_MOVWF, popGet(AOP(result),offset));
+
+ break;
+ default:
+ if (AOP_TYPE(left) == AOP_ACC) {
+ emitpcode(POC_IORLW, popGetLit(t));
+ } else {
+ emitpcode(POC_MOVLW, popGetLit(t));
+ emitpcode(POC_IORFW, popGet(AOP(left),offset));
+ }
+ emitpcode(POC_MOVWF, popGet(AOP(result),offset));
+ }
+ continue;
+ }
+
+ // faster than result <- left, anl result,right
+ // and better if result is SFR
+ if (AOP_TYPE(left) == AOP_ACC) {
+ emitpcode(POC_IORFW,popGet(AOP(right),offset));
+ } else {
+ emitpcode(POC_MOVFW,popGet(AOP(right),offset));
+ emitpcode(POC_IORFW,popGet(AOP(left),offset));
+ }
+ emitpcode(POC_MOVWF, popGet(AOP(result),offset));
+ }
+ }
release :
- freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- freeAsmop(result,NULL,ic,TRUE);
+ freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(result,NULL,ic,TRUE);
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static void genXor (iCode *ic, iCode *ifx)
{
- operand *left, *right, *result;
- int size, offset=0;
- unsigned long lit = 0L;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- aopOp((left = IC_LEFT(ic)),ic,FALSE);
- aopOp((right= IC_RIGHT(ic)),ic,FALSE);
- aopOp((result=IC_RESULT(ic)),ic,TRUE);
-
- /* if left is a literal & right is not ||
- if left needs acc & right does not */
- if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
- (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
- operand *tmp = right ;
- right = left;
- left = tmp;
- }
-
- /* if result = right then exchange them */
- if(pic14_sameRegs(AOP(result),AOP(right))){
- operand *tmp = right ;
- right = left;
- left = tmp;
- }
-
- /* if right is bit then exchange them */
- if (AOP_TYPE(right) == AOP_CRY &&
- AOP_TYPE(left) != AOP_CRY){
- operand *tmp = right ;
- right = left;
- left = tmp;
- }
- if(AOP_TYPE(right) == AOP_LIT)
- lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
-
- size = AOP_SIZE(result);
-
- // if(bit ^ yy)
- // xx = bit ^ yy;
- if (AOP_TYPE(left) == AOP_CRY){
- if(AOP_TYPE(right) == AOP_LIT){
- // c = bit & literal;
- if(lit>>1){
- // lit>>1 != 0 => result = 1
- if(AOP_TYPE(result) == AOP_CRY){
- if(size)
- {emitpcode(POC_BSF, popGet(AOP(result),offset));
- pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
- else if(ifx)
- continueIfTrue(ifx);
- goto release;
- }
- pic14_emitcode("setb","c");
- } else{
- // lit == (0 or 1)
- if(lit == 0){
- // lit == 0, result = left
- if(size && pic14_sameRegs(AOP(result),AOP(left)))
- goto release;
- pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
- } else{
- // lit == 1, result = not(left)
- if(size && pic14_sameRegs(AOP(result),AOP(left))){
- emitpcode(POC_MOVLW, popGet(AOP(result),offset));
- emitpcode(POC_XORWF, popGet(AOP(result),offset));
- pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
- goto release;
- } else {
- assert ( !"incomplete genXor" );
- pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
- pic14_emitcode("cpl","c");
- }
- }
- }
-
- } else {
- // right != literal
- symbol *tlbl = newiTempLabel(NULL);
- if (AOP_TYPE(right) == AOP_CRY){
- // c = bit ^ bit;
- pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
- }
- else{
- int sizer = AOP_SIZE(right);
- // c = bit ^ val
- // if val>>1 != 0, result = 1
- pic14_emitcode("setb","c");
- while(sizer){
- MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
- if(sizer == 1)
- // test the msb of the lsb
- pic14_emitcode("anl","a,#0xfe");
- pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
- sizer--;
- }
- // val = (0,1)
- pic14_emitcode("rrc","a");
- }
- pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
- pic14_emitcode("cpl","c");
- pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
- }
- // bit = c
- // val = c
- if(size)
- pic14_outBitC(result);
- // if(bit | ...)
- else if((AOP_TYPE(result) == AOP_CRY) && ifx)
- genIfxJump(ifx, "c");
- goto release ;
- }
-
- if(pic14_sameRegs(AOP(result),AOP(left))){
- /* if left is same as result */
- for(;size--; offset++) {
- if(AOP_TYPE(right) == AOP_LIT){
- int t = (lit >> (offset*8)) & 0x0FFL;
- if(t == 0x00L)
- continue;
- else
- if (IS_AOP_PREG(left)) {
- MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
- pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
- aopPut(AOP(result),"a",offset);
- } else {
- emitpcode(POC_MOVLW, popGetLit(t));
- emitpcode(POC_XORWF,popGet(AOP(left),offset));
- pic14_emitcode("xrl","%s,%s",
- aopGet(AOP(left),offset,FALSE,TRUE),
- aopGet(AOP(right),offset,FALSE,FALSE));
- }
- } else {
- if (AOP_TYPE(left) == AOP_ACC)
- pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
- else {
- emitpcode(POC_MOVFW,popGet(AOP(right),offset));
- emitpcode(POC_XORWF,popGet(AOP(left),offset));
- /*
- if (IS_AOP_PREG(left)) {
- pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
- aopPut(AOP(result),"a",offset);
- } else
- pic14_emitcode("xrl","%s,a",
- aopGet(AOP(left),offset,FALSE,TRUE));
- */
- }
- }
- }
- } else {
- // left & result in different registers
- if(AOP_TYPE(result) == AOP_CRY){
- // result = bit
- // if(size), result in bit
- // if(!size && ifx), conditional oper: if(left ^ right)
- symbol *tlbl = newiTempLabel(NULL);
- int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
- if(size)
- pic14_emitcode("setb","c");
- while(sizer--){
- if((AOP_TYPE(right) == AOP_LIT) &&
- (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
- MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
- } else {
- MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
- pic14_emitcode("xrl","a,%s",
- aopGet(AOP(left),offset,FALSE,FALSE));
- }
- pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
- offset++;
- }
- if(size){
- CLRC;
- pic14_emitcode("","%05d_DS_:",tlbl->key+100);
- pic14_outBitC(result);
- } else if(ifx)
- jmpTrueOrFalse(ifx, tlbl);
- } else for(;(size--);offset++){
- // normal case
- // result = left & right
- if(AOP_TYPE(right) == AOP_LIT){
- int t = (lit >> (offset*8)) & 0x0FFL;
- switch(t) {
- case 0x00:
- if (AOP_TYPE(left) != AOP_ACC) {
- emitpcode(POC_MOVFW,popGet(AOP(left),offset));
- }
- emitpcode(POC_MOVWF,popGet(AOP(result),offset));
- pic14_emitcode("movf","%s,w",
- aopGet(AOP(left),offset,FALSE,FALSE));
- pic14_emitcode("movwf","%s",
- aopGet(AOP(result),offset,FALSE,FALSE));
- break;
- case 0xff:
- if (AOP_TYPE(left) == AOP_ACC) {
- emitpcode(POC_XORLW, popGetLit(t));
- } else {
- emitpcode(POC_COMFW,popGet(AOP(left),offset));
- }
- emitpcode(POC_MOVWF,popGet(AOP(result),offset));
- break;
- default:
- if (AOP_TYPE(left) == AOP_ACC) {
- emitpcode(POC_XORLW, popGetLit(t));
- } else {
- emitpcode(POC_MOVLW, popGetLit(t));
- emitpcode(POC_XORFW,popGet(AOP(left),offset));
- }
- emitpcode(POC_MOVWF,popGet(AOP(result),offset));
- pic14_emitcode("movlw","0x%x",t);
- pic14_emitcode("xorwf","%s,w",
- aopGet(AOP(left),offset,FALSE,FALSE));
- pic14_emitcode("movwf","%s",
- aopGet(AOP(result),offset,FALSE,FALSE));
-
- }
- continue;
- }
-
- // faster than result <- left, anl result,right
- // and better if result is SFR
- if (AOP_TYPE(left) == AOP_ACC) {
- emitpcode(POC_XORFW,popGet(AOP(right),offset));
- } else {
- emitpcode(POC_MOVFW,popGet(AOP(right),offset));
- emitpcode(POC_XORFW,popGet(AOP(left),offset));
- }
- if ( AOP_TYPE(result) != AOP_ACC){
- emitpcode(POC_MOVWF,popGet(AOP(result),offset));
- }
- }
- }
-
+ operand *left, *right, *result;
+ int size, offset=0;
+ unsigned long lit = 0L;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ aopOp((left = IC_LEFT(ic)),ic,FALSE);
+ aopOp((right= IC_RIGHT(ic)),ic,FALSE);
+ aopOp((result=IC_RESULT(ic)),ic,TRUE);
+
+ /* if left is a literal & right is not ||
+ if left needs acc & right does not */
+ if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
+ (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
+ operand *tmp = right ;
+ right = left;
+ left = tmp;
+ }
+
+ /* if result = right then exchange them */
+ if(pic14_sameRegs(AOP(result),AOP(right))){
+ operand *tmp = right ;
+ right = left;
+ left = tmp;
+ }
+
+ /* if right is bit then exchange them */
+ if (AOP_TYPE(right) == AOP_CRY &&
+ AOP_TYPE(left) != AOP_CRY){
+ operand *tmp = right ;
+ right = left;
+ left = tmp;
+ }
+ if(AOP_TYPE(right) == AOP_LIT)
+ lit = ulFromVal (AOP(right)->aopu.aop_lit);
+
+ size = AOP_SIZE(result);
+
+ // if(bit ^ yy)
+ // xx = bit ^ yy;
+ if (AOP_TYPE(left) == AOP_CRY){
+ if(AOP_TYPE(right) == AOP_LIT){
+ // c = bit & literal;
+ if(lit>>1){
+ // lit>>1 != 0 => result = 1
+ if(AOP_TYPE(result) == AOP_CRY){
+ if(size)
+ {emitpcode(POC_BSF, popGet(AOP(result),offset));
+ pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
+ else if(ifx)
+ continueIfTrue(ifx);
+ goto release;
+ }
+ pic14_emitcode("setb","c");
+ } else{
+ // lit == (0 or 1)
+ if(lit == 0){
+ // lit == 0, result = left
+ if(size && pic14_sameRegs(AOP(result),AOP(left)))
+ goto release;
+ pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
+ } else{
+ // lit == 1, result = not(left)
+ if(size && pic14_sameRegs(AOP(result),AOP(left))){
+ emitpcode(POC_MOVLW, popGet(AOP(result),offset));
+ emitpcode(POC_XORWF, popGet(AOP(result),offset));
+ pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
+ goto release;
+ } else {
+ assert ( !"incomplete genXor" );
+ pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
+ pic14_emitcode("cpl","c");
+ }
+ }
+ }
+
+ } else {
+ // right != literal
+ symbol *tlbl = newiTempLabel(NULL);
+ if (AOP_TYPE(right) == AOP_CRY){
+ // c = bit ^ bit;
+ pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
+ }
+ else{
+ int sizer = AOP_SIZE(right);
+ // c = bit ^ val
+ // if val>>1 != 0, result = 1
+ pic14_emitcode("setb","c");
+ while(sizer){
+ MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
+ if(sizer == 1)
+ // test the msb of the lsb
+ pic14_emitcode("anl","a,#0xfe");
+ pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
+ sizer--;
+ }
+ // val = (0,1)
+ pic14_emitcode("rrc","a");
+ }
+ pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
+ pic14_emitcode("cpl","c");
+ pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
+ }
+ // bit = c
+ // val = c
+ if(size)
+ pic14_outBitC(result);
+ // if(bit | ...)
+ else if((AOP_TYPE(result) == AOP_CRY) && ifx)
+ genIfxJump(ifx, "c");
+ goto release ;
+ }
+
+ if(pic14_sameRegs(AOP(result),AOP(left))){
+ /* if left is same as result */
+ for(;size--; offset++) {
+ if(AOP_TYPE(right) == AOP_LIT){
+ int t = (lit >> (offset*8)) & 0x0FFL;
+ if(t == 0x00L)
+ continue;
+ else
+ if (IS_AOP_PREG(left)) {
+ MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
+ pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
+ aopPut(AOP(result),"a",offset);
+ } else {
+ emitpcode(POC_MOVLW, popGetLit(t));
+ emitpcode(POC_XORWF,popGet(AOP(left),offset));
+ pic14_emitcode("xrl","%s,%s",
+ aopGet(AOP(left),offset,FALSE,TRUE),
+ aopGet(AOP(right),offset,FALSE,FALSE));
+ }
+ } else {
+ if (AOP_TYPE(left) == AOP_ACC)
+ pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
+ else {
+ emitpcode(POC_MOVFW,popGet(AOP(right),offset));
+ emitpcode(POC_XORWF,popGet(AOP(left),offset));
+ /*
+ if (IS_AOP_PREG(left)) {
+ pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
+ aopPut(AOP(result),"a",offset);
+ } else
+ pic14_emitcode("xrl","%s,a",
+ aopGet(AOP(left),offset,FALSE,TRUE));
+ */
+ }
+ }
+ }
+ } else {
+ // left & result in different registers
+ if(AOP_TYPE(result) == AOP_CRY){
+ // result = bit
+ // if(size), result in bit
+ // if(!size && ifx), conditional oper: if(left ^ right)
+ symbol *tlbl = newiTempLabel(NULL);
+ int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
+ if(size)
+ pic14_emitcode("setb","c");
+ while(sizer--){
+ if((AOP_TYPE(right) == AOP_LIT) &&
+ (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
+ MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
+ } else {
+ MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
+ pic14_emitcode("xrl","a,%s",
+ aopGet(AOP(left),offset,FALSE,FALSE));
+ }
+ pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
+ offset++;
+ }
+ if(size){
+ CLRC;
+ pic14_emitcode("","%05d_DS_:",tlbl->key+100);
+ pic14_outBitC(result);
+ } else if(ifx)
+ jmpTrueOrFalse(ifx, tlbl);
+ } else for(;(size--);offset++){
+ // normal case
+ // result = left & right
+ if(AOP_TYPE(right) == AOP_LIT){
+ int t = (lit >> (offset*8)) & 0x0FFL;
+ switch(t) {
+ case 0x00:
+ if (AOP_TYPE(left) != AOP_ACC) {
+ emitpcode(POC_MOVFW,popGet(AOP(left),offset));
+ }
+ emitpcode(POC_MOVWF,popGet(AOP(result),offset));
+ pic14_emitcode("movf","%s,w",
+ aopGet(AOP(left),offset,FALSE,FALSE));
+ pic14_emitcode("movwf","%s",
+ aopGet(AOP(result),offset,FALSE,FALSE));
+ break;
+ case 0xff:
+ if (AOP_TYPE(left) == AOP_ACC) {
+ emitpcode(POC_XORLW, popGetLit(t));
+ } else {
+ emitpcode(POC_COMFW,popGet(AOP(left),offset));
+ }
+ emitpcode(POC_MOVWF,popGet(AOP(result),offset));
+ break;
+ default:
+ if (AOP_TYPE(left) == AOP_ACC) {
+ emitpcode(POC_XORLW, popGetLit(t));
+ } else {
+ emitpcode(POC_MOVLW, popGetLit(t));
+ emitpcode(POC_XORFW,popGet(AOP(left),offset));
+ }
+ emitpcode(POC_MOVWF,popGet(AOP(result),offset));
+ pic14_emitcode("movlw","0x%x",t);
+ pic14_emitcode("xorwf","%s,w",
+ aopGet(AOP(left),offset,FALSE,FALSE));
+ pic14_emitcode("movwf","%s",
+ aopGet(AOP(result),offset,FALSE,FALSE));
+
+ }
+ continue;
+ }
+
+ // faster than result <- left, anl result,right
+ // and better if result is SFR
+ if (AOP_TYPE(left) == AOP_ACC) {
+ emitpcode(POC_XORFW,popGet(AOP(right),offset));
+ } else {
+ emitpcode(POC_MOVFW,popGet(AOP(right),offset));
+ emitpcode(POC_XORFW,popGet(AOP(left),offset));
+ }
+ if ( AOP_TYPE(result) != AOP_ACC){
+ emitpcode(POC_MOVWF,popGet(AOP(result),offset));
+ }
+ }
+ }
+
release :
- freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- freeAsmop(result,NULL,ic,TRUE);
+ freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(result,NULL,ic,TRUE);
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static void genRRC (iCode *ic)
{
- operand *left , *result ;
- int size, offset = 0, same;
-
- FENTRY;
- /* rotate right with carry */
- left = IC_LEFT(ic);
- result=IC_RESULT(ic);
- aopOp (left,ic,FALSE);
- aopOp (result,ic,FALSE);
-
- DEBUGpic14_AopType(__LINE__,left,NULL,result);
-
- same = pic14_sameRegs(AOP(result),AOP(left));
-
- size = AOP_SIZE(result);
-
- /* get the lsb and put it into the carry */
- emitpcode(POC_RRFW, popGet(AOP(left),size-1));
-
- offset = 0 ;
-
- while(size--) {
-
- if(same) {
- emitpcode(POC_RRF, popGet(AOP(left),offset));
- } else {
- emitpcode(POC_RRFW, popGet(AOP(left),offset));
- emitpcode(POC_MOVWF, popGet(AOP(result),offset));
- }
-
- offset++;
- }
-
- freeAsmop(left,NULL,ic,TRUE);
- freeAsmop(result,NULL,ic,TRUE);
+ operand *left , *result ;
+ int size, offset = 0, same;
+
+ FENTRY;
+ /* rotate right with carry */
+ left = IC_LEFT(ic);
+ result=IC_RESULT(ic);
+ aopOp (left,ic,FALSE);
+ aopOp (result,ic,FALSE);
+
+ DEBUGpic14_AopType(__LINE__,left,NULL,result);
+
+ same = pic14_sameRegs(AOP(result),AOP(left));
+
+ size = AOP_SIZE(result);
+
+ /* get the lsb and put it into the carry */
+ emitpcode(POC_RRFW, popGet(AOP(left),size-1));
+
+ offset = 0 ;
+
+ while(size--) {
+
+ if(same) {
+ emitpcode(POC_RRF, popGet(AOP(left),offset));
+ } else {
+ emitpcode(POC_RRFW, popGet(AOP(left),offset));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offset));
+ }
+
+ offset++;
+ }
+
+ freeAsmop(left,NULL,ic,TRUE);
+ freeAsmop(result,NULL,ic,TRUE);
}
/*-----------------------------------------------------------------*/
/* genRLC - generate code for rotate left with carry */
/*-----------------------------------------------------------------*/
static void genRLC (iCode *ic)
-{
- operand *left , *result ;
- int size, offset = 0;
- int same;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- /* rotate right with carry */
- left = IC_LEFT(ic);
- result=IC_RESULT(ic);
- aopOp (left,ic,FALSE);
- aopOp (result,ic,FALSE);
-
- DEBUGpic14_AopType(__LINE__,left,NULL,result);
-
- same = pic14_sameRegs(AOP(result),AOP(left));
-
- /* move it to the result */
- size = AOP_SIZE(result);
-
- /* get the msb and put it into the carry */
- emitpcode(POC_RLFW, popGet(AOP(left),size-1));
-
- offset = 0 ;
-
- while(size--) {
-
- if(same) {
- emitpcode(POC_RLF, popGet(AOP(left),offset));
- } else {
- emitpcode(POC_RLFW, popGet(AOP(left),offset));
- emitpcode(POC_MOVWF, popGet(AOP(result),offset));
- }
-
- offset++;
- }
-
-
- freeAsmop(left,NULL,ic,TRUE);
- freeAsmop(result,NULL,ic,TRUE);
+{
+ operand *left , *result ;
+ int size, offset = 0;
+ int same;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* rotate right with carry */
+ left = IC_LEFT(ic);
+ result=IC_RESULT(ic);
+ aopOp (left,ic,FALSE);
+ aopOp (result,ic,FALSE);
+
+ DEBUGpic14_AopType(__LINE__,left,NULL,result);
+
+ same = pic14_sameRegs(AOP(result),AOP(left));
+
+ /* move it to the result */
+ size = AOP_SIZE(result);
+
+ /* get the msb and put it into the carry */
+ emitpcode(POC_RLFW, popGet(AOP(left),size-1));
+
+ offset = 0 ;
+
+ while(size--) {
+
+ if(same) {
+ emitpcode(POC_RLF, popGet(AOP(left),offset));
+ } else {
+ emitpcode(POC_RLFW, popGet(AOP(left),offset));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offset));
+ }
+
+ offset++;
+ }
+
+
+ freeAsmop(left,NULL,ic,TRUE);
+ freeAsmop(result,NULL,ic,TRUE);
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static void genGetHbit (iCode *ic)
{
- operand *left, *result;
- left = IC_LEFT(ic);
- result=IC_RESULT(ic);
- aopOp (left,ic,FALSE);
- aopOp (result,ic,FALSE);
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- /* get the highest order byte into a */
- MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
- if(AOP_TYPE(result) == AOP_CRY){
- pic14_emitcode("rlc","a");
- pic14_outBitC(result);
- }
- else{
- pic14_emitcode("rl","a");
- pic14_emitcode("anl","a,#0x01");
- pic14_outAcc(result);
- }
-
-
- freeAsmop(left,NULL,ic,TRUE);
- freeAsmop(result,NULL,ic,TRUE);
+ operand *left, *result;
+ left = IC_LEFT(ic);
+ result=IC_RESULT(ic);
+ aopOp (left,ic,FALSE);
+ aopOp (result,ic,FALSE);
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* get the highest order byte into a */
+ MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
+ if(AOP_TYPE(result) == AOP_CRY){
+ pic14_emitcode("rlc","a");
+ pic14_outBitC(result);
+ }
+ else{
+ pic14_emitcode("rl","a");
+ pic14_emitcode("anl","a,#0x01");
+ pic14_outAcc(result);
+ }
+
+
+ freeAsmop(left,NULL,ic,TRUE);
+ freeAsmop(result,NULL,ic,TRUE);
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static void AccLsh (pCodeOp *pcop,int shCount)
{
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- shCount &= 0x0007; // shCount : 0..7
- switch(shCount){
- case 0 :
- return;
- break;
- case 1 :
- emitCLRC;
- emitpcode(POC_RLF,pcop);
- return;
- break;
- case 2 :
- emitpcode(POC_RLF,pcop);
- emitpcode(POC_RLF,pcop);
- break;
- case 3 :
- emitpcode(POC_RLF,pcop);
- emitpcode(POC_RLF,pcop);
- emitpcode(POC_RLF,pcop);
- break;
- case 4 :
- emitpcode(POC_SWAPF,pcop);
- break;
- case 5 :
- emitpcode(POC_SWAPF,pcop);
- emitpcode(POC_RLF,pcop);
- break;
- case 6 :
- emitpcode(POC_SWAPF,pcop);
- emitpcode(POC_RLF,pcop);
- emitpcode(POC_RLF,pcop);
- break;
- case 7 :
- emitpcode(POC_RRFW,pcop);
- emitpcode(POC_RRF,pcop);
- break;
- }
- /* clear invalid bits */
- emitpcode(POC_MOVLW, popGetLit ((unsigned char)(~((1UL << shCount) - 1))));
- emitpcode(POC_ANDWF, pcop);
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ shCount &= 0x0007; // shCount : 0..7
+ switch(shCount){
+ case 0 :
+ return;
+ break;
+ case 1 :
+ emitCLRC;
+ emitpcode(POC_RLF,pcop);
+ return;
+ break;
+ case 2 :
+ emitpcode(POC_RLF,pcop);
+ emitpcode(POC_RLF,pcop);
+ break;
+ case 3 :
+ emitpcode(POC_RLF,pcop);
+ emitpcode(POC_RLF,pcop);
+ emitpcode(POC_RLF,pcop);
+ break;
+ case 4 :
+ emitpcode(POC_SWAPF,pcop);
+ break;
+ case 5 :
+ emitpcode(POC_SWAPF,pcop);
+ emitpcode(POC_RLF,pcop);
+ break;
+ case 6 :
+ emitpcode(POC_SWAPF,pcop);
+ emitpcode(POC_RLF,pcop);
+ emitpcode(POC_RLF,pcop);
+ break;
+ case 7 :
+ emitpcode(POC_RRFW,pcop);
+ emitpcode(POC_RRF,pcop);
+ break;
+ }
+ /* clear invalid bits */
+ emitpcode(POC_MOVLW, popGetLit ((unsigned char)(~((1UL << shCount) - 1))));
+ emitpcode(POC_ANDWF, pcop);
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static void AccRsh (pCodeOp *pcop,int shCount, int mask_mode)
{
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- shCount &= 0x0007; // shCount : 0..7
- switch(shCount){
- case 0 :
- return;
- break;
- case 1 :
- /* load sign if needed */
- if (mask_mode == 2) emitpcode(POC_RLFW,pcop);
- else if (mask_mode == 1) emitCLRC;
- emitpcode(POC_RRF,pcop);
- return;
- break;
- case 2 :
- /* load sign if needed */
- if (mask_mode == 2) emitpcode(POC_RLFW,pcop);
- emitpcode(POC_RRF,pcop);
- /* load sign if needed */
- if (mask_mode == 2) emitpcode(POC_RLFW,pcop);
- emitpcode(POC_RRF,pcop);
- if (mask_mode == 2) return;
- break;
- case 3 :
- /* load sign if needed */
- if (mask_mode == 2) emitpcode(POC_RLFW,pcop);
- emitpcode(POC_RRF,pcop);
- /* load sign if needed */
- if (mask_mode == 2) emitpcode(POC_RLFW,pcop);
- emitpcode(POC_RRF,pcop);
- /* load sign if needed */
- if (mask_mode == 2) emitpcode(POC_RLFW,pcop);
- emitpcode(POC_RRF,pcop);
- if (mask_mode == 2) return;
- break;
- case 4 :
- emitpcode(POC_SWAPF,pcop);
- break;
- case 5 :
- emitpcode(POC_SWAPF,pcop);
- emitpcode(POC_RRF,pcop);
- break;
- case 6 :
- emitpcode(POC_SWAPF,pcop);
- emitpcode(POC_RRF,pcop);
- emitpcode(POC_RRF,pcop);
- break;
- case 7 :
- if (mask_mode == 2)
- {
- /* load sign */
- emitpcode(POC_RLFW,pcop);
- emitpcode(POC_CLRF,pcop);
- emitSKPNC;
- emitpcode(POC_COMF,pcop);
- return;
- } else {
- emitpcode(POC_RLFW,pcop);
- emitpcode(POC_RLF,pcop);
- }
- break;
- }
-
- if (mask_mode == 0)
- {
- /* leave invalid bits undefined */
- return;
- }
-
- /* clear invalid bits -- zero-extend */
- emitpcode(POC_MOVLW, popGetLit (0x00ff >> shCount));
- emitpcode(POC_ANDWF, pcop);
-
- if (mask_mode == 2) {
- /* sign-extend */
- emitpcode(POC_MOVLW, popGetLit (0x00ff << (8 - shCount)));
- emitpcode(POC_BTFSC, newpCodeOpBit (get_op(pcop,NULL,0), 7 - shCount ,0));
- emitpcode(POC_IORWF, pcop);
- }
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ shCount &= 0x0007; // shCount : 0..7
+ switch(shCount){
+ case 0 :
+ return;
+ break;
+ case 1 :
+ /* load sign if needed */
+ if (mask_mode == 2) emitpcode(POC_RLFW,pcop);
+ else if (mask_mode == 1) emitCLRC;
+ emitpcode(POC_RRF,pcop);
+ return;
+ break;
+ case 2 :
+ /* load sign if needed */
+ if (mask_mode == 2) emitpcode(POC_RLFW,pcop);
+ emitpcode(POC_RRF,pcop);
+ /* load sign if needed */
+ if (mask_mode == 2) emitpcode(POC_RLFW,pcop);
+ emitpcode(POC_RRF,pcop);
+ if (mask_mode == 2) return;
+ break;
+ case 3 :
+ /* load sign if needed */
+ if (mask_mode == 2) emitpcode(POC_RLFW,pcop);
+ emitpcode(POC_RRF,pcop);
+ /* load sign if needed */
+ if (mask_mode == 2) emitpcode(POC_RLFW,pcop);
+ emitpcode(POC_RRF,pcop);
+ /* load sign if needed */
+ if (mask_mode == 2) emitpcode(POC_RLFW,pcop);
+ emitpcode(POC_RRF,pcop);
+ if (mask_mode == 2) return;
+ break;
+ case 4 :
+ emitpcode(POC_SWAPF,pcop);
+ break;
+ case 5 :
+ emitpcode(POC_SWAPF,pcop);
+ emitpcode(POC_RRF,pcop);
+ break;
+ case 6 :
+ emitpcode(POC_SWAPF,pcop);
+ emitpcode(POC_RRF,pcop);
+ emitpcode(POC_RRF,pcop);
+ break;
+ case 7 :
+ if (mask_mode == 2)
+ {
+ /* load sign */
+ emitpcode(POC_RLFW,pcop);
+ emitpcode(POC_CLRF,pcop);
+ emitSKPNC;
+ emitpcode(POC_COMF,pcop);
+ return;
+ } else {
+ emitpcode(POC_RLFW,pcop);
+ emitpcode(POC_RLF,pcop);
+ }
+ break;
+ }
+
+ if (mask_mode == 0)
+ {
+ /* leave invalid bits undefined */
+ return;
+ }
+
+ /* clear invalid bits -- zero-extend */
+ emitpcode(POC_MOVLW, popGetLit (0x00ff >> shCount));
+ emitpcode(POC_ANDWF, pcop);
+
+ if (mask_mode == 2) {
+ /* sign-extend */
+ emitpcode(POC_MOVLW, popGetLit (0x00ff << (8 - shCount)));
+ emitpcode(POC_BTFSC, newpCodeOpBit (get_op(pcop,NULL,0), 7 - shCount ,0));
+ emitpcode(POC_IORWF, pcop);
+ }
}
#if 0
/*-----------------------------------------------------------------*/
static void AccSRsh (int shCount)
{
- symbol *tlbl ;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if(shCount != 0){
- if(shCount == 1){
- pic14_emitcode("mov","c,acc.7");
- pic14_emitcode("rrc","a");
- } else if(shCount == 2){
- pic14_emitcode("mov","c,acc.7");
- pic14_emitcode("rrc","a");
- pic14_emitcode("mov","c,acc.7");
- pic14_emitcode("rrc","a");
- } else {
- tlbl = newiTempLabel(NULL);
- /* rotate right accumulator */
- AccRol(8 - shCount);
- /* and kill the higher order bits */
- pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
- pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
- pic14_emitcode("orl","a,#0x%02x",
- (unsigned char)~SRMask[shCount]);
- pic14_emitcode("","%05d_DS_:",tlbl->key+100);
- }
- }
+ symbol *tlbl ;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ if(shCount != 0){
+ if(shCount == 1){
+ pic14_emitcode("mov","c,acc.7");
+ pic14_emitcode("rrc","a");
+ } else if(shCount == 2){
+ pic14_emitcode("mov","c,acc.7");
+ pic14_emitcode("rrc","a");
+ pic14_emitcode("mov","c,acc.7");
+ pic14_emitcode("rrc","a");
+ } else {
+ tlbl = newiTempLabel(NULL);
+ /* rotate right accumulator */
+ AccRol(8 - shCount);
+ /* and kill the higher order bits */
+ pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
+ pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
+ pic14_emitcode("orl","a,#0x%02x",
+ (unsigned char)~SRMask[shCount]);
+ pic14_emitcode("","%05d_DS_:",tlbl->key+100);
+ }
+ }
}
/*-----------------------------------------------------------------*/
/* shiftR1Left2Result - shift right one byte from left to result */
/*-----------------------------------------------------------------*/
static void shiftR1Left2ResultSigned (operand *left, int offl,
- operand *result, int offr,
- int shCount)
-{
- int same;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
-
- switch(shCount) {
- case 1:
- emitpcode(POC_RLFW, popGet(AOP(left),offl));
- if(same)
- emitpcode(POC_RRF, popGet(AOP(result),offr));
- else {
- emitpcode(POC_RRFW, popGet(AOP(left),offl));
- emitpcode(POC_MOVWF, popGet(AOP(result),offr));
- }
-
- break;
- case 2:
-
- emitpcode(POC_RLFW, popGet(AOP(left),offl));
- if(same)
- emitpcode(POC_RRF, popGet(AOP(result),offr));
- else {
- emitpcode(POC_RRFW, popGet(AOP(left),offl));
- emitpcode(POC_MOVWF, popGet(AOP(result),offr));
- }
- emitpcode(POC_RLFW, popGet(AOP(result),offr));
- emitpcode(POC_RRF, popGet(AOP(result),offr));
-
- break;
-
- case 3:
- if(same)
- emitpcode(POC_SWAPF, popGet(AOP(result),offr));
- else {
- emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
- emitpcode(POC_MOVWF, popGet(AOP(result),offr));
- }
-
- emitpcode(POC_RLFW, popGet(AOP(result),offr));
- emitpcode(POC_RLFW, popGet(AOP(result),offr));
- emitpcode(POC_ANDLW, popGetLit(0x1f));
-
- emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
- emitpcode(POC_IORLW, popGetLit(0xe0));
-
- emitpcode(POC_MOVWF, popGet(AOP(result),offr));
- break;
-
- case 4:
- emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
- emitpcode(POC_ANDLW, popGetLit(0x0f));
- emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
- emitpcode(POC_IORLW, popGetLit(0xf0));
- emitpcode(POC_MOVWF, popGet(AOP(result),offr));
- break;
- case 5:
- if(same) {
- emitpcode(POC_SWAPF, popGet(AOP(result),offr));
- } else {
- emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
- emitpcode(POC_MOVWF, popGet(AOP(result),offr));
- }
- emitpcode(POC_RRFW, popGet(AOP(result),offr));
- emitpcode(POC_ANDLW, popGetLit(0x07));
- emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
- emitpcode(POC_IORLW, popGetLit(0xf8));
- emitpcode(POC_MOVWF, popGet(AOP(result),offr));
- break;
-
- case 6:
- if(same) {
- emitpcode(POC_MOVLW, popGetLit(0x00));
- emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
- emitpcode(POC_MOVLW, popGetLit(0xfe));
- emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
- emitpcode(POC_IORLW, popGetLit(0x01));
- emitpcode(POC_MOVWF, popGet(AOP(result),offr));
- } else {
- emitpcode(POC_CLRF, popGet(AOP(result),offr));
- emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
- emitpcode(POC_DECF, popGet(AOP(result),offr));
- emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
- emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
- }
- break;
-
- case 7:
- if(same) {
- emitpcode(POC_MOVLW, popGetLit(0x00));
- emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
- emitpcode(POC_MOVLW, popGetLit(0xff));
- emitpcode(POC_MOVWF, popGet(AOP(result),offr));
- } else {
- emitpcode(POC_CLRF, popGet(AOP(result),offr));
- emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
- emitpcode(POC_DECF, popGet(AOP(result),offr));
- }
-
- default:
- break;
- }
+ operand *result, int offr,
+ int shCount)
+{
+ int same;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
+
+ switch(shCount) {
+ case 1:
+ emitpcode(POC_RLFW, popGet(AOP(left),offl));
+ if(same)
+ emitpcode(POC_RRF, popGet(AOP(result),offr));
+ else {
+ emitpcode(POC_RRFW, popGet(AOP(left),offl));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offr));
+ }
+
+ break;
+ case 2:
+
+ emitpcode(POC_RLFW, popGet(AOP(left),offl));
+ if(same)
+ emitpcode(POC_RRF, popGet(AOP(result),offr));
+ else {
+ emitpcode(POC_RRFW, popGet(AOP(left),offl));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offr));
+ }
+ emitpcode(POC_RLFW, popGet(AOP(result),offr));
+ emitpcode(POC_RRF, popGet(AOP(result),offr));
+
+ break;
+
+ case 3:
+ if(same)
+ emitpcode(POC_SWAPF, popGet(AOP(result),offr));
+ else {
+ emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offr));
+ }
+
+ emitpcode(POC_RLFW, popGet(AOP(result),offr));
+ emitpcode(POC_RLFW, popGet(AOP(result),offr));
+ emitpcode(POC_ANDLW, popGetLit(0x1f));
+
+ emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
+ emitpcode(POC_IORLW, popGetLit(0xe0));
+
+ emitpcode(POC_MOVWF, popGet(AOP(result),offr));
+ break;
+
+ case 4:
+ emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
+ emitpcode(POC_ANDLW, popGetLit(0x0f));
+ emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
+ emitpcode(POC_IORLW, popGetLit(0xf0));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offr));
+ break;
+ case 5:
+ if(same) {
+ emitpcode(POC_SWAPF, popGet(AOP(result),offr));
+ } else {
+ emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offr));
+ }
+ emitpcode(POC_RRFW, popGet(AOP(result),offr));
+ emitpcode(POC_ANDLW, popGetLit(0x07));
+ emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
+ emitpcode(POC_IORLW, popGetLit(0xf8));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offr));
+ break;
+
+ case 6:
+ if(same) {
+ emitpcode(POC_MOVLW, popGetLit(0x00));
+ emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
+ emitpcode(POC_MOVLW, popGetLit(0xfe));
+ emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
+ emitpcode(POC_IORLW, popGetLit(0x01));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offr));
+ } else {
+ emitpcode(POC_CLRF, popGet(AOP(result),offr));
+ emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
+ emitpcode(POC_DECF, popGet(AOP(result),offr));
+ emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
+ emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
+ }
+ break;
+
+ case 7:
+ if(same) {
+ emitpcode(POC_MOVLW, popGetLit(0x00));
+ emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
+ emitpcode(POC_MOVLW, popGetLit(0xff));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offr));
+ } else {
+ emitpcode(POC_CLRF, popGet(AOP(result),offr));
+ emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
+ emitpcode(POC_DECF, popGet(AOP(result),offr));
+ }
+
+ default:
+ break;
+ }
}
/*-----------------------------------------------------------------*/
/* shiftR1Left2Result - shift right one byte from left to result */
/*-----------------------------------------------------------------*/
static void shiftR1Left2Result (operand *left, int offl,
- operand *result, int offr,
- int shCount, int sign)
-{
- int same;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
-
- /* Copy the msb into the carry if signed. */
- if(sign) {
- shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
- return;
- }
-
-
-
- switch(shCount) {
- case 1:
- emitCLRC;
- if(same)
- emitpcode(POC_RRF, popGet(AOP(result),offr));
- else {
- emitpcode(POC_RRFW, popGet(AOP(left),offl));
- emitpcode(POC_MOVWF, popGet(AOP(result),offr));
- }
- break;
- case 2:
- emitCLRC;
- if(same) {
- emitpcode(POC_RRF, popGet(AOP(result),offr));
- } else {
- emitpcode(POC_RRFW, popGet(AOP(left),offl));
- emitpcode(POC_MOVWF, popGet(AOP(result),offr));
- }
- emitCLRC;
- emitpcode(POC_RRF, popGet(AOP(result),offr));
-
- break;
- case 3:
- if(same)
- emitpcode(POC_SWAPF, popGet(AOP(result),offr));
- else {
- emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
- emitpcode(POC_MOVWF, popGet(AOP(result),offr));
- }
-
- emitpcode(POC_RLFW, popGet(AOP(result),offr));
- emitpcode(POC_RLFW, popGet(AOP(result),offr));
- emitpcode(POC_ANDLW, popGetLit(0x1f));
- emitpcode(POC_MOVWF, popGet(AOP(result),offr));
- break;
-
- case 4:
- emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
- emitpcode(POC_ANDLW, popGetLit(0x0f));
- emitpcode(POC_MOVWF, popGet(AOP(result),offr));
- break;
-
- case 5:
- emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
- emitpcode(POC_ANDLW, popGetLit(0x0f));
- emitpcode(POC_MOVWF, popGet(AOP(result),offr));
- emitCLRC;
- emitpcode(POC_RRF, popGet(AOP(result),offr));
-
- break;
- case 6:
-
- emitpcode(POC_RLFW, popGet(AOP(left),offl));
- emitpcode(POC_ANDLW, popGetLit(0x80));
- emitpcode(POC_MOVWF, popGet(AOP(result),offr));
- emitpcode(POC_RLF, popGet(AOP(result),offr));
- emitpcode(POC_RLF, popGet(AOP(result),offr));
- break;
-
- case 7:
-
- emitpcode(POC_RLFW, popGet(AOP(left),offl));
- emitpcode(POC_CLRF, popGet(AOP(result),offr));
- emitpcode(POC_RLF, popGet(AOP(result),offr));
-
- break;
-
- default:
- break;
- }
+ operand *result, int offr,
+ int shCount, int sign)
+{
+ int same;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
+
+ /* Copy the msb into the carry if signed. */
+ if(sign) {
+ shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
+ return;
+ }
+
+
+
+ switch(shCount) {
+ case 1:
+ emitCLRC;
+ if(same)
+ emitpcode(POC_RRF, popGet(AOP(result),offr));
+ else {
+ emitpcode(POC_RRFW, popGet(AOP(left),offl));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offr));
+ }
+ break;
+ case 2:
+ emitCLRC;
+ if(same) {
+ emitpcode(POC_RRF, popGet(AOP(result),offr));
+ } else {
+ emitpcode(POC_RRFW, popGet(AOP(left),offl));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offr));
+ }
+ emitCLRC;
+ emitpcode(POC_RRF, popGet(AOP(result),offr));
+
+ break;
+ case 3:
+ if(same)
+ emitpcode(POC_SWAPF, popGet(AOP(result),offr));
+ else {
+ emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offr));
+ }
+
+ emitpcode(POC_RLFW, popGet(AOP(result),offr));
+ emitpcode(POC_RLFW, popGet(AOP(result),offr));
+ emitpcode(POC_ANDLW, popGetLit(0x1f));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offr));
+ break;
+
+ case 4:
+ emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
+ emitpcode(POC_ANDLW, popGetLit(0x0f));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offr));
+ break;
+
+ case 5:
+ emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
+ emitpcode(POC_ANDLW, popGetLit(0x0f));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offr));
+ emitCLRC;
+ emitpcode(POC_RRF, popGet(AOP(result),offr));
+
+ break;
+ case 6:
+
+ emitpcode(POC_RLFW, popGet(AOP(left),offl));
+ emitpcode(POC_ANDLW, popGetLit(0x80));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offr));
+ emitpcode(POC_RLF, popGet(AOP(result),offr));
+ emitpcode(POC_RLF, popGet(AOP(result),offr));
+ break;
+
+ case 7:
+
+ emitpcode(POC_RLFW, popGet(AOP(left),offl));
+ emitpcode(POC_CLRF, popGet(AOP(result),offr));
+ emitpcode(POC_RLF, popGet(AOP(result),offr));
+
+ break;
+
+ default:
+ break;
+ }
}
/*-----------------------------------------------------------------*/
/* shiftL1Left2Result - shift left one byte from left to result */
/*-----------------------------------------------------------------*/
static void shiftL1Left2Result (operand *left, int offl,
- operand *result, int offr, int shCount)
-{
- int same;
-
- // char *l;
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
- DEBUGpic14_emitcode ("; ***","same = %d",same);
- // l = aopGet(AOP(left),offl,FALSE,FALSE);
- // MOVA(l);
- /* shift left accumulator */
- //AccLsh(shCount); // don't comment out just yet...
- // aopPut(AOP(result),"a",offr);
-
- switch(shCount) {
- case 1:
- /* Shift left 1 bit position */
- emitpcode(POC_MOVFW, popGet(AOP(left),offl));
- if(same) {
- emitpcode(POC_ADDWF, popGet(AOP(left),offl));
- } else {
- emitpcode(POC_ADDFW, popGet(AOP(left),offl));
- emitpcode(POC_MOVWF, popGet(AOP(result),offr));
- }
- break;
- case 2:
- emitpcode(POC_RLFW, popGet(AOP(left),offl));
- emitpcode(POC_ANDLW,popGetLit(0x7e));
- emitpcode(POC_MOVWF,popGet(AOP(result),offr));
- emitpcode(POC_ADDWF,popGet(AOP(result),offr));
- break;
- case 3:
- emitpcode(POC_RLFW, popGet(AOP(left),offl));
- emitpcode(POC_ANDLW,popGetLit(0x3e));
- emitpcode(POC_MOVWF,popGet(AOP(result),offr));
- emitpcode(POC_ADDWF,popGet(AOP(result),offr));
- emitpcode(POC_RLF, popGet(AOP(result),offr));
- break;
- case 4:
- emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
- emitpcode(POC_ANDLW, popGetLit(0xf0));
- emitpcode(POC_MOVWF,popGet(AOP(result),offr));
- break;
- case 5:
- emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
- emitpcode(POC_ANDLW, popGetLit(0xf0));
- emitpcode(POC_MOVWF,popGet(AOP(result),offr));
- emitpcode(POC_ADDWF,popGet(AOP(result),offr));
- break;
- case 6:
- emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
- emitpcode(POC_ANDLW, popGetLit(0x30));
- emitpcode(POC_MOVWF,popGet(AOP(result),offr));
- emitpcode(POC_ADDWF,popGet(AOP(result),offr));
- emitpcode(POC_RLF, popGet(AOP(result),offr));
- break;
- case 7:
- emitpcode(POC_RRFW, popGet(AOP(left),offl));
- emitpcode(POC_CLRF, popGet(AOP(result),offr));
- emitpcode(POC_RRF, popGet(AOP(result),offr));
- break;
-
- default:
- DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
- }
-
+ operand *result, int offr, int shCount)
+{
+ int same;
+
+ // char *l;
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
+ DEBUGpic14_emitcode ("; ***","same = %d",same);
+ // l = aopGet(AOP(left),offl,FALSE,FALSE);
+ // MOVA(l);
+ /* shift left accumulator */
+ //AccLsh(shCount); // don't comment out just yet...
+ // aopPut(AOP(result),"a",offr);
+
+ switch(shCount) {
+ case 1:
+ /* Shift left 1 bit position */
+ emitpcode(POC_MOVFW, popGet(AOP(left),offl));
+ if(same) {
+ emitpcode(POC_ADDWF, popGet(AOP(left),offl));
+ } else {
+ emitpcode(POC_ADDFW, popGet(AOP(left),offl));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offr));
+ }
+ break;
+ case 2:
+ emitpcode(POC_RLFW, popGet(AOP(left),offl));
+ emitpcode(POC_ANDLW,popGetLit(0x7e));
+ emitpcode(POC_MOVWF,popGet(AOP(result),offr));
+ emitpcode(POC_ADDWF,popGet(AOP(result),offr));
+ break;
+ case 3:
+ emitpcode(POC_RLFW, popGet(AOP(left),offl));
+ emitpcode(POC_ANDLW,popGetLit(0x3e));
+ emitpcode(POC_MOVWF,popGet(AOP(result),offr));
+ emitpcode(POC_ADDWF,popGet(AOP(result),offr));
+ emitpcode(POC_RLF, popGet(AOP(result),offr));
+ break;
+ case 4:
+ emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
+ emitpcode(POC_ANDLW, popGetLit(0xf0));
+ emitpcode(POC_MOVWF,popGet(AOP(result),offr));
+ break;
+ case 5:
+ emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
+ emitpcode(POC_ANDLW, popGetLit(0xf0));
+ emitpcode(POC_MOVWF,popGet(AOP(result),offr));
+ emitpcode(POC_ADDWF,popGet(AOP(result),offr));
+ break;
+ case 6:
+ emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
+ emitpcode(POC_ANDLW, popGetLit(0x30));
+ emitpcode(POC_MOVWF,popGet(AOP(result),offr));
+ emitpcode(POC_ADDWF,popGet(AOP(result),offr));
+ emitpcode(POC_RLF, popGet(AOP(result),offr));
+ break;
+ case 7:
+ emitpcode(POC_RRFW, popGet(AOP(left),offl));
+ emitpcode(POC_CLRF, popGet(AOP(result),offr));
+ emitpcode(POC_RRF, popGet(AOP(result),offr));
+ break;
+
+ default:
+ DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
+ }
+
}
#endif
/* movLeft2Result - move byte from left to result */
/*-----------------------------------------------------------------*/
static void movLeft2Result (operand *left, int offl,
- operand *result, int offr)
+ operand *result, int offr)
{
- char *l;
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
- l = aopGet(AOP(left),offl,FALSE,FALSE);
-
- if (*l == '@' && (IS_AOP_PREG(result))) {
- pic14_emitcode("mov","a,%s",l);
- aopPut(AOP(result),"a",offr);
- } else {
- emitpcode(POC_MOVFW, popGet(AOP(left),offl));
- emitpcode(POC_MOVWF, popGet(AOP(result),offr));
- }
- }
+ char *l;
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
+ l = aopGet(AOP(left),offl,FALSE,FALSE);
+
+ if (*l == '@' && (IS_AOP_PREG(result))) {
+ pic14_emitcode("mov","a,%s",l);
+ aopPut(AOP(result),"a",offr);
+ } else {
+ emitpcode(POC_MOVFW, popGet(AOP(left),offl));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offr));
+ }
+ }
}
/*-----------------------------------------------------------------*/
static void shiftLeft_Left2ResultLit (operand *left, operand *result, int shCount)
{
- int size, same, offr, i;
-
- size = AOP_SIZE(left);
- if (AOP_SIZE(result) < size) size = AOP_SIZE(result);
-
- same = pic14_sameRegs (AOP(left), AOP(result));
-
- offr = shCount / 8;
- shCount = shCount & 0x07;
-
- size -= offr;
-
- switch (shCount)
- {
- case 0: /* takes 0 or 2N cycles (for offr==0) */
- if (!same || offr) {
- for (i=size-1; i >= 0; i--)
- movLeft2Result (left, i, result, offr + i);
- } // if
- break;
-
- case 1: /* takes 1N+1 or 2N+1 cycles (or offr==0) */
- if (same && offr) {
- shiftLeft_Left2ResultLit (left, result, 8 * offr);
- shiftLeft_Left2ResultLit (result, result, shCount);
- return; /* prevent clearing result again */
- } else {
- emitCLRC;
- for (i=0; i < size; i++) {
- if (same && !offr) {
- emitpcode (POC_RLF, popGet (AOP(left), i));
- } else {
- emitpcode (POC_RLFW, popGet (AOP(left), i));
- emitpcode (POC_MOVWF, popGet (AOP(result), i + offr));
- } // if
- } // for
- } // if (offr)
- break;
-
- case 4: /* takes 3+5(N-1) = 5N-2 cycles (for offr==0) */
- /* works in-place/with offr as well */
- emitpcode (POC_SWAPFW, popGet (AOP(left), size-1));
- emitpcode (POC_ANDLW, popGetLit (0xF0));
- emitpcode (POC_MOVWF, popGet(AOP(result), size-1+offr));
-
- for (i = size - 2; i >= 0; i--)
- {
- emitpcode (POC_SWAPFW, popGet (AOP(left), i));
- emitpcode (POC_MOVWF, popGet (AOP(result), i + offr));
- emitpcode (POC_ANDLW, popGetLit (0x0F));
- emitpcode (POC_IORWF, popGet (AOP(result), i + offr + 1));
- emitpcode (POC_XORWF, popGet (AOP(result), i + offr));
- } // for i
- break;
-
- case 7: /* takes 2(N-1)+3 = 2N+1 cycles */
- /* works in-place/with offr as well */
- emitpcode (POC_RRFW, popGet (AOP(left), size-1));
- for (i = size-2; i >= 0; i--) {
- emitpcode (POC_RRFW, popGet (AOP(left), i));
- emitpcode (POC_MOVWF, popGet (AOP(result), offr + i + 1));
- } // for i
- emitpcode (POC_CLRF, popGet (AOP(result), offr));
- emitpcode (POC_RRF, popGet (AOP(result), offr));
- break;
-
- default:
- shiftLeft_Left2ResultLit (left, result, offr * 8 + shCount-1);
- shiftLeft_Left2ResultLit (result, result, 1);
- return; /* prevent clearing result again */
- break;
- } // switch
-
- while (0 < offr--)
- {
- emitpcode (POC_CLRF, popGet (AOP(result), offr));
- } // while
+ int size, same, offr, i;
+
+ size = AOP_SIZE(left);
+ if (AOP_SIZE(result) < size) size = AOP_SIZE(result);
+
+ same = pic14_sameRegs (AOP(left), AOP(result));
+
+ offr = shCount / 8;
+ shCount = shCount & 0x07;
+
+ size -= offr;
+
+ switch (shCount)
+ {
+ case 0: /* takes 0 or 2N cycles (for offr==0) */
+ if (!same || offr) {
+ for (i=size-1; i >= 0; i--)
+ movLeft2Result (left, i, result, offr + i);
+ } // if
+ break;
+
+ case 1: /* takes 1N+1 or 2N+1 cycles (or offr==0) */
+ if (same && offr) {
+ shiftLeft_Left2ResultLit (left, result, 8 * offr);
+ shiftLeft_Left2ResultLit (result, result, shCount);
+ return; /* prevent clearing result again */
+ } else {
+ emitCLRC;
+ for (i=0; i < size; i++) {
+ if (same && !offr) {
+ emitpcode (POC_RLF, popGet (AOP(left), i));
+ } else {
+ emitpcode (POC_RLFW, popGet (AOP(left), i));
+ emitpcode (POC_MOVWF, popGet (AOP(result), i + offr));
+ } // if
+ } // for
+ } // if (offr)
+ break;
+
+ case 4: /* takes 3+5(N-1) = 5N-2 cycles (for offr==0) */
+ /* works in-place/with offr as well */
+ emitpcode (POC_SWAPFW, popGet (AOP(left), size-1));
+ emitpcode (POC_ANDLW, popGetLit (0xF0));
+ emitpcode (POC_MOVWF, popGet(AOP(result), size-1+offr));
+
+ for (i = size - 2; i >= 0; i--)
+ {
+ emitpcode (POC_SWAPFW, popGet (AOP(left), i));
+ emitpcode (POC_MOVWF, popGet (AOP(result), i + offr));
+ emitpcode (POC_ANDLW, popGetLit (0x0F));
+ emitpcode (POC_IORWF, popGet (AOP(result), i + offr + 1));
+ emitpcode (POC_XORWF, popGet (AOP(result), i + offr));
+ } // for i
+ break;
+
+ case 7: /* takes 2(N-1)+3 = 2N+1 cycles */
+ /* works in-place/with offr as well */
+ emitpcode (POC_RRFW, popGet (AOP(left), size-1));
+ for (i = size-2; i >= 0; i--) {
+ emitpcode (POC_RRFW, popGet (AOP(left), i));
+ emitpcode (POC_MOVWF, popGet (AOP(result), offr + i + 1));
+ } // for i
+ emitpcode (POC_CLRF, popGet (AOP(result), offr));
+ emitpcode (POC_RRF, popGet (AOP(result), offr));
+ break;
+
+ default:
+ shiftLeft_Left2ResultLit (left, result, offr * 8 + shCount-1);
+ shiftLeft_Left2ResultLit (result, result, 1);
+ return; /* prevent clearing result again */
+ break;
+ } // switch
+
+ while (0 < offr--)
+ {
+ emitpcode (POC_CLRF, popGet (AOP(result), offr));
+ } // while
}
/*-----------------------------------------------------------------*/
/* shiftRight_Left2ResultLit - shift right by known count */
/*-----------------------------------------------------------------*/
-static void shiftRight_Left2ResultLit (operand *left, operand *result, int shCount, int sign)
-{
- int size, same, offr, i;
-
- size = AOP_SIZE(left);
- if (AOP_SIZE(result) < size) size = AOP_SIZE(result);
-
- same = pic14_sameRegs (AOP(left), AOP(result));
-
- offr = shCount / 8;
- shCount = shCount & 0x07;
-
- size -= offr;
-
- if (size)
- {
- switch (shCount)
- {
- case 0: /* takes 0 or 2N cycles (for offr==0) */
- if (!same || offr) {
- for (i=0; i < size; i++)
- movLeft2Result (left, i + offr, result, i);
- } // if
- break;
-
- case 1: /* takes 1N+1(3) or 2N+1(3) cycles (or offr==0) */
- emitpComment ("%s:%d: shCount=%d, size=%d, sign=%d, same=%d, offr=%d", __FUNCTION__, __LINE__, shCount, size, sign, same, offr);
- if (same && offr) {
- shiftRight_Left2ResultLit (left, result, 8 * offr, sign);
- shiftRight_Left2ResultLit (result, result, shCount, sign);
- return; /* prevent sign-extending result again */
- } else {
- emitCLRC;
- if (sign) {
- emitpcode (POC_BTFSC, newpCodeOpBit (aopGet (AOP(left), AOP_SIZE(left)-1, FALSE, FALSE), 7, 0));
- emitSETC;
- }
- for (i = size-1; i >= 0; i--) {
- if (same && !offr) {
- emitpcode (POC_RRF, popGet (AOP(left), i));
- } else {
- emitpcode (POC_RRFW, popGet (AOP(left), i + offr));
- emitpcode (POC_MOVWF, popGet (AOP(result), i));
- }
- } // for i
- } // if (offr)
- break;
-
- case 4: /* takes 3(6)+5(N-1) = 5N-2(+1) cycles (for offr==0) */
- /* works in-place/with offr as well */
- emitpcode (POC_SWAPFW, popGet (AOP(left), offr));
- emitpcode (POC_ANDLW, popGetLit (0x0F));
- emitpcode (POC_MOVWF, popGet(AOP(result), 0));
-
- for (i = 1; i < size; i++)
- {
- emitpcode (POC_SWAPFW, popGet (AOP(left), i + offr));
- emitpcode (POC_MOVWF, popGet (AOP(result), i));
- emitpcode (POC_ANDLW, popGetLit (0xF0));
- emitpcode (POC_IORWF, popGet (AOP(result), i - 1));
- emitpcode (POC_XORWF, popGet (AOP(result), i));
- } // for i
-
- if (sign)
- {
- emitpcode (POC_MOVLW, popGetLit (0xF0));
- emitpcode (POC_BTFSC, newpCodeOpBit (aopGet (AOP(result), size-1, FALSE, FALSE), 3, 0));
- emitpcode (POC_IORWF, popGet (AOP(result), size-1));
- } // if
- break;
-
- case 7: /* takes 2(N-1)+3(4) = 2N+1(2) cycles */
- /* works in-place/with offr as well */
- emitpcode (POC_RLFW, popGet (AOP(left), offr));
- for (i = 0; i < size-1; i++) {
- emitpcode (POC_RLFW, popGet (AOP(left), offr + i + 1));
- emitpcode (POC_MOVWF, popGet (AOP(result), i));
- } // for i
- emitpcode (POC_CLRF, popGet (AOP(result), size-1));
- if (!sign) {
- emitpcode (POC_RLF, popGet (AOP(result), size-1));
- } else {
- emitSKPNC;
- emitpcode (POC_DECF, popGet (AOP(result), size-1));
- }
- break;
-
- default:
- shiftRight_Left2ResultLit (left, result, offr * 8 + shCount-1, sign);
- shiftRight_Left2ResultLit (result, result, 1, sign);
- return; /* prevent sign extending result again */
- break;
- } // switch
- } // if
-
- addSign (result, size, sign);
-}
+static void shiftRight_Left2ResultLit (operand *left, operand *result, int shCount, int sign)
+{
+ int size, same, offr, i;
+
+ size = AOP_SIZE(left);
+ if (AOP_SIZE(result) < size) size = AOP_SIZE(result);
+
+ same = pic14_sameRegs (AOP(left), AOP(result));
+
+ offr = shCount / 8;
+ shCount = shCount & 0x07;
+
+ size -= offr;
+
+ if (size)
+ {
+ switch (shCount)
+ {
+ case 0: /* takes 0 or 2N cycles (for offr==0) */
+ if (!same || offr) {
+ for (i=0; i < size; i++)
+ movLeft2Result (left, i + offr, result, i);
+ } // if
+ break;
+
+ case 1: /* takes 1N+1(3) or 2N+1(3) cycles (or offr==0) */
+ emitpComment ("%s:%d: shCount=%d, size=%d, sign=%d, same=%d, offr=%d", __FUNCTION__, __LINE__, shCount, size, sign, same, offr);
+ if (same && offr) {
+ shiftRight_Left2ResultLit (left, result, 8 * offr, sign);
+ shiftRight_Left2ResultLit (result, result, shCount, sign);
+ return; /* prevent sign-extending result again */
+ } else {
+ emitCLRC;
+ if (sign) {
+ emitpcode (POC_BTFSC, newpCodeOpBit (aopGet (AOP(left), AOP_SIZE(left)-1, FALSE, FALSE), 7, 0));
+ emitSETC;
+ }
+ for (i = size-1; i >= 0; i--) {
+ if (same && !offr) {
+ emitpcode (POC_RRF, popGet (AOP(left), i));
+ } else {
+ emitpcode (POC_RRFW, popGet (AOP(left), i + offr));
+ emitpcode (POC_MOVWF, popGet (AOP(result), i));
+ }
+ } // for i
+ } // if (offr)
+ break;
+
+ case 4: /* takes 3(6)+5(N-1) = 5N-2(+1) cycles (for offr==0) */
+ /* works in-place/with offr as well */
+ emitpcode (POC_SWAPFW, popGet (AOP(left), offr));
+ emitpcode (POC_ANDLW, popGetLit (0x0F));
+ emitpcode (POC_MOVWF, popGet(AOP(result), 0));
+
+ for (i = 1; i < size; i++)
+ {
+ emitpcode (POC_SWAPFW, popGet (AOP(left), i + offr));
+ emitpcode (POC_MOVWF, popGet (AOP(result), i));
+ emitpcode (POC_ANDLW, popGetLit (0xF0));
+ emitpcode (POC_IORWF, popGet (AOP(result), i - 1));
+ emitpcode (POC_XORWF, popGet (AOP(result), i));
+ } // for i
+
+ if (sign)
+ {
+ emitpcode (POC_MOVLW, popGetLit (0xF0));
+ emitpcode (POC_BTFSC, newpCodeOpBit (aopGet (AOP(result), size-1, FALSE, FALSE), 3, 0));
+ emitpcode (POC_IORWF, popGet (AOP(result), size-1));
+ } // if
+ break;
+
+ case 7: /* takes 2(N-1)+3(4) = 2N+1(2) cycles */
+ /* works in-place/with offr as well */
+ emitpcode (POC_RLFW, popGet (AOP(left), offr));
+ for (i = 0; i < size-1; i++) {
+ emitpcode (POC_RLFW, popGet (AOP(left), offr + i + 1));
+ emitpcode (POC_MOVWF, popGet (AOP(result), i));
+ } // for i
+ emitpcode (POC_CLRF, popGet (AOP(result), size-1));
+ if (!sign) {
+ emitpcode (POC_RLF, popGet (AOP(result), size-1));
+ } else {
+ emitSKPNC;
+ emitpcode (POC_DECF, popGet (AOP(result), size-1));
+ }
+ break;
+
+ default:
+ shiftRight_Left2ResultLit (left, result, offr * 8 + shCount-1, sign);
+ shiftRight_Left2ResultLit (result, result, 1, sign);
+ return; /* prevent sign extending result again */
+ break;
+ } // switch
+ } // if
+
+ addSign (result, size, sign);
+}
+
+#if 0
+/*-----------------------------------------------------------------*/
+/* shiftL2Left2Result - shift left two bytes from left to result */
+/*-----------------------------------------------------------------*/
+static void shiftL2Left2Result (operand *left, int offl,
+ operand *result, int offr, int shCount)
+{
+ FENTRY;
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ if(pic14_sameRegs(AOP(result), AOP(left))) {
+ switch(shCount) {
+ case 0:
+ break;
+ case 1:
+ case 2:
+ case 3:
+
+ emitpcode(POC_MOVFW,popGet(AOP(result),offr));
+ emitpcode(POC_ADDWF,popGet(AOP(result),offr));
+ emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
+
+ while(--shCount) {
+ emitCLRC;
+ emitpcode(POC_RLF, popGet(AOP(result),offr));
+ emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
+ }
+
+ break;
+ case 4:
+ case 5:
+ emitpcode(POC_MOVLW, popGetLit(0x0f));
+ emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_SWAPF, popGet(AOP(result),offr));
+ emitpcode(POC_ANDFW, popGet(AOP(result),offr));
+ emitpcode(POC_XORWF, popGet(AOP(result),offr));
+ emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
+ if(shCount >=5) {
+ emitpcode(POC_RLF, popGet(AOP(result),offr));
+ emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
+ }
+ break;
+ case 6:
+ emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_RRF, popGet(AOP(result),offr));
+ emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_RRF, popGet(AOP(result),offr));
+ emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_ANDLW,popGetLit(0xc0));
+ emitpcode(POC_XORFW,popGet(AOP(result),offr));
+ emitpcode(POC_XORWF,popGet(AOP(result),offr));
+ emitpcode(POC_XORFW,popGet(AOP(result),offr));
+ emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
+ break;
+ case 7:
+ emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_RRFW, popGet(AOP(result),offr));
+ emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_CLRF, popGet(AOP(result),offr));
+ emitpcode(POC_RRF, popGet(AOP(result),offr));
+ }
+
+ } else {
+ switch(shCount) {
+ case 0:
+ break;
+ case 1:
+ case 2:
+ case 3:
+ /* note, use a mov/add for the shift since the mov has a
+ chance of getting optimized out */
+ emitpcode(POC_MOVFW, popGet(AOP(left),offl));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offr));
+ emitpcode(POC_ADDWF, popGet(AOP(result),offr));
+ emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
+
+ while(--shCount) {
+ emitCLRC;
+ emitpcode(POC_RLF, popGet(AOP(result),offr));
+ emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
+ }
+ break;
+
+ case 4:
+ case 5:
+ emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
+ emitpcode(POC_ANDLW, popGetLit(0xF0));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offr));
+ emitpcode(POC_ANDLW, popGetLit(0xF0));
+ emitpcode(POC_XORWF, popGet(AOP(result),offr));
+ emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
+
+
+ if(shCount == 5) {
+ emitpcode(POC_RLF, popGet(AOP(result),offr));
+ emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
+ }
+ break;
+ case 6:
+ emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
+ emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_RRFW, popGet(AOP(result),offl));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offr));
+
+ emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_RRF, popGet(AOP(result),offr));
+ emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_ANDLW,popGetLit(0xc0));
+ emitpcode(POC_XORFW,popGet(AOP(result),offr));
+ emitpcode(POC_XORWF,popGet(AOP(result),offr));
+ emitpcode(POC_XORFW,popGet(AOP(result),offr));
+ emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
+ break;
+ case 7:
+ emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
+ emitpcode(POC_RRFW, popGet(AOP(left),offl));
+ emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_CLRF, popGet(AOP(result),offr));
+ emitpcode(POC_RRF, popGet(AOP(result),offr));
+ }
+ }
-#if 0
-/*-----------------------------------------------------------------*/
-/* shiftL2Left2Result - shift left two bytes from left to result */
-/*-----------------------------------------------------------------*/
-static void shiftL2Left2Result (operand *left, int offl,
- operand *result, int offr, int shCount)
-{
- FENTRY;
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- if(pic14_sameRegs(AOP(result), AOP(left))) {
- switch(shCount) {
- case 0:
- break;
- case 1:
- case 2:
- case 3:
-
- emitpcode(POC_MOVFW,popGet(AOP(result),offr));
- emitpcode(POC_ADDWF,popGet(AOP(result),offr));
- emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
-
- while(--shCount) {
- emitCLRC;
- emitpcode(POC_RLF, popGet(AOP(result),offr));
- emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
- }
-
- break;
- case 4:
- case 5:
- emitpcode(POC_MOVLW, popGetLit(0x0f));
- emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
- emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
- emitpcode(POC_SWAPF, popGet(AOP(result),offr));
- emitpcode(POC_ANDFW, popGet(AOP(result),offr));
- emitpcode(POC_XORWF, popGet(AOP(result),offr));
- emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
- if(shCount >=5) {
- emitpcode(POC_RLF, popGet(AOP(result),offr));
- emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
- }
- break;
- case 6:
- emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
- emitpcode(POC_RRF, popGet(AOP(result),offr));
- emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
- emitpcode(POC_RRF, popGet(AOP(result),offr));
- emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
- emitpcode(POC_ANDLW,popGetLit(0xc0));
- emitpcode(POC_XORFW,popGet(AOP(result),offr));
- emitpcode(POC_XORWF,popGet(AOP(result),offr));
- emitpcode(POC_XORFW,popGet(AOP(result),offr));
- emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
- break;
- case 7:
- emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
- emitpcode(POC_RRFW, popGet(AOP(result),offr));
- emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
- emitpcode(POC_CLRF, popGet(AOP(result),offr));
- emitpcode(POC_RRF, popGet(AOP(result),offr));
- }
-
- } else {
- switch(shCount) {
- case 0:
- break;
- case 1:
- case 2:
- case 3:
- /* note, use a mov/add for the shift since the mov has a
- chance of getting optimized out */
- emitpcode(POC_MOVFW, popGet(AOP(left),offl));
- emitpcode(POC_MOVWF, popGet(AOP(result),offr));
- emitpcode(POC_ADDWF, popGet(AOP(result),offr));
- emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
- emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
-
- while(--shCount) {
- emitCLRC;
- emitpcode(POC_RLF, popGet(AOP(result),offr));
- emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
- }
- break;
-
- case 4:
- case 5:
- emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
- emitpcode(POC_ANDLW, popGetLit(0xF0));
- emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
- emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
- emitpcode(POC_MOVWF, popGet(AOP(result),offr));
- emitpcode(POC_ANDLW, popGetLit(0xF0));
- emitpcode(POC_XORWF, popGet(AOP(result),offr));
- emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
-
-
- if(shCount == 5) {
- emitpcode(POC_RLF, popGet(AOP(result),offr));
- emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
- }
- break;
- case 6:
- emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
- emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
- emitpcode(POC_RRFW, popGet(AOP(result),offl));
- emitpcode(POC_MOVWF, popGet(AOP(result),offr));
-
- emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
- emitpcode(POC_RRF, popGet(AOP(result),offr));
- emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
- emitpcode(POC_ANDLW,popGetLit(0xc0));
- emitpcode(POC_XORFW,popGet(AOP(result),offr));
- emitpcode(POC_XORWF,popGet(AOP(result),offr));
- emitpcode(POC_XORFW,popGet(AOP(result),offr));
- emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
- break;
- case 7:
- emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
- emitpcode(POC_RRFW, popGet(AOP(left),offl));
- emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
- emitpcode(POC_CLRF, popGet(AOP(result),offr));
- emitpcode(POC_RRF, popGet(AOP(result),offr));
- }
- }
-
}
/*-----------------------------------------------------------------*/
/* shiftR2Left2Result - shift right two bytes from left to result */
/*-----------------------------------------------------------------*/
static void shiftR2Left2Result (operand *left, int offl,
- operand *result, int offr,
- int shCount, int sign)
-{
- int same=0;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- same = pic14_sameRegs(AOP(result), AOP(left));
-
- if(same && ((offl + MSB16) == offr)){
- same=1;
- /* don't crash result[offr] */
- MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
- pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
- }
- /* else {
- movLeft2Result(left,offl, result, offr);
- MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
- }
- */
- /* a:x >> shCount (x = lsb(result))*/
- /*
- if(sign)
- AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
- else {
- AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
- */
- switch(shCount) {
- case 0:
- break;
- case 1:
- case 2:
- case 3:
- if(sign)
- emitpcode(POC_RLFW,popGet(AOP(left),offl+MSB16));
- else
- emitCLRC;
-
- if(same) {
- emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
- emitpcode(POC_RRF,popGet(AOP(result),offr));
- } else {
- emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
- emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
- emitpcode(POC_RRFW, popGet(AOP(left),offl));
- emitpcode(POC_MOVWF,popGet(AOP(result),offr));
- }
-
- while(--shCount) {
- if(sign)
- emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
- else
- emitCLRC;
- emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
- emitpcode(POC_RRF,popGet(AOP(result),offr));
- }
- break;
- case 4:
- case 5:
- if(same) {
-
- emitpcode(POC_MOVLW, popGetLit(0xf0));
- emitpcode(POC_ANDWF, popGet(AOP(result),offr));
- emitpcode(POC_SWAPF, popGet(AOP(result),offr));
-
- emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
- emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
- emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
- emitpcode(POC_ADDWF, popGet(AOP(result),offr));
- } else {
- emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
- emitpcode(POC_ANDLW, popGetLit(0x0f));
- emitpcode(POC_MOVWF, popGet(AOP(result),offr));
-
- emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
- emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
- emitpcode(POC_ANDLW, popGetLit(0xf0));
- emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
- emitpcode(POC_ADDWF, popGet(AOP(result),offr));
- }
-
- if(shCount >=5) {
- emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
- emitpcode(POC_RRF, popGet(AOP(result),offr));
- }
-
- if(sign) {
- emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
- emitpcode(POC_BTFSC,
- newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
- emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
- }
-
- break;
-
- case 6:
- if(same) {
-
- emitpcode(POC_RLF, popGet(AOP(result),offr));
- emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
-
- emitpcode(POC_RLF, popGet(AOP(result),offr));
- emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
- emitpcode(POC_RLFW, popGet(AOP(result),offr));
- emitpcode(POC_ANDLW,popGetLit(0x03));
- if(sign) {
- emitpcode(POC_BTFSC,
- newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
- emitpcode(POC_IORLW,popGetLit(0xfc));
- }
- emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
- emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
- emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
- emitpcode(POC_MOVWF,popGet(AOP(result),offr));
- } else {
- emitpcode(POC_RLFW, popGet(AOP(left),offl));
- emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
- emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
- emitpcode(POC_MOVWF,popGet(AOP(result),offr));
- emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
- emitpcode(POC_RLF, popGet(AOP(result),offr));
- emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
- emitpcode(POC_ANDLW,popGetLit(0x03));
- if(sign) {
- emitpcode(POC_BTFSC,
- newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
- emitpcode(POC_IORLW,popGetLit(0xfc));
- }
- emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
- //emitpcode(POC_RLF, popGet(AOP(result),offr));
-
-
- }
-
- break;
- case 7:
- emitpcode(POC_RLFW, popGet(AOP(left),offl));
- emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
- emitpcode(POC_MOVWF,popGet(AOP(result),offr));
- emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
- if(sign) {
- emitSKPNC;
- emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
- } else
- emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
+ operand *result, int offr,
+ int shCount, int sign)
+{
+ int same=0;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ same = pic14_sameRegs(AOP(result), AOP(left));
+
+ if(same && ((offl + MSB16) == offr)){
+ same=1;
+ /* don't crash result[offr] */
+ MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
+ pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
+ }
+ /* else {
+ movLeft2Result(left,offl, result, offr);
+ MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
+ }
+ */
+ /* a:x >> shCount (x = lsb(result))*/
+ /*
+ if(sign)
+ AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
+ else {
+ AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
+ */
+ switch(shCount) {
+ case 0:
+ break;
+ case 1:
+ case 2:
+ case 3:
+ if(sign)
+ emitpcode(POC_RLFW,popGet(AOP(left),offl+MSB16));
+ else
+ emitCLRC;
+
+ if(same) {
+ emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_RRF,popGet(AOP(result),offr));
+ } else {
+ emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
+ emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_RRFW, popGet(AOP(left),offl));
+ emitpcode(POC_MOVWF,popGet(AOP(result),offr));
+ }
+
+ while(--shCount) {
+ if(sign)
+ emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
+ else
+ emitCLRC;
+ emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_RRF,popGet(AOP(result),offr));
+ }
+ break;
+ case 4:
+ case 5:
+ if(same) {
+
+ emitpcode(POC_MOVLW, popGetLit(0xf0));
+ emitpcode(POC_ANDWF, popGet(AOP(result),offr));
+ emitpcode(POC_SWAPF, popGet(AOP(result),offr));
+
+ emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_ADDWF, popGet(AOP(result),offr));
+ } else {
+ emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
+ emitpcode(POC_ANDLW, popGetLit(0x0f));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offr));
+
+ emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_ANDLW, popGetLit(0xf0));
+ emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_ADDWF, popGet(AOP(result),offr));
+ }
+
+ if(shCount >=5) {
+ emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_RRF, popGet(AOP(result),offr));
+ }
+
+ if(sign) {
+ emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
+ emitpcode(POC_BTFSC,
+ newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
+ emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
+ }
+
+ break;
+
+ case 6:
+ if(same) {
+
+ emitpcode(POC_RLF, popGet(AOP(result),offr));
+ emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
+
+ emitpcode(POC_RLF, popGet(AOP(result),offr));
+ emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_RLFW, popGet(AOP(result),offr));
+ emitpcode(POC_ANDLW,popGetLit(0x03));
+ if(sign) {
+ emitpcode(POC_BTFSC,
+ newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
+ emitpcode(POC_IORLW,popGetLit(0xfc));
+ }
+ emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_MOVWF,popGet(AOP(result),offr));
+ } else {
+ emitpcode(POC_RLFW, popGet(AOP(left),offl));
+ emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
+ emitpcode(POC_MOVWF,popGet(AOP(result),offr));
+ emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_RLF, popGet(AOP(result),offr));
+ emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
+ emitpcode(POC_ANDLW,popGetLit(0x03));
+ if(sign) {
+ emitpcode(POC_BTFSC,
+ newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
+ emitpcode(POC_IORLW,popGetLit(0xfc));
+ }
+ emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
+ //emitpcode(POC_RLF, popGet(AOP(result),offr));
+
+
+ }
+
+ break;
+ case 7:
+ emitpcode(POC_RLFW, popGet(AOP(left),offl));
+ emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
+ emitpcode(POC_MOVWF,popGet(AOP(result),offr));
+ emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
+ if(sign) {
+ emitSKPNC;
+ emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
+ } else
+ emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
}
}
/* shiftLLeftOrResult - shift left one byte from left, or to result*/
/*-----------------------------------------------------------------*/
static void shiftLLeftOrResult (operand *left, int offl,
- operand *result, int offr, int shCount)
+ operand *result, int offr, int shCount)
{
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- /* shift left accumulator */
- AccLsh(left,offl,shCount);
- /* or with result */
- emitpcode (POC_IORWF, popGet (AOP(result), offr));
- assert ( !"broken (modifies left, fails for left==result))" );
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ /* shift left accumulator */
+ AccLsh(left,offl,shCount);
+ /* or with result */
+ emitpcode (POC_IORWF, popGet (AOP(result), offr));
+ assert ( !"broken (modifies left, fails for left==result))" );
}
/*-----------------------------------------------------------------*/
/* shiftRLeftOrResult - shift right one byte from left,or to result*/
/*-----------------------------------------------------------------*/
static void shiftRLeftOrResult (operand *left, int offl,
- operand *result, int offr, int shCount)
+ operand *result, int offr, int shCount)
{
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- /* shift right accumulator */
- AccRsh(left,offl,shCount);
- /* or with result */
- emitpcode (POC_IORWF, popGet (AOP(result), offr));
- assert ( !"broken (modifies left, fails for left==result))" );
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ /* shift right accumulator */
+ AccRsh(left,offl,shCount);
+ /* or with result */
+ emitpcode (POC_IORWF, popGet (AOP(result), offr));
+ assert ( !"broken (modifies left, fails for left==result))" );
}
/*-----------------------------------------------------------------*/
/* genlshOne - left shift a one byte quantity by known count */
/*-----------------------------------------------------------------*/
static void genlshOne (operand *result, operand *left, int shCount)
-{
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- shiftL1Left2Result(left, LSB, result, LSB, shCount);
+{
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ shiftL1Left2Result(left, LSB, result, LSB, shCount);
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static void genlshTwo (operand *result,operand *left, int shCount)
{
- int size;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- size = pic14_getDataSize(result);
-
- /* if shCount >= 8 */
- if (shCount >= 8) {
- shCount -= 8 ;
-
- if (size > 1){
- if (shCount)
- shiftL1Left2Result(left, LSB, result, MSB16, shCount);
- else
- movLeft2Result(left, LSB, result, MSB16);
- }
- emitpcode(POC_CLRF,popGet(AOP(result),LSB));
- }
-
- /* 1 <= shCount <= 7 */
- else {
- if(size == 1)
- shiftL1Left2Result(left, LSB, result, LSB, shCount);
- else
- shiftL2Left2Result(left, LSB, result, LSB, shCount);
- }
+ int size;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ size = pic14_getDataSize(result);
+
+ /* if shCount >= 8 */
+ if (shCount >= 8) {
+ shCount -= 8 ;
+
+ if (size > 1){
+ if (shCount)
+ shiftL1Left2Result(left, LSB, result, MSB16, shCount);
+ else
+ movLeft2Result(left, LSB, result, MSB16);
+ }
+ emitpcode(POC_CLRF,popGet(AOP(result),LSB));
+ }
+
+ /* 1 <= shCount <= 7 */
+ else {
+ if(size == 1)
+ shiftL1Left2Result(left, LSB, result, LSB, shCount);
+ else
+ shiftL2Left2Result(left, LSB, result, LSB, shCount);
+ }
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static void shiftLLong (operand *left, operand *result, int offr )
{
- char *l;
- int size = AOP_SIZE(result);
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if(size >= LSB+offr){
- l = aopGet(AOP(left),LSB,FALSE,FALSE);
- MOVA(l);
- pic14_emitcode("add","a,acc");
- if (pic14_sameRegs(AOP(left),AOP(result)) &&
- size >= MSB16+offr && offr != LSB )
- pic14_emitcode("xch","a,%s",
- aopGet(AOP(left),LSB+offr,FALSE,FALSE));
- else
- aopPut(AOP(result),"a",LSB+offr);
- }
-
- if(size >= MSB16+offr){
- if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
- l = aopGet(AOP(left),MSB16,FALSE,FALSE);
- MOVA(l);
- }
- pic14_emitcode("rlc","a");
- if (pic14_sameRegs(AOP(left),AOP(result)) &&
- size >= MSB24+offr && offr != LSB)
- pic14_emitcode("xch","a,%s",
- aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
- else
- aopPut(AOP(result),"a",MSB16+offr);
- }
-
- if(size >= MSB24+offr){
- if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
- l = aopGet(AOP(left),MSB24,FALSE,FALSE);
- MOVA(l);
- }
- pic14_emitcode("rlc","a");
- if (pic14_sameRegs(AOP(left),AOP(result)) &&
- size >= MSB32+offr && offr != LSB )
- pic14_emitcode("xch","a,%s",
- aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
- else
- aopPut(AOP(result),"a",MSB24+offr);
- }
-
- if(size > MSB32+offr){
- if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
- l = aopGet(AOP(left),MSB32,FALSE,FALSE);
- MOVA(l);
- }
- pic14_emitcode("rlc","a");
- aopPut(AOP(result),"a",MSB32+offr);
- }
- if(offr != LSB)
- aopPut(AOP(result),zero,LSB);
+ char *l;
+ int size = AOP_SIZE(result);
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ if(size >= LSB+offr){
+ l = aopGet(AOP(left),LSB,FALSE,FALSE);
+ MOVA(l);
+ pic14_emitcode("add","a,acc");
+ if (pic14_sameRegs(AOP(left),AOP(result)) &&
+ size >= MSB16+offr && offr != LSB )
+ pic14_emitcode("xch","a,%s",
+ aopGet(AOP(left),LSB+offr,FALSE,FALSE));
+ else
+ aopPut(AOP(result),"a",LSB+offr);
+ }
+
+ if(size >= MSB16+offr){
+ if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
+ l = aopGet(AOP(left),MSB16,FALSE,FALSE);
+ MOVA(l);
+ }
+ pic14_emitcode("rlc","a");
+ if (pic14_sameRegs(AOP(left),AOP(result)) &&
+ size >= MSB24+offr && offr != LSB)
+ pic14_emitcode("xch","a,%s",
+ aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
+ else
+ aopPut(AOP(result),"a",MSB16+offr);
+ }
+
+ if(size >= MSB24+offr){
+ if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
+ l = aopGet(AOP(left),MSB24,FALSE,FALSE);
+ MOVA(l);
+ }
+ pic14_emitcode("rlc","a");
+ if (pic14_sameRegs(AOP(left),AOP(result)) &&
+ size >= MSB32+offr && offr != LSB )
+ pic14_emitcode("xch","a,%s",
+ aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
+ else
+ aopPut(AOP(result),"a",MSB24+offr);
+ }
+
+ if(size > MSB32+offr){
+ if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
+ l = aopGet(AOP(left),MSB32,FALSE,FALSE);
+ MOVA(l);
+ }
+ pic14_emitcode("rlc","a");
+ aopPut(AOP(result),"a",MSB32+offr);
+ }
+ if(offr != LSB)
+ aopPut(AOP(result),zero,LSB);
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static void genlshFour (operand *result, operand *left, int shCount)
{
- int size;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- size = AOP_SIZE(result);
-
- /* if shifting more that 3 bytes */
- if (shCount >= 24 ) {
- shCount -= 24;
- if (shCount)
- /* lowest order of left goes to the highest
- order of the destination */
- shiftL1Left2Result(left, LSB, result, MSB32, shCount);
- else
- movLeft2Result(left, LSB, result, MSB32);
- aopPut(AOP(result),zero,LSB);
- aopPut(AOP(result),zero,MSB16);
- aopPut(AOP(result),zero,MSB32);
- return;
- }
-
- /* more than two bytes */
- else if ( shCount >= 16 ) {
- /* lower order two bytes goes to higher order two bytes */
- shCount -= 16;
- /* if some more remaining */
- if (shCount)
- shiftL2Left2Result(left, LSB, result, MSB24, shCount);
- else {
- movLeft2Result(left, MSB16, result, MSB32);
- movLeft2Result(left, LSB, result, MSB24);
- }
- aopPut(AOP(result),zero,MSB16);
- aopPut(AOP(result),zero,LSB);
- return;
- }
-
- /* if more than 1 byte */
- else if ( shCount >= 8 ) {
- /* lower order three bytes goes to higher order three bytes */
- shCount -= 8;
- if(size == 2){
- if(shCount)
- shiftL1Left2Result(left, LSB, result, MSB16, shCount);
- else
- movLeft2Result(left, LSB, result, MSB16);
- }
- else{ /* size = 4 */
- if(shCount == 0){
- movLeft2Result(left, MSB24, result, MSB32);
- movLeft2Result(left, MSB16, result, MSB24);
- movLeft2Result(left, LSB, result, MSB16);
- aopPut(AOP(result),zero,LSB);
- }
- else if(shCount == 1)
- shiftLLong(left, result, MSB16);
- else{
- shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
- shiftL1Left2Result(left, LSB, result, MSB16, shCount);
- shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
- aopPut(AOP(result),zero,LSB);
- }
- }
- }
-
- /* 1 <= shCount <= 7 */
- else if(shCount <= 2){
- shiftLLong(left, result, LSB);
- if(shCount == 2)
- shiftLLong(result, result, LSB);
- }
- /* 3 <= shCount <= 7, optimize */
- else{
- shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
- shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
- shiftL2Left2Result(left, LSB, result, LSB, shCount);
- }
+ int size;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ size = AOP_SIZE(result);
+
+ /* if shifting more that 3 bytes */
+ if (shCount >= 24 ) {
+ shCount -= 24;
+ if (shCount)
+ /* lowest order of left goes to the highest
+ order of the destination */
+ shiftL1Left2Result(left, LSB, result, MSB32, shCount);
+ else
+ movLeft2Result(left, LSB, result, MSB32);
+ aopPut(AOP(result),zero,LSB);
+ aopPut(AOP(result),zero,MSB16);
+ aopPut(AOP(result),zero,MSB32);
+ return;
+ }
+
+ /* more than two bytes */
+ else if ( shCount >= 16 ) {
+ /* lower order two bytes goes to higher order two bytes */
+ shCount -= 16;
+ /* if some more remaining */
+ if (shCount)
+ shiftL2Left2Result(left, LSB, result, MSB24, shCount);
+ else {
+ movLeft2Result(left, MSB16, result, MSB32);
+ movLeft2Result(left, LSB, result, MSB24);
+ }
+ aopPut(AOP(result),zero,MSB16);
+ aopPut(AOP(result),zero,LSB);
+ return;
+ }
+
+ /* if more than 1 byte */
+ else if ( shCount >= 8 ) {
+ /* lower order three bytes goes to higher order three bytes */
+ shCount -= 8;
+ if(size == 2){
+ if(shCount)
+ shiftL1Left2Result(left, LSB, result, MSB16, shCount);
+ else
+ movLeft2Result(left, LSB, result, MSB16);
+ }
+ else{ /* size = 4 */
+ if(shCount == 0){
+ movLeft2Result(left, MSB24, result, MSB32);
+ movLeft2Result(left, MSB16, result, MSB24);
+ movLeft2Result(left, LSB, result, MSB16);
+ aopPut(AOP(result),zero,LSB);
+ }
+ else if(shCount == 1)
+ shiftLLong(left, result, MSB16);
+ else{
+ shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
+ shiftL1Left2Result(left, LSB, result, MSB16, shCount);
+ shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
+ aopPut(AOP(result),zero,LSB);
+ }
+ }
+ }
+
+ /* 1 <= shCount <= 7 */
+ else if(shCount <= 2){
+ shiftLLong(left, result, LSB);
+ if(shCount == 2)
+ shiftLLong(result, result, LSB);
+ }
+ /* 3 <= shCount <= 7, optimize */
+ else{
+ shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
+ shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
+ shiftL2Left2Result(left, LSB, result, LSB, shCount);
+ }
}
#endif
/* genLeftShiftLiteral - left shifting by known count */
/*-----------------------------------------------------------------*/
static void genLeftShiftLiteral (operand *left,
- operand *right,
- operand *result,
- iCode *ic)
-{
- int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
- //int size;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- freeAsmop(right,NULL,ic,TRUE);
-
- aopOp(left,ic,FALSE);
- aopOp(result,ic,FALSE);
-
- size = getSize(operandType(result));
-
+ operand *right,
+ operand *result,
+ iCode *ic)
+{
+ int shCount = (int) ulFromVal (AOP(right)->aopu.aop_lit);
+ //int size;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ freeAsmop(right,NULL,ic,TRUE);
+
+ aopOp(left,ic,FALSE);
+ aopOp(result,ic,FALSE);
+
+ size = getSize(operandType(result));
+
#if VIEW_SIZE
- pic14_emitcode("; shift left ","result %d, left %d",size,
- AOP_SIZE(left));
+ pic14_emitcode("; shift left ","result %d, left %d",size,
+ AOP_SIZE(left));
#endif
-
- /* I suppose that the left size >= result size */
- if(shCount == 0){
- while(size--){
- movLeft2Result(left, size, result, size);
- }
- }
-
- else if(shCount >= (size * 8))
- while(size--)
- aopPut(AOP(result),zero,size);
- else{
- switch (size) {
- case 1:
- genlshOne (result,left,shCount);
- break;
-
- case 2:
- case 3:
- genlshTwo (result,left,shCount);
- break;
-
- case 4:
- genlshFour (result,left,shCount);
- break;
- }
- }
- freeAsmop(left,NULL,ic,TRUE);
- freeAsmop(result,NULL,ic,TRUE);
+
+ /* I suppose that the left size >= result size */
+ if(shCount == 0){
+ while(size--){
+ movLeft2Result(left, size, result, size);
+ }
+ }
+
+ else if(shCount >= (size * 8))
+ while(size--)
+ aopPut(AOP(result),zero,size);
+ else{
+ switch (size) {
+ case 1:
+ genlshOne (result,left,shCount);
+ break;
+
+ case 2:
+ case 3:
+ genlshTwo (result,left,shCount);
+ break;
+
+ case 4:
+ genlshFour (result,left,shCount);
+ break;
+ }
+ }
+ freeAsmop(left,NULL,ic,TRUE);
+ freeAsmop(result,NULL,ic,TRUE);
}
#endif
/*-----------------------------------------------------------------*
* genMultiAsm - repeat assembly instruction for size of register.
-* if endian == 1, then the high byte (i.e base address + size of
+* if endian == 1, then the high byte (i.e base address + size of
* register) is used first else the low byte is used first;
*-----------------------------------------------------------------*/
static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
{
-
- int offset = 0;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- if(!reg)
- return;
-
- if(!endian) {
- endian = 1;
- } else {
- endian = -1;
- offset = size-1;
- }
-
- while(size--) {
- emitpcode(poc, popGet(AOP(reg),offset));
- offset += endian;
- }
-
+
+ int offset = 0;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ if(!reg)
+ return;
+
+ if(!endian) {
+ endian = 1;
+ } else {
+ endian = -1;
+ offset = size-1;
+ }
+
+ while(size--) {
+ emitpcode(poc, popGet(AOP(reg),offset));
+ offset += endian;
+ }
+
}
#if 0
/*-----------------------------------------------------------------*/
static void genLeftShift (iCode *ic)
{
- operand *left,*right, *result;
- int size, offset;
- unsigned long lit = 0L;
- char *l;
- symbol *tlbl , *tlbl1;
- pCodeOp *pctemp;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- right = IC_RIGHT(ic);
- left = IC_LEFT(ic);
- result = IC_RESULT(ic);
-
- aopOp(right,ic,FALSE);
- aopOp(left,ic,FALSE);
- aopOp(result,ic,FALSE);
-
-
- /* if the shift count is known then do it
- as efficiently as possible */
- if (AOP_TYPE(right) == AOP_LIT) {
- shiftLeft_Left2ResultLit (left, result, (int) floatFromVal (AOP(right)->aopu.aop_lit));
- return ;
- }
-
- /* shift count is unknown then we have to form
- a loop get the loop count in B : Note: we take
- only the lower order byte since shifting
- more that 32 bits make no sense anyway, ( the
- largest size of an object can be only 32 bits ) */
-
- /* this code fails for RIGHT == RESULT */
- assert (!pic14_sameRegs (AOP(right), AOP(result)));
-
- /* now move the left to the result if they are not the
- same */
- if (!pic14_sameRegs(AOP(left),AOP(result)) &&
- AOP_SIZE(result) > 1) {
-
- size = AOP_SIZE(result);
- offset=0;
- while (size--) {
- l = aopGet(AOP(left),offset,FALSE,TRUE);
- if (*l == '@' && (IS_AOP_PREG(result))) {
-
- pic14_emitcode("mov","a,%s",l);
- aopPut(AOP(result),"a",offset);
- } else {
- emitpcode(POC_MOVFW, popGet(AOP(left),offset));
- emitpcode(POC_MOVWF, popGet(AOP(result),offset));
- //aopPut(AOP(result),l,offset);
- }
- offset++;
- }
- }
-
- if(AOP_TYPE(left) == AOP_LIT)
- lit = (unsigned long)floatFromVal (AOP(left)->aopu.aop_lit);
-
- size = AOP_SIZE(result);
-
- /* if it is only one byte then */
- if (size == 1) {
- if(optimized_for_speed && AOP_TYPE(left)!=AOP_LIT) {
- emitpcode(POC_SWAPFW, popGet(AOP(left),0));
- emitpcode(POC_ANDLW, popGetLit(0xf0));
- emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_MOVWF, popGet(AOP(result),0));
- emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
- emitpcode(POC_ADDWF, popGet(AOP(result),0));
- emitpcode(POC_RLFW, popGet(AOP(result),0));
- emitpcode(POC_ANDLW, popGetLit(0xfe));
- emitpcode(POC_ADDFW, popGet(AOP(result),0));
- emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
- emitpcode(POC_ADDWF, popGet(AOP(result),0));
- } else {
-
- tlbl = newiTempLabel(NULL);
- if (!pic14_sameRegs(AOP(left),AOP(result))) {
- mov2w (AOP(left), 0);
- emitpcode(POC_MOVWF, popGet(AOP(result),0));
- }
-
- emitpcode(POC_COMFW, popGet(AOP(right),0));
- emitpcode(POC_RRF, popGet(AOP(result),0));
- emitpLabel(tlbl->key);
- emitpcode(POC_RLF, popGet(AOP(result),0));
- emitpcode(POC_ADDLW, popGetLit(1));
- emitSKPC;
- emitpcode(POC_GOTO,popGetLabel(tlbl->key));
- }
- goto release ;
- }
-
- if (pic14_sameRegs(AOP(left),AOP(result))) {
-
- tlbl = newiTempLabel(NULL);
- emitpcode(POC_COMFW, popGet(AOP(right),0));
- genMultiAsm(POC_RRF, result, size,1);
- emitpLabel(tlbl->key);
- genMultiAsm(POC_RLF, result, size,0);
- emitpcode(POC_ADDLW, popGetLit(1));
- emitSKPC;
- emitpcode(POC_GOTO,popGetLabel(tlbl->key));
- goto release;
- }
-
- //tlbl = newiTempLabel(NULL);
- //offset = 0 ;
- //tlbl1 = newiTempLabel(NULL);
-
- //reAdjustPreg(AOP(result));
-
- //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
- //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
- //l = aopGet(AOP(result),offset,FALSE,FALSE);
- //MOVA(l);
- //pic14_emitcode("add","a,acc");
- //aopPut(AOP(result),"a",offset++);
- //while (--size) {
- // l = aopGet(AOP(result),offset,FALSE,FALSE);
- // MOVA(l);
- // pic14_emitcode("rlc","a");
- // aopPut(AOP(result),"a",offset++);
- //}
- //reAdjustPreg(AOP(result));
-
- //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
- //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
-
-
- tlbl = newiTempLabel(NULL);
- tlbl1= newiTempLabel(NULL);
-
- size = AOP_SIZE(result);
- offset = 1;
-
- pctemp = popGetTempReg(); /* grab a temporary working register. */
-
- emitpcode(POC_MOVFW, popGet(AOP(right),0));
-
- /* offset should be 0, 1 or 3 */
- emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
- emitSKPNZ;
- emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
-
- emitpcode(POC_MOVWF, pctemp);
-
-
- emitpLabel(tlbl->key);
-
- emitCLRC;
- emitpcode(POC_RLF, popGet(AOP(result),0));
- while(--size)
- emitpcode(POC_RLF, popGet(AOP(result),offset++));
-
- emitpcode(POC_DECFSZ, pctemp);
- emitpcode(POC_GOTO,popGetLabel(tlbl->key));
- emitpLabel(tlbl1->key);
-
- popReleaseTempReg(pctemp);
-
-
+ operand *left,*right, *result;
+ int size, offset;
+ unsigned long lit = 0L;
+ char *l;
+ symbol *tlbl , *tlbl1;
+ pCodeOp *pctemp;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ right = IC_RIGHT(ic);
+ left = IC_LEFT(ic);
+ result = IC_RESULT(ic);
+
+ aopOp(right,ic,FALSE);
+ aopOp(left,ic,FALSE);
+ aopOp(result,ic,FALSE);
+
+
+ /* if the shift count is known then do it
+ as efficiently as possible */
+ if (AOP_TYPE(right) == AOP_LIT) {
+ shiftLeft_Left2ResultLit (left, result, (int) ulFromVal (AOP(right)->aopu.aop_lit));
+ return ;
+ }
+
+ /* shift count is unknown then we have to form
+ a loop get the loop count in B : Note: we take
+ only the lower order byte since shifting
+ more that 32 bits make no sense anyway, ( the
+ largest size of an object can be only 32 bits ) */
+
+ /* this code fails for RIGHT == RESULT */
+ assert (!pic14_sameRegs (AOP(right), AOP(result)));
+
+ /* now move the left to the result if they are not the
+ same */
+ if (!pic14_sameRegs(AOP(left),AOP(result)) &&
+ AOP_SIZE(result) > 1) {
+
+ size = AOP_SIZE(result);
+ offset=0;
+ while (size--) {
+ l = aopGet(AOP(left),offset,FALSE,TRUE);
+ if (*l == '@' && (IS_AOP_PREG(result))) {
+
+ pic14_emitcode("mov","a,%s",l);
+ aopPut(AOP(result),"a",offset);
+ } else {
+ emitpcode(POC_MOVFW, popGet(AOP(left),offset));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offset));
+ //aopPut(AOP(result),l,offset);
+ }
+ offset++;
+ }
+ }
+
+ if(AOP_TYPE(left) == AOP_LIT)
+ lit = ulFromVal (AOP(left)->aopu.aop_lit);
+
+ size = AOP_SIZE(result);
+
+ /* if it is only one byte then */
+ if (size == 1) {
+ if(optimized_for_speed && AOP_TYPE(left)!=AOP_LIT) {
+ emitpcode(POC_SWAPFW, popGet(AOP(left),0));
+ emitpcode(POC_ANDLW, popGetLit(0xf0));
+ emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ emitpcode(POC_MOVWF, popGet(AOP(result),0));
+ emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
+ emitpcode(POC_ADDWF, popGet(AOP(result),0));
+ emitpcode(POC_RLFW, popGet(AOP(result),0));
+ emitpcode(POC_ANDLW, popGetLit(0xfe));
+ emitpcode(POC_ADDFW, popGet(AOP(result),0));
+ emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
+ emitpcode(POC_ADDWF, popGet(AOP(result),0));
+ } else {
+
+ tlbl = newiTempLabel(NULL);
+ if (!pic14_sameRegs(AOP(left),AOP(result))) {
+ mov2w (AOP(left), 0);
+ emitpcode(POC_MOVWF, popGet(AOP(result),0));
+ }
+
+ emitpcode(POC_COMFW, popGet(AOP(right),0));
+ emitpcode(POC_RRF, popGet(AOP(result),0));
+ emitpLabel(tlbl->key);
+ emitpcode(POC_RLF, popGet(AOP(result),0));
+ emitpcode(POC_ADDLW, popGetLit(1));
+ emitSKPC;
+ emitpcode(POC_GOTO,popGetLabel(tlbl->key));
+ }
+ goto release ;
+ }
+
+ if (pic14_sameRegs(AOP(left),AOP(result))) {
+
+ tlbl = newiTempLabel(NULL);
+ emitpcode(POC_COMFW, popGet(AOP(right),0));
+ genMultiAsm(POC_RRF, result, size,1);
+ emitpLabel(tlbl->key);
+ genMultiAsm(POC_RLF, result, size,0);
+ emitpcode(POC_ADDLW, popGetLit(1));
+ emitSKPC;
+ emitpcode(POC_GOTO,popGetLabel(tlbl->key));
+ goto release;
+ }
+
+ //tlbl = newiTempLabel(NULL);
+ //offset = 0 ;
+ //tlbl1 = newiTempLabel(NULL);
+
+ //reAdjustPreg(AOP(result));
+
+ //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
+ //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
+ //l = aopGet(AOP(result),offset,FALSE,FALSE);
+ //MOVA(l);
+ //pic14_emitcode("add","a,acc");
+ //aopPut(AOP(result),"a",offset++);
+ //while (--size) {
+ // l = aopGet(AOP(result),offset,FALSE,FALSE);
+ // MOVA(l);
+ // pic14_emitcode("rlc","a");
+ // aopPut(AOP(result),"a",offset++);
+ //}
+ //reAdjustPreg(AOP(result));
+
+ //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
+ //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
+
+
+ tlbl = newiTempLabel(NULL);
+ tlbl1= newiTempLabel(NULL);
+
+ size = AOP_SIZE(result);
+ offset = 1;
+
+ pctemp = popGetTempReg(); /* grab a temporary working register. */
+
+ emitpcode(POC_MOVFW, popGet(AOP(right),0));
+
+ /* offset should be 0, 1 or 3 */
+ emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
+ emitSKPNZ;
+ emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
+
+ emitpcode(POC_MOVWF, pctemp);
+
+
+ emitpLabel(tlbl->key);
+
+ emitCLRC;
+ emitpcode(POC_RLF, popGet(AOP(result),0));
+ while(--size)
+ emitpcode(POC_RLF, popGet(AOP(result),offset++));
+
+ emitpcode(POC_DECFSZ, pctemp);
+ emitpcode(POC_GOTO,popGetLabel(tlbl->key));
+ emitpLabel(tlbl1->key);
+
+ popReleaseTempReg(pctemp);
+
+
release:
- freeAsmop (right,NULL,ic,TRUE);
- freeAsmop(left,NULL,ic,TRUE);
- freeAsmop(result,NULL,ic,TRUE);
+ freeAsmop (right,NULL,ic,TRUE);
+ freeAsmop(left,NULL,ic,TRUE);
+ freeAsmop(result,NULL,ic,TRUE);
}
#endif
/* genrshOne - right shift a one byte quantity by known count */
/*-----------------------------------------------------------------*/
static void genrshOne (operand *result, operand *left,
- int shCount, int sign)
+ int shCount, int sign)
{
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
}
/*-----------------------------------------------------------------*/
/* genrshTwo - right shift two bytes by known amount != 0 */
/*-----------------------------------------------------------------*/
static void genrshTwo (operand *result,operand *left,
- int shCount, int sign)
-{
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- /* if shCount >= 8 */
- if (shCount >= 8) {
- shCount -= 8 ;
- if (shCount)
- shiftR1Left2Result(left, MSB16, result, LSB,
- shCount, sign);
- else
- movLeft2Result(left, MSB16, result, LSB);
-
- emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
-
- if(sign) {
- emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
- emitpcode(POC_DECF, popGet(AOP(result),MSB16));
- }
- }
-
- /* 1 <= shCount <= 7 */
- else
- shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
+ int shCount, int sign)
+{
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* if shCount >= 8 */
+ if (shCount >= 8) {
+ shCount -= 8 ;
+ if (shCount)
+ shiftR1Left2Result(left, MSB16, result, LSB,
+ shCount, sign);
+ else
+ movLeft2Result(left, MSB16, result, LSB);
+
+ emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
+
+ if(sign) {
+ emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
+ emitpcode(POC_DECF, popGet(AOP(result),MSB16));
+ }
+ }
+
+ /* 1 <= shCount <= 7 */
+ else
+ shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
}
/*-----------------------------------------------------------------*/
/* offl = LSB or MSB16 */
/*-----------------------------------------------------------------*/
static void shiftRLong (operand *left, int offl,
- operand *result, int sign)
+ operand *result, int sign)
{
- int size, same;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- size = AOP_SIZE(left);
- if (AOP_SIZE(result) < size) size = AOP_SIZE(result);
-
- if (sign)
- emitpcode (POC_RLFW, popGet (AOP(left), AOP_SIZE(left)-1));
- else
- emitCLRC;
+ int size, same;
- assert (offl >= 0 && offl < size);
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ size = AOP_SIZE(left);
+ if (AOP_SIZE(result) < size) size = AOP_SIZE(result);
+
+ if (sign)
+ emitpcode (POC_RLFW, popGet (AOP(left), AOP_SIZE(left)-1));
+ else
+ emitCLRC;
+
+ assert (offl >= 0 && offl < size);
- same = pic14_sameRegs (AOP(left), AOP(result));
+ same = pic14_sameRegs (AOP(left), AOP(result));
- /* perform the shift */
- while (size--)
- {
- if (same && !offl) {
- emitpcode (POC_RRF, popGet (AOP(result), size));
- } else {
- emitpcode (POC_RRFW, popGet (AOP(left), size));
- emitpcode (POC_MOVWF, popGet (AOP(result), size-offl));
- }
- } // while
+ /* perform the shift */
+ while (size--)
+ {
+ if (same && !offl) {
+ emitpcode (POC_RRF, popGet (AOP(result), size));
+ } else {
+ emitpcode (POC_RRFW, popGet (AOP(left), size));
+ emitpcode (POC_MOVWF, popGet (AOP(result), size-offl));
+ }
+ } // while
- addSign (result, AOP_SIZE(left) - offl, sign);
+ addSign (result, AOP_SIZE(left) - offl, sign);
}
/*-----------------------------------------------------------------*/
/* genrshFour - shift four byte by a known amount != 0 */
/*-----------------------------------------------------------------*/
static void genrshFour (operand *result, operand *left,
- int shCount, int sign)
-{
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- /* if shifting more that 3 bytes */
- if(shCount >= 24 ) {
- shCount -= 24;
- if(shCount)
- shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
- else
- movLeft2Result(left, MSB32, result, LSB);
-
- addSign(result, MSB16, sign);
- }
- else if(shCount >= 16){
- shCount -= 16;
- if(shCount)
- shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
- else{
- movLeft2Result(left, MSB24, result, LSB);
- movLeft2Result(left, MSB32, result, MSB16);
- }
- addSign(result, MSB24, sign);
- }
- else if(shCount >= 8){
- shCount -= 8;
- if(shCount == 1)
- shiftRLong(left, MSB16, result, sign);
- else if(shCount == 0){
- movLeft2Result(left, MSB16, result, LSB);
- movLeft2Result(left, MSB24, result, MSB16);
- movLeft2Result(left, MSB32, result, MSB24);
- addSign(result, MSB32, sign);
- }
- else{
- shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
- shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
- /* the last shift is signed */
- shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
- addSign(result, MSB32, sign);
- }
- }
- else{ /* 1 <= shCount <= 7 */
- if(shCount <= 2){
- shiftRLong(left, LSB, result, sign);
- if(shCount == 2)
- shiftRLong(result, LSB, result, sign);
- }
- else{
- shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
- shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
- shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
- }
- }
+ int shCount, int sign)
+{
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* if shifting more that 3 bytes */
+ if(shCount >= 24 ) {
+ shCount -= 24;
+ if(shCount)
+ shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
+ else
+ movLeft2Result(left, MSB32, result, LSB);
+
+ addSign(result, MSB16, sign);
+ }
+ else if(shCount >= 16){
+ shCount -= 16;
+ if(shCount)
+ shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
+ else{
+ movLeft2Result(left, MSB24, result, LSB);
+ movLeft2Result(left, MSB32, result, MSB16);
+ }
+ addSign(result, MSB24, sign);
+ }
+ else if(shCount >= 8){
+ shCount -= 8;
+ if(shCount == 1)
+ shiftRLong(left, MSB16, result, sign);
+ else if(shCount == 0){
+ movLeft2Result(left, MSB16, result, LSB);
+ movLeft2Result(left, MSB24, result, MSB16);
+ movLeft2Result(left, MSB32, result, MSB24);
+ addSign(result, MSB32, sign);
+ }
+ else{
+ shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
+ shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
+ /* the last shift is signed */
+ shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
+ addSign(result, MSB32, sign);
+ }
+ }
+ else{ /* 1 <= shCount <= 7 */
+ if(shCount <= 2){
+ shiftRLong(left, LSB, result, sign);
+ if(shCount == 2)
+ shiftRLong(result, LSB, result, sign);
+ }
+ else{
+ shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
+ shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
+ shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
+ }
+ }
}
/*-----------------------------------------------------------------*/
/* genRightShiftLiteral - right shifting by known count */
/*-----------------------------------------------------------------*/
static void genRightShiftLiteral (operand *left,
- operand *right,
- operand *result,
- iCode *ic,
- int sign)
-{
- int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
- int lsize,res_size;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- freeAsmop(right,NULL,ic,TRUE);
-
- aopOp(left,ic,FALSE);
- aopOp(result,ic,FALSE);
-
+ operand *right,
+ operand *result,
+ iCode *ic,
+ int sign)
+{
+ int shCount = (int) ulFromVal (AOP(right)->aopu.aop_lit);
+ int lsize,res_size;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ freeAsmop(right,NULL,ic,TRUE);
+
+ aopOp(left,ic,FALSE);
+ aopOp(result,ic,FALSE);
+
#if VIEW_SIZE
- pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
- AOP_SIZE(left));
+ pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
+ AOP_SIZE(left));
#endif
-
- lsize = pic14_getDataSize(left);
- res_size = pic14_getDataSize(result);
- /* test the LEFT size !!! */
-
- /* I suppose that the left size >= result size */
- if(shCount == 0){
- while(res_size--)
- movLeft2Result(left, res_size, result, res_size);
- }
-
- else if(shCount >= (lsize * 8)){
-
- if(res_size == 1) {
- emitpcode(POC_CLRF, popGet(AOP(result),LSB));
- if(sign) {
- emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
- emitpcode(POC_DECF, popGet(AOP(result),LSB));
- }
- } else {
-
- if(sign) {
- emitpcode(POC_MOVLW, popGetLit(0));
- emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
- emitpcode(POC_MOVLW, popGetLit(0xff));
- while(res_size--)
- emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
-
- } else {
-
- while(res_size--)
- emitpcode(POC_CLRF, popGet(AOP(result),res_size));
- }
- }
- } else {
-
- switch (res_size) {
- case 1:
- genrshOne (result,left,shCount,sign);
- break;
-
- case 2:
- genrshTwo (result,left,shCount,sign);
- break;
-
- case 4:
- genrshFour (result,left,shCount,sign);
- break;
- default :
- break;
- }
-
- }
-
- freeAsmop(left,NULL,ic,TRUE);
- freeAsmop(result,NULL,ic,TRUE);
+
+ lsize = pic14_getDataSize(left);
+ res_size = pic14_getDataSize(result);
+ /* test the LEFT size !!! */
+
+ /* I suppose that the left size >= result size */
+ if(shCount == 0){
+ while(res_size--)
+ movLeft2Result(left, res_size, result, res_size);
+ }
+
+ else if(shCount >= (lsize * 8)){
+
+ if(res_size == 1) {
+ emitpcode(POC_CLRF, popGet(AOP(result),LSB));
+ if(sign) {
+ emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
+ emitpcode(POC_DECF, popGet(AOP(result),LSB));
+ }
+ } else {
+
+ if(sign) {
+ emitpcode(POC_MOVLW, popGetLit(0));
+ emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
+ emitpcode(POC_MOVLW, popGetLit(0xff));
+ while(res_size--)
+ emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
+
+ } else {
+
+ while(res_size--)
+ emitpcode(POC_CLRF, popGet(AOP(result),res_size));
+ }
+ }
+ } else {
+
+ switch (res_size) {
+ case 1:
+ genrshOne (result,left,shCount,sign);
+ break;
+
+ case 2:
+ genrshTwo (result,left,shCount,sign);
+ break;
+
+ case 4:
+ genrshFour (result,left,shCount,sign);
+ break;
+ default :
+ break;
+ }
+
+ }
+
+ freeAsmop(left,NULL,ic,TRUE);
+ freeAsmop(result,NULL,ic,TRUE);
}
#endif
/*-----------------------------------------------------------------*/
static void genSignedRightShift (iCode *ic)
{
- operand *right, *left, *result;
- int size, offset;
- // char *l;
- symbol *tlbl, *tlbl1 ;
- pCodeOp *pctemp;
-
- //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
-
- /* we do it the hard way put the shift count in b
- and loop thru preserving the sign */
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- right = IC_RIGHT(ic);
- left = IC_LEFT(ic);
- result = IC_RESULT(ic);
-
- aopOp(right,ic,FALSE);
- aopOp(left,ic,FALSE);
- aopOp(result,ic,FALSE);
-
-
- if ( AOP_TYPE(right) == AOP_LIT) {
- shiftRight_Left2ResultLit (left, result, (int) floatFromVal (AOP(right)->aopu.aop_lit), 1);
- //genRightShiftLiteral (left,right,result,ic,1);
- return ;
- }
- /* shift count is unknown then we have to form
- a loop get the loop count in B : Note: we take
- only the lower order byte since shifting
- more that 32 bits make no sense anyway, ( the
- largest size of an object can be only 32 bits ) */
-
- //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
- //pic14_emitcode("inc","b");
- //freeAsmop (right,NULL,ic,TRUE);
- //aopOp(left,ic,FALSE);
- //aopOp(result,ic,FALSE);
-
- /* now move the left to the result if they are not the
- same */
- if (!pic14_sameRegs(AOP(left),AOP(result)) &&
- AOP_SIZE(result) > 1) {
-
- size = AOP_SIZE(result);
- offset=0;
- while (size--) {
- /*
- l = aopGet(AOP(left),offset,FALSE,TRUE);
- if (*l == '@' && IS_AOP_PREG(result)) {
- pic14_emitcode("mov","a,%s",l);
- aopPut(AOP(result),"a",offset);
- } else
- aopPut(AOP(result),l,offset);
- */
- emitpcode(POC_MOVFW, popGet(AOP(left),offset));
- emitpcode(POC_MOVWF, popGet(AOP(result),offset));
-
- offset++;
- }
- }
-
- /* mov the highest order bit to OVR */
- tlbl = newiTempLabel(NULL);
- tlbl1= newiTempLabel(NULL);
-
- size = AOP_SIZE(result);
- offset = size - 1;
-
- pctemp = popGetTempReg(); /* grab a temporary working register. */
-
- emitpcode(POC_MOVFW, popGet(AOP(right),0));
-
- /* offset should be 0, 1 or 3 */
- emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
- emitSKPNZ;
- emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
-
- emitpcode(POC_MOVWF, pctemp);
-
-
- emitpLabel(tlbl->key);
-
- emitpcode(POC_RLFW, popGet(AOP(result),offset));
- emitpcode(POC_RRF, popGet(AOP(result),offset));
-
- while(--size) {
- emitpcode(POC_RRF, popGet(AOP(result),--offset));
- }
-
- emitpcode(POC_DECFSZ, pctemp);
- emitpcode(POC_GOTO,popGetLabel(tlbl->key));
- emitpLabel(tlbl1->key);
-
- popReleaseTempReg(pctemp);
+ operand *right, *left, *result;
+ int size, offset;
+ // char *l;
+ symbol *tlbl, *tlbl1 ;
+ pCodeOp *pctemp;
+
+ //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
+
+ /* we do it the hard way put the shift count in b
+ and loop thru preserving the sign */
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ right = IC_RIGHT(ic);
+ left = IC_LEFT(ic);
+ result = IC_RESULT(ic);
+
+ aopOp(right,ic,FALSE);
+ aopOp(left,ic,FALSE);
+ aopOp(result,ic,FALSE);
+
+
+ if ( AOP_TYPE(right) == AOP_LIT) {
+ shiftRight_Left2ResultLit (left, result, (int) ulFromVal (AOP(right)->aopu.aop_lit), 1);
+ //genRightShiftLiteral (left,right,result,ic,1);
+ return ;
+ }
+ /* shift count is unknown then we have to form
+ a loop get the loop count in B : Note: we take
+ only the lower order byte since shifting
+ more that 32 bits make no sense anyway, ( the
+ largest size of an object can be only 32 bits ) */
+
+ //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
+ //pic14_emitcode("inc","b");
+ //freeAsmop (right,NULL,ic,TRUE);
+ //aopOp(left,ic,FALSE);
+ //aopOp(result,ic,FALSE);
+
+ /* now move the left to the result if they are not the
+ same */
+ if (!pic14_sameRegs(AOP(left),AOP(result)) &&
+ AOP_SIZE(result) > 1) {
+
+ size = AOP_SIZE(result);
+ offset=0;
+ while (size--) {
+ /*
+ l = aopGet(AOP(left),offset,FALSE,TRUE);
+ if (*l == '@' && IS_AOP_PREG(result)) {
+ pic14_emitcode("mov","a,%s",l);
+ aopPut(AOP(result),"a",offset);
+ } else
+ aopPut(AOP(result),l,offset);
+ */
+ emitpcode(POC_MOVFW, popGet(AOP(left),offset));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offset));
+
+ offset++;
+ }
+ }
+
+ /* mov the highest order bit to OVR */
+ tlbl = newiTempLabel(NULL);
+ tlbl1= newiTempLabel(NULL);
+
+ size = AOP_SIZE(result);
+ offset = size - 1;
+
+ pctemp = popGetTempReg(); /* grab a temporary working register. */
+
+ emitpcode(POC_MOVFW, popGet(AOP(right),0));
+
+ /* offset should be 0, 1 or 3 */
+ emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
+ emitSKPNZ;
+ emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
+
+ emitpcode(POC_MOVWF, pctemp);
+
+
+ emitpLabel(tlbl->key);
+
+ emitpcode(POC_RLFW, popGet(AOP(result),offset));
+ emitpcode(POC_RRF, popGet(AOP(result),offset));
+
+ while(--size) {
+ emitpcode(POC_RRF, popGet(AOP(result),--offset));
+ }
+
+ emitpcode(POC_DECFSZ, pctemp);
+ emitpcode(POC_GOTO,popGetLabel(tlbl->key));
+ emitpLabel(tlbl1->key);
+
+ popReleaseTempReg(pctemp);
#if 0
- size = AOP_SIZE(result);
- offset = size - 1;
- pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
- pic14_emitcode("rlc","a");
- pic14_emitcode("mov","ov,c");
- /* if it is only one byte then */
- if (size == 1) {
- l = aopGet(AOP(left),0,FALSE,FALSE);
- MOVA(l);
- pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
- pic14_emitcode("","%05d_DS_:",tlbl->key+100);
- pic14_emitcode("mov","c,ov");
- pic14_emitcode("rrc","a");
- pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
- pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
- aopPut(AOP(result),"a",0);
- goto release ;
- }
-
- reAdjustPreg(AOP(result));
- pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
- pic14_emitcode("","%05d_DS_:",tlbl->key+100);
- pic14_emitcode("mov","c,ov");
- while (size--) {
- l = aopGet(AOP(result),offset,FALSE,FALSE);
- MOVA(l);
- pic14_emitcode("rrc","a");
- aopPut(AOP(result),"a",offset--);
- }
- reAdjustPreg(AOP(result));
- pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
- pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
-
+ size = AOP_SIZE(result);
+ offset = size - 1;
+ pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
+ pic14_emitcode("rlc","a");
+ pic14_emitcode("mov","ov,c");
+ /* if it is only one byte then */
+ if (size == 1) {
+ l = aopGet(AOP(left),0,FALSE,FALSE);
+ MOVA(l);
+ pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
+ pic14_emitcode("","%05d_DS_:",tlbl->key+100);
+ pic14_emitcode("mov","c,ov");
+ pic14_emitcode("rrc","a");
+ pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
+ pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
+ aopPut(AOP(result),"a",0);
+ goto release ;
+ }
+
+ reAdjustPreg(AOP(result));
+ pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
+ pic14_emitcode("","%05d_DS_:",tlbl->key+100);
+ pic14_emitcode("mov","c,ov");
+ while (size--) {
+ l = aopGet(AOP(result),offset,FALSE,FALSE);
+ MOVA(l);
+ pic14_emitcode("rrc","a");
+ aopPut(AOP(result),"a",offset--);
+ }
+ reAdjustPreg(AOP(result));
+ pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
+ pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
+
release:
#endif
-
- freeAsmop(left,NULL,ic,TRUE);
- freeAsmop(result,NULL,ic,TRUE);
- freeAsmop(right,NULL,ic,TRUE);
+
+ freeAsmop(left,NULL,ic,TRUE);
+ freeAsmop(result,NULL,ic,TRUE);
+ freeAsmop(right,NULL,ic,TRUE);
}
#endif
static void loadSignToC (operand *op)
{
- FENTRY;
- assert (op && AOP(op) && AOP_SIZE(op));
+ FENTRY;
+ assert (op && AOP(op) && AOP_SIZE(op));
+
+ emitCLRC;
+ emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),AOP_SIZE(op)-1,FALSE,FALSE),7,0));
+ emitSETC;
+}
+
+/*-----------------------------------------------------------------*/
+/* genRightShift - generate code for right shifting */
+/*-----------------------------------------------------------------*/
+static void genGenericShift (iCode *ic, int shiftRight)
+{
+ operand *right, *left, *result;
+ sym_link *retype ;
+ int size;
+ symbol *tlbl, *tlbl1, *inverselbl;
+
+ FENTRY;
+ /* if signed then we do it the hard way preserve the
+ sign bit moving it inwards */
+ retype = getSpec(operandType(IC_RESULT(ic)));
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ /* signed & unsigned types are treated the same : i.e. the
+ signed is NOT propagated inwards : quoting from the
+ ANSI - standard : "for E1 >> E2, is equivalent to division
+ by 2**E2 if unsigned or if it has a non-negative value,
+ otherwise the result is implementation defined ", MY definition
+ is that the sign does not get propagated */
+
+ right = IC_RIGHT(ic);
+ left = IC_LEFT(ic);
+ result = IC_RESULT(ic);
+
+ aopOp(right,ic,FALSE);
+ aopOp(left,ic,FALSE);
+ aopOp(result,ic,FALSE);
+
+ /* if the shift count is known then do it
+ as efficiently as possible */
+ if (AOP_TYPE(right) == AOP_LIT) {
+ int lit = (int) ulFromVal (AOP(right)->aopu.aop_lit);
+ if (lit < 0)
+ {
+ lit = -lit;
+ shiftRight = !shiftRight;
+ }
+
+ if (shiftRight)
+ shiftRight_Left2ResultLit (left, result, lit, !SPEC_USIGN(operandType(left)));
+ else
+ shiftLeft_Left2ResultLit (left, result, lit);
+ //genRightShiftLiteral (left,right,result,ic, 0);
+ return ;
+ }
+
+ /* shift count is unknown then we have to form
+ a loop get the loop count in B : Note: we take
+ only the lower order byte since shifting
+ more that 32 bits make no sense anyway, ( the
+ largest size of an object can be only 32 bits ) */
+
+ /* we must not overwrite the shift counter */
+ assert (!pic14_sameRegs(AOP(right),AOP(result)));
+
+ /* now move the left to the result if they are not the
+ same */
+ if (!pic14_sameRegs(AOP(left),AOP(result)))
+ {
+ size = min(AOP_SIZE(result), AOP_SIZE(left));
+ while (size--) {
+ mov2w(AOP(left), size);
+ movwf(AOP(result), size);
+ }
+ addSign (result, AOP_SIZE(left), !SPEC_USIGN(operandType(left)));
+ }
+
+ tlbl = newiTempLabel(NULL);
+ tlbl1= newiTempLabel(NULL);
+ inverselbl = NULL;
+ size = AOP_SIZE(result);
+
+ mov2w(AOP(right),0);
+ if (!SPEC_USIGN(operandType(right)))
+ {
+ inverselbl = newiTempLabel(NULL);
+ /* signed shift count -- invert shift direction for c<0 */
+ emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
+ emitpcode(POC_GOTO, popGetLabel(inverselbl->key));
+ } // if
+ emitpcode(POC_SUBLW, popGetLit(0)); /* -count in WREG, 0-x > 0 --> BORROW = !CARRY --> CARRY is clear! */
+ /* check for `a = b >> c' with `-c == 0' */
+ emitSKPNZ;
+ emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
+ emitpLabel(tlbl->key);
+ /* propagate the sign bit inwards for SIGNED result */
+ if (shiftRight && !SPEC_USIGN(operandType(result))) loadSignToC(result);
+ genMultiAsm(shiftRight ? POC_RRF : POC_RLF, result, size, shiftRight);
+ emitpcode(POC_ADDLW, popGetLit(1)); /* clears CARRY (unless W==0 afterwards) */
+ emitSKPC;
+ emitpcode(POC_GOTO,popGetLabel(tlbl->key));
+
+ if (!SPEC_USIGN(operandType(right)))
+ {
+ symbol *inv_loop = newiTempLabel(NULL);
+
+ shiftRight = !shiftRight; /* invert shift direction */
+
+ /* we came here from the code above -- we are done */
+ emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
+
+ /* emit code for shifting N<0 steps, count is already in W */
+ emitpLabel(inverselbl->key);
+ if (!shiftRight || SPEC_USIGN(operandType(result))) emitCLRC;
+ emitpLabel(inv_loop->key);
+ /* propagate the sign bit inwards for SIGNED result */
+ if (shiftRight && !SPEC_USIGN(operandType(result))) loadSignToC(result);
+ genMultiAsm(shiftRight ? POC_RRF : POC_RLF, result, size, shiftRight);
+ emitpcode(POC_ADDLW, popGetLit(1));
+ emitSKPC;
+ emitpcode(POC_GOTO, popGetLabel(inv_loop->key));
+ } // if
- emitCLRC;
- emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),AOP_SIZE(op)-1,FALSE,FALSE),7,0));
- emitSETC;
-}
+ emitpLabel(tlbl1->key);
-/*-----------------------------------------------------------------*/
-/* genRightShift - generate code for right shifting */
-/*-----------------------------------------------------------------*/
-static void genGenericShift (iCode *ic, int shiftRight)
-{
- operand *right, *left, *result;
- sym_link *retype ;
- int size;
- symbol *tlbl, *tlbl1, *inverselbl;
-
- FENTRY;
- /* if signed then we do it the hard way preserve the
- sign bit moving it inwards */
- retype = getSpec(operandType(IC_RESULT(ic)));
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- /* signed & unsigned types are treated the same : i.e. the
- signed is NOT propagated inwards : quoting from the
- ANSI - standard : "for E1 >> E2, is equivalent to division
- by 2**E2 if unsigned or if it has a non-negative value,
- otherwise the result is implementation defined ", MY definition
- is that the sign does not get propagated */
-
- right = IC_RIGHT(ic);
- left = IC_LEFT(ic);
- result = IC_RESULT(ic);
-
- aopOp(right,ic,FALSE);
- aopOp(left,ic,FALSE);
- aopOp(result,ic,FALSE);
-
- /* if the shift count is known then do it
- as efficiently as possible */
- if (AOP_TYPE(right) == AOP_LIT) {
- int lit = (int)floatFromVal (AOP(right)->aopu.aop_lit);
- if (lit < 0)
- {
- lit = -lit;
- shiftRight = !shiftRight;
- }
-
- if (shiftRight)
- shiftRight_Left2ResultLit (left, result, lit, !SPEC_USIGN(operandType(left)));
- else
- shiftLeft_Left2ResultLit (left, result, lit);
- //genRightShiftLiteral (left,right,result,ic, 0);
- return ;
- }
-
- /* shift count is unknown then we have to form
- a loop get the loop count in B : Note: we take
- only the lower order byte since shifting
- more that 32 bits make no sense anyway, ( the
- largest size of an object can be only 32 bits ) */
-
- /* we must not overwrite the shift counter */
- assert (!pic14_sameRegs(AOP(right),AOP(result)));
-
- /* now move the left to the result if they are not the
- same */
- if (!pic14_sameRegs(AOP(left),AOP(result)))
- {
- size = min(AOP_SIZE(result), AOP_SIZE(left));
- while (size--) {
- mov2w(AOP(left), size);
- movwf(AOP(result), size);
- }
- addSign (result, AOP_SIZE(left), !SPEC_USIGN(operandType(left)));
- }
-
- tlbl = newiTempLabel(NULL);
- tlbl1= newiTempLabel(NULL);
- inverselbl = NULL;
- size = AOP_SIZE(result);
-
- mov2w(AOP(right),0);
- if (!SPEC_USIGN(operandType(right)))
- {
- inverselbl = newiTempLabel(NULL);
- /* signed shift count -- invert shift direction for c<0 */
- emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
- emitpcode(POC_GOTO, popGetLabel(inverselbl->key));
- } // if
- emitpcode(POC_SUBLW, popGetLit(0)); /* -count in WREG, 0-x > 0 --> BORROW = !CARRY --> CARRY is clear! */
- /* check for `a = b >> c' with `-c == 0' */
- emitSKPNZ;
- emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
- emitpLabel(tlbl->key);
- /* propagate the sign bit inwards for SIGNED result */
- if (shiftRight && !SPEC_USIGN(operandType(result))) loadSignToC(result);
- genMultiAsm(shiftRight ? POC_RRF : POC_RLF, result, size, shiftRight);
- emitpcode(POC_ADDLW, popGetLit(1)); /* clears CARRY (unless W==0 afterwards) */
- emitSKPC;
- emitpcode(POC_GOTO,popGetLabel(tlbl->key));
-
- if (!SPEC_USIGN(operandType(right)))
- {
- symbol *inv_loop = newiTempLabel(NULL);
-
- shiftRight = !shiftRight; /* invert shift direction */
-
- /* we came here from the code above -- we are done */
- emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
-
- /* emit code for shifting N<0 steps, count is already in W */
- emitpLabel(inverselbl->key);
- if (!shiftRight || SPEC_USIGN(operandType(result))) emitCLRC;
- emitpLabel(inv_loop->key);
- /* propagate the sign bit inwards for SIGNED result */
- if (shiftRight && !SPEC_USIGN(operandType(result))) loadSignToC(result);
- genMultiAsm(shiftRight ? POC_RRF : POC_RLF, result, size, shiftRight);
- emitpcode(POC_ADDLW, popGetLit(1));
- emitSKPC;
- emitpcode(POC_GOTO, popGetLabel(inv_loop->key));
- } // if
-
- emitpLabel(tlbl1->key);
-
- freeAsmop(left,NULL,ic,TRUE);
- freeAsmop (right,NULL,ic,TRUE);
- freeAsmop(result,NULL,ic,TRUE);
+ freeAsmop(left,NULL,ic,TRUE);
+ freeAsmop (right,NULL,ic,TRUE);
+ freeAsmop(result,NULL,ic,TRUE);
}
static void genRightShift (iCode *ic)
{
- genGenericShift(ic, 1);
+ genGenericShift(ic, 1);
}
static void genLeftShift (iCode *ic)
{
- genGenericShift(ic, 0);
+ genGenericShift(ic, 0);
}
/*-----------------------------------------------------------------*/
/* SetIrp - Set IRP bit */
/*-----------------------------------------------------------------*/
void SetIrp(operand *result) {
- FENTRY;
- if (AOP_TYPE(result) == AOP_LIT) {
- unsigned lit = (unsigned)operandLitValue(result);
- if (lit&0x100)
- emitSETIRP;
- else
- emitCLRIRP;
- } else {
- if (PCOP(AOP(result))->type == PO_LITERAL) {
- int addrs = PCOL(AOP(result))->lit;
- if (addrs & 0x100)
- emitSETIRP;
- else
- emitCLRIRP;
- } else {
- emitCLRIRP; /* always ensure this is clear as it may have previouly been set */
- if(AOP_SIZE(result) > 1) {
- emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
- emitSETIRP;
- }
- }
- }
+ FENTRY;
+ if (AOP_TYPE(result) == AOP_LIT) {
+ unsigned lit = (unsigned) double2ul (operandLitValue(result));
+ if (lit&0x100)
+ emitSETIRP;
+ else
+ emitCLRIRP;
+ } else {
+ if (PCOP(AOP(result))->type == PO_LITERAL) {
+ int addrs = PCOL(AOP(result))->lit;
+ if (addrs & 0x100)
+ emitSETIRP;
+ else
+ emitCLRIRP;
+ } else {
+ emitCLRIRP; /* always ensure this is clear as it may have previouly been set */
+ if(AOP_SIZE(result) > 1) {
+ emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
+ emitSETIRP;
+ }
+ }
+ }
}
static void
if (!alreadyAddressed) setup_fsr (src);
emitpcode(POC_MOVFW, popCopyReg (&pc_fsr));
break;
-
+
case CPOINTER:
assert( AOP_SIZE(src) == 2 );
mov2w_op(src, 0);
emitpcode(POC_MOVWF, popRegFromIdx (Gstack_base_addr-1));
mov2w_op(src, 1);
emitpcode(POC_MOVWF, popRegFromIdx (Gstack_base_addr));
- emitpcode(POC_MOVLW, popGetLit (GPTRTAG_CODE)); /* GPOINTER tag for __code space */
+ emitpcode(POC_MOVLW, popGetLit (GPTRTAG_CODE)); /* GPOINTER tag for __code space */
call_libraryfunc ("__gptrget1");
break;
-
+
case GPOINTER:
assert( AOP_SIZE(src) == 3 );
mov2w_op(src, 0);
mov2w_op(src, 2);
call_libraryfunc ("__gptrget1");
break;
-
+
default:
assert( !"unhandled pointer type" );
break;
if (!alreadyAddressed) setup_fsr (dst);
emitpcode(POC_MOVWF, popCopyReg (&pc_fsr));
break;
-
+
case CPOINTER:
assert( !"trying to assign to __code pointer" );
break;
-
+
case GPOINTER:
emitpcode(POC_MOVWF, popRegFromIdx (Gstack_base_addr-2));
mov2w_op(dst, 0);
/* genUnpackBits - generates code for unpacking bits */
/*-----------------------------------------------------------------*/
static void genUnpackBits (operand *result, operand *left, int ptype, iCode *ifx)
-{
+{
int rsize; /* result size */
sym_link *etype; /* bitfield type information */
int blen; /* bitfield length */
resolvedIfx rIfx;
resolveIfx(&rIfx,ifx);
if (ptype == -1) /* direct */
- pcop = newpCodeOpBit(aopGet (AOP(left),0,FALSE,FALSE),bstr,0);
+ pcop = newpCodeOpBit(aopGet (AOP(left),0,FALSE,FALSE),bstr,0);
else
- pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
+ pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
emitpcode((rIfx.condition) ? POC_BTFSC : POC_BTFSS,pcop);
emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
ifx->generated=1;
int i;
assert (!pic14_sameRegs (AOP(result), AOP(left)));
for (i=0; i < AOP_SIZE(result); i++)
- emitpcode (POC_CLRF, popGet (AOP(result), i));
+ emitpcode (POC_CLRF, popGet (AOP(result), i));
switch (ptype)
{
case -1:
emitpcode(POC_BTFSC,newpCodeOpBit(aopGet (AOP(left),0,FALSE,FALSE),bstr,0));
- /* adjust result below */
+ /* adjust result below */
break;
-
+
case POINTER:
case FPOINTER:
case GPOINTER:
case CPOINTER:
emitPtrByteGet (left, ptype, FALSE);
- emitpcode(POC_ANDLW, popGetLit (1UL << bstr));
- emitSKPZ;
- /* adjust result below */
+ emitpcode(POC_ANDLW, popGetLit (1UL << bstr));
+ emitSKPZ;
+ /* adjust result below */
break;
-
+
default:
assert( !"unhandled pointer type" );
} // switch
/* move sign-/zero extended bit to result */
if (SPEC_USIGN(OP_SYM_ETYPE(left))) {
- emitpcode (POC_INCF, popGet (AOP(result), 0));
+ emitpcode (POC_INCF, popGet (AOP(result), 0));
} else {
- emitpcode (POC_DECF, popGet (AOP(result), 0));
+ emitpcode (POC_DECF, popGet (AOP(result), 0));
}
addSign (result, 1, !SPEC_USIGN(OP_SYM_ETYPE(left)));
}
case -1:
mov2w(AOP(left), 0);
break;
-
+
case POINTER:
case FPOINTER:
case GPOINTER:
case CPOINTER:
emitPtrByteGet (left, ptype, FALSE);
break;
-
+
default:
assert( !"unhandled pointer type" );
} // switch
/*-----------------------------------------------------------------*/
/* genDataPointerGet - generates code when ptr offset is known */
/*-----------------------------------------------------------------*/
-static void genDataPointerGet (operand *left,
- operand *result,
- iCode *ic)
-{
- int size , offset = 0;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
-
- /* optimization - most of the time, left and result are the same
- * address, but different types. for the pic code, we could omit
- * the following
- */
- aopOp(result,ic,TRUE);
-
- if (pic14_sameRegs (AOP(left), AOP(result)))
- return;
-
- DEBUGpic14_AopType(__LINE__,left,NULL,result);
-
- //emitpcode(POC_MOVFW, popGet(AOP(left),0));
-
- size = AOP_SIZE(result);
- if (size > getSize(OP_SYM_ETYPE(left))) size = getSize(OP_SYM_ETYPE(left));
-
- offset = 0;
- while (size--) {
- emitpcode(POC_MOVFW, popGet(AOP(left),offset));
- emitpcode(POC_MOVWF, popGet(AOP(result),offset));
- offset++;
- }
-
- freeAsmop(left,NULL,ic,TRUE);
- freeAsmop(result,NULL,ic,TRUE);
+static void genDataPointerGet (operand *left,
+ operand *result,
+ iCode *ic)
+{
+ int size , offset = 0;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+
+ /* optimization - most of the time, left and result are the same
+ * address, but different types. for the pic code, we could omit
+ * the following
+ */
+ aopOp(result,ic,TRUE);
+
+ if (pic14_sameRegs (AOP(left), AOP(result)))
+ return;
+
+ DEBUGpic14_AopType(__LINE__,left,NULL,result);
+
+ //emitpcode(POC_MOVFW, popGet(AOP(left),0));
+
+ size = AOP_SIZE(result);
+ if (size > getSize(OP_SYM_ETYPE(left))) size = getSize(OP_SYM_ETYPE(left));
+
+ offset = 0;
+ while (size--) {
+ emitpcode(POC_MOVFW, popGet(AOP(left),offset));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offset));
+ offset++;
+ }
+
+ freeAsmop(left,NULL,ic,TRUE);
+ freeAsmop(result,NULL,ic,TRUE);
}
#endif
/*-----------------------------------------------------------------*/
/* genNearPointerGet - pic14_emitcode for near pointer fetch */
/*-----------------------------------------------------------------*/
-static void genNearPointerGet (operand *left,
- operand *result,
- iCode *ic)
-{
- asmop *aop = NULL;
- sym_link *ltype = operandType(left);
- sym_link *rtype = operandType(result);
- sym_link *retype= getSpec(rtype); /* bitfield type information */
- int direct = 0;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
-
- aopOp(left,ic,FALSE);
-
- /* if left is rematerialisable and
- result is not bit variable type and
- the left is pointer to data space i.e
- lower 128 bytes of space */
- if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
- !IS_BITVAR(retype) &&
- PIC_IS_DATA_PTR(ltype)) {
- genDataPointerGet (left,result,ic);
- return ;
- }
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- aopOp (result,ic,FALSE);
-
- /* Check if can access directly instead of via a pointer */
- if ((PCOP(AOP(left))->type == PO_LITERAL || PCOP(AOP(left))->type == PO_IMMEDIATE)
- && AOP_SIZE(result) == 1)
- {
- direct = 1;
- }
-
- if (IS_BITFIELD(getSpec(operandType(result))))
- {
- genUnpackBits (result,left,direct?-1:POINTER,ifxForOp(IC_RESULT(ic),ic));
- goto release;
- }
-
- /* If the pointer value is not in a the FSR then need to put it in */
- /* Must set/reset IRP bit for use with FSR. */
- if (!direct)
- setup_fsr (left);
-
-// sym_link *etype;
- /* if bitfield then unpack the bits */
- {
- /* we have can just get the values */
- int size = AOP_SIZE(result);
- int offset = 0 ;
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- while(size--) {
- if (direct)
- emitpcode(POC_MOVWF,popGet(AOP(left),0));
- else
- emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
- if (AOP_TYPE(result) == AOP_LIT) {
- emitpcode(POC_MOVLW,popGet(AOP(result),offset));
- } else {
- emitpcode(POC_MOVWF,popGet(AOP(result),offset));
- }
- if (size && !direct)
- emitpcode(POC_INCF,popCopyReg(&pc_fsr));
- offset++;
- }
- }
-
- /* now some housekeeping stuff */
- if (aop) {
- /* we had to allocate for this iCode */
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- freeAsmop(NULL,aop,ic,TRUE);
- } else {
- /* we did not allocate which means left
- already in a pointer register, then
- if size > 0 && this could be used again
- we have to point it back to where it
- belongs */
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if (AOP_SIZE(result) > 1 &&
- !OP_SYMBOL(left)->remat &&
- ( OP_SYMBOL(left)->liveTo > ic->seq ||
- ic->depth )) {
- int size = AOP_SIZE(result) - 1;
- while (size--)
- emitpcode(POC_DECF, popCopyReg(&pc_fsr));
- }
- }
-
+static void genNearPointerGet (operand *left,
+ operand *result,
+ iCode *ic)
+{
+ asmop *aop = NULL;
+ sym_link *ltype = operandType(left);
+ sym_link *rtype = operandType(result);
+ sym_link *retype= getSpec(rtype); /* bitfield type information */
+ int direct = 0;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+
+ aopOp(left,ic,FALSE);
+
+ /* if left is rematerialisable and
+ result is not bit variable type and
+ the left is pointer to data space i.e
+ lower 128 bytes of space */
+ if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
+ !IS_BITVAR(retype) &&
+ PIC_IS_DATA_PTR(ltype)) {
+ genDataPointerGet (left,result,ic);
+ return ;
+ }
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ aopOp (result,ic,FALSE);
+
+ /* Check if can access directly instead of via a pointer */
+ if ((PCOP(AOP(left))->type == PO_LITERAL || PCOP(AOP(left))->type == PO_IMMEDIATE)
+ && AOP_SIZE(result) == 1)
+ {
+ direct = 1;
+ }
+
+ if (IS_BITFIELD(getSpec(operandType(result))))
+ {
+ genUnpackBits (result,left,direct?-1:POINTER,ifxForOp(IC_RESULT(ic),ic));
+ goto release;
+ }
+
+ /* If the pointer value is not in a the FSR then need to put it in */
+ /* Must set/reset IRP bit for use with FSR. */
+ if (!direct)
+ setup_fsr (left);
+
+// sym_link *etype;
+ /* if bitfield then unpack the bits */
+ {
+ /* we have can just get the values */
+ int size = AOP_SIZE(result);
+ int offset = 0 ;
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ while(size--) {
+ if (direct)
+ emitpcode(POC_MOVWF,popGet(AOP(left),0));
+ else
+ emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
+ if (AOP_TYPE(result) == AOP_LIT) {
+ emitpcode(POC_MOVLW,popGet(AOP(result),offset));
+ } else {
+ emitpcode(POC_MOVWF,popGet(AOP(result),offset));
+ }
+ if (size && !direct)
+ emitpcode(POC_INCF,popCopyReg(&pc_fsr));
+ offset++;
+ }
+ }
+
+ /* now some housekeeping stuff */
+ if (aop) {
+ /* we had to allocate for this iCode */
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ freeAsmop(NULL,aop,ic,TRUE);
+ } else {
+ /* we did not allocate which means left
+ already in a pointer register, then
+ if size > 0 && this could be used again
+ we have to point it back to where it
+ belongs */
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ if (AOP_SIZE(result) > 1 &&
+ !OP_SYMBOL(left)->remat &&
+ ( OP_SYMBOL(left)->liveTo > ic->seq ||
+ ic->depth )) {
+ int size = AOP_SIZE(result) - 1;
+ while (size--)
+ emitpcode(POC_DECF, popCopyReg(&pc_fsr));
+ }
+ }
+
release:
- /* done */
- freeAsmop(left,NULL,ic,TRUE);
- freeAsmop(result,NULL,ic,TRUE);
+ /* done */
+ freeAsmop(left,NULL,ic,TRUE);
+ freeAsmop(result,NULL,ic,TRUE);
}
/*-----------------------------------------------------------------*/
/* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
/*-----------------------------------------------------------------*/
-static void genPagedPointerGet (operand *left,
- operand *result,
- iCode *ic)
-{
- asmop *aop = NULL;
- regs *preg = NULL ;
- char *rname ;
- sym_link *rtype, *retype;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- rtype = operandType(result);
- retype= getSpec(rtype);
-
- aopOp(left,ic,FALSE);
-
- /* if the value is already in a pointer register
- then don't need anything more */
- if (!AOP_INPREG(AOP(left))) {
- /* otherwise get a free pointer register */
- aop = newAsmop(0);
- preg = getFreePtr(ic,&aop,FALSE);
- pic14_emitcode("mov","%s,%s",
- preg->name,
- aopGet(AOP(left),0,FALSE,TRUE));
- rname = preg->name ;
- } else
- rname = aopGet(AOP(left),0,FALSE,FALSE);
-
- freeAsmop(left,NULL,ic,TRUE);
- aopOp (result,ic,FALSE);
-
- /* if bitfield then unpack the bits */
- if (IS_BITFIELD(retype))
- genUnpackBits (result,left,rname,PPOINTER,0);
- else {
- /* we have can just get the values */
- int size = AOP_SIZE(result);
- int offset = 0 ;
-
- while (size--) {
-
- pic14_emitcode("movx","a,@%s",rname);
- aopPut(AOP(result),"a",offset);
-
- offset++ ;
-
- if (size)
- pic14_emitcode("inc","%s",rname);
- }
- }
-
- /* now some housekeeping stuff */
- if (aop) {
- /* we had to allocate for this iCode */
- freeAsmop(NULL,aop,ic,TRUE);
- } else {
- /* we did not allocate which means left
- already in a pointer register, then
- if size > 0 && this could be used again
- we have to point it back to where it
- belongs */
- if (AOP_SIZE(result) > 1 &&
- !OP_SYMBOL(left)->remat &&
- ( OP_SYMBOL(left)->liveTo > ic->seq ||
- ic->depth )) {
- int size = AOP_SIZE(result) - 1;
- while (size--)
- pic14_emitcode("dec","%s",rname);
- }
- }
-
- /* done */
- freeAsmop(result,NULL,ic,TRUE);
-
-
+static void genPagedPointerGet (operand *left,
+ operand *result,
+ iCode *ic)
+{
+ asmop *aop = NULL;
+ regs *preg = NULL ;
+ char *rname ;
+ sym_link *rtype, *retype;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ rtype = operandType(result);
+ retype= getSpec(rtype);
+
+ aopOp(left,ic,FALSE);
+
+ /* if the value is already in a pointer register
+ then don't need anything more */
+ if (!AOP_INPREG(AOP(left))) {
+ /* otherwise get a free pointer register */
+ aop = newAsmop(0);
+ preg = getFreePtr(ic,&aop,FALSE);
+ pic14_emitcode("mov","%s,%s",
+ preg->name,
+ aopGet(AOP(left),0,FALSE,TRUE));
+ rname = preg->name ;
+ } else
+ rname = aopGet(AOP(left),0,FALSE,FALSE);
+
+ freeAsmop(left,NULL,ic,TRUE);
+ aopOp (result,ic,FALSE);
+
+ /* if bitfield then unpack the bits */
+ if (IS_BITFIELD(retype))
+ genUnpackBits (result,left,rname,PPOINTER,0);
+ else {
+ /* we have can just get the values */
+ int size = AOP_SIZE(result);
+ int offset = 0 ;
+
+ while (size--) {
+
+ pic14_emitcode("movx","a,@%s",rname);
+ aopPut(AOP(result),"a",offset);
+
+ offset++ ;
+
+ if (size)
+ pic14_emitcode("inc","%s",rname);
+ }
+ }
+
+ /* now some housekeeping stuff */
+ if (aop) {
+ /* we had to allocate for this iCode */
+ freeAsmop(NULL,aop,ic,TRUE);
+ } else {
+ /* we did not allocate which means left
+ already in a pointer register, then
+ if size > 0 && this could be used again
+ we have to point it back to where it
+ belongs */
+ if (AOP_SIZE(result) > 1 &&
+ !OP_SYMBOL(left)->remat &&
+ ( OP_SYMBOL(left)->liveTo > ic->seq ||
+ ic->depth )) {
+ int size = AOP_SIZE(result) - 1;
+ while (size--)
+ pic14_emitcode("dec","%s",rname);
+ }
+ }
+
+ /* done */
+ freeAsmop(result,NULL,ic,TRUE);
+
+
}
/*-----------------------------------------------------------------*/
/* genFarPointerGet - gget value from far space */
/*-----------------------------------------------------------------*/
static void genFarPointerGet (operand *left,
- operand *result, iCode *ic)
-{
- int size, offset ;
- sym_link *retype = getSpec(operandType(result));
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- aopOp(left,ic,FALSE);
-
- /* if the operand is already in dptr
- then we do nothing else we move the value to dptr */
- if (AOP_TYPE(left) != AOP_STR) {
- /* if this is remateriazable */
- if (AOP_TYPE(left) == AOP_IMMD)
- pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
- else { /* we need to get it byte by byte */
- pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
- pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
- if (options.model == MODEL_FLAT24)
- {
- pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
- }
- }
- }
- /* so dptr know contains the address */
- freeAsmop(left,NULL,ic,TRUE);
- aopOp(result,ic,FALSE);
-
- /* if bit then unpack */
- if (IS_BITFIELD(retype))
- genUnpackBits(result,left,"dptr",FPOINTER,0);
- else {
- size = AOP_SIZE(result);
- offset = 0 ;
-
- while (size--) {
- pic14_emitcode("movx","a,@dptr");
- aopPut(AOP(result),"a",offset++);
- if (size)
- pic14_emitcode("inc","dptr");
- }
- }
-
- freeAsmop(result,NULL,ic,TRUE);
+ operand *result, iCode *ic)
+{
+ int size, offset ;
+ sym_link *retype = getSpec(operandType(result));
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ aopOp(left,ic,FALSE);
+
+ /* if the operand is already in dptr
+ then we do nothing else we move the value to dptr */
+ if (AOP_TYPE(left) != AOP_STR) {
+ /* if this is remateriazable */
+ if (AOP_TYPE(left) == AOP_IMMD)
+ pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
+ else { /* we need to get it byte by byte */
+ pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
+ pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
+ if (options.model == MODEL_FLAT24)
+ {
+ pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
+ }
+ }
+ }
+ /* so dptr know contains the address */
+ freeAsmop(left,NULL,ic,TRUE);
+ aopOp(result,ic,FALSE);
+
+ /* if bit then unpack */
+ if (IS_BITFIELD(retype))
+ genUnpackBits(result,left,"dptr",FPOINTER,0);
+ else {
+ size = AOP_SIZE(result);
+ offset = 0 ;
+
+ while (size--) {
+ pic14_emitcode("movx","a,@dptr");
+ aopPut(AOP(result),"a",offset++);
+ if (size)
+ pic14_emitcode("inc","dptr");
+ }
+ }
+
+ freeAsmop(result,NULL,ic,TRUE);
}
#endif
/* genCodePointerGet - get value from code space */
/*-----------------------------------------------------------------*/
static void genCodePointerGet (operand *left,
- operand *result, iCode *ic)
-{
- int size, offset ;
- sym_link *retype = getSpec(operandType(result));
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- aopOp(left,ic,FALSE);
-
- /* if the operand is already in dptr
- then we do nothing else we move the value to dptr */
- if (AOP_TYPE(left) != AOP_STR) {
- /* if this is remateriazable */
- if (AOP_TYPE(left) == AOP_IMMD)
- pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
- else { /* we need to get it byte by byte */
- pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
- pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
- if (options.model == MODEL_FLAT24)
- {
- pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
- }
- }
- }
- /* so dptr know contains the address */
- freeAsmop(left,NULL,ic,TRUE);
- aopOp(result,ic,FALSE);
-
- /* if bit then unpack */
- if (IS_BITFIELD(retype))
- genUnpackBits(result,left,"dptr",CPOINTER,0);
- else {
- size = AOP_SIZE(result);
- offset = 0 ;
-
- while (size--) {
- pic14_emitcode("clr","a");
- pic14_emitcode("movc","a,@a+dptr");
- aopPut(AOP(result),"a",offset++);
- if (size)
- pic14_emitcode("inc","dptr");
- }
- }
-
- freeAsmop(result,NULL,ic,TRUE);
+ operand *result, iCode *ic)
+{
+ int size, offset ;
+ sym_link *retype = getSpec(operandType(result));
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ aopOp(left,ic,FALSE);
+
+ /* if the operand is already in dptr
+ then we do nothing else we move the value to dptr */
+ if (AOP_TYPE(left) != AOP_STR) {
+ /* if this is remateriazable */
+ if (AOP_TYPE(left) == AOP_IMMD)
+ pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
+ else { /* we need to get it byte by byte */
+ pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
+ pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
+ if (options.model == MODEL_FLAT24)
+ {
+ pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
+ }
+ }
+ }
+ /* so dptr know contains the address */
+ freeAsmop(left,NULL,ic,TRUE);
+ aopOp(result,ic,FALSE);
+
+ /* if bit then unpack */
+ if (IS_BITFIELD(retype))
+ genUnpackBits(result,left,"dptr",CPOINTER,0);
+ else {
+ size = AOP_SIZE(result);
+ offset = 0 ;
+
+ while (size--) {
+ pic14_emitcode("clr","a");
+ pic14_emitcode("movc","a,@a+dptr");
+ aopPut(AOP(result),"a",offset++);
+ if (size)
+ pic14_emitcode("inc","dptr");
+ }
+ }
+
+ freeAsmop(result,NULL,ic,TRUE);
}
#endif
/*-----------------------------------------------------------------*/
/* genGenPointerGet - gget value from generic pointer space */
/*-----------------------------------------------------------------*/
static void genGenPointerGet (operand *left,
- operand *result, iCode *ic)
-{
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- aopOp(left,ic,FALSE);
- aopOp(result,ic,FALSE);
-
-
- DEBUGpic14_AopType(__LINE__,left,NULL,result);
-
- if (IS_BITFIELD(getSpec(operandType(result))))
- {
- genUnpackBits (result, left, GPOINTER, ifxForOp (IC_RESULT(ic), ic));
- return;
- }
-
- {
- /* emit call to __gptrget */
- char *func[] = {NULL, "__gptrget1", "__gptrget2", "__gptrget3", "__gptrget4"};
- int size = AOP_SIZE(result);
- int idx = 0;
-
- assert (size > 0 && size <= 4);
-
- /* pass arguments */
- assert (AOP_SIZE(left) == 3);
- mov2w(AOP(left), 0);
- emitpcode(POC_MOVWF, popRegFromIdx (Gstack_base_addr-1));
- mov2w(AOP(left), 1);
- emitpcode(POC_MOVWF, popRegFromIdx (Gstack_base_addr));
- mov2w(AOP(left), 2);
- call_libraryfunc (func[size]);
-
- /* save result */
- movwf (AOP(result), --size);
- while (size--) {
- emitpcode (POC_MOVFW,popRegFromIdx (Gstack_base_addr - idx++));
- movwf (AOP(result), size);
- } // while
- }
-
- freeAsmop(left,NULL,ic,TRUE);
- freeAsmop(result,NULL,ic,TRUE);
-
+ operand *result, iCode *ic)
+{
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ aopOp(left,ic,FALSE);
+ aopOp(result,ic,FALSE);
+
+
+ DEBUGpic14_AopType(__LINE__,left,NULL,result);
+
+ if (IS_BITFIELD(getSpec(operandType(result))))
+ {
+ genUnpackBits (result, left, GPOINTER, ifxForOp (IC_RESULT(ic), ic));
+ return;
+ }
+
+ {
+ /* emit call to __gptrget */
+ char *func[] = {NULL, "__gptrget1", "__gptrget2", "__gptrget3", "__gptrget4"};
+ int size = AOP_SIZE(result);
+ int idx = 0;
+
+ assert (size > 0 && size <= 4);
+
+ /* pass arguments */
+ assert (AOP_SIZE(left) == 3);
+ mov2w(AOP(left), 0);
+ emitpcode(POC_MOVWF, popRegFromIdx (Gstack_base_addr-1));
+ mov2w(AOP(left), 1);
+ emitpcode(POC_MOVWF, popRegFromIdx (Gstack_base_addr));
+ mov2w(AOP(left), 2);
+ call_libraryfunc (func[size]);
+
+ /* save result */
+ movwf (AOP(result), --size);
+ while (size--) {
+ emitpcode (POC_MOVFW,popRegFromIdx (Gstack_base_addr - idx++));
+ movwf (AOP(result), size);
+ } // while
+ }
+
+ freeAsmop(left,NULL,ic,TRUE);
+ freeAsmop(result,NULL,ic,TRUE);
+
}
/*-----------------------------------------------------------------*/
/* genConstPointerGet - get value from const generic pointer space */
/*-----------------------------------------------------------------*/
static void genConstPointerGet (operand *left,
- operand *result, iCode *ic)
-{
- //sym_link *retype = getSpec(operandType(result));
- #if 0
- symbol *albl, *blbl;//, *clbl;
- pCodeOp *pcop;
- #endif
- PIC_OPCODE poc;
- int i, size, lit;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- aopOp(left,ic,FALSE);
- aopOp(result,ic,FALSE);
-
- size = AOP_SIZE(result);
-
- DEBUGpic14_AopType(__LINE__,left,NULL,result);
-
- DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
-
- lit = op_isLitLike (left);
- poc = lit ? POC_MOVLW : POC_MOVFW;
-
- if (IS_BITFIELD(getSpec(operandType(result))))
- {
- genUnpackBits (result, left, lit ? -1 : CPOINTER, ifxForOp (IC_RESULT(ic), ic));
- goto release;
- }
-
- {
- char *func[] = { NULL, "__gptrget1", "__gptrget2", "__gptrget3", "__gptrget4" };
- int size = min(getSize(OP_SYM_ETYPE(left)), AOP_SIZE(result));
- assert (size > 0 && size <= 4);
-
- mov2w_op(left, 0);
- emitpcode(POC_MOVWF, popRegFromIdx (Gstack_base_addr-1));
- mov2w_op(left, 1);
- emitpcode(POC_MOVWF, popRegFromIdx (Gstack_base_addr));
- emitpcode(POC_MOVLW, popGetLit (GPTRTAG_CODE)); /* GPOINTER tag for __code space */
- call_libraryfunc (func[size]);
-
- movwf(AOP(result),size-1);
- for (i = 1; i < size; i++)
- {
- emitpcode(POC_MOVFW, popRegFromIdx (Gstack_base_addr+1-i));
- movwf(AOP(result),size - 1 - i);
- } // for
- }
-
+ operand *result, iCode *ic)
+{
+ //sym_link *retype = getSpec(operandType(result));
+ #if 0
+ symbol *albl, *blbl;//, *clbl;
+ pCodeOp *pcop;
+ #endif
+ PIC_OPCODE poc;
+ int i, size, lit;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ aopOp(left,ic,FALSE);
+ aopOp(result,ic,FALSE);
+
+ size = AOP_SIZE(result);
+
+ DEBUGpic14_AopType(__LINE__,left,NULL,result);
+
+ DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
+
+ lit = op_isLitLike (left);
+ poc = lit ? POC_MOVLW : POC_MOVFW;
+
+ if (IS_BITFIELD(getSpec(operandType(result))))
+ {
+ genUnpackBits (result, left, lit ? -1 : CPOINTER, ifxForOp (IC_RESULT(ic), ic));
+ goto release;
+ }
+
+ {
+ char *func[] = { NULL, "__gptrget1", "__gptrget2", "__gptrget3", "__gptrget4" };
+ int size = min(getSize(OP_SYM_ETYPE(left)), AOP_SIZE(result));
+ assert (size > 0 && size <= 4);
+
+ mov2w_op(left, 0);
+ emitpcode(POC_MOVWF, popRegFromIdx (Gstack_base_addr-1));
+ mov2w_op(left, 1);
+ emitpcode(POC_MOVWF, popRegFromIdx (Gstack_base_addr));
+ emitpcode(POC_MOVLW, popGetLit (GPTRTAG_CODE)); /* GPOINTER tag for __code space */
+ call_libraryfunc (func[size]);
+
+ movwf(AOP(result),size-1);
+ for (i = 1; i < size; i++)
+ {
+ emitpcode(POC_MOVFW, popRegFromIdx (Gstack_base_addr+1-i));
+ movwf(AOP(result),size - 1 - i);
+ } // for
+ }
+
release:
- freeAsmop(left,NULL,ic,TRUE);
- freeAsmop(result,NULL,ic,TRUE);
-
+ freeAsmop(left,NULL,ic,TRUE);
+ freeAsmop(result,NULL,ic,TRUE);
+
}
/*-----------------------------------------------------------------*/
/* genPointerGet - generate code for pointer get */
/*-----------------------------------------------------------------*/
static void genPointerGet (iCode *ic)
{
- operand *left, *result ;
- sym_link *type, *etype;
- int p_type = -1;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- left = IC_LEFT(ic);
- result = IC_RESULT(ic) ;
-
- /* depending on the type of pointer we need to
- move it to the correct pointer register */
- type = operandType(left);
- etype = getSpec(type);
-
- if (IS_PTR_CONST(type))
- DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
-
- /* if left is of type of pointer then it is simple */
- if (IS_PTR(type) && !IS_FUNC(type->next))
- p_type = DCL_TYPE(type);
- else {
- /* we have to go by the storage class */
- p_type = PTR_TYPE(SPEC_OCLS(etype));
-
- DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
-
- if (SPEC_OCLS(etype)->codesp ) {
- DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
- //p_type = CPOINTER ;
- }
- else
- if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
- DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
- /*p_type = FPOINTER ;*/
- else
- if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
- DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
- /* p_type = PPOINTER; */
- else
- if (SPEC_OCLS(etype) == idata )
- DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
- /* p_type = IPOINTER; */
- else
- DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
- /* p_type = POINTER ; */
- }
-
- /* now that we have the pointer type we assign
- the pointer values */
- switch (p_type) {
-
- case POINTER:
- case FPOINTER:
- //case IPOINTER:
- genNearPointerGet (left,result,ic);
- break;
+ operand *left, *result ;
+ sym_link *type, *etype;
+ int p_type = -1;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ left = IC_LEFT(ic);
+ result = IC_RESULT(ic) ;
+
+ /* depending on the type of pointer we need to
+ move it to the correct pointer register */
+ type = operandType(left);
+ etype = getSpec(type);
+
+ if (IS_PTR_CONST(type))
+ DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
+
+ /* if left is of type of pointer then it is simple */
+ if (IS_PTR(type) && !IS_FUNC(type->next))
+ p_type = DCL_TYPE(type);
+ else {
+ /* we have to go by the storage class */
+ p_type = PTR_TYPE(SPEC_OCLS(etype));
+
+ DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
+
+ if (SPEC_OCLS(etype)->codesp ) {
+ DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
+ //p_type = CPOINTER ;
+ }
+ else
+ if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
+ DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
+ /*p_type = FPOINTER ;*/
+ else
+ if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
+ DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
+ /* p_type = PPOINTER; */
+ else
+ if (SPEC_OCLS(etype) == idata )
+ DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
+ /* p_type = IPOINTER; */
+ else
+ DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
+ /* p_type = POINTER ; */
+ }
+
+ /* now that we have the pointer type we assign
+ the pointer values */
+ switch (p_type) {
+
+ case POINTER:
+ case FPOINTER:
+ //case IPOINTER:
+ genNearPointerGet (left,result,ic);
+ break;
/*
- case PPOINTER:
- genPagedPointerGet(left,result,ic);
- break;
-
- case FPOINTER:
- genFarPointerGet (left,result,ic);
- break;
-*/
- case CPOINTER:
- genConstPointerGet (left,result,ic);
- break;
-
- case GPOINTER:
- genGenPointerGet (left,result,ic);
- break;
- default:
- assert ( !"unhandled pointer type" );
- break;
- }
-
+ case PPOINTER:
+ genPagedPointerGet(left,result,ic);
+ break;
+
+ case FPOINTER:
+ genFarPointerGet (left,result,ic);
+ break;
+*/
+ case CPOINTER:
+ genConstPointerGet (left,result,ic);
+ break;
+
+ case GPOINTER:
+ genGenPointerGet (left,result,ic);
+ break;
+ default:
+ assert ( !"unhandled pointer type" );
+ break;
+ }
+
}
/*-----------------------------------------------------------------*/
if ((blen <= 8) && ((bstr + blen) <= 8))
{
mask = ((unsigned char) (0xFF << (blen + bstr)) |
- (unsigned char) (0xFF >> (8 - bstr)));
+ (unsigned char) (0xFF >> (8 - bstr)));
if (AOP_TYPE (right) == AOP_LIT)
{
/* Case with a bitfield length <8 and literal source */
- int lit = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+ int lit = (int) ulFromVal (AOP (right)->aopu.aop_lit);
if (blen == 1) {
pCodeOp *pcop;
-
- switch (p_type)
- {
- case -1:
- if (AOP(result)->type == AOP_PCODE)
- pcop = newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),bstr,0);
- else
- pcop = popGet(AOP(result),0);
- emitpcode(lit?POC_BSF:POC_BCF,pcop);
- break;
-
- case POINTER:
- case FPOINTER:
- setup_fsr (result);
- emitpcode(lit?POC_BSF:POC_BCF,newpCodeOpBit(PCOP(&pc_indf)->name,bstr,0));
- break;
-
- case CPOINTER:
- assert( !"trying to assign to bitfield via pointer to __code space" );
- break;
-
- case GPOINTER:
- emitPtrByteGet(result, p_type, FALSE);
- if (lit) {
- emitpcode(POC_IORLW, newpCodeOpLit (1UL << bstr));
- } else {
- emitpcode(POC_ANDLW, newpCodeOpLit ((~(1UL << bstr)) & 0x0ff));
- }
- emitPtrByteSet(result, p_type, TRUE);
- break;
-
- default:
- assert( !"unhandled pointer type" );
- break;
- } // switch (p_type)
+
+ switch (p_type)
+ {
+ case -1:
+ if (AOP(result)->type == AOP_PCODE)
+ pcop = newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),bstr,0);
+ else
+ pcop = popGet(AOP(result),0);
+ emitpcode(lit?POC_BSF:POC_BCF,pcop);
+ break;
+
+ case POINTER:
+ case FPOINTER:
+ setup_fsr (result);
+ emitpcode(lit?POC_BSF:POC_BCF,newpCodeOpBit(PCOP(&pc_indf)->name,bstr,0));
+ break;
+
+ case CPOINTER:
+ assert( !"trying to assign to bitfield via pointer to __code space" );
+ break;
+
+ case GPOINTER:
+ emitPtrByteGet(result, p_type, FALSE);
+ if (lit) {
+ emitpcode(POC_IORLW, newpCodeOpLit (1UL << bstr));
+ } else {
+ emitpcode(POC_ANDLW, newpCodeOpLit ((~(1UL << bstr)) & 0x0ff));
+ }
+ emitPtrByteSet(result, p_type, TRUE);
+ break;
+
+ default:
+ assert( !"unhandled pointer type" );
+ break;
+ } // switch (p_type)
} else {
/* blen > 1 */
- litval = lit << bstr;
- litval &= (~mask) & 0x00ff;
-
- switch (p_type)
- {
- case -1:
- mov2w (AOP(result), 0);
- if ((litval|mask) != 0x00ff)
- emitpcode(POC_ANDLW, popGetLit (mask));
- if (litval != 0x00)
- emitpcode(POC_IORLW, popGetLit (litval));
- movwf (AOP(result), 0);
- break;
-
- case POINTER:
- case FPOINTER:
- case GPOINTER:
- emitPtrByteGet(result, p_type, FALSE);
- if ((litval|mask) != 0x00ff)
- emitpcode(POC_ANDLW, popGetLit (mask));
- if (litval != 0x00)
- emitpcode(POC_IORLW, popGetLit (litval));
- emitPtrByteSet(result, p_type, TRUE);
- break;
-
- case CPOINTER:
- assert( !"trying to assign to bitfield via pointer to __code space" );
- break;
-
- default:
- assert( !"unhandled pointer type" );
- break;
- } // switch
+ litval = lit << bstr;
+ litval &= (~mask) & 0x00ff;
+
+ switch (p_type)
+ {
+ case -1:
+ mov2w (AOP(result), 0);
+ if ((litval|mask) != 0x00ff)
+ emitpcode(POC_ANDLW, popGetLit (mask));
+ if (litval != 0x00)
+ emitpcode(POC_IORLW, popGetLit (litval));
+ movwf (AOP(result), 0);
+ break;
+
+ case POINTER:
+ case FPOINTER:
+ case GPOINTER:
+ emitPtrByteGet(result, p_type, FALSE);
+ if ((litval|mask) != 0x00ff)
+ emitpcode(POC_ANDLW, popGetLit (mask));
+ if (litval != 0x00)
+ emitpcode(POC_IORLW, popGetLit (litval));
+ emitPtrByteSet(result, p_type, TRUE);
+ break;
+
+ case CPOINTER:
+ assert( !"trying to assign to bitfield via pointer to __code space" );
+ break;
+
+ default:
+ assert( !"unhandled pointer type" );
+ break;
+ } // switch
} // if (blen > 1)
}
else
/* right is no literal */
if (blen==1) {
switch (p_type)
- {
- case -1:
- /* Note more efficient code, of pre clearing bit then only setting it if required,
- * can only be done if it is known that the result is not a SFR */
- emitpcode(POC_RRFW,popGet(AOP(right),0));
- emitSKPC;
- emitpcode(POC_BCF,newpCodeOpBit (aopGet(AOP(result), 0, FALSE, FALSE), bstr, 0));
- emitSKPNC;
- emitpcode(POC_BSF,newpCodeOpBit (aopGet(AOP(result), 0, FALSE, FALSE), bstr, 0));
- break;
-
- case POINTER:
- case FPOINTER:
- case GPOINTER:
- emitPtrByteGet (result, p_type, FALSE);
- emitpcode(POC_BTFSS, newpCodeOpBit (aopGet(AOP(right), 0, FALSE, FALSE), bstr, 0));
- emitpcode(POC_ANDLW, newpCodeOpLit (~(1UL << bstr) & 0x0ff));
- emitpcode(POC_BTFSC, newpCodeOpBit (aopGet(AOP(right), 0, FALSE, FALSE), bstr, 0));
- emitpcode(POC_IORLW, newpCodeOpLit ((1UL << bstr) & 0x0ff));
- emitPtrByteSet (result, p_type, TRUE);
- break;
-
- case CPOINTER:
- assert( !"trying to assign to bitfield via pointer to __code space" );
- break;
-
- default:
- assert( !"unhandled pointer type" );
- break;
- } // switch
- return;
+ {
+ case -1:
+ /* Note more efficient code, of pre clearing bit then only setting it if required,
+ * can only be done if it is known that the result is not a SFR */
+ emitpcode(POC_RRFW,popGet(AOP(right),0));
+ emitSKPC;
+ emitpcode(POC_BCF,newpCodeOpBit (aopGet(AOP(result), 0, FALSE, FALSE), bstr, 0));
+ emitSKPNC;
+ emitpcode(POC_BSF,newpCodeOpBit (aopGet(AOP(result), 0, FALSE, FALSE), bstr, 0));
+ break;
+
+ case POINTER:
+ case FPOINTER:
+ case GPOINTER:
+ emitPtrByteGet (result, p_type, FALSE);
+ emitpcode(POC_BTFSS, newpCodeOpBit (aopGet(AOP(right), 0, FALSE, FALSE), bstr, 0));
+ emitpcode(POC_ANDLW, newpCodeOpLit (~(1UL << bstr) & 0x0ff));
+ emitpcode(POC_BTFSC, newpCodeOpBit (aopGet(AOP(right), 0, FALSE, FALSE), bstr, 0));
+ emitpcode(POC_IORLW, newpCodeOpLit ((1UL << bstr) & 0x0ff));
+ emitPtrByteSet (result, p_type, TRUE);
+ break;
+
+ case CPOINTER:
+ assert( !"trying to assign to bitfield via pointer to __code space" );
+ break;
+
+ default:
+ assert( !"unhandled pointer type" );
+ break;
+ } // switch
+ return;
} else {
- /* Case with a bitfield 1 < length <= 8 and arbitrary source */
- pCodeOp *temp = popGetTempReg ();
-
- mov2w (AOP(right), 0);
- if (blen < 8) {
- emitpcode (POC_ANDLW, popGetLit ((1UL << blen)-1));
- }
- emitpcode(POC_MOVWF, temp);
- if (bstr) {
- AccLsh (temp, bstr);
- }
-
- switch (p_type)
- {
- case -1:
- mov2w (AOP(result), 0);
- emitpcode(POC_ANDLW, popGetLit (mask));
- emitpcode(POC_IORFW, temp);
- movwf (AOP(result), 0);
- break;
-
- case POINTER:
- case FPOINTER:
- case GPOINTER:
- emitPtrByteGet (result, p_type, FALSE);
- emitpcode(POC_ANDLW, popGetLit (mask));
- emitpcode(POC_IORFW, temp);
- emitPtrByteSet (result, p_type, TRUE);
- break;
-
- case CPOINTER:
- assert( !"trying to assign to bitfield via pointer to __code space" );
- break;
-
- default:
- assert( !"unhandled pointer type" );
- break;
- } // switch
-
- popReleaseTempReg (temp);
+ /* Case with a bitfield 1 < length <= 8 and arbitrary source */
+ pCodeOp *temp = popGetTempReg ();
+
+ mov2w (AOP(right), 0);
+ if (blen < 8) {
+ emitpcode (POC_ANDLW, popGetLit ((1UL << blen)-1));
+ }
+ emitpcode(POC_MOVWF, temp);
+ if (bstr) {
+ AccLsh (temp, bstr);
+ }
+
+ switch (p_type)
+ {
+ case -1:
+ mov2w (AOP(result), 0);
+ emitpcode(POC_ANDLW, popGetLit (mask));
+ emitpcode(POC_IORFW, temp);
+ movwf (AOP(result), 0);
+ break;
+
+ case POINTER:
+ case FPOINTER:
+ case GPOINTER:
+ emitPtrByteGet (result, p_type, FALSE);
+ emitpcode(POC_ANDLW, popGetLit (mask));
+ emitpcode(POC_IORFW, temp);
+ emitPtrByteSet (result, p_type, TRUE);
+ break;
+
+ case CPOINTER:
+ assert( !"trying to assign to bitfield via pointer to __code space" );
+ break;
+
+ default:
+ assert( !"unhandled pointer type" );
+ break;
+ } // switch
+
+ popReleaseTempReg (temp);
} // if (blen > 1)
} // if (AOP(right)->type != AOP_LIT)
return;
/* genDataPointerSet - remat pointer to data space */
/*-----------------------------------------------------------------*/
static void genDataPointerSet(operand *right,
- operand *result,
- iCode *ic)
-{
- int size, offset = 0 ;
- int ressize;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- aopOp(right,ic,FALSE);
- aopOp(result,ic,FALSE);
-
- assert (IS_SYMOP(result));
- assert (IS_PTR(OP_SYM_TYPE(result)));
-
- if (AOP_TYPE(right) == AOP_LIT)
- size = 4;
- else
- size = AOP_SIZE(right);
- ressize = getSize(OP_SYM_ETYPE(result));
- if (size > ressize) size = ressize;
- //fprintf (stderr, "%s:%u: size(right): %d, size(result): %d\n", __FUNCTION__,__LINE__, AOP_SIZE(right), ressize);
-
- //assert( !"what's going on here?" );
-
- /*
- if ( AOP_TYPE(result) == AOP_PCODE) {
- fprintf(stderr,"genDataPointerSet %s, %d\n",
- AOP(result)->aopu.pcop->name,
- PCOI(AOP(result)->aopu.pcop)->offset);
- }
- */
-
- // tsd, was l+1 - the underline `_' prefix was being stripped
- while (size--) {
- emitpComment ("%s:%u: size=%d/%d, offset=%d, AOP_TYPE(res)=%d", __FILE__,__LINE__, size, ressize, offset, AOP_TYPE(result));
-
- if (AOP_TYPE(right) == AOP_LIT) {
- unsigned int lit = pic14aopLiteral(AOP(IC_RIGHT(ic))->aopu.aop_lit, offset);
- //fprintf (stderr, "%s:%u: lit %d 0x%x\n", __FUNCTION__,__LINE__, lit, lit);
- if(lit&0xff) {
- emitpcode(POC_MOVLW, popGetLit(lit&0xff));
- emitpcode(POC_MOVWF, popGet(AOP(result), offset));
- } else {
- emitpcode(POC_CLRF, popGet(AOP(result), offset));
- }
- } else {
- //fprintf (stderr, "%s:%u: no lit\n", __FUNCTION__,__LINE__);
- emitpcode(POC_MOVFW, popGet(AOP(right), offset));
- emitpcode(POC_MOVWF, popGet(AOP(result), offset));
- }
-
- offset++;
- }
-
- freeAsmop(right,NULL,ic,TRUE);
- freeAsmop(result,NULL,ic,TRUE);
+ operand *result,
+ iCode *ic)
+{
+ int size, offset = 0 ;
+ int ressize;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ aopOp(right,ic,FALSE);
+ aopOp(result,ic,FALSE);
+
+ assert (IS_SYMOP(result));
+ assert (IS_PTR(OP_SYM_TYPE(result)));
+
+ if (AOP_TYPE(right) == AOP_LIT)
+ size = 4;
+ else
+ size = AOP_SIZE(right);
+ ressize = getSize(OP_SYM_ETYPE(result));
+ if (size > ressize) size = ressize;
+ //fprintf (stderr, "%s:%u: size(right): %d, size(result): %d\n", __FUNCTION__,__LINE__, AOP_SIZE(right), ressize);
+
+ //assert( !"what's going on here?" );
+
+ /*
+ if ( AOP_TYPE(result) == AOP_PCODE) {
+ fprintf(stderr,"genDataPointerSet %s, %d\n",
+ AOP(result)->aopu.pcop->name,
+ PCOI(AOP(result)->aopu.pcop)->offset);
+ }
+ */
+
+ // tsd, was l+1 - the underline `_' prefix was being stripped
+ while (size--) {
+ emitpComment ("%s:%u: size=%d/%d, offset=%d, AOP_TYPE(res)=%d", __FILE__,__LINE__, size, ressize, offset, AOP_TYPE(result));
+
+ if (AOP_TYPE(right) == AOP_LIT) {
+ unsigned int lit = pic14aopLiteral(AOP(IC_RIGHT(ic))->aopu.aop_lit, offset);
+ //fprintf (stderr, "%s:%u: lit %d 0x%x\n", __FUNCTION__,__LINE__, lit, lit);
+ if(lit&0xff) {
+ emitpcode(POC_MOVLW, popGetLit(lit&0xff));
+ emitpcode(POC_MOVWF, popGet(AOP(result), offset));
+ } else {
+ emitpcode(POC_CLRF, popGet(AOP(result), offset));
+ }
+ } else {
+ //fprintf (stderr, "%s:%u: no lit\n", __FUNCTION__,__LINE__);
+ emitpcode(POC_MOVFW, popGet(AOP(right), offset));
+ emitpcode(POC_MOVWF, popGet(AOP(result), offset));
+ }
+
+ offset++;
+ }
+
+ freeAsmop(right,NULL,ic,TRUE);
+ freeAsmop(result,NULL,ic,TRUE);
}
/*-----------------------------------------------------------------*/
/* genNearPointerSet - pic14_emitcode for near pointer put */
/*-----------------------------------------------------------------*/
static void genNearPointerSet (operand *right,
- operand *result,
- iCode *ic)
-{
- asmop *aop = NULL;
- sym_link *ptype = operandType(result);
- sym_link *retype = getSpec(operandType(right));
- sym_link *letype = getSpec(ptype);
- int direct = 0;
-
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- aopOp(result,ic,FALSE);
-
+ operand *result,
+ iCode *ic)
+{
+ asmop *aop = NULL;
+ sym_link *ptype = operandType(result);
+ sym_link *retype = getSpec(operandType(right));
+ sym_link *letype = getSpec(ptype);
+ int direct = 0;
+
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ aopOp(result,ic,FALSE);
+
#if 1
- /* if the result is rematerializable &
- in data space & not a bit variable */
- //if (AOP_TYPE(result) == AOP_IMMD &&
- if (AOP_TYPE(result) == AOP_PCODE &&
- PIC_IS_DATA_PTR(ptype) &&
- !IS_BITVAR (retype) &&
- !IS_BITVAR (letype)) {
- genDataPointerSet (right,result,ic);
- freeAsmop(result,NULL,ic,TRUE);
- return;
- }
+ /* if the result is rematerializable &
+ in data space & not a bit variable */
+ //if (AOP_TYPE(result) == AOP_IMMD &&
+ if (AOP_TYPE(result) == AOP_PCODE &&
+ PIC_IS_DATA_PTR(ptype) &&
+ !IS_BITVAR (retype) &&
+ !IS_BITVAR (letype)) {
+ genDataPointerSet (right,result,ic);
+ freeAsmop(result,NULL,ic,TRUE);
+ return;
+ }
#endif
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- aopOp(right,ic,FALSE);
- DEBUGpic14_AopType(__LINE__,NULL,right,result);
-
- /* Check if can access directly instead of via a pointer */
- if (PCOP(AOP(result))->type == PO_LITERAL && AOP_SIZE(right) == 1) {
- direct = 1;
- }
-
- if (IS_BITFIELD (letype))
- {
- genPackBits (letype, result, right, direct?-1:POINTER);
- return;
- }
-
- /* If the pointer value is not in a the FSR then need to put it in */
- /* Must set/reset IRP bit for use with FSR. */
- /* Note only do this once - assuming that never need to cross a bank boundary at address 0x100. */
- if (!direct)
- setup_fsr (result);
-
- {
- /* we have can just get the values */
- int size = AOP_SIZE(right);
- int offset = 0 ;
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- while (size--) {
- char *l = aopGet(AOP(right),offset,FALSE,TRUE);
- if (*l == '@' ) {
- emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
- } else {
- if (AOP_TYPE(right) == AOP_LIT) {
- emitpcode(POC_MOVLW,popGet(AOP(right),offset));
- } else {
- emitpcode(POC_MOVFW,popGet(AOP(right),offset));
- }
- if (direct)
- emitpcode(POC_MOVWF,popGet(AOP(result),0));
- else
- emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
- }
- if (size && !direct)
- emitpcode(POC_INCF,popCopyReg(&pc_fsr));
- offset++;
- }
- }
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- /* now some housekeeping stuff */
- if (aop) {
- /* we had to allocate for this iCode */
- freeAsmop(NULL,aop,ic,TRUE);
- } else {
- /* we did not allocate which means left
- already in a pointer register, then
- if size > 0 && this could be used again
- we have to point it back to where it
- belongs */
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if (AOP_SIZE(right) > 1 &&
- !OP_SYMBOL(result)->remat &&
- ( OP_SYMBOL(result)->liveTo > ic->seq ||
- ic->depth )) {
- int size = AOP_SIZE(right) - 1;
- while (size--)
- emitpcode(POC_DECF, popCopyReg(&pc_fsr));
- }
- }
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- /* done */
-
- freeAsmop(right,NULL,ic,TRUE);
- freeAsmop(result,NULL,ic,TRUE);
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ aopOp(right,ic,FALSE);
+ DEBUGpic14_AopType(__LINE__,NULL,right,result);
+
+ /* Check if can access directly instead of via a pointer */
+ if (PCOP(AOP(result))->type == PO_LITERAL && AOP_SIZE(right) == 1) {
+ direct = 1;
+ }
+
+ if (IS_BITFIELD (letype))
+ {
+ genPackBits (letype, result, right, direct?-1:POINTER);
+ return;
+ }
+
+ /* If the pointer value is not in a the FSR then need to put it in */
+ /* Must set/reset IRP bit for use with FSR. */
+ /* Note only do this once - assuming that never need to cross a bank boundary at address 0x100. */
+ if (!direct)
+ setup_fsr (result);
+
+ {
+ /* we have can just get the values */
+ int size = AOP_SIZE(right);
+ int offset = 0 ;
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ while (size--) {
+ char *l = aopGet(AOP(right),offset,FALSE,TRUE);
+ if (*l == '@' ) {
+ emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
+ } else {
+ if (AOP_TYPE(right) == AOP_LIT) {
+ emitpcode(POC_MOVLW,popGet(AOP(right),offset));
+ } else {
+ emitpcode(POC_MOVFW,popGet(AOP(right),offset));
+ }
+ if (direct)
+ emitpcode(POC_MOVWF,popGet(AOP(result),0));
+ else
+ emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
+ }
+ if (size && !direct)
+ emitpcode(POC_INCF,popCopyReg(&pc_fsr));
+ offset++;
+ }
+ }
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* now some housekeeping stuff */
+ if (aop) {
+ /* we had to allocate for this iCode */
+ freeAsmop(NULL,aop,ic,TRUE);
+ } else {
+ /* we did not allocate which means left
+ already in a pointer register, then
+ if size > 0 && this could be used again
+ we have to point it back to where it
+ belongs */
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ if (AOP_SIZE(right) > 1 &&
+ !OP_SYMBOL(result)->remat &&
+ ( OP_SYMBOL(result)->liveTo > ic->seq ||
+ ic->depth )) {
+ int size = AOP_SIZE(right) - 1;
+ while (size--)
+ emitpcode(POC_DECF, popCopyReg(&pc_fsr));
+ }
+ }
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* done */
+
+ freeAsmop(right,NULL,ic,TRUE);
+ freeAsmop(result,NULL,ic,TRUE);
}
#if 0
/* genPagedPointerSet - pic14_emitcode for Paged pointer put */
/*-----------------------------------------------------------------*/
static void genPagedPointerSet (operand *right,
- operand *result,
- iCode *ic)
-{
- asmop *aop = NULL;
- regs *preg = NULL ;
- char *rname , *l;
- sym_link *retype;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- retype= getSpec(operandType(right));
-
- aopOp(result,ic,FALSE);
-
- /* if the value is already in a pointer register
- then don't need anything more */
- if (!AOP_INPREG(AOP(result))) {
- /* otherwise get a free pointer register */
- aop = newAsmop(0);
- preg = getFreePtr(ic,&aop,FALSE);
- pic14_emitcode("mov","%s,%s",
- preg->name,
- aopGet(AOP(result),0,FALSE,TRUE));
- rname = preg->name ;
- } else
- rname = aopGet(AOP(result),0,FALSE,FALSE);
-
- freeAsmop(result,NULL,ic,TRUE);
- aopOp (right,ic,FALSE);
-
- /* if bitfield then unpack the bits */
- if (IS_BITFIELD(retype))
- genPackBits (retype,result,right,rname,PPOINTER);
- else {
- /* we have can just get the values */
- int size = AOP_SIZE(right);
- int offset = 0 ;
-
- while (size--) {
- l = aopGet(AOP(right),offset,FALSE,TRUE);
-
- MOVA(l);
- pic14_emitcode("movx","@%s,a",rname);
-
- if (size)
- pic14_emitcode("inc","%s",rname);
-
- offset++;
- }
- }
-
- /* now some housekeeping stuff */
- if (aop) {
- /* we had to allocate for this iCode */
- freeAsmop(NULL,aop,ic,TRUE);
- } else {
- /* we did not allocate which means left
- already in a pointer register, then
- if size > 0 && this could be used again
- we have to point it back to where it
- belongs */
- if (AOP_SIZE(right) > 1 &&
- !OP_SYMBOL(result)->remat &&
- ( OP_SYMBOL(result)->liveTo > ic->seq ||
- ic->depth )) {
- int size = AOP_SIZE(right) - 1;
- while (size--)
- pic14_emitcode("dec","%s",rname);
- }
- }
-
- /* done */
- freeAsmop(right,NULL,ic,TRUE);
-
-
+ operand *result,
+ iCode *ic)
+{
+ asmop *aop = NULL;
+ regs *preg = NULL ;
+ char *rname , *l;
+ sym_link *retype;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ retype= getSpec(operandType(right));
+
+ aopOp(result,ic,FALSE);
+
+ /* if the value is already in a pointer register
+ then don't need anything more */
+ if (!AOP_INPREG(AOP(result))) {
+ /* otherwise get a free pointer register */
+ aop = newAsmop(0);
+ preg = getFreePtr(ic,&aop,FALSE);
+ pic14_emitcode("mov","%s,%s",
+ preg->name,
+ aopGet(AOP(result),0,FALSE,TRUE));
+ rname = preg->name ;
+ } else
+ rname = aopGet(AOP(result),0,FALSE,FALSE);
+
+ freeAsmop(result,NULL,ic,TRUE);
+ aopOp (right,ic,FALSE);
+
+ /* if bitfield then unpack the bits */
+ if (IS_BITFIELD(retype))
+ genPackBits (retype,result,right,rname,PPOINTER);
+ else {
+ /* we have can just get the values */
+ int size = AOP_SIZE(right);
+ int offset = 0 ;
+
+ while (size--) {
+ l = aopGet(AOP(right),offset,FALSE,TRUE);
+
+ MOVA(l);
+ pic14_emitcode("movx","@%s,a",rname);
+
+ if (size)
+ pic14_emitcode("inc","%s",rname);
+
+ offset++;
+ }
+ }
+
+ /* now some housekeeping stuff */
+ if (aop) {
+ /* we had to allocate for this iCode */
+ freeAsmop(NULL,aop,ic,TRUE);
+ } else {
+ /* we did not allocate which means left
+ already in a pointer register, then
+ if size > 0 && this could be used again
+ we have to point it back to where it
+ belongs */
+ if (AOP_SIZE(right) > 1 &&
+ !OP_SYMBOL(result)->remat &&
+ ( OP_SYMBOL(result)->liveTo > ic->seq ||
+ ic->depth )) {
+ int size = AOP_SIZE(right) - 1;
+ while (size--)
+ pic14_emitcode("dec","%s",rname);
+ }
+ }
+
+ /* done */
+ freeAsmop(right,NULL,ic,TRUE);
+
+
}
/*-----------------------------------------------------------------*/
/* genFarPointerSet - set value from far space */
/*-----------------------------------------------------------------*/
static void genFarPointerSet (operand *right,
- operand *result, iCode *ic)
-{
- int size, offset ;
- sym_link *retype = getSpec(operandType(right));
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- aopOp(result,ic,FALSE);
-
- /* if the operand is already in dptr
- then we do nothing else we move the value to dptr */
- if (AOP_TYPE(result) != AOP_STR) {
- /* if this is remateriazable */
- if (AOP_TYPE(result) == AOP_IMMD)
- pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
- else { /* we need to get it byte by byte */
- pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
- pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
- if (options.model == MODEL_FLAT24)
- {
- pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
- }
- }
- }
- /* so dptr know contains the address */
- freeAsmop(result,NULL,ic,TRUE);
- aopOp(right,ic,FALSE);
-
- /* if bit then unpack */
- if (IS_BITFIELD(retype))
- genPackBits(retype,result,right,"dptr",FPOINTER);
- else {
- size = AOP_SIZE(right);
- offset = 0 ;
-
- while (size--) {
- char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
- MOVA(l);
- pic14_emitcode("movx","@dptr,a");
- if (size)
- pic14_emitcode("inc","dptr");
- }
- }
-
- freeAsmop(right,NULL,ic,TRUE);
+ operand *result, iCode *ic)
+{
+ int size, offset ;
+ sym_link *retype = getSpec(operandType(right));
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ aopOp(result,ic,FALSE);
+
+ /* if the operand is already in dptr
+ then we do nothing else we move the value to dptr */
+ if (AOP_TYPE(result) != AOP_STR) {
+ /* if this is remateriazable */
+ if (AOP_TYPE(result) == AOP_IMMD)
+ pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
+ else { /* we need to get it byte by byte */
+ pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
+ pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
+ if (options.model == MODEL_FLAT24)
+ {
+ pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
+ }
+ }
+ }
+ /* so dptr know contains the address */
+ freeAsmop(result,NULL,ic,TRUE);
+ aopOp(right,ic,FALSE);
+
+ /* if bit then unpack */
+ if (IS_BITFIELD(retype))
+ genPackBits(retype,result,right,"dptr",FPOINTER);
+ else {
+ size = AOP_SIZE(right);
+ offset = 0 ;
+
+ while (size--) {
+ char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
+ MOVA(l);
+ pic14_emitcode("movx","@dptr,a");
+ if (size)
+ pic14_emitcode("inc","dptr");
+ }
+ }
+
+ freeAsmop(right,NULL,ic,TRUE);
}
#endif
/*-----------------------------------------------------------------*/
static void genGenPointerSet (operand *right, operand *result, iCode *ic)
{
- sym_link *retype = getSpec(operandType(result));
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- aopOp(right,ic,FALSE);
- aopOp(result,ic,FALSE);
-
-
- DEBUGpic14_AopType(__LINE__,right,NULL,result);
-
- if (IS_BITFIELD(retype))
- {
- genPackBits (retype, result, right, GPOINTER);
- return;
- }
-
- {
- /* emit call to __gptrput */
- char *func[] = {NULL, "__gptrput1", "__gptrput2", "__gptrput3", "__gptrput4"};
- int size = AOP_SIZE(right);
- int idx = 0;
-
- /* The following assertion fails for
- * struct foo { char a; char b; } bar;
- * void demo(struct foo *dst, char c) { dst->b = c; }
- * as size will be 1 (sizeof(c)), whereas dst->b will be accessed
- * using (((char *)dst)+1), whose OP_SYM_ETYPE still is struct foo
- * of size 2.
- * The frontend seems to guarantee that IC_LEFT has the correct size,
- * it works fine both for larger and smaller types of `char c'.
- * */
- //assert (size == getSize(OP_SYM_ETYPE(result)));
- assert (size > 0 && size <= 4);
-
- /* pass arguments */
- /* - value (MSB in Gstack_base_addr-2, growing downwards) */
- {
- int off = size;
- idx = 2;
- while (off--)
- {
- mov2w_op (right, off);
- emitpcode (POC_MOVWF, popRegFromIdx (Gstack_base_addr - idx++));
- }
- idx = 0;
- }
- /* - address */
- assert (AOP_SIZE(result) == 3);
- mov2w(AOP(result), 0);
- emitpcode(POC_MOVWF, popRegFromIdx (Gstack_base_addr - 1));
- mov2w(AOP(result), 1);
- emitpcode(POC_MOVWF, popRegFromIdx (Gstack_base_addr));
- mov2w(AOP(result), 2);
- call_libraryfunc (func[size]);
- }
-
- freeAsmop(right,NULL,ic,TRUE);
- freeAsmop(result,NULL,ic,TRUE);
+ sym_link *retype = getSpec(operandType(result));
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ aopOp(right,ic,FALSE);
+ aopOp(result,ic,FALSE);
+
+
+ DEBUGpic14_AopType(__LINE__,right,NULL,result);
+
+ if (IS_BITFIELD(retype))
+ {
+ genPackBits (retype, result, right, GPOINTER);
+ return;
+ }
+
+ {
+ /* emit call to __gptrput */
+ char *func[] = {NULL, "__gptrput1", "__gptrput2", "__gptrput3", "__gptrput4"};
+ int size = AOP_SIZE(right);
+ int idx = 0;
+
+ /* The following assertion fails for
+ * struct foo { char a; char b; } bar;
+ * void demo(struct foo *dst, char c) { dst->b = c; }
+ * as size will be 1 (sizeof(c)), whereas dst->b will be accessed
+ * using (((char *)dst)+1), whose OP_SYM_ETYPE still is struct foo
+ * of size 2.
+ * The frontend seems to guarantee that IC_LEFT has the correct size,
+ * it works fine both for larger and smaller types of `char c'.
+ * */
+ //assert (size == getSize(OP_SYM_ETYPE(result)));
+ assert (size > 0 && size <= 4);
+
+ /* pass arguments */
+ /* - value (MSB in Gstack_base_addr-2, growing downwards) */
+ {
+ int off = size;
+ idx = 2;
+ while (off--)
+ {
+ mov2w_op (right, off);
+ emitpcode (POC_MOVWF, popRegFromIdx (Gstack_base_addr - idx++));
+ }
+ idx = 0;
+ }
+ /* - address */
+ assert (AOP_SIZE(result) == 3);
+ mov2w(AOP(result), 0);
+ emitpcode(POC_MOVWF, popRegFromIdx (Gstack_base_addr - 1));
+ mov2w(AOP(result), 1);
+ emitpcode(POC_MOVWF, popRegFromIdx (Gstack_base_addr));
+ mov2w(AOP(result), 2);
+ call_libraryfunc (func[size]);
+ }
+
+ freeAsmop(right,NULL,ic,TRUE);
+ freeAsmop(result,NULL,ic,TRUE);
}
/*-----------------------------------------------------------------*/
/* genPointerSet - stores the value into a pointer location */
/*-----------------------------------------------------------------*/
static void genPointerSet (iCode *ic)
-{
- operand *right, *result ;
- sym_link *type, *etype;
- int p_type;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- right = IC_RIGHT(ic);
- result = IC_RESULT(ic) ;
-
- /* depending on the type of pointer we need to
- move it to the correct pointer register */
- type = operandType(result);
- etype = getSpec(type);
- /* if left is of type of pointer then it is simple */
- if (IS_PTR(type) && !IS_FUNC(type->next)) {
- p_type = DCL_TYPE(type);
- }
- else {
- /* we have to go by the storage class */
- p_type = PTR_TYPE(SPEC_OCLS(etype));
-
- /* if (SPEC_OCLS(etype)->codesp ) { */
- /* p_type = CPOINTER ; */
- /* } */
- /* else */
- /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
- /* p_type = FPOINTER ; */
- /* else */
- /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
- /* p_type = PPOINTER ; */
- /* else */
- /* if (SPEC_OCLS(etype) == idata ) */
- /* p_type = IPOINTER ; */
- /* else */
- /* p_type = POINTER ; */
- }
-
- /* now that we have the pointer type we assign
- the pointer values */
- switch (p_type) {
-
- case POINTER:
- case FPOINTER:
- //case IPOINTER:
- genNearPointerSet (right,result,ic);
- break;
+{
+ operand *right, *result ;
+ sym_link *type, *etype;
+ int p_type;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ right = IC_RIGHT(ic);
+ result = IC_RESULT(ic) ;
+
+ /* depending on the type of pointer we need to
+ move it to the correct pointer register */
+ type = operandType(result);
+ etype = getSpec(type);
+ /* if left is of type of pointer then it is simple */
+ if (IS_PTR(type) && !IS_FUNC(type->next)) {
+ p_type = DCL_TYPE(type);
+ }
+ else {
+ /* we have to go by the storage class */
+ p_type = PTR_TYPE(SPEC_OCLS(etype));
+
+ /* if (SPEC_OCLS(etype)->codesp ) { */
+ /* p_type = CPOINTER ; */
+ /* } */
+ /* else */
+ /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
+ /* p_type = FPOINTER ; */
+ /* else */
+ /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
+ /* p_type = PPOINTER ; */
+ /* else */
+ /* if (SPEC_OCLS(etype) == idata ) */
+ /* p_type = IPOINTER ; */
+ /* else */
+ /* p_type = POINTER ; */
+ }
+
+ /* now that we have the pointer type we assign
+ the pointer values */
+ switch (p_type) {
+
+ case POINTER:
+ case FPOINTER:
+ //case IPOINTER:
+ genNearPointerSet (right,result,ic);
+ break;
/*
- case PPOINTER:
- genPagedPointerSet (right,result,ic);
- break;
-
- case FPOINTER:
- genFarPointerSet (right,result,ic);
- break;
+ case PPOINTER:
+ genPagedPointerSet (right,result,ic);
+ break;
+
+ case FPOINTER:
+ genFarPointerSet (right,result,ic);
+ break;
*/
- case GPOINTER:
- genGenPointerSet (right,result,ic);
- break;
-
- default:
- werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "genPointerSet: illegal pointer type");
- }
+ case GPOINTER:
+ genGenPointerSet (right,result,ic);
+ break;
+
+ default:
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "genPointerSet: illegal pointer type");
+ }
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static void genIfx (iCode *ic, iCode *popIc)
{
- operand *cond = IC_COND(ic);
- int isbit =0;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- aopOp(cond,ic,FALSE);
-
- /* get the value into acc */
- if (AOP_TYPE(cond) != AOP_CRY)
- pic14_toBoolean(cond);
- else
- isbit = 1;
-
- /* if there was something to be popped then do it */
- if (popIc)
- genIpop(popIc);
-
- if (isbit)
- {
- /* This assumes that CARRY is set iff cond is true */
- if (IC_TRUE(ic))
- {
- assert (!IC_FALSE(ic));
- emitpcode(POC_BTFSC, popGet(AOP(cond), 0));
- //emitSKPNC;
- emitpcode(POC_GOTO, popGetLabel(IC_TRUE(ic)->key));
- } else {
- assert (IC_FALSE(ic));
- emitpcode(POC_BTFSS, popGet(AOP(cond), 0));
- //emitSKPC;
- emitpcode(POC_GOTO, popGetLabel(IC_FALSE(ic)->key));
- }
- if (0)
- {
- static int hasWarned = 0;
- if (!hasWarned)
- {
- fprintf (stderr, "WARNING: using untested code for %s:%u -- please check the .asm output and report bugs.\n", ic->filename, ic->lineno);
- hasWarned = 1;
- }
- }
- }
- else
- {
- /* now Z is set iff !cond */
- if (IC_TRUE(ic))
- {
- assert (!IC_FALSE(ic));
- emitSKPZ;
- emitpcode(POC_GOTO, popGetLabel(IC_TRUE(ic)->key));
- } else {
- emitSKPNZ;
- emitpcode(POC_GOTO, popGetLabel(IC_FALSE(ic)->key));
- }
- }
-
- ic->generated = 1;
-
- /* the result is now in the accumulator */
- freeAsmop(cond,NULL,ic,TRUE);
+ operand *cond = IC_COND(ic);
+ int isbit =0;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ aopOp(cond,ic,FALSE);
+
+ /* get the value into acc */
+ if (AOP_TYPE(cond) != AOP_CRY)
+ pic14_toBoolean(cond);
+ else
+ isbit = 1;
+
+ /* if there was something to be popped then do it */
+ if (popIc)
+ genIpop(popIc);
+
+ if (isbit)
+ {
+ /* This assumes that CARRY is set iff cond is true */
+ if (IC_TRUE(ic))
+ {
+ assert (!IC_FALSE(ic));
+ emitpcode(POC_BTFSC, popGet(AOP(cond), 0));
+ //emitSKPNC;
+ emitpcode(POC_GOTO, popGetLabel(IC_TRUE(ic)->key));
+ } else {
+ assert (IC_FALSE(ic));
+ emitpcode(POC_BTFSS, popGet(AOP(cond), 0));
+ //emitSKPC;
+ emitpcode(POC_GOTO, popGetLabel(IC_FALSE(ic)->key));
+ }
+ if (0)
+ {
+ static int hasWarned = 0;
+ if (!hasWarned)
+ {
+ fprintf (stderr, "WARNING: using untested code for %s:%u -- please check the .asm output and report bugs.\n", ic->filename, ic->lineno);
+ hasWarned = 1;
+ }
+ }
+ }
+ else
+ {
+ /* now Z is set iff !cond */
+ if (IC_TRUE(ic))
+ {
+ assert (!IC_FALSE(ic));
+ emitSKPZ;
+ emitpcode(POC_GOTO, popGetLabel(IC_TRUE(ic)->key));
+ } else {
+ emitSKPNZ;
+ emitpcode(POC_GOTO, popGetLabel(IC_FALSE(ic)->key));
+ }
+ }
+
+ ic->generated = 1;
+
+ /* the result is now in the accumulator */
+ freeAsmop(cond,NULL,ic,TRUE);
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static void genAddrOf (iCode *ic)
{
- operand *right, *result, *left;
- int size, offset ;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
-
- //aopOp(IC_RESULT(ic),ic,FALSE);
-
- aopOp((left=IC_LEFT(ic)),ic,FALSE);
- aopOp((right=IC_RIGHT(ic)),ic,FALSE);
- aopOp((result=IC_RESULT(ic)),ic,TRUE);
-
- DEBUGpic14_AopType(__LINE__,left,right,result);
- assert (IS_SYMOP (left));
-
- /* sanity check: generic pointers to code space are not yet supported,
- * pionters to codespace must not be assigned addresses of __data values. */
+ operand *right, *result, *left;
+ int size, offset ;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+
+ //aopOp(IC_RESULT(ic),ic,FALSE);
+
+ aopOp((left=IC_LEFT(ic)),ic,FALSE);
+ aopOp((right=IC_RIGHT(ic)),ic,FALSE);
+ aopOp((result=IC_RESULT(ic)),ic,TRUE);
+
+ DEBUGpic14_AopType(__LINE__,left,right,result);
+ assert (IS_SYMOP (left));
+
+ /* sanity check: generic pointers to code space are not yet supported,
+ * pionters to codespace must not be assigned addresses of __data values. */
#if 0
- fprintf (stderr, "result: %s, left: %s\n", OP_SYMBOL(result)->name, OP_SYMBOL(left)->name);
- fprintf (stderr, "result->type : "); printTypeChain (OP_SYM_TYPE(result), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n", IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_TYPE(result)))), IS_CODEPTR(OP_SYM_TYPE(result)), IS_PTR_CONST(OP_SYM_TYPE(result)));
- fprintf (stderr, "result->etype: "); printTypeChain (OP_SYM_ETYPE(result), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n", IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_ETYPE(result)))), IS_CODEPTR(OP_SYM_ETYPE(result)), IS_PTR_CONST(OP_SYM_ETYPE(result)));
- fprintf (stderr, "left->type : "); printTypeChain (OP_SYM_TYPE(left), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n", IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_TYPE(left)))), IS_CODEPTR(OP_SYM_TYPE(left)), IS_PTR_CONST(OP_SYM_TYPE(left)));
- fprintf (stderr, "left->etype : "); printTypeChain (OP_SYM_ETYPE(left), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n",IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_ETYPE(left)))), IS_CODEPTR(OP_SYM_ETYPE(left)), IS_PTR_CONST(OP_SYM_ETYPE(left)));
+ fprintf (stderr, "result: %s, left: %s\n", OP_SYMBOL(result)->name, OP_SYMBOL(left)->name);
+ fprintf (stderr, "result->type : "); printTypeChain (OP_SYM_TYPE(result), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n", IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_TYPE(result)))), IS_CODEPTR(OP_SYM_TYPE(result)), IS_PTR_CONST(OP_SYM_TYPE(result)));
+ fprintf (stderr, "result->etype: "); printTypeChain (OP_SYM_ETYPE(result), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n", IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_ETYPE(result)))), IS_CODEPTR(OP_SYM_ETYPE(result)), IS_PTR_CONST(OP_SYM_ETYPE(result)));
+ fprintf (stderr, "left->type : "); printTypeChain (OP_SYM_TYPE(left), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n", IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_TYPE(left)))), IS_CODEPTR(OP_SYM_TYPE(left)), IS_PTR_CONST(OP_SYM_TYPE(left)));
+ fprintf (stderr, "left->etype : "); printTypeChain (OP_SYM_ETYPE(left), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n",IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_ETYPE(left)))), IS_CODEPTR(OP_SYM_ETYPE(left)), IS_PTR_CONST(OP_SYM_ETYPE(left)));
#endif
- if (IS_CODEPTR(OP_SYM_TYPE(result)) && !IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_TYPE(left))))) {
- fprintf (stderr, "trying to assign __code pointer (%s) an address in __data space (&%s) -- expect trouble\n",
- IS_SYMOP(result) ? OP_SYMBOL(result)->name : "unknown",
- OP_SYMBOL(left)->name);
- } else if (!IS_CODEPTR (OP_SYM_TYPE(result)) && IN_CODESPACE(SPEC_OCLS(getSpec(OP_SYM_TYPE(left))))) {
- fprintf (stderr, "trying to assign __data pointer (%s) an address in __code space (&%s) -- expect trouble\n",
- IS_SYMOP(result) ? OP_SYMBOL(result)->name : "unknown",
- OP_SYMBOL(left)->name);
- }
-
- size = AOP_SIZE(IC_RESULT(ic));
- if (IS_GENPTR(OP_SYM_TYPE(result))) {
- /* strip tag */
- if (size > GPTRSIZE-1) size = GPTRSIZE-1;
- }
- offset = 0;
-
- while (size--) {
- /* fixing bug #863624, reported from (errolv) */
- emitpcode(POC_MOVLW, popGetImmd(OP_SYMBOL(left)->rname, offset, 0, IS_FUNC(OP_SYM_TYPE(left))));
- emitpcode(POC_MOVWF, popGet(AOP(result), offset));
-
+ if (IS_CODEPTR(OP_SYM_TYPE(result)) && !IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_TYPE(left))))) {
+ fprintf (stderr, "trying to assign __code pointer (%s) an address in __data space (&%s) -- expect trouble\n",
+ IS_SYMOP(result) ? OP_SYMBOL(result)->name : "unknown",
+ OP_SYMBOL(left)->name);
+ } else if (!IS_CODEPTR (OP_SYM_TYPE(result)) && IN_CODESPACE(SPEC_OCLS(getSpec(OP_SYM_TYPE(left))))) {
+ fprintf (stderr, "trying to assign __data pointer (%s) an address in __code space (&%s) -- expect trouble\n",
+ IS_SYMOP(result) ? OP_SYMBOL(result)->name : "unknown",
+ OP_SYMBOL(left)->name);
+ }
+
+ size = AOP_SIZE(IC_RESULT(ic));
+ if (IS_GENPTR(OP_SYM_TYPE(result))) {
+ /* strip tag */
+ if (size > GPTRSIZE-1) size = GPTRSIZE-1;
+ }
+ offset = 0;
+
+ while (size--) {
+ /* fixing bug #863624, reported from (errolv) */
+ emitpcode(POC_MOVLW, popGetImmd(OP_SYMBOL(left)->rname, offset, 0, IS_FUNC(OP_SYM_TYPE(left))));
+ emitpcode(POC_MOVWF, popGet(AOP(result), offset));
+
#if 0
- emitpcode(POC_MOVLW, popGet(AOP(left),offset));
- emitpcode(POC_MOVWF, popGet(AOP(result),offset));
+ emitpcode(POC_MOVLW, popGet(AOP(left),offset));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offset));
#endif
- offset++;
- }
-
- if (IS_GENPTR(OP_SYM_TYPE(result)))
- {
- /* provide correct tag */
- int isCode = IN_CODESPACE(SPEC_OCLS(getSpec(OP_SYM_TYPE(left))));
- emitpcode (POC_MOVLW, popGetLit (isCode ? GPTRTAG_CODE : GPTRTAG_DATA));
- movwf (AOP(result), 2);
- }
-
- freeAsmop(left,NULL,ic,FALSE);
- freeAsmop(result,NULL,ic,TRUE);
-
+ offset++;
+ }
+
+ if (IS_GENPTR(OP_SYM_TYPE(result)))
+ {
+ /* provide correct tag */
+ int isCode = IN_CODESPACE(SPEC_OCLS(getSpec(OP_SYM_TYPE(left))));
+ emitpcode (POC_MOVLW, popGetLit (isCode ? GPTRTAG_CODE : GPTRTAG_DATA));
+ movwf (AOP(result), 2);
+ }
+
+ freeAsmop(left,NULL,ic,FALSE);
+ freeAsmop(result,NULL,ic,TRUE);
+
}
#if 0
/*-----------------------------------------------------------------*/
static void genFarFarAssign (operand *result, operand *right, iCode *ic)
{
- int size = AOP_SIZE(right);
- int offset = 0;
- char *l ;
- /* first push the right side on to the stack */
- while (size--) {
- l = aopGet(AOP(right),offset++,FALSE,FALSE);
- MOVA(l);
- pic14_emitcode ("push","acc");
- }
-
- freeAsmop(right,NULL,ic,FALSE);
- /* now assign DPTR to result */
- aopOp(result,ic,FALSE);
- size = AOP_SIZE(result);
- while (size--) {
- pic14_emitcode ("pop","acc");
- aopPut(AOP(result),"a",--offset);
- }
- freeAsmop(result,NULL,ic,FALSE);
-
+ int size = AOP_SIZE(right);
+ int offset = 0;
+ char *l ;
+ /* first push the right side on to the stack */
+ while (size--) {
+ l = aopGet(AOP(right),offset++,FALSE,FALSE);
+ MOVA(l);
+ pic14_emitcode ("push","acc");
+ }
+
+ freeAsmop(right,NULL,ic,FALSE);
+ /* now assign DPTR to result */
+ aopOp(result,ic,FALSE);
+ size = AOP_SIZE(result);
+ while (size--) {
+ pic14_emitcode ("pop","acc");
+ aopPut(AOP(result),"a",--offset);
+ }
+ freeAsmop(result,NULL,ic,FALSE);
+
}
#endif
/*-----------------------------------------------------------------*/
static void genAssign (iCode *ic)
{
- operand *result, *right;
- int size, offset,know_W;
- unsigned long lit = 0L;
-
- result = IC_RESULT(ic);
- right = IC_RIGHT(ic) ;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- /* if they are the same */
- if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
- return ;
-
- aopOp(right,ic,FALSE);
- aopOp(result,ic,TRUE);
-
- DEBUGpic14_AopType(__LINE__,NULL,right,result);
-
- /* if they are the same registers */
- if (pic14_sameRegs(AOP(right),AOP(result)))
- goto release;
-
- /* special case: assign from __code */
- if (!IS_ITEMP(right) /* --> iTemps never reside in __code */
- && IS_SYMOP (right) /* --> must be an immediate (otherwise we would be in genConstPointerGet) */
- && !IS_FUNC(OP_SYM_TYPE(right)) /* --> we would want its address instead of the first instruction */
- && !IS_CODEPTR(OP_SYM_TYPE(right)) /* --> get symbols address instread */
- && IN_CODESPACE (SPEC_OCLS (getSpec (OP_SYM_TYPE(right)))))
- {
- emitpComment ("genAssign from CODESPACE");
- genConstPointerGet (right, result, ic);
- goto release;
- }
-
- /* just for symmetry reasons... */
- if (!IS_ITEMP(result)
- && IS_SYMOP (result)
- && IN_CODESPACE (SPEC_OCLS (getSpec (OP_SYM_TYPE(result)))))
- {
- assert ( !"cannot write to CODESPACE" );
- }
-
- /* if the result is a bit */
- if (AOP_TYPE(result) == AOP_CRY) {
-
- /* if the right size is a literal then
- we know what the value is */
- if (AOP_TYPE(right) == AOP_LIT) {
-
- emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
- popGet(AOP(result),0));
-
- if (((int) operandLitValue(right)))
- pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
- AOP(result)->aopu.aop_dir,
- AOP(result)->aopu.aop_dir);
- else
- pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
- AOP(result)->aopu.aop_dir,
- AOP(result)->aopu.aop_dir);
- goto release;
- }
-
- /* the right is also a bit variable */
- if (AOP_TYPE(right) == AOP_CRY) {
- emitpcode(POC_BCF, popGet(AOP(result),0));
- emitpcode(POC_BTFSC, popGet(AOP(right),0));
- emitpcode(POC_BSF, popGet(AOP(result),0));
-
- pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
- AOP(result)->aopu.aop_dir,
- AOP(result)->aopu.aop_dir);
- pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
- AOP(right)->aopu.aop_dir,
- AOP(right)->aopu.aop_dir);
- pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
- AOP(result)->aopu.aop_dir,
- AOP(result)->aopu.aop_dir);
- goto release ;
- }
-
- /* we need to or */
- emitpcode(POC_BCF, popGet(AOP(result),0));
- pic14_toBoolean(right);
- emitSKPZ;
- emitpcode(POC_BSF, popGet(AOP(result),0));
- //aopPut(AOP(result),"a",0);
- goto release ;
- }
-
- /* bit variables done */
- /* general case */
- size = AOP_SIZE(result);
- offset = 0 ;
- if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if(aopIdx(AOP(result),0) == 4) {
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- emitpcode(POC_MOVFW, popGet(AOP(right),offset));
- emitpcode(POC_MOVWF, popGet(AOP(result),offset));
- goto release;
- } else
- DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
- }
-
- know_W=-1;
- while (size--) {
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if(AOP_TYPE(right) == AOP_LIT) {
- lit = (unsigned long)pic14aopLiteral(AOP(right)->aopu.aop_lit, offset) & 0x0ff;
- if(lit&0xff) {
- if(know_W != (int)(lit&0xff))
- emitpcode(POC_MOVLW,popGetLit(lit&0xff));
- know_W = lit&0xff;
- emitpcode(POC_MOVWF, popGet(AOP(result),offset));
- } else
- emitpcode(POC_CLRF, popGet(AOP(result),offset));
-
- } else if (AOP_TYPE(right) == AOP_CRY) {
- emitpcode(POC_CLRF, popGet(AOP(result),offset));
- if(offset == 0) {
- emitpcode(POC_BTFSS, popGet(AOP(right),0));
- emitpcode(POC_INCF, popGet(AOP(result),0));
- }
- } else {
- mov2w_op (right, offset);
- emitpcode(POC_MOVWF, popGet(AOP(result),offset));
- }
-
- offset++;
- }
-
-
+ operand *result, *right;
+ int size, offset,know_W;
+ unsigned long lit = 0L;
+
+ result = IC_RESULT(ic);
+ right = IC_RIGHT(ic) ;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ /* if they are the same */
+ if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
+ return ;
+
+ aopOp(right,ic,FALSE);
+ aopOp(result,ic,TRUE);
+
+ DEBUGpic14_AopType(__LINE__,NULL,right,result);
+
+ /* if they are the same registers */
+ if (pic14_sameRegs(AOP(right),AOP(result)))
+ goto release;
+
+ /* special case: assign from __code */
+ if (!IS_ITEMP(right) /* --> iTemps never reside in __code */
+ && IS_SYMOP (right) /* --> must be an immediate (otherwise we would be in genConstPointerGet) */
+ && !IS_FUNC(OP_SYM_TYPE(right)) /* --> we would want its address instead of the first instruction */
+ && !IS_CODEPTR(OP_SYM_TYPE(right)) /* --> get symbols address instread */
+ && IN_CODESPACE (SPEC_OCLS (getSpec (OP_SYM_TYPE(right)))))
+ {
+ emitpComment ("genAssign from CODESPACE");
+ genConstPointerGet (right, result, ic);
+ goto release;
+ }
+
+ /* just for symmetry reasons... */
+ if (!IS_ITEMP(result)
+ && IS_SYMOP (result)
+ && IN_CODESPACE (SPEC_OCLS (getSpec (OP_SYM_TYPE(result)))))
+ {
+ assert ( !"cannot write to CODESPACE" );
+ }
+
+ /* if the result is a bit */
+ if (AOP_TYPE(result) == AOP_CRY) {
+
+ /* if the right size is a literal then
+ we know what the value is */
+ if (AOP_TYPE(right) == AOP_LIT) {
+
+ emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
+ popGet(AOP(result),0));
+
+ if (((int) operandLitValue(right)))
+ pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
+ AOP(result)->aopu.aop_dir,
+ AOP(result)->aopu.aop_dir);
+ else
+ pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
+ AOP(result)->aopu.aop_dir,
+ AOP(result)->aopu.aop_dir);
+ goto release;
+ }
+
+ /* the right is also a bit variable */
+ if (AOP_TYPE(right) == AOP_CRY) {
+ emitpcode(POC_BCF, popGet(AOP(result),0));
+ emitpcode(POC_BTFSC, popGet(AOP(right),0));
+ emitpcode(POC_BSF, popGet(AOP(result),0));
+
+ pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
+ AOP(result)->aopu.aop_dir,
+ AOP(result)->aopu.aop_dir);
+ pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
+ AOP(right)->aopu.aop_dir,
+ AOP(right)->aopu.aop_dir);
+ pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
+ AOP(result)->aopu.aop_dir,
+ AOP(result)->aopu.aop_dir);
+ goto release ;
+ }
+
+ /* we need to or */
+ emitpcode(POC_BCF, popGet(AOP(result),0));
+ pic14_toBoolean(right);
+ emitSKPZ;
+ emitpcode(POC_BSF, popGet(AOP(result),0));
+ //aopPut(AOP(result),"a",0);
+ goto release ;
+ }
+
+ /* bit variables done */
+ /* general case */
+ size = AOP_SIZE(result);
+ offset = 0 ;
+ if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ if(aopIdx(AOP(result),0) == 4) {
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ emitpcode(POC_MOVFW, popGet(AOP(right),offset));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offset));
+ goto release;
+ } else
+ DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
+ }
+
+ know_W=-1;
+ while (size--) {
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ if(AOP_TYPE(right) == AOP_LIT) {
+ lit = (unsigned long)pic14aopLiteral(AOP(right)->aopu.aop_lit, offset) & 0x0ff;
+ if(lit&0xff) {
+ if(know_W != (int)(lit&0xff))
+ emitpcode(POC_MOVLW,popGetLit(lit&0xff));
+ know_W = lit&0xff;
+ emitpcode(POC_MOVWF, popGet(AOP(result),offset));
+ } else
+ emitpcode(POC_CLRF, popGet(AOP(result),offset));
+
+ } else if (AOP_TYPE(right) == AOP_CRY) {
+ emitpcode(POC_CLRF, popGet(AOP(result),offset));
+ if(offset == 0) {
+ emitpcode(POC_BTFSS, popGet(AOP(right),0));
+ emitpcode(POC_INCF, popGet(AOP(result),0));
+ }
+ } else {
+ mov2w_op (right, offset);
+ emitpcode(POC_MOVWF, popGet(AOP(result),offset));
+ }
+
+ offset++;
+ }
+
+
release:
- freeAsmop (right,NULL,ic,FALSE);
- freeAsmop (result,NULL,ic,TRUE);
-}
+ freeAsmop (right,NULL,ic,FALSE);
+ freeAsmop (result,NULL,ic,TRUE);
+}
/*-----------------------------------------------------------------*/
/* genJumpTab - genrates code for jump table */
/*-----------------------------------------------------------------*/
static void genJumpTab (iCode *ic)
{
- symbol *jtab;
- char *l;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- aopOp(IC_JTCOND(ic),ic,FALSE);
- /* get the condition into accumulator */
- l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
- MOVA(l);
- /* multiply by three */
- pic14_emitcode("add","a,acc");
- pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
-
- jtab = newiTempLabel(NULL);
- pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
- pic14_emitcode("jmp","@a+dptr");
- pic14_emitcode("","%05d_DS_:",jtab->key+100);
-
- emitpcode(POC_MOVLW, popGetHighLabel(jtab->key));
- emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
- emitpcode(POC_MOVLW, popGetLabel(jtab->key));
- emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
- emitSKPNC;
- emitpcode(POC_INCF, popCopyReg(&pc_pclath));
- emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
- emitpLabel(jtab->key);
-
- freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
-
- /* now generate the jump labels */
- for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
- jtab = setNextItem(IC_JTLABELS(ic))) {
- pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
- emitpcode(POC_GOTO,popGetLabel(jtab->key));
-
- }
-
+ symbol *jtab;
+ char *l;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ aopOp(IC_JTCOND(ic),ic,FALSE);
+ /* get the condition into accumulator */
+ l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
+ MOVA(l);
+ /* multiply by three */
+ pic14_emitcode("add","a,acc");
+ pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
+
+ jtab = newiTempLabel(NULL);
+ pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
+ pic14_emitcode("jmp","@a+dptr");
+ pic14_emitcode("","%05d_DS_:",jtab->key+100);
+
+ emitpcode(POC_MOVLW, popGetHighLabel(jtab->key));
+ emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
+ emitpcode(POC_MOVLW, popGetLabel(jtab->key));
+ emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
+ emitSKPNC;
+ emitpcode(POC_INCF, popCopyReg(&pc_pclath));
+ emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
+ emitpLabel(jtab->key);
+
+ freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
+
+ /* now generate the jump labels */
+ for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
+ jtab = setNextItem(IC_JTLABELS(ic))) {
+ pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
+ emitpcode(POC_GOTO,popGetLabel(jtab->key));
+
+ }
+
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
/*
TSD - Written for the PIC port - but this unfortunately is buggy.
-This routine is good in that it is able to efficiently promote
+This routine is good in that it is able to efficiently promote
types to different (larger) sizes. Unfortunately, the temporary
variables that are optimized out by this routine are sometimes
-used in other places. So until I know how to really parse the
+used in other places. So until I know how to really parse the
iCode tree, I'm going to not be using this routine :(.
*/
static int genMixedOperation (iCode *ic)
{
- FENTRY;
+ FENTRY;
#if 0
- operand *result = IC_RESULT(ic);
- sym_link *ctype = operandType(IC_LEFT(ic));
- operand *right = IC_RIGHT(ic);
- int ret = 0;
- int big,small;
- int offset;
-
- iCode *nextic;
- operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
-
- pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
-
- nextic = ic->next;
- if(!nextic)
- return 0;
-
- nextright = IC_RIGHT(nextic);
- nextleft = IC_LEFT(nextic);
- nextresult = IC_RESULT(nextic);
-
- aopOp(right,ic,FALSE);
- aopOp(result,ic,FALSE);
- aopOp(nextright, nextic, FALSE);
- aopOp(nextleft, nextic, FALSE);
- aopOp(nextresult, nextic, FALSE);
-
- if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
-
- operand *t = right;
- right = nextright;
- nextright = t;
-
- pic14_emitcode(";remove right +","");
-
- } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
- /*
- operand *t = right;
- right = nextleft;
- nextleft = t;
- */
- pic14_emitcode(";remove left +","");
- } else
- return 0;
-
- big = AOP_SIZE(nextleft);
- small = AOP_SIZE(nextright);
-
- switch(nextic->op) {
-
- case '+':
- pic14_emitcode(";optimize a +","");
- /* if unsigned or not an integral type */
- if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
- pic14_emitcode(";add a bit to something","");
- } else {
-
- pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
-
- if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
- pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
- pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
- } else
- pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
-
- offset = 0;
- while(--big) {
-
- offset++;
-
- if(--small) {
- if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
- pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
- pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
- }
-
- pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
- emitSKPNC;
- pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
- AOP(IC_RIGHT(nextic))->aopu.aop_dir,
- AOP(IC_RIGHT(nextic))->aopu.aop_dir);
- pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
- pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
-
- } else {
- pic14_emitcode("rlf","known_zero,w");
-
- /*
- if right is signed
- btfsc right,7
- addlw ff
- */
- if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
- pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
- pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
- } else {
- pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
- }
- }
- }
- ret = 1;
- }
- }
- ret = 1;
-
+ operand *result = IC_RESULT(ic);
+ sym_link *ctype = operandType(IC_LEFT(ic));
+ operand *right = IC_RIGHT(ic);
+ int ret = 0;
+ int big,small;
+ int offset;
+
+ iCode *nextic;
+ operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
+
+ pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ nextic = ic->next;
+ if(!nextic)
+ return 0;
+
+ nextright = IC_RIGHT(nextic);
+ nextleft = IC_LEFT(nextic);
+ nextresult = IC_RESULT(nextic);
+
+ aopOp(right,ic,FALSE);
+ aopOp(result,ic,FALSE);
+ aopOp(nextright, nextic, FALSE);
+ aopOp(nextleft, nextic, FALSE);
+ aopOp(nextresult, nextic, FALSE);
+
+ if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
+
+ operand *t = right;
+ right = nextright;
+ nextright = t;
+
+ pic14_emitcode(";remove right +","");
+
+ } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
+ /*
+ operand *t = right;
+ right = nextleft;
+ nextleft = t;
+ */
+ pic14_emitcode(";remove left +","");
+ } else
+ return 0;
+
+ big = AOP_SIZE(nextleft);
+ small = AOP_SIZE(nextright);
+
+ switch(nextic->op) {
+
+ case '+':
+ pic14_emitcode(";optimize a +","");
+ /* if unsigned or not an integral type */
+ if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
+ pic14_emitcode(";add a bit to something","");
+ } else {
+
+ pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
+
+ if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
+ pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
+ pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
+ } else
+ pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
+
+ offset = 0;
+ while(--big) {
+
+ offset++;
+
+ if(--small) {
+ if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
+ pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
+ pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
+ }
+
+ pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
+ emitSKPNC;
+ pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
+ AOP(IC_RIGHT(nextic))->aopu.aop_dir,
+ AOP(IC_RIGHT(nextic))->aopu.aop_dir);
+ pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
+ pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
+
+ } else {
+ pic14_emitcode("rlf","known_zero,w");
+
+ /*
+ if right is signed
+ btfsc right,7
+ addlw ff
+ */
+ if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
+ pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
+ pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
+ } else {
+ pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
+ }
+ }
+ }
+ ret = 1;
+ }
+ }
+ ret = 1;
+
release:
- freeAsmop(right,NULL,ic,TRUE);
- freeAsmop(result,NULL,ic,TRUE);
- freeAsmop(nextright,NULL,ic,TRUE);
- freeAsmop(nextleft,NULL,ic,TRUE);
- if(ret)
- nextic->generated = 1;
-
- return ret;
+ freeAsmop(right,NULL,ic,TRUE);
+ freeAsmop(result,NULL,ic,TRUE);
+ freeAsmop(nextright,NULL,ic,TRUE);
+ freeAsmop(nextleft,NULL,ic,TRUE);
+ if(ret)
+ nextic->generated = 1;
+
+ return ret;
#else
- return 0;
+ return 0;
#endif
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static void genCast (iCode *ic)
{
- operand *result = IC_RESULT(ic);
- sym_link *restype = operandType(result);
- sym_link *rtype = operandType(IC_RIGHT(ic));
- operand *right = IC_RIGHT(ic);
- int size, offset ;
-
- FENTRY;
- DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
- /* if they are equivalent then do nothing */
- if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
- return ;
-
- aopOp(right,ic,FALSE) ;
- aopOp(result,ic,FALSE);
-
- DEBUGpic14_AopType(__LINE__,NULL,right,result);
-
- /* if the result is a bit */
- if (AOP_TYPE(result) == AOP_CRY) {
- assert(!"assigning to bit variables is not supported");
- }
-
- if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
- int offset = 1;
- size = AOP_SIZE(result);
-
- DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
-
- emitpcode(POC_CLRF, popGet(AOP(result),0));
- emitpcode(POC_BTFSC, popGet(AOP(right),0));
- emitpcode(POC_INCF, popGet(AOP(result),0));
-
- while (size--)
- emitpcode(POC_CLRF, popGet(AOP(result),offset++));
-
- goto release;
- }
-
- if (IS_PTR(restype))
- {
- operand *result = IC_RESULT(ic);
- //operand *left = IC_LEFT(ic);
- operand *right = IC_RIGHT(ic);
- int tag = 0xff;
-
- /* copy common part */
- int max, size = AOP_SIZE(result);
- if (size > AOP_SIZE(right)) size = AOP_SIZE(right);
- DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
-
- /* warn if we discard generic opinter tag */
- if (!IS_GENPTR(restype) && IS_GENPTR(rtype) && (AOP_SIZE(result) < AOP_SIZE(right)))
- {
- //fprintf (stderr, "%s:%u: discarding generic pointer type tag\n", __FUNCTION__, __LINE__);
- } // if
-
- max = size;
- while (size--)
- {
- mov2w_op (right, size);
- movwf (AOP(result), size);
- } // while
-
- /* upcast into generic pointer type? */
- if (IS_GENPTR(restype)
- && (size < AOP_SIZE(result))
- && (!IS_GENPTR(rtype) || AOP_SIZE(right) < GPTRSIZE))
- {
- //fprintf (stderr, "%s:%u: must determine pointer type\n", __FUNCTION__, __LINE__);
- if (IS_PTR(rtype))
- {
- switch (DCL_TYPE(rtype))
- {
- case POINTER: /* __data */
- case FPOINTER: /* __data */
- assert (AOP_SIZE(right) == 2);
- tag = GPTRTAG_DATA;
- break;
-
- case CPOINTER: /* __code */
- assert (AOP_SIZE(right) == 2);
- tag = GPTRTAG_CODE;
- break;
-
- case GPOINTER: /* unknown destination, __data or __code */
- /* assume __data space (address of immediate) */
- assert (AOP_TYPE(right) == AOP_PCODE && AOP(right)->aopu.pcop->type == PO_IMMEDIATE);
- if (AOP(right)->code)
- tag = GPTRTAG_CODE;
- else
- tag = GPTRTAG_DATA;
- break;
-
- default:
- assert (!"unhandled pointer type");
- } // switch
- } else {
- /* convert other values into pointers to __data space */
- tag = GPTRTAG_DATA;
- }
-
- assert (AOP_SIZE(result) == 3);
- if (tag == 0) {
- emitpcode(POC_CLRF, popGet(AOP(result), 2));
- } else {
- emitpcode(POC_MOVLW, popGetLit(tag));
- movwf(AOP(result), 2);
- }
- } else {
- addSign(result, max, 0);
- } // if
- goto release;
- }
-
- /* if they are the same size : or less */
- if (AOP_SIZE(result) <= AOP_SIZE(right)) {
-
- /* if they are in the same place */
- if (pic14_sameRegs(AOP(right),AOP(result)))
- goto release;
-
- DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
- if (IS_PTR_CONST(rtype))
- DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
- if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
- DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
-
- if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
- emitpcode(POC_MOVLW, popGetAddr(AOP(right),0,0));
- emitpcode(POC_MOVWF, popGet(AOP(result),0));
- emitpcode(POC_MOVLW, popGetAddr(AOP(right),1,0));
- emitpcode(POC_MOVWF, popGet(AOP(result),1));
- if(AOP_SIZE(result) <2)
- fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
-
- } else {
-
- /* if they in different places then copy */
- size = AOP_SIZE(result);
- offset = 0 ;
- while (size--) {
- emitpcode(POC_MOVFW, popGet(AOP(right),offset));
- emitpcode(POC_MOVWF, popGet(AOP(result),offset));
-
- //aopPut(AOP(result),
- // aopGet(AOP(right),offset,FALSE,FALSE),
- // offset);
-
- offset++;
- }
- }
- goto release;
- }
-
- /* so we now know that the size of destination is greater
- than the size of the source.
- Now, if the next iCode is an operator then we might be
- able to optimize the operation without performing a cast.
- */
- if(0 && genMixedOperation(ic)) {
- /* XXX: cannot optimize: must copy regs! */
- goto release;
- }
-
- /* we move to result for the size of source */
- size = AOP_SIZE(right);
- offset = 0 ;
- while (size--) {
- emitpcode(POC_MOVFW, popGet(AOP(right),offset));
- emitpcode(POC_MOVWF, popGet(AOP(result),offset));
- offset++;
- }
-
- addSign (result, AOP_SIZE(right), !SPEC_USIGN(rtype));
+ operand *result = IC_RESULT(ic);
+ sym_link *restype = operandType(result);
+ sym_link *rtype = operandType(IC_RIGHT(ic));
+ operand *right = IC_RIGHT(ic);
+ int size, offset ;
+
+ FENTRY;
+ DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* if they are equivalent then do nothing */
+ if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
+ return ;
+
+ aopOp(right,ic,FALSE) ;
+ aopOp(result,ic,FALSE);
+
+ DEBUGpic14_AopType(__LINE__,NULL,right,result);
+
+ /* if the result is a bit */
+ if (AOP_TYPE(result) == AOP_CRY) {
+ assert(!"assigning to bit variables is not supported");
+ }
+
+ if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
+ int offset = 1;
+ size = AOP_SIZE(result);
+
+ DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ emitpcode(POC_CLRF, popGet(AOP(result),0));
+ emitpcode(POC_BTFSC, popGet(AOP(right),0));
+ emitpcode(POC_INCF, popGet(AOP(result),0));
+
+ while (size--)
+ emitpcode(POC_CLRF, popGet(AOP(result),offset++));
+
+ goto release;
+ }
+
+ if (IS_PTR(restype))
+ {
+ operand *result = IC_RESULT(ic);
+ //operand *left = IC_LEFT(ic);
+ operand *right = IC_RIGHT(ic);
+ int tag = 0xff;
+
+ /* copy common part */
+ int max, size = AOP_SIZE(result);
+ if (size > AOP_SIZE(right)) size = AOP_SIZE(right);
+ DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ /* warn if we discard generic opinter tag */
+ if (!IS_GENPTR(restype) && IS_GENPTR(rtype) && (AOP_SIZE(result) < AOP_SIZE(right)))
+ {
+ //fprintf (stderr, "%s:%u: discarding generic pointer type tag\n", __FUNCTION__, __LINE__);
+ } // if
+
+ max = size;
+ while (size--)
+ {
+ mov2w_op (right, size);
+ movwf (AOP(result), size);
+ } // while
+
+ /* upcast into generic pointer type? */
+ if (IS_GENPTR(restype)
+ && (size < AOP_SIZE(result))
+ && (!IS_GENPTR(rtype) || AOP_SIZE(right) < GPTRSIZE))
+ {
+ //fprintf (stderr, "%s:%u: must determine pointer type\n", __FUNCTION__, __LINE__);
+ if (IS_PTR(rtype))
+ {
+ switch (DCL_TYPE(rtype))
+ {
+ case POINTER: /* __data */
+ case FPOINTER: /* __data */
+ assert (AOP_SIZE(right) == 2);
+ tag = GPTRTAG_DATA;
+ break;
+
+ case CPOINTER: /* __code */
+ assert (AOP_SIZE(right) == 2);
+ tag = GPTRTAG_CODE;
+ break;
+
+ case GPOINTER: /* unknown destination, __data or __code */
+ /* assume __data space (address of immediate) */
+ assert (AOP_TYPE(right) == AOP_PCODE && AOP(right)->aopu.pcop->type == PO_IMMEDIATE);
+ if (AOP(right)->code)
+ tag = GPTRTAG_CODE;
+ else
+ tag = GPTRTAG_DATA;
+ break;
+
+ default:
+ assert (!"unhandled pointer type");
+ } // switch
+ } else {
+ /* convert other values into pointers to __data space */
+ tag = GPTRTAG_DATA;
+ }
+
+ assert (AOP_SIZE(result) == 3);
+ if (tag == 0) {
+ emitpcode(POC_CLRF, popGet(AOP(result), 2));
+ } else {
+ emitpcode(POC_MOVLW, popGetLit(tag));
+ movwf(AOP(result), 2);
+ }
+ } else {
+ addSign(result, max, 0);
+ } // if
+ goto release;
+ }
+
+ /* if they are the same size : or less */
+ if (AOP_SIZE(result) <= AOP_SIZE(right)) {
+
+ /* if they are in the same place */
+ if (pic14_sameRegs(AOP(right),AOP(result)))
+ goto release;
+
+ DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
+ if (IS_PTR_CONST(rtype))
+ DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
+ if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
+ DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
+
+ if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
+ emitpcode(POC_MOVLW, popGetAddr(AOP(right),0,0));
+ emitpcode(POC_MOVWF, popGet(AOP(result),0));
+ emitpcode(POC_MOVLW, popGetAddr(AOP(right),1,0));
+ emitpcode(POC_MOVWF, popGet(AOP(result),1));
+ if(AOP_SIZE(result) <2)
+ fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
+
+ } else {
+
+ /* if they in different places then copy */
+ size = AOP_SIZE(result);
+ offset = 0 ;
+ while (size--) {
+ emitpcode(POC_MOVFW, popGet(AOP(right),offset));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offset));
+
+ //aopPut(AOP(result),
+ // aopGet(AOP(right),offset,FALSE,FALSE),
+ // offset);
+
+ offset++;
+ }
+ }
+ goto release;
+ }
+
+ /* so we now know that the size of destination is greater
+ than the size of the source.
+ Now, if the next iCode is an operator then we might be
+ able to optimize the operation without performing a cast.
+ */
+ if(0 && genMixedOperation(ic)) {
+ /* XXX: cannot optimize: must copy regs! */
+ goto release;
+ }
+
+ /* we move to result for the size of source */
+ size = AOP_SIZE(right);
+ offset = 0 ;
+ while (size--) {
+ emitpcode(POC_MOVFW, popGet(AOP(right),offset));
+ emitpcode(POC_MOVWF, popGet(AOP(result),offset));
+ offset++;
+ }
+
+ addSign (result, AOP_SIZE(right), !SPEC_USIGN(rtype));
release:
- freeAsmop(right,NULL,ic,TRUE);
- freeAsmop(result,NULL,ic,TRUE);
-
+ freeAsmop(right,NULL,ic,TRUE);
+ freeAsmop(result,NULL,ic,TRUE);
+
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static int genDjnz (iCode *ic, iCode *ifx)
{
- symbol *lbl, *lbl1;
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- if (!ifx)
- return 0;
-
- /* if the if condition has a false label
- then we cannot save */
- if (IC_FALSE(ifx))
- return 0;
-
- /* if the minus is not of the form
- a = a - 1 */
- if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
- !IS_OP_LITERAL(IC_RIGHT(ic)))
- return 0;
-
- if (operandLitValue(IC_RIGHT(ic)) != 1)
- return 0;
-
- /* if the size of this greater than one then no
- saving */
- if (getSize(operandType(IC_RESULT(ic))) > 1)
- return 0;
-
- /* otherwise we can save BIG */
- lbl = newiTempLabel(NULL);
- lbl1= newiTempLabel(NULL);
-
- aopOp(IC_RESULT(ic),ic,FALSE);
-
- if (IS_AOP_PREG(IC_RESULT(ic))) {
- pic14_emitcode("dec","%s",
- aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
- pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
- pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
- } else {
-
-
- emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
- emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
-
- pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
- pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
-
- }
- /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
- /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
- /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
- /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
-
-
- freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
- ifx->generated = 1;
- return 1;
+ symbol *lbl, *lbl1;
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ if (!ifx)
+ return 0;
+
+ /* if the if condition has a false label
+ then we cannot save */
+ if (IC_FALSE(ifx))
+ return 0;
+
+ /* if the minus is not of the form
+ a = a - 1 */
+ if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
+ !IS_OP_LITERAL(IC_RIGHT(ic)))
+ return 0;
+
+ if (operandLitValue(IC_RIGHT(ic)) != 1)
+ return 0;
+
+ /* if the size of this greater than one then no
+ saving */
+ if (getSize(operandType(IC_RESULT(ic))) > 1)
+ return 0;
+
+ /* otherwise we can save BIG */
+ lbl = newiTempLabel(NULL);
+ lbl1= newiTempLabel(NULL);
+
+ aopOp(IC_RESULT(ic),ic,FALSE);
+
+ if (IS_AOP_PREG(IC_RESULT(ic))) {
+ pic14_emitcode("dec","%s",
+ aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
+ pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
+ pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
+ } else {
+
+
+ emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
+ emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
+
+ pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
+ pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
+
+ }
+ /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
+ /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
+ /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
+ /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
+
+
+ freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
+ ifx->generated = 1;
+ return 1;
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static void genReceive (iCode *ic)
{
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- if (isOperandInFarSpace(IC_RESULT(ic)) &&
- ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
- IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
-
- int size = getSize(operandType(IC_RESULT(ic)));
- int offset = fReturnSizePic - size;
- while (size--) {
- pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
- fReturn[fReturnSizePic - offset - 1] : "acc"));
- offset++;
- }
- aopOp(IC_RESULT(ic),ic,FALSE);
- size = AOP_SIZE(IC_RESULT(ic));
- offset = 0;
- while (size--) {
- pic14_emitcode ("pop","acc");
- aopPut (AOP(IC_RESULT(ic)),"a",offset++);
- }
-
- } else {
- _G.accInUse++;
- aopOp(IC_RESULT(ic),ic,FALSE);
- _G.accInUse--;
- GpsuedoStkPtr = ic->parmBytes; // address used arg on stack
- assignResultValue(IC_RESULT(ic));
- }
-
- freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ if (isOperandInFarSpace(IC_RESULT(ic)) &&
+ ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
+ IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
+
+ int size = getSize(operandType(IC_RESULT(ic)));
+ int offset = fReturnSizePic - size;
+ while (size--) {
+ pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
+ fReturn[fReturnSizePic - offset - 1] : "acc"));
+ offset++;
+ }
+ aopOp(IC_RESULT(ic),ic,FALSE);
+ size = AOP_SIZE(IC_RESULT(ic));
+ offset = 0;
+ while (size--) {
+ pic14_emitcode ("pop","acc");
+ aopPut (AOP(IC_RESULT(ic)),"a",offset++);
+ }
+
+ } else {
+ _G.accInUse++;
+ aopOp(IC_RESULT(ic),ic,FALSE);
+ _G.accInUse--;
+ GpsuedoStkPtr = ic->parmBytes; // address used arg on stack
+ assignResultValue(IC_RESULT(ic));
+ }
+
+ freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
}
/*-----------------------------------------------------------------*/
static void
genDummyRead (iCode * ic)
{
- FENTRY;
- pic14_emitcode ("; genDummyRead","");
- pic14_emitcode ("; not implemented","");
-
- ic = ic;
+ FENTRY;
+ pic14_emitcode ("; genDummyRead","");
+ pic14_emitcode ("; not implemented","");
+
+ ic = ic;
}
/*-----------------------------------------------------------------*/
void genpic14Code (iCode *lic)
{
- iCode *ic;
- int cln = 0;
- const char *cline;
-
- FENTRY;
- lineHead = lineCurr = NULL;
-
- pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
- addpBlock(pb);
-
- /* if debug information required */
- if (options.debug && debugFile && currFunc) {
- debugFile->writeFunction (currFunc, lic);
- }
-
-
- for (ic = lic ; ic ; ic = ic->next ) {
-
- //DEBUGpic14_emitcode(";ic","");
- //fprintf (stderr, "in ic loop\n");
- //pic14_emitcode ("", ";\t%s:%d: %s", ic->filename,
- //ic->lineno, printCLine(ic->filename, ic->lineno));
-
- if (!options.noCcodeInAsm && (cln != ic->lineno)) {
- cln = ic->lineno;
- //fprintf (stderr, "%s\n", printCLine (ic->filename, ic->lineno));
- cline = printCLine (ic->filename, ic->lineno);
- if (!cline || strlen (cline) == 0) cline = printCLine (ic->filename, ic->lineno);
- addpCode2pBlock (pb, newpCodeCSource (ic->lineno, ic->filename, cline));
- //emitpComment ("[C-SRC] %s:%d: %s", ic->filename, cln, cline);
- }
-
- if (options.iCodeInAsm) {
+ iCode *ic;
+ int cln = 0;
+ const char *cline;
+
+ FENTRY;
+ lineHead = lineCurr = NULL;
+
+ pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
+ addpBlock(pb);
+
+ /* if debug information required */
+ if (options.debug && debugFile && currFunc) {
+ debugFile->writeFunction (currFunc, lic);
+ }
+
+
+ for (ic = lic ; ic ; ic = ic->next ) {
+
+ //DEBUGpic14_emitcode(";ic","");
+ //fprintf (stderr, "in ic loop\n");
+ //pic14_emitcode ("", ";\t%s:%d: %s", ic->filename,
+ //ic->lineno, printCLine(ic->filename, ic->lineno));
+
+ if (!options.noCcodeInAsm && (cln != ic->lineno)) {
+ cln = ic->lineno;
+ //fprintf (stderr, "%s\n", printCLine (ic->filename, ic->lineno));
+ cline = printCLine (ic->filename, ic->lineno);
+ if (!cline || strlen (cline) == 0) cline = printCLine (ic->filename, ic->lineno);
+ addpCode2pBlock (pb, newpCodeCSource (ic->lineno, ic->filename, cline));
+ //emitpComment ("[C-SRC] %s:%d: %s", ic->filename, cln, cline);
+ }
+
+ if (options.iCodeInAsm) {
char *iLine = printILine(ic);
- emitpComment ("[ICODE] %s:%d: %s", ic->filename, ic->lineno, printILine (ic));
+ emitpComment ("[ICODE] %s:%d: %s", ic->filename, ic->lineno, printILine (ic));
dbuf_free(iLine);
- }
- /* if the result is marked as
- spilt and rematerializable or code for
- this has already been generated then
- do nothing */
- if (resultRemat(ic) || ic->generated )
- continue ;
-
- /* depending on the operation */
- switch (ic->op) {
- case '!' :
- genNot(ic);
- break;
-
- case '~' :
- genCpl(ic);
- break;
-
- case UNARYMINUS:
- genUminus (ic);
- break;
-
- case IPUSH:
- genIpush (ic);
- break;
-
- case IPOP:
- /* IPOP happens only when trying to restore a
- spilt live range, if there is an ifx statement
- following this pop then the if statement might
- be using some of the registers being popped which
- would destory the contents of the register so
- we need to check for this condition and handle it */
- if (ic->next &&
- ic->next->op == IFX &&
- regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
- genIfx (ic->next,ic);
- else
- genIpop (ic);
- break;
-
- case CALL:
- genCall (ic);
- break;
-
- case PCALL:
- genPcall (ic);
- break;
-
- case FUNCTION:
- genFunction (ic);
- break;
-
- case ENDFUNCTION:
- genEndFunction (ic);
- break;
-
- case RETURN:
- genRet (ic);
- break;
-
- case LABEL:
- genLabel (ic);
- break;
-
- case GOTO:
- genGoto (ic);
- break;
-
- case '+' :
- genPlus (ic) ;
- break;
-
- case '-' :
- if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
- genMinus (ic);
- break;
-
- case '*' :
- genMult (ic);
- break;
-
- case '/' :
- genDiv (ic) ;
- break;
-
- case '%' :
- genMod (ic);
- break;
-
- case '>' :
- genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
- break;
-
- case '<' :
- genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
- break;
-
- case LE_OP:
- case GE_OP:
- case NE_OP:
-
- /* note these two are xlated by algebraic equivalence
- during parsing SDCC.y */
- werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
- "got '>=' or '<=' shouldn't have come here");
- break;
-
- case EQ_OP:
- genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
- break;
-
- case AND_OP:
- genAndOp (ic);
- break;
-
- case OR_OP:
- genOrOp (ic);
- break;
-
- case '^' :
- genXor (ic,ifxForOp(IC_RESULT(ic),ic));
- break;
-
- case '|' :
- genOr (ic,ifxForOp(IC_RESULT(ic),ic));
- break;
-
- case BITWISEAND:
- genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
- break;
-
- case INLINEASM:
- genInline (ic);
- break;
-
- case RRC:
- genRRC (ic);
- break;
-
- case RLC:
- genRLC (ic);
- break;
-
- case GETHBIT:
- genGetHbit (ic);
- break;
-
- case LEFT_OP:
- genLeftShift (ic);
- break;
-
- case RIGHT_OP:
- genRightShift (ic);
- break;
-
- case GET_VALUE_AT_ADDRESS:
- genPointerGet(ic);
- break;
-
- case '=' :
- if (POINTER_SET(ic))
- genPointerSet(ic);
- else
- genAssign(ic);
- break;
-
- case IFX:
- genIfx (ic,NULL);
- break;
-
- case ADDRESS_OF:
- genAddrOf (ic);
- break;
-
- case JUMPTABLE:
- genJumpTab (ic);
- break;
-
- case CAST:
- genCast (ic);
- break;
-
- case RECEIVE:
- genReceive(ic);
- break;
-
- case SEND:
- addSet(&_G.sendSet,ic);
- break;
-
- case DUMMY_READ_VOLATILE:
- genDummyRead (ic);
- break;
-
- default :
- fprintf(stderr, "UNHANDLED iCode: "); piCode(ic, stderr);
- ic = ic;
- break;
- }
- }
-
-
- /* now we are ready to call the
- peep hole optimizer */
- if (!options.nopeep) {
- peepHole (&lineHead);
- }
- /* now do the actual printing */
- printLine (lineHead,codeOutBuf);
-
+ }
+ /* if the result is marked as
+ spilt and rematerializable or code for
+ this has already been generated then
+ do nothing */
+ if (resultRemat(ic) || ic->generated )
+ continue ;
+
+ /* depending on the operation */
+ switch (ic->op) {
+ case '!' :
+ genNot(ic);
+ break;
+
+ case '~' :
+ genCpl(ic);
+ break;
+
+ case UNARYMINUS:
+ genUminus (ic);
+ break;
+
+ case IPUSH:
+ genIpush (ic);
+ break;
+
+ case IPOP:
+ /* IPOP happens only when trying to restore a
+ spilt live range, if there is an ifx statement
+ following this pop then the if statement might
+ be using some of the registers being popped which
+ would destory the contents of the register so
+ we need to check for this condition and handle it */
+ if (ic->next &&
+ ic->next->op == IFX &&
+ regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
+ genIfx (ic->next,ic);
+ else
+ genIpop (ic);
+ break;
+
+ case CALL:
+ genCall (ic);
+ break;
+
+ case PCALL:
+ genPcall (ic);
+ break;
+
+ case FUNCTION:
+ genFunction (ic);
+ break;
+
+ case ENDFUNCTION:
+ genEndFunction (ic);
+ break;
+
+ case RETURN:
+ genRet (ic);
+ break;
+
+ case LABEL:
+ genLabel (ic);
+ break;
+
+ case GOTO:
+ genGoto (ic);
+ break;
+
+ case '+' :
+ genPlus (ic) ;
+ break;
+
+ case '-' :
+ if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
+ genMinus (ic);
+ break;
+
+ case '*' :
+ genMult (ic);
+ break;
+
+ case '/' :
+ genDiv (ic) ;
+ break;
+
+ case '%' :
+ genMod (ic);
+ break;
+
+ case '>' :
+ genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
+ break;
+
+ case '<' :
+ genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
+ break;
+
+ case LE_OP:
+ case GE_OP:
+ case NE_OP:
+
+ /* note these two are xlated by algebraic equivalence
+ during parsing SDCC.y */
+ werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
+ "got '>=' or '<=' shouldn't have come here");
+ break;
+
+ case EQ_OP:
+ genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
+ break;
+
+ case AND_OP:
+ genAndOp (ic);
+ break;
+
+ case OR_OP:
+ genOrOp (ic);
+ break;
+
+ case '^' :
+ genXor (ic,ifxForOp(IC_RESULT(ic),ic));
+ break;
+
+ case '|' :
+ genOr (ic,ifxForOp(IC_RESULT(ic),ic));
+ break;
+
+ case BITWISEAND:
+ genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
+ break;
+
+ case INLINEASM:
+ genInline (ic);
+ break;
+
+ case RRC:
+ genRRC (ic);
+ break;
+
+ case RLC:
+ genRLC (ic);
+ break;
+
+ case GETHBIT:
+ genGetHbit (ic);
+ break;
+
+ case LEFT_OP:
+ genLeftShift (ic);
+ break;
+
+ case RIGHT_OP:
+ genRightShift (ic);
+ break;
+
+ case GET_VALUE_AT_ADDRESS:
+ genPointerGet(ic);
+ break;
+
+ case '=' :
+ if (POINTER_SET(ic))
+ genPointerSet(ic);
+ else
+ genAssign(ic);
+ break;
+
+ case IFX:
+ genIfx (ic,NULL);
+ break;
+
+ case ADDRESS_OF:
+ genAddrOf (ic);
+ break;
+
+ case JUMPTABLE:
+ genJumpTab (ic);
+ break;
+
+ case CAST:
+ genCast (ic);
+ break;
+
+ case RECEIVE:
+ genReceive(ic);
+ break;
+
+ case SEND:
+ addSet(&_G.sendSet,ic);
+ break;
+
+ case DUMMY_READ_VOLATILE:
+ genDummyRead (ic);
+ break;
+
+ default :
+ fprintf(stderr, "UNHANDLED iCode: "); piCode(ic, stderr);
+ ic = ic;
+ break;
+ }
+ }
+
+
+ /* now we are ready to call the
+ peep hole optimizer */
+ if (!options.nopeep) {
+ peepHole (&lineHead);
+ }
+ /* now do the actual printing */
+ printLine (lineHead,codeOutBuf);
+
#ifdef PCODE_DEBUG
- DFPRINTF((stderr,"printing pBlock\n\n"));
- printpBlock(stdout,pb);
+ DFPRINTF((stderr,"printing pBlock\n\n"));
+ printpBlock(stdout,pb);
#endif
-
- return;
+
+ return;
}
/* This is not safe, as a AOP_PCODE/PO_IMMEDIATE might be used both as literal
if (aop->type == AOP_LIT) return 1;
if (aop->type == AOP_IMMD) return 1;
if ((aop->type == AOP_PCODE) &&
- ((aop->aopu.pcop->type == PO_LITERAL)))
+ ((aop->aopu.pcop->type == PO_LITERAL)))
{
/* this should be treated like a literal/immediate (use MOVLW/ADDLW/SUBLW
* instead of MOVFW/ADDFW/SUBFW, use popGetAddr instead of popGet) */
const char *AopType(short type)
{
- switch(type) {
- case AOP_LIT:
- return "AOP_LIT";
- break;
- case AOP_REG:
- return "AOP_REG";
- break;
- case AOP_DIR:
- return "AOP_DIR";
- break;
- case AOP_DPTR:
- return "AOP_DPTR";
- break;
- case AOP_DPTR2:
- return "AOP_DPTR2";
- break;
- case AOP_R0:
- return "AOP_R0";
- break;
- case AOP_R1:
- return "AOP_R1";
- break;
- case AOP_STK:
- return "AOP_STK";
- break;
- case AOP_IMMD:
- return "AOP_IMMD";
- break;
- case AOP_STR:
- return "AOP_STR";
- break;
- case AOP_CRY:
- return "AOP_CRY";
- break;
- case AOP_ACC:
- return "AOP_ACC";
- break;
- case AOP_PCODE:
- return "AOP_PCODE";
- break;
- }
-
- return "BAD TYPE";
+ switch(type) {
+ case AOP_LIT:
+ return "AOP_LIT";
+ break;
+ case AOP_REG:
+ return "AOP_REG";
+ break;
+ case AOP_DIR:
+ return "AOP_DIR";
+ break;
+ case AOP_DPTR:
+ return "AOP_DPTR";
+ break;
+ case AOP_DPTR2:
+ return "AOP_DPTR2";
+ break;
+ case AOP_R0:
+ return "AOP_R0";
+ break;
+ case AOP_R1:
+ return "AOP_R1";
+ break;
+ case AOP_STK:
+ return "AOP_STK";
+ break;
+ case AOP_IMMD:
+ return "AOP_IMMD";
+ break;
+ case AOP_STR:
+ return "AOP_STR";
+ break;
+ case AOP_CRY:
+ return "AOP_CRY";
+ break;
+ case AOP_ACC:
+ return "AOP_ACC";
+ break;
+ case AOP_PCODE:
+ return "AOP_PCODE";
+ break;
+ }
+
+ return "BAD TYPE";
}
void DebugAop(asmop *aop)
{
- if(!aop)
- return;
- printf("%s\n",AopType(aop->type));
- printf(" current offset: %d\n",aop->coff);
- printf(" size: %d\n",aop->size);
-
- switch(aop->type) {
- case AOP_LIT:
- printf(" name: %s\n",aop->aopu.aop_lit->name);
- break;
- case AOP_REG:
- printf(" name: %s\n",aop->aopu.aop_reg[0]->name);
- break;
- case AOP_CRY:
- case AOP_DIR:
- printf(" name: %s\n",aop->aopu.aop_dir);
- break;
- case AOP_DPTR:
- case AOP_DPTR2:
- case AOP_R0:
- case AOP_R1:
- case AOP_ACC:
- printf("not supported\n");
- break;
- case AOP_STK:
- printf(" Stack offset: %d\n",aop->aopu.aop_stk);
- break;
- case AOP_IMMD:
- printf(" immediate: %s\n",aop->aopu.aop_immd);
- break;
- case AOP_STR:
- printf(" aop_str[0]: %s\n",aop->aopu.aop_str[0]);
- break;
- case AOP_PCODE:
- //printpCode(stdout,aop->aopu.pcop);
- break;
- }
+ if(!aop)
+ return;
+ printf("%s\n",AopType(aop->type));
+ printf(" current offset: %d\n",aop->coff);
+ printf(" size: %d\n",aop->size);
+
+ switch(aop->type) {
+ case AOP_LIT:
+ printf(" name: %s\n",aop->aopu.aop_lit->name);
+ break;
+ case AOP_REG:
+ printf(" name: %s\n",aop->aopu.aop_reg[0]->name);
+ break;
+ case AOP_CRY:
+ case AOP_DIR:
+ printf(" name: %s\n",aop->aopu.aop_dir);
+ break;
+ case AOP_DPTR:
+ case AOP_DPTR2:
+ case AOP_R0:
+ case AOP_R1:
+ case AOP_ACC:
+ printf("not supported\n");
+ break;
+ case AOP_STK:
+ printf(" Stack offset: %d\n",aop->aopu.aop_stk);
+ break;
+ case AOP_IMMD:
+ printf(" immediate: %s\n",aop->aopu.aop_immd);
+ break;
+ case AOP_STR:
+ printf(" aop_str[0]: %s\n",aop->aopu.aop_str[0]);
+ break;
+ case AOP_PCODE:
+ //printpCode(stdout,aop->aopu.pcop);
+ break;
+ }
}
const char *pCodeOpType( pCodeOp *pcop)
{
-
- if(pcop) {
-
- switch(pcop->type) {
-
- case PO_NONE:
- return "PO_NONE";
- case PO_W:
- return "PO_W";
- case PO_STATUS:
- return "PO_STATUS";
- case PO_FSR:
- return "PO_FSR";
- case PO_INDF:
- return "PO_INDF";
- case PO_INTCON:
- return "PO_INTCON";
- case PO_GPR_REGISTER:
- return "PO_GPR_REGISTER";
- case PO_GPR_POINTER:
- return "PO_GPR_POINTER";
- case PO_GPR_BIT:
- return "PO_GPR_BIT";
- case PO_GPR_TEMP:
- return "PO_GPR_TEMP";
- case PO_SFR_REGISTER:
- return "PO_SFR_REGISTER";
- case PO_PCL:
- return "PO_PCL";
- case PO_PCLATH:
- return "PO_PCLATH";
- case PO_LITERAL:
- return "PO_LITERAL";
- case PO_IMMEDIATE:
- return "PO_IMMEDIATE";
- case PO_DIR:
- return "PO_DIR";
- case PO_CRY:
- return "PO_CRY";
- case PO_BIT:
- return "PO_BIT";
- case PO_STR:
- return "PO_STR";
- case PO_LABEL:
- return "PO_LABEL";
- case PO_WILD:
- return "PO_WILD";
- }
- }
-
- return "BAD PO_TYPE";
+
+ if(pcop) {
+
+ switch(pcop->type) {
+
+ case PO_NONE:
+ return "PO_NONE";
+ case PO_W:
+ return "PO_W";
+ case PO_STATUS:
+ return "PO_STATUS";
+ case PO_FSR:
+ return "PO_FSR";
+ case PO_INDF:
+ return "PO_INDF";
+ case PO_INTCON:
+ return "PO_INTCON";
+ case PO_GPR_REGISTER:
+ return "PO_GPR_REGISTER";
+ case PO_GPR_POINTER:
+ return "PO_GPR_POINTER";
+ case PO_GPR_BIT:
+ return "PO_GPR_BIT";
+ case PO_GPR_TEMP:
+ return "PO_GPR_TEMP";
+ case PO_SFR_REGISTER:
+ return "PO_SFR_REGISTER";
+ case PO_PCL:
+ return "PO_PCL";
+ case PO_PCLATH:
+ return "PO_PCLATH";
+ case PO_LITERAL:
+ return "PO_LITERAL";
+ case PO_IMMEDIATE:
+ return "PO_IMMEDIATE";
+ case PO_DIR:
+ return "PO_DIR";
+ case PO_CRY:
+ return "PO_CRY";
+ case PO_BIT:
+ return "PO_BIT";
+ case PO_STR:
+ return "PO_STR";
+ case PO_LABEL:
+ return "PO_LABEL";
+ case PO_WILD:
+ return "PO_WILD";
+ }
+ }
+
+ return "BAD PO_TYPE";
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
bool genPlusIncr (iCode *ic)
{
- unsigned int icount ;
- unsigned int size = pic14_getDataSize(IC_RESULT(ic));
- FENTRY;
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
- AopType(AOP_TYPE(IC_RESULT(ic))),
- AopType(AOP_TYPE(IC_LEFT(ic))),
- AopType(AOP_TYPE(IC_RIGHT(ic))));
-
- /* will try to generate an increment */
- /* if the right side is not a literal
- we cannot */
- if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
- return FALSE ;
-
- DEBUGpic14_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
- /* if the literal value of the right hand side
- is greater than 1 then it is faster to add */
- if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
- return FALSE ;
-
- /* if increment 16 bits in register */
- if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
- (icount == 1)) {
-
- int offset = MSB16;
-
- emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),LSB));
- //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
-
- while(--size) {
- emitSKPNZ;
- emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++));
- //pic14_emitcode(" incf","%s,f",aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
- }
-
- return TRUE;
- }
-
- DEBUGpic14_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
- /* if left is in accumulator - probably a bit operation*/
- if( strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") &&
- (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
-
- emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
- pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
- AOP(IC_RESULT(ic))->aopu.aop_dir,
- AOP(IC_RESULT(ic))->aopu.aop_dir);
- if(icount)
- emitpcode(POC_XORLW,popGetLit(1));
- //pic14_emitcode("xorlw","1");
- else
- emitpcode(POC_ANDLW,popGetLit(1));
- //pic14_emitcode("andlw","1");
-
- emitSKPZ;
- emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
- pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
- AOP(IC_RESULT(ic))->aopu.aop_dir,
- AOP(IC_RESULT(ic))->aopu.aop_dir);
-
- return TRUE;
- }
-
-
-
- /* if the sizes are greater than 1 then we cannot */
- if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
- AOP_SIZE(IC_LEFT(ic)) > 1 )
- return FALSE ;
-
- /* If we are incrementing the same register by two: */
-
- if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
-
- while (icount--)
- emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
- //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
-
- return TRUE ;
- }
-
- DEBUGpic14_emitcode ("; ","couldn't increment ");
-
- return FALSE ;
+ unsigned int icount ;
+ unsigned int size = pic14_getDataSize(IC_RESULT(ic));
+ FENTRY;
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
+ AopType(AOP_TYPE(IC_RESULT(ic))),
+ AopType(AOP_TYPE(IC_LEFT(ic))),
+ AopType(AOP_TYPE(IC_RIGHT(ic))));
+
+ /* will try to generate an increment */
+ /* if the right side is not a literal
+ we cannot */
+ if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
+ return FALSE ;
+
+ DEBUGpic14_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
+ /* if the literal value of the right hand side
+ is greater than 1 then it is faster to add */
+ if ((icount = (unsigned int) ulFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
+ return FALSE ;
+
+ /* if increment 16 bits in register */
+ if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
+ (icount == 1)) {
+
+ int offset = MSB16;
+
+ emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),LSB));
+ //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
+
+ while(--size) {
+ emitSKPNZ;
+ emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++));
+ //pic14_emitcode(" incf","%s,f",aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
+ }
+
+ return TRUE;
+ }
+
+ DEBUGpic14_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
+ /* if left is in accumulator - probably a bit operation*/
+ if( strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") &&
+ (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
+
+ emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
+ pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
+ AOP(IC_RESULT(ic))->aopu.aop_dir,
+ AOP(IC_RESULT(ic))->aopu.aop_dir);
+ if(icount)
+ emitpcode(POC_XORLW,popGetLit(1));
+ //pic14_emitcode("xorlw","1");
+ else
+ emitpcode(POC_ANDLW,popGetLit(1));
+ //pic14_emitcode("andlw","1");
+
+ emitSKPZ;
+ emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
+ pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
+ AOP(IC_RESULT(ic))->aopu.aop_dir,
+ AOP(IC_RESULT(ic))->aopu.aop_dir);
+
+ return TRUE;
+ }
+
+
+
+ /* if the sizes are greater than 1 then we cannot */
+ if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
+ AOP_SIZE(IC_LEFT(ic)) > 1 )
+ return FALSE ;
+
+ /* If we are incrementing the same register by two: */
+
+ if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
+
+ while (icount--)
+ emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
+ //pic14_emitcode("incf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
+
+ return TRUE ;
+ }
+
+ DEBUGpic14_emitcode ("; ","couldn't increment ");
+
+ return FALSE ;
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
void pic14_outBitAcc(operand *result)
{
- symbol *tlbl = newiTempLabel(NULL);
- /* if the result is a bit */
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- if (AOP_TYPE(result) == AOP_CRY){
- aopPut(AOP(result),"a",0);
- }
- else {
- pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
- pic14_emitcode("mov","a,#01");
- pic14_emitcode("","%05d_DS_:",tlbl->key+100);
- pic14_outAcc(result);
- }
+ symbol *tlbl = newiTempLabel(NULL);
+ /* if the result is a bit */
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ if (AOP_TYPE(result) == AOP_CRY){
+ aopPut(AOP(result),"a",0);
+ }
+ else {
+ pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
+ pic14_emitcode("mov","a,#01");
+ pic14_emitcode("","%05d_DS_:",tlbl->key+100);
+ pic14_outAcc(result);
+ }
}
#if 0
*/
static void adjustArithmeticResult(iCode *ic)
{
- if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
- AOP_SIZE(IC_LEFT(ic)) == 3 &&
- !pic14_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 &&
- !pic14_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 &&
- !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
- !pic14_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);
- }
+ if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
+ AOP_SIZE(IC_LEFT(ic)) == 3 &&
+ !pic14_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 &&
+ !pic14_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 &&
+ !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
+ !pic14_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.
*/
static void adjustArithmeticResult(iCode *ic)
{
- if (opIsGptr(IC_RESULT(ic)) &&
- opIsGptr(IC_LEFT(ic)) &&
- !pic14_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)) &&
- !pic14_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 &&
- !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
- !pic14_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);
- }
+ if (opIsGptr(IC_RESULT(ic)) &&
+ opIsGptr(IC_LEFT(ic)) &&
+ !pic14_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)) &&
+ !pic14_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 &&
+ !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
+ !pic14_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
/*-----------------------------------------------------------------*/
static void genAddLit2byte (operand *result, int offr, int lit)
{
- FENTRY;
-
- switch(lit & 0xff) {
- case 0:
- break;
- case 1:
- emitpcode(POC_INCF, popGet(AOP(result),offr));
- break;
- case 0xff:
- emitpcode(POC_DECF, popGet(AOP(result),offr));
- break;
- default:
- emitpcode(POC_MOVLW,popGetLit(lit&0xff));
- emitpcode(POC_ADDWF,popGet(AOP(result),offr));
- }
-
+ FENTRY;
+
+ switch(lit & 0xff) {
+ case 0:
+ break;
+ case 1:
+ emitpcode(POC_INCF, popGet(AOP(result),offr));
+ break;
+ case 0xff:
+ emitpcode(POC_DECF, popGet(AOP(result),offr));
+ break;
+ default:
+ emitpcode(POC_MOVLW,popGetLit(lit&0xff));
+ emitpcode(POC_ADDWF,popGet(AOP(result),offr));
+ }
+
}
static void emitMOVWF(operand *reg, int offset)
{
- FENTRY;
- if(!reg)
- return;
-
- if (AOP_TYPE(reg) == AOP_ACC) {
- DEBUGpic14_emitcode ("; ***","%s %d ignoring mov into W",__FUNCTION__,__LINE__);
- return;
- }
-
- emitpcode(POC_MOVWF, popGet(AOP(reg),offset));
-
+ FENTRY;
+ if(!reg)
+ return;
+
+ if (AOP_TYPE(reg) == AOP_ACC) {
+ DEBUGpic14_emitcode ("; ***","%s %d ignoring mov into W",__FUNCTION__,__LINE__);
+ return;
+ }
+
+ emitpcode(POC_MOVWF, popGet(AOP(reg),offset));
+
}
static void genAddLit (iCode *ic, int lit)
{
-
- int size,same;
- int lo;
-
- operand *result;
- operand *left;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
-
- left = IC_LEFT(ic);
- result = IC_RESULT(ic);
- same = pic14_sameRegs(AOP(left), AOP(result));
- size = pic14_getDataSize(result);
- if (size > pic14_getDataSize(left))
- size = pic14_getDataSize(left);
-
- if(same) {
-
- /* Handle special cases first */
- if(size == 1)
- genAddLit2byte (result, 0, lit);
-
- else if(size == 2) {
- int hi = 0xff & (lit >> 8);
- lo = lit & 0xff;
-
- switch(hi) {
- case 0:
-
- /* lit = 0x00LL */
- DEBUGpic14_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
- switch(lo) {
- case 0:
- break;
- case 1:
- emitpcode(POC_INCF, popGet(AOP(result),0));
- emitSKPNZ;
- emitpcode(POC_INCF, popGet(AOP(result),MSB16));
- break;
- case 0xff:
- emitpcode(POC_DECF, popGet(AOP(result),0));
- emitpcode(POC_INCFSZW, popGet(AOP(result),0));
- emitpcode(POC_INCF, popGet(AOP(result),MSB16));
-
- break;
- default:
- emitpcode(POC_MOVLW,popGetLit(lit&0xff));
- emitpcode(POC_ADDWF,popGet(AOP(result),0));
- emitSKPNC;
- emitpcode(POC_INCF, popGet(AOP(result),MSB16));
-
-
- }
- break;
-
- case 1:
- /* lit = 0x01LL */
- DEBUGpic14_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
- switch(lo) {
- case 0: /* 0x0100 */
- emitpcode(POC_INCF, popGet(AOP(result),MSB16));
- break;
- case 1: /* 0x0101 */
- emitpcode(POC_INCF, popGet(AOP(result),MSB16));
- emitpcode(POC_INCF, popGet(AOP(result),0));
- emitSKPNZ;
- emitpcode(POC_INCF, popGet(AOP(result),MSB16));
- break;
- case 0xff: /* 0x01ff */
- emitpcode(POC_DECF, popGet(AOP(result),0));
- emitpcode(POC_INCFSZW, popGet(AOP(result),0));
- emitpcode(POC_INCF, popGet(AOP(result),MSB16));
- emitpcode(POC_INCF, popGet(AOP(result),MSB16));
- }
- break;
-
- case 0xff:
- DEBUGpic14_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
- /* lit = 0xffLL */
- switch(lo) {
- case 0: /* 0xff00 */
- emitpcode(POC_DECF, popGet(AOP(result),MSB16));
- break;
- case 1: /*0xff01 */
- emitpcode(POC_INCFSZ, popGet(AOP(result),0));
- emitpcode(POC_DECF, popGet(AOP(result),MSB16));
- break;
- /* case 0xff: * 0xffff *
- emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE));
- emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
- emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE));
- break;
- */
- default:
- emitpcode(POC_MOVLW,popGetLit(lo));
- emitpcode(POC_ADDWF,popGet(AOP(result),0));
- emitSKPC;
- emitpcode(POC_DECF, popGet(AOP(result),MSB16));
-
- }
-
- break;
-
- default:
- DEBUGpic14_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
-
- /* lit = 0xHHLL */
- switch(lo) {
- case 0: /* 0xHH00 */
- genAddLit2byte (result, MSB16, hi);
- break;
- case 1: /* 0xHH01 */
- emitpcode(POC_MOVLW,popGetLit((hi+1)&0xff));
- emitpcode(POC_INCFSZ, popGet(AOP(result),0));
- emitpcode(POC_MOVLW,popGetLit(hi));
- emitpcode(POC_ADDWF,popGet(AOP(result),MSB16));
- break;
- /* case 0xff: * 0xHHff *
- emitpcode(POC_MOVFW, popGet(AOP(result),0,FALSE,FALSE));
- emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
- emitpcode(POC_MOVLW,popGetLit(hi));
- emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE));
- break;
- */ default: /* 0xHHLL */
- emitpcode(POC_MOVLW,popGetLit(lo));
- emitpcode(POC_ADDWF, popGet(AOP(result),0));
- emitpcode(POC_MOVLW,popGetLit(hi));
- emitSKPNC;
- emitpcode(POC_MOVLW,popGetLit((hi+1) & 0xff));
- emitpcode(POC_ADDWF,popGet(AOP(result),MSB16));
- break;
- }
-
- }
- } else {
- int carry_info = 0;
- int offset = 0;
- /* size > 2 */
- DEBUGpic14_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
-
- while(size--) {
- lo = BYTEofLONG(lit,0);
-
- if(carry_info) {
- switch(lo) {
- case 0:
- switch(carry_info) {
- case 1:
- emitSKPNZ;
- emitpcode(POC_INCF, popGet(AOP(result),offset));
- break;
- case 2:
- emitpcode(POC_RLFW, popGet(AOP(result),offset));
- emitpcode(POC_ANDLW,popGetLit(1));
- emitpcode(POC_ADDWF, popGet(AOP(result),offset));
- break;
- default: /* carry_info = 3 */
- emitSKPNC;
- emitpcode(POC_INCF, popGet(AOP(result),offset));
- carry_info = 1;
- break;
- }
- break;
- case 0xff:
- emitpcode(POC_MOVLW,popGetLit(lo));
- if(carry_info==1)
- emitSKPZ;
- else
- emitSKPC;
- emitpcode(POC_ADDWF, popGet(AOP(result),offset));
- break;
- default:
- emitpcode(POC_MOVLW,popGetLit(lo));
- if(carry_info==1)
- emitSKPNZ;
- else
- emitSKPNC;
- emitpcode(POC_MOVLW,popGetLit(lo+1));
- emitpcode(POC_ADDWF, popGet(AOP(result),offset));
- carry_info=2;
- break;
- }
- }else {
- /* no carry info from previous step */
- /* this means this is the first time to add */
- switch(lo) {
- case 0:
- break;
- case 1:
- emitpcode(POC_INCF, popGet(AOP(result),offset));
- carry_info=1;
- break;
- default:
- emitpcode(POC_MOVLW,popGetLit(lo));
- emitpcode(POC_ADDWF, popGet(AOP(result),offset));
- if(lit <0x100)
- carry_info = 3; /* Were adding only one byte and propogating the carry */
- else
- carry_info = 2;
- break;
- }
- }
- offset++;
- lit >>= 8;
- }
-
- /*
- lo = BYTEofLONG(lit,0);
-
- if(lit < 0x100) {
- if(lo) {
- if(lo == 1) {
- emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
- emitSKPNZ;
- } else {
- emitpcode(POC_MOVLW,popGetLit(lo));
- emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
- emitSKPNC;
- }
- emitpcode(POC_INCF, popGet(AOP(result),1,FALSE,FALSE));
- emitSKPNZ;
- emitpcode(POC_INCF, popGet(AOP(result),2,FALSE,FALSE));
- emitSKPNZ;
- emitpcode(POC_INCF, popGet(AOP(result),3,FALSE,FALSE));
-
- }
- }
-
- */
- }
- } else {
- int offset = 1;
- DEBUGpic14_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
-
- if(size == 1) {
-
- if(AOP_TYPE(left) == AOP_ACC) {
- /* left addend is already in accumulator */
- switch(lit & 0xff) {
- case 0:
- //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
- emitMOVWF(result,0);
- break;
- default:
- emitpcode(POC_ADDLW, popGetLit(lit & 0xff));
- //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
- emitMOVWF(result,0);
- }
- } else {
- /* left addend is in a register */
- switch(lit & 0xff) {
- case 0:
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitMOVWF(result, 0);
- //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
- emitMOVWF(result,0);
- break;
- case 1:
- emitpcode(POC_INCFW, popGet(AOP(left),0));
- //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
- emitMOVWF(result,0);
- break;
- case 0xff:
- emitpcode(POC_DECFW, popGet(AOP(left),0));
- //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
- emitMOVWF(result,0);
- break;
- default:
- emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
- emitpcode(POC_ADDFW, popGet(AOP(left),0));
- //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
- emitMOVWF(result,0);
- }
- }
-
- } else {
- int clear_carry=0;
-
- /* left is not the accumulator */
- if(lit & 0xff) {
- emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
- emitpcode(POC_ADDFW, popGet(AOP(left),0));
- } else {
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- /* We don't know the state of the carry bit at this point */
- clear_carry = 1;
- }
- //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
- emitMOVWF(result,0);
- while(--size) {
-
- lit >>= 8;
- if(lit & 0xff) {
- if(clear_carry) {
- /* The ls byte of the lit must've been zero - that
- means we don't have to deal with carry */
-
- emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
- emitpcode(POC_ADDFW, popGet(AOP(left),offset));
- emitpcode(POC_MOVWF, popGet(AOP(left),offset));
-
- clear_carry = 0;
-
- } else {
- emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
- //emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
- emitMOVWF(result,offset);
- emitpcode(POC_MOVFW, popGet(AOP(left),offset));
- emitSKPNC;
- emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
- emitpcode(POC_ADDWF, popGet(AOP(result),offset));
- }
-
- } else {
- emitpcode(POC_CLRF, popGet(AOP(result),offset));
- emitpcode(POC_RLF, popGet(AOP(result),offset));
- emitpcode(POC_MOVFW, popGet(AOP(left),offset));
- emitpcode(POC_ADDWF, popGet(AOP(result),offset));
- }
- offset++;
- }
- }
- }
+
+ int size,same;
+ int lo;
+
+ operand *result;
+ operand *left;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+
+ left = IC_LEFT(ic);
+ result = IC_RESULT(ic);
+ same = pic14_sameRegs(AOP(left), AOP(result));
+ size = pic14_getDataSize(result);
+ if (size > pic14_getDataSize(left))
+ size = pic14_getDataSize(left);
+
+ if(same) {
+
+ /* Handle special cases first */
+ if(size == 1)
+ genAddLit2byte (result, 0, lit);
+
+ else if(size == 2) {
+ int hi = 0xff & (lit >> 8);
+ lo = lit & 0xff;
+
+ switch(hi) {
+ case 0:
+
+ /* lit = 0x00LL */
+ DEBUGpic14_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
+ switch(lo) {
+ case 0:
+ break;
+ case 1:
+ emitpcode(POC_INCF, popGet(AOP(result),0));
+ emitSKPNZ;
+ emitpcode(POC_INCF, popGet(AOP(result),MSB16));
+ break;
+ case 0xff:
+ emitpcode(POC_DECF, popGet(AOP(result),0));
+ emitpcode(POC_INCFSZW, popGet(AOP(result),0));
+ emitpcode(POC_INCF, popGet(AOP(result),MSB16));
+
+ break;
+ default:
+ emitpcode(POC_MOVLW,popGetLit(lit&0xff));
+ emitpcode(POC_ADDWF,popGet(AOP(result),0));
+ emitSKPNC;
+ emitpcode(POC_INCF, popGet(AOP(result),MSB16));
+
+
+ }
+ break;
+
+ case 1:
+ /* lit = 0x01LL */
+ DEBUGpic14_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
+ switch(lo) {
+ case 0: /* 0x0100 */
+ emitpcode(POC_INCF, popGet(AOP(result),MSB16));
+ break;
+ case 1: /* 0x0101 */
+ emitpcode(POC_INCF, popGet(AOP(result),MSB16));
+ emitpcode(POC_INCF, popGet(AOP(result),0));
+ emitSKPNZ;
+ emitpcode(POC_INCF, popGet(AOP(result),MSB16));
+ break;
+ case 0xff: /* 0x01ff */
+ emitpcode(POC_DECF, popGet(AOP(result),0));
+ emitpcode(POC_INCFSZW, popGet(AOP(result),0));
+ emitpcode(POC_INCF, popGet(AOP(result),MSB16));
+ emitpcode(POC_INCF, popGet(AOP(result),MSB16));
+ }
+ break;
+
+ case 0xff:
+ DEBUGpic14_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
+ /* lit = 0xffLL */
+ switch(lo) {
+ case 0: /* 0xff00 */
+ emitpcode(POC_DECF, popGet(AOP(result),MSB16));
+ break;
+ case 1: /*0xff01 */
+ emitpcode(POC_INCFSZ, popGet(AOP(result),0));
+ emitpcode(POC_DECF, popGet(AOP(result),MSB16));
+ break;
+ /* case 0xff: * 0xffff *
+ emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE));
+ emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE));
+ emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE));
+ break;
+ */
+ default:
+ emitpcode(POC_MOVLW,popGetLit(lo));
+ emitpcode(POC_ADDWF,popGet(AOP(result),0));
+ emitSKPC;
+ emitpcode(POC_DECF, popGet(AOP(result),MSB16));
+
+ }
+
+ break;
+
+ default:
+ DEBUGpic14_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
+
+ /* lit = 0xHHLL */
+ switch(lo) {
+ case 0: /* 0xHH00 */
+ genAddLit2byte (result, MSB16, hi);
+ break;
+ case 1: /* 0xHH01 */
+ emitpcode(POC_MOVLW,popGetLit((hi+1)&0xff));
+ emitpcode(POC_INCFSZ, popGet(AOP(result),0));
+ emitpcode(POC_MOVLW,popGetLit(hi));
+ emitpcode(POC_ADDWF,popGet(AOP(result),MSB16));
+ break;
+ /* case 0xff: * 0xHHff *
+ emitpcode(POC_MOVFW, popGet(AOP(result),0,FALSE,FALSE));
+ emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE));
+ emitpcode(POC_MOVLW,popGetLit(hi));
+ emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE));
+ break;
+ */ default: /* 0xHHLL */
+ emitpcode(POC_MOVLW,popGetLit(lo));
+ emitpcode(POC_ADDWF, popGet(AOP(result),0));
+ emitpcode(POC_MOVLW,popGetLit(hi));
+ emitSKPNC;
+ emitpcode(POC_MOVLW,popGetLit((hi+1) & 0xff));
+ emitpcode(POC_ADDWF,popGet(AOP(result),MSB16));
+ break;
+ }
+
+ }
+ } else {
+ int carry_info = 0;
+ int offset = 0;
+ /* size > 2 */
+ DEBUGpic14_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
+
+ while(size--) {
+ lo = BYTEofLONG(lit,0);
+
+ if(carry_info) {
+ switch(lo) {
+ case 0:
+ switch(carry_info) {
+ case 1:
+ emitSKPNZ;
+ emitpcode(POC_INCF, popGet(AOP(result),offset));
+ break;
+ case 2:
+ emitpcode(POC_RLFW, popGet(AOP(result),offset));
+ emitpcode(POC_ANDLW,popGetLit(1));
+ emitpcode(POC_ADDWF, popGet(AOP(result),offset));
+ break;
+ default: /* carry_info = 3 */
+ emitSKPNC;
+ emitpcode(POC_INCF, popGet(AOP(result),offset));
+ carry_info = 1;
+ break;
+ }
+ break;
+ case 0xff:
+ emitpcode(POC_MOVLW,popGetLit(lo));
+ if(carry_info==1)
+ emitSKPZ;
+ else
+ emitSKPC;
+ emitpcode(POC_ADDWF, popGet(AOP(result),offset));
+ break;
+ default:
+ emitpcode(POC_MOVLW,popGetLit(lo));
+ if(carry_info==1)
+ emitSKPNZ;
+ else
+ emitSKPNC;
+ emitpcode(POC_MOVLW,popGetLit(lo+1));
+ emitpcode(POC_ADDWF, popGet(AOP(result),offset));
+ carry_info=2;
+ break;
+ }
+ }else {
+ /* no carry info from previous step */
+ /* this means this is the first time to add */
+ switch(lo) {
+ case 0:
+ break;
+ case 1:
+ emitpcode(POC_INCF, popGet(AOP(result),offset));
+ carry_info=1;
+ break;
+ default:
+ emitpcode(POC_MOVLW,popGetLit(lo));
+ emitpcode(POC_ADDWF, popGet(AOP(result),offset));
+ if(lit <0x100)
+ carry_info = 3; /* Were adding only one byte and propogating the carry */
+ else
+ carry_info = 2;
+ break;
+ }
+ }
+ offset++;
+ lit >>= 8;
+ }
+
+ /*
+ lo = BYTEofLONG(lit,0);
+
+ if(lit < 0x100) {
+ if(lo) {
+ if(lo == 1) {
+ emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE));
+ emitSKPNZ;
+ } else {
+ emitpcode(POC_MOVLW,popGetLit(lo));
+ emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE));
+ emitSKPNC;
+ }
+ emitpcode(POC_INCF, popGet(AOP(result),1,FALSE,FALSE));
+ emitSKPNZ;
+ emitpcode(POC_INCF, popGet(AOP(result),2,FALSE,FALSE));
+ emitSKPNZ;
+ emitpcode(POC_INCF, popGet(AOP(result),3,FALSE,FALSE));
+
+ }
+ }
+
+ */
+ }
+ } else {
+ int offset = 1;
+ DEBUGpic14_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__);
+
+ if(size == 1) {
+
+ if(AOP_TYPE(left) == AOP_ACC) {
+ /* left addend is already in accumulator */
+ switch(lit & 0xff) {
+ case 0:
+ //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
+ emitMOVWF(result,0);
+ break;
+ default:
+ emitpcode(POC_ADDLW, popGetLit(lit & 0xff));
+ //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
+ emitMOVWF(result,0);
+ }
+ } else {
+ /* left addend is in a register */
+ switch(lit & 0xff) {
+ case 0:
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ emitMOVWF(result, 0);
+ //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
+ emitMOVWF(result,0);
+ break;
+ case 1:
+ emitpcode(POC_INCFW, popGet(AOP(left),0));
+ //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
+ emitMOVWF(result,0);
+ break;
+ case 0xff:
+ emitpcode(POC_DECFW, popGet(AOP(left),0));
+ //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
+ emitMOVWF(result,0);
+ break;
+ default:
+ emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
+ emitpcode(POC_ADDFW, popGet(AOP(left),0));
+ //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
+ emitMOVWF(result,0);
+ }
+ }
+
+ } else {
+ int clear_carry=0;
+
+ /* left is not the accumulator */
+ if(lit & 0xff) {
+ emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
+ emitpcode(POC_ADDFW, popGet(AOP(left),0));
+ } else {
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ /* We don't know the state of the carry bit at this point */
+ clear_carry = 1;
+ }
+ //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE));
+ emitMOVWF(result,0);
+ while(--size) {
+
+ lit >>= 8;
+ if(lit & 0xff) {
+ if(clear_carry) {
+ /* The ls byte of the lit must've been zero - that
+ means we don't have to deal with carry */
+
+ emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
+ emitpcode(POC_ADDFW, popGet(AOP(left),offset));
+ emitpcode(POC_MOVWF, popGet(AOP(left),offset));
+
+ clear_carry = 0;
+
+ } else {
+ emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
+ //emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE));
+ emitMOVWF(result,offset);
+ emitpcode(POC_MOVFW, popGet(AOP(left),offset));
+ emitSKPNC;
+ emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
+ emitpcode(POC_ADDWF, popGet(AOP(result),offset));
+ }
+
+ } else {
+ emitpcode(POC_CLRF, popGet(AOP(result),offset));
+ emitpcode(POC_RLF, popGet(AOP(result),offset));
+ emitpcode(POC_MOVFW, popGet(AOP(left),offset));
+ emitpcode(POC_ADDWF, popGet(AOP(result),offset));
+ }
+ offset++;
+ }
+ }
+ }
- size = pic14_getDataSize(result);
- if (size > pic14_getDataSize(left))
- size = pic14_getDataSize(left);
- addSign(result, size, 0);
+ size = pic14_getDataSize(result);
+ if (size > pic14_getDataSize(left))
+ size = pic14_getDataSize(left);
+ addSign(result, size, 0);
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
void genPlus (iCode *ic)
{
- int size, offset = 0;
-
- /* special cases :- */
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- FENTRY;
-
- aopOp (IC_LEFT(ic),ic,FALSE);
- aopOp (IC_RIGHT(ic),ic,FALSE);
- aopOp (IC_RESULT(ic),ic,TRUE);
-
- DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),IC_RIGHT(ic),IC_RESULT(ic));
-
- /* if literal, literal on the right or
- if left requires ACC or right is already
- in ACC */
-
- if (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) {
- operand *t = IC_RIGHT(ic);
- IC_RIGHT(ic) = IC_LEFT(ic);
- IC_LEFT(ic) = t;
- }
-
- /* if left in bit space & right literal */
- if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
- AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
- /* if result in bit space */
- if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
- if((unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit) != 0L) {
- emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0));
- if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
- emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
- emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
- }
- } else {
- size = pic14_getDataSize(IC_RESULT(ic));
- while (size--) {
- MOVA(aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
- pic14_emitcode("addc","a,#00 ;%d",__LINE__);
- aopPut(AOP(IC_RESULT(ic)),"a",offset++);
- }
- }
- goto release ;
- }
-
- /* if I can do an increment instead
- of add then GOOD for ME */
- if (genPlusIncr (ic) == TRUE)
- goto release;
-
- size = pic14_getDataSize(IC_RESULT(ic));
-
- if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
- /* Add a literal to something else */
- //bool know_W=0;
- unsigned lit = (unsigned) floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
- // unsigned l1=0;
-
- // offset = 0;
- DEBUGpic14_emitcode(";","adding lit to something. size %d",size);
-
- genAddLit (ic, lit);
- goto release;
-
- } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
-
- pic14_emitcode(";bitadd","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
- pic14_emitcode(";bitadd","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
- pic14_emitcode(";bitadd","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
-
- /* here we are adding a bit to a char or int */
- if(size == 1) {
- if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
-
- emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
- emitpcode(POC_INCF , popGet(AOP(IC_RESULT(ic)),0));
-
- pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
- AOP(IC_RIGHT(ic))->aopu.aop_dir,
- AOP(IC_RIGHT(ic))->aopu.aop_dir);
- pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
- } else {
-
- if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
- emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
- emitpcode(POC_XORLW , popGetLit(1));
-
- pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
- AOP(IC_RIGHT(ic))->aopu.aop_dir,
- AOP(IC_RIGHT(ic))->aopu.aop_dir);
- pic14_emitcode(" xorlw","1");
- } else {
- emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
- emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
- emitpcode(POC_INCFW , popGet(AOP(IC_LEFT(ic)),0));
-
- pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
- pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
- AOP(IC_RIGHT(ic))->aopu.aop_dir,
- AOP(IC_RIGHT(ic))->aopu.aop_dir);
- pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
- }
-
- if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
-
- if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
- emitpcode(POC_ANDLW , popGetLit(1));
- emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
- emitSKPZ;
- emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
- } else {
- emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
- pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
- }
- }
- }
-
- } else {
- int offset = 1;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
- emitCLRZ;
- emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
- emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
-
- pic14_emitcode("clrz","");
-
- pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
- AOP(IC_RIGHT(ic))->aopu.aop_dir,
- AOP(IC_RIGHT(ic))->aopu.aop_dir);
- pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
-
- } else {
-
- emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),0));
- emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
- emitpcode(POC_INCFW, popGet(AOP(IC_LEFT(ic)),0));
- //emitpcode(POC_MOVWF, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
- emitMOVWF(IC_RIGHT(ic),0);
-
- pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
- pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
- AOP(IC_RIGHT(ic))->aopu.aop_dir,
- AOP(IC_RIGHT(ic))->aopu.aop_dir);
- pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
- pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
-
- }
-
- while(--size){
- emitSKPZ;
- emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++));
- //pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
- }
-
- }
-
- } else {
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- /* Add the first bytes */
-
- if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
- emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
- emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
- } else {
-
- if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
- emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
- if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
- emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
- } else {
-
- emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
-
- if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
- emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
- else {
- PIC_OPCODE poc = POC_ADDFW;
-
- if (op_isLitLike (IC_LEFT (ic)))
- poc = POC_ADDLW;
- emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),0,0));
- if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
- emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
- }
- }
- }
-
- size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
- offset = 1;
-
-
- if(size){
- if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
- if (op_isLitLike (IC_LEFT(ic)))
- {
- while(size--){
- emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
- emitSKPNC;
- emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
- emitpcode(POC_ADDLW, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
- emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
- offset++;
- }
- } else {
- while(size--){
- emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
- emitSKPNC;
- emitpcode(POC_INCFSZW, popGet(AOP(IC_LEFT(ic)),offset));
- emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset));
- offset++;
- }
- }
- } else {
- PIC_OPCODE poc = POC_MOVFW;
- if (op_isLitLike (IC_LEFT(ic)))
- poc = POC_MOVLW;
- while(size--){
- if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
- emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
- emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
- }
- emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
- emitSKPNC;
- emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
- emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset));
- offset++;
- }
- }
- }
- }
-
- if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
- int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
- SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
-
-
- /* Need to extend result to higher bytes */
- size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
-
- /* First grab the carry from the lower bytes */
- if (AOP_SIZE(IC_LEFT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
- int leftsize = AOP_SIZE(IC_LEFT(ic)) - AOP_SIZE(IC_RIGHT(ic));
- PIC_OPCODE poc = POC_MOVFW;
- if (op_isLitLike (IC_LEFT(ic)))
- poc = POC_MOVLW;
- while(leftsize-- > 0) {
- emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
- emitSKPNC;
- emitpcode(POC_ADDLW, popGetLit(0x01));
- emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
- //emitSKPNC;
- //emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset)); /* INCF does not update Carry! */
- offset++;
- if (size)
- size--;
- else
- break;
- }
- } else {
- emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
- emitpcode(POC_RLF, popGet(AOP(IC_RESULT(ic)),offset));
- }
-
-
- if(sign && offset > 0 && offset < AOP_SIZE(IC_RESULT(ic))) {
- /* Now this is really horrid. Gotta check the sign of the addends and propogate
- * to the result */
-
- emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
- emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
- emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
- emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
-
- /* if chars or ints or being signed extended to longs: */
- if(size) {
- emitpcode(POC_MOVLW, popGetLit(0));
- emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
- emitpcode(POC_MOVLW, popGetLit(0xff));
- }
- }
-
- offset++;
- while(size--) {
-
- if(sign)
- emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
- else
- emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
-
- offset++;
- }
- }
-
-
- //adjustArithmeticResult(ic);
-
+ int size, offset = 0;
+
+ /* special cases :- */
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ FENTRY;
+
+ aopOp (IC_LEFT(ic),ic,FALSE);
+ aopOp (IC_RIGHT(ic),ic,FALSE);
+ aopOp (IC_RESULT(ic),ic,TRUE);
+
+ DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),IC_RIGHT(ic),IC_RESULT(ic));
+
+ /* if literal, literal on the right or
+ if left requires ACC or right is already
+ in ACC */
+
+ if (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) {
+ operand *t = IC_RIGHT(ic);
+ IC_RIGHT(ic) = IC_LEFT(ic);
+ IC_LEFT(ic) = t;
+ }
+
+ /* if left in bit space & right literal */
+ if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY &&
+ AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
+ /* if result in bit space */
+ if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){
+ if(ulFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit) != 0L) {
+ emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0));
+ if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
+ emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0));
+ emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0));
+ }
+ } else {
+ size = pic14_getDataSize(IC_RESULT(ic));
+ while (size--) {
+ MOVA(aopGet(AOP(IC_RIGHT(ic)),offset,FALSE,FALSE));
+ pic14_emitcode("addc","a,#00 ;%d",__LINE__);
+ aopPut(AOP(IC_RESULT(ic)),"a",offset++);
+ }
+ }
+ goto release ;
+ }
+
+ /* if I can do an increment instead
+ of add then GOOD for ME */
+ if (genPlusIncr (ic) == TRUE)
+ goto release;
+
+ size = pic14_getDataSize(IC_RESULT(ic));
+
+ if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
+ /* Add a literal to something else */
+ //bool know_W=0;
+ unsigned lit = (unsigned) ulFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
+ // unsigned l1=0;
+
+ // offset = 0;
+ DEBUGpic14_emitcode(";","adding lit to something. size %d",size);
+
+ genAddLit (ic, lit);
+ goto release;
+
+ } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
+
+ pic14_emitcode(";bitadd","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
+ pic14_emitcode(";bitadd","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
+ pic14_emitcode(";bitadd","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
+
+ /* here we are adding a bit to a char or int */
+ if(size == 1) {
+ if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
+
+ emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
+ emitpcode(POC_INCF , popGet(AOP(IC_RESULT(ic)),0));
+
+ pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
+ AOP(IC_RIGHT(ic))->aopu.aop_dir,
+ AOP(IC_RIGHT(ic))->aopu.aop_dir);
+ pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
+ } else {
+
+ if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
+ emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
+ emitpcode(POC_XORLW , popGetLit(1));
+
+ pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
+ AOP(IC_RIGHT(ic))->aopu.aop_dir,
+ AOP(IC_RIGHT(ic))->aopu.aop_dir);
+ pic14_emitcode(" xorlw","1");
+ } else {
+ emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
+ emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
+ emitpcode(POC_INCFW , popGet(AOP(IC_LEFT(ic)),0));
+
+ pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
+ pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
+ AOP(IC_RIGHT(ic))->aopu.aop_dir,
+ AOP(IC_RIGHT(ic))->aopu.aop_dir);
+ pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
+ }
+
+ if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
+
+ if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
+ emitpcode(POC_ANDLW , popGetLit(1));
+ emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
+ emitSKPZ;
+ emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
+ } else {
+ emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
+ pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
+ }
+ }
+ }
+
+ } else {
+ int offset = 1;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
+ emitCLRZ;
+ emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
+ emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
+
+ pic14_emitcode("clrz","");
+
+ pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
+ AOP(IC_RIGHT(ic))->aopu.aop_dir,
+ AOP(IC_RIGHT(ic))->aopu.aop_dir);
+ pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
+
+ } else {
+
+ emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),0));
+ emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0));
+ emitpcode(POC_INCFW, popGet(AOP(IC_LEFT(ic)),0));
+ //emitpcode(POC_MOVWF, popGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
+ emitMOVWF(IC_RIGHT(ic),0);
+
+ pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
+ pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
+ AOP(IC_RIGHT(ic))->aopu.aop_dir,
+ AOP(IC_RIGHT(ic))->aopu.aop_dir);
+ pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
+ pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
+
+ }
+
+ while(--size){
+ emitSKPZ;
+ emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset++));
+ //pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RIGHT(ic)),offset++,FALSE,FALSE));
+ }
+
+ }
+
+ } else {
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ /* Add the first bytes */
+
+ if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
+ emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
+ emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
+ } else {
+
+ if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
+ emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0));
+ if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
+ emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
+ } else {
+
+ emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
+
+ if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
+ emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
+ else {
+ PIC_OPCODE poc = POC_ADDFW;
+
+ if (op_isLitLike (IC_LEFT (ic)))
+ poc = POC_ADDLW;
+ emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),0,0));
+ if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
+ emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
+ }
+ }
+ }
+
+ size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
+ offset = 1;
+
+
+ if(size){
+ if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
+ if (op_isLitLike (IC_LEFT(ic)))
+ {
+ while(size--){
+ emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
+ emitSKPNC;
+ emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
+ emitpcode(POC_ADDLW, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
+ emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
+ offset++;
+ }
+ } else {
+ while(size--){
+ emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
+ emitSKPNC;
+ emitpcode(POC_INCFSZW, popGet(AOP(IC_LEFT(ic)),offset));
+ emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset));
+ offset++;
+ }
+ }
+ } else {
+ PIC_OPCODE poc = POC_MOVFW;
+ if (op_isLitLike (IC_LEFT(ic)))
+ poc = POC_MOVLW;
+ while(size--){
+ if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
+ emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
+ emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
+ }
+ emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
+ emitSKPNC;
+ emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
+ emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),offset));
+ offset++;
+ }
+ }
+ }
+ }
+
+ if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
+ int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) |
+ SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) );
+
+
+ /* Need to extend result to higher bytes */
+ size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1;
+
+ /* First grab the carry from the lower bytes */
+ if (AOP_SIZE(IC_LEFT(ic)) > AOP_SIZE(IC_RIGHT(ic))) {
+ int leftsize = AOP_SIZE(IC_LEFT(ic)) - AOP_SIZE(IC_RIGHT(ic));
+ PIC_OPCODE poc = POC_MOVFW;
+ if (op_isLitLike (IC_LEFT(ic)))
+ poc = POC_MOVLW;
+ while(leftsize-- > 0) {
+ emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
+ emitSKPNC;
+ emitpcode(POC_ADDLW, popGetLit(0x01));
+ emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
+ //emitSKPNC;
+ //emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset)); /* INCF does not update Carry! */
+ offset++;
+ if (size)
+ size--;
+ else
+ break;
+ }
+ } else {
+ emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
+ emitpcode(POC_RLF, popGet(AOP(IC_RESULT(ic)),offset));
+ }
+
+
+ if(sign && offset > 0 && offset < AOP_SIZE(IC_RESULT(ic))) {
+ /* Now this is really horrid. Gotta check the sign of the addends and propogate
+ * to the result */
+
+ emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0));
+ emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
+ emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0));
+ emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
+
+ /* if chars or ints or being signed extended to longs: */
+ if(size) {
+ emitpcode(POC_MOVLW, popGetLit(0));
+ emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0));
+ emitpcode(POC_MOVLW, popGetLit(0xff));
+ }
+ }
+
+ offset++;
+ while(size--) {
+
+ if(sign)
+ emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
+ else
+ emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
+
+ offset++;
+ }
+ }
+
+
+ //adjustArithmeticResult(ic);
+
release:
- freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
+ freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
bool genMinusDec (iCode *ic)
{
- unsigned int icount ;
- unsigned int size = pic14_getDataSize(IC_RESULT(ic));
- FENTRY;
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- /* will try to generate an increment */
- /* if the right side is not a literal
- we cannot */
- if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
- (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
- (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
- return FALSE ;
-
- DEBUGpic14_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
-
- /* if the literal value of the right hand side
- is greater than 4 then it is not worth it */
- if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
- return FALSE ;
-
- /* if decrement 16 bits in register */
- if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
- (size > 1) &&
- (icount == 1)) {
-
- if(size == 2) {
- emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),LSB));
- emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB));
- emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),MSB16));
- emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),MSB16));
-
- pic14_emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
- pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
- pic14_emitcode(" decf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
- } else {
- /* size is 3 or 4 */
- emitpcode(POC_MOVLW, popGetLit(0xff));
- emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),LSB));
- emitSKPNC;
- emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB16));
- emitSKPNC;
- emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB24));
-
- pic14_emitcode("movlw","0xff");
- pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
-
- emitSKPNC;
- pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
- emitSKPNC;
- pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
-
- if(size > 3) {
- emitSKPNC;
- emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB32));
-
- pic14_emitcode("skpnc","");
- emitSKPNC;
- pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
- }
-
- }
-
- return TRUE;
-
- }
-
- /* if the sizes are greater than 1 then we cannot */
- if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
- AOP_SIZE(IC_LEFT(ic)) > 1 )
- return FALSE ;
-
- /* we can if the aops of the left & result match or
- if they are in registers and the registers are the
- same */
- if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
-
- while (icount--)
- emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0));
-
- //pic14_emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
-
- return TRUE ;
- }
-
- DEBUGpic14_emitcode ("; returning"," result=%s, left=%s",
- aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
- aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
- if(size==1) {
-
- pic14_emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
- pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
-
- emitpcode(POC_DECFW, popGet(AOP(IC_LEFT(ic)),0));
- emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
-
- return TRUE;
- }
-
- return FALSE ;
+ unsigned int icount ;
+ unsigned int size = pic14_getDataSize(IC_RESULT(ic));
+ FENTRY;
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* will try to generate an increment */
+ /* if the right side is not a literal
+ we cannot */
+ if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
+ (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
+ (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
+ return FALSE ;
+
+ DEBUGpic14_emitcode ("; lit val","%d",(unsigned int) ulFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
+
+ /* if the literal value of the right hand side
+ is greater than 4 then it is not worth it */
+ if ((icount = (unsigned int) ulFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
+ return FALSE ;
+
+ /* if decrement 16 bits in register */
+ if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
+ (size > 1) &&
+ (icount == 1)) {
+
+ if(size == 2) {
+ emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),LSB));
+ emitpcode(POC_INCFSZW, popGet(AOP(IC_RESULT(ic)),LSB));
+ emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),MSB16));
+ emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),MSB16));
+
+ pic14_emitcode("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
+ pic14_emitcode("incfsz","%s,w",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
+ pic14_emitcode(" decf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
+ } else {
+ /* size is 3 or 4 */
+ emitpcode(POC_MOVLW, popGetLit(0xff));
+ emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),LSB));
+ emitSKPNC;
+ emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB16));
+ emitSKPNC;
+ emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB24));
+
+ pic14_emitcode("movlw","0xff");
+ pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
+
+ emitSKPNC;
+ pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
+ emitSKPNC;
+ pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
+
+ if(size > 3) {
+ emitSKPNC;
+ emitpcode(POC_ADDWF, popGet(AOP(IC_RESULT(ic)),MSB32));
+
+ pic14_emitcode("skpnc","");
+ emitSKPNC;
+ pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
+ }
+
+ }
+
+ return TRUE;
+
+ }
+
+ /* if the sizes are greater than 1 then we cannot */
+ if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
+ AOP_SIZE(IC_LEFT(ic)) > 1 )
+ return FALSE ;
+
+ /* we can if the aops of the left & result match or
+ if they are in registers and the registers are the
+ same */
+ if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
+
+ while (icount--)
+ emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),0));
+
+ //pic14_emitcode ("decf","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
+
+ return TRUE ;
+ }
+
+ DEBUGpic14_emitcode ("; returning"," result=%s, left=%s",
+ aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
+ aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
+ if(size==1) {
+
+ pic14_emitcode("decf","%s,w",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
+ pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
+
+ emitpcode(POC_DECFW, popGet(AOP(IC_LEFT(ic)),0));
+ emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
+
+ return TRUE;
+ }
+
+ return FALSE ;
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
void addSign(operand *result, int offset, int sign)
{
- int size = (pic14_getDataSize(result) - offset);
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- FENTRY;
-
- if(size > 0){
- if(sign && offset) {
-
- if(size == 1) {
- emitpcode(POC_CLRF,popGet(AOP(result),offset));
- emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
- emitpcode(POC_DECF, popGet(AOP(result),offset));
- } else {
-
- emitpcode(POC_MOVLW, popGetLit(0));
- emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
- emitpcode(POC_MOVLW, popGetLit(0xff));
- while(size--)
- emitpcode(POC_MOVWF, popGet(AOP(result),offset+size));
- }
- } else
- while(size--)
- emitpcode(POC_CLRF,popGet(AOP(result),offset++));
- }
+ int size = (pic14_getDataSize(result) - offset);
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ FENTRY;
+
+ if(size > 0){
+ if(sign && offset) {
+
+ if(size == 1) {
+ emitpcode(POC_CLRF,popGet(AOP(result),offset));
+ emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
+ emitpcode(POC_DECF, popGet(AOP(result),offset));
+ } else {
+
+ emitpcode(POC_MOVLW, popGetLit(0));
+ emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
+ emitpcode(POC_MOVLW, popGetLit(0xff));
+ while(size--)
+ emitpcode(POC_MOVWF, popGet(AOP(result),offset+size));
+ }
+ } else
+ while(size--)
+ emitpcode(POC_CLRF,popGet(AOP(result),offset++));
+ }
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
void genMinus (iCode *ic)
{
- int size, offset = 0, same=0;
- unsigned long lit = 0L;
-
- FENTRY;
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- aopOp (IC_LEFT(ic),ic,FALSE);
- aopOp (IC_RIGHT(ic),ic,FALSE);
- aopOp (IC_RESULT(ic),ic,TRUE);
-
- if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
- AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
- operand *t = IC_RIGHT(ic);
- IC_RIGHT(ic) = IC_LEFT(ic);
- IC_LEFT(ic) = t;
- }
-
- DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
- AopType(AOP_TYPE(IC_RESULT(ic))),
- AopType(AOP_TYPE(IC_LEFT(ic))),
- AopType(AOP_TYPE(IC_RIGHT(ic))));
-
- /* if I can do an decrement instead
- of subtract then GOOD for ME */
- // if (genMinusDec (ic) == TRUE)
- // goto release;
-
- size = pic14_getDataSize(IC_RESULT(ic));
- same = pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
-
- if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
- /* Add a literal to something else */
-
- lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
- lit = - (long)lit;
-
- genAddLit ( ic, lit);
-
+ int size, offset = 0, same=0;
+ unsigned long lit = 0L;
+
+ FENTRY;
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ aopOp (IC_LEFT(ic),ic,FALSE);
+ aopOp (IC_RIGHT(ic),ic,FALSE);
+ aopOp (IC_RESULT(ic),ic,TRUE);
+
+ if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
+ AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) {
+ operand *t = IC_RIGHT(ic);
+ IC_RIGHT(ic) = IC_LEFT(ic);
+ IC_LEFT(ic) = t;
+ }
+
+ DEBUGpic14_emitcode ("; ","result %s, left %s, right %s",
+ AopType(AOP_TYPE(IC_RESULT(ic))),
+ AopType(AOP_TYPE(IC_LEFT(ic))),
+ AopType(AOP_TYPE(IC_RIGHT(ic))));
+
+ /* if I can do an decrement instead
+ of subtract then GOOD for ME */
+ // if (genMinusDec (ic) == TRUE)
+ // goto release;
+
+ size = pic14_getDataSize(IC_RESULT(ic));
+ same = pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
+
+ if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
+ /* Add a literal to something else */
+
+ lit = ulFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
+ lit = - (long)lit;
+
+ genAddLit ( ic, lit);
+
#if 0
- /* add the first byte: */
- pic14_emitcode("movlw","0x%x", lit & 0xff);
- pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
- emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
- emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
-
-
- offset = 1;
- size--;
-
- while(size-- > 0) {
-
- lit >>= 8;
-
- if(lit & 0xff) {
-
- if((lit & 0xff) == 0xff) {
- emitpcode(POC_MOVLW, popGetLit(0xff));
- emitSKPC;
- emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
- } else {
- emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
- emitSKPNC;
- emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
- emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
- }
-
- } else {
- /* do the rlf known zero trick here */
- emitpcode(POC_MOVLW, popGetLit(1));
- emitSKPNC;
- emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
- }
- offset++;
- }
+ /* add the first byte: */
+ pic14_emitcode("movlw","0x%x", lit & 0xff);
+ pic14_emitcode("addwf","%s,f", aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
+ emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
+ emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0));
+
+
+ offset = 1;
+ size--;
+
+ while(size-- > 0) {
+
+ lit >>= 8;
+
+ if(lit & 0xff) {
+
+ if((lit & 0xff) == 0xff) {
+ emitpcode(POC_MOVLW, popGetLit(0xff));
+ emitSKPC;
+ emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
+ } else {
+ emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
+ emitSKPNC;
+ emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
+ emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
+ }
+
+ } else {
+ /* do the rlf known zero trick here */
+ emitpcode(POC_MOVLW, popGetLit(1));
+ emitSKPNC;
+ emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),offset));
+ }
+ offset++;
+ }
#endif
- } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
- // bit subtraction
-
- pic14_emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
- pic14_emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
- pic14_emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
-
- /* here we are subtracting a bit from a char or int */
- if(size == 1) {
- if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
-
- emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
- emitpcode(POC_DECF , popGet(AOP(IC_RESULT(ic)),0));
-
- pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
- AOP(IC_RIGHT(ic))->aopu.aop_dir,
- AOP(IC_RIGHT(ic))->aopu.aop_dir);
- pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
- } else {
-
- if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
- emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
- emitpcode(POC_XORLW , popGetLit(1));
- }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
- (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
-
- lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
-
- if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
- if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
- if(lit & 1) {
- emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0));
- emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0));
- }
- }else{
- emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
- if(lit & 1)
- emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0));
- else
- emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
- emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
- }
- goto release;
- } else {
- emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
- emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
- emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
- emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
-
- }
-
- } else {
- emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
- emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
- emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0));
- }
-
- if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
-
- emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
-
- } else {
- emitpcode(POC_ANDLW , popGetLit(1));
- /*
- emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
- emitSKPZ;
- emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
- */
- }
-
- }
-
- }
- } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
- (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
- (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
-
- lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
- DEBUGpic14_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
- AopType(AOP_TYPE(IC_RESULT(ic))),
- AopType(AOP_TYPE(IC_LEFT(ic))),
- AopType(AOP_TYPE(IC_RIGHT(ic))));
-
-
- if( (size == 1) && ((lit & 0xff) == 0) ) {
- /* res = 0 - right */
- if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
- emitpcode(POC_COMF, popGet(AOP(IC_RIGHT(ic)),0));
- emitpcode(POC_INCF, popGet(AOP(IC_RIGHT(ic)),0));
- } else {
- emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),0));
- emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
- emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
- }
- goto release;
- }
-
- emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0));
- emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
- emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
-
-
- offset = 1;
- while(--size) {
- lit >>= 8;
-
- if(size == 1) {
- /* This is the last byte in a multibyte subtraction
- * There are a couple of tricks we can do by not worrying about
- * propogating the carry */
- if(lit == 0xff) {
- /* 0xff - x == ~x */
- if(same) {
- emitpcode(POC_COMF, popGet(AOP(IC_RESULT(ic)),offset));
- emitSKPC;
- emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
- } else {
- emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset));
- emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
- emitSKPC;
- emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
- }
- } else {
- emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
- emitSKPC;
- emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
- emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
- emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
- }
-
- goto release;
- }
-
- if(same) {
-
- if(lit & 0xff) {
- emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
- emitSKPC;
- emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1));
- emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
- } else {
- emitSKPNC;
- emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
-
- }
- } else {
-
- if(lit & 0xff) {
- emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
- emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
- } else
- emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
-
- emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
- emitSKPC;
- emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
- emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
- }
- }
-
-
- } else {
-
- DEBUGpic14_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
- AopType(AOP_TYPE(IC_RESULT(ic))),
- AopType(AOP_TYPE(IC_LEFT(ic))),
- AopType(AOP_TYPE(IC_RIGHT(ic))));
-
- if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
- emitpcode(POC_SUBLW, popGetLit(0));
- emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
- } else {
-
- if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
- emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
- emitpcode(POC_SUBLW, popGetLit(0));
- if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
- emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
- } else {
-
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
- emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
-
- if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
- emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0));
- else {
- if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
- (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
- emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0));
- } else {
- emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0));
- }
- if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
- if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
- emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
- emitSKPZ;
- emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
- }else
- emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
- }
- }
- }
- }
-
- size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
- offset = 1;
-
- if(size){
- if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
- int lit = 0;
- if (op_isLitLike (IC_LEFT(ic)))
- lit = 1;
- while(size--){
- emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
- emitSKPC;
- emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
- emitpcode(lit?POC_SUBLW:POC_SUBFW, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
- emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
- offset++;
- }
- } else {
- PIC_OPCODE poc = POC_MOVFW;
- if (op_isLitLike (IC_LEFT(ic)))
- poc = POC_MOVLW;
- while(size--){
- if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
- emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
- emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
- }
- emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
- emitSKPC;
- emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
- emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
- offset++;
- }
- }
- }
- }
-
- // adjustArithmeticResult(ic);
-
+ } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
+ // bit subtraction
+
+ pic14_emitcode(";bitsub","right is bit: %s",aopGet(AOP(IC_RIGHT(ic)),0,FALSE,FALSE));
+ pic14_emitcode(";bitsub","left is bit: %s",aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
+ pic14_emitcode(";bitsub","result is bit: %s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
+
+ /* here we are subtracting a bit from a char or int */
+ if(size == 1) {
+ if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
+
+ emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
+ emitpcode(POC_DECF , popGet(AOP(IC_RESULT(ic)),0));
+
+ pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
+ AOP(IC_RIGHT(ic))->aopu.aop_dir,
+ AOP(IC_RIGHT(ic))->aopu.aop_dir);
+ pic14_emitcode(" incf","%s,f", aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
+ } else {
+
+ if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
+ emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
+ emitpcode(POC_XORLW , popGetLit(1));
+ }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
+ (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
+
+ lit = ulFromVal (AOP(IC_LEFT(ic))->aopu.aop_lit);
+
+ if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
+ if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
+ if(lit & 1) {
+ emitpcode(POC_MOVLW , popGet(AOP(IC_RIGHT(ic)),0));
+ emitpcode(POC_XORWF , popGet(AOP(IC_RIGHT(ic)),0));
+ }
+ }else{
+ emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
+ if(lit & 1)
+ emitpcode(POC_BTFSS , popGet(AOP(IC_RIGHT(ic)),0));
+ else
+ emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
+ emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
+ }
+ goto release;
+ } else {
+ emitpcode(POC_MOVLW , popGetLit(lit & 0xff));
+ emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
+ emitpcode(POC_MOVLW , popGetLit((lit-1) & 0xff));
+ emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
+
+ }
+
+ } else {
+ emitpcode(POC_MOVFW , popGet(AOP(IC_LEFT(ic)),0));
+ emitpcode(POC_BTFSC , popGet(AOP(IC_RIGHT(ic)),0));
+ emitpcode(POC_DECFW , popGet(AOP(IC_LEFT(ic)),0));
+ }
+
+ if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
+
+ emitpcode(POC_MOVWF , popGet(AOP(IC_RESULT(ic)),0));
+
+ } else {
+ emitpcode(POC_ANDLW , popGetLit(1));
+ /*
+ emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
+ emitSKPZ;
+ emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
+ */
+ }
+
+ }
+
+ }
+ } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
+ (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
+ (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
+
+ lit = ulFromVal (AOP(IC_LEFT(ic))->aopu.aop_lit);
+ DEBUGpic14_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
+ AopType(AOP_TYPE(IC_RESULT(ic))),
+ AopType(AOP_TYPE(IC_LEFT(ic))),
+ AopType(AOP_TYPE(IC_RIGHT(ic))));
+
+
+ if( (size == 1) && ((lit & 0xff) == 0) ) {
+ /* res = 0 - right */
+ if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
+ emitpcode(POC_COMF, popGet(AOP(IC_RIGHT(ic)),0));
+ emitpcode(POC_INCF, popGet(AOP(IC_RIGHT(ic)),0));
+ } else {
+ emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),0));
+ emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0));
+ emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
+ }
+ goto release;
+ }
+
+ emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),0));
+ emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
+ emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
+
+
+ offset = 1;
+ while(--size) {
+ lit >>= 8;
+
+ if(size == 1) {
+ /* This is the last byte in a multibyte subtraction
+ * There are a couple of tricks we can do by not worrying about
+ * propogating the carry */
+ if(lit == 0xff) {
+ /* 0xff - x == ~x */
+ if(same) {
+ emitpcode(POC_COMF, popGet(AOP(IC_RESULT(ic)),offset));
+ emitSKPC;
+ emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
+ } else {
+ emitpcode(POC_COMFW, popGet(AOP(IC_RIGHT(ic)),offset));
+ emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
+ emitSKPC;
+ emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset));
+ }
+ } else {
+ emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
+ emitSKPC;
+ emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
+ emitpcode(POC_SUBLW, popGetLit(lit & 0xff));
+ emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
+ }
+
+ goto release;
+ }
+
+ if(same) {
+
+ if(lit & 0xff) {
+ emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
+ emitSKPC;
+ emitpcode(POC_MOVLW, popGetLit((lit & 0xff)-1));
+ emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
+ } else {
+ emitSKPNC;
+ emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
+
+ }
+ } else {
+
+ if(lit & 0xff) {
+ emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
+ emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
+ } else
+ emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset));
+
+ emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
+ emitSKPC;
+ emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
+ emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
+ }
+ }
+
+
+ } else {
+
+ DEBUGpic14_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
+ AopType(AOP_TYPE(IC_RESULT(ic))),
+ AopType(AOP_TYPE(IC_LEFT(ic))),
+ AopType(AOP_TYPE(IC_RIGHT(ic))));
+
+ if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) {
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
+ emitpcode(POC_SUBLW, popGetLit(0));
+ emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
+ } else {
+
+ if ( AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
+ emitpcode(POC_SUBFW, popGet(AOP(IC_RIGHT(ic)),0));
+ emitpcode(POC_SUBLW, popGetLit(0));
+ if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
+ emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
+ } else {
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
+ emitpcode(POC_MOVFW,popGet(AOP(IC_RIGHT(ic)),0));
+
+ if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
+ emitpcode(POC_SUBWF, popGet(AOP(IC_LEFT(ic)),0));
+ else {
+ if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
+ (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
+ emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),0));
+ } else {
+ emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),0));
+ }
+ if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
+ if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
+ emitpcode(POC_BCF , popGet(AOP(IC_RESULT(ic)),0));
+ emitSKPZ;
+ emitpcode(POC_BSF , popGet(AOP(IC_RESULT(ic)),0));
+ }else
+ emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
+ }
+ }
+ }
+ }
+
+ size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1;
+ offset = 1;
+
+ if(size){
+ if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
+ int lit = 0;
+ if (op_isLitLike (IC_LEFT(ic)))
+ lit = 1;
+ while(size--){
+ emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
+ emitSKPC;
+ emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
+ emitpcode(lit?POC_SUBLW:POC_SUBFW, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
+ emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
+ offset++;
+ }
+ } else {
+ PIC_OPCODE poc = POC_MOVFW;
+ if (op_isLitLike (IC_LEFT(ic)))
+ poc = POC_MOVLW;
+ while(size--){
+ if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
+ emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
+ emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
+ }
+ emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset));
+ emitSKPC;
+ emitpcode(POC_INCFSZW,popGet(AOP(IC_RIGHT(ic)),offset));
+ emitpcode(POC_SUBWF, popGet(AOP(IC_RESULT(ic)),offset));
+ offset++;
+ }
+ }
+ }
+ }
+
+ // adjustArithmeticResult(ic);
+
release:
- freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
+ freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
}
/*-----------------------------------------------------------------*
* genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
*
*-----------------------------------------------------------------*/
void genUMult8XLit_16 (operand *left,
- operand *right,
- operand *result,
- pCodeOpReg *result_hi)
-
+ operand *right,
+ operand *result,
+ pCodeOpReg *result_hi)
+
{
-
- unsigned int lit;
- unsigned int i,have_first_bit;
- int same;
- pCodeOp *temp;
-
- FENTRY;
- if (AOP_TYPE(right) != AOP_LIT){
- fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
- exit(EXIT_FAILURE);
- }
-
-
- if(!result_hi) {
- result_hi = PCOR(popGet(AOP(result),1));
- }
-
- lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
- lit &= 0xff;
- pic14_emitcode(";","Unrolled 8 X 8 multiplication");
-
- same = pic14_sameRegs(AOP(left), AOP(result));
-
- if(same) {
- switch(lit) {
- case 0:
- emitpcode(POC_CLRF, popGet(AOP(left),0));
- return;
- case 2:
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_ADDWF, popGet(AOP(left),0));
- return;
- case 3:
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_ADDWF, popGet(AOP(left),0));
- emitpcode(POC_ADDWF, popGet(AOP(left),0));
- return;
- case 4:
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_ADDWF, popGet(AOP(left),0));
- emitpcode(POC_ADDWF, popGet(AOP(left),0));
- emitpcode(POC_ADDWF, popGet(AOP(left),0));
- return;
- case 5:
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
- emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
- emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
- return;
- case 6:
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_ADDWF, popGet(AOP(left),0));
- emitpcode(POC_ADDWF, popGet(AOP(left),0));
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_ADDWF, popGet(AOP(left),0));
- return;
- case 7:
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
- emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
- emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
- emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 7*F
- return;
- case 8:
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
- emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
- emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
- emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 8*F
- return;
- case 9:
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_ADDWF, popGet(AOP(left),0));
- emitpcode(POC_ADDWF, popGet(AOP(left),0));
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_ADDWF, popGet(AOP(left),0));
- emitpcode(POC_ADDWF, popGet(AOP(left),0));
- return;
- case 10:
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
- emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
- emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_ADDWF, popGet(AOP(left),0));
- return;
- case 11:
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
- emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
- emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
- emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 8*F
- emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 11*F
- return;
- case 12:
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_ADDWF, popGet(AOP(left),0));
- emitpcode(POC_ADDWF, popGet(AOP(left),0));
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_ADDWF, popGet(AOP(left),0));
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_ADDWF, popGet(AOP(left),0));
- return;
- case 13:
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
- emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
- emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
- emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 8*F
- emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 13*F
- return;
- case 14:
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
- emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
- emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
- emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 8*F
- emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 11*F
- emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 14*F
- return;
- case 15:
- temp = popGetTempReg();
- if(!temp) {
- fprintf(stderr,"ERROR: unable to allocate register. %s:%d\n",__FUNCTION__,__LINE__);
- exit(EXIT_FAILURE);
- }
- emitpcode(POC_SWAPFW, popGet(AOP(left),0));
- emitpcode(POC_MOVWF, temp);
- emitpcode(POC_ANDLW, popGetLit(0xf0));
- emitpcode(POC_MOVWF, popGet(AOP(left),0));
- emitpcode(POC_SWAPFW, temp);
- emitpcode(POC_SUBWF, popGet(AOP(left),0));
- popReleaseTempReg(temp);
- return;
- case 16:
- emitpcode(POC_SWAPFW, popGet(AOP(left),0));
- emitpcode(POC_ANDLW, popGetLit(0xf0));
- emitpcode(POC_MOVWF, popGet(AOP(left),0));
- return;
- case 17:
- emitpcode(POC_SWAPFW, popGet(AOP(left),0));
- emitpcode(POC_ANDLW, popGetLit(0xf0));
- emitpcode(POC_ADDWF, popGet(AOP(left),0));
- return;
- case 32:
- emitpcode(POC_SWAPF, popGet(AOP(left),0));
- emitpcode(POC_RLFW, popGet(AOP(left),0));
- emitpcode(POC_ANDLW, popGetLit(0xe0));
- emitpcode(POC_MOVWF, popGet(AOP(left),0));
- return;
- case 64:
- emitpcode(POC_SWAPF, popGet(AOP(left),0));
- emitpcode(POC_RLF, popGet(AOP(left),0));
- emitpcode(POC_RLFW, popGet(AOP(left),0));
- emitpcode(POC_ANDLW, popGetLit(0xc0));
- emitpcode(POC_MOVWF, popGet(AOP(left),0));
- return;
- case 128:
- emitpcode(POC_RRFW, popGet(AOP(left),0));
- emitpcode(POC_CLRF, popGet(AOP(left),0));
- emitpcode(POC_RRF, popGet(AOP(left),0));
- return;
-
- }
- } else {
-
- switch(lit) {
- case 0:
- emitpcode(POC_CLRF, popGet(AOP(result),0));
- emitpcode(POC_CLRF, popCopyReg(result_hi));
- return;
- case 2:
- if (AOP_TYPE(left) != AOP_ACC) /* Check if w is already loaded */
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_MOVWF, popGet(AOP(result),0));
- emitpcode(POC_ADDWF, popGet(AOP(result),0));
- emitpcode(POC_CLRF, popCopyReg(result_hi));
- emitpcode(POC_RLF, popCopyReg(result_hi));
- return;
- case 4:
- case 8:
- if (AOP_TYPE(left) != AOP_ACC) /* Check if w is already loaded */
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_MOVWF, popGet(AOP(result),0));
- emitpcode(POC_CLRF, popCopyReg(result_hi));
- emitpcode(POC_BCF, popCopyReg(&pc_status));
- emitpcode(POC_RLF, popGet(AOP(result),0));
- emitpcode(POC_RLF, popCopyReg(result_hi));
- emitpcode(POC_RLF, popGet(AOP(result),0));
- emitpcode(POC_RLF, popCopyReg(result_hi));
- if (lit >= 8) {
- emitpcode(POC_RLF, popGet(AOP(result),0));
- emitpcode(POC_RLF, popCopyReg(result_hi));
- }
- return;
- }
-
- }
-
- if (AOP_TYPE(left) != AOP_ACC) /* Check if w is already loaded */
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_CLRF, popGet(AOP(result),0));
- emitpcode(POC_CLRF, popCopyReg(result_hi));
+
+ unsigned int lit;
+ unsigned int i,have_first_bit;
+ int same;
+ pCodeOp *temp;
+
+ FENTRY;
+ if (AOP_TYPE(right) != AOP_LIT){
+ fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
+ exit(EXIT_FAILURE);
+ }
+
+
+ if(!result_hi) {
+ result_hi = PCOR(popGet(AOP(result),1));
+ }
+
+ lit = (unsigned int) ulFromVal (AOP(right)->aopu.aop_lit);
+ lit &= 0xff;
+ pic14_emitcode(";","Unrolled 8 X 8 multiplication");
+
+ same = pic14_sameRegs(AOP(left), AOP(result));
+
+ if(same) {
+ switch(lit) {
+ case 0:
+ emitpcode(POC_CLRF, popGet(AOP(left),0));
+ return;
+ case 2:
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ emitpcode(POC_ADDWF, popGet(AOP(left),0));
+ return;
+ case 3:
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ emitpcode(POC_ADDWF, popGet(AOP(left),0));
+ emitpcode(POC_ADDWF, popGet(AOP(left),0));
+ return;
+ case 4:
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ emitpcode(POC_ADDWF, popGet(AOP(left),0));
+ emitpcode(POC_ADDWF, popGet(AOP(left),0));
+ emitpcode(POC_ADDWF, popGet(AOP(left),0));
+ return;
+ case 5:
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
+ emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
+ emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
+ return;
+ case 6:
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ emitpcode(POC_ADDWF, popGet(AOP(left),0));
+ emitpcode(POC_ADDWF, popGet(AOP(left),0));
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ emitpcode(POC_ADDWF, popGet(AOP(left),0));
+ return;
+ case 7:
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
+ emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
+ emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
+ emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 7*F
+ return;
+ case 8:
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
+ emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
+ emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
+ emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 8*F
+ return;
+ case 9:
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ emitpcode(POC_ADDWF, popGet(AOP(left),0));
+ emitpcode(POC_ADDWF, popGet(AOP(left),0));
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ emitpcode(POC_ADDWF, popGet(AOP(left),0));
+ emitpcode(POC_ADDWF, popGet(AOP(left),0));
+ return;
+ case 10:
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
+ emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
+ emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 5*F
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ emitpcode(POC_ADDWF, popGet(AOP(left),0));
+ return;
+ case 11:
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
+ emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
+ emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
+ emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 8*F
+ emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 11*F
+ return;
+ case 12:
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ emitpcode(POC_ADDWF, popGet(AOP(left),0));
+ emitpcode(POC_ADDWF, popGet(AOP(left),0));
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ emitpcode(POC_ADDWF, popGet(AOP(left),0));
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ emitpcode(POC_ADDWF, popGet(AOP(left),0));
+ return;
+ case 13:
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
+ emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
+ emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
+ emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 8*F
+ emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 13*F
+ return;
+ case 14:
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 2*F
+ emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 3*F
+ emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 5*F
+ emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 8*F
+ emitpcode(POC_ADDFW, popGet(AOP(left),0)); // W = 11*F
+ emitpcode(POC_ADDWF, popGet(AOP(left),0)); // F = 14*F
+ return;
+ case 15:
+ temp = popGetTempReg();
+ if(!temp) {
+ fprintf(stderr,"ERROR: unable to allocate register. %s:%d\n",__FUNCTION__,__LINE__);
+ exit(EXIT_FAILURE);
+ }
+ emitpcode(POC_SWAPFW, popGet(AOP(left),0));
+ emitpcode(POC_MOVWF, temp);
+ emitpcode(POC_ANDLW, popGetLit(0xf0));
+ emitpcode(POC_MOVWF, popGet(AOP(left),0));
+ emitpcode(POC_SWAPFW, temp);
+ emitpcode(POC_SUBWF, popGet(AOP(left),0));
+ popReleaseTempReg(temp);
+ return;
+ case 16:
+ emitpcode(POC_SWAPFW, popGet(AOP(left),0));
+ emitpcode(POC_ANDLW, popGetLit(0xf0));
+ emitpcode(POC_MOVWF, popGet(AOP(left),0));
+ return;
+ case 17:
+ emitpcode(POC_SWAPFW, popGet(AOP(left),0));
+ emitpcode(POC_ANDLW, popGetLit(0xf0));
+ emitpcode(POC_ADDWF, popGet(AOP(left),0));
+ return;
+ case 32:
+ emitpcode(POC_SWAPF, popGet(AOP(left),0));
+ emitpcode(POC_RLFW, popGet(AOP(left),0));
+ emitpcode(POC_ANDLW, popGetLit(0xe0));
+ emitpcode(POC_MOVWF, popGet(AOP(left),0));
+ return;
+ case 64:
+ emitpcode(POC_SWAPF, popGet(AOP(left),0));
+ emitpcode(POC_RLF, popGet(AOP(left),0));
+ emitpcode(POC_RLFW, popGet(AOP(left),0));
+ emitpcode(POC_ANDLW, popGetLit(0xc0));
+ emitpcode(POC_MOVWF, popGet(AOP(left),0));
+ return;
+ case 128:
+ emitpcode(POC_RRFW, popGet(AOP(left),0));
+ emitpcode(POC_CLRF, popGet(AOP(left),0));
+ emitpcode(POC_RRF, popGet(AOP(left),0));
+ return;
+
+ }
+ } else {
+
+ switch(lit) {
+ case 0:
+ emitpcode(POC_CLRF, popGet(AOP(result),0));
+ emitpcode(POC_CLRF, popCopyReg(result_hi));
+ return;
+ case 2:
+ if (AOP_TYPE(left) != AOP_ACC) /* Check if w is already loaded */
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ emitpcode(POC_MOVWF, popGet(AOP(result),0));
+ emitpcode(POC_ADDWF, popGet(AOP(result),0));
+ emitpcode(POC_CLRF, popCopyReg(result_hi));
+ emitpcode(POC_RLF, popCopyReg(result_hi));
+ return;
+ case 4:
+ case 8:
+ if (AOP_TYPE(left) != AOP_ACC) /* Check if w is already loaded */
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ emitpcode(POC_MOVWF, popGet(AOP(result),0));
+ emitpcode(POC_CLRF, popCopyReg(result_hi));
+ emitpcode(POC_BCF, popCopyReg(&pc_status));
+ emitpcode(POC_RLF, popGet(AOP(result),0));
+ emitpcode(POC_RLF, popCopyReg(result_hi));
+ emitpcode(POC_RLF, popGet(AOP(result),0));
+ emitpcode(POC_RLF, popCopyReg(result_hi));
+ if (lit >= 8) {
+ emitpcode(POC_RLF, popGet(AOP(result),0));
+ emitpcode(POC_RLF, popCopyReg(result_hi));
+ }
+ return;
+ }
+
+ }
+
+ if (AOP_TYPE(left) != AOP_ACC) /* Check if w is already loaded */
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ emitpcode(POC_CLRF, popGet(AOP(result),0));
+ emitpcode(POC_CLRF, popCopyReg(result_hi));
- have_first_bit = 0;
- for(i=0; i<8; i++) {
-
- if(lit & 1) {
- emitpcode(POC_ADDWF, popCopyReg(result_hi));
- have_first_bit = 1;
- }
-
- if(have_first_bit) {
- emitpcode(POC_RRF, popCopyReg(result_hi));
- emitpcode(POC_RRF, popGet(AOP(result),0));
- }
-
- lit >>= 1;
- }
+ have_first_bit = 0;
+ for(i=0; i<8; i++) {
+
+ if(lit & 1) {
+ emitpcode(POC_ADDWF, popCopyReg(result_hi));
+ have_first_bit = 1;
+ }
+
+ if(have_first_bit) {
+ emitpcode(POC_RRF, popCopyReg(result_hi));
+ emitpcode(POC_RRF, popGet(AOP(result),0));
+ }
+
+ lit >>= 1;
+ }
}
/*-----------------------------------------------------------------*
*
*-----------------------------------------------------------------*/
void genUMult8X8_16 (operand *left,
- operand *right,
- operand *result,
- pCodeOpReg *result_hi)
-
+ operand *right,
+ operand *result,
+ pCodeOpReg *result_hi)
+
{
-
- int i;
- int looped = 1;
-
- FENTRY;
- if(!result_hi) {
- result_hi = PCOR(popGet(AOP(result),1));
- }
-
- if (AOP_TYPE(right) == AOP_LIT) {
- genUMult8XLit_16(left,right,result,result_hi);
- return;
- }
-
- if(!looped) {
- pic14_emitcode(";","Unrolled 8 X 8 multiplication");
-
- emitpcode(POC_MOVFW, popGet(AOP(right),0));
- emitpcode(POC_CLRF, popGet(AOP(result),0));
- emitpcode(POC_CLRF, popCopyReg(result_hi));
- emitCLRC;
-
- for(i=0; i<8; i++) {
- emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),i,0));
- emitpcode(POC_ADDWF, popCopyReg(result_hi));
- emitpcode(POC_RRF, popCopyReg(result_hi));
- emitpcode(POC_RRF, popGet(AOP(result),0));
- }
-
-
- /*
- Here's another version that does the same thing and takes the
- same number of instructions. The one above is slightly better
- because the entry instructions have a higher probability of
- being optimized out.
- */
- /*
- emitpcode(POC_CLRF, popCopyReg(result_hi));
- emitpcode(POC_RRFW, popGet(AOP(left),0));
- emitpcode(POC_MOVWF, popGet(AOP(result),0));
- emitpcode(POC_MOVFW, popGet(AOP(right),0));
-
- for(i=0; i<8; i++) {
- emitSKPNC;
- emitpcode(POC_ADDWF, popCopyReg(result_hi));
- emitpcode(POC_RRF, popCopyReg(result_hi));
- emitpcode(POC_RRF, popGet(AOP(result),0));
- }
- */
-
- } else {
- symbol *tlbl = newiTempLabel(NULL);
- pCodeOp *temp;
-
-
- pic14_emitcode(";","Looped 8 X 8 multiplication");
-
- emitpcode(POC_CLRF, popGet(AOP(result),0));
- emitpcode(POC_CLRF, popCopyReg(result_hi));
-
- emitpcode(POC_BSF, newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),7,0));
-
- emitpcode(POC_MOVFW, popGet(AOP(right),0));
-
- temp = popGetTempReg();
- emitpcode(POC_MOVWF, popCopyReg(PCOR(temp)));
-
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
-
- emitpLabel(tlbl->key);
-
- emitpcode(POC_RRF, popCopyReg(PCOR(temp)));
- emitSKPNC;
- emitpcode(POC_ADDWF, popCopyReg(result_hi));
-
- emitpcode(POC_RRF, popCopyReg(result_hi));
- emitpcode(POC_RRF, popGet(AOP(result),0));
-
- emitSKPC;
- emitpcode(POC_GOTO, popGetLabel(tlbl->key));
-
- popReleaseTempReg(temp);
-
- }
+
+ int i;
+ int looped = 1;
+
+ FENTRY;
+ if(!result_hi) {
+ result_hi = PCOR(popGet(AOP(result),1));
+ }
+
+ if (AOP_TYPE(right) == AOP_LIT) {
+ genUMult8XLit_16(left,right,result,result_hi);
+ return;
+ }
+
+ if(!looped) {
+ pic14_emitcode(";","Unrolled 8 X 8 multiplication");
+
+ emitpcode(POC_MOVFW, popGet(AOP(right),0));
+ emitpcode(POC_CLRF, popGet(AOP(result),0));
+ emitpcode(POC_CLRF, popCopyReg(result_hi));
+ emitCLRC;
+
+ for(i=0; i<8; i++) {
+ emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),i,0));
+ emitpcode(POC_ADDWF, popCopyReg(result_hi));
+ emitpcode(POC_RRF, popCopyReg(result_hi));
+ emitpcode(POC_RRF, popGet(AOP(result),0));
+ }
+
+
+ /*
+ Here's another version that does the same thing and takes the
+ same number of instructions. The one above is slightly better
+ because the entry instructions have a higher probability of
+ being optimized out.
+ */
+ /*
+ emitpcode(POC_CLRF, popCopyReg(result_hi));
+ emitpcode(POC_RRFW, popGet(AOP(left),0));
+ emitpcode(POC_MOVWF, popGet(AOP(result),0));
+ emitpcode(POC_MOVFW, popGet(AOP(right),0));
+
+ for(i=0; i<8; i++) {
+ emitSKPNC;
+ emitpcode(POC_ADDWF, popCopyReg(result_hi));
+ emitpcode(POC_RRF, popCopyReg(result_hi));
+ emitpcode(POC_RRF, popGet(AOP(result),0));
+ }
+ */
+
+ } else {
+ symbol *tlbl = newiTempLabel(NULL);
+ pCodeOp *temp;
+
+
+ pic14_emitcode(";","Looped 8 X 8 multiplication");
+
+ emitpcode(POC_CLRF, popGet(AOP(result),0));
+ emitpcode(POC_CLRF, popCopyReg(result_hi));
+
+ emitpcode(POC_BSF, newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),7,0));
+
+ emitpcode(POC_MOVFW, popGet(AOP(right),0));
+
+ temp = popGetTempReg();
+ emitpcode(POC_MOVWF, popCopyReg(PCOR(temp)));
+
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+
+ emitpLabel(tlbl->key);
+
+ emitpcode(POC_RRF, popCopyReg(PCOR(temp)));
+ emitSKPNC;
+ emitpcode(POC_ADDWF, popCopyReg(result_hi));
+
+ emitpcode(POC_RRF, popCopyReg(result_hi));
+ emitpcode(POC_RRF, popGet(AOP(result),0));
+
+ emitSKPC;
+ emitpcode(POC_GOTO, popGetLabel(tlbl->key));
+
+ popReleaseTempReg(temp);
+
+ }
}
/*-----------------------------------------------------------------*
* post-fix the sign bit.
*-----------------------------------------------------------------*/
void genSMult8X8_16 (operand *left,
- operand *right,
- operand *result,
- pCodeOpReg *result_hi)
+ operand *right,
+ operand *result,
+ pCodeOpReg *result_hi)
{
-
- FENTRY;
- if(!result_hi) {
- result_hi = PCOR(popGet(AOP(result),1));
- }
-
- genUMult8X8_16(left,right,result,result_hi);
-
- emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),7,0));
- emitpcode(POC_SUBWF, popCopyReg(result_hi));
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
- emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
- emitpcode(POC_SUBWF, popGet(AOP(result),1));
-
+
+ FENTRY;
+ if(!result_hi) {
+ result_hi = PCOR(popGet(AOP(result),1));
+ }
+
+ genUMult8X8_16(left,right,result,result_hi);
+
+ emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),7,0));
+ emitpcode(POC_SUBWF, popCopyReg(result_hi));
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
+ emitpcode(POC_SUBWF, popGet(AOP(result),1));
+
}
/*-----------------------------------------------------------------*
*
*-----------------------------------------------------------------*/
void genMult8X8_8 (operand *left,
- operand *right,
- operand *result)
+ operand *right,
+ operand *result)
{
- pCodeOp *result_hi;
- FENTRY;
- if (result && result->aop && result->aop->type==2 && result->aop->size>=1) {
- result->aop->aopu.aop_reg[0]->isFree = 0; /* Sometimes (ie part of last instruction in a blk) the result reg is pre marked as free, which mean on the next line popGetTempReg() will return this reg instead of allocating a new one. */
- }
- result_hi = popGetTempReg();
-
- if (AOP_TYPE(right) == AOP_LIT)
- genUMult8XLit_16(left,right,result,PCOR(result_hi));
- else
- genUMult8X8_16(left,right,result,PCOR(result_hi));
-
- popReleaseTempReg(result_hi);
+ pCodeOp *result_hi;
+ FENTRY;
+ if (result && result->aop && result->aop->type==2 && result->aop->size>=1) {
+ result->aop->aopu.aop_reg[0]->isFree = 0; /* Sometimes (ie part of last instruction in a blk) the result reg is pre marked as free, which mean on the next line popGetTempReg() will return this reg instead of allocating a new one. */
+ }
+ result_hi = popGetTempReg();
+
+ if (AOP_TYPE(right) == AOP_LIT)
+ genUMult8XLit_16(left,right,result,PCOR(result_hi));
+ else
+ genUMult8X8_16(left,right,result,PCOR(result_hi));
+
+ popReleaseTempReg(result_hi);
}
#if 0
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
void genMultConst(unsigned C)
{
-
- unsigned lit;
- unsigned sr3; // Shift right 3
- unsigned mask;
-
- int size = 1;
-
- /*
- Convert a string of 3 binary 1's in the lit into
- 0111 = 1000 - 1;
- */
-
- mask = 7 << ( (size*8) - 3);
- lit = C;
- sr3 = 0;
-
- while(mask < (1<<size*8)) {
-
- if( (mask & lit) == lit) {
- unsigned lsb;
-
- /* We found 3 (or more) consecutive 1's */
-
- lsb = mask & ~(mask & (mask-1)); // lsb of mask.
-
- consecutive_bits = ((lit + lsb) & lit) ^ lit;
-
- lit ^= consecutive_bits;
-
- mask <<= 3;
-
- sr3 |= (consecutive + lsb);
-
- }
-
- mask >>= 1;
-
- }
-
+
+ unsigned lit;
+ unsigned sr3; // Shift right 3
+ unsigned mask;
+
+ int size = 1;
+
+ /*
+ Convert a string of 3 binary 1's in the lit into
+ 0111 = 1000 - 1;
+ */
+
+ mask = 7 << ( (size*8) - 3);
+ lit = C;
+ sr3 = 0;
+
+ while(mask < (1<<size*8)) {
+
+ if( (mask & lit) == lit) {
+ unsigned lsb;
+
+ /* We found 3 (or more) consecutive 1's */
+
+ lsb = mask & ~(mask & (mask-1)); // lsb of mask.
+
+ consecutive_bits = ((lit + lsb) & lit) ^ lit;
+
+ lit ^= consecutive_bits;
+
+ mask <<= 3;
+
+ sr3 |= (consecutive + lsb);
+
+ }
+
+ mask >>= 1;
+
+ }
+
}
#endif
#endif
#define BYTE_IN_LONG(x,b) ((x>>(8*_ENDIAN(b)))&0xff)
-#define IS_GLOBAL(sym) ((sym)->level == 0)
+#define IS_GLOBAL(sym) ((sym)->level == 0)
extern symbol *interrupts[256];
static void showAllMemmaps(FILE *of); // XXX: emits initialized symbols
int getHasSecondConfigReg(void);
void pic14_debugLogClose(void); // from ralloc.c
-char *udata_section_name=0; // FIXME Temporary fix to change udata section name -- VR
-int pic14_hasInterrupt = 0; // Indicates whether to emit interrupt handler or not
+char *udata_section_name=0; // FIXME Temporary fix to change udata section name -- VR
+int pic14_hasInterrupt = 0; // Indicates whether to emit interrupt handler or not
/* dbufs for initialized data (idata and code sections),
* extern, and global declarations */
/*-----------------------------------------------------------------*/
unsigned int pic14aopLiteral (value *val, int offset)
{
- union {
- float f;
- unsigned char c[4];
- } fl;
-
- /* if it is a float then it gets tricky */
- /* otherwise it is fairly simple */
- if (!IS_FLOAT(val->type)) {
- unsigned long v = (unsigned long) floatFromVal(val);
-
- return ( (v >> (offset * 8)) & 0xff);
- }
-
- /* it is type float */
- fl.f = (float) floatFromVal(val);
+ union {
+ float f;
+ unsigned char c[4];
+ } fl;
+
+ /* if it is a float then it gets tricky */
+ /* otherwise it is fairly simple */
+ if (!IS_FLOAT(val->type)) {
+ unsigned long v = ulFromVal (val);
+
+ return ( (v >> (offset * 8)) & 0xff);
+ }
+
+ /* it is type float */
+ fl.f = (float) floatFromVal(val);
#ifdef WORDS_BIGENDIAN
- return fl.c[3-offset];
+ return fl.c[3-offset];
#else
- return fl.c[offset];
+ return fl.c[offset];
#endif
-
+
}
#if 0
/* only accept [a-zA-Z_][a-zA-Z0-9_] */
if (!((a >= 'a' && a <= 'z')
- || (a >= 'A' && a <= 'z')
- || (a == '_')))
+ || (a >= 'A' && a <= 'z')
+ || (a == '_')))
return 0;
name++;
while ((a = *name++))
{
if (!((a >= 'a' && a <= 'z')
- || (a >= 'A' && a <= 'Z')
- || (a >= '0' && a <= '9')
- || (a == '_')))
+ || (a >= 'A' && a <= 'Z')
+ || (a >= '0' && a <= '9')
+ || (a == '_')))
return 0;
} // while
shared = pic14_getSharedStack(&low, &high, &size);
if (!pic14_options.isLibrarySource)
{
- pic = pic14_getPIC();
-
- dbuf_printf (oBuf, "\n");
- dbuf_printf (oBuf, "\tglobal PSAVE\n");
- dbuf_printf (oBuf, "\tglobal SSAVE\n");
- dbuf_printf (oBuf, "\tglobal WSAVE\n");
- for (i = size - 4; i >= 0; i--) {
- dbuf_printf (oBuf, "\tglobal STK%02d\n", i);
- } // for i
- dbuf_printf (oBuf, "\n");
-
- // 16f84 has no SHAREBANK (in linkerscript) but memory aliased in two
- // banks, sigh...
- if (1 || !shared) {
- // for single banked devices: use normal, "banked" RAM
- dbuf_printf (oBuf, "sharebank udata_ovr 0x%04X\n", low);
- } else {
- // for devices with at least two banks, require a sharebank section
- dbuf_printf (oBuf, "sharebank udata_shr\n");
- }
- dbuf_printf (oBuf, "PSAVE\tres 1\n");
- dbuf_printf (oBuf, "SSAVE\tres 1\n");
- dbuf_printf (oBuf, "WSAVE\tres 1\n"); // WSAVE *must* be in sharebank (IRQ handlers)
- /* fill rest of sharebank with stack STKxx .. STK00 */
- for (i = size - 4; i >= 0; i--) {
- dbuf_printf (oBuf, "STK%02d\tres 1\n", i);
- } // for i
+ pic = pic14_getPIC();
+
+ dbuf_printf (oBuf, "\n");
+ dbuf_printf (oBuf, "\tglobal PSAVE\n");
+ dbuf_printf (oBuf, "\tglobal SSAVE\n");
+ dbuf_printf (oBuf, "\tglobal WSAVE\n");
+ for (i = size - 4; i >= 0; i--) {
+ dbuf_printf (oBuf, "\tglobal STK%02d\n", i);
+ } // for i
+ dbuf_printf (oBuf, "\n");
+
+ // 16f84 has no SHAREBANK (in linkerscript) but memory aliased in two
+ // banks, sigh...
+ if (1 || !shared) {
+ // for single banked devices: use normal, "banked" RAM
+ dbuf_printf (oBuf, "sharebank udata_ovr 0x%04X\n", low);
+ } else {
+ // for devices with at least two banks, require a sharebank section
+ dbuf_printf (oBuf, "sharebank udata_shr\n");
+ }
+ dbuf_printf (oBuf, "PSAVE\tres 1\n");
+ dbuf_printf (oBuf, "SSAVE\tres 1\n");
+ dbuf_printf (oBuf, "WSAVE\tres 1\n"); // WSAVE *must* be in sharebank (IRQ handlers)
+ /* fill rest of sharebank with stack STKxx .. STK00 */
+ for (i = size - 4; i >= 0; i--) {
+ dbuf_printf (oBuf, "STK%02d\tres 1\n", i);
+ } // for i
} else {
- /* declare STKxx as extern for all files
- * except the one containing main() */
- dbuf_printf (oBufExt, "\n");
- dbuf_printf (oBufExt, "\textern PSAVE\n");
- dbuf_printf (oBufExt, "\textern SSAVE\n");
- dbuf_printf (oBufExt, "\textern WSAVE\n");
- for (i = size - 4; i >= 0; i--) {
- char buffer[128];
- SNPRINTF(&buffer[0], 127, "STK%02d", i);
- dbuf_printf (oBufExt, "\textern %s\n", &buffer[0]);
- pic14_stringInSet(&buffer[0], &emitted, 1);
- } // for i
+ /* declare STKxx as extern for all files
+ * except the one containing main() */
+ dbuf_printf (oBufExt, "\n");
+ dbuf_printf (oBufExt, "\textern PSAVE\n");
+ dbuf_printf (oBufExt, "\textern SSAVE\n");
+ dbuf_printf (oBufExt, "\textern WSAVE\n");
+ for (i = size - 4; i >= 0; i--) {
+ char buffer[128];
+ SNPRINTF(&buffer[0], 127, "STK%02d", i);
+ dbuf_printf (oBufExt, "\textern %s\n", &buffer[0]);
+ pic14_stringInSet(&buffer[0], &emitted, 1);
+ } // for i
}
dbuf_printf (oBuf, "\n");
}
static int
emitIfNew(struct dbuf_s *oBuf, set **emitted, const char *fmt,
- const char *name)
+ const char *name)
{
int wasPresent = pic14_stringInSet(name, emitted, 1);
if (!wasPresent) {
- dbuf_printf (oBuf, fmt, name);
+ dbuf_printf (oBuf, fmt, name);
} // if
return (!wasPresent);
}
-#define IS_DEFINED_HERE(sym) (!IS_EXTERN(sym->etype))
+#define IS_DEFINED_HERE(sym) (!IS_EXTERN(sym->etype))
extern int IS_CONFIG_ADDRESS( int addr );
static void
pic14_constructAbsMap (struct dbuf_s *oBuf, struct dbuf_s *gloBuf)
for (i=0; maps[i] != NULL; i++)
{
for (sym = (symbol *)setFirstItem (maps[i]->syms);
- sym; sym = setNextItem (maps[i]->syms))
+ sym; sym = setNextItem (maps[i]->syms))
{
if (IS_DEFINED_HERE(sym) && SPEC_ABSA(sym->etype))
{
- addr = SPEC_ADDR(sym->etype);
-
- /* handle CONFIG words here */
- if (IS_CONFIG_ADDRESS( addr ))
- {
- //fprintf( stderr, "%s: assignment to CONFIG@0x%x found\n", __FUNCTION__, addr );
- //fprintf( stderr, "ival: %p (0x%x)\n", sym->ival, (int)list2int( sym->ival ) );
- if (sym->ival) {
- pic14_assignConfigWordValue( addr, (int)list2int( sym->ival ) );
- } else {
- fprintf( stderr, "ERROR: Symbol %s, which is covering a __CONFIG word must be initialized!\n", sym->name );
- }
- continue;
- }
-
- if (max == -1 || addr > max) max = addr;
- if (min == -1 || addr < min) min = addr;
- //fprintf (stderr, "%s: sym %s @ 0x%x\n", __FUNCTION__, sym->name, addr);
- aliases = hTabItemWithKey (ht, addr);
- if (aliases) {
- /* May not use addSetHead, as we cannot update the
- * list's head in the hastable `ht'. */
- addSet (&aliases, sym);
+ addr = SPEC_ADDR(sym->etype);
+
+ /* handle CONFIG words here */
+ if (IS_CONFIG_ADDRESS( addr ))
+ {
+ //fprintf( stderr, "%s: assignment to CONFIG@0x%x found\n", __FUNCTION__, addr );
+ //fprintf( stderr, "ival: %p (0x%x)\n", sym->ival, (int)list2int( sym->ival ) );
+ if (sym->ival) {
+ pic14_assignConfigWordValue( addr, (int)list2int( sym->ival ) );
+ } else {
+ fprintf( stderr, "ERROR: Symbol %s, which is covering a __CONFIG word must be initialized!\n", sym->name );
+ }
+ continue;
+ }
+
+ if (max == -1 || addr > max) max = addr;
+ if (min == -1 || addr < min) min = addr;
+ //fprintf (stderr, "%s: sym %s @ 0x%x\n", __FUNCTION__, sym->name, addr);
+ aliases = hTabItemWithKey (ht, addr);
+ if (aliases) {
+ /* May not use addSetHead, as we cannot update the
+ * list's head in the hastable `ht'. */
+ addSet (&aliases, sym);
#if 0
- fprintf( stderr, "%s: now %d aliases for %s @ 0x%x\n",
- __FUNCTION__, elementsInSet(aliases), sym->name, addr);
+ fprintf( stderr, "%s: now %d aliases for %s @ 0x%x\n",
+ __FUNCTION__, elementsInSet(aliases), sym->name, addr);
#endif
- } else {
- addSet (&aliases, sym);
- hTabAddItem (&ht, addr, aliases);
- } // if
+ } else {
+ addSet (&aliases, sym);
+ hTabAddItem (&ht, addr, aliases);
+ } // if
} // if
} // for sym
} // for i
if (aliases && elementsInSet(aliases)) {
/* Make sure there is no initialized value at this location! */
for (sym = setFirstItem(aliases); sym; sym = setNextItem(aliases)) {
- if (sym->ival) break;
+ if (sym->ival) break;
} // for
if (sym) continue;
dbuf_printf (oBuf, "UD_abs_%s_%x\tudata_ovr\t0x%04x\n",
- moduleName, addr, addr);
+ moduleName, addr, addr);
for (sym = setFirstItem (aliases); sym;
- sym = setNextItem (aliases))
+ sym = setNextItem (aliases))
{
- if (getSize(sym->type) > size) {
- size = getSize(sym->type);
- }
-
- /* initialized values are handled somewhere else */
- if (sym->ival) continue;
-
+ if (getSize(sym->type) > size) {
+ size = getSize(sym->type);
+ }
+
+ /* initialized values are handled somewhere else */
+ if (sym->ival) continue;
+
/* emit STATUS as well as _STATUS, required for SFRs only */
- //dbuf_printf (oBuf, "%s\tres\t0\n", sym->name);
- dbuf_printf (oBuf, "%s\n", sym->rname);
+ //dbuf_printf (oBuf, "%s\tres\t0\n", sym->name);
+ dbuf_printf (oBuf, "%s\n", sym->rname);
- if (IS_GLOBAL(sym) && !IS_STATIC(sym->etype)) {
- //emitIfNew(gloBuf, &emitted, "\tglobal\t%s\n", sym->name);
- emitIfNew(gloBuf, &emitted, "\tglobal\t%s\n", sym->rname);
- } // if
+ if (IS_GLOBAL(sym) && !IS_STATIC(sym->etype)) {
+ //emitIfNew(gloBuf, &emitted, "\tglobal\t%s\n", sym->name);
+ emitIfNew(gloBuf, &emitted, "\tglobal\t%s\n", sym->rname);
+ } // if
} // for
dbuf_printf (oBuf, "\tres\t%d\n", size);
} // if
static void
pic14emitRegularMap (memmap * map, bool addPublics, bool arFlag)
{
- symbol *sym;
- int bitvars = 0;;
-
- /* print the area name */
- if (addPublics)
- dbuf_printf (&map->oBuf, ";\t.area\t%s\n", map->sname);
-
- for (sym = setFirstItem (map->syms); sym;
- sym = setNextItem (map->syms)) {
-
- //printf("%s\n",sym->name);
-
- /* ignore if config word */
- if (SPEC_ABSA(sym->etype)
- && IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype)))
- continue;
-
- /* if extern then add it into the extern list */
- if (IS_EXTERN (sym->etype)) {
- addSetHead (&externs, sym);
- continue;
- }
-
- /* if allocation required check is needed
- then check if the symbol really requires
- allocation only for local variables */
- if (arFlag && !IS_AGGREGATE (sym->type) &&
- !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
- !sym->allocreq && sym->level)
- continue;
-
- /* if global variable & not static or extern
- and addPublics allowed then add it to the public set */
- if ((sym->level == 0 ||
- (sym->_isparm && !IS_REGPARM (sym->etype))) &&
- addPublics &&
- !IS_STATIC (sym->etype))
- {
- //fprintf( stderr, "%s: made public %s\n", __FUNCTION__, sym->name );
- addSetHead (&publics, sym);
- }
-
- // PIC code allocates its own registers - so ignore parameter variable generated by processFuncArgs()
- if (sym->_isparm)
- continue;
- /* if extern then do nothing or is a function
- then do nothing */
- if (IS_FUNC (sym->type))
- continue;
+ symbol *sym;
+ int bitvars = 0;;
+
+ /* print the area name */
+ if (addPublics)
+ dbuf_printf (&map->oBuf, ";\t.area\t%s\n", map->sname);
+
+ for (sym = setFirstItem (map->syms); sym;
+ sym = setNextItem (map->syms)) {
+
+ //printf("%s\n",sym->name);
+
+ /* ignore if config word */
+ if (SPEC_ABSA(sym->etype)
+ && IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype)))
+ continue;
+
+ /* if extern then add it into the extern list */
+ if (IS_EXTERN (sym->etype)) {
+ addSetHead (&externs, sym);
+ continue;
+ }
+
+ /* if allocation required check is needed
+ then check if the symbol really requires
+ allocation only for local variables */
+ if (arFlag && !IS_AGGREGATE (sym->type) &&
+ !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
+ !sym->allocreq && sym->level)
+ continue;
+
+ /* if global variable & not static or extern
+ and addPublics allowed then add it to the public set */
+ if ((sym->level == 0 ||
+ (sym->_isparm && !IS_REGPARM (sym->etype))) &&
+ addPublics &&
+ !IS_STATIC (sym->etype))
+ {
+ //fprintf( stderr, "%s: made public %s\n", __FUNCTION__, sym->name );
+ addSetHead (&publics, sym);
+ }
+
+ // PIC code allocates its own registers - so ignore parameter variable generated by processFuncArgs()
+ if (sym->_isparm)
+ continue;
+ /* if extern then do nothing or is a function
+ then do nothing */
+ if (IS_FUNC (sym->type))
+ continue;
#if 0
- /* print extra debug info if required */
- if (options.debug || sym->level == 0)
- {
- if (!sym->level) /* global */
- if (IS_STATIC (sym->etype))
- dbuf_printf (&map->oBuf, "F%s_", moduleName); /* scope is file */
- else
- dbuf_printf (&map->oBuf, "G_"); /* scope is global */
- else
- /* symbol is local */
- dbuf_printf (&map->oBuf, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
- dbuf_printf (&map->oBuf, "%s_%d_%d", sym->name, sym->level, sym->block);
- }
+ /* print extra debug info if required */
+ if (options.debug || sym->level == 0)
+ {
+ if (!sym->level) /* global */
+ if (IS_STATIC (sym->etype))
+ dbuf_printf (&map->oBuf, "F%s_", moduleName); /* scope is file */
+ else
+ dbuf_printf (&map->oBuf, "G_"); /* scope is global */
+ else
+ /* symbol is local */
+ dbuf_printf (&map->oBuf, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
+ dbuf_printf (&map->oBuf, "%s_%d_%d", sym->name, sym->level, sym->block);
+ }
#endif
- /* absolute symbols are handled in pic14_constructAbsMap */
- if (SPEC_ABSA(sym->etype) && IS_DEFINED_HERE(sym))
- continue;
-
- /* if it has an absolute address then generate
- an equate for this no need to allocate space */
- if (0 && SPEC_ABSA (sym->etype))
- {
- //if (options.debug || sym->level == 0)
- //dbuf_printf (&map->oBuf,"; == 0x%04x\n",SPEC_ADDR (sym->etype));
-
- dbuf_printf (&map->oBuf, "%s\tEQU\t0x%04x\n",
- sym->rname,
- SPEC_ADDR (sym->etype));
- }
- else
- {
- /* allocate space */
-
- /* If this is a bit variable, then allocate storage after 8 bits have been declared */
- /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
- /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
- if (IS_BITVAR (sym->etype))
- {
- bitvars++;
- }
- else
- {
- if (!sym->ival) {
- emitSymbol (&map->oBuf,
- sym->rname,
- NULL,
- getSize (sym->type) & 0xffff,
- SPEC_ABSA(sym->etype)
- ? SPEC_ADDR(sym->etype)
- : -1,
- 0,
- 0);
- }
- /*
- {
- int i, size;
-
- if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1)
- {
- for (i = 1; i < size; i++)
- dbuf_printf (&map->oBuf, "\t%s_%d\n", sym->rname, i);
- }
- }
- */
- }
- //dbuf_printf (&map->oBuf, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
- }
-
- /* if it has a initial value then do it only if
- it is a global variable */
- if (sym->ival) {
- /* mark symbol as already defined */
- pic14_stringInSet(sym->name, &emitted, 1);
- pic14_stringInSet(sym->rname, &emitted, 1);
- }
-#if 0
- /* if it has a initial value then do it only if
- it is a global variable */
- if (sym->ival && sym->level == 0) {
- ast *ival = NULL;
-
- if (IS_AGGREGATE (sym->type))
- ival = initAggregates (sym, sym->ival, NULL);
- else
- ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
- decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_TYPE_NONE));
- codeOutBuf = &statsg->oBuf;
- GcurMemmap = statsg;
- eBBlockFromiCode (iCodeFromAst (ival));
- sym->ival = NULL;
- }
+ /* absolute symbols are handled in pic14_constructAbsMap */
+ if (SPEC_ABSA(sym->etype) && IS_DEFINED_HERE(sym))
+ continue;
+
+ /* if it has an absolute address then generate
+ an equate for this no need to allocate space */
+ if (0 && SPEC_ABSA (sym->etype))
+ {
+ //if (options.debug || sym->level == 0)
+ //dbuf_printf (&map->oBuf,"; == 0x%04x\n",SPEC_ADDR (sym->etype));
+
+ dbuf_printf (&map->oBuf, "%s\tEQU\t0x%04x\n",
+ sym->rname,
+ SPEC_ADDR (sym->etype));
+ }
+ else
+ {
+ /* allocate space */
+
+ /* If this is a bit variable, then allocate storage after 8 bits have been declared */
+ /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
+ /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
+ if (IS_BITVAR (sym->etype))
+ {
+ bitvars++;
+ }
+ else
+ {
+ if (!sym->ival) {
+ emitSymbol (&map->oBuf,
+ sym->rname,
+ NULL,
+ getSize (sym->type) & 0xffff,
+ SPEC_ABSA(sym->etype)
+ ? SPEC_ADDR(sym->etype)
+ : -1,
+ 0,
+ 0);
+ }
+ /*
+ {
+ int i, size;
+
+ if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1)
+ {
+ for (i = 1; i < size; i++)
+ dbuf_printf (&map->oBuf, "\t%s_%d\n", sym->rname, i);
+ }
+ }
+ */
+ }
+ //dbuf_printf (&map->oBuf, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
+ }
+
+ /* if it has a initial value then do it only if
+ it is a global variable */
+ if (sym->ival) {
+ /* mark symbol as already defined */
+ pic14_stringInSet(sym->name, &emitted, 1);
+ pic14_stringInSet(sym->rname, &emitted, 1);
+ }
+#if 0
+ /* if it has a initial value then do it only if
+ it is a global variable */
+ if (sym->ival && sym->level == 0) {
+ ast *ival = NULL;
+
+ if (IS_AGGREGATE (sym->type))
+ ival = initAggregates (sym, sym->ival, NULL);
+ else
+ ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
+ decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_TYPE_NONE));
+ codeOutBuf = &statsg->oBuf;
+ GcurMemmap = statsg;
+ eBBlockFromiCode (iCodeFromAst (ival));
+ sym->ival = NULL;
+ }
#endif
- }
+ }
}
#endif
static void
printIvalType (symbol *sym, sym_link * type, initList * ilist, pBlock *pb)
{
- value *val;
- unsigned long ulval;
-
- //fprintf(stderr, "%s\n",__FUNCTION__);
-
- /* if initList is deep */
- if (ilist->type == INIT_DEEP)
- ilist = ilist->init.deep;
-
- if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
- werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
- }
-
- if (!(val = list2val (ilist))) {
- // assuming a warning has been thrown
- val=constVal("0");
- }
-
- if (val->type != type) {
- val = valCastLiteral(type, floatFromVal(val));
- }
-
- if(val)
- ulval = (unsigned long) floatFromVal (val);
- else
- ulval =0;
-
- switch (getSize (type)) {
- case 1:
- addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
- break;
-
- case 2:
- addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
- addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
- break;
-
- case 4:
- addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
- addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
- addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,2))));
- addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,3))));
- break;
- }
+ value *val;
+ unsigned long ulval;
+
+ //fprintf(stderr, "%s\n",__FUNCTION__);
+
+ /* if initList is deep */
+ if (ilist->type == INIT_DEEP)
+ ilist = ilist->init.deep;
+
+ if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
+ werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
+ }
+
+ if (!(val = list2val (ilist))) {
+ // assuming a warning has been thrown
+ val=constVal("0");
+ }
+
+ if (val->type != type) {
+ val = valCastLiteral(type, floatFromVal(val));
+ }
+
+ if(val)
+ ulval = ulFromVal (val);
+ else
+ ulval =0;
+
+ switch (getSize (type)) {
+ case 1:
+ addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
+ break;
+
+ case 2:
+ addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
+ addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
+ break;
+
+ case 4:
+ addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
+ addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
+ addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,2))));
+ addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,3))));
+ break;
+ }
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static void printIvalBitFields(symbol **sym, initList **ilist, pBlock *pb )
{
- value *val ;
- symbol *lsym = *sym;
- initList *lilist = *ilist ;
- unsigned long ival = 0;
- int size =0;
-
-
- do {
- unsigned long i;
- val = list2val(lilist);
- if (size) {
- if (SPEC_BLEN(lsym->etype) > 8) {
- size += ((SPEC_BLEN (lsym->etype) / 8) +
- (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
- }
- } else {
- size = ((SPEC_BLEN (lsym->etype) / 8) +
- (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
- }
- i = (unsigned long)floatFromVal(val);
- i <<= SPEC_BSTR (lsym->etype);
- ival |= i;
- if (! ( lsym->next &&
- (IS_BITFIELD(lsym->next->type)) &&
- (SPEC_BSTR(lsym->next->etype)))) break;
- lsym = lsym->next;
- lilist = lilist->next;
- } while (1);
- switch (size) {
- case 1:
- //tfprintf (oFile, "\t!db !constbyte\n",ival);
- addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival)));
- break;
-
- case 2:
- //tfprintf (oFile, "\t!dw !constword\n",ival);
- addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival>>8)));
- addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival)));
- break;
- case 4:
- //tfprintf (oFile, "\t!db !constword,!constword\n",(ival >> 8) & 0xffff, (ival & 0xffff));
- addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival>>24)));
- addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival>>16)));
- addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival>>8)));
- addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival)));
- break;
- }
- *sym = lsym;
- *ilist = lilist;
+ value *val ;
+ symbol *lsym = *sym;
+ initList *lilist = *ilist ;
+ unsigned long ival = 0;
+ int size =0;
+
+
+ do {
+ unsigned long i;
+ val = list2val(lilist);
+ if (size) {
+ if (SPEC_BLEN(lsym->etype) > 8) {
+ size += ((SPEC_BLEN (lsym->etype) / 8) +
+ (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
+ }
+ } else {
+ size = ((SPEC_BLEN (lsym->etype) / 8) +
+ (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
+ }
+ i = ulFromVal (val);
+ i <<= SPEC_BSTR (lsym->etype);
+ ival |= i;
+ if (! ( lsym->next &&
+ (IS_BITFIELD(lsym->next->type)) &&
+ (SPEC_BSTR(lsym->next->etype)))) break;
+ lsym = lsym->next;
+ lilist = lilist->next;
+ } while (1);
+ switch (size) {
+ case 1:
+ //tfprintf (oFile, "\t!db !constbyte\n",ival);
+ addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival)));
+ break;
+
+ case 2:
+ //tfprintf (oFile, "\t!dw !constword\n",ival);
+ addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival>>8)));
+ addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival)));
+ break;
+ case 4:
+ //tfprintf (oFile, "\t!db !constword,!constword\n",(ival >> 8) & 0xffff, (ival & 0xffff));
+ addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival>>24)));
+ addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival>>16)));
+ addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival>>8)));
+ addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival)));
+ break;
+ }
+ *sym = lsym;
+ *ilist = lilist;
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static void printIvalStruct (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
{
- symbol *sflds;
- initList *iloop = NULL;
-
- sflds = SPEC_STRUCT (type)->fields;
-
- if (ilist) {
- if (ilist->type != INIT_DEEP) {
- werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
- return;
- }
-
- iloop = ilist->init.deep;
- }
-
- for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
- if (IS_BITFIELD(sflds->type)) {
- printIvalBitFields(&sflds,&iloop,pb);
- } else {
- printIval (sym, sflds->type, iloop, pb);
- }
- }
- if (iloop) {
- werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
- }
- return;
+ symbol *sflds;
+ initList *iloop = NULL;
+
+ sflds = SPEC_STRUCT (type)->fields;
+
+ if (ilist) {
+ if (ilist->type != INIT_DEEP) {
+ werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
+ return;
+ }
+
+ iloop = ilist->init.deep;
+ }
+
+ for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
+ if (IS_BITFIELD(sflds->type)) {
+ printIvalBitFields(&sflds,&iloop,pb);
+ } else {
+ printIval (sym, sflds->type, iloop, pb);
+ }
+ }
+ if (iloop) {
+ werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
+ }
+ return;
}
/*-----------------------------------------------------------------*/
static int
printIvalChar (sym_link * type, initList * ilist, pBlock *pb, char *s)
{
- value *val;
- int remain, ilen;
-
- if(!pb)
- return 0;
-
- //fprintf(stderr, "%s\n",__FUNCTION__);
- if (!s)
- {
-
- val = list2val (ilist);
-
- /* if the value is a character string */
- if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
- {
- ilen = DCL_ELEM(val->type);
-
- if (!DCL_ELEM (type))
- DCL_ELEM (type) = ilen;
-
- /* emit string constant */
- for (remain = 0; remain < ilen; remain++) {
- addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(SPEC_CVAL(val->etype).v_char[remain])));
- }
-
- /* fill array up to desired size */
- if ((remain = (DCL_ELEM (type) - ilen)) > 0)
- while (remain--)
- //tfprintf (oFile, "\t!db !constbyte\n", 0);
- addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(0)));
- return 1;
- }
- else
- return 0;
- }
- else {
- //printChar (oFile, s, strlen (s) + 1);
-
- for(remain=0; remain<(int)strlen(s); remain++) {
- addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(s[remain])));
- //fprintf(stderr,"0x%02x ",s[remain]);
- }
- //fprintf(stderr,"\n");
- }
- return 1;
+ value *val;
+ int remain, ilen;
+
+ if(!pb)
+ return 0;
+
+ //fprintf(stderr, "%s\n",__FUNCTION__);
+ if (!s)
+ {
+
+ val = list2val (ilist);
+
+ /* if the value is a character string */
+ if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
+ {
+ ilen = DCL_ELEM(val->type);
+
+ if (!DCL_ELEM (type))
+ DCL_ELEM (type) = ilen;
+
+ /* emit string constant */
+ for (remain = 0; remain < ilen; remain++) {
+ addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(SPEC_CVAL(val->etype).v_char[remain])));
+ }
+
+ /* fill array up to desired size */
+ if ((remain = (DCL_ELEM (type) - ilen)) > 0)
+ while (remain--)
+ //tfprintf (oFile, "\t!db !constbyte\n", 0);
+ addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(0)));
+ return 1;
+ }
+ else
+ return 0;
+ }
+ else {
+ //printChar (oFile, s, strlen (s) + 1);
+
+ for(remain=0; remain<(int)strlen(s); remain++) {
+ addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(s[remain])));
+ //fprintf(stderr,"0x%02x ",s[remain]);
+ }
+ //fprintf(stderr,"\n");
+ }
+ return 1;
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static void
printIvalArray (symbol * sym, sym_link * type, initList * ilist,
- pBlock *pb)
+ pBlock *pb)
{
- initList *iloop;
- unsigned size = 0;
-
- if(!pb)
- return;
- if (ilist) {
- /* take care of the special case */
- /* array of characters can be init */
- /* by a string */
- if (IS_CHAR (type->next)) {
- //fprintf(stderr,"%s:%d - is_char\n",__FUNCTION__,__LINE__);
- if (!IS_LITERAL(list2val(ilist)->etype)) {
- werror (W_INIT_WRONG);
- return;
- }
- if (printIvalChar (type,
- (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
- pb, SPEC_CVAL (sym->etype).v_char))
- return;
- }
- /* not the special case */
- if (ilist->type != INIT_DEEP) {
- werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
- return;
- }
-
- for (iloop=ilist->init.deep; iloop; iloop=iloop->next) {
- if ((++size > DCL_ELEM(type)) && DCL_ELEM(type)) {
- werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "array", sym->name);
- break;
- }
- printIval (sym, type->next, iloop, pb);
- }
- }
-
- if (DCL_ELEM(type)) {
- // pad with zeros if needed
- if (size<DCL_ELEM(type)) {
- size = (DCL_ELEM(type) - size) * getSize(type->next);
- while (size--) {
- //tfprintf (oFile, "\t!db !constbyte\n", 0);
- addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(0)));
- }
- }
- } else {
- // we have not been given a size, but we now know it
- DCL_ELEM (type) = size;
- }
-
- return;
+ initList *iloop;
+ unsigned size = 0;
+
+ if(!pb)
+ return;
+ if (ilist) {
+ /* take care of the special case */
+ /* array of characters can be init */
+ /* by a string */
+ if (IS_CHAR (type->next)) {
+ //fprintf(stderr,"%s:%d - is_char\n",__FUNCTION__,__LINE__);
+ if (!IS_LITERAL(list2val(ilist)->etype)) {
+ werror (W_INIT_WRONG);
+ return;
+ }
+ if (printIvalChar (type,
+ (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
+ pb, SPEC_CVAL (sym->etype).v_char))
+ return;
+ }
+ /* not the special case */
+ if (ilist->type != INIT_DEEP) {
+ werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
+ return;
+ }
+
+ for (iloop=ilist->init.deep; iloop; iloop=iloop->next) {
+ if ((++size > DCL_ELEM(type)) && DCL_ELEM(type)) {
+ werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "array", sym->name);
+ break;
+ }
+ printIval (sym, type->next, iloop, pb);
+ }
+ }
+
+ if (DCL_ELEM(type)) {
+ // pad with zeros if needed
+ if (size<DCL_ELEM(type)) {
+ size = (DCL_ELEM(type) - size) * getSize(type->next);
+ while (size--) {
+ //tfprintf (oFile, "\t!db !constbyte\n", 0);
+ addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(0)));
+ }
+ }
+ } else {
+ // we have not been given a size, but we now know it
+ DCL_ELEM (type) = size;
+ }
+
+ return;
}
/*-----------------------------------------------------------------*/
static void
printIvalPtr (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
{
- value *val;
-
- if (!ilist || !pb)
- return;
-
- fprintf (stderr, "FIXME: initializers for pointers...\n");
- printTypeChain (type, stderr);
-
- fprintf (stderr, "symbol: %s, DCL_TYPE():%d, DCL_ELEM():%d, IS_ARRAY():%d", sym->rname, DCL_TYPE(type), DCL_ELEM(type), IS_ARRAY(type));
- fprintf (stderr, "ilist: type=%d (INIT_DEEP=%d, INIT_NODE=%d)\n", ilist->type, INIT_DEEP, INIT_NODE);
-
- if (ilist && (ilist->type == INIT_DEEP))
- ilist = ilist->init.deep;
-
- /* function pointers */
- if (IS_FUNC (type->next))
- {
- assert ( !"function pointers not yet handled" );
- //printIvalFuncPtr (type, ilist, pb);
- }
-
- if (!(val = initPointer (ilist, type)))
- return;
-
- if (IS_CHAR (type->next))
- {
- if (printIvalChar (type, ilist, pb, NULL)) return;
- }
-
- /* check the type */
- if (compareType (type, val->type) == 0)
- {
- werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
- printFromToType (val->type, type);
- }
-
- if (IS_LITERAL (val->etype))
- {
- switch (getSize (type))
- {
- case 1:
- fprintf (stderr, "BYTE: %i\n", (unsigned char)floatFromVal (val) & 0x00FF);
- break;
- case 2:
- fprintf (stderr, "WORD: %i\n", (unsigned int)floatFromVal (val) & 0x00FFFF);
- break;
- case 3: /* gneric pointers */
- assert ( !"generic pointers not yet handled" );
- case 4:
- fprintf (stderr, "LONG: %i\n", (unsigned int)floatFromVal (val) & 0x0000FFFFFFFF);
- break;
- default:
- assert ( !"invaild size of value -- aborting" );
- } // switch
-
- return;
- } // if (IS_LITERAL)
-
- /* now handle symbolic values */
- switch (getSize (type))
- {
- case 1:
- fprintf (stderr, "BYTE: %s", val->name);
- break;
- case 2:
- fprintf (stderr, "WORD: %s", val->name);
- break;
- case 4:
- fprintf (stderr, "LONG: %s", val->name);
- break;
- default:
- assert ( !"invalid size of (symbolic) value -- aborting" );
- } // switch
+ value *val;
+
+ if (!ilist || !pb)
+ return;
+
+ fprintf (stderr, "FIXME: initializers for pointers...\n");
+ printTypeChain (type, stderr);
+
+ fprintf (stderr, "symbol: %s, DCL_TYPE():%d, DCL_ELEM():%d, IS_ARRAY():%d", sym->rname, DCL_TYPE(type), DCL_ELEM(type), IS_ARRAY(type));
+ fprintf (stderr, "ilist: type=%d (INIT_DEEP=%d, INIT_NODE=%d)\n", ilist->type, INIT_DEEP, INIT_NODE);
+
+ if (ilist && (ilist->type == INIT_DEEP))
+ ilist = ilist->init.deep;
+
+ /* function pointers */
+ if (IS_FUNC (type->next))
+ {
+ assert ( !"function pointers not yet handled" );
+ //printIvalFuncPtr (type, ilist, pb);
+ }
+
+ if (!(val = initPointer (ilist, type)))
+ return;
+
+ if (IS_CHAR (type->next))
+ {
+ if (printIvalChar (type, ilist, pb, NULL)) return;
+ }
+
+ /* check the type */
+ if (compareType (type, val->type) == 0)
+ {
+ werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
+ printFromToType (val->type, type);
+ }
+
+ if (IS_LITERAL (val->etype))
+ {
+ switch (getSize (type))
+ {
+ case 1:
+ fprintf (stderr, "BYTE: %i\n", (unsigned char) ulFromVal (val) & 0x00FF);
+ break;
+ case 2:
+ fprintf (stderr, "WORD: %i\n", (unsigned int) ulFromVal (val) & 0x00FFFF);
+ break;
+ case 3: /* gneric pointers */
+ assert ( !"generic pointers not yet handled" );
+ case 4:
+ fprintf (stderr, "LONG: %i\n", (unsigned int) ulFromVal (val) & 0x0000FFFFFFFF);
+ break;
+ default:
+ assert ( !"invaild size of value -- aborting" );
+ } // switch
+
+ return;
+ } // if (IS_LITERAL)
+
+ /* now handle symbolic values */
+ switch (getSize (type))
+ {
+ case 1:
+ fprintf (stderr, "BYTE: %s", val->name);
+ break;
+ case 2:
+ fprintf (stderr, "WORD: %s", val->name);
+ break;
+ case 4:
+ fprintf (stderr, "LONG: %s", val->name);
+ break;
+ default:
+ assert ( !"invalid size of (symbolic) value -- aborting" );
+ } // switch
}
/*-----------------------------------------------------------------*/
static void
printIval (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
{
- if (!ilist || !pb)
- return;
-
- /* if structure then */
- if (IS_STRUCT (type))
- {
- //fprintf(stderr,"%s struct: %s\n",__FUNCTION__, sym->rname);
- printIvalStruct (sym, type, ilist, pb);
- return;
- }
-
- /* if this is an array */
- if (IS_ARRAY (type))
- {
- //fprintf(stderr,"%s array: %s\n",__FUNCTION__, sym->rname);
- printIvalArray (sym, type, ilist, pb);
- return;
- }
-
- /* if this is a pointer */
- if (IS_PTR (type))
- {
- //fprintf(stderr,"%s pointer: %s\n",__FUNCTION__, sym->rname);
- printIvalPtr (sym, type, ilist, pb);
- return;
- }
-
- /* if type is SPECIFIER */
- if (IS_SPEC (type))
- {
- //fprintf(stderr,"%s spec %s\n",__FUNCTION__, sym->rname);
- printIvalType (sym, type, ilist, pb);
- return;
- }
+ if (!ilist || !pb)
+ return;
+
+ /* if structure then */
+ if (IS_STRUCT (type))
+ {
+ //fprintf(stderr,"%s struct: %s\n",__FUNCTION__, sym->rname);
+ printIvalStruct (sym, type, ilist, pb);
+ return;
+ }
+
+ /* if this is an array */
+ if (IS_ARRAY (type))
+ {
+ //fprintf(stderr,"%s array: %s\n",__FUNCTION__, sym->rname);
+ printIvalArray (sym, type, ilist, pb);
+ return;
+ }
+
+ /* if this is a pointer */
+ if (IS_PTR (type))
+ {
+ //fprintf(stderr,"%s pointer: %s\n",__FUNCTION__, sym->rname);
+ printIvalPtr (sym, type, ilist, pb);
+ return;
+ }
+
+ /* if type is SPECIFIER */
+ if (IS_SPEC (type))
+ {
+ //fprintf(stderr,"%s spec %s\n",__FUNCTION__, sym->rname);
+ printIvalType (sym, type, ilist, pb);
+ return;
+ }
}
#endif
static void
pic14emitStaticSeg (memmap * map)
{
- symbol *sym;
-
- dbuf_printf (&map->oBuf, ";\t.area\t%s\n", map->sname);
-
- //fprintf(stderr, "%s\n",__FUNCTION__);
-
- /* for all variables in this segment do */
- for (sym = setFirstItem (map->syms); sym;
- sym = setNextItem (map->syms))
- {
- /* if extern then add it into the extern list */
- if (IS_EXTERN (sym->etype)) {
- addSetHead (&externs, sym);
- continue;
- }
-
- /* if it is not static add it to the public
- table */
- if (!IS_STATIC (sym->etype))
- addSetHead (&publics, sym);
-
- /* print extra debug info if required */
- if (options.debug || sym->level == 0)
- {
- if (!sym->level)
- { /* global */
- if (IS_STATIC (sym->etype))
- dbuf_printf (&code->oBuf, "F%s_", moduleName); /* scope is file */
- else
- dbuf_printf (&code->oBuf, "G_"); /* scope is global */
- }
- else
- /* symbol is local */
- dbuf_printf (&code->oBuf, "L%s_",
- (sym->localof ? sym->localof->name : "-null-"));
- dbuf_printf (&code->oBuf, "%s_%d_%d", sym->name, sym->level, sym->block);
-
- }
-
- /* if it has an absolute address */
- if (SPEC_ABSA (sym->etype))
- {
- if (options.debug || sym->level == 0)
- dbuf_printf (&code->oBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
-
- dbuf_printf (&code->oBuf, "%s\t=\t0x%04x\n",
- sym->rname,
- SPEC_ADDR (sym->etype));
- }
- else
- {
- if (options.debug || sym->level == 0)
- dbuf_printf (&code->oBuf, " == .\n");
-
- /* if it has an initial value */
- if (sym->ival)
- {
+ symbol *sym;
+
+ dbuf_printf (&map->oBuf, ";\t.area\t%s\n", map->sname);
+
+ //fprintf(stderr, "%s\n",__FUNCTION__);
+
+ /* for all variables in this segment do */
+ for (sym = setFirstItem (map->syms); sym;
+ sym = setNextItem (map->syms))
+ {
+ /* if extern then add it into the extern list */
+ if (IS_EXTERN (sym->etype)) {
+ addSetHead (&externs, sym);
+ continue;
+ }
+
+ /* if it is not static add it to the public
+ table */
+ if (!IS_STATIC (sym->etype))
+ addSetHead (&publics, sym);
+
+ /* print extra debug info if required */
+ if (options.debug || sym->level == 0)
+ {
+ if (!sym->level)
+ { /* global */
+ if (IS_STATIC (sym->etype))
+ dbuf_printf (&code->oBuf, "F%s_", moduleName); /* scope is file */
+ else
+ dbuf_printf (&code->oBuf, "G_"); /* scope is global */
+ }
+ else
+ /* symbol is local */
+ dbuf_printf (&code->oBuf, "L%s_",
+ (sym->localof ? sym->localof->name : "-null-"));
+ dbuf_printf (&code->oBuf, "%s_%d_%d", sym->name, sym->level, sym->block);
+
+ }
+
+ /* if it has an absolute address */
+ if (SPEC_ABSA (sym->etype))
+ {
+ if (options.debug || sym->level == 0)
+ dbuf_printf (&code->oBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
+
+ dbuf_printf (&code->oBuf, "%s\t=\t0x%04x\n",
+ sym->rname,
+ SPEC_ADDR (sym->etype));
+ }
+ else
+ {
+ if (options.debug || sym->level == 0)
+ dbuf_printf (&code->oBuf, " == .\n");
+
+ /* if it has an initial value */
+ if (sym->ival)
+ {
#if 0
- pBlock *pb;
-
- dbuf_printf (&code->oBuf, "%s:\n", sym->rname);
- noAlloc++;
- resolveIvalSym (sym->ival, sym->type);
- //printIval (sym, sym->type, sym->ival, &code->oBuf);
- pb = newpCodeChain(NULL, 'P',newpCodeCharP("; Starting pCode block for Ival"));
- addpBlock(pb);
- addpCode2pBlock(pb,newpCodeLabel(sym->rname,-1));
-
- printIval (sym, sym->type, sym->ival, pb);
- noAlloc--;
+ pBlock *pb;
+
+ dbuf_printf (&code->oBuf, "%s:\n", sym->rname);
+ noAlloc++;
+ resolveIvalSym (sym->ival, sym->type);
+ //printIval (sym, sym->type, sym->ival, &code->oBuf);
+ pb = newpCodeChain(NULL, 'P',newpCodeCharP("; Starting pCode block for Ival"));
+ addpBlock(pb);
+ addpCode2pBlock(pb,newpCodeLabel(sym->rname,-1));
+
+ printIval (sym, sym->type, sym->ival, pb);
+ noAlloc--;
#endif
- }
- else
- {
-
- /* allocate space */
- dbuf_printf (&code->oBuf, "%s:\n", sym->rname);
- /* special case for character strings */
- if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
- SPEC_CVAL (sym->etype).v_char)
- pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
- /*printChar (code->oFile,
- SPEC_CVAL (sym->etype).v_char,
- strlen (SPEC_CVAL (sym->etype).v_char) + 1);*/
- else
- dbuf_printf (&code->oBuf, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
- }
- }
- }
-
+ }
+ else
+ {
+
+ /* allocate space */
+ dbuf_printf (&code->oBuf, "%s:\n", sym->rname);
+ /* special case for character strings */
+ if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
+ SPEC_CVAL (sym->etype).v_char)
+ pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
+ /*printChar (code->oFile,
+ SPEC_CVAL (sym->etype).v_char,
+ strlen (SPEC_CVAL (sym->etype).v_char) + 1);*/
+ else
+ dbuf_printf (&code->oBuf, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
+ }
+ }
+ }
+
}
#endif
static void
pic14emitMaps ()
{
- pic14_constructAbsMap (&sfr->oBuf);
- emitPseudoStack(&sfr->oBuf, &sfr->oBuf);
+ pic14_constructAbsMap (&sfr->oBuf);
+ emitPseudoStack(&sfr->oBuf, &sfr->oBuf);
/* no special considerations for the following
- data, idata & bit & xdata */
- pic14emitRegularMap (data, TRUE, TRUE);
- pic14emitRegularMap (idata, TRUE, TRUE);
- pic14emitRegularMap (bit, TRUE, FALSE);
- pic14emitRegularMap (xdata, TRUE, TRUE);
- pic14emitRegularMap (sfr, TRUE, FALSE);
- pic14emitRegularMap (sfrbit, FALSE, FALSE);
- pic14emitRegularMap (code, TRUE, FALSE);
- pic14emitStaticSeg (statsg);
- pic14emitStaticSeg (c_abs);
+ data, idata & bit & xdata */
+ pic14emitRegularMap (data, TRUE, TRUE);
+ pic14emitRegularMap (idata, TRUE, TRUE);
+ pic14emitRegularMap (bit, TRUE, FALSE);
+ pic14emitRegularMap (xdata, TRUE, TRUE);
+ pic14emitRegularMap (sfr, TRUE, FALSE);
+ pic14emitRegularMap (sfrbit, FALSE, FALSE);
+ pic14emitRegularMap (code, TRUE, FALSE);
+ pic14emitStaticSeg (statsg);
+ pic14emitStaticSeg (c_abs);
}
#endif
static void
pic14createInterruptVect (struct dbuf_s * vBuf)
{
- mainf = newSymbol ("main", 0);
- mainf->block = 0;
-
- /* only if the main function exists */
- if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
- {
- struct options *op = &options;
- if (!(op->cc_only || noAssemble))
- // werror (E_NO_MAIN);
- fprintf(stderr,"WARNING: function 'main' undefined\n");
- return;
- }
-
- /* if the main is only a prototype ie. no body then do nothing */
- if (!IFFUNC_HASBODY(mainf->type))
- {
- /* if ! compile only then main function should be present */
- if (!(options.cc_only || noAssemble))
- // werror (E_NO_MAIN);
- fprintf(stderr,"WARNING: function 'main' undefined\n");
- return;
- }
-
- dbuf_printf (vBuf, "%s", iComments2);
- dbuf_printf (vBuf, "; reset vector \n");
- dbuf_printf (vBuf, "%s", iComments2);
- dbuf_printf (vBuf, "STARTUP\t%s\n", CODE_NAME); // Lkr file should place section STARTUP at address 0x0
- dbuf_printf (vBuf, "\tnop\n"); /* first location for used by incircuit debugger */
- dbuf_printf (vBuf, "\tpagesel __sdcc_gsinit_startup\n");
- dbuf_printf (vBuf, "\tgoto\t__sdcc_gsinit_startup\n");
- popGetExternal("__sdcc_gsinit_startup", 0);
+ mainf = newSymbol ("main", 0);
+ mainf->block = 0;
+
+ /* only if the main function exists */
+ if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
+ {
+ struct options *op = &options;
+ if (!(op->cc_only || noAssemble))
+ // werror (E_NO_MAIN);
+ fprintf(stderr,"WARNING: function 'main' undefined\n");
+ return;
+ }
+
+ /* if the main is only a prototype ie. no body then do nothing */
+ if (!IFFUNC_HASBODY(mainf->type))
+ {
+ /* if ! compile only then main function should be present */
+ if (!(options.cc_only || noAssemble))
+ // werror (E_NO_MAIN);
+ fprintf(stderr,"WARNING: function 'main' undefined\n");
+ return;
+ }
+
+ dbuf_printf (vBuf, "%s", iComments2);
+ dbuf_printf (vBuf, "; reset vector \n");
+ dbuf_printf (vBuf, "%s", iComments2);
+ dbuf_printf (vBuf, "STARTUP\t%s\n", CODE_NAME); // Lkr file should place section STARTUP at address 0x0
+ dbuf_printf (vBuf, "\tnop\n"); /* first location for used by incircuit debugger */
+ dbuf_printf (vBuf, "\tpagesel __sdcc_gsinit_startup\n");
+ dbuf_printf (vBuf, "\tgoto\t__sdcc_gsinit_startup\n");
+ popGetExternal("__sdcc_gsinit_startup", 0);
}
static void
pic14initialComments (FILE * afile)
{
- initialComments (afile);
- fprintf (afile, "; PIC port for the 14-bit core\n");
- fprintf (afile, iComments2);
-
+ initialComments (afile);
+ fprintf (afile, "; PIC port for the 14-bit core\n");
+ fprintf (afile, iComments2);
+
}
int
*/
if (!is_valid_identifier(name))
{
- //fprintf( stderr, "%s:%s:%u: ignored symbol: %s\n", __FILE__, __FUNCTION__, __LINE__, name );
- return;
+ //fprintf( stderr, "%s:%s:%u: ignored symbol: %s\n", __FILE__, __FUNCTION__, __LINE__, name );
+ return;
}
/* check whether the symbol is already defined */
/* new symbol -- define it */
//fprintf (stderr, "%s: emitting %s (%d)\n", __FUNCTION__, name, size);
if (useEQU) {
- dbuf_printf (oBuf, "%s\tEQU\t0x%04x\n", name, addr);
+ dbuf_printf (oBuf, "%s\tEQU\t0x%04x\n", name, addr);
} else {
- /* we place each symbol into a section of its own to allow the linker
- * to distribute the data into all available memory banks */
- if (!section_type) section_type = "udata";
- if (addr != -1)
- {
- /* absolute symbols are handled in pic14_constructAbsMap */
- /* do nothing */
- } else {
- if (globalize) dbuf_printf (oBuf, "\tglobal\t%s\n", name);
- dbuf_printf (oBuf, "udata_%s_%u\t%s\n", moduleName,
- sec_idx++, section_type);
- dbuf_printf (oBuf, "%s\tres\t%d\n", name, size);
- }
+ /* we place each symbol into a section of its own to allow the linker
+ * to distribute the data into all available memory banks */
+ if (!section_type) section_type = "udata";
+ if (addr != -1)
+ {
+ /* absolute symbols are handled in pic14_constructAbsMap */
+ /* do nothing */
+ } else {
+ if (globalize) dbuf_printf (oBuf, "\tglobal\t%s\n", name);
+ dbuf_printf (oBuf, "udata_%s_%u\t%s\n", moduleName,
+ sec_idx++, section_type);
+ dbuf_printf (oBuf, "%s\tres\t%d\n", name, size);
+ }
}
}
#endif
static void
pic14printExterns (FILE * afile)
{
- symbol *sym;
-
- fprintf (afile, "%s", iComments2);
- fprintf (afile, "; extern variables in this module\n");
- fprintf (afile, "%s", iComments2);
-
- for (sym = setFirstItem (externs); sym; sym = setNextItem (externs))
- pic14_emitSymbolIfNew(afile, "\textern %s\n", sym->rname, 1);
+ symbol *sym;
+
+ fprintf (afile, "%s", iComments2);
+ fprintf (afile, "; extern variables in this module\n");
+ fprintf (afile, "%s", iComments2);
+
+ for (sym = setFirstItem (externs); sym; sym = setNextItem (externs))
+ pic14_emitSymbolIfNew(afile, "\textern %s\n", sym->rname, 1);
}
/*-----------------------------------------------------------------*/
if(!IS_BITFIELD(sym->type) && ((IS_FUNC(sym->type) || sym->allocreq))) {
if (!IS_BITVAR(sym->type))
- pic14_emitSymbolIfNew(afile, "\tglobal %s\n", sym->rname, 0);
+ pic14_emitSymbolIfNew(afile, "\tglobal %s\n", sym->rname, 0);
} else {
/* Absolute variables are defines in the asm file as equates and thus can not be made global. */
/* Not any longer! */
// see pic14printLocals
if (getenv("SDCC_PIC14_SPLIT_LOCALS")) {
- // no clustering applied, each register resides in its own bank
+ // no clustering applied, each register resides in its own bank
} else {
- // check whether BOTH names are local registers
- // XXX: This is some kind of shortcut, should be safe...
- // In this model, all r0xXXXX are allocated into a single section
- // per file, so no BANKSEL required if accessing a r0xXXXX after a
- // (different) r0xXXXX. Works great for multi-byte operands.
- if (str1 && str2 && str1[0] == 'r' && str2[0] == 'r') return (1);
+ // check whether BOTH names are local registers
+ // XXX: This is some kind of shortcut, should be safe...
+ // In this model, all r0xXXXX are allocated into a single section
+ // per file, so no BANKSEL required if accessing a r0xXXXX after a
+ // (different) r0xXXXX. Works great for multi-byte operands.
+ if (str1 && str2 && str1[0] == 'r' && str2[0] == 'r') return (1);
} // if
// assume operands in different banks
pic14printLocals (struct dbuf_s *oBuf)
{
set *allregs[6] = { dynAllocRegs/*, dynStackRegs, dynProcessorRegs*/,
- dynDirectRegs, dynDirectBitRegs/*, dynInternalRegs */ };
+ dynDirectRegs, dynDirectBitRegs/*, dynInternalRegs */ };
regs *reg;
int i, is_first = 1;
static unsigned sectionNr = 0;
/* emit all registers from all possible sets */
for (i = 0; i < 6; i++) {
- if (allregs[i] == NULL) continue;
-
- for (reg = setFirstItem(allregs[i]); reg; reg = setNextItem(allregs[i])) {
- if (reg->isEmitted) continue;
-
- if (reg->wasUsed && !reg->isExtern) {
- if (!pic14_stringInSet(reg->name, &emitted, 1)) {
- if (reg->isFixed) {
- // Should not happen, really...
- assert ( !"Compiler-assigned variables should not be pinned... This is a bug." );
- dbuf_printf(oBuf, "UDL_%s_%u\tudata\t0x%04X\n%s\tres\t%d\n",
- moduleName, sectionNr++, reg->address, reg->name, reg->size);
- } else {
- if (getenv("SDCC_PIC14_SPLIT_LOCALS")) {
- // assign each local register into its own section
- dbuf_printf(oBuf, "UDL_%s_%u\tudata\n%s\tres\t%d\n",
- moduleName, sectionNr++, reg->name, reg->size);
- } else {
- // group all local registers into a single section
- // This should greatly improve BANKSEL generation...
- if (is_first) {
- dbuf_printf(oBuf, "UDL_%s_%u\tudata\n", moduleName, sectionNr++);
- is_first = 0;
- }
- dbuf_printf(oBuf, "%s\tres\t%d\n", reg->name, reg->size);
- }
- }
- }
- }
- reg->isEmitted = 1;
- } // for
+ if (allregs[i] == NULL) continue;
+
+ for (reg = setFirstItem(allregs[i]); reg; reg = setNextItem(allregs[i])) {
+ if (reg->isEmitted) continue;
+
+ if (reg->wasUsed && !reg->isExtern) {
+ if (!pic14_stringInSet(reg->name, &emitted, 1)) {
+ if (reg->isFixed) {
+ // Should not happen, really...
+ assert ( !"Compiler-assigned variables should not be pinned... This is a bug." );
+ dbuf_printf(oBuf, "UDL_%s_%u\tudata\t0x%04X\n%s\tres\t%d\n",
+ moduleName, sectionNr++, reg->address, reg->name, reg->size);
+ } else {
+ if (getenv("SDCC_PIC14_SPLIT_LOCALS")) {
+ // assign each local register into its own section
+ dbuf_printf(oBuf, "UDL_%s_%u\tudata\n%s\tres\t%d\n",
+ moduleName, sectionNr++, reg->name, reg->size);
+ } else {
+ // group all local registers into a single section
+ // This should greatly improve BANKSEL generation...
+ if (is_first) {
+ dbuf_printf(oBuf, "UDL_%s_%u\tudata\n", moduleName, sectionNr++);
+ is_first = 0;
+ }
+ dbuf_printf(oBuf, "%s\tres\t%d\n", reg->name, reg->size);
+ }
+ }
+ }
+ }
+ reg->isEmitted = 1;
+ } // for
} // for
}
static void
pic14emitOverlay (struct dbuf_s * aBuf)
{
- set *ovrset;
-
- /* if (!elementsInSet (ovrSetSets))*/
-
- /* the hack below, fixes translates for devices which
- * only have udata_shr memory */
- dbuf_printf (aBuf, "%s\t%s\n",
- (elementsInSet(ovrSetSets)?"":";"),
- port->mem.overlay_name);
-
- /* for each of the sets in the overlay segment do */
- for (ovrset = setFirstItem (ovrSetSets); ovrset;
- ovrset = setNextItem (ovrSetSets))
- {
-
- symbol *sym;
-
- if (elementsInSet (ovrset))
- {
- /* this dummy area is used to fool the assembler
- otherwise the assembler will append each of these
- declarations into one chunk and will not overlay
- sad but true */
-
- /* I don't think this applies to us. We are using gpasm. CRF */
-
- dbuf_printf (aBuf, ";\t.area _DUMMY\n");
- /* output the area informtion */
- dbuf_printf (aBuf, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
- }
-
- for (sym = setFirstItem (ovrset); sym;
- sym = setNextItem (ovrset))
- {
-
- /* if extern then do nothing */
- if (IS_EXTERN (sym->etype))
- continue;
-
- /* if allocation required check is needed
- then check if the symbol really requires
- allocation only for local variables */
- if (!IS_AGGREGATE (sym->type) &&
- !(sym->_isparm && !IS_REGPARM (sym->etype))
- && !sym->allocreq && sym->level)
- continue;
-
- /* if global variable & not static or extern
- and addPublics allowed then add it to the public set */
- if ((sym->_isparm && !IS_REGPARM (sym->etype))
- && !IS_STATIC (sym->etype))
- addSetHead (&publics, sym);
-
- /* if extern then do nothing or is a function
- then do nothing */
- if (IS_FUNC (sym->type))
- continue;
-
- /* print extra debug info if required */
- if (options.debug || sym->level == 0)
- {
- if (!sym->level)
- { /* global */
- if (IS_STATIC (sym->etype))
- dbuf_printf (aBuf, "F%s_", moduleName); /* scope is file */
- else
- dbuf_printf (aBuf, "G_"); /* scope is global */
- }
- else
- /* symbol is local */
- dbuf_printf (aBuf, "L%s_",
- (sym->localof ? sym->localof->name : "-null-"));
- dbuf_printf (aBuf, "%s_%d_%d", sym->name, sym->level, sym->block);
- }
-
- /* if is has an absolute address then generate
- an equate for this no need to allocate space */
- if (SPEC_ABSA (sym->etype))
- {
-
- if (options.debug || sym->level == 0)
- dbuf_printf (aBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
-
- dbuf_printf (aBuf, "%s\t=\t0x%04x\n",
- sym->rname,
- SPEC_ADDR (sym->etype));
- }
- else
- {
- if (options.debug || sym->level == 0)
- dbuf_printf (aBuf, "==.\n");
-
- /* allocate space */
- dbuf_printf (aBuf, "%s:\n", sym->rname);
- dbuf_printf (aBuf, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
- }
-
- }
- }
+ set *ovrset;
+
+ /* if (!elementsInSet (ovrSetSets))*/
+
+ /* the hack below, fixes translates for devices which
+ * only have udata_shr memory */
+ dbuf_printf (aBuf, "%s\t%s\n",
+ (elementsInSet(ovrSetSets)?"":";"),
+ port->mem.overlay_name);
+
+ /* for each of the sets in the overlay segment do */
+ for (ovrset = setFirstItem (ovrSetSets); ovrset;
+ ovrset = setNextItem (ovrSetSets))
+ {
+
+ symbol *sym;
+
+ if (elementsInSet (ovrset))
+ {
+ /* this dummy area is used to fool the assembler
+ otherwise the assembler will append each of these
+ declarations into one chunk and will not overlay
+ sad but true */
+
+ /* I don't think this applies to us. We are using gpasm. CRF */
+
+ dbuf_printf (aBuf, ";\t.area _DUMMY\n");
+ /* output the area informtion */
+ dbuf_printf (aBuf, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
+ }
+
+ for (sym = setFirstItem (ovrset); sym;
+ sym = setNextItem (ovrset))
+ {
+
+ /* if extern then do nothing */
+ if (IS_EXTERN (sym->etype))
+ continue;
+
+ /* if allocation required check is needed
+ then check if the symbol really requires
+ allocation only for local variables */
+ if (!IS_AGGREGATE (sym->type) &&
+ !(sym->_isparm && !IS_REGPARM (sym->etype))
+ && !sym->allocreq && sym->level)
+ continue;
+
+ /* if global variable & not static or extern
+ and addPublics allowed then add it to the public set */
+ if ((sym->_isparm && !IS_REGPARM (sym->etype))
+ && !IS_STATIC (sym->etype))
+ addSetHead (&publics, sym);
+
+ /* if extern then do nothing or is a function
+ then do nothing */
+ if (IS_FUNC (sym->type))
+ continue;
+
+ /* print extra debug info if required */
+ if (options.debug || sym->level == 0)
+ {
+ if (!sym->level)
+ { /* global */
+ if (IS_STATIC (sym->etype))
+ dbuf_printf (aBuf, "F%s_", moduleName); /* scope is file */
+ else
+ dbuf_printf (aBuf, "G_"); /* scope is global */
+ }
+ else
+ /* symbol is local */
+ dbuf_printf (aBuf, "L%s_",
+ (sym->localof ? sym->localof->name : "-null-"));
+ dbuf_printf (aBuf, "%s_%d_%d", sym->name, sym->level, sym->block);
+ }
+
+ /* if is has an absolute address then generate
+ an equate for this no need to allocate space */
+ if (SPEC_ABSA (sym->etype))
+ {
+
+ if (options.debug || sym->level == 0)
+ dbuf_printf (aBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
+
+ dbuf_printf (aBuf, "%s\t=\t0x%04x\n",
+ sym->rname,
+ SPEC_ADDR (sym->etype));
+ }
+ else
+ {
+ if (options.debug || sym->level == 0)
+ dbuf_printf (aBuf, "==.\n");
+
+ /* allocate space */
+ dbuf_printf (aBuf, "%s:\n", sym->rname);
+ dbuf_printf (aBuf, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
+ }
+
+ }
+ }
}
void
pic14_emitInterruptHandler (FILE * asmFile)
{
- if (pic14_hasInterrupt)
- {
-
- fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile, "; interrupt and initialization code\n");
- fprintf (asmFile, "%s", iComments2);
- // Note - for mplink may have to enlarge section vectors in .lnk file
- // Note: Do NOT name this code_interrupt to avoid nameclashes with
- // source files's code segment (interrupt.c -> code_interrupt)
- fprintf (asmFile, "c_interrupt\t%s\t0x4\n", CODE_NAME);
-
- /* interrupt service routine */
- fprintf (asmFile, "__sdcc_interrupt\n");
- copypCode(asmFile, 'I');
- }
+ if (pic14_hasInterrupt)
+ {
+
+ fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile, "; interrupt and initialization code\n");
+ fprintf (asmFile, "%s", iComments2);
+ // Note - for mplink may have to enlarge section vectors in .lnk file
+ // Note: Do NOT name this code_interrupt to avoid nameclashes with
+ // source files's code segment (interrupt.c -> code_interrupt)
+ fprintf (asmFile, "c_interrupt\t%s\t0x4\n", CODE_NAME);
+
+ /* interrupt service routine */
+ fprintf (asmFile, "__sdcc_interrupt\n");
+ copypCode(asmFile, 'I');
+ }
}
/*-----------------------------------------------------------------*/
void
picglue ()
{
- FILE *asmFile;
+ FILE *asmFile;
struct dbuf_s ovrBuf;
struct dbuf_s vBuf;
dbuf_init(&ovrBuf, 4096);
dbuf_init(&vBuf, 4096);
- pCodeInitRegisters();
+ pCodeInitRegisters();
- /* check for main() */
- mainf = newSymbol ("main", 0);
- mainf->block = 0;
- mainf = findSymWithLevel (SymbolTab, mainf);
+ /* check for main() */
+ mainf = newSymbol ("main", 0);
+ mainf->block = 0;
+ mainf = findSymWithLevel (SymbolTab, mainf);
- if (!mainf || !IFFUNC_HASBODY(mainf->type))
- {
- /* main missing -- import stack from main module */
- //fprintf (stderr, "main() missing -- assuming we are NOT the main module\n");
- pic14_options.isLibrarySource = 1;
- }
+ if (!mainf || !IFFUNC_HASBODY(mainf->type))
+ {
+ /* main missing -- import stack from main module */
+ //fprintf (stderr, "main() missing -- assuming we are NOT the main module\n");
+ pic14_options.isLibrarySource = 1;
+ }
#if 0
- if (mainf && IFFUNC_HASBODY(mainf->type)) {
-
- pBlock *pb = newpCodeChain(NULL,'X',newpCodeCharP("; Starting pCode block"));
- addpBlock(pb);
-
- /* entry point @ start of CSEG */
- addpCode2pBlock(pb,newpCodeLabel("__sdcc_program_startup",-1));
- /* put in the call to main */
- addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp("_main",PO_STR)));
-
- if (options.mainreturn) {
-
- addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will return to caller\n"));
- addpCode2pBlock(pb,newpCode(POC_RETURN,NULL));
-
- } else {
-
- addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will lock up\n"));
- addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("$",PO_STR)));
-
- }
- }
-#endif
-
- /* At this point we've got all the code in the form of pCode structures */
- /* Now it needs to be rearranged into the order it should be placed in the */
- /* code space */
-
- movepBlock2Head('P'); // Last
- movepBlock2Head(code->dbName);
- movepBlock2Head('X');
- movepBlock2Head(statsg->dbName); // First
-
-
- /* print the global struct definitions */
- if (options.debug)
- cdbStructBlock (0);
-
- /* emit code for the all the variables declared */
- //pic14emitMaps ();
- /* do the overlay segments */
- pic14emitOverlay(&ovrBuf);
-
- /* PENDING: this isnt the best place but it will do */
- if (port->general.glue_up_main) {
- /* create the interrupt vector table */
- pic14createInterruptVect (&vBuf);
- }
-
- AnalyzepCode('*');
-
- ReuseReg(); // ReuseReg where call tree permits
-
- InlinepCode();
-
- AnalyzepCode('*');
-
- if (options.debug) pcode_test();
-
-
- /* now put it all together into the assembler file */
- /* create the assembler file name */
-
- if ((noAssemble || options.c1mode) && fullDstFileName)
- {
- sprintf (buffer, fullDstFileName);
- }
- else
- {
- sprintf (buffer, dstFileName);
- strcat (buffer, ".asm");
- }
-
- if (!(asmFile = fopen (buffer, "w"))) {
- werror (E_FILE_OPEN_ERR, buffer);
- exit (1);
- }
-
- /* prepare statistics */
- resetpCodeStatistics ();
-
- /* initial comments */
- pic14initialComments (asmFile);
-
- /* print module name */
- fprintf (asmFile, ";\t.module %s\n", moduleName);
-
- /* Let the port generate any global directives, etc. */
- if (port->genAssemblerPreamble)
- {
- port->genAssemblerPreamble(asmFile);
- }
-
- /* print the global variables in this module */
- //pic14printPublics (asmFile);
-
- /* print the extern variables in this module */
- //pic14printExterns (asmFile);
-
- /* copy the sfr segment */
+ if (mainf && IFFUNC_HASBODY(mainf->type)) {
+
+ pBlock *pb = newpCodeChain(NULL,'X',newpCodeCharP("; Starting pCode block"));
+ addpBlock(pb);
+
+ /* entry point @ start of CSEG */
+ addpCode2pBlock(pb,newpCodeLabel("__sdcc_program_startup",-1));
+ /* put in the call to main */
+ addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp("_main",PO_STR)));
+
+ if (options.mainreturn) {
+
+ addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will return to caller\n"));
+ addpCode2pBlock(pb,newpCode(POC_RETURN,NULL));
+
+ } else {
+
+ addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will lock up\n"));
+ addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("$",PO_STR)));
+
+ }
+ }
+#endif
+
+ /* At this point we've got all the code in the form of pCode structures */
+ /* Now it needs to be rearranged into the order it should be placed in the */
+ /* code space */
+
+ movepBlock2Head('P'); // Last
+ movepBlock2Head(code->dbName);
+ movepBlock2Head('X');
+ movepBlock2Head(statsg->dbName); // First
+
+
+ /* print the global struct definitions */
+ if (options.debug)
+ cdbStructBlock (0);
+
+ /* emit code for the all the variables declared */
+ //pic14emitMaps ();
+ /* do the overlay segments */
+ pic14emitOverlay(&ovrBuf);
+
+ /* PENDING: this isnt the best place but it will do */
+ if (port->general.glue_up_main) {
+ /* create the interrupt vector table */
+ pic14createInterruptVect (&vBuf);
+ }
+
+ AnalyzepCode('*');
+
+ ReuseReg(); // ReuseReg where call tree permits
+
+ InlinepCode();
+
+ AnalyzepCode('*');
+
+ if (options.debug) pcode_test();
+
+
+ /* now put it all together into the assembler file */
+ /* create the assembler file name */
+
+ if ((noAssemble || options.c1mode) && fullDstFileName)
+ {
+ sprintf (buffer, fullDstFileName);
+ }
+ else
+ {
+ sprintf (buffer, dstFileName);
+ strcat (buffer, ".asm");
+ }
+
+ if (!(asmFile = fopen (buffer, "w"))) {
+ werror (E_FILE_OPEN_ERR, buffer);
+ exit (1);
+ }
+
+ /* prepare statistics */
+ resetpCodeStatistics ();
+
+ /* initial comments */
+ pic14initialComments (asmFile);
+
+ /* print module name */
+ fprintf (asmFile, ";\t.module %s\n", moduleName);
+
+ /* Let the port generate any global directives, etc. */
+ if (port->genAssemblerPreamble)
+ {
+ port->genAssemblerPreamble(asmFile);
+ }
+
+ /* print the global variables in this module */
+ //pic14printPublics (asmFile);
+
+ /* print the extern variables in this module */
+ //pic14printExterns (asmFile);
+
+ /* copy the sfr segment */
#if 0
- fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile, "; special function registers\n");
- fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile, "; special function registers\n");
+ fprintf (asmFile, "%s", iComments2);
dbuf_write_and_destroy (&sfr->oBuf, asmFile);
-
-
- if (udata_section_name) {
- sprintf(udata_name,"%s",udata_section_name);
- } else {
- sprintf(udata_name,"data_%s",moduleName);
- }
- fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile, "; udata\n");
- fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile, "%s\tudata\n", udata_name);
+
+
+ if (udata_section_name) {
+ sprintf(udata_name,"%s",udata_section_name);
+ } else {
+ sprintf(udata_name,"data_%s",moduleName);
+ }
+ fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile, "; udata\n");
+ fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile, "%s\tudata\n", udata_name);
dbuf_write_and_destroy(&data->oBuf, asmFile);
#endif
- /* Put all variables into a cblock */
- AnalyzeBanking();
+ /* Put all variables into a cblock */
+ AnalyzeBanking();
- /* emit initialized data */
- showAllMemmaps(asmFile);
+ /* emit initialized data */
+ showAllMemmaps(asmFile);
- /* print the locally defined variables in this module */
- writeUsedRegs(asmFile);
-
- /* create the overlay segments */
- fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile, "; overlayable items in internal ram \n");
- fprintf (asmFile, "%s", iComments2);
+ /* print the locally defined variables in this module */
+ writeUsedRegs(asmFile);
+
+ /* create the overlay segments */
+ fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile, "; overlayable items in internal ram \n");
+ fprintf (asmFile, "%s", iComments2);
dbuf_write_and_destroy (&ovrBuf, asmFile);
-
+
#if 0
-
- /* create the stack segment MOF */
- if (mainf && IFFUNC_HASBODY(mainf->type)) {
- fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile, "; Stack segment in internal ram \n");
- fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile, ";\t.area\tSSEG\t(DATA)\n"
- ";__start__stack:\n;\t.ds\t1\n\n");
- }
-
- /* create the idata segment */
- fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile, "; indirectly addressable internal ram data\n");
- fprintf (asmFile, "%s", iComments2);
+
+ /* create the stack segment MOF */
+ if (mainf && IFFUNC_HASBODY(mainf->type)) {
+ fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile, "; Stack segment in internal ram \n");
+ fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile, ";\t.area\tSSEG\t(DATA)\n"
+ ";__start__stack:\n;\t.ds\t1\n\n");
+ }
+
+ /* create the idata segment */
+ fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile, "; indirectly addressable internal ram data\n");
+ fprintf (asmFile, "%s", iComments2);
dbuf_write_and_destroy (&idata->oBuf, asmFile);
- /* if external stack then reserve space of it */
- if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
- fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile, "; external stack \n");
- fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
- fprintf (asmFile,";\t.ds 256\n");
- }
-
- /* copy xtern ram data */
- fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile, "; external ram data\n");
- fprintf (asmFile, "%s", iComments2);
+ /* if external stack then reserve space of it */
+ if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
+ fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile, "; external stack \n");
+ fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
+ fprintf (asmFile,";\t.ds 256\n");
+ }
+
+ /* copy xtern ram data */
+ fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile, "; external ram data\n");
+ fprintf (asmFile, "%s", iComments2);
dbuf_write_and_destroy (&xdata->oBuf, asmFile);
#endif
-
- /* copy the bit segment */
+
+ /* copy the bit segment */
#if 0
- fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile, "; bit data\n");
- fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile, "; bit data\n");
+ fprintf (asmFile, "%s", iComments2);
dbuf_write_and_destroy (&bit->oBuf, asmFile);
#endif
- /* copy the interrupt vector table */
- if (mainf && IFFUNC_HASBODY(mainf->type))
- dbuf_write_and_destroy (&vBuf, asmFile);
+ /* copy the interrupt vector table */
+ if (mainf && IFFUNC_HASBODY(mainf->type))
+ dbuf_write_and_destroy (&vBuf, asmFile);
else
- dbuf_destroy(&vBuf);
-
- /* create interupt ventor handler */
- pic14_emitInterruptHandler (asmFile);
-
- /* copy over code */
- fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile, "; code\n");
- fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile, "code_%s\t%s\n", moduleName, port->mem.code_name);
-
- /* unknown */
- copypCode(asmFile, 'X');
-
- /* _main function */
- copypCode(asmFile, 'M');
-
- /* other functions */
- copypCode(asmFile, code->dbName);
-
- /* unknown */
- copypCode(asmFile, 'P');
-
- dumppCodeStatistics (asmFile);
-
- fprintf (asmFile,"\tend\n");
-
- fclose (asmFile);
- pic14_debugLogClose();
+ dbuf_destroy(&vBuf);
+
+ /* create interupt ventor handler */
+ pic14_emitInterruptHandler (asmFile);
+
+ /* copy over code */
+ fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile, "; code\n");
+ fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile, "code_%s\t%s\n", moduleName, port->mem.code_name);
+
+ /* unknown */
+ copypCode(asmFile, 'X');
+
+ /* _main function */
+ copypCode(asmFile, 'M');
+
+ /* other functions */
+ copypCode(asmFile, code->dbName);
+
+ /* unknown */
+ copypCode(asmFile, 'P');
+
+ dumppCodeStatistics (asmFile);
+
+ fprintf (asmFile,"\tend\n");
+
+ fclose (asmFile);
+ pic14_debugLogClose();
}
/*
static const char *ast_type[] = { "EX_OP", "EX_VALUE", "EX_LINK", "EX_OPERAND" };
struct ast *ast;
while (list) {
- printf (" %d: type %u (%s), init %p, next %p\n", level, list->type, list_type[list->type], list->init.node, list->next);
- if (list->type == INIT_DEEP) {
- showInitList(list->init.deep, level + 1);
- } else if (list->type == INIT_NODE) {
- ast = list->init.node;
- printf (" type %u (%s), level %d, block %d, seqPoint %d\n",
- ast->type, ast_type[ast->type], ast->level, ast->block, ast->seqPoint);
- if (ast->type == EX_VALUE) {
- printf (" VAL %lf\n", floatFromVal(ast->opval.val));
- } else if (ast->type == EX_LINK) {
- printTypeChain(ast->opval.lnk, NULL);
- } else if (ast->type == EX_OP) {
- printf (" OP %u\n", ast->opval.op);
- }
- } // if
- list = list->next;
+ printf (" %d: type %u (%s), init %p, next %p\n", level, list->type, list_type[list->type], list->init.node, list->next);
+ if (list->type == INIT_DEEP) {
+ showInitList(list->init.deep, level + 1);
+ } else if (list->type == INIT_NODE) {
+ ast = list->init.node;
+ printf (" type %u (%s), level %d, block %d, seqPoint %d\n",
+ ast->type, ast_type[ast->type], ast->level, ast->block, ast->seqPoint);
+ if (ast->type == EX_VALUE) {
+ printf (" VAL %lf\n", floatFromVal(ast->opval.val));
+ } else if (ast->type == EX_LINK) {
+ printTypeChain(ast->opval.lnk, NULL);
+ } else if (ast->type == EX_OP) {
+ printf (" OP %u\n", ast->opval.op);
+ }
+ } // if
+ list = list->next;
} // while
}
#endif
printVal(value *val)
{
printf ("value %p: name %s, type %p, etype %p, sym %s, vArgs %d, lit 0x%lx/%ld\n",
- val, val->name, val->type, val->etype,
- val->sym ? val->sym->name : NULL, val->vArgs,
- (long)floatFromVal(val), (long)floatFromVal(val));
+ val, val->name, val->type, val->etype,
+ val->sym ? val->sym->name : NULL, val->vArgs,
+ (long) ulFromVal (val), (long) ulFromVal (val));
printTypeChain(val->type, stdout);
printf ("\n");
printTypeChain(val->etype, stdout);
char *left, *right;
if (IS_AST_VALUE(node)) {
- value *val = AST_VALUE(node);
- symbol *sym = IS_AST_SYM_VALUE(node) ? AST_SYMBOL(node) : NULL;
- if (inCodeSpace && val->type
- && (IS_FUNC(val->type) || IS_CODE(getSpec(val->type))))
- {
- *inCodeSpace = 1;
- }
- if (inCodeSpace && sym
- && (IS_FUNC(sym->type)
- || IS_CODE(getSpec(sym->type))))
- {
- *inCodeSpace = 1;
- }
-
- DEBUGprintf ("%s: AST_VALUE\n", __FUNCTION__);
- if (IS_AST_LIT_VALUE(node)) {
- buffer = Safe_alloc(LEN);
- SNPRINTF(buffer, LEN, "0x%lx", (long)AST_LIT_VALUE(node));
- } else if (IS_AST_SYM_VALUE(node)) {
- assert ( AST_SYMBOL(node) );
- /*
- printf ("sym %s: ", AST_SYMBOL(node)->rname);
- printTypeChain(AST_SYMBOL(node)->type, stdout);
- printTypeChain(AST_SYMBOL(node)->etype, stdout);
- printf ("\n---sym %s: done\n", AST_SYMBOL(node)->rname);
- */
- buffer = Safe_strdup(AST_SYMBOL(node)->rname);
- } else {
- assert ( !"Invalid values type for initializers in AST." );
- }
+ value *val = AST_VALUE(node);
+ symbol *sym = IS_AST_SYM_VALUE(node) ? AST_SYMBOL(node) : NULL;
+ if (inCodeSpace && val->type
+ && (IS_FUNC(val->type) || IS_CODE(getSpec(val->type))))
+ {
+ *inCodeSpace = 1;
+ }
+ if (inCodeSpace && sym
+ && (IS_FUNC(sym->type)
+ || IS_CODE(getSpec(sym->type))))
+ {
+ *inCodeSpace = 1;
+ }
+
+ DEBUGprintf ("%s: AST_VALUE\n", __FUNCTION__);
+ if (IS_AST_LIT_VALUE(node)) {
+ buffer = Safe_alloc(LEN);
+ SNPRINTF(buffer, LEN, "0x%lx", (long)AST_LIT_VALUE(node));
+ } else if (IS_AST_SYM_VALUE(node)) {
+ assert ( AST_SYMBOL(node) );
+ /*
+ printf ("sym %s: ", AST_SYMBOL(node)->rname);
+ printTypeChain(AST_SYMBOL(node)->type, stdout);
+ printTypeChain(AST_SYMBOL(node)->etype, stdout);
+ printf ("\n---sym %s: done\n", AST_SYMBOL(node)->rname);
+ */
+ buffer = Safe_strdup(AST_SYMBOL(node)->rname);
+ } else {
+ assert ( !"Invalid values type for initializers in AST." );
+ }
} else if (IS_AST_OP(node)) {
- DEBUGprintf ("%s: AST_OP\n", __FUNCTION__);
- switch (node->opval.op) {
- case CAST:
- assert (node->right);
- buffer = parseIvalAst(node->right, inCodeSpace);
- DEBUGprintf ("%s: %s\n", __FUNCTION__, buffer);
- break;
- case '&':
- assert ( node->left && !node->right );
- buffer = parseIvalAst(node->left, inCodeSpace);
- DEBUGprintf ("%s: %s\n", __FUNCTION__, buffer);
- break;
- case '+':
- assert (node->left && node->right );
- left = parseIvalAst(node->left, inCodeSpace);
- right = parseIvalAst(node->right, inCodeSpace);
- buffer = Safe_alloc(LEN);
- SNPRINTF(buffer, LEN, "(%s + %s)", left, right);
- DEBUGprintf ("%s: %s\n", __FUNCTION__, buffer);
- Safe_free(left);
- Safe_free(right);
- break;
- case '[':
- assert ( node->left && node->right );
- assert ( IS_AST_VALUE(node->left) && AST_VALUE(node->left)->sym );
- right = parseIvalAst(node->right, inCodeSpace);
- buffer = Safe_alloc(LEN);
- SNPRINTF(buffer, LEN, "(%s + %u * %s)",
- AST_VALUE(node->left)->sym->rname, getSize(AST_VALUE(node->left)->type), right);
- Safe_free(right);
- DEBUGprintf ("%s: %s\n", __FUNCTION__, &buffer[0]);
- break;
- default:
- assert ( !"Unhandled operation in initializer." );
- break;
- }
+ DEBUGprintf ("%s: AST_OP\n", __FUNCTION__);
+ switch (node->opval.op) {
+ case CAST:
+ assert (node->right);
+ buffer = parseIvalAst(node->right, inCodeSpace);
+ DEBUGprintf ("%s: %s\n", __FUNCTION__, buffer);
+ break;
+ case '&':
+ assert ( node->left && !node->right );
+ buffer = parseIvalAst(node->left, inCodeSpace);
+ DEBUGprintf ("%s: %s\n", __FUNCTION__, buffer);
+ break;
+ case '+':
+ assert (node->left && node->right );
+ left = parseIvalAst(node->left, inCodeSpace);
+ right = parseIvalAst(node->right, inCodeSpace);
+ buffer = Safe_alloc(LEN);
+ SNPRINTF(buffer, LEN, "(%s + %s)", left, right);
+ DEBUGprintf ("%s: %s\n", __FUNCTION__, buffer);
+ Safe_free(left);
+ Safe_free(right);
+ break;
+ case '[':
+ assert ( node->left && node->right );
+ assert ( IS_AST_VALUE(node->left) && AST_VALUE(node->left)->sym );
+ right = parseIvalAst(node->right, inCodeSpace);
+ buffer = Safe_alloc(LEN);
+ SNPRINTF(buffer, LEN, "(%s + %u * %s)",
+ AST_VALUE(node->left)->sym->rname, getSize(AST_VALUE(node->left)->type), right);
+ Safe_free(right);
+ DEBUGprintf ("%s: %s\n", __FUNCTION__, &buffer[0]);
+ break;
+ default:
+ assert ( !"Unhandled operation in initializer." );
+ break;
+ }
} else {
- assert ( !"Invalid construct in initializer." );
+ assert ( !"Invalid construct in initializer." );
}
return (buffer);
static int sectionNr = 0;
if (sym) {
- // code or data space?
- if (IS_CODE(getSpec(sym->type))) {
- segname = "code";
- in_code = 1;
- } else {
- segname = "idata";
- in_code = 0;
- }
- dbuf_printf(oBuf, "\nID_%s_%d\t%s", moduleName, sectionNr++, segname);
- if (SPEC_ABSA(getSpec(sym->type))) {
- // specify address for absolute symbols
- dbuf_printf(oBuf, "\t0x%04X", SPEC_ADDR(getSpec(sym->type)));
- } // if
- dbuf_printf(oBuf, "\n%s\n", sym->rname);
-
- addSet(&emitted, sym->rname);
+ // code or data space?
+ if (IS_CODE(getSpec(sym->type))) {
+ segname = "code";
+ in_code = 1;
+ } else {
+ segname = "idata";
+ in_code = 0;
+ }
+ dbuf_printf(oBuf, "\nID_%s_%d\t%s", moduleName, sectionNr++, segname);
+ if (SPEC_ABSA(getSpec(sym->type))) {
+ // specify address for absolute symbols
+ dbuf_printf(oBuf, "\t0x%04X", SPEC_ADDR(getSpec(sym->type)));
+ } // if
+ dbuf_printf(oBuf, "\n%s\n", sym->rname);
+
+ addSet(&emitted, sym->rname);
}
return (in_code);
}
if (!in_code) dbuf_printf (oBuf, "\tdb\t");
if (!node) {
- // initialize as zero
- for (i=0; i < size; i++) {
- if (in_code) {
- dbuf_printf (oBuf, "\tretlw 0x00");
- } else {
- dbuf_printf (oBuf, "%s0x00", (i == 0) ? "" : ", ");
- }
- } // for
- dbuf_printf (oBuf, "\n");
- return;
+ // initialize as zero
+ for (i=0; i < size; i++) {
+ if (in_code) {
+ dbuf_printf (oBuf, "\tretlw 0x00");
+ } else {
+ dbuf_printf (oBuf, "%s0x00", (i == 0) ? "" : ", ");
+ }
+ } // for
+ dbuf_printf (oBuf, "\n");
+ return;
} // if
op = NULL;
if (constExprTree(node) && (val = constExprValue(node, 0))) {
- op = operandFromValue(val);
- DEBUGprintf ("%s: constExpr ", __FUNCTION__);
- //printVal(val);
+ op = operandFromValue(val);
+ DEBUGprintf ("%s: constExpr ", __FUNCTION__);
+ //printVal(val);
} else if (IS_AST_VALUE(node)) {
- op = operandFromAst(node, 0);
+ op = operandFromAst(node, 0);
} else if (IS_AST_OP(node)) {
- str = parseIvalAst(node, &inCodeSpace);
- DEBUGprintf("%s: AST_OP: %s\n", __FUNCTION__, str);
- op = NULL;
+ str = parseIvalAst(node, &inCodeSpace);
+ DEBUGprintf("%s: AST_OP: %s\n", __FUNCTION__, str);
+ op = NULL;
} else {
- assert ( !"Unhandled construct in intializer." );
+ assert ( !"Unhandled construct in intializer." );
}
if (op) {
- aopOp(op, NULL, 1);
- assert(AOP(op));
- //printOperand(op, of);
+ aopOp(op, NULL, 1);
+ assert(AOP(op));
+ //printOperand(op, of);
}
for (i=0; i < size; i++) {
- char *text = op ? aopGet(AOP(op), i, 0, 0)
- : get_op(newpCodeOpImmd(str, i, 0, inCodeSpace, 0), NULL, 0);
- if (in_code) {
- dbuf_printf (oBuf, "\tretlw %s\n", text);
- } else {
- dbuf_printf (oBuf, "%s%s", (i == 0) ? "" : ", ", text);
- }
+ char *text = op ? aopGet(AOP(op), i, 0, 0)
+ : get_op(newpCodeOpImmd(str, i, 0, inCodeSpace, 0), NULL, 0);
+ if (in_code) {
+ dbuf_printf (oBuf, "\tretlw %s\n", text);
+ } else {
+ dbuf_printf (oBuf, "%s%s", (i == 0) ? "" : ", ", text);
+ }
} // for
dbuf_printf (oBuf, "\n");
}
assert (type);
if (IS_PTR(type) || IS_CHAR(type) || IS_INT(type) || IS_LONG(type)
- || IS_FLOAT(type))
+ || IS_FLOAT(type))
{
- if (!list || (list->type == INIT_NODE)) {
- DEBUGprintf ("OK, simple type\n");
- return (type);
- } else {
- DEBUGprintf ("ERROR, simple type\n");
- return (NULL);
- }
+ if (!list || (list->type == INIT_NODE)) {
+ DEBUGprintf ("OK, simple type\n");
+ return (type);
+ } else {
+ DEBUGprintf ("ERROR, simple type\n");
+ return (NULL);
+ }
} else if (IS_BITFIELD(type)) {
- if (!list || (list->type == INIT_NODE)) {
- DEBUGprintf ("OK, bitfield\n");
- return (type);
- } else {
- DEBUGprintf ("ERROR, bitfield\n");
- return (NULL);
- }
+ if (!list || (list->type == INIT_NODE)) {
+ DEBUGprintf ("OK, bitfield\n");
+ return (type);
+ } else {
+ DEBUGprintf ("ERROR, bitfield\n");
+ return (NULL);
+ }
} else if (IS_STRUCT(type) && SPEC_STRUCT(getSpec(type))->type == STRUCT) {
- if (!list || (list->type == INIT_DEEP)) {
- if (list) list = list->init.deep;
- sym = SPEC_STRUCT(type)->fields;
- while (sym) {
- DEBUGprintf ("Checking STRUCT member %s\n", sym->name);
- if (!matchIvalToUnion(list, sym->type, 0)) {
- DEBUGprintf ("ERROR, STRUCT member %s\n", sym->name);
- return (NULL);
- }
- if (list) list = list->next;
- sym = sym->next;
- } // while
-
- // excess initializers?
- if (list) {
- DEBUGprintf ("ERROR, excess initializers\n");
- return (NULL);
- }
-
- DEBUGprintf ("OK, struct\n");
- return (type);
- }
- return (NULL);
+ if (!list || (list->type == INIT_DEEP)) {
+ if (list) list = list->init.deep;
+ sym = SPEC_STRUCT(type)->fields;
+ while (sym) {
+ DEBUGprintf ("Checking STRUCT member %s\n", sym->name);
+ if (!matchIvalToUnion(list, sym->type, 0)) {
+ DEBUGprintf ("ERROR, STRUCT member %s\n", sym->name);
+ return (NULL);
+ }
+ if (list) list = list->next;
+ sym = sym->next;
+ } // while
+
+ // excess initializers?
+ if (list) {
+ DEBUGprintf ("ERROR, excess initializers\n");
+ return (NULL);
+ }
+
+ DEBUGprintf ("OK, struct\n");
+ return (type);
+ }
+ return (NULL);
} else if (IS_STRUCT(type) && SPEC_STRUCT(getSpec(type))->type == UNION) {
- if (!list || (list->type == INIT_DEEP)) {
- if (list) list = list->init.deep;
- sym = SPEC_STRUCT(type)->fields;
- while (sym) {
- DEBUGprintf ("Checking UNION member %s.\n", sym->name);
- if (((IS_STRUCT(sym->type) || getSize(sym->type) == size))
- && matchIvalToUnion(list, sym->type, size))
- {
- DEBUGprintf ("Matched UNION member %s.\n", sym->name);
- return (sym->type);
- }
- sym = sym->next;
- } // while
- } // if
- // no match found
- DEBUGprintf ("ERROR, no match found.\n");
- return (NULL);
+ if (!list || (list->type == INIT_DEEP)) {
+ if (list) list = list->init.deep;
+ sym = SPEC_STRUCT(type)->fields;
+ while (sym) {
+ DEBUGprintf ("Checking UNION member %s.\n", sym->name);
+ if (((IS_STRUCT(sym->type) || getSize(sym->type) == size))
+ && matchIvalToUnion(list, sym->type, size))
+ {
+ DEBUGprintf ("Matched UNION member %s.\n", sym->name);
+ return (sym->type);
+ }
+ sym = sym->next;
+ } // while
+ } // if
+ // no match found
+ DEBUGprintf ("ERROR, no match found.\n");
+ return (NULL);
} else {
- assert ( !"Unhandled type in UNION." );
+ assert ( !"Unhandled type in UNION." );
}
assert ( !"No match found in UNION for the given initializer structure." );
size = getSize(my_type);
if (IS_PTR(my_type)) {
- DEBUGprintf ("(pointer, %d byte) %p\n", size, list ? (void *)(long)list2int(list) : NULL);
- emitIvals(oBuf, topsym, list, 0, size);
- return;
+ DEBUGprintf ("(pointer, %d byte) %p\n", size, list ? (void *)(long)list2int(list) : NULL);
+ emitIvals(oBuf, topsym, list, 0, size);
+ return;
}
if (IS_ARRAY(my_type) && topsym && topsym->isstrlit) {
- str = (unsigned char *)SPEC_CVAL(topsym->etype).v_char;
- emitIvalLabel(oBuf, topsym);
- do {
- dbuf_printf (oBuf, "\tretlw 0x%02x ; '%c'\n", str[0], (str[0] >= 0x20 && str[0] < 128) ? str[0] : '.');
- } while (*(str++));
- return;
+ str = (unsigned char *)SPEC_CVAL(topsym->etype).v_char;
+ emitIvalLabel(oBuf, topsym);
+ do {
+ dbuf_printf (oBuf, "\tretlw 0x%02x ; '%c'\n", str[0], (str[0] >= 0x20 && str[0] < 128) ? str[0] : '.');
+ } while (*(str++));
+ return;
}
if (IS_ARRAY(my_type) && list && list->type == INIT_NODE) {
- fprintf (stderr, "Unhandled initialized symbol: %s\n", topsym->name);
- assert ( !"Initialized char-arrays are not yet supported, assign at runtime instead." );
- return;
+ fprintf (stderr, "Unhandled initialized symbol: %s\n", topsym->name);
+ assert ( !"Initialized char-arrays are not yet supported, assign at runtime instead." );
+ return;
}
if (IS_ARRAY(my_type)) {
- DEBUGprintf ("(array, %d items, %d byte) below\n", DCL_ELEM(my_type), size);
- assert (!list || list->type == INIT_DEEP);
- if (list) list = list->init.deep;
- for (i = 0; i < DCL_ELEM(my_type); i++) {
- emitInitVal(oBuf, topsym, my_type->next, list);
- topsym = NULL;
- if (list) list = list->next;
- } // for i
- return;
+ DEBUGprintf ("(array, %d items, %d byte) below\n", DCL_ELEM(my_type), size);
+ assert (!list || list->type == INIT_DEEP);
+ if (list) list = list->init.deep;
+ for (i = 0; i < DCL_ELEM(my_type); i++) {
+ emitInitVal(oBuf, topsym, my_type->next, list);
+ topsym = NULL;
+ if (list) list = list->next;
+ } // for i
+ return;
}
if (IS_FLOAT(my_type)) {
- // float, 32 bit
- DEBUGprintf ("(float, %d byte) %lf\n", size, list ? list2int(list) : 0.0);
- emitIvals(oBuf, topsym, list, 0, size);
- return;
+ // float, 32 bit
+ DEBUGprintf ("(float, %d byte) %lf\n", size, list ? list2int(list) : 0.0);
+ emitIvals(oBuf, topsym, list, 0, size);
+ return;
}
if (IS_CHAR(my_type) || IS_INT(my_type) || IS_LONG(my_type)) {
- // integral type, 8, 16, or 32 bit
- DEBUGprintf ("(integral, %d byte) 0x%lx/%ld\n", size, list ? (long)list2int(list) : 0, list ? (long)list2int(list) : 0);
- emitIvals(oBuf, topsym, list, 0, size);
- return;
-
+ // integral type, 8, 16, or 32 bit
+ DEBUGprintf ("(integral, %d byte) 0x%lx/%ld\n", size, list ? (long)list2int(list) : 0, list ? (long)list2int(list) : 0);
+ emitIvals(oBuf, topsym, list, 0, size);
+ return;
+
} else if (IS_STRUCT(my_type) && SPEC_STRUCT(my_type)->type == STRUCT) {
- // struct
- DEBUGprintf ("(struct, %d byte) handled below\n", size);
- assert (!list || (list->type == INIT_DEEP));
-
- // iterate over struct members and initList
- if (list) list = list->init.deep;
- sym = SPEC_STRUCT(my_type)->fields;
- while (sym) {
- long bitfield = 0;
- int len = 0;
- if (IS_BITFIELD(sym->type)) {
- while (sym && IS_BITFIELD(sym->type)) {
- assert (!list || ((list->type == INIT_NODE)
- && IS_AST_LIT_VALUE(list->init.node)));
- lit = list ? list2int(list) : 0;
- DEBUGprintf ( "(bitfield member) %02lx (%d bit, starting at %d, bitfield %02lx)\n",
- lit, SPEC_BLEN(getSpec(sym->type)),
- SPEC_BSTR(getSpec(sym->type)), bitfield);
- bitfield |= (lit & ((1ul << SPEC_BLEN(getSpec(sym->type))) - 1)) << SPEC_BSTR(getSpec(sym->type));
- len += SPEC_BLEN(getSpec(sym->type));
-
- sym = sym->next;
- if (list) list = list->next;
- } // while
- assert (len < sizeof (long) * 8); // did we overflow our initializer?!?
- len = (len + 7) & ~0x07; // round up to full bytes
- emitIvals(oBuf, topsym, NULL, bitfield, len / 8);
- topsym = NULL;
- } // if
-
- if (sym) {
- emitInitVal(oBuf, topsym, sym->type, list);
- topsym = NULL;
- sym = sym->next;
- if (list) list = list->next;
- } // if
- } // while
- if (list) {
- assert ( !"Excess initializers." );
- } // if
- return;
-
+ // struct
+ DEBUGprintf ("(struct, %d byte) handled below\n", size);
+ assert (!list || (list->type == INIT_DEEP));
+
+ // iterate over struct members and initList
+ if (list) list = list->init.deep;
+ sym = SPEC_STRUCT(my_type)->fields;
+ while (sym) {
+ long bitfield = 0;
+ int len = 0;
+ if (IS_BITFIELD(sym->type)) {
+ while (sym && IS_BITFIELD(sym->type)) {
+ assert (!list || ((list->type == INIT_NODE)
+ && IS_AST_LIT_VALUE(list->init.node)));
+ lit = (long) (list ? list2int(list) : 0);
+ DEBUGprintf ( "(bitfield member) %02lx (%d bit, starting at %d, bitfield %02lx)\n",
+ lit, SPEC_BLEN(getSpec(sym->type)),
+ SPEC_BSTR(getSpec(sym->type)), bitfield);
+ bitfield |= (lit & ((1ul << SPEC_BLEN(getSpec(sym->type))) - 1)) << SPEC_BSTR(getSpec(sym->type));
+ len += SPEC_BLEN(getSpec(sym->type));
+
+ sym = sym->next;
+ if (list) list = list->next;
+ } // while
+ assert (len < sizeof (long) * 8); // did we overflow our initializer?!?
+ len = (len + 7) & ~0x07; // round up to full bytes
+ emitIvals(oBuf, topsym, NULL, bitfield, len / 8);
+ topsym = NULL;
+ } // if
+
+ if (sym) {
+ emitInitVal(oBuf, topsym, sym->type, list);
+ topsym = NULL;
+ sym = sym->next;
+ if (list) list = list->next;
+ } // if
+ } // while
+ if (list) {
+ assert ( !"Excess initializers." );
+ } // if
+ return;
+
} else if (IS_STRUCT(my_type) && SPEC_STRUCT(my_type)->type == UNION) {
- // union
- DEBUGprintf ("(union, %d byte) handled below\n", size);
- assert (list && list->type == INIT_DEEP);
-
- // iterate over union members and initList, try to map number and type of fields and initializers
- my_type = matchIvalToUnion(list, my_type, size);
- if (my_type) {
- emitInitVal(oBuf, topsym, my_type, list->init.deep);
- topsym = NULL;
- size -= getSize(my_type);
- if (size > 0) {
- // pad with (leading) zeros
- emitIvals(oBuf, NULL, NULL, 0, size);
- }
- return;
- } // if
-
- assert ( !"No UNION member matches the initializer structure.");
+ // union
+ DEBUGprintf ("(union, %d byte) handled below\n", size);
+ assert (list && list->type == INIT_DEEP);
+
+ // iterate over union members and initList, try to map number and type of fields and initializers
+ my_type = matchIvalToUnion(list, my_type, size);
+ if (my_type) {
+ emitInitVal(oBuf, topsym, my_type, list->init.deep);
+ topsym = NULL;
+ size -= getSize(my_type);
+ if (size > 0) {
+ // pad with (leading) zeros
+ emitIvals(oBuf, NULL, NULL, 0, size);
+ }
+ return;
+ } // if
+
+ assert ( !"No UNION member matches the initializer structure.");
} else if (IS_BITFIELD(my_type)) {
- assert ( !"bitfields should only occur in structs..." );
-
+ assert ( !"bitfields should only occur in structs..." );
+
} else {
- printf ("SPEC_NOUN: %d\n", SPEC_NOUN(my_type));
- assert( !"Unhandled initialized type.");
+ printf ("SPEC_NOUN: %d\n", SPEC_NOUN(my_type));
+ assert( !"Unhandled initialized type.");
}
}
for (sym = setFirstItem(s); sym; sym = setNextItem(s)) {
#if 0
- fprintf (stdout, "; name %s, rname %s, level %d, block %d, key %d, local %d, ival %p, static %d, cdef %d, used %d\n",
- sym->name, sym->rname, sym->level, sym->block, sym->key, sym->islocal, sym->ival, IS_STATIC(sym->etype), sym->cdef, sym->used);
+ fprintf (stdout, "; name %s, rname %s, level %d, block %d, key %d, local %d, ival %p, static %d, cdef %d, used %d\n",
+ sym->name, sym->rname, sym->level, sym->block, sym->key, sym->islocal, sym->ival, IS_STATIC(sym->etype), sym->cdef, sym->used);
#endif
- if (sym->etype && SPEC_ABSA(sym->etype)
- && IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype))
- && sym->ival)
- {
- // handle config words
- pic14_assignConfigWordValue(SPEC_ADDR(sym->etype),
- (int)list2int(sym->ival));
- pic14_stringInSet(sym->rname, &emitted, 1);
- continue;
- }
-
- if (sym->isstrlit) {
- // special case: string literals
- emitInitVal(ivalBuf, sym, sym->type, NULL);
- continue;
- }
-
- if (type != 0 || sym->cdef
- || (!IS_STATIC(sym->etype)
- && IS_GLOBAL(sym)))
- {
- // bail out for ___fsadd and friends
- if (sym->cdef && !sym->used) continue;
-
- /* export or import non-static globals */
- if (!pic14_stringInSet(sym->rname, &emitted, 0)) {
-
- if (type == 2 || IS_EXTERN(sym->etype) || sym->cdef)
- {
- /* do not add to emitted set, it might occur again! */
- //if (!sym->used) continue;
- // declare symbol
- emitIfNew (extBuf, &emitted, "\textern\t%s\n", sym->rname);
- } else {
- // declare symbol
- emitIfNew (gloBuf, &emitted, "\tglobal\t%s\n", sym->rname);
- if (!sym->ival && !IS_FUNC(sym->type)) {
- // also define symbol
- if (IS_ABSOLUTE(sym->etype)) {
- // absolute location?
- //dbuf_printf (gloDefBuf, "UD_%s_%u\tudata\t0x%04X\n", moduleName, sectionNr++, SPEC_ADDR(sym->etype));
- // deferred to pic14_constructAbsMap
- } else {
- dbuf_printf (gloDefBuf, "UD_%s_%u\tudata\n", moduleName, sectionNr++);
- dbuf_printf (gloDefBuf, "%s\tres\t%d\n\n", sym->rname, getSize(sym->type));
- }
- } // if
- } // if
- pic14_stringInSet(sym->rname, &emitted, 1);
- } // if
- } // if
- list = sym->ival;
- //if (list) showInitList(list, 0);
- if (list) {
- resolveIvalSym( list, sym->type );
- emitInitVal(ivalBuf, sym, sym->type, sym->ival);
- dbuf_printf (ivalBuf, "\n");
- }
+ if (sym->etype && SPEC_ABSA(sym->etype)
+ && IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype))
+ && sym->ival)
+ {
+ // handle config words
+ pic14_assignConfigWordValue(SPEC_ADDR(sym->etype),
+ (int)list2int(sym->ival));
+ pic14_stringInSet(sym->rname, &emitted, 1);
+ continue;
+ }
+
+ if (sym->isstrlit) {
+ // special case: string literals
+ emitInitVal(ivalBuf, sym, sym->type, NULL);
+ continue;
+ }
+
+ if (type != 0 || sym->cdef
+ || (!IS_STATIC(sym->etype)
+ && IS_GLOBAL(sym)))
+ {
+ // bail out for ___fsadd and friends
+ if (sym->cdef && !sym->used) continue;
+
+ /* export or import non-static globals */
+ if (!pic14_stringInSet(sym->rname, &emitted, 0)) {
+
+ if (type == 2 || IS_EXTERN(sym->etype) || sym->cdef)
+ {
+ /* do not add to emitted set, it might occur again! */
+ //if (!sym->used) continue;
+ // declare symbol
+ emitIfNew (extBuf, &emitted, "\textern\t%s\n", sym->rname);
+ } else {
+ // declare symbol
+ emitIfNew (gloBuf, &emitted, "\tglobal\t%s\n", sym->rname);
+ if (!sym->ival && !IS_FUNC(sym->type)) {
+ // also define symbol
+ if (IS_ABSOLUTE(sym->etype)) {
+ // absolute location?
+ //dbuf_printf (gloDefBuf, "UD_%s_%u\tudata\t0x%04X\n", moduleName, sectionNr++, SPEC_ADDR(sym->etype));
+ // deferred to pic14_constructAbsMap
+ } else {
+ dbuf_printf (gloDefBuf, "UD_%s_%u\tudata\n", moduleName, sectionNr++);
+ dbuf_printf (gloDefBuf, "%s\tres\t%d\n\n", sym->rname, getSize(sym->type));
+ }
+ } // if
+ } // if
+ pic14_stringInSet(sym->rname, &emitted, 1);
+ } // if
+ } // if
+ list = sym->ival;
+ //if (list) showInitList(list, 0);
+ if (list) {
+ resolveIvalSym( list, sym->type );
+ emitInitVal(ivalBuf, sym, sym->type, sym->ival);
+ dbuf_printf (ivalBuf, "\n");
+ }
} // for sym
}
{
struct dbuf_s locBuf;
memmap *maps[] = {
- xstack, istack, code, data, pdata, xdata, xidata, xinit,
- idata, bit, statsg, c_abs, x_abs, i_abs, d_abs,
- sfr, sfrbit, reg, generic, overlay, eeprom, home };
+ xstack, istack, code, data, pdata, xdata, xidata, xinit,
+ idata, bit, statsg, c_abs, x_abs, i_abs, d_abs,
+ sfr, sfrbit, reg, generic, overlay, eeprom, home };
memmap * map;
int i;
dbuf_printf (&locBuf, "%s; compiler-defined variables\n%s", iComments2, iComments2);
for (i = 0; i < sizeof(maps) / sizeof (memmap *); i++) {
- map = maps[i];
- //DEBUGprintf ("memmap %i: %p\n", i, map);
- if (map) {
+ map = maps[i];
+ //DEBUGprintf ("memmap %i: %p\n", i, map);
+ if (map) {
#if 0
- fprintf (stdout, "; pageno %c, sname %s, dbName %c, ptrType %d, slbl %d, sloc %u, fmap %u, paged %u, direct %u, bitsp %u, codesp %u, regsp %u, syms %p\n",
- map->pageno, map->sname, map->dbName, map->ptrType, map->slbl,
- map->sloc, map->fmap, map->paged, map->direct, map->bitsp,
- map->codesp, map->regsp, map->syms);
+ fprintf (stdout, "; pageno %c, sname %s, dbName %c, ptrType %d, slbl %d, sloc %u, fmap %u, paged %u, direct %u, bitsp %u, codesp %u, regsp %u, syms %p\n",
+ map->pageno, map->sname, map->dbName, map->ptrType, map->slbl,
+ map->sloc, map->fmap, map->paged, map->direct, map->bitsp,
+ map->codesp, map->regsp, map->syms);
#endif
- emitSymbolSet(map->syms, 0);
- } // if (map)
+ emitSymbolSet(map->syms, 0);
+ } // if (map)
} // for i
DEBUGprintf ("---end of memmaps---\n");
extBuf = gloBuf = gloDefBuf = ivalBuf = NULL;
}
-
/*------------------------------------------------------------------------
SDCCralloc.c - source file for register allocation. (8051) specific
-
- Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
- Added Pic Port T.scott Dattalo scott@dattalo.com (2000)
-
+
+ Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
+ Added Pic Port T.scott Dattalo scott@dattalo.com (2000)
+
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+
In other words, you are welcome to use, share and improve this program.
You are forbidden to forbid anyone else to use, share and improve
- what you give them. Help stamp out software-hoarding!
+ what you give them. Help stamp out software-hoarding!
-------------------------------------------------------------------------*/
#include "common.h"
#include "gen.h"
-#define FENTRY2 1 ? (void)0 : printf
+#define FENTRY2 1 ? (void)0 : printf
/* this should go in SDCCicode.h, but it doesn't. */
#define IS_REF(op) (IS_SYMOP(op) && op->operand.symOperand->isref == 1)
/* Global data */
static struct
{
- bitVect *spiltSet;
- set *stackSpil;
- bitVect *regAssigned;
- short blockSpil;
- int slocNum;
- bitVect *funcrUsed; /* registers used in a function */
- int stackExtend;
- int dataExtend;
+ bitVect *spiltSet;
+ set *stackSpil;
+ bitVect *regAssigned;
+ short blockSpil;
+ int slocNum;
+ bitVect *funcrUsed; /* registers used in a function */
+ int stackExtend;
+ int dataExtend;
}
_G;
/* Shared with gen.c */
-int pic14_ptrRegReq; /* one byte pointer register required */
+int pic14_ptrRegReq; /* one byte pointer register required */
set *dynAllocRegs=NULL;
int pic14_nRegs = 128; // = sizeof (regspic14) / sizeof (regs);
int Gstack_base_addr=0; /* The starting address of registers that
- * are used to pass and return parameters */
+ * are used to pass and return parameters */
int Gstack_size = 0;
static void spillThis (symbol *);
-static int debug = 0; // should be 0 when committed, creates .d files
+static int debug = 0; // should be 0 when committed, creates .d files
static FILE *debugF = NULL;
/*-----------------------------------------------------------------*/
/* debugLog - open a file for debugging information */
static void
debugLog (char *fmt,...)
{
- static int append = 0; // First time through, open the file without append.
+ static int append = 0; // First time through, open the file without append.
- char buffer[256];
- //char *bufferP=buffer;
- va_list ap;
+ char buffer[256];
+ //char *bufferP=buffer;
+ va_list ap;
- if (!debug || !dstFileName)
- return;
+ if (!debug || !dstFileName)
+ return;
- if (!debugF)
- {
- /* create the file name */
- strcpy (buffer, dstFileName);
- strcat (buffer, ".d");
+ if (!debugF)
+ {
+ /* create the file name */
+ strcpy (buffer, dstFileName);
+ strcat (buffer, ".d");
- if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
- {
- werror (E_FILE_OPEN_ERR, buffer);
- exit (1);
- }
- append = 1; // Next time debugLog is called, we'll append the debug info
+ if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
+ {
+ werror (E_FILE_OPEN_ERR, buffer);
+ exit (1);
+ }
+ append = 1; // Next time debugLog is called, we'll append the debug info
- }
+ }
- va_start (ap, fmt);
- vsprintf (buffer, fmt, ap);
- va_end (ap);
+ va_start (ap, fmt);
+ vsprintf (buffer, fmt, ap);
+ va_end (ap);
- fprintf (debugF, "%s", buffer);
- //if (options.verbose) fprintf (stderr, "%s: %s", __FUNCTION__, buffer);
+ fprintf (debugF, "%s", buffer);
+ //if (options.verbose) fprintf (stderr, "%s: %s", __FUNCTION__, buffer);
}
-
+
static void
debugNewLine (void)
{
- if (debugF)
- fputc ('\n', debugF);
+ if (debugF)
+ fputc ('\n', debugF);
}
/*-----------------------------------------------------------------*/
/* pic14_debugLogClose - closes the debug log file (if opened) */
void
pic14_debugLogClose (void)
{
- if (debugF)
- {
- fclose (debugF);
- debugF = NULL;
- }
+ if (debugF)
+ {
+ fclose (debugF);
+ debugF = NULL;
+ }
}
#define AOP(op) op->aop
-
+
static char *
debugAopGet (char *str, operand * op)
{
- if (!debug) return NULL;
+ if (!debug) return NULL;
if (str) debugLog (str);
- printOperand (op, debugF);
- debugNewLine ();
+ printOperand (op, debugF);
+ debugNewLine ();
- return NULL;
+ return NULL;
}
static char *
decodeOp (unsigned int op)
{
- if (op < 128 && op > ' ')
- {
- buffer[0] = (op & 0xff);
- buffer[1] = 0;
- return buffer;
- }
-
- switch (op)
- {
- case IDENTIFIER: return "IDENTIFIER";
- case TYPE_NAME: return "TYPE_NAME";
- case CONSTANT: return "CONSTANT";
- case STRING_LITERAL: return "STRING_LITERAL";
- case SIZEOF: return "SIZEOF";
- case PTR_OP: return "PTR_OP";
- case INC_OP: return "INC_OP";
- case DEC_OP: return "DEC_OP";
- case LEFT_OP: return "LEFT_OP";
- case RIGHT_OP: return "RIGHT_OP";
- case LE_OP: return "LE_OP";
- case GE_OP: return "GE_OP";
- case EQ_OP: return "EQ_OP";
- case NE_OP: return "NE_OP";
- case AND_OP: return "AND_OP";
- case OR_OP: return "OR_OP";
- case MUL_ASSIGN: return "MUL_ASSIGN";
- case DIV_ASSIGN: return "DIV_ASSIGN";
- case MOD_ASSIGN: return "MOD_ASSIGN";
- case ADD_ASSIGN: return "ADD_ASSIGN";
- case SUB_ASSIGN: return "SUB_ASSIGN";
- case LEFT_ASSIGN: return "LEFT_ASSIGN";
- case RIGHT_ASSIGN: return "RIGHT_ASSIGN";
- case AND_ASSIGN: return "AND_ASSIGN";
- case XOR_ASSIGN: return "XOR_ASSIGN";
- case OR_ASSIGN: return "OR_ASSIGN";
- case TYPEDEF: return "TYPEDEF";
- case EXTERN: return "EXTERN";
- case STATIC: return "STATIC";
- case AUTO: return "AUTO";
- case REGISTER: return "REGISTER";
- case CODE: return "CODE";
- case EEPROM: return "EEPROM";
- case INTERRUPT: return "INTERRUPT";
- case SFR: return "SFR";
- case AT: return "AT";
- case SBIT: return "SBIT";
- case REENTRANT: return "REENTRANT";
- case USING: return "USING";
- case XDATA: return "XDATA";
- case DATA: return "DATA";
- case IDATA: return "IDATA";
- case PDATA: return "PDATA";
- case VAR_ARGS: return "VAR_ARGS";
- case CRITICAL: return "CRITICAL";
- case NONBANKED: return "NONBANKED";
- case BANKED: return "BANKED";
- case CHAR: return "CHAR";
- case SHORT: return "SHORT";
- case INT: return "INT";
- case LONG: return "LONG";
- case SIGNED: return "SIGNED";
- case UNSIGNED: return "UNSIGNED";
- case FLOAT: return "FLOAT";
- case DOUBLE: return "DOUBLE";
- case CONST: return "CONST";
- case VOLATILE: return "VOLATILE";
- case VOID: return "VOID";
- case BIT: return "BIT";
- case STRUCT: return "STRUCT";
- case UNION: return "UNION";
- case ENUM: return "ENUM";
- case RANGE: return "RANGE";
- case FAR: return "FAR";
- case CASE: return "CASE";
- case DEFAULT: return "DEFAULT";
- case IF: return "IF";
- case ELSE: return "ELSE";
- case SWITCH: return "SWITCH";
- case WHILE: return "WHILE";
- case DO: return "DO";
- case FOR: return "FOR";
- case GOTO: return "GOTO";
- case CONTINUE: return "CONTINUE";
- case BREAK: return "BREAK";
- case RETURN: return "RETURN";
- case INLINEASM: return "INLINEASM";
- case IFX: return "IFX";
- case ADDRESS_OF: return "ADDRESS_OF";
- case GET_VALUE_AT_ADDRESS: return "GET_VALUE_AT_ADDRESS";
- case SPIL: return "SPIL";
- case UNSPIL: return "UNSPIL";
- case GETHBIT: return "GETHBIT";
- case BITWISEAND: return "BITWISEAND";
- case UNARYMINUS: return "UNARYMINUS";
- case IPUSH: return "IPUSH";
- case IPOP: return "IPOP";
- case PCALL: return "PCALL";
- case ENDFUNCTION: return "ENDFUNCTION";
- case JUMPTABLE: return "JUMPTABLE";
- case RRC: return "RRC";
- case RLC: return "RLC";
- case CAST: return "CAST";
- case CALL: return "CALL";
- case PARAM: return "PARAM ";
- case NULLOP: return "NULLOP";
- case BLOCK: return "BLOCK";
- case LABEL: return "LABEL";
- case RECEIVE: return "RECEIVE";
- case SEND: return "SEND";
- }
- sprintf (buffer, "unknown op %d %c", op, op & 0xff);
- return buffer;
+ if (op < 128 && op > ' ')
+ {
+ buffer[0] = (op & 0xff);
+ buffer[1] = 0;
+ return buffer;
+ }
+
+ switch (op)
+ {
+ case IDENTIFIER: return "IDENTIFIER";
+ case TYPE_NAME: return "TYPE_NAME";
+ case CONSTANT: return "CONSTANT";
+ case STRING_LITERAL: return "STRING_LITERAL";
+ case SIZEOF: return "SIZEOF";
+ case PTR_OP: return "PTR_OP";
+ case INC_OP: return "INC_OP";
+ case DEC_OP: return "DEC_OP";
+ case LEFT_OP: return "LEFT_OP";
+ case RIGHT_OP: return "RIGHT_OP";
+ case LE_OP: return "LE_OP";
+ case GE_OP: return "GE_OP";
+ case EQ_OP: return "EQ_OP";
+ case NE_OP: return "NE_OP";
+ case AND_OP: return "AND_OP";
+ case OR_OP: return "OR_OP";
+ case MUL_ASSIGN: return "MUL_ASSIGN";
+ case DIV_ASSIGN: return "DIV_ASSIGN";
+ case MOD_ASSIGN: return "MOD_ASSIGN";
+ case ADD_ASSIGN: return "ADD_ASSIGN";
+ case SUB_ASSIGN: return "SUB_ASSIGN";
+ case LEFT_ASSIGN: return "LEFT_ASSIGN";
+ case RIGHT_ASSIGN: return "RIGHT_ASSIGN";
+ case AND_ASSIGN: return "AND_ASSIGN";
+ case XOR_ASSIGN: return "XOR_ASSIGN";
+ case OR_ASSIGN: return "OR_ASSIGN";
+ case TYPEDEF: return "TYPEDEF";
+ case EXTERN: return "EXTERN";
+ case STATIC: return "STATIC";
+ case AUTO: return "AUTO";
+ case REGISTER: return "REGISTER";
+ case CODE: return "CODE";
+ case EEPROM: return "EEPROM";
+ case INTERRUPT: return "INTERRUPT";
+ case SFR: return "SFR";
+ case AT: return "AT";
+ case SBIT: return "SBIT";
+ case REENTRANT: return "REENTRANT";
+ case USING: return "USING";
+ case XDATA: return "XDATA";
+ case DATA: return "DATA";
+ case IDATA: return "IDATA";
+ case PDATA: return "PDATA";
+ case VAR_ARGS: return "VAR_ARGS";
+ case CRITICAL: return "CRITICAL";
+ case NONBANKED: return "NONBANKED";
+ case BANKED: return "BANKED";
+ case CHAR: return "CHAR";
+ case SHORT: return "SHORT";
+ case INT: return "INT";
+ case LONG: return "LONG";
+ case SIGNED: return "SIGNED";
+ case UNSIGNED: return "UNSIGNED";
+ case FLOAT: return "FLOAT";
+ case DOUBLE: return "DOUBLE";
+ case CONST: return "CONST";
+ case VOLATILE: return "VOLATILE";
+ case VOID: return "VOID";
+ case BIT: return "BIT";
+ case STRUCT: return "STRUCT";
+ case UNION: return "UNION";
+ case ENUM: return "ENUM";
+ case RANGE: return "RANGE";
+ case FAR: return "FAR";
+ case CASE: return "CASE";
+ case DEFAULT: return "DEFAULT";
+ case IF: return "IF";
+ case ELSE: return "ELSE";
+ case SWITCH: return "SWITCH";
+ case WHILE: return "WHILE";
+ case DO: return "DO";
+ case FOR: return "FOR";
+ case GOTO: return "GOTO";
+ case CONTINUE: return "CONTINUE";
+ case BREAK: return "BREAK";
+ case RETURN: return "RETURN";
+ case INLINEASM: return "INLINEASM";
+ case IFX: return "IFX";
+ case ADDRESS_OF: return "ADDRESS_OF";
+ case GET_VALUE_AT_ADDRESS: return "GET_VALUE_AT_ADDRESS";
+ case SPIL: return "SPIL";
+ case UNSPIL: return "UNSPIL";
+ case GETHBIT: return "GETHBIT";
+ case BITWISEAND: return "BITWISEAND";
+ case UNARYMINUS: return "UNARYMINUS";
+ case IPUSH: return "IPUSH";
+ case IPOP: return "IPOP";
+ case PCALL: return "PCALL";
+ case ENDFUNCTION: return "ENDFUNCTION";
+ case JUMPTABLE: return "JUMPTABLE";
+ case RRC: return "RRC";
+ case RLC: return "RLC";
+ case CAST: return "CAST";
+ case CALL: return "CALL";
+ case PARAM: return "PARAM ";
+ case NULLOP: return "NULLOP";
+ case BLOCK: return "BLOCK";
+ case LABEL: return "LABEL";
+ case RECEIVE: return "RECEIVE";
+ case SEND: return "SEND";
+ }
+ sprintf (buffer, "unknown op %d %c", op, op & 0xff);
+ return buffer;
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static char *
debugLogRegType (short type)
{
-
- switch (type)
- {
- case REG_GPR: return "REG_GPR";
- case REG_PTR: return "REG_PTR";
- case REG_CND: return "REG_CND";
- }
-
- sprintf (buffer, "unknown reg type %d", type);
- return buffer;
+
+ switch (type)
+ {
+ case REG_GPR: return "REG_GPR";
+ case REG_PTR: return "REG_PTR";
+ case REG_CND: return "REG_CND";
+ }
+
+ sprintf (buffer, "unknown reg type %d", type);
+ return buffer;
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static int regname2key(char const *name)
{
- int key = 0;
-
- if(!name)
- return 0;
-
- while(*name) {
-
- key += (*name++) + 1;
-
- }
-
- return ( (key + (key >> 4) + (key>>8)) & 0x3f);
-
+ int key = 0;
+
+ if(!name)
+ return 0;
+
+ while(*name) {
+
+ key += (*name++) + 1;
+
+ }
+
+ return ( (key + (key >> 4) + (key>>8)) & 0x3f);
+
}
static regs *regWithIdx (set *dRegs, int idx, int fixed);
/*-----------------------------------------------------------------*/
static regs* newReg(short type, PIC_OPTYPE pc_type, int rIdx, char *name, int size, int alias)
{
-
- regs *dReg, *reg_alias;
-
- /* check whether a matching register already exists */
- dReg = dirregWithName( name );
- if (dReg) {
- //printf( "%s: already present: %s\n", __FUNCTION__, name );
- return (dReg);
- }
-
- // check whether a register at that location exists
- reg_alias = regWithIdx( dynDirectRegs, rIdx, 0 );
- if (!reg_alias) reg_alias = regWithIdx( dynDirectRegs, rIdx, 1 );
-
- // create a new register
- dReg = Safe_calloc(1,sizeof(regs));
- dReg->type = type;
- dReg->pc_type = pc_type;
- dReg->rIdx = rIdx;
- if(name) {
- dReg->name = Safe_strdup(name);
- } else {
- sprintf(buffer,"r0x%02X", dReg->rIdx);
- dReg->name = Safe_strdup(buffer);
- }
- dReg->isFree = 0;
- dReg->wasUsed = 0;
- if (type == REG_SFR)
- dReg->isFixed = 1;
- else
- dReg->isFixed = 0;
-
- dReg->isMapped = 0;
- dReg->isEmitted = 0;
- dReg->isPublic = 0;
- dReg->isExtern = 0;
- dReg->address = 0;
- dReg->size = size;
- dReg->alias = alias;
- dReg->reg_alias = reg_alias;
- dReg->reglives.usedpFlows = newSet();
- dReg->reglives.assignedpFlows = newSet();
- if (type != REG_STK) hTabAddItem(&dynDirectRegNames, regname2key(dReg->name), dReg);
- debugLog( "%s: Created register %s.\n", __FUNCTION__, dReg->name);
-
- return dReg;
+
+ regs *dReg, *reg_alias;
+
+ /* check whether a matching register already exists */
+ dReg = dirregWithName( name );
+ if (dReg) {
+ //printf( "%s: already present: %s\n", __FUNCTION__, name );
+ return (dReg);
+ }
+
+ // check whether a register at that location exists
+ reg_alias = regWithIdx( dynDirectRegs, rIdx, 0 );
+ if (!reg_alias) reg_alias = regWithIdx( dynDirectRegs, rIdx, 1 );
+
+ // create a new register
+ dReg = Safe_calloc(1,sizeof(regs));
+ dReg->type = type;
+ dReg->pc_type = pc_type;
+ dReg->rIdx = rIdx;
+ if(name) {
+ dReg->name = Safe_strdup(name);
+ } else {
+ sprintf(buffer,"r0x%02X", dReg->rIdx);
+ dReg->name = Safe_strdup(buffer);
+ }
+ dReg->isFree = 0;
+ dReg->wasUsed = 0;
+ if (type == REG_SFR)
+ dReg->isFixed = 1;
+ else
+ dReg->isFixed = 0;
+
+ dReg->isMapped = 0;
+ dReg->isEmitted = 0;
+ dReg->isPublic = 0;
+ dReg->isExtern = 0;
+ dReg->address = 0;
+ dReg->size = size;
+ dReg->alias = alias;
+ dReg->reg_alias = reg_alias;
+ dReg->reglives.usedpFlows = newSet();
+ dReg->reglives.assignedpFlows = newSet();
+ if (type != REG_STK) hTabAddItem(&dynDirectRegNames, regname2key(dReg->name), dReg);
+ debugLog( "%s: Created register %s.\n", __FUNCTION__, dReg->name);
+
+ return dReg;
}
/*-----------------------------------------------------------------*/
static regs *
regWithIdx (set *dRegs, int idx, int fixed)
{
- regs *dReg;
-
- for (dReg = setFirstItem(dRegs) ; dReg ;
- dReg = setNextItem(dRegs)) {
-
- if(idx == dReg->rIdx && (fixed == (int)dReg->isFixed)) {
- while (dReg->reg_alias) dReg = dReg->reg_alias;
- return dReg;
- }
- }
-
- return NULL;
+ regs *dReg;
+
+ for (dReg = setFirstItem(dRegs) ; dReg ;
+ dReg = setNextItem(dRegs)) {
+
+ if(idx == dReg->rIdx && (fixed == (int)dReg->isFixed)) {
+ while (dReg->reg_alias) dReg = dReg->reg_alias;
+ return dReg;
+ }
+ }
+
+ return NULL;
}
/*-----------------------------------------------------------------*/
static regs *
regWithName (set *dRegs, const char *name)
{
- regs *dReg;
-
- for (dReg = setFirstItem(dRegs) ; dReg ;
- dReg = setNextItem(dRegs)) {
-
- if((strcmp(name,dReg->name)==0)) {
- return dReg;
- }
- }
-
- return NULL;
+ regs *dReg;
+
+ for (dReg = setFirstItem(dRegs) ; dReg ;
+ dReg = setNextItem(dRegs)) {
+
+ if((strcmp(name,dReg->name)==0)) {
+ return dReg;
+ }
+ }
+
+ return NULL;
}
/*-----------------------------------------------------------------*/
regs *
regFindWithName (const char *name)
{
- regs *dReg;
-
- if( (dReg = regWithName ( dynDirectRegs, name)) != NULL ) {
- debugLog ("Found a Direct Register!\n");
- return dReg;
- }
- if( (dReg = regWithName ( dynDirectBitRegs, name)) != NULL) {
- debugLog ("Found a Direct Bit Register!\n");
- return dReg;
- }
-
- if (*name=='_') name++; // Step passed '_'
-
- if( (dReg = regWithName ( dynAllocRegs, name)) != NULL) {
- debugLog ("Found a Dynamic Register!\n");
- return dReg;
- }
- if( (dReg = regWithName ( dynProcessorRegs, name)) != NULL) {
- debugLog ("Found a Processor Register!\n");
- return dReg;
- }
- if( (dReg = regWithName ( dynInternalRegs, name)) != NULL) {
- debugLog ("Found an Internal Register!\n");
- return dReg;
- }
- if( (dReg = regWithName ( dynStackRegs, name)) != NULL) {
- debugLog ("Found an Stack Register!\n");
- return dReg;
- }
-
- return NULL;
+ regs *dReg;
+
+ if( (dReg = regWithName ( dynDirectRegs, name)) != NULL ) {
+ debugLog ("Found a Direct Register!\n");
+ return dReg;
+ }
+ if( (dReg = regWithName ( dynDirectBitRegs, name)) != NULL) {
+ debugLog ("Found a Direct Bit Register!\n");
+ return dReg;
+ }
+
+ if (*name=='_') name++; // Step passed '_'
+
+ if( (dReg = regWithName ( dynAllocRegs, name)) != NULL) {
+ debugLog ("Found a Dynamic Register!\n");
+ return dReg;
+ }
+ if( (dReg = regWithName ( dynProcessorRegs, name)) != NULL) {
+ debugLog ("Found a Processor Register!\n");
+ return dReg;
+ }
+ if( (dReg = regWithName ( dynInternalRegs, name)) != NULL) {
+ debugLog ("Found an Internal Register!\n");
+ return dReg;
+ }
+ if( (dReg = regWithName ( dynStackRegs, name)) != NULL) {
+ debugLog ("Found an Stack Register!\n");
+ return dReg;
+ }
+
+ return NULL;
}
/*-----------------------------------------------------------------*/
static regs *
regFindFree (set *dRegs)
{
- regs *dReg;
-
- for (dReg = setFirstItem(dRegs) ; dReg ;
- dReg = setNextItem(dRegs)) {
-
- if(dReg->isFree)
- return dReg;
- }
-
- return NULL;
+ regs *dReg;
+
+ for (dReg = setFirstItem(dRegs) ; dReg ;
+ dReg = setNextItem(dRegs)) {
+
+ if(dReg->isFree)
+ return dReg;
+ }
+
+ return NULL;
}
/*-----------------------------------------------------------------*/
/* initStack - allocate registers for a pseudo stack */
/*-----------------------------------------------------------------*/
void initStack(int base_address, int size, int shared)
{
-
- int i;
- PIC_device *pic;
-
- pic = pic14_getPIC();
- Gstack_base_addr = base_address;
- Gstack_size = size;
- //fprintf(stderr,"initStack [base:0x%02x, size:%d]\n", base_address, size);
-
- for(i = 0; i<size; i++) {
- char buffer[16];
- regs *r;
- SNPRINTF(&buffer[0], 16, "STK%02d", i);
- // multi-bank device, sharebank prohibited by user
- r = newReg(REG_STK, PO_GPR_TEMP, base_address--, buffer, 1, shared ? (pic ? pic->bankMask : 0x180) : 0x0);
- r->isFixed = 1;
- r->isPublic = 1;
- r->isEmitted = 1;
- //r->name[0] = 's';
- addSet(&dynStackRegs,r);
- }
+
+ int i;
+ PIC_device *pic;
+
+ pic = pic14_getPIC();
+ Gstack_base_addr = base_address;
+ Gstack_size = size;
+ //fprintf(stderr,"initStack [base:0x%02x, size:%d]\n", base_address, size);
+
+ for(i = 0; i<size; i++) {
+ char buffer[16];
+ regs *r;
+ SNPRINTF(&buffer[0], 16, "STK%02d", i);
+ // multi-bank device, sharebank prohibited by user
+ r = newReg(REG_STK, PO_GPR_TEMP, base_address--, buffer, 1, shared ? (pic ? pic->bankMask : 0x180) : 0x0);
+ r->isFixed = 1;
+ r->isPublic = 1;
+ r->isEmitted = 1;
+ //r->name[0] = 's';
+ addSet(&dynStackRegs,r);
+ }
}
/*-----------------------------------------------------------------*
regs *
allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
{
-
- //fprintf(stderr,"allocProcessorRegister %s addr =0x%x\n",name,rIdx);
- return addSet(&dynProcessorRegs,newReg(REG_SFR, po_type, rIdx, name,1,alias));
+
+ //fprintf(stderr,"allocProcessorRegister %s addr =0x%x\n",name,rIdx);
+ return addSet(&dynProcessorRegs,newReg(REG_SFR, po_type, rIdx, name,1,alias));
}
/*-----------------------------------------------------------------*
regs *
allocInternalRegister(int rIdx, char * name, PIC_OPTYPE po_type, int alias)
{
- regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias);
-
- //fprintf(stderr,"allocInternalRegister %s addr =0x%x\n",name,rIdx);
- if(reg) {
- reg->wasUsed = 0;
- return addSet(&dynInternalRegs,reg);
- }
-
- return NULL;
+ regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias);
+
+ //fprintf(stderr,"allocInternalRegister %s addr =0x%x\n",name,rIdx);
+ if(reg) {
+ reg->wasUsed = 0;
+ return addSet(&dynInternalRegs,reg);
+ }
+
+ return NULL;
}
/*-----------------------------------------------------------------*/
/* allocReg - allocates register of given type */
static regs *
allocReg (short type)
{
- regs *reg;
-
- debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
- //fprintf(stderr,"allocReg\n");
-
- reg = pic14_findFreeReg (type);
-
- reg->isFree = 0;
- reg->wasUsed = 1;
-
- return reg;
-
-
- //return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
-
+ regs *reg;
+
+ debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
+ //fprintf(stderr,"allocReg\n");
+
+ reg = pic14_findFreeReg (type);
+
+ reg->isFree = 0;
+ reg->wasUsed = 1;
+
+ return reg;
+
+
+ //return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
+
}
regs *
dirregWithName (char *name)
{
- int hkey;
- regs *reg;
-
- if(!name)
- return NULL;
-
- /* hash the name to get a key */
-
- hkey = regname2key(name);
-
- reg = hTabFirstItemWK(dynDirectRegNames, hkey);
-
- while(reg) {
-
- if(STRCASECMP(reg->name, name) == 0) {
- // handle registers with multiple names
- while (reg->reg_alias) reg = reg->reg_alias;
- return(reg);
- }
-
- reg = hTabNextItemWK (dynDirectRegNames);
-
- }
-
- return NULL; // name wasn't found in the hash table
+ int hkey;
+ regs *reg;
+
+ if(!name)
+ return NULL;
+
+ /* hash the name to get a key */
+
+ hkey = regname2key(name);
+
+ reg = hTabFirstItemWK(dynDirectRegNames, hkey);
+
+ while(reg) {
+
+ if(STRCASECMP(reg->name, name) == 0) {
+ // handle registers with multiple names
+ while (reg->reg_alias) reg = reg->reg_alias;
+ return(reg);
+ }
+
+ reg = hTabNextItemWK (dynDirectRegNames);
+
+ }
+
+ return NULL; // name wasn't found in the hash table
}
int IS_CONFIG_ADDRESS(int address)
{
-
- return ((address == 0x2007) || (address == 0x2008));
+
+ return ((address == 0x2007) || (address == 0x2008));
}
/*-----------------------------------------------------------------*/
regs *
allocNewDirReg (sym_link *symlnk,const char *name)
{
- regs *reg;
- int address = 0;
- sym_link *spec = getSpec (symlnk);
-
- /* if this is at an absolute address, then get the address. */
- if (SPEC_ABSA (spec) ) {
- address = SPEC_ADDR (spec);
- //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
- }
-
- /* Register wasn't found in hash, so let's create
- * a new one and put it in the hash table AND in the
- * dynDirectRegNames set */
- if (IS_CONFIG_ADDRESS(address)) {
- debugLog (" -- %s is declared at address 0x2007\n",name);
- reg = 0;
- } else {
- int idx;
- if (address) {
- if (IS_BITVAR (spec))
- idx = address >> 3;
- else
- idx = address;
- } else {
- idx = dynrIdx++;
- }
- reg = newReg(REG_GPR, PO_DIR, idx, (char*)name,getSize (symlnk),0 );
- debugLog (" -- added %s to hash, size = %d\n", (char*)name,reg->size);
-
- if (SPEC_ABSA (spec) ) {
- reg->type = REG_SFR;
- }
-
- if (IS_BITVAR (spec)) {
- addSet(&dynDirectBitRegs, reg);
- reg->isBitField = 1;
- } else
- addSet(&dynDirectRegs, reg);
-
- if (!IS_STATIC (spec)) {
- reg->isPublic = 1;
- }
- if (IS_EXTERN (spec)) {
- reg->isExtern = 1;
- }
-
- }
-
- if (address && reg) {
- reg->isFixed = 1;
- reg->address = address;
- debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
- }
-
- return reg;
+ regs *reg;
+ int address = 0;
+ sym_link *spec = getSpec (symlnk);
+
+ /* if this is at an absolute address, then get the address. */
+ if (SPEC_ABSA (spec) ) {
+ address = SPEC_ADDR (spec);
+ //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
+ }
+
+ /* Register wasn't found in hash, so let's create
+ * a new one and put it in the hash table AND in the
+ * dynDirectRegNames set */
+ if (IS_CONFIG_ADDRESS(address)) {
+ debugLog (" -- %s is declared at address 0x2007\n",name);
+ reg = 0;
+ } else {
+ int idx;
+ if (address) {
+ if (IS_BITVAR (spec))
+ idx = address >> 3;
+ else
+ idx = address;
+ } else {
+ idx = dynrIdx++;
+ }
+ reg = newReg(REG_GPR, PO_DIR, idx, (char*)name,getSize (symlnk),0 );
+ debugLog (" -- added %s to hash, size = %d\n", (char*)name,reg->size);
+
+ if (SPEC_ABSA (spec) ) {
+ reg->type = REG_SFR;
+ }
+
+ if (IS_BITVAR (spec)) {
+ addSet(&dynDirectBitRegs, reg);
+ reg->isBitField = 1;
+ } else
+ addSet(&dynDirectRegs, reg);
+
+ if (!IS_STATIC (spec)) {
+ reg->isPublic = 1;
+ }
+ if (IS_EXTERN (spec)) {
+ reg->isExtern = 1;
+ }
+
+ }
+
+ if (address && reg) {
+ reg->isFixed = 1;
+ reg->address = address;
+ debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
+ }
+
+ return reg;
}
/*-----------------------------------------------------------------*/
regs *
allocDirReg (operand *op )
{
-
- regs *reg;
- char *name;
-
- if(!IS_SYMOP(op)) {
- debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
- return NULL;
- }
-
- name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
-
- /* If the symbol is at a fixed address, then remove the leading underscore
- * from the name. This is hack to allow the .asm include file named registers
- * to match the .c declared register names */
-
- //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
- //name++;
-
- debugLog ("%s symbol name %s\n", __FUNCTION__,name);
- {
- if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
- debugLog(" %d const char\n",__LINE__);
- debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
- }
-
- debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
- if (IS_CODE ( OP_SYM_ETYPE(op)) )
- debugLog(" %d code space\n",__LINE__);
-
- if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
- debugLog(" %d integral\n",__LINE__);
- if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
- debugLog(" %d literal\n",__LINE__);
- if (IS_SPEC ( OP_SYM_ETYPE(op)) )
- debugLog(" %d specifier\n",__LINE__);
- debugAopGet(NULL, op);
- }
-
- if (IS_CODE ( OP_SYM_ETYPE(op)) )
- return NULL;
-
- /* First, search the hash table to see if there is a register with this name */
- if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
- reg = regWithIdx (dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
- /*
- if(!reg)
- fprintf(stderr,"ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
- name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
- else
- fprintf(stderr,"ralloc %s at fixed address has already been declared, addr=0x%x\n",
- name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
- */
- } else {
- //fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
-
- reg = dirregWithName(name);
- }
-
+
+ regs *reg;
+ char *name;
+
+ if(!IS_SYMOP(op)) {
+ debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
+ return NULL;
+ }
+
+ name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
+
+ /* If the symbol is at a fixed address, then remove the leading underscore
+ * from the name. This is hack to allow the .asm include file named registers
+ * to match the .c declared register names */
+
+ //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
+ //name++;
+
+ debugLog ("%s symbol name %s\n", __FUNCTION__,name);
+ {
+ if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
+ debugLog(" %d const char\n",__LINE__);
+ debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
+ }
+
+ debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
+ if (IS_CODE ( OP_SYM_ETYPE(op)) )
+ debugLog(" %d code space\n",__LINE__);
+
+ if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
+ debugLog(" %d integral\n",__LINE__);
+ if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
+ debugLog(" %d literal\n",__LINE__);
+ if (IS_SPEC ( OP_SYM_ETYPE(op)) )
+ debugLog(" %d specifier\n",__LINE__);
+ debugAopGet(NULL, op);
+ }
+
+ if (IS_CODE ( OP_SYM_ETYPE(op)) )
+ return NULL;
+
+ /* First, search the hash table to see if there is a register with this name */
+ if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
+ reg = regWithIdx (dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
+ /*
+ if(!reg)
+ fprintf(stderr,"ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
+ name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
+ else
+ fprintf(stderr,"ralloc %s at fixed address has already been declared, addr=0x%x\n",
+ name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
+ */
+ } else {
+ //fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
+
+ reg = dirregWithName(name);
+ }
+
#if 0
- if(!reg) {
- int address = 0;
-
- /* if this is at an absolute address, then get the address. */
- if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
- address = SPEC_ADDR ( OP_SYM_ETYPE(op));
- //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
- }
-
- /* Register wasn't found in hash, so let's create
- * a new one and put it in the hash table AND in the
- * dynDirectRegNames set */
- if(!IS_CONFIG_ADDRESS(address)) {
- //fprintf(stderr,"allocating new reg %s\n",name);
-
- reg = newReg(REG_GPR, PO_DIR, dynrIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
- debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
-
- //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
-
- if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
-
- //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
- reg->type = REG_SFR;
- }
-
- if (IS_BITVAR (OP_SYM_ETYPE(op))) {
- addSet(&dynDirectBitRegs, reg);
- reg->isBitField = 1;
- } else
- addSet(&dynDirectRegs, reg);
-
- if (!IS_STATIC (OP_SYM_ETYPE(op))) {
- reg->isPublic = 1;
- }
- if (IS_EXTERN (OP_SYM_ETYPE(op))) {
- reg->isExtern = 1;
- }
-
-
- } else {
- debugLog (" -- %s is declared at address 0x2007\n",name);
-
- }
- }
-
- if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
- reg->isFixed = 1;
- reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
- debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
- }
+ if(!reg) {
+ int address = 0;
+
+ /* if this is at an absolute address, then get the address. */
+ if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
+ address = SPEC_ADDR ( OP_SYM_ETYPE(op));
+ //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
+ }
+
+ /* Register wasn't found in hash, so let's create
+ * a new one and put it in the hash table AND in the
+ * dynDirectRegNames set */
+ if(!IS_CONFIG_ADDRESS(address)) {
+ //fprintf(stderr,"allocating new reg %s\n",name);
+
+ reg = newReg(REG_GPR, PO_DIR, dynrIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
+ debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
+
+ //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
+
+ if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
+
+ //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
+ reg->type = REG_SFR;
+ }
+
+ if (IS_BITVAR (OP_SYM_ETYPE(op))) {
+ addSet(&dynDirectBitRegs, reg);
+ reg->isBitField = 1;
+ } else
+ addSet(&dynDirectRegs, reg);
+
+ if (!IS_STATIC (OP_SYM_ETYPE(op))) {
+ reg->isPublic = 1;
+ }
+ if (IS_EXTERN (OP_SYM_ETYPE(op))) {
+ reg->isExtern = 1;
+ }
+
+
+ } else {
+ debugLog (" -- %s is declared at address 0x2007\n",name);
+
+ }
+ }
+
+ if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
+ reg->isFixed = 1;
+ reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
+ debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
+ }
#endif
-
- if(reg) {
- if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
- reg->isFixed = 1;
- reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
- debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
- }
- } else {
- allocNewDirReg (OP_SYM_TYPE(op),name);
- }
-
- return reg;
+
+ if(reg) {
+ if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
+ reg->isFixed = 1;
+ reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
+ debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
+ }
+ } else {
+ allocNewDirReg (OP_SYM_TYPE(op),name);
+ }
+
+ return reg;
}
regs *
allocRegByName (char *name, int size)
{
-
- regs *reg;
-
- if(!name) {
- fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
- exit(1);
- }
-
- /* First, search the hash table to see if there is a register with this name */
- reg = dirregWithName(name);
-
-
- if(!reg) {
- int found = 0;
- symbol *sym;
- /* Register wasn't found in hash, so let's create
- * a new one and put it in the hash table AND in the
- * dynDirectRegNames set */
- //fprintf (stderr,"%s symbol name %s, size:%d\n", __FUNCTION__,name,size);
- reg = newReg(REG_GPR, PO_DIR, dynrIdx++, name,size,0 );
- for (sym = setFirstItem(sfr->syms); sym; sym = setNextItem(sfr->syms)) {
- if (strcmp(reg->name+1,sym->name)==0) {
- unsigned a = SPEC_ADDR(sym->etype);
- reg->address = a;
- reg->isFixed = 1;
- reg->type = REG_SFR;
- if (!IS_STATIC (sym->etype)) {
- reg->isPublic = 1;
- }
- if (IS_EXTERN (sym->etype)) {
- reg->isExtern = 1;
- }
- if (IS_BITVAR (sym->etype))
- reg->isBitField = 1;
- found = 1;
- break;
- }
- }
- if (!found) {
- for (sym = setFirstItem(data->syms); sym; sym = setNextItem(data->syms)) {
- if (strcmp(reg->name+1,sym->name)==0) {
- unsigned a = SPEC_ADDR(sym->etype);
- reg->address = a;
- if (!IS_STATIC (sym->etype)) {
- reg->isPublic = 1;
- }
- if (IS_EXTERN (sym->etype)) {
- reg->isExtern = 1;
- }
- if (IS_BITVAR (sym->etype))
- reg->isBitField = 1;
- found = 1;
- break;
- }
- }
- }
-
- debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
-
- //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
- if (reg->isBitField) {
- addSet(&dynDirectBitRegs, reg);
- } else
- addSet(&dynDirectRegs, reg);
- }
-
- return reg;
+
+ regs *reg;
+
+ if(!name) {
+ fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
+ exit(1);
+ }
+
+ /* First, search the hash table to see if there is a register with this name */
+ reg = dirregWithName(name);
+
+
+ if(!reg) {
+ int found = 0;
+ symbol *sym;
+ /* Register wasn't found in hash, so let's create
+ * a new one and put it in the hash table AND in the
+ * dynDirectRegNames set */
+ //fprintf (stderr,"%s symbol name %s, size:%d\n", __FUNCTION__,name,size);
+ reg = newReg(REG_GPR, PO_DIR, dynrIdx++, name,size,0 );
+ for (sym = setFirstItem(sfr->syms); sym; sym = setNextItem(sfr->syms)) {
+ if (strcmp(reg->name+1,sym->name)==0) {
+ unsigned a = SPEC_ADDR(sym->etype);
+ reg->address = a;
+ reg->isFixed = 1;
+ reg->type = REG_SFR;
+ if (!IS_STATIC (sym->etype)) {
+ reg->isPublic = 1;
+ }
+ if (IS_EXTERN (sym->etype)) {
+ reg->isExtern = 1;
+ }
+ if (IS_BITVAR (sym->etype))
+ reg->isBitField = 1;
+ found = 1;
+ break;
+ }
+ }
+ if (!found) {
+ for (sym = setFirstItem(data->syms); sym; sym = setNextItem(data->syms)) {
+ if (strcmp(reg->name+1,sym->name)==0) {
+ unsigned a = SPEC_ADDR(sym->etype);
+ reg->address = a;
+ if (!IS_STATIC (sym->etype)) {
+ reg->isPublic = 1;
+ }
+ if (IS_EXTERN (sym->etype)) {
+ reg->isExtern = 1;
+ }
+ if (IS_BITVAR (sym->etype))
+ reg->isBitField = 1;
+ found = 1;
+ break;
+ }
+ }
+ }
+
+ debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
+
+ //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
+ if (reg->isBitField) {
+ addSet(&dynDirectBitRegs, reg);
+ } else
+ addSet(&dynDirectRegs, reg);
+ }
+
+ return reg;
}
/*-----------------------------------------------------------------*/
regs *
typeRegWithIdx (int idx, int type, int fixed)
{
-
- regs *dReg;
-
- debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
-
- switch (type) {
-
- case REG_GPR:
- if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
-
- debugLog ("Found a Dynamic Register!\n");
- return dReg;
- }
- if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) {
- debugLog ("Found a Direct Register!\n");
- return dReg;
- }
-
- break;
- case REG_STK:
- if( (dReg = regWithIdx ( dynStackRegs, idx, 0)) != NULL ) {
- debugLog ("Found a Stack Register!\n");
- return dReg;
- } else
- if( (dReg = regWithIdx ( dynStackRegs, idx, 1)) != NULL ) {
- debugLog ("Found a Stack Register!\n");
- return dReg;
- }
- else {
- werror (E_STACK_OUT, "Register");
+
+ regs *dReg;
+
+ debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
+
+ switch (type) {
+
+ case REG_GPR:
+ if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
+
+ debugLog ("Found a Dynamic Register!\n");
+ return dReg;
+ }
+ if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) {
+ debugLog ("Found a Direct Register!\n");
+ return dReg;
+ }
+
+ break;
+ case REG_STK:
+ if( (dReg = regWithIdx ( dynStackRegs, idx, 0)) != NULL ) {
+ debugLog ("Found a Stack Register!\n");
+ return dReg;
+ } else
+ if( (dReg = regWithIdx ( dynStackRegs, idx, 1)) != NULL ) {
+ debugLog ("Found a Stack Register!\n");
+ return dReg;
+ }
+ else {
+ werror (E_STACK_OUT, "Register");
/* return an existing register just to avoid the SDCC crash */
- return regWithIdx ( dynStackRegs, 0x7f, 0);
+ return regWithIdx ( dynStackRegs, 0x7f, 0);
}
- break;
- case REG_SFR:
- if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
- debugLog ("Found a Processor Register!\n");
- return dReg;
- }
-
- case REG_CND:
- case REG_PTR:
- default:
- break;
- }
-
-
- return NULL;
+ break;
+ case REG_SFR:
+ if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
+ debugLog ("Found a Processor Register!\n");
+ return dReg;
+ }
+
+ case REG_CND:
+ case REG_PTR:
+ default:
+ break;
+ }
+
+
+ return NULL;
}
/*-----------------------------------------------------------------*/
regs *
pic14_regWithIdx (int idx)
{
- regs *dReg;
-
- if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL)
- return dReg;
-
- if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL)
- return dReg;
-
- return NULL;
+ regs *dReg;
+
+ if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL)
+ return dReg;
+
+ if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL)
+ return dReg;
+
+ return NULL;
}
/*-----------------------------------------------------------------*/
regs *
pic14_allocWithIdx (int idx)
{
-
- regs *dReg;
-
- debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
-
- if( (dReg = regWithIdx ( dynAllocRegs, idx,0)) != NULL) {
-
- debugLog ("Found a Dynamic Register!\n");
- } else if( (dReg = regWithIdx ( dynStackRegs, idx,0)) != NULL ) {
- debugLog ("Found a Stack Register!\n");
- } else if( (dReg = regWithIdx ( dynProcessorRegs, idx,0)) != NULL ) {
- debugLog ("Found a Processor Register!\n");
- } else if( (dReg = regWithIdx ( dynInternalRegs, idx,0)) != NULL ) {
- debugLog ("Found an Internal Register!\n");
- } else if( (dReg = regWithIdx ( dynInternalRegs, idx,1)) != NULL ) {
- debugLog ("Found an Internal Register!\n");
- } else {
-
- debugLog ("Dynamic Register not found\n");
-
-
- //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
- werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "regWithIdx not found");
- exit (1);
-
- }
-
- dReg->wasUsed = 1;
- dReg->isFree = 0;
-
- return dReg;
+
+ regs *dReg;
+
+ debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
+
+ if( (dReg = regWithIdx ( dynAllocRegs, idx,0)) != NULL) {
+
+ debugLog ("Found a Dynamic Register!\n");
+ } else if( (dReg = regWithIdx ( dynStackRegs, idx,0)) != NULL ) {
+ debugLog ("Found a Stack Register!\n");
+ } else if( (dReg = regWithIdx ( dynProcessorRegs, idx,0)) != NULL ) {
+ debugLog ("Found a Processor Register!\n");
+ } else if( (dReg = regWithIdx ( dynInternalRegs, idx,0)) != NULL ) {
+ debugLog ("Found an Internal Register!\n");
+ } else if( (dReg = regWithIdx ( dynInternalRegs, idx,1)) != NULL ) {
+ debugLog ("Found an Internal Register!\n");
+ } else {
+
+ debugLog ("Dynamic Register not found\n");
+
+
+ //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "regWithIdx not found");
+ exit (1);
+
+ }
+
+ dReg->wasUsed = 1;
+ dReg->isFree = 0;
+
+ return dReg;
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
regs *
pic14_findFreeReg(short type)
{
- // int i;
- regs* dReg;
-
- switch (type) {
- case REG_GPR:
- if((dReg = regFindFree(dynAllocRegs)) != NULL)
- return dReg;
- return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
-
- case REG_STK:
-
- if((dReg = regFindFree(dynStackRegs)) != NULL)
- return dReg;
-
- return NULL;
-
- case REG_PTR:
- case REG_CND:
- case REG_SFR:
- default:
- return NULL;
- }
+ // int i;
+ regs* dReg;
+
+ switch (type) {
+ case REG_GPR:
+ if((dReg = regFindFree(dynAllocRegs)) != NULL)
+ return dReg;
+ return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
+
+ case REG_STK:
+
+ if((dReg = regFindFree(dynStackRegs)) != NULL)
+ return dReg;
+
+ return NULL;
+
+ case REG_PTR:
+ case REG_CND:
+ case REG_SFR:
+ default:
+ return NULL;
+ }
}
/*-----------------------------------------------------------------*/
/* freeReg - frees a register */
static void
freeReg (regs * reg)
{
- debugLog ("%s\n", __FUNCTION__);
- reg->isFree = 1;
+ debugLog ("%s\n", __FUNCTION__);
+ reg->isFree = 1;
}
nFreeRegs (int type)
{
/* dynamically allocate as many as we need and worry about
- * fitting them into a PIC later */
-
- return 100;
+ * fitting them into a PIC later */
+
+ return 100;
#if 0
- int i;
- int nfr = 0;
-
- debugLog ("%s\n", __FUNCTION__);
- for (i = 0; i < pic14_nRegs; i++)
- if (regspic14[i].isFree && regspic14[i].type == type)
- nfr++;
- return nfr;
+ int i;
+ int nfr = 0;
+
+ debugLog ("%s\n", __FUNCTION__);
+ for (i = 0; i < pic14_nRegs; i++)
+ if (regspic14[i].isFree && regspic14[i].type == type)
+ nfr++;
+ return nfr;
#endif
}
static int
nfreeRegsType (int type)
{
- int nfr;
- debugLog ("%s\n", __FUNCTION__);
- if (type == REG_PTR)
- {
- if ((nfr = nFreeRegs (type)) == 0)
- return nFreeRegs (REG_GPR);
- }
-
- return nFreeRegs (type);
+ int nfr;
+ debugLog ("%s\n", __FUNCTION__);
+ if (type == REG_PTR)
+ {
+ if ((nfr = nFreeRegs (type)) == 0)
+ return nFreeRegs (REG_GPR);
+ }
+
+ return nFreeRegs (type);
}
void writeSetUsedRegs(FILE *of, set *dRegs)
{
-
- regs *dReg;
-
- for (dReg = setFirstItem(dRegs) ; dReg ;
- dReg = setNextItem(dRegs)) {
-
- if(dReg->wasUsed)
- fprintf (of, "\t%s\n",dReg->name);
- }
-
+
+ regs *dReg;
+
+ for (dReg = setFirstItem(dRegs) ; dReg ;
+ dReg = setNextItem(dRegs)) {
+
+ if(dReg->wasUsed)
+ fprintf (of, "\t%s\n",dReg->name);
+ }
+
}
extern void dump_map(void);
void packBits(set *bregs)
{
- set *regset;
- regs *breg;
- regs *bitfield=NULL;
- regs *relocbitfield=NULL;
- int bit_no=0;
- int byte_no=-1;
- char buffer[20];
-
-
- for (regset = bregs ; regset ;
- regset = regset->next) {
-
- breg = regset->item;
- breg->isBitField = 1;
- //fprintf(stderr,"bit reg: %s\n",breg->name);
-
- if(breg->isFixed) {
- //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
-
- bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
- breg->rIdx = breg->address & 7;
- breg->address >>= 3;
-
- if(!bitfield) {
- //sprintf (buffer, "fbitfield%02x", breg->address);
- sprintf (buffer, "0x%02x", breg->address);
- //fprintf(stderr,"new bit field\n");
- bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0);
- bitfield->isBitField = 1;
- bitfield->isFixed = 1;
- bitfield->address = breg->address;
- //addSet(&dynDirectRegs,bitfield);
- addSet(&dynInternalRegs,bitfield);
- //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
- } else {
- //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
- ;
- }
- breg->reg_alias = bitfield;
- bitfield = NULL;
-
- } else {
- if(!relocbitfield || bit_no >7) {
- byte_no++;
- bit_no=0;
- sprintf (buffer, "bitfield%d", byte_no);
- //fprintf(stderr,"new relocatable bit field\n");
- relocbitfield = newReg(REG_GPR, PO_GPR_BIT,dynrIdx++,buffer,1,0);
- relocbitfield->isBitField = 1;
- //addSet(&dynDirectRegs,relocbitfield);
- addSet(&dynInternalRegs,relocbitfield);
- //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
-
- }
-
- breg->reg_alias = relocbitfield;
- breg->address = dynrIdx; /* byte_no; */
- breg->rIdx = bit_no++;
- }
- }
-
+ set *regset;
+ regs *breg;
+ regs *bitfield=NULL;
+ regs *relocbitfield=NULL;
+ int bit_no=0;
+ int byte_no=-1;
+ char buffer[20];
+
+
+ for (regset = bregs ; regset ;
+ regset = regset->next) {
+
+ breg = regset->item;
+ breg->isBitField = 1;
+ //fprintf(stderr,"bit reg: %s\n",breg->name);
+
+ if(breg->isFixed) {
+ //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
+
+ bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
+ breg->rIdx = breg->address & 7;
+ breg->address >>= 3;
+
+ if(!bitfield) {
+ //sprintf (buffer, "fbitfield%02x", breg->address);
+ sprintf (buffer, "0x%02x", breg->address);
+ //fprintf(stderr,"new bit field\n");
+ bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0);
+ bitfield->isBitField = 1;
+ bitfield->isFixed = 1;
+ bitfield->address = breg->address;
+ //addSet(&dynDirectRegs,bitfield);
+ addSet(&dynInternalRegs,bitfield);
+ //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
+ } else {
+ //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
+ ;
+ }
+ breg->reg_alias = bitfield;
+ bitfield = NULL;
+
+ } else {
+ if(!relocbitfield || bit_no >7) {
+ byte_no++;
+ bit_no=0;
+ sprintf (buffer, "bitfield%d", byte_no);
+ //fprintf(stderr,"new relocatable bit field\n");
+ relocbitfield = newReg(REG_GPR, PO_GPR_BIT,dynrIdx++,buffer,1,0);
+ relocbitfield->isBitField = 1;
+ //addSet(&dynDirectRegs,relocbitfield);
+ addSet(&dynInternalRegs,relocbitfield);
+ //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
+
+ }
+
+ breg->reg_alias = relocbitfield;
+ breg->address = dynrIdx; /* byte_no; */
+ breg->rIdx = bit_no++;
+ }
+ }
+
}
void bitEQUs(FILE *of, set *bregs)
{
- regs *breg,*bytereg;
- int bit_no=0;
-
- //fprintf(stderr," %s\n",__FUNCTION__);
- for (breg = setFirstItem(bregs) ; breg ;
- breg = setNextItem(bregs)) {
-
- //fprintf(stderr,"bit reg: %s\n",breg->name);
-
- bytereg = breg->reg_alias;
- if(bytereg)
- fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
- breg->name,
- bytereg->name,
- breg->rIdx & 0x0007);
-
- else {
- //fprintf(stderr, "bit field is not assigned to a register\n");
- fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
- breg->name,
- bit_no>>3,
- bit_no & 0x0007);
-
- bit_no++;
- }
- }
-
+ regs *breg,*bytereg;
+ int bit_no=0;
+
+ //fprintf(stderr," %s\n",__FUNCTION__);
+ for (breg = setFirstItem(bregs) ; breg ;
+ breg = setNextItem(bregs)) {
+
+ //fprintf(stderr,"bit reg: %s\n",breg->name);
+
+ bytereg = breg->reg_alias;
+ if(bytereg)
+ fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
+ breg->name,
+ bytereg->name,
+ breg->rIdx & 0x0007);
+
+ else {
+ //fprintf(stderr, "bit field is not assigned to a register\n");
+ fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
+ breg->name,
+ bit_no>>3,
+ bit_no & 0x0007);
+
+ bit_no++;
+ }
+ }
+
}
void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
{
- regs *reg;
-
-
- for (reg = setFirstItem(fregs) ; reg ;
- reg = setNextItem(fregs)) {
-
- //if(!reg->isEmitted && reg->wasUsed) {
- if(reg->wasUsed) {
- if(use_rIdx)
- fprintf (of, "%s\tEQU\t0x%03x\n",
- reg->name,
- reg->rIdx);
- else
- fprintf (of, "%s\tEQU\t0x%03x\n",
- reg->name,
- reg->address);
- }
- }
-
+ regs *reg;
+
+
+ for (reg = setFirstItem(fregs) ; reg ;
+ reg = setNextItem(fregs)) {
+
+ //if(!reg->isEmitted && reg->wasUsed) {
+ if(reg->wasUsed) {
+ if(use_rIdx)
+ fprintf (of, "%s\tEQU\t0x%03x\n",
+ reg->name,
+ reg->rIdx);
+ else
+ fprintf (of, "%s\tEQU\t0x%03x\n",
+ reg->name,
+ reg->address);
+ }
+ }
+
}
-void writeUsedRegs(FILE *of)
+void writeUsedRegs(FILE *of)
{
-
- packBits(dynDirectBitRegs);
-
- //dump_map();
-
- bitEQUs(of,dynDirectBitRegs);
+
+ packBits(dynDirectBitRegs);
+
+ //dump_map();
+
+ bitEQUs(of,dynDirectBitRegs);
}
/*-----------------------------------------------------------------*/
static bitVect *
computeSpillable (iCode * ic)
{
- bitVect *spillable;
-
- debugLog ("%s\n", __FUNCTION__);
- /* spillable live ranges are those that are live at this
- point . the following categories need to be subtracted
- from this set.
- a) - those that are already spilt
- b) - if being used by this one
- c) - defined by this one */
-
- spillable = bitVectCopy (ic->rlive);
- spillable =
- bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
- spillable =
- bitVectCplAnd (spillable, ic->uses); /* used in this one */
- bitVectUnSetBit (spillable, ic->defKey);
- spillable = bitVectIntersect (spillable, _G.regAssigned);
- return spillable;
-
+ bitVect *spillable;
+
+ debugLog ("%s\n", __FUNCTION__);
+ /* spillable live ranges are those that are live at this
+ point . the following categories need to be subtracted
+ from this set.
+ a) - those that are already spilt
+ b) - if being used by this one
+ c) - defined by this one */
+
+ spillable = bitVectCopy (ic->rlive);
+ spillable =
+ bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
+ spillable =
+ bitVectCplAnd (spillable, ic->uses); /* used in this one */
+ bitVectUnSetBit (spillable, ic->defKey);
+ spillable = bitVectIntersect (spillable, _G.regAssigned);
+ return spillable;
+
}
/*-----------------------------------------------------------------*/
static int
noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
{
- debugLog ("%s\n", __FUNCTION__);
- return (sym->usl.spillLoc ? 0 : 1);
+ debugLog ("%s\n", __FUNCTION__);
+ return (sym->usl.spillLoc ? 0 : 1);
}
/*-----------------------------------------------------------------*/
static int
hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
{
- debugLog ("%s\n", __FUNCTION__);
- return (sym->usl.spillLoc ? 1 : 0);
+ debugLog ("%s\n", __FUNCTION__);
+ return (sym->usl.spillLoc ? 1 : 0);
}
/*-----------------------------------------------------------------*/
static int
directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
{
- debugLog ("%s\n", __FUNCTION__);
- if (sym->usl.spillLoc &&
- (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
- return 1;
- else
- return 0;
+ debugLog ("%s\n", __FUNCTION__);
+ if (sym->usl.spillLoc &&
+ (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
+ return 1;
+ else
+ return 0;
}
/*-----------------------------------------------------------------*/
static int
hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
{
- debugLog ("%s\n", __FUNCTION__);
- return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
+ debugLog ("%s\n", __FUNCTION__);
+ return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
}
/*-----------------------------------------------------------------*/
static int
rematable (symbol * sym, eBBlock * ebp, iCode * ic)
{
- debugLog ("%s\n", __FUNCTION__);
- return sym->remat;
+ debugLog ("%s\n", __FUNCTION__);
+ return sym->remat;
}
/*-----------------------------------------------------------------*/
static int
notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
{
- debugLog ("%s\n", __FUNCTION__);
- return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
- allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
+ debugLog ("%s\n", __FUNCTION__);
+ return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
+ allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
}
/*-----------------------------------------------------------------*/
static int
allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
{
- debugLog ("%s\n", __FUNCTION__);
- return 1;
+ debugLog ("%s\n", __FUNCTION__);
+ return 1;
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static set *
liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
- eBBlock * ebp, iCode * ic)
+ eBBlock * ebp, iCode * ic)
{
- set *rset = NULL;
- int i;
-
- debugLog ("%s\n", __FUNCTION__);
- if (!lrs || !lrs->size)
- return NULL;
-
- for (i = 1; i < lrs->size; i++)
- {
- symbol *sym;
- if (!bitVectBitValue (lrs, i))
- continue;
-
- /* if we don't find it in the live range
- hash table we are in serious trouble */
- if (!(sym = hTabItemWithKey (liveRanges, i)))
- {
- werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "liveRangesWith could not find liveRange");
- exit (1);
- }
-
- if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
- addSetHead (&rset, sym);
- }
-
- return rset;
+ set *rset = NULL;
+ int i;
+
+ debugLog ("%s\n", __FUNCTION__);
+ if (!lrs || !lrs->size)
+ return NULL;
+
+ for (i = 1; i < lrs->size; i++)
+ {
+ symbol *sym;
+ if (!bitVectBitValue (lrs, i))
+ continue;
+
+ /* if we don't find it in the live range
+ hash table we are in serious trouble */
+ if (!(sym = hTabItemWithKey (liveRanges, i)))
+ {
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "liveRangesWith could not find liveRange");
+ exit (1);
+ }
+
+ if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
+ addSetHead (&rset, sym);
+ }
+
+ return rset;
}
static symbol *
leastUsedLR (set * sset)
{
- symbol *sym = NULL, *lsym = NULL;
-
- debugLog ("%s\n", __FUNCTION__);
- sym = lsym = setFirstItem (sset);
-
- if (!lsym)
- return NULL;
-
- for (; lsym; lsym = setNextItem (sset))
- {
-
- /* if usage is the same then prefer
- the spill the smaller of the two */
- if (lsym->used == sym->used)
- if (getSize (lsym->type) < getSize (sym->type))
- sym = lsym;
-
- /* if less usage */
- if (lsym->used < sym->used)
- sym = lsym;
-
- }
-
- setToNull ((void *) &sset);
- sym->blockSpil = 0;
- return sym;
+ symbol *sym = NULL, *lsym = NULL;
+
+ debugLog ("%s\n", __FUNCTION__);
+ sym = lsym = setFirstItem (sset);
+
+ if (!lsym)
+ return NULL;
+
+ for (; lsym; lsym = setNextItem (sset))
+ {
+
+ /* if usage is the same then prefer
+ the spill the smaller of the two */
+ if (lsym->used == sym->used)
+ if (getSize (lsym->type) < getSize (sym->type))
+ sym = lsym;
+
+ /* if less usage */
+ if (lsym->used < sym->used)
+ sym = lsym;
+
+ }
+
+ setToNull ((void *) &sset);
+ sym->blockSpil = 0;
+ return sym;
}
/*-----------------------------------------------------------------*/
static int
noOverLap (set * itmpStack, symbol * fsym)
{
- symbol *sym;
- debugLog ("%s\n", __FUNCTION__);
-
-
- for (sym = setFirstItem (itmpStack); sym;
- sym = setNextItem (itmpStack))
- {
- if (sym->liveTo > fsym->liveFrom)
- return 0;
-
- }
-
- return 1;
+ symbol *sym;
+ debugLog ("%s\n", __FUNCTION__);
+
+
+ for (sym = setFirstItem (itmpStack); sym;
+ sym = setNextItem (itmpStack))
+ {
+ if (sym->liveTo > fsym->liveFrom)
+ return 0;
+
+ }
+
+ return 1;
}
/*-----------------------------------------------------------------*/
static
DEFSETFUNC (isFree)
{
- symbol *sym = item;
- V_ARG (symbol **, sloc);
- V_ARG (symbol *, fsym);
-
- debugLog ("%s\n", __FUNCTION__);
- /* if already found */
- if (*sloc)
- return 0;
-
- /* if it is free && and the itmp assigned to
- this does not have any overlapping live ranges
- with the one currently being assigned and
- the size can be accomodated */
- if (sym->isFree &&
- noOverLap (sym->usl.itmpStack, fsym) &&
- getSize (sym->type) >= getSize (fsym->type))
- {
- *sloc = sym;
- return 1;
- }
-
- return 0;
+ symbol *sym = item;
+ V_ARG (symbol **, sloc);
+ V_ARG (symbol *, fsym);
+
+ debugLog ("%s\n", __FUNCTION__);
+ /* if already found */
+ if (*sloc)
+ return 0;
+
+ /* if it is free && and the itmp assigned to
+ this does not have any overlapping live ranges
+ with the one currently being assigned and
+ the size can be accomodated */
+ if (sym->isFree &&
+ noOverLap (sym->usl.itmpStack, fsym) &&
+ getSize (sym->type) >= getSize (fsym->type))
+ {
+ *sloc = sym;
+ return 1;
+ }
+
+ return 0;
}
/*-----------------------------------------------------------------*/
static void
spillLRWithPtrReg (symbol * forSym)
{
- symbol *lrsym;
- regs *r0, *r1;
- int k;
-
- debugLog ("%s\n", __FUNCTION__);
- if (!_G.regAssigned ||
- bitVectIsZero (_G.regAssigned))
- return;
-
- r0 = pic14_regWithIdx (R0_IDX);
- r1 = pic14_regWithIdx (R1_IDX);
-
- /* for all live ranges */
- for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
- lrsym = hTabNextItem (liveRanges, &k))
- {
- int j;
-
- /* if no registers assigned to it or
- spilt */
- /* if it does not overlap with this then
- not need to spill it */
-
- if (lrsym->isspilt || !lrsym->nRegs ||
- (lrsym->liveTo < forSym->liveFrom))
- continue;
-
- /* go thru the registers : if it is either
- r0 or r1 then spil it */
- for (j = 0; j < lrsym->nRegs; j++)
- if (lrsym->regs[j] == r0 ||
- lrsym->regs[j] == r1)
- {
- spillThis (lrsym);
- break;
- }
- }
-
+ symbol *lrsym;
+ regs *r0, *r1;
+ int k;
+
+ debugLog ("%s\n", __FUNCTION__);
+ if (!_G.regAssigned ||
+ bitVectIsZero (_G.regAssigned))
+ return;
+
+ r0 = pic14_regWithIdx (R0_IDX);
+ r1 = pic14_regWithIdx (R1_IDX);
+
+ /* for all live ranges */
+ for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
+ lrsym = hTabNextItem (liveRanges, &k))
+ {
+ int j;
+
+ /* if no registers assigned to it or
+ spilt */
+ /* if it does not overlap with this then
+ not need to spill it */
+
+ if (lrsym->isspilt || !lrsym->nRegs ||
+ (lrsym->liveTo < forSym->liveFrom))
+ continue;
+
+ /* go thru the registers : if it is either
+ r0 or r1 then spil it */
+ for (j = 0; j < lrsym->nRegs; j++)
+ if (lrsym->regs[j] == r0 ||
+ lrsym->regs[j] == r1)
+ {
+ spillThis (lrsym);
+ break;
+ }
+ }
+
}
/*-----------------------------------------------------------------*/
static symbol *
createStackSpil (symbol * sym)
{
- symbol *sloc = NULL;
- int useXstack, model, noOverlay;
-
- char slocBuffer[30];
- debugLog ("%s\n", __FUNCTION__);
-
- FENTRY2("called.");
-
- /* first go try and find a free one that is already
- existing on the stack */
- if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
- {
- /* found a free one : just update & return */
- sym->usl.spillLoc = sloc;
- sym->stackSpil = 1;
- sloc->isFree = 0;
- addSetHead (&sloc->usl.itmpStack, sym);
- return sym;
- }
-
- /* could not then have to create one , this is the hard part
- we need to allocate this on the stack : this is really a
- hack!! but cannot think of anything better at this time */
-
- if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
- {
- fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
- __FILE__, __LINE__);
- exit (1);
- }
-
- sloc = newiTemp (slocBuffer);
-
- /* set the type to the spilling symbol */
- sloc->type = copyLinkChain (sym->type);
- sloc->etype = getSpec (sloc->type);
- SPEC_SCLS (sloc->etype) = S_DATA;
- SPEC_EXTR (sloc->etype) = 0;
- SPEC_STAT (sloc->etype) = 0;
-
- /* we don't allow it to be allocated`
- onto the external stack since : so we
- temporarily turn it off ; we also
- turn off memory model to prevent
- the spil from going to the external storage
- and turn off overlaying
- */
-
- useXstack = options.useXstack;
- model = options.model;
- noOverlay = options.noOverlay;
- options.noOverlay = 1;
- options.model = options.useXstack = 0;
-
- allocLocal (sloc);
-
- options.useXstack = useXstack;
- options.model = model;
- options.noOverlay = noOverlay;
- sloc->isref = 1; /* to prevent compiler warning */
-
- /* if it is on the stack then update the stack */
- if (IN_STACK (sloc->etype))
- {
- currFunc->stack += getSize (sloc->type);
- _G.stackExtend += getSize (sloc->type);
- }
- else
- _G.dataExtend += getSize (sloc->type);
-
- /* add it to the _G.stackSpil set */
- addSetHead (&_G.stackSpil, sloc);
- sym->usl.spillLoc = sloc;
- sym->stackSpil = 1;
-
- /* add it to the set of itempStack set
- of the spill location */
- addSetHead (&sloc->usl.itmpStack, sym);
- return sym;
+ symbol *sloc = NULL;
+ int useXstack, model, noOverlay;
+
+ char slocBuffer[30];
+ debugLog ("%s\n", __FUNCTION__);
+
+ FENTRY2("called.");
+
+ /* first go try and find a free one that is already
+ existing on the stack */
+ if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
+ {
+ /* found a free one : just update & return */
+ sym->usl.spillLoc = sloc;
+ sym->stackSpil = 1;
+ sloc->isFree = 0;
+ addSetHead (&sloc->usl.itmpStack, sym);
+ return sym;
+ }
+
+ /* could not then have to create one , this is the hard part
+ we need to allocate this on the stack : this is really a
+ hack!! but cannot think of anything better at this time */
+
+ if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
+ {
+ fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
+ __FILE__, __LINE__);
+ exit (1);
+ }
+
+ sloc = newiTemp (slocBuffer);
+
+ /* set the type to the spilling symbol */
+ sloc->type = copyLinkChain (sym->type);
+ sloc->etype = getSpec (sloc->type);
+ SPEC_SCLS (sloc->etype) = S_DATA;
+ SPEC_EXTR (sloc->etype) = 0;
+ SPEC_STAT (sloc->etype) = 0;
+
+ /* we don't allow it to be allocated`
+ onto the external stack since : so we
+ temporarily turn it off ; we also
+ turn off memory model to prevent
+ the spil from going to the external storage
+ and turn off overlaying
+ */
+
+ useXstack = options.useXstack;
+ model = options.model;
+ noOverlay = options.noOverlay;
+ options.noOverlay = 1;
+ options.model = options.useXstack = 0;
+
+ allocLocal (sloc);
+
+ options.useXstack = useXstack;
+ options.model = model;
+ options.noOverlay = noOverlay;
+ sloc->isref = 1; /* to prevent compiler warning */
+
+ /* if it is on the stack then update the stack */
+ if (IN_STACK (sloc->etype))
+ {
+ currFunc->stack += getSize (sloc->type);
+ _G.stackExtend += getSize (sloc->type);
+ }
+ else
+ _G.dataExtend += getSize (sloc->type);
+
+ /* add it to the _G.stackSpil set */
+ addSetHead (&_G.stackSpil, sloc);
+ sym->usl.spillLoc = sloc;
+ sym->stackSpil = 1;
+
+ /* add it to the set of itempStack set
+ of the spill location */
+ addSetHead (&sloc->usl.itmpStack, sym);
+ return sym;
}
/*-----------------------------------------------------------------*/
static bool
isSpiltOnStack (symbol * sym)
{
- sym_link *etype;
-
- debugLog ("%s\n", __FUNCTION__);
- FENTRY2("called.");
-
- if (!sym)
- return FALSE;
-
- if (!sym->isspilt)
- return FALSE;
-
- /* if (sym->_G.stackSpil) */
- /* return TRUE; */
-
- if (!sym->usl.spillLoc)
- return FALSE;
-
- etype = getSpec (sym->usl.spillLoc->type);
- if (IN_STACK (etype))
- return TRUE;
-
- return FALSE;
+ sym_link *etype;
+
+ debugLog ("%s\n", __FUNCTION__);
+ FENTRY2("called.");
+
+ if (!sym)
+ return FALSE;
+
+ if (!sym->isspilt)
+ return FALSE;
+
+ /* if (sym->_G.stackSpil) */
+ /* return TRUE; */
+
+ if (!sym->usl.spillLoc)
+ return FALSE;
+
+ etype = getSpec (sym->usl.spillLoc->type);
+ if (IN_STACK (etype))
+ return TRUE;
+
+ return FALSE;
}
/*-----------------------------------------------------------------*/
static void
spillThis (symbol * sym)
{
- int i;
- debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
- FENTRY2("sym: %s, spillLoc:%p (%s)\n", sym->rname, sym->usl.spillLoc, sym->usl.spillLoc ? sym->usl.spillLoc->rname : "<unknown>");
-
- /* if this is rematerializable or has a spillLocation
- we are okay, else we need to create a spillLocation
- for it */
- if (!(sym->remat || sym->usl.spillLoc))
- createStackSpil (sym);
-
-
- /* mark it has spilt & put it in the spilt set */
- sym->isspilt = 1;
- _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
-
- bitVectUnSetBit (_G.regAssigned, sym->key);
-
- for (i = 0; i < sym->nRegs; i++)
- {
- if (sym->regs[i])
- {
- freeReg (sym->regs[i]);
- sym->regs[i] = NULL;
- }
- }
-
- /* if spilt on stack then free up r0 & r1
- if they could have been assigned to some
- LIVE ranges */
- if (!pic14_ptrRegReq && isSpiltOnStack (sym))
- {
- pic14_ptrRegReq++;
- spillLRWithPtrReg (sym);
- }
-
- if (sym->usl.spillLoc && !sym->remat)
- sym->usl.spillLoc->allocreq = 1;
-
- return;
-}
+ int i;
+ debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
+ FENTRY2("sym: %s, spillLoc:%p (%s)\n", sym->rname, sym->usl.spillLoc, sym->usl.spillLoc ? sym->usl.spillLoc->rname : "<unknown>");
+
+ /* if this is rematerializable or has a spillLocation
+ we are okay, else we need to create a spillLocation
+ for it */
+ if (!(sym->remat || sym->usl.spillLoc))
+ createStackSpil (sym);
+
+
+ /* mark it has spilt & put it in the spilt set */
+ sym->isspilt = 1;
+ _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
+
+ bitVectUnSetBit (_G.regAssigned, sym->key);
+
+ for (i = 0; i < sym->nRegs; i++)
+ {
+ if (sym->regs[i])
+ {
+ freeReg (sym->regs[i]);
+ sym->regs[i] = NULL;
+ }
+ }
+
+ /* if spilt on stack then free up r0 & r1
+ if they could have been assigned to some
+ LIVE ranges */
+ if (!pic14_ptrRegReq && isSpiltOnStack (sym))
+ {
+ pic14_ptrRegReq++;
+ spillLRWithPtrReg (sym);
+ }
+
+ if (sym->usl.spillLoc && !sym->remat)
+ sym->usl.spillLoc->allocreq = 1;
+
+ return;
+}
+
+/*-----------------------------------------------------------------*/
+/* selectSpil - select a iTemp to spil : rather a simple procedure */
+/*-----------------------------------------------------------------*/
+static symbol *
+selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
+{
+ bitVect *lrcs = NULL;
+ set *selectS;
+ symbol *sym;
+
+ debugLog ("%s\n", __FUNCTION__);
+ FENTRY2("called.");
+ /* get the spillable live ranges */
+ lrcs = computeSpillable (ic);
+
+
+ /* get all live ranges that are rematerizable */
+ if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
+ {
+ /* return the least used of these */
+ return leastUsedLR (selectS);
+ }
+
+ /* get live ranges with spillLocations in direct space */
+ if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
+ {
+ sym = leastUsedLR (selectS);
+ strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
+ sym->usl.spillLoc->rname :
+ sym->usl.spillLoc->name));
+ sym->spildir = 1;
+ /* mark it as allocation required */
+ sym->usl.spillLoc->allocreq = 1;
+ return sym;
+ }
+
+ /* if the symbol is local to the block then */
+ if (forSym->liveTo < ebp->lSeq)
+ {
+
+ /* check if there are any live ranges allocated
+ to registers that are not used in this block */
+ if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
+ {
+ sym = leastUsedLR (selectS);
+ /* if this is not rematerializable */
+ if (!sym->remat)
+ {
+ _G.blockSpil++;
+ sym->blockSpil = 1;
+ }
+ return sym;
+ }
+
+ /* check if there are any live ranges that not
+ used in the remainder of the block */
+ if (!_G.blockSpil &&
+ !isiCodeInFunctionCall (ic) &&
+ (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
+ {
+ sym = leastUsedLR (selectS);
+ if (!sym->remat)
+ {
+ sym->remainSpil = 1;
+ _G.blockSpil++;
+ }
+ return sym;
+ }
+ }
+
+ /* find live ranges with spillocation && not used as pointers */
+ if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
+ {
+
+ sym = leastUsedLR (selectS);
+ /* mark this as allocation required */
+ sym->usl.spillLoc->allocreq = 1;
+ return sym;
+ }
+
+ /* find live ranges with spillocation */
+ if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
+ {
+
+ sym = leastUsedLR (selectS);
+ sym->usl.spillLoc->allocreq = 1;
+ return sym;
+ }
+
+ /* couldn't find then we need to create a spil
+ location on the stack , for which one? the least
+ used ofcourse */
+ if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
+ {
+
+ /* return a created spil location */
+ sym = createStackSpil (leastUsedLR (selectS));
+ sym->usl.spillLoc->allocreq = 1;
+ return sym;
+ }
+
+ /* this is an extreme situation we will spill
+ this one : happens very rarely but it does happen */
+ spillThis (forSym);
+ return forSym;
-/*-----------------------------------------------------------------*/
-/* selectSpil - select a iTemp to spil : rather a simple procedure */
-/*-----------------------------------------------------------------*/
-static symbol *
-selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
-{
- bitVect *lrcs = NULL;
- set *selectS;
- symbol *sym;
-
- debugLog ("%s\n", __FUNCTION__);
- FENTRY2("called.");
- /* get the spillable live ranges */
- lrcs = computeSpillable (ic);
-
-
- /* get all live ranges that are rematerizable */
- if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
- {
- /* return the least used of these */
- return leastUsedLR (selectS);
- }
-
- /* get live ranges with spillLocations in direct space */
- if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
- {
- sym = leastUsedLR (selectS);
- strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
- sym->usl.spillLoc->rname :
- sym->usl.spillLoc->name));
- sym->spildir = 1;
- /* mark it as allocation required */
- sym->usl.spillLoc->allocreq = 1;
- return sym;
- }
-
- /* if the symbol is local to the block then */
- if (forSym->liveTo < ebp->lSeq)
- {
-
- /* check if there are any live ranges allocated
- to registers that are not used in this block */
- if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
- {
- sym = leastUsedLR (selectS);
- /* if this is not rematerializable */
- if (!sym->remat)
- {
- _G.blockSpil++;
- sym->blockSpil = 1;
- }
- return sym;
- }
-
- /* check if there are any live ranges that not
- used in the remainder of the block */
- if (!_G.blockSpil &&
- !isiCodeInFunctionCall (ic) &&
- (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
- {
- sym = leastUsedLR (selectS);
- if (!sym->remat)
- {
- sym->remainSpil = 1;
- _G.blockSpil++;
- }
- return sym;
- }
- }
-
- /* find live ranges with spillocation && not used as pointers */
- if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
- {
-
- sym = leastUsedLR (selectS);
- /* mark this as allocation required */
- sym->usl.spillLoc->allocreq = 1;
- return sym;
- }
-
- /* find live ranges with spillocation */
- if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
- {
-
- sym = leastUsedLR (selectS);
- sym->usl.spillLoc->allocreq = 1;
- return sym;
- }
-
- /* couldn't find then we need to create a spil
- location on the stack , for which one? the least
- used ofcourse */
- if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
- {
-
- /* return a created spil location */
- sym = createStackSpil (leastUsedLR (selectS));
- sym->usl.spillLoc->allocreq = 1;
- return sym;
- }
-
- /* this is an extreme situation we will spill
- this one : happens very rarely but it does happen */
- spillThis (forSym);
- return forSym;
-
}
/*-----------------------------------------------------------------*/
static bool
spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
{
- symbol *ssym;
- int i;
-
- debugLog ("%s\n", __FUNCTION__);
- /* get something we can spil */
- ssym = selectSpil (ic, ebp, forSym);
-
- /* mark it as spilt */
- ssym->isspilt = 1;
- _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
-
- /* mark it as not register assigned &
- take it away from the set */
- bitVectUnSetBit (_G.regAssigned, ssym->key);
-
- /* mark the registers as free */
- for (i = 0; i < ssym->nRegs; i++)
- if (ssym->regs[i])
- freeReg (ssym->regs[i]);
-
- /* if spilt on stack then free up r0 & r1
- if they could have been assigned to as gprs */
- if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
- {
- pic14_ptrRegReq++;
- spillLRWithPtrReg (ssym);
- }
-
- /* if this was a block level spil then insert push & pop
- at the start & end of block respectively */
- if (ssym->blockSpil)
- {
- iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
- /* add push to the start of the block */
- addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
- ebp->sch->next : ebp->sch));
- nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
- /* add pop to the end of the block */
- addiCodeToeBBlock (ebp, nic, NULL);
- }
-
- /* if spilt because not used in the remainder of the
- block then add a push before this instruction and
- a pop at the end of the block */
- if (ssym->remainSpil)
- {
-
- iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
- /* add push just before this instruction */
- addiCodeToeBBlock (ebp, nic, ic);
-
- nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
- /* add pop to the end of the block */
- addiCodeToeBBlock (ebp, nic, NULL);
- }
-
- if (ssym == forSym)
- return FALSE;
- else
- return TRUE;
+ symbol *ssym;
+ int i;
+
+ debugLog ("%s\n", __FUNCTION__);
+ /* get something we can spil */
+ ssym = selectSpil (ic, ebp, forSym);
+
+ /* mark it as spilt */
+ ssym->isspilt = 1;
+ _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
+
+ /* mark it as not register assigned &
+ take it away from the set */
+ bitVectUnSetBit (_G.regAssigned, ssym->key);
+
+ /* mark the registers as free */
+ for (i = 0; i < ssym->nRegs; i++)
+ if (ssym->regs[i])
+ freeReg (ssym->regs[i]);
+
+ /* if spilt on stack then free up r0 & r1
+ if they could have been assigned to as gprs */
+ if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
+ {
+ pic14_ptrRegReq++;
+ spillLRWithPtrReg (ssym);
+ }
+
+ /* if this was a block level spil then insert push & pop
+ at the start & end of block respectively */
+ if (ssym->blockSpil)
+ {
+ iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
+ /* add push to the start of the block */
+ addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
+ ebp->sch->next : ebp->sch));
+ nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
+ /* add pop to the end of the block */
+ addiCodeToeBBlock (ebp, nic, NULL);
+ }
+
+ /* if spilt because not used in the remainder of the
+ block then add a push before this instruction and
+ a pop at the end of the block */
+ if (ssym->remainSpil)
+ {
+
+ iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
+ /* add push just before this instruction */
+ addiCodeToeBBlock (ebp, nic, ic);
+
+ nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
+ /* add pop to the end of the block */
+ addiCodeToeBBlock (ebp, nic, NULL);
+ }
+
+ if (ssym == forSym)
+ return FALSE;
+ else
+ return TRUE;
}
/*-----------------------------------------------------------------*/
static regs *
getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
{
- regs *reg;
- int j;
-
- debugLog ("%s\n", __FUNCTION__);
+ regs *reg;
+ int j;
+
+ debugLog ("%s\n", __FUNCTION__);
tryAgain:
- /* try for a ptr type */
- if ((reg = allocReg (REG_PTR)))
- return reg;
-
- /* try for gpr type */
- if ((reg = allocReg (REG_GPR)))
- return reg;
-
- /* we have to spil */
- if (!spilSomething (ic, ebp, sym))
- return NULL;
-
- /* make sure partially assigned registers aren't reused */
- for (j=0; j<=sym->nRegs; j++)
- if (sym->regs[j])
- sym->regs[j]->isFree = 0;
-
- /* this looks like an infinite loop but
- in really selectSpil will abort */
- goto tryAgain;
+ /* try for a ptr type */
+ if ((reg = allocReg (REG_PTR)))
+ return reg;
+
+ /* try for gpr type */
+ if ((reg = allocReg (REG_GPR)))
+ return reg;
+
+ /* we have to spil */
+ if (!spilSomething (ic, ebp, sym))
+ return NULL;
+
+ /* make sure partially assigned registers aren't reused */
+ for (j=0; j<=sym->nRegs; j++)
+ if (sym->regs[j])
+ sym->regs[j]->isFree = 0;
+
+ /* this looks like an infinite loop but
+ in really selectSpil will abort */
+ goto tryAgain;
}
/*-----------------------------------------------------------------*/
static regs *
getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
{
- regs *reg;
- int j;
-
- debugLog ("%s\n", __FUNCTION__);
+ regs *reg;
+ int j;
+
+ debugLog ("%s\n", __FUNCTION__);
tryAgain:
- /* try for gpr type */
- if ((reg = allocReg (REG_GPR)))
- return reg;
-
- if (!pic14_ptrRegReq)
- if ((reg = allocReg (REG_PTR)))
- return reg;
-
- /* we have to spil */
- if (!spilSomething (ic, ebp, sym))
- return NULL;
-
- /* make sure partially assigned registers aren't reused */
- for (j=0; j<=sym->nRegs; j++)
- if (sym->regs[j])
- sym->regs[j]->isFree = 0;
-
- /* this looks like an infinite loop but
- in really selectSpil will abort */
- goto tryAgain;
+ /* try for gpr type */
+ if ((reg = allocReg (REG_GPR)))
+ return reg;
+
+ if (!pic14_ptrRegReq)
+ if ((reg = allocReg (REG_PTR)))
+ return reg;
+
+ /* we have to spil */
+ if (!spilSomething (ic, ebp, sym))
+ return NULL;
+
+ /* make sure partially assigned registers aren't reused */
+ for (j=0; j<=sym->nRegs; j++)
+ if (sym->regs[j])
+ sym->regs[j]->isFree = 0;
+
+ /* this looks like an infinite loop but
+ in really selectSpil will abort */
+ goto tryAgain;
}
/*-----------------------------------------------------------------*/
static bool
symHasReg (symbol * sym, regs * reg)
{
- int i;
-
- debugLog ("%s\n", __FUNCTION__);
- for (i = 0; i < sym->nRegs; i++)
- if (sym->regs[i] == reg)
- return TRUE;
-
- return FALSE;
+ int i;
+
+ debugLog ("%s\n", __FUNCTION__);
+ for (i = 0; i < sym->nRegs; i++)
+ if (sym->regs[i] == reg)
+ return TRUE;
+
+ return FALSE;
}
/*-----------------------------------------------------------------*/
static void
deassignLRs (iCode * ic, eBBlock * ebp)
{
- symbol *sym;
- int k;
- symbol *result;
-
- debugLog ("%s\n", __FUNCTION__);
- for (sym = hTabFirstItem (liveRanges, &k); sym;
- sym = hTabNextItem (liveRanges, &k))
- {
-
- symbol *psym = NULL;
- /* if it does not end here */
- if (sym->liveTo > ic->seq)
- continue;
-
- /* Prevent the result from being assigned the same registers as (one)
- * operand as many genXXX-functions fail otherwise.
- * POINTER_GET(ic) || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == NOT
- * are known to fail. */
- if (sym->liveTo == ic->seq && IC_RESULT(ic))
- {
- switch (ic->op)
- {
- case '=': /* assignment */
- case BITWISEAND: /* bitwise AND */
- case '|': /* bitwise OR */
- case '^': /* bitwise XOR */
- case '~': /* bitwise negate */
- case RLC: /* rotate through carry */
- case RRC:
- case UNARYMINUS:
- case '+': /* addition */
- case '-': /* subtraction */
- /* go ahead, these are safe to use with
- * non-disjoint register sets */
- break;
-
- default:
- /* do not release operand registers */
- //fprintf (stderr, "%s:%u: operand not freed: ", __FILE__, __LINE__); piCode (ic, stderr); fprintf (stderr, "\n");
- continue;
- } // switch
- }
-
- /* if it was spilt on stack then we can
- mark the stack spil location as free */
- if (sym->isspilt)
- {
- if (sym->stackSpil)
- {
- sym->usl.spillLoc->isFree = 1;
- sym->stackSpil = 0;
- }
- continue;
- }
-
- if (!bitVectBitValue (_G.regAssigned, sym->key))
- continue;
- /* special case check if this is an IFX &
- the privious one was a pop and the
- previous one was not spilt then keep track
- of the symbol */
- if (ic->op == IFX && ic->prev &&
- ic->prev->op == IPOP &&
- !ic->prev->parmPush &&
- IS_SYMOP(IC_LEFT (ic->prev)) &&
- !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
- psym = OP_SYMBOL (IC_LEFT (ic->prev));
-
- if (sym->nRegs)
- {
- int i = 0;
-
- bitVectUnSetBit (_G.regAssigned, sym->key);
-
- /* if the result of this one needs registers
- and does not have it then assign it right
- away */
- if (IC_RESULT (ic) &&
- !(SKIP_IC2 (ic) || /* not a special icode */
- ic->op == JUMPTABLE ||
- ic->op == IFX ||
- ic->op == IPUSH ||
- ic->op == IPOP ||
- ic->op == RETURN ||
- POINTER_SET (ic)) &&
- IS_SYMOP (IC_RESULT (ic)) &&
- (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
- result->liveTo > ic->seq && /* and will live beyond this */
- result->liveTo <= ebp->lSeq && /* does not go beyond this block */
- result->liveFrom == ic->seq && /* does not start before here */
- result->regType == sym->regType && /* same register types */
- result->regType == sym->regType && /* same register types */
- result->nRegs && /* which needs registers */
- !result->isspilt && /* and does not already have them */
- !result->remat &&
- !bitVectBitValue (_G.regAssigned, result->key) &&
- /* the number of free regs + number of regs in this LR
- can accomodate the what result Needs */
- ((nfreeRegsType (result->regType) +
- sym->nRegs) >= result->nRegs)
- )
- {
-
- for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
- if (i < sym->nRegs)
- result->regs[i] = sym->regs[i];
- else
- result->regs[i] = getRegGpr (ic, ebp, result);
-
- _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
-
- }
-
- /* free the remaining */
- for (; i < sym->nRegs; i++)
- {
- if (psym)
- {
- if (!symHasReg (psym, sym->regs[i]))
- freeReg (sym->regs[i]);
- }
- else
- freeReg (sym->regs[i]);
- }
- }
- }
+ symbol *sym;
+ int k;
+ symbol *result;
+
+ debugLog ("%s\n", __FUNCTION__);
+ for (sym = hTabFirstItem (liveRanges, &k); sym;
+ sym = hTabNextItem (liveRanges, &k))
+ {
+
+ symbol *psym = NULL;
+ /* if it does not end here */
+ if (sym->liveTo > ic->seq)
+ continue;
+
+ /* Prevent the result from being assigned the same registers as (one)
+ * operand as many genXXX-functions fail otherwise.
+ * POINTER_GET(ic) || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == NOT
+ * are known to fail. */
+ if (sym->liveTo == ic->seq && IC_RESULT(ic))
+ {
+ switch (ic->op)
+ {
+ case '=': /* assignment */
+ case BITWISEAND: /* bitwise AND */
+ case '|': /* bitwise OR */
+ case '^': /* bitwise XOR */
+ case '~': /* bitwise negate */
+ case RLC: /* rotate through carry */
+ case RRC:
+ case UNARYMINUS:
+ case '+': /* addition */
+ case '-': /* subtraction */
+ /* go ahead, these are safe to use with
+ * non-disjoint register sets */
+ break;
+
+ default:
+ /* do not release operand registers */
+ //fprintf (stderr, "%s:%u: operand not freed: ", __FILE__, __LINE__); piCode (ic, stderr); fprintf (stderr, "\n");
+ continue;
+ } // switch
+ }
+
+ /* if it was spilt on stack then we can
+ mark the stack spil location as free */
+ if (sym->isspilt)
+ {
+ if (sym->stackSpil)
+ {
+ sym->usl.spillLoc->isFree = 1;
+ sym->stackSpil = 0;
+ }
+ continue;
+ }
+
+ if (!bitVectBitValue (_G.regAssigned, sym->key))
+ continue;
+ /* special case check if this is an IFX &
+ the privious one was a pop and the
+ previous one was not spilt then keep track
+ of the symbol */
+ if (ic->op == IFX && ic->prev &&
+ ic->prev->op == IPOP &&
+ !ic->prev->parmPush &&
+ IS_SYMOP(IC_LEFT (ic->prev)) &&
+ !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
+ psym = OP_SYMBOL (IC_LEFT (ic->prev));
+
+ if (sym->nRegs)
+ {
+ int i = 0;
+
+ bitVectUnSetBit (_G.regAssigned, sym->key);
+
+ /* if the result of this one needs registers
+ and does not have it then assign it right
+ away */
+ if (IC_RESULT (ic) &&
+ !(SKIP_IC2 (ic) || /* not a special icode */
+ ic->op == JUMPTABLE ||
+ ic->op == IFX ||
+ ic->op == IPUSH ||
+ ic->op == IPOP ||
+ ic->op == RETURN ||
+ POINTER_SET (ic)) &&
+ IS_SYMOP (IC_RESULT (ic)) &&
+ (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
+ result->liveTo > ic->seq && /* and will live beyond this */
+ result->liveTo <= ebp->lSeq && /* does not go beyond this block */
+ result->liveFrom == ic->seq && /* does not start before here */
+ result->regType == sym->regType && /* same register types */
+ result->regType == sym->regType && /* same register types */
+ result->nRegs && /* which needs registers */
+ !result->isspilt && /* and does not already have them */
+ !result->remat &&
+ !bitVectBitValue (_G.regAssigned, result->key) &&
+ /* the number of free regs + number of regs in this LR
+ can accomodate the what result Needs */
+ ((nfreeRegsType (result->regType) +
+ sym->nRegs) >= result->nRegs)
+ )
+ {
+
+ for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
+ if (i < sym->nRegs)
+ result->regs[i] = sym->regs[i];
+ else
+ result->regs[i] = getRegGpr (ic, ebp, result);
+
+ _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
+
+ }
+
+ /* free the remaining */
+ for (; i < sym->nRegs; i++)
+ {
+ if (psym)
+ {
+ if (!symHasReg (psym, sym->regs[i]))
+ freeReg (sym->regs[i]);
+ }
+ else
+ freeReg (sym->regs[i]);
+ }
+ }
+ }
}
static void
reassignLR (operand * op)
{
- symbol *sym = OP_SYMBOL (op);
- int i;
-
- debugLog ("%s\n", __FUNCTION__);
- /* not spilt any more */
- sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
- bitVectUnSetBit (_G.spiltSet, sym->key);
-
- _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
-
- _G.blockSpil--;
-
- for (i = 0; i < sym->nRegs; i++)
- sym->regs[i]->isFree = 0;
+ symbol *sym = OP_SYMBOL (op);
+ int i;
+
+ debugLog ("%s\n", __FUNCTION__);
+ /* not spilt any more */
+ sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
+ bitVectUnSetBit (_G.spiltSet, sym->key);
+
+ _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
+
+ _G.blockSpil--;
+
+ for (i = 0; i < sym->nRegs; i++)
+ sym->regs[i]->isFree = 0;
}
/*-----------------------------------------------------------------*/
static int
willCauseSpill (int nr, int rt)
{
- debugLog ("%s\n", __FUNCTION__);
- /* first check if there are any avlb registers
- of te type required */
- if (rt == REG_PTR)
- {
- /* special case for pointer type
- if pointer type not avlb then
- check for type gpr */
- if (nFreeRegs (rt) >= nr)
- return 0;
- if (nFreeRegs (REG_GPR) >= nr)
- return 0;
- }
- else
- {
- if (pic14_ptrRegReq)
- {
- if (nFreeRegs (rt) >= nr)
- return 0;
- }
- else
- {
- if (nFreeRegs (REG_PTR) +
- nFreeRegs (REG_GPR) >= nr)
- return 0;
- }
- }
-
- debugLog (" ... yep it will (cause a spill)\n");
- /* it will cause a spil */
- return 1;
+ debugLog ("%s\n", __FUNCTION__);
+ /* first check if there are any avlb registers
+ of te type required */
+ if (rt == REG_PTR)
+ {
+ /* special case for pointer type
+ if pointer type not avlb then
+ check for type gpr */
+ if (nFreeRegs (rt) >= nr)
+ return 0;
+ if (nFreeRegs (REG_GPR) >= nr)
+ return 0;
+ }
+ else
+ {
+ if (pic14_ptrRegReq)
+ {
+ if (nFreeRegs (rt) >= nr)
+ return 0;
+ }
+ else
+ {
+ if (nFreeRegs (REG_PTR) +
+ nFreeRegs (REG_GPR) >= nr)
+ return 0;
+ }
+ }
+
+ debugLog (" ... yep it will (cause a spill)\n");
+ /* it will cause a spil */
+ return 1;
}
/*-----------------------------------------------------------------*/
static void
positionRegs (symbol * result, symbol * opsym, int lineno)
{
- int count = min (result->nRegs, opsym->nRegs);
- int i, j = 0, shared = 0;
-
- debugLog ("%s\n", __FUNCTION__);
- /* if the result has been spilt then cannot share */
- if (opsym->isspilt)
- return;
+ int count = min (result->nRegs, opsym->nRegs);
+ int i, j = 0, shared = 0;
+
+ debugLog ("%s\n", __FUNCTION__);
+ /* if the result has been spilt then cannot share */
+ if (opsym->isspilt)
+ return;
again:
- shared = 0;
- /* first make sure that they actually share */
- for (i = 0; i < count; i++)
- {
- for (j = 0; j < count; j++)
- {
- if (result->regs[i] == opsym->regs[j] && i != j)
- {
- shared = 1;
- goto xchgPositions;
- }
- }
- }
+ shared = 0;
+ /* first make sure that they actually share */
+ for (i = 0; i < count; i++)
+ {
+ for (j = 0; j < count; j++)
+ {
+ if (result->regs[i] == opsym->regs[j] && i != j)
+ {
+ shared = 1;
+ goto xchgPositions;
+ }
+ }
+ }
xchgPositions:
- if (shared)
- {
- regs *tmp = result->regs[i];
- result->regs[i] = result->regs[j];
- result->regs[j] = tmp;
- goto again;
- }
+ if (shared)
+ {
+ regs *tmp = result->regs[i];
+ result->regs[i] = result->regs[j];
+ result->regs[j] = tmp;
+ goto again;
+ }
}
/*------------------------------------------------------------------*/
verifyRegsAssigned (operand *op, iCode * ic)
{
symbol * sym;
-
+
if (!op) return;
if (!IS_ITEMP (op)) return;
-
+
sym = OP_SYMBOL (op);
if (sym->isspilt) return;
if (!sym->nRegs) return;
if (sym->regs[0]) return;
-
- werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
- sym->prereqv ? sym->prereqv->name : sym->name);
+
+ werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
+ sym->prereqv ? sym->prereqv->name : sym->name);
spillThis (sym);
}
static void
serialRegAssign (eBBlock ** ebbs, int count)
{
- int i;
-
- debugLog ("%s\n", __FUNCTION__);
- /* for all blocks */
- for (i = 0; i < count; i++)
- {
-
- iCode *ic;
-
- if (ebbs[i]->noPath &&
- (ebbs[i]->entryLabel != entryLabel &&
- ebbs[i]->entryLabel != returnLabel))
- continue;
-
- /* of all instructions do */
- for (ic = ebbs[i]->sch; ic; ic = ic->next)
- {
- debugLog (" op: %s\n", decodeOp (ic->op));
-
- /* if this is an ipop that means some live
- range will have to be assigned again */
- if (ic->op == IPOP)
- reassignLR (IC_LEFT (ic));
-
- /* if result is present && is a true symbol */
- if (IC_RESULT (ic) && ic->op != IFX &&
- IS_TRUE_SYMOP (IC_RESULT (ic)))
- OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
-
- /* take away registers from live
- ranges that end at this instruction */
- deassignLRs (ic, ebbs[i]);
-
- /* some don't need registers */
- if (SKIP_IC2 (ic) ||
- ic->op == JUMPTABLE ||
- ic->op == IFX ||
- ic->op == IPUSH ||
- ic->op == IPOP ||
- (IC_RESULT (ic) && POINTER_SET (ic)))
- continue;
-
- /* now we need to allocate registers
- only for the result */
- if (IC_RESULT (ic) && IS_SYMOP (IC_RESULT (ic)))
- {
- symbol *sym = OP_SYMBOL (IC_RESULT (ic));
- bitVect *spillable;
- int willCS;
- int j;
- int ptrRegSet = 0;
-
- /* Make sure any spill location is definately allocated */
- if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
- !sym->usl.spillLoc->allocreq)
- {
- sym->usl.spillLoc->allocreq++;
- }
-
- /* if it does not need or is spilt
- or is already assigned to registers
- or will not live beyond this instructions */
- if (!sym->nRegs ||
- sym->isspilt ||
- bitVectBitValue (_G.regAssigned, sym->key) ||
- sym->liveTo <= ic->seq)
- continue;
-
- /* if some liverange has been spilt at the block level
- and this one live beyond this block then spil this
- to be safe */
- if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
- {
- spillThis (sym);
- continue;
- }
- /* if trying to allocate this will cause
- a spill and there is nothing to spill
- or this one is rematerializable then
- spill this one */
- willCS = willCauseSpill (sym->nRegs, sym->regType);
- spillable = computeSpillable (ic);
- if (sym->remat ||
- (willCS && bitVectIsZero (spillable)))
- {
-
- spillThis (sym);
- continue;
-
- }
-
- /* If the live range preceeds the point of definition
- then ideally we must take into account registers that
- have been allocated after sym->liveFrom but freed
- before ic->seq. This is complicated, so spill this
- symbol instead and let fillGaps handle the allocation. */
- if (sym->liveFrom < ic->seq)
- {
- spillThis (sym);
- continue;
- }
-
- /* if it has a spillocation & is used less than
- all other live ranges then spill this */
- if (willCS) {
- if (sym->usl.spillLoc) {
- symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
- allLRs, ebbs[i], ic));
- if (leastUsed && leastUsed->used > sym->used) {
- spillThis (sym);
- continue;
- }
- } else {
- /* if none of the liveRanges have a spillLocation then better
- to spill this one than anything else already assigned to registers */
- if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
- /* if this is local to this block then we might find a block spil */
- if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
- spillThis (sym);
- continue;
- }
- }
- }
- }
-
- if (ic->op == RECEIVE)
- debugLog ("When I get clever, I'll optimize the receive logic\n");
-
- /* if we need ptr regs for the right side
- then mark it */
- if (POINTER_GET (ic)
- && IS_SYMOP(IC_LEFT(ic))
- && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
- <= (unsigned) PTRSIZE)
- {
- pic14_ptrRegReq++;
- ptrRegSet = 1;
- }
- /* else we assign registers to it */
- _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
-
- debugLog (" %d - \n", __LINE__);
- if(debugF)
- bitVectDebugOn(_G.regAssigned, debugF);
- for (j = 0; j < sym->nRegs; j++)
- {
- if (sym->regType == REG_PTR)
- sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
- else
- sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
-
- /* if the allocation failed which means
- this was spilt then break */
- if (!sym->regs[j])
- break;
- }
- debugLog (" %d - \n", __LINE__);
-
- /* if it shares registers with operands make sure
- that they are in the same position */
- if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
- IS_SYMOP(IC_RESULT(ic)) &&
- OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
- positionRegs (OP_SYMBOL (IC_RESULT (ic)),
- OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
- /* do the same for the right operand */
- if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
- IS_SYMOP(IC_RESULT(ic)) &&
- OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
- positionRegs (OP_SYMBOL (IC_RESULT (ic)),
- OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
-
- debugLog (" %d - \n", __LINE__);
- if (ptrRegSet)
- {
- debugLog (" %d - \n", __LINE__);
- pic14_ptrRegReq--;
- ptrRegSet = 0;
- }
-
- }
- }
- }
+ int i;
+
+ debugLog ("%s\n", __FUNCTION__);
+ /* for all blocks */
+ for (i = 0; i < count; i++)
+ {
+
+ iCode *ic;
+
+ if (ebbs[i]->noPath &&
+ (ebbs[i]->entryLabel != entryLabel &&
+ ebbs[i]->entryLabel != returnLabel))
+ continue;
+
+ /* of all instructions do */
+ for (ic = ebbs[i]->sch; ic; ic = ic->next)
+ {
+ debugLog (" op: %s\n", decodeOp (ic->op));
+
+ /* if this is an ipop that means some live
+ range will have to be assigned again */
+ if (ic->op == IPOP)
+ reassignLR (IC_LEFT (ic));
+
+ /* if result is present && is a true symbol */
+ if (IC_RESULT (ic) && ic->op != IFX &&
+ IS_TRUE_SYMOP (IC_RESULT (ic)))
+ OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
+
+ /* take away registers from live
+ ranges that end at this instruction */
+ deassignLRs (ic, ebbs[i]);
+
+ /* some don't need registers */
+ if (SKIP_IC2 (ic) ||
+ ic->op == JUMPTABLE ||
+ ic->op == IFX ||
+ ic->op == IPUSH ||
+ ic->op == IPOP ||
+ (IC_RESULT (ic) && POINTER_SET (ic)))
+ continue;
+
+ /* now we need to allocate registers
+ only for the result */
+ if (IC_RESULT (ic) && IS_SYMOP (IC_RESULT (ic)))
+ {
+ symbol *sym = OP_SYMBOL (IC_RESULT (ic));
+ bitVect *spillable;
+ int willCS;
+ int j;
+ int ptrRegSet = 0;
+
+ /* Make sure any spill location is definately allocated */
+ if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
+ !sym->usl.spillLoc->allocreq)
+ {
+ sym->usl.spillLoc->allocreq++;
+ }
+
+ /* if it does not need or is spilt
+ or is already assigned to registers
+ or will not live beyond this instructions */
+ if (!sym->nRegs ||
+ sym->isspilt ||
+ bitVectBitValue (_G.regAssigned, sym->key) ||
+ sym->liveTo <= ic->seq)
+ continue;
+
+ /* if some liverange has been spilt at the block level
+ and this one live beyond this block then spil this
+ to be safe */
+ if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
+ {
+ spillThis (sym);
+ continue;
+ }
+ /* if trying to allocate this will cause
+ a spill and there is nothing to spill
+ or this one is rematerializable then
+ spill this one */
+ willCS = willCauseSpill (sym->nRegs, sym->regType);
+ spillable = computeSpillable (ic);
+ if (sym->remat ||
+ (willCS && bitVectIsZero (spillable)))
+ {
+
+ spillThis (sym);
+ continue;
+
+ }
+
+ /* If the live range preceeds the point of definition
+ then ideally we must take into account registers that
+ have been allocated after sym->liveFrom but freed
+ before ic->seq. This is complicated, so spill this
+ symbol instead and let fillGaps handle the allocation. */
+ if (sym->liveFrom < ic->seq)
+ {
+ spillThis (sym);
+ continue;
+ }
+
+ /* if it has a spillocation & is used less than
+ all other live ranges then spill this */
+ if (willCS) {
+ if (sym->usl.spillLoc) {
+ symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
+ allLRs, ebbs[i], ic));
+ if (leastUsed && leastUsed->used > sym->used) {
+ spillThis (sym);
+ continue;
+ }
+ } else {
+ /* if none of the liveRanges have a spillLocation then better
+ to spill this one than anything else already assigned to registers */
+ if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
+ /* if this is local to this block then we might find a block spil */
+ if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
+ spillThis (sym);
+ continue;
+ }
+ }
+ }
+ }
+
+ if (ic->op == RECEIVE)
+ debugLog ("When I get clever, I'll optimize the receive logic\n");
+
+ /* if we need ptr regs for the right side
+ then mark it */
+ if (POINTER_GET (ic)
+ && IS_SYMOP(IC_LEFT(ic))
+ && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
+ <= (unsigned) PTRSIZE)
+ {
+ pic14_ptrRegReq++;
+ ptrRegSet = 1;
+ }
+ /* else we assign registers to it */
+ _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
+
+ debugLog (" %d - \n", __LINE__);
+ if(debugF)
+ bitVectDebugOn(_G.regAssigned, debugF);
+ for (j = 0; j < sym->nRegs; j++)
+ {
+ if (sym->regType == REG_PTR)
+ sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
+ else
+ sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
+
+ /* if the allocation failed which means
+ this was spilt then break */
+ if (!sym->regs[j])
+ break;
+ }
+ debugLog (" %d - \n", __LINE__);
+
+ /* if it shares registers with operands make sure
+ that they are in the same position */
+ if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
+ IS_SYMOP(IC_RESULT(ic)) &&
+ OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
+ positionRegs (OP_SYMBOL (IC_RESULT (ic)),
+ OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
+ /* do the same for the right operand */
+ if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
+ IS_SYMOP(IC_RESULT(ic)) &&
+ OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
+ positionRegs (OP_SYMBOL (IC_RESULT (ic)),
+ OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
+
+ debugLog (" %d - \n", __LINE__);
+ if (ptrRegSet)
+ {
+ debugLog (" %d - \n", __LINE__);
+ pic14_ptrRegReq--;
+ ptrRegSet = 0;
+ }
+
+ }
+ }
+ }
/* Check for and fix any problems with uninitialized operands */
for (i = 0; i < count; i++)
- {
- iCode *ic;
-
- if (ebbs[i]->noPath &&
- (ebbs[i]->entryLabel != entryLabel &&
- ebbs[i]->entryLabel != returnLabel))
- continue;
-
- for (ic = ebbs[i]->sch; ic; ic = ic->next)
- {
- if (SKIP_IC2 (ic))
- continue;
-
- if (ic->op == IFX)
- {
- verifyRegsAssigned (IC_COND (ic), ic);
- continue;
- }
-
- if (ic->op == JUMPTABLE)
- {
- verifyRegsAssigned (IC_JTCOND (ic), ic);
- continue;
- }
-
- verifyRegsAssigned (IC_RESULT (ic), ic);
- verifyRegsAssigned (IC_LEFT (ic), ic);
- verifyRegsAssigned (IC_RIGHT (ic), ic);
- }
- }
+ {
+ iCode *ic;
+
+ if (ebbs[i]->noPath &&
+ (ebbs[i]->entryLabel != entryLabel &&
+ ebbs[i]->entryLabel != returnLabel))
+ continue;
+
+ for (ic = ebbs[i]->sch; ic; ic = ic->next)
+ {
+ if (SKIP_IC2 (ic))
+ continue;
+
+ if (ic->op == IFX)
+ {
+ verifyRegsAssigned (IC_COND (ic), ic);
+ continue;
+ }
+
+ if (ic->op == JUMPTABLE)
+ {
+ verifyRegsAssigned (IC_JTCOND (ic), ic);
+ continue;
+ }
+
+ verifyRegsAssigned (IC_RESULT (ic), ic);
+ verifyRegsAssigned (IC_LEFT (ic), ic);
+ verifyRegsAssigned (IC_RIGHT (ic), ic);
+ }
+ }
}
static bitVect *
rUmaskForOp (operand * op)
{
- bitVect *rumask;
- symbol *sym;
- int j;
-
- debugLog ("%s\n", __FUNCTION__);
- /* only temporaries are assigned registers */
- if (!IS_ITEMP (op))
- return NULL;
-
- sym = OP_SYMBOL (op);
-
- /* if spilt or no registers assigned to it
- then nothing */
- if (sym->isspilt || !sym->nRegs)
- return NULL;
-
- rumask = newBitVect (pic14_nRegs);
-
- for (j = 0; j < sym->nRegs; j++)
- {
- rumask = bitVectSetBit (rumask,
- sym->regs[j]->rIdx);
- }
-
- return rumask;
+ bitVect *rumask;
+ symbol *sym;
+ int j;
+
+ debugLog ("%s\n", __FUNCTION__);
+ /* only temporaries are assigned registers */
+ if (!IS_ITEMP (op))
+ return NULL;
+
+ sym = OP_SYMBOL (op);
+
+ /* if spilt or no registers assigned to it
+ then nothing */
+ if (sym->isspilt || !sym->nRegs)
+ return NULL;
+
+ rumask = newBitVect (pic14_nRegs);
+
+ for (j = 0; j < sym->nRegs; j++)
+ {
+ rumask = bitVectSetBit (rumask,
+ sym->regs[j]->rIdx);
+ }
+
+ return rumask;
}
/*-----------------------------------------------------------------*/
static bitVect *
regsUsedIniCode (iCode * ic)
{
- bitVect *rmask = newBitVect (pic14_nRegs);
-
- debugLog ("%s\n", __FUNCTION__);
- /* do the special cases first */
- if (ic->op == IFX)
- {
- rmask = bitVectUnion (rmask,
- rUmaskForOp (IC_COND (ic)));
- goto ret;
- }
-
- /* for the jumptable */
- if (ic->op == JUMPTABLE)
- {
- rmask = bitVectUnion (rmask,
- rUmaskForOp (IC_JTCOND (ic)));
-
- goto ret;
- }
-
- /* of all other cases */
- if (IC_LEFT (ic))
- rmask = bitVectUnion (rmask,
- rUmaskForOp (IC_LEFT (ic)));
-
-
- if (IC_RIGHT (ic))
- rmask = bitVectUnion (rmask,
- rUmaskForOp (IC_RIGHT (ic)));
-
- if (IC_RESULT (ic))
- rmask = bitVectUnion (rmask,
- rUmaskForOp (IC_RESULT (ic)));
-
+ bitVect *rmask = newBitVect (pic14_nRegs);
+
+ debugLog ("%s\n", __FUNCTION__);
+ /* do the special cases first */
+ if (ic->op == IFX)
+ {
+ rmask = bitVectUnion (rmask,
+ rUmaskForOp (IC_COND (ic)));
+ goto ret;
+ }
+
+ /* for the jumptable */
+ if (ic->op == JUMPTABLE)
+ {
+ rmask = bitVectUnion (rmask,
+ rUmaskForOp (IC_JTCOND (ic)));
+
+ goto ret;
+ }
+
+ /* of all other cases */
+ if (IC_LEFT (ic))
+ rmask = bitVectUnion (rmask,
+ rUmaskForOp (IC_LEFT (ic)));
+
+
+ if (IC_RIGHT (ic))
+ rmask = bitVectUnion (rmask,
+ rUmaskForOp (IC_RIGHT (ic)));
+
+ if (IC_RESULT (ic))
+ rmask = bitVectUnion (rmask,
+ rUmaskForOp (IC_RESULT (ic)));
+
ret:
- return rmask;
+ return rmask;
}
/*-----------------------------------------------------------------*/
static void
createRegMask (eBBlock ** ebbs, int count)
{
- int i;
-
- debugLog ("%s\n", __FUNCTION__);
- /* for all blocks */
- for (i = 0; i < count; i++)
- {
- iCode *ic;
-
- if (ebbs[i]->noPath &&
- (ebbs[i]->entryLabel != entryLabel &&
- ebbs[i]->entryLabel != returnLabel))
- continue;
-
- /* for all instructions */
- for (ic = ebbs[i]->sch; ic; ic = ic->next)
- {
-
- int j;
-
- if (SKIP_IC2 (ic) || !ic->rlive)
- continue;
-
- /* first mark the registers used in this
- instruction */
- ic->rUsed = regsUsedIniCode (ic);
- _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
-
- /* now create the register mask for those
- registers that are in use : this is a
- super set of ic->rUsed */
- ic->rMask = newBitVect (pic14_nRegs + 1);
-
- /* for all live Ranges alive at this point */
- for (j = 1; j < ic->rlive->size; j++)
- {
- symbol *sym;
- int k;
-
- /* if not alive then continue */
- if (!bitVectBitValue (ic->rlive, j))
- continue;
-
- /* find the live range we are interested in */
- if (!(sym = hTabItemWithKey (liveRanges, j)))
- {
- werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "createRegMask cannot find live range");
- exit (0);
- }
-
- /* if no register assigned to it */
- if (!sym->nRegs || sym->isspilt)
- continue;
-
- /* for all the registers allocated to it */
- for (k = 0; k < sym->nRegs; k++)
- if (sym->regs[k])
- ic->rMask =
- bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
- }
- }
- }
+ int i;
+
+ debugLog ("%s\n", __FUNCTION__);
+ /* for all blocks */
+ for (i = 0; i < count; i++)
+ {
+ iCode *ic;
+
+ if (ebbs[i]->noPath &&
+ (ebbs[i]->entryLabel != entryLabel &&
+ ebbs[i]->entryLabel != returnLabel))
+ continue;
+
+ /* for all instructions */
+ for (ic = ebbs[i]->sch; ic; ic = ic->next)
+ {
+
+ int j;
+
+ if (SKIP_IC2 (ic) || !ic->rlive)
+ continue;
+
+ /* first mark the registers used in this
+ instruction */
+ ic->rUsed = regsUsedIniCode (ic);
+ _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
+
+ /* now create the register mask for those
+ registers that are in use : this is a
+ super set of ic->rUsed */
+ ic->rMask = newBitVect (pic14_nRegs + 1);
+
+ /* for all live Ranges alive at this point */
+ for (j = 1; j < ic->rlive->size; j++)
+ {
+ symbol *sym;
+ int k;
+
+ /* if not alive then continue */
+ if (!bitVectBitValue (ic->rlive, j))
+ continue;
+
+ /* find the live range we are interested in */
+ if (!(sym = hTabItemWithKey (liveRanges, j)))
+ {
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "createRegMask cannot find live range");
+ exit (0);
+ }
+
+ /* if no register assigned to it */
+ if (!sym->nRegs || sym->isspilt)
+ continue;
+
+ /* for all the registers allocated to it */
+ for (k = 0; k < sym->nRegs; k++)
+ if (sym->regs[k])
+ ic->rMask =
+ bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
+ }
+ }
+ }
}
#if 0
/* This was the active version */
static symbol *
rematStr (symbol * sym)
{
- char *s = buffer;
- iCode *ic = sym->rematiCode;
- symbol *psym = NULL;
-
- debugLog ("%s\n", __FUNCTION__);
-
- //printf ("%s\n", s);
-
- /* if plus or minus print the right hand side */
-
- if (ic->op == '+' || ic->op == '-') {
-
- iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
-
- sprintf (s, "(%s %c 0x%04x)",
- OP_SYMBOL (IC_LEFT (ric))->rname,
- ic->op,
- (int) operandLitValue (IC_RIGHT (ic)));
-
-
- //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
-
- psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
- psym->offset = (int) operandLitValue (IC_RIGHT (ic));
-
- return psym;
- }
-
- sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
- psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
-
- //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
- return psym;
+ char *s = buffer;
+ iCode *ic = sym->rematiCode;
+ symbol *psym = NULL;
+
+ debugLog ("%s\n", __FUNCTION__);
+
+ //printf ("%s\n", s);
+
+ /* if plus or minus print the right hand side */
+
+ if (ic->op == '+' || ic->op == '-') {
+
+ iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
+
+ sprintf (s, "(%s %c 0x%04x)",
+ OP_SYMBOL (IC_LEFT (ric))->rname,
+ ic->op,
+ (int) operandLitValue (IC_RIGHT (ic)));
+
+
+ //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
+
+ psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
+ psym->offset = (int) operandLitValue (IC_RIGHT (ic));
+
+ return psym;
+ }
+
+ sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
+ psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
+
+ //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
+ return psym;
}
#endif
static char *
rematStr (symbol * sym)
{
- char *s = buffer;
- iCode *ic = sym->rematiCode;
-
- debugLog ("%s\n", __FUNCTION__);
- while (1)
- {
-
- printf ("%s\n", s);
- /* if plus or minus print the right hand side */
- /*
- if (ic->op == '+' || ic->op == '-') {
- sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
- ic->op );
- s += strlen(s);
- ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
- continue ;
- }
- */
- if (ic->op == '+' || ic->op == '-')
- {
- iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
- sprintf (s, "(%s %c 0x%04x)",
- OP_SYMBOL (IC_LEFT (ric))->rname,
- ic->op,
- (int) operandLitValue (IC_RIGHT (ic)));
-
- //s += strlen(s);
- //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
- //continue ;
- //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
- return buffer;
- }
-
- /* we reached the end */
- sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
- break;
- }
-
- printf ("%s\n", buffer);
- return buffer;
+ char *s = buffer;
+ iCode *ic = sym->rematiCode;
+
+ debugLog ("%s\n", __FUNCTION__);
+ while (1)
+ {
+
+ printf ("%s\n", s);
+ /* if plus or minus print the right hand side */
+ /*
+ if (ic->op == '+' || ic->op == '-') {
+ sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
+ ic->op );
+ s += strlen(s);
+ ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
+ continue ;
+ }
+ */
+ if (ic->op == '+' || ic->op == '-')
+ {
+ iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
+ sprintf (s, "(%s %c 0x%04x)",
+ OP_SYMBOL (IC_LEFT (ric))->rname,
+ ic->op,
+ (int) operandLitValue (IC_RIGHT (ic)));
+
+ //s += strlen(s);
+ //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
+ //continue ;
+ //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
+ return buffer;
+ }
+
+ /* we reached the end */
+ sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
+ break;
+ }
+
+ printf ("%s\n", buffer);
+ return buffer;
}
#endif
static void
regTypeNum ()
{
- symbol *sym;
- int k;
- //iCode *ic;
-
- debugLog ("%s\n", __FUNCTION__);
- /* for each live range do */
- for (sym = hTabFirstItem (liveRanges, &k); sym;
- sym = hTabNextItem (liveRanges, &k)) {
-
- debugLog (" %d - %s\n", __LINE__, sym->rname);
-
- /* if used zero times then no registers needed */
- if ((sym->liveTo - sym->liveFrom) == 0)
- continue;
-
-
- /* if the live range is a temporary */
- if (sym->isitmp) {
-
- debugLog (" %d - itemp register\n", __LINE__);
-
- /* if the type is marked as a conditional */
- if (sym->regType == REG_CND)
- continue;
-
- /* if used in return only then we don't
- need registers */
- if (sym->accuse) {
- if (IS_AGGREGATE (sym->type) || sym->isptr)
- sym->type = aggrToPtr (sym->type, FALSE);
- debugLog (" %d - no reg needed - accumulator used\n", __LINE__);
-
- continue;
- }
-
- if (sym->ruonly) {
- //if (IS_AGGREGATE (sym->type) || sym->isptr)
- // sym->type = aggrToPtr (sym->type, FALSE);
- debugLog (" %d - used as a return\n", __LINE__);
-
- //continue;
- }
-
- /* if the symbol has only one definition &
- that definition is a get_pointer and the
- pointer we are getting is rematerializable and
- in "data" space */
-
+ symbol *sym;
+ int k;
+ //iCode *ic;
+
+ debugLog ("%s\n", __FUNCTION__);
+ /* for each live range do */
+ for (sym = hTabFirstItem (liveRanges, &k); sym;
+ sym = hTabNextItem (liveRanges, &k)) {
+
+ debugLog (" %d - %s\n", __LINE__, sym->rname);
+
+ /* if used zero times then no registers needed */
+ if ((sym->liveTo - sym->liveFrom) == 0)
+ continue;
+
+
+ /* if the live range is a temporary */
+ if (sym->isitmp) {
+
+ debugLog (" %d - itemp register\n", __LINE__);
+
+ /* if the type is marked as a conditional */
+ if (sym->regType == REG_CND)
+ continue;
+
+ /* if used in return only then we don't
+ need registers */
+ if (sym->accuse) {
+ if (IS_AGGREGATE (sym->type) || sym->isptr)
+ sym->type = aggrToPtr (sym->type, FALSE);
+ debugLog (" %d - no reg needed - accumulator used\n", __LINE__);
+
+ continue;
+ }
+
+ if (sym->ruonly) {
+ //if (IS_AGGREGATE (sym->type) || sym->isptr)
+ // sym->type = aggrToPtr (sym->type, FALSE);
+ debugLog (" %d - used as a return\n", __LINE__);
+
+ //continue;
+ }
+
+ /* if the symbol has only one definition &
+ that definition is a get_pointer and the
+ pointer we are getting is rematerializable and
+ in "data" space */
+
#if 0
- if (bitVectnBitsOn (sym->defs) == 1 &&
- (ic = hTabItemWithKey (iCodehTab,
- bitVectFirstBit (sym->defs))) &&
- POINTER_GET (ic) &&
- !IS_BITVAR (sym->etype) &&
- (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
-
- if (ptrPseudoSymSafe (sym, ic)) {
-
- symbol *psym;
-
- debugLog (" %d - \n", __LINE__);
-
- /* create a pseudo symbol & force a spil */
- //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
- psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
- psym->type = sym->type;
- psym->etype = sym->etype;
- psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
- strcpy (psym->rname, psym->name);
- sym->isspilt = 1;
- sym->usl.spillLoc = psym;
- continue;
- }
-
- /* if in data space or idata space then try to
- allocate pointer register */
-
- }
+ if (bitVectnBitsOn (sym->defs) == 1 &&
+ (ic = hTabItemWithKey (iCodehTab,
+ bitVectFirstBit (sym->defs))) &&
+ POINTER_GET (ic) &&
+ !IS_BITVAR (sym->etype) &&
+ (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
+
+ if (ptrPseudoSymSafe (sym, ic)) {
+
+ symbol *psym;
+
+ debugLog (" %d - \n", __LINE__);
+
+ /* create a pseudo symbol & force a spil */
+ //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
+ psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
+ psym->type = sym->type;
+ psym->etype = sym->etype;
+ psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
+ strcpy (psym->rname, psym->name);
+ sym->isspilt = 1;
+ sym->usl.spillLoc = psym;
+ continue;
+ }
+
+ /* if in data space or idata space then try to
+ allocate pointer register */
+
+ }
#endif
-
- /* if not then we require registers */
- sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
- getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
- getSize (sym->type));
-
-
- if(IS_PTR_CONST (sym->type)) {
- debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
- sym->nRegs = 2;
- }
-
- if (sym->nRegs > 4) {
- fprintf (stderr, "allocated more than 4 or 0 registers for type ");
- printTypeChain (sym->type, stderr);
- fprintf (stderr, "\n");
- }
-
- /* determine the type of register required */
- if (sym->nRegs == 1 &&
- IS_PTR (sym->type) &&
- sym->uptr)
- sym->regType = REG_PTR;
- else
- sym->regType = REG_GPR;
-
-
- debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
-
- }
- else
- /* for the first run we don't provide */
- /* registers for true symbols we will */
- /* see how things go */
- sym->nRegs = 0;
- }
-
+
+ /* if not then we require registers */
+ sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
+ getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
+ getSize (sym->type));
+
+
+ if(IS_PTR_CONST (sym->type)) {
+ debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
+ sym->nRegs = 2;
+ }
+
+ if (sym->nRegs > 4) {
+ fprintf (stderr, "allocated more than 4 or 0 registers for type ");
+ printTypeChain (sym->type, stderr);
+ fprintf (stderr, "\n");
+ }
+
+ /* determine the type of register required */
+ if (sym->nRegs == 1 &&
+ IS_PTR (sym->type) &&
+ sym->uptr)
+ sym->regType = REG_PTR;
+ else
+ sym->regType = REG_GPR;
+
+
+ debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
+
+ }
+ else
+ /* for the first run we don't provide */
+ /* registers for true symbols we will */
+ /* see how things go */
+ sym->nRegs = 0;
+ }
+
}
DEFSETFUNC (markRegFree)
{
- ((regs *)item)->isFree = 1;
-
- return 0;
+ ((regs *)item)->isFree = 1;
+
+ return 0;
}
DEFSETFUNC (deallocReg)
{
- fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
- ((regs *)item)->isFree = 1;
- ((regs *)item)->wasUsed = 0;
-
- return 0;
+ fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
+ ((regs *)item)->isFree = 1;
+ ((regs *)item)->wasUsed = 0;
+
+ return 0;
}
/*-----------------------------------------------------------------*/
/* freeAllRegs - mark all registers as free */
void
pic14_freeAllRegs ()
{
- // int i;
-
- debugLog ("%s\n", __FUNCTION__);
-
- applyToSet(dynAllocRegs,markRegFree);
- applyToSet(dynStackRegs,markRegFree);
-
- /*
- for (i = 0; i < pic14_nRegs; i++)
- regspic14[i].isFree = 1;
- */
+ // int i;
+
+ debugLog ("%s\n", __FUNCTION__);
+
+ applyToSet(dynAllocRegs,markRegFree);
+ applyToSet(dynStackRegs,markRegFree);
+
+ /*
+ for (i = 0; i < pic14_nRegs; i++)
+ regspic14[i].isFree = 1;
+ */
}
/*-----------------------------------------------------------------*/
void
pic14_deallocateAllRegs ()
{
- // int i;
-
- debugLog ("%s\n", __FUNCTION__);
-
- applyToSet(dynAllocRegs,deallocReg);
-
- /*
- for (i = 0; i < pic14_nRegs; i++) {
- if(regspic14[i].pc_type == PO_GPR_TEMP) {
- regspic14[i].isFree = 1;
- regspic14[i].wasUsed = 0;
- }
- }
- */
+ // int i;
+
+ debugLog ("%s\n", __FUNCTION__);
+
+ applyToSet(dynAllocRegs,deallocReg);
+
+ /*
+ for (i = 0; i < pic14_nRegs; i++) {
+ if(regspic14[i].pc_type == PO_GPR_TEMP) {
+ regspic14[i].isFree = 1;
+ regspic14[i].wasUsed = 0;
+ }
+ }
+ */
}
static
DEFSETFUNC (deallocStackSpil)
{
- symbol *sym = item;
-
- debugLog ("%s\n", __FUNCTION__);
- deallocLocal (sym);
- return 0;
+ symbol *sym = item;
+
+ debugLog ("%s\n", __FUNCTION__);
+ deallocLocal (sym);
+ return 0;
}
/*-----------------------------------------------------------------*/
static iCode *
farSpacePackable (iCode * ic)
{
- iCode *dic;
-
- debugLog ("%s\n", __FUNCTION__);
- /* go thru till we find a definition for the
- symbol on the right */
- for (dic = ic->prev; dic; dic = dic->prev)
- {
-
- /* if the definition is a call then no */
- if ((dic->op == CALL || dic->op == PCALL) &&
- IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
- {
- return NULL;
- }
-
- /* if shift by unknown amount then not */
- if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
- IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
- return NULL;
-
- /* if pointer get and size > 1 */
- if (POINTER_GET (dic) &&
- getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
- return NULL;
-
- if (POINTER_SET (dic) &&
- getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
- return NULL;
-
- /* if any three is a true symbol in far space */
- if (IC_RESULT (dic) &&
- IS_TRUE_SYMOP (IC_RESULT (dic)) &&
- isOperandInFarSpace (IC_RESULT (dic)))
- return NULL;
-
- if (IC_RIGHT (dic) &&
- IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
- isOperandInFarSpace (IC_RIGHT (dic)) &&
- !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
- return NULL;
-
- if (IC_LEFT (dic) &&
- IS_TRUE_SYMOP (IC_LEFT (dic)) &&
- isOperandInFarSpace (IC_LEFT (dic)) &&
- !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
- return NULL;
-
- if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
- {
- if ((dic->op == LEFT_OP ||
- dic->op == RIGHT_OP ||
- dic->op == '-') &&
- IS_OP_LITERAL (IC_RIGHT (dic)))
- return NULL;
- else
- return dic;
- }
- }
-
- return NULL;
+ iCode *dic;
+
+ debugLog ("%s\n", __FUNCTION__);
+ /* go thru till we find a definition for the
+ symbol on the right */
+ for (dic = ic->prev; dic; dic = dic->prev)
+ {
+
+ /* if the definition is a call then no */
+ if ((dic->op == CALL || dic->op == PCALL) &&
+ IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
+ {
+ return NULL;
+ }
+
+ /* if shift by unknown amount then not */
+ if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
+ IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
+ return NULL;
+
+ /* if pointer get and size > 1 */
+ if (POINTER_GET (dic) &&
+ getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
+ return NULL;
+
+ if (POINTER_SET (dic) &&
+ getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
+ return NULL;
+
+ /* if any three is a true symbol in far space */
+ if (IC_RESULT (dic) &&
+ IS_TRUE_SYMOP (IC_RESULT (dic)) &&
+ isOperandInFarSpace (IC_RESULT (dic)))
+ return NULL;
+
+ if (IC_RIGHT (dic) &&
+ IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
+ isOperandInFarSpace (IC_RIGHT (dic)) &&
+ !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
+ return NULL;
+
+ if (IC_LEFT (dic) &&
+ IS_TRUE_SYMOP (IC_LEFT (dic)) &&
+ isOperandInFarSpace (IC_LEFT (dic)) &&
+ !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
+ return NULL;
+
+ if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
+ {
+ if ((dic->op == LEFT_OP ||
+ dic->op == RIGHT_OP ||
+ dic->op == '-') &&
+ IS_OP_LITERAL (IC_RIGHT (dic)))
+ return NULL;
+ else
+ return dic;
+ }
+ }
+
+ return NULL;
}
/*-----------------------------------------------------------------*/
static int
packRegsForAssign (iCode * ic, eBBlock * ebp)
{
-
- iCode *dic, *sic;
-
- debugLog ("%s\n", __FUNCTION__);
-
- debugAopGet (" result:", IC_RESULT (ic));
- debugAopGet (" left:", IC_LEFT (ic));
- debugAopGet (" right:", IC_RIGHT (ic));
-
- /* if this is at an absolute address, then get the address. */
- if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
- if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
- debugLog (" %d - found config word declaration\n", __LINE__);
- if(IS_VALOP(IC_RIGHT(ic))) {
- debugLog (" setting config word to %x\n",
- (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
- pic14_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
- (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
- }
-
- /* remove the assignment from the iCode chain. */
-
- remiCodeFromeBBlock (ebp, ic);
- bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
- hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
-
- return 1;
-
- }
- }
-
- if (!IS_ITEMP (IC_RESULT (ic))) {
- allocDirReg(IC_RESULT (ic));
- debugLog (" %d - result is not temp\n", __LINE__);
- }
- /*
- if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
- debugLog (" %d - left is not temp, allocating\n", __LINE__);
- allocDirReg(IC_LEFT (ic));
- }
- */
-
- if (!IS_ITEMP (IC_RIGHT (ic))) {
- debugLog (" %d - not packing - right is not temp\n", __LINE__);
-
- /* only pack if this is not a function pointer */
- if (!IS_REF (IC_RIGHT (ic)))
- allocDirReg(IC_RIGHT (ic));
- return 0;
- }
-
- if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
- OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
- {
- debugLog (" %d - not packing - right side fails \n", __LINE__);
- return 0;
- }
-
- /* if the true symbol is defined in far space or on stack
- then we should not since this will increase register pressure */
- if (isOperandInFarSpace (IC_RESULT (ic)))
- {
- if ((dic = farSpacePackable (ic)))
- goto pack;
- else
- return 0;
-
- }
- /* find the definition of iTempNN scanning backwards if we find a
- a use of the true symbol before we find the definition then
- we cannot pack */
- for (dic = ic->prev; dic; dic = dic->prev)
- {
-
- /* if there is a function call and this is
- a parameter & not my parameter then don't pack it */
- if ((dic->op == CALL || dic->op == PCALL) &&
- (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
- !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
- {
- debugLog (" %d - \n", __LINE__);
- dic = NULL;
- break;
- }
-
- if (SKIP_IC2 (dic))
- continue;
-
- if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
- IS_OP_VOLATILE (IC_RESULT (dic)))
- {
- debugLog (" %d - dic is VOLATILE \n", __LINE__);
- dic = NULL;
- break;
- }
-
- if (IS_SYMOP (IC_RESULT (dic)) &&
- IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
- {
- /* A previous result was assigned to the same register - we'll our definition */
- debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
- __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
- if (POINTER_SET (dic))
- dic = NULL;
-
- break;
- }
-
- if (IS_SYMOP (IC_RIGHT (dic)) &&
- (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
- IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
- {
- debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
- dic = NULL;
- break;
- }
-
- if (IS_SYMOP (IC_LEFT (dic)) &&
- (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
- IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
- {
- debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
- dic = NULL;
- break;
- }
-
- if (POINTER_SET (dic) &&
- IC_RESULT (dic)->key == IC_RESULT (ic)->key)
- {
- debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
- __LINE__);
- dic = NULL;
- break;
- }
- }
-
- if (!dic)
- return 0; /* did not find */
-
- /* if assignment then check that right is not a bit */
- if (ASSIGNMENT (ic) && !POINTER_SET (ic))
- {
- sym_link *etype = operandType (IC_RESULT (dic));
- if (IS_BITFIELD (etype))
- {
- /* if result is a bit too then it's ok */
- etype = operandType (IC_RESULT (ic));
- if (!IS_BITFIELD (etype))
- return 0;
- }
- }
-
- /* if the result is on stack or iaccess then it must be
- the same at least one of the operands */
- if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
- OP_SYMBOL (IC_RESULT (ic))->iaccess)
- {
-
- /* the operation has only one symbol
- operator then we can pack */
- if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
- (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
- goto pack;
-
- if (!((IC_LEFT (dic) &&
- IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
- (IC_RIGHT (dic) &&
- IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
- return 0;
- }
+
+ iCode *dic, *sic;
+
+ debugLog ("%s\n", __FUNCTION__);
+
+ debugAopGet (" result:", IC_RESULT (ic));
+ debugAopGet (" left:", IC_LEFT (ic));
+ debugAopGet (" right:", IC_RIGHT (ic));
+
+ /* if this is at an absolute address, then get the address. */
+ if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
+ if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
+ debugLog (" %d - found config word declaration\n", __LINE__);
+ if(IS_VALOP(IC_RIGHT(ic))) {
+ debugLog (" setting config word to %x\n",
+ (int) ulFromVal (IC_RIGHT(ic)->operand.valOperand));
+ pic14_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
+ (int) ulFromVal (IC_RIGHT(ic)->operand.valOperand));
+ }
+
+ /* remove the assignment from the iCode chain. */
+
+ remiCodeFromeBBlock (ebp, ic);
+ bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
+ hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
+
+ return 1;
+
+ }
+ }
+
+ if (!IS_ITEMP (IC_RESULT (ic))) {
+ allocDirReg(IC_RESULT (ic));
+ debugLog (" %d - result is not temp\n", __LINE__);
+ }
+ /*
+ if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
+ debugLog (" %d - left is not temp, allocating\n", __LINE__);
+ allocDirReg(IC_LEFT (ic));
+ }
+ */
+
+ if (!IS_ITEMP (IC_RIGHT (ic))) {
+ debugLog (" %d - not packing - right is not temp\n", __LINE__);
+
+ /* only pack if this is not a function pointer */
+ if (!IS_REF (IC_RIGHT (ic)))
+ allocDirReg(IC_RIGHT (ic));
+ return 0;
+ }
+
+ if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
+ OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
+ {
+ debugLog (" %d - not packing - right side fails \n", __LINE__);
+ return 0;
+ }
+
+ /* if the true symbol is defined in far space or on stack
+ then we should not since this will increase register pressure */
+ if (isOperandInFarSpace (IC_RESULT (ic)))
+ {
+ if ((dic = farSpacePackable (ic)))
+ goto pack;
+ else
+ return 0;
+
+ }
+ /* find the definition of iTempNN scanning backwards if we find a
+ a use of the true symbol before we find the definition then
+ we cannot pack */
+ for (dic = ic->prev; dic; dic = dic->prev)
+ {
+
+ /* if there is a function call and this is
+ a parameter & not my parameter then don't pack it */
+ if ((dic->op == CALL || dic->op == PCALL) &&
+ (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
+ !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
+ {
+ debugLog (" %d - \n", __LINE__);
+ dic = NULL;
+ break;
+ }
+
+ if (SKIP_IC2 (dic))
+ continue;
+
+ if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
+ IS_OP_VOLATILE (IC_RESULT (dic)))
+ {
+ debugLog (" %d - dic is VOLATILE \n", __LINE__);
+ dic = NULL;
+ break;
+ }
+
+ if (IS_SYMOP (IC_RESULT (dic)) &&
+ IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
+ {
+ /* A previous result was assigned to the same register - we'll our definition */
+ debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
+ __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
+ if (POINTER_SET (dic))
+ dic = NULL;
+
+ break;
+ }
+
+ if (IS_SYMOP (IC_RIGHT (dic)) &&
+ (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
+ IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
+ {
+ debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
+ dic = NULL;
+ break;
+ }
+
+ if (IS_SYMOP (IC_LEFT (dic)) &&
+ (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
+ IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
+ {
+ debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
+ dic = NULL;
+ break;
+ }
+
+ if (POINTER_SET (dic) &&
+ IC_RESULT (dic)->key == IC_RESULT (ic)->key)
+ {
+ debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
+ __LINE__);
+ dic = NULL;
+ break;
+ }
+ }
+
+ if (!dic)
+ return 0; /* did not find */
+
+ /* if assignment then check that right is not a bit */
+ if (ASSIGNMENT (ic) && !POINTER_SET (ic))
+ {
+ sym_link *etype = operandType (IC_RESULT (dic));
+ if (IS_BITFIELD (etype))
+ {
+ /* if result is a bit too then it's ok */
+ etype = operandType (IC_RESULT (ic));
+ if (!IS_BITFIELD (etype))
+ return 0;
+ }
+ }
+
+ /* if the result is on stack or iaccess then it must be
+ the same at least one of the operands */
+ if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
+ OP_SYMBOL (IC_RESULT (ic))->iaccess)
+ {
+
+ /* the operation has only one symbol
+ operator then we can pack */
+ if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
+ (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
+ goto pack;
+
+ if (!((IC_LEFT (dic) &&
+ IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
+ (IC_RIGHT (dic) &&
+ IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
+ return 0;
+ }
pack:
- debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
- debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
- /* found the definition */
- /* replace the result with the result of */
- /* this assignment and remove this assignment */
- bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
- IC_RESULT (dic) = IC_RESULT (ic);
-
- if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
- {
- OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
- }
- /* delete from liverange table also
- delete from all the points inbetween and the new
- one */
- for (sic = dic; sic != ic; sic = sic->next)
- {
- bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
- if (IS_ITEMP (IC_RESULT (dic)))
- bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
- }
-
- remiCodeFromeBBlock (ebp, ic);
- bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
- hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
- OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
- return 1;
-
-
+ debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
+ debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
+ /* found the definition */
+ /* replace the result with the result of */
+ /* this assignment and remove this assignment */
+ bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
+ IC_RESULT (dic) = IC_RESULT (ic);
+
+ if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
+ {
+ OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
+ }
+ /* delete from liverange table also
+ delete from all the points inbetween and the new
+ one */
+ for (sic = dic; sic != ic; sic = sic->next)
+ {
+ bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
+ if (IS_ITEMP (IC_RESULT (dic)))
+ bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
+ }
+
+ remiCodeFromeBBlock (ebp, ic);
+ bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
+ hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
+ OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
+ return 1;
+
+
}
/*-----------------------------------------------------------------*/
static iCode *
findAssignToSym (operand * op, iCode * ic)
{
- iCode *dic;
-
- debugLog ("%s\n", __FUNCTION__);
- for (dic = ic->prev; dic; dic = dic->prev)
- {
-
- /* if definition by assignment */
- if (dic->op == '=' &&
- !POINTER_SET (dic) &&
- IC_RESULT (dic)->key == op->key
- /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
- )
- {
-
- /* we are interested only if defined in far space */
- /* or in stack space in case of + & - */
-
- /* if assigned to a non-symbol then return
- true */
- if (!IS_SYMOP (IC_RIGHT (dic)))
- break;
-
- /* if the symbol is in far space then
- we should not */
- if (isOperandInFarSpace (IC_RIGHT (dic)))
- return NULL;
-
- /* for + & - operations make sure that
- if it is on the stack it is the same
- as one of the three operands */
- if ((ic->op == '+' || ic->op == '-') &&
- OP_SYMBOL (IC_RIGHT (dic))->onStack)
- {
-
- if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
- IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
- IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
- return NULL;
- }
-
- break;
-
- }
-
- /* if we find an usage then we cannot delete it */
- if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
- return NULL;
-
- if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
- return NULL;
-
- if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
- return NULL;
- }
-
- /* now make sure that the right side of dic
- is not defined between ic & dic */
- if (dic)
- {
- iCode *sic = dic->next;
-
- for (; sic != ic; sic = sic->next)
- if (IC_RESULT (sic) &&
- IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
- return NULL;
- }
-
- return dic;
-
-
+ iCode *dic;
+
+ debugLog ("%s\n", __FUNCTION__);
+ for (dic = ic->prev; dic; dic = dic->prev)
+ {
+
+ /* if definition by assignment */
+ if (dic->op == '=' &&
+ !POINTER_SET (dic) &&
+ IC_RESULT (dic)->key == op->key
+ /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
+ )
+ {
+
+ /* we are interested only if defined in far space */
+ /* or in stack space in case of + & - */
+
+ /* if assigned to a non-symbol then return
+ true */
+ if (!IS_SYMOP (IC_RIGHT (dic)))
+ break;
+
+ /* if the symbol is in far space then
+ we should not */
+ if (isOperandInFarSpace (IC_RIGHT (dic)))
+ return NULL;
+
+ /* for + & - operations make sure that
+ if it is on the stack it is the same
+ as one of the three operands */
+ if ((ic->op == '+' || ic->op == '-') &&
+ OP_SYMBOL (IC_RIGHT (dic))->onStack)
+ {
+
+ if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
+ IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
+ IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
+ return NULL;
+ }
+
+ break;
+
+ }
+
+ /* if we find an usage then we cannot delete it */
+ if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
+ return NULL;
+
+ if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
+ return NULL;
+
+ if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
+ return NULL;
+ }
+
+ /* now make sure that the right side of dic
+ is not defined between ic & dic */
+ if (dic)
+ {
+ iCode *sic = dic->next;
+
+ for (; sic != ic; sic = sic->next)
+ if (IC_RESULT (sic) &&
+ IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
+ return NULL;
+ }
+
+ return dic;
+
+
}
/*-----------------------------------------------------------------*/
static int
packRegsForSupport (iCode * ic, eBBlock * ebp)
{
- int change = 0;
-
- debugLog ("%s\n", __FUNCTION__);
- /* for the left & right operand :- look to see if the
- left was assigned a true symbol in far space in that
- case replace them */
- if (IS_ITEMP (IC_LEFT (ic)) &&
- OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
- {
- iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
- iCode *sic;
-
- if (!dic)
- goto right;
-
- debugAopGet ("removing left:", IC_LEFT (ic));
-
- /* found it we need to remove it from the
- block */
- for (sic = dic; sic != ic; sic = sic->next)
- bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
-
- IC_LEFT (ic)->operand.symOperand =
- IC_RIGHT (dic)->operand.symOperand;
- IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
- remiCodeFromeBBlock (ebp, dic);
- bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
- hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
- change++;
- }
-
- /* do the same for the right operand */
+ int change = 0;
+
+ debugLog ("%s\n", __FUNCTION__);
+ /* for the left & right operand :- look to see if the
+ left was assigned a true symbol in far space in that
+ case replace them */
+ if (IS_ITEMP (IC_LEFT (ic)) &&
+ OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
+ {
+ iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
+ iCode *sic;
+
+ if (!dic)
+ goto right;
+
+ debugAopGet ("removing left:", IC_LEFT (ic));
+
+ /* found it we need to remove it from the
+ block */
+ for (sic = dic; sic != ic; sic = sic->next)
+ bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
+
+ IC_LEFT (ic)->operand.symOperand =
+ IC_RIGHT (dic)->operand.symOperand;
+ IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
+ remiCodeFromeBBlock (ebp, dic);
+ bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
+ hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
+ change++;
+ }
+
+ /* do the same for the right operand */
right:
- if (!change &&
- IS_ITEMP (IC_RIGHT (ic)) &&
- OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
- {
- iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
- iCode *sic;
-
- if (!dic)
- return change;
-
- /* if this is a subtraction & the result
- is a true symbol in far space then don't pack */
- if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
- {
- sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
- if (IN_FARSPACE (SPEC_OCLS (etype)))
- return change;
- }
-
- debugAopGet ("removing right:", IC_RIGHT (ic));
-
- /* found it we need to remove it from the
- block */
- for (sic = dic; sic != ic; sic = sic->next)
- bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
-
- IC_RIGHT (ic)->operand.symOperand =
- IC_RIGHT (dic)->operand.symOperand;
- IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
-
- remiCodeFromeBBlock (ebp, dic);
- bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
- hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
- change++;
- }
-
- return change;
+ if (!change &&
+ IS_ITEMP (IC_RIGHT (ic)) &&
+ OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
+ {
+ iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
+ iCode *sic;
+
+ if (!dic)
+ return change;
+
+ /* if this is a subtraction & the result
+ is a true symbol in far space then don't pack */
+ if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
+ {
+ sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
+ if (IN_FARSPACE (SPEC_OCLS (etype)))
+ return change;
+ }
+
+ debugAopGet ("removing right:", IC_RIGHT (ic));
+
+ /* found it we need to remove it from the
+ block */
+ for (sic = dic; sic != ic; sic = sic->next)
+ bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
+
+ IC_RIGHT (ic)->operand.symOperand =
+ IC_RIGHT (dic)->operand.symOperand;
+ IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
+
+ remiCodeFromeBBlock (ebp, dic);
+ bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
+ hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
+ change++;
+ }
+
+ return change;
}
#define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
static iCode *
packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
{
- bitVect *uses;
- iCode *dic, *sic;
-
- debugLog ("%s\n", __FUNCTION__);
- /* if returning a literal then do nothing */
- if (!IS_SYMOP (op))
- return NULL;
-
- /* only upto 2 bytes since we cannot predict
- the usage of b, & acc */
- if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
- ic->op != RETURN &&
- ic->op != SEND)
- return NULL;
-
- /* this routine will mark the a symbol as used in one
- instruction use only && if the definition is local
- (ie. within the basic block) && has only one definition &&
- that definition is either a return value from a
- function or does not contain any variables in
- far space */
- uses = bitVectCopy (OP_USES (op));
- bitVectUnSetBit (uses, ic->key); /* take away this iCode */
- if (!bitVectIsZero (uses)) /* has other uses */
- return NULL;
-
- /* if it has only one defintion */
- if (bitVectnBitsOn (OP_DEFS (op)) > 1)
- return NULL; /* has more than one definition */
-
- /* get that definition */
- if (!(dic =
- hTabItemWithKey (iCodehTab,
- bitVectFirstBit (OP_DEFS (op)))))
- return NULL;
-
- /* found the definition now check if it is local */
- if (dic->seq < ebp->fSeq ||
- dic->seq > ebp->lSeq)
- return NULL; /* non-local */
-
- /* now check if it is the return from
- a function call */
- if (dic->op == CALL || dic->op == PCALL)
- {
- if (ic->op != SEND && ic->op != RETURN &&
- !POINTER_SET(ic) && !POINTER_GET(ic))
- {
- OP_SYMBOL (op)->ruonly = 1;
- return dic;
- }
- dic = dic->next;
- }
-
-
- /* 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_GET (dic) &&
- !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
- return NULL;
-
- sic = dic;
-
- /* also make sure the intervenening instructions
- don't have any thing in far space */
- for (dic = dic->next; dic && dic != ic; dic = dic->next)
- {
-
- /* if there is an intervening function call then no */
- if (dic->op == CALL || dic->op == PCALL)
- 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 address of & the result is remat then okay */
- if (dic->op == ADDRESS_OF &&
- OP_SYMBOL (IC_RESULT (dic))->remat)
- continue;
-
- /* if operand has size of three or more & this
- operation is a '*','/' or '%' then 'b' may
- cause a problem */
- if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
- getSize (operandType (op)) >= 3)
- return NULL;
-
- /* if left or right or result is in far space */
- if (isOperandInFarSpace (IC_LEFT (dic)) ||
- isOperandInFarSpace (IC_RIGHT (dic)) ||
- isOperandInFarSpace (IC_RESULT (dic)) ||
- IS_OP_RUONLY (IC_LEFT (dic)) ||
- IS_OP_RUONLY (IC_RIGHT (dic)) ||
- IS_OP_RUONLY (IC_RESULT (dic)))
- {
- return NULL;
- }
- }
-
- OP_SYMBOL (op)->ruonly = 1;
- return sic;
-
+ bitVect *uses;
+ iCode *dic, *sic;
+
+ debugLog ("%s\n", __FUNCTION__);
+ /* if returning a literal then do nothing */
+ if (!IS_SYMOP (op))
+ return NULL;
+
+ /* only upto 2 bytes since we cannot predict
+ the usage of b, & acc */
+ if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
+ ic->op != RETURN &&
+ ic->op != SEND)
+ return NULL;
+
+ /* this routine will mark the a symbol as used in one
+ instruction use only && if the definition is local
+ (ie. within the basic block) && has only one definition &&
+ that definition is either a return value from a
+ function or does not contain any variables in
+ far space */
+ uses = bitVectCopy (OP_USES (op));
+ bitVectUnSetBit (uses, ic->key); /* take away this iCode */
+ if (!bitVectIsZero (uses)) /* has other uses */
+ return NULL;
+
+ /* if it has only one defintion */
+ if (bitVectnBitsOn (OP_DEFS (op)) > 1)
+ return NULL; /* has more than one definition */
+
+ /* get that definition */
+ if (!(dic =
+ hTabItemWithKey (iCodehTab,
+ bitVectFirstBit (OP_DEFS (op)))))
+ return NULL;
+
+ /* found the definition now check if it is local */
+ if (dic->seq < ebp->fSeq ||
+ dic->seq > ebp->lSeq)
+ return NULL; /* non-local */
+
+ /* now check if it is the return from
+ a function call */
+ if (dic->op == CALL || dic->op == PCALL)
+ {
+ if (ic->op != SEND && ic->op != RETURN &&
+ !POINTER_SET(ic) && !POINTER_GET(ic))
+ {
+ OP_SYMBOL (op)->ruonly = 1;
+ return dic;
+ }
+ dic = dic->next;
+ }
+
+
+ /* 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_GET (dic) &&
+ !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
+ return NULL;
+
+ sic = dic;
+
+ /* also make sure the intervenening instructions
+ don't have any thing in far space */
+ for (dic = dic->next; dic && dic != ic; dic = dic->next)
+ {
+
+ /* if there is an intervening function call then no */
+ if (dic->op == CALL || dic->op == PCALL)
+ 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 address of & the result is remat then okay */
+ if (dic->op == ADDRESS_OF &&
+ OP_SYMBOL (IC_RESULT (dic))->remat)
+ continue;
+
+ /* if operand has size of three or more & this
+ operation is a '*','/' or '%' then 'b' may
+ cause a problem */
+ if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
+ getSize (operandType (op)) >= 3)
+ return NULL;
+
+ /* if left or right or result is in far space */
+ if (isOperandInFarSpace (IC_LEFT (dic)) ||
+ isOperandInFarSpace (IC_RIGHT (dic)) ||
+ isOperandInFarSpace (IC_RESULT (dic)) ||
+ IS_OP_RUONLY (IC_LEFT (dic)) ||
+ IS_OP_RUONLY (IC_RIGHT (dic)) ||
+ IS_OP_RUONLY (IC_RESULT (dic)))
+ {
+ return NULL;
+ }
+ }
+
+ OP_SYMBOL (op)->ruonly = 1;
+ return sic;
+
}
/*-----------------------------------------------------------------*/
static bool
isBitwiseOptimizable (iCode * ic)
{
- sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
- sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
-
- debugLog ("%s\n", __FUNCTION__);
- /* bitwise operations are considered optimizable
- under the following conditions (Jean-Louis VERN)
-
- x & lit
- bit & bit
- bit & x
- bit ^ bit
- bit ^ x
- x ^ lit
- x | lit
- bit | bit
- bit | x
- */
- if (IS_LITERAL (rtype) ||
- (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
- return TRUE;
- else
- return FALSE;
+ sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
+ sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
+
+ debugLog ("%s\n", __FUNCTION__);
+ /* bitwise operations are considered optimizable
+ under the following conditions (Jean-Louis VERN)
+
+ x & lit
+ bit & bit
+ bit & x
+ bit ^ bit
+ bit ^ x
+ x ^ lit
+ x | lit
+ bit | bit
+ bit | x
+ */
+ if (IS_LITERAL (rtype) ||
+ (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
+ return TRUE;
+ else
+ return FALSE;
}
/*-----------------------------------------------------------------*/
static void
packRegsForAccUse (iCode * ic)
{
- //iCode *uic;
-
- debugLog ("%s\n", __FUNCTION__);
-
- /* result too large for WREG? */
- if (getSize (operandType (IC_RESULT (ic))) > 1)
- return;
-
- /* We have to make sure that OP_SYMBOL(IC_RESULT(ic))
- * is never used as an operand to an instruction that
- * cannot have WREG as an operand (e.g. BTFSx cannot
- * operate on WREG...
- * For now, store all results into proper registers. */
- return;
+ //iCode *uic;
+
+ debugLog ("%s\n", __FUNCTION__);
+
+ /* result too large for WREG? */
+ if (getSize (operandType (IC_RESULT (ic))) > 1)
+ return;
+
+ /* We have to make sure that OP_SYMBOL(IC_RESULT(ic))
+ * is never used as an operand to an instruction that
+ * cannot have WREG as an operand (e.g. BTFSx cannot
+ * operate on WREG...
+ * For now, store all results into proper registers. */
+ return;
#if 0
- /* if this is an aggregate, e.g. a one byte char array */
- if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
- return;
- }
- debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
-
- /* if + or - then it has to be one byte result */
- if ((ic->op == '+' || ic->op == '-')
- && getSize (operandType (IC_RESULT (ic))) > 1)
- return;
-
- debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
- /* if shift operation make sure right side is not a literal */
- if (ic->op == RIGHT_OP &&
- (isOperandLiteral (IC_RIGHT (ic)) ||
- getSize (operandType (IC_RESULT (ic))) > 1))
- return;
-
- if (ic->op == LEFT_OP &&
- (isOperandLiteral (IC_RIGHT (ic)) ||
- getSize (operandType (IC_RESULT (ic))) > 1))
- return;
-
- if (IS_BITWISE_OP (ic) &&
- getSize (operandType (IC_RESULT (ic))) > 1)
- return;
-
-
- /* has only one definition */
- if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
- return;
-
- /* has only one use */
- if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
- return;
-
- /* and the usage immediately follows this iCode */
- if (!(uic = hTabItemWithKey (iCodehTab,
- bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
- return;
-
- debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
- if (ic->next != uic)
- return;
-
- /* if it is a conditional branch then we definitely can */
- if (uic->op == IFX)
- goto accuse;
-
- if (uic->op == JUMPTABLE)
- return;
-
- /* if the usage is not is an assignment
- or an arithmetic / bitwise / shift operation then not */
- if (POINTER_SET (uic) &&
- getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
- return;
-
- debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
- if (uic->op != '=' &&
- !IS_ARITHMETIC_OP (uic) &&
- !IS_BITWISE_OP (uic) &&
- uic->op != LEFT_OP &&
- uic->op != RIGHT_OP)
- return;
-
- debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
- /* if used in ^ operation then make sure right is not a
- literl */
- if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
- return;
-
- /* if shift operation make sure right side is not a literal */
- if (uic->op == RIGHT_OP &&
- (isOperandLiteral (IC_RIGHT (uic)) ||
- getSize (operandType (IC_RESULT (uic))) > 1))
- return;
-
- if (uic->op == LEFT_OP &&
- (isOperandLiteral (IC_RIGHT (uic)) ||
- getSize (operandType (IC_RESULT (uic))) > 1))
- return;
-
- /* make sure that the result of this icode is not on the
- stack, since acc is used to compute stack offset */
- if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
- OP_SYMBOL (IC_RESULT (uic))->onStack)
- return;
-
- /* if either one of them in far space then we cannot */
- if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
- isOperandInFarSpace (IC_LEFT (uic))) ||
- (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
- isOperandInFarSpace (IC_RIGHT (uic))))
- return;
-
- /* if the usage has only one operand then we can */
- if (IC_LEFT (uic) == NULL ||
- IC_RIGHT (uic) == NULL)
- goto accuse;
-
- /* make sure this is on the left side if not
- a '+' since '+' is commutative */
- if (ic->op != '+' &&
- IC_LEFT (uic)->key != IC_RESULT (ic)->key)
- return;
-
- debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
- /* if one of them is a literal then we can */
- if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
- (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
- (getSize (operandType (IC_RESULT (uic))) <= 1))
- {
- OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
- return;
- }
-
- debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
- /* if the other one is not on stack then we can */
- if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
- (IS_ITEMP (IC_RIGHT (uic)) ||
- (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
- !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
- goto accuse;
-
- if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
- (IS_ITEMP (IC_LEFT (uic)) ||
- (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
- !OP_SYMBOL (IC_LEFT (uic))->onStack)))
- goto accuse;
-
- return;
-
+ /* if this is an aggregate, e.g. a one byte char array */
+ if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
+ return;
+ }
+ debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
+
+ /* if + or - then it has to be one byte result */
+ if ((ic->op == '+' || ic->op == '-')
+ && getSize (operandType (IC_RESULT (ic))) > 1)
+ return;
+
+ debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
+ /* if shift operation make sure right side is not a literal */
+ if (ic->op == RIGHT_OP &&
+ (isOperandLiteral (IC_RIGHT (ic)) ||
+ getSize (operandType (IC_RESULT (ic))) > 1))
+ return;
+
+ if (ic->op == LEFT_OP &&
+ (isOperandLiteral (IC_RIGHT (ic)) ||
+ getSize (operandType (IC_RESULT (ic))) > 1))
+ return;
+
+ if (IS_BITWISE_OP (ic) &&
+ getSize (operandType (IC_RESULT (ic))) > 1)
+ return;
+
+
+ /* has only one definition */
+ if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
+ return;
+
+ /* has only one use */
+ if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
+ return;
+
+ /* and the usage immediately follows this iCode */
+ if (!(uic = hTabItemWithKey (iCodehTab,
+ bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
+ return;
+
+ debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
+ if (ic->next != uic)
+ return;
+
+ /* if it is a conditional branch then we definitely can */
+ if (uic->op == IFX)
+ goto accuse;
+
+ if (uic->op == JUMPTABLE)
+ return;
+
+ /* if the usage is not is an assignment
+ or an arithmetic / bitwise / shift operation then not */
+ if (POINTER_SET (uic) &&
+ getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
+ return;
+
+ debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
+ if (uic->op != '=' &&
+ !IS_ARITHMETIC_OP (uic) &&
+ !IS_BITWISE_OP (uic) &&
+ uic->op != LEFT_OP &&
+ uic->op != RIGHT_OP)
+ return;
+
+ debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
+ /* if used in ^ operation then make sure right is not a
+ literl */
+ if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
+ return;
+
+ /* if shift operation make sure right side is not a literal */
+ if (uic->op == RIGHT_OP &&
+ (isOperandLiteral (IC_RIGHT (uic)) ||
+ getSize (operandType (IC_RESULT (uic))) > 1))
+ return;
+
+ if (uic->op == LEFT_OP &&
+ (isOperandLiteral (IC_RIGHT (uic)) ||
+ getSize (operandType (IC_RESULT (uic))) > 1))
+ return;
+
+ /* make sure that the result of this icode is not on the
+ stack, since acc is used to compute stack offset */
+ if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
+ OP_SYMBOL (IC_RESULT (uic))->onStack)
+ return;
+
+ /* if either one of them in far space then we cannot */
+ if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
+ isOperandInFarSpace (IC_LEFT (uic))) ||
+ (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
+ isOperandInFarSpace (IC_RIGHT (uic))))
+ return;
+
+ /* if the usage has only one operand then we can */
+ if (IC_LEFT (uic) == NULL ||
+ IC_RIGHT (uic) == NULL)
+ goto accuse;
+
+ /* make sure this is on the left side if not
+ a '+' since '+' is commutative */
+ if (ic->op != '+' &&
+ IC_LEFT (uic)->key != IC_RESULT (ic)->key)
+ return;
+
+ debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
+ /* if one of them is a literal then we can */
+ if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
+ (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
+ (getSize (operandType (IC_RESULT (uic))) <= 1))
+ {
+ OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
+ return;
+ }
+
+ debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
+ /* if the other one is not on stack then we can */
+ if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
+ (IS_ITEMP (IC_RIGHT (uic)) ||
+ (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
+ !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
+ goto accuse;
+
+ if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
+ (IS_ITEMP (IC_LEFT (uic)) ||
+ (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
+ !OP_SYMBOL (IC_LEFT (uic))->onStack)))
+ goto accuse;
+
+ return;
+
accuse:
- debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
- OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
-#endif
+ debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
+ OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
+#endif
}
/*-----------------------------------------------------------------*/
static void
packForReceive (iCode * ic, eBBlock * ebp)
{
- iCode *dic;
-
- debugLog ("%s\n", __FUNCTION__);
- debugAopGet (" result:", IC_RESULT (ic));
- debugAopGet (" left:", IC_LEFT (ic));
- debugAopGet (" right:", IC_RIGHT (ic));
-
- if (!ic->next)
- return;
-
- for (dic = ic->next; dic; dic = dic->next)
- {
-
-
-
- if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
- debugLog (" used on left\n");
- if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
- debugLog (" used on right\n");
- if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
- debugLog (" used on result\n");
-
- if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
- (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
- return;
-
- }
-
- debugLog (" hey we can remove this unnecessary assign\n");
+ iCode *dic;
+
+ debugLog ("%s\n", __FUNCTION__);
+ debugAopGet (" result:", IC_RESULT (ic));
+ debugAopGet (" left:", IC_LEFT (ic));
+ debugAopGet (" right:", IC_RIGHT (ic));
+
+ if (!ic->next)
+ return;
+
+ for (dic = ic->next; dic; dic = dic->next)
+ {
+
+
+
+ if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
+ debugLog (" used on left\n");
+ if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
+ debugLog (" used on right\n");
+ if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
+ debugLog (" used on result\n");
+
+ if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
+ (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
+ return;
+
+ }
+
+ debugLog (" hey we can remove this unnecessary assign\n");
}
/*-----------------------------------------------------------------*/
/* packForPush - hueristics to reduce iCode for pushing */
static void
packForPush (iCode * ic, eBBlock * ebp)
{
- iCode *dic;
-
- debugLog ("%s\n", __FUNCTION__);
- if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
- return;
-
- /* must have only definition & one usage */
- if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
- bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
- return;
-
- /* find the definition */
- if (!(dic = hTabItemWithKey (iCodehTab,
- bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
- return;
-
- if (dic->op != '=' || POINTER_SET (dic))
- return;
-
- /* we now we know that it has one & only one def & use
- and the that the definition is an assignment */
- IC_LEFT (ic) = IC_RIGHT (dic);
-
- remiCodeFromeBBlock (ebp, dic);
- bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
- hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
+ iCode *dic;
+
+ debugLog ("%s\n", __FUNCTION__);
+ if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
+ return;
+
+ /* must have only definition & one usage */
+ if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
+ bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
+ return;
+
+ /* find the definition */
+ if (!(dic = hTabItemWithKey (iCodehTab,
+ bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
+ return;
+
+ if (dic->op != '=' || POINTER_SET (dic))
+ return;
+
+ /* we now we know that it has one & only one def & use
+ and the that the definition is an assignment */
+ IC_LEFT (ic) = IC_RIGHT (dic);
+
+ remiCodeFromeBBlock (ebp, dic);
+ bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
+ hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
}
void printSymType(char * str, sym_link *sl)
{
- if (debug) {
- debugLog (" %s Symbol type: ",str);
- printTypeChain( sl, debugF);
- debugLog ("\n");
- }
+ if (debug) {
+ debugLog (" %s Symbol type: ",str);
+ printTypeChain( sl, debugF);
+ debugLog ("\n");
+ }
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
void isData(sym_link *sl)
{
- FILE *of = stderr;
-
- // avoid garbage `data' and `sfr' output
- if(!sl || !debugF)
- return;
-
- if(debugF)
- of = debugF;
-
- for ( ; sl; sl=sl->next) {
- if(!IS_DECL(sl) ) {
- switch (SPEC_SCLS(sl)) {
-
- case S_DATA: fprintf (of, "data "); break;
- case S_XDATA: fprintf (of, "xdata "); break;
- case S_SFR: fprintf (of, "sfr "); break;
- case S_SBIT: fprintf (of, "sbit "); break;
- case S_CODE: fprintf (of, "code "); break;
- case S_IDATA: fprintf (of, "idata "); break;
- case S_PDATA: fprintf (of, "pdata "); break;
- case S_LITERAL: fprintf (of, "literal "); break;
- case S_STACK: fprintf (of, "stack "); break;
- case S_XSTACK: fprintf (of, "xstack "); break;
- case S_BIT: fprintf (of, "bit "); break;
- case S_EEPROM: fprintf (of, "eeprom "); break;
- default: break;
- }
-
- }
-
- }
-
+ FILE *of = stderr;
+
+ // avoid garbage `data' and `sfr' output
+ if(!sl || !debugF)
+ return;
+
+ if(debugF)
+ of = debugF;
+
+ for ( ; sl; sl=sl->next) {
+ if(!IS_DECL(sl) ) {
+ switch (SPEC_SCLS(sl)) {
+
+ case S_DATA: fprintf (of, "data "); break;
+ case S_XDATA: fprintf (of, "xdata "); break;
+ case S_SFR: fprintf (of, "sfr "); break;
+ case S_SBIT: fprintf (of, "sbit "); break;
+ case S_CODE: fprintf (of, "code "); break;
+ case S_IDATA: fprintf (of, "idata "); break;
+ case S_PDATA: fprintf (of, "pdata "); break;
+ case S_LITERAL: fprintf (of, "literal "); break;
+ case S_STACK: fprintf (of, "stack "); break;
+ case S_XSTACK: fprintf (of, "xstack "); break;
+ case S_BIT: fprintf (of, "bit "); break;
+ case S_EEPROM: fprintf (of, "eeprom "); break;
+ default: break;
+ }
+
+ }
+
+ }
+
}
/*-----------------------------------------------------------------*/
static void
packRegisters (eBBlock * ebp)
{
- iCode *ic;
- int change = 0;
-
- debugLog ("%s\n", __FUNCTION__);
-
- while (1) {
-
- change = 0;
-
- /* look for assignments of the form */
- /* iTempNN = TRueSym (someoperation) SomeOperand */
- /* .... */
- /* TrueSym := iTempNN:1 */
- for (ic = ebp->sch; ic; ic = ic->next)
- {
-
- /* find assignment of the form TrueSym := iTempNN:1 */
- if (ic->op == '=' && !POINTER_SET (ic))
- change += packRegsForAssign (ic, ebp);
- /* debug stuff */
- if (ic->op == '=')
- {
- if (POINTER_SET (ic))
- debugLog ("pointer is set\n");
- debugAopGet (" result:", IC_RESULT (ic));
- debugAopGet (" left:", IC_LEFT (ic));
- debugAopGet (" right:", IC_RIGHT (ic));
- }
-
- }
-
- if (!change)
- break;
- }
-
- for (ic = ebp->sch; ic; ic = ic->next) {
-
- if(IS_SYMOP ( IC_LEFT(ic))) {
- sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
-
- debugAopGet (" left:", IC_LEFT (ic));
- if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
- debugLog (" is a pointer\n");
-
- if(IS_OP_VOLATILE(IC_LEFT(ic)))
- debugLog (" is volatile\n");
-
- isData(etype);
-
- printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
- }
-
- if(IS_SYMOP ( IC_RIGHT(ic))) {
- debugAopGet (" right:", IC_RIGHT (ic));
- printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
- }
-
- if(IS_SYMOP ( IC_RESULT(ic))) {
- debugAopGet (" result:", IC_RESULT (ic));
- printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
- }
-
- if (POINTER_SET (ic))
- debugLog (" %d - Pointer set\n", __LINE__);
-
-
- /* Look for two subsequent iCodes with */
- /* iTemp := _c; */
- /* _c = iTemp & op; */
- /* and replace them by */
- /* iTemp := _c; */
- /* _c = _c & op; */
- if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^') &&
- ic->prev &&
- ic->prev->op == '=' &&
- IS_ITEMP (IC_LEFT (ic)) &&
- IC_LEFT (ic) == IC_RESULT (ic->prev) &&
- isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
+ iCode *ic;
+ int change = 0;
+
+ debugLog ("%s\n", __FUNCTION__);
+
+ while (1) {
+
+ change = 0;
+
+ /* look for assignments of the form */
+ /* iTempNN = TRueSym (someoperation) SomeOperand */
+ /* .... */
+ /* TrueSym := iTempNN:1 */
+ for (ic = ebp->sch; ic; ic = ic->next)
+ {
+
+ /* find assignment of the form TrueSym := iTempNN:1 */
+ if (ic->op == '=' && !POINTER_SET (ic))
+ change += packRegsForAssign (ic, ebp);
+ /* debug stuff */
+ if (ic->op == '=')
+ {
+ if (POINTER_SET (ic))
+ debugLog ("pointer is set\n");
+ debugAopGet (" result:", IC_RESULT (ic));
+ debugAopGet (" left:", IC_LEFT (ic));
+ debugAopGet (" right:", IC_RIGHT (ic));
+ }
+
+ }
+
+ if (!change)
+ break;
+ }
+
+ for (ic = ebp->sch; ic; ic = ic->next) {
+
+ if(IS_SYMOP ( IC_LEFT(ic))) {
+ sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
+
+ debugAopGet (" left:", IC_LEFT (ic));
+ if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
+ debugLog (" is a pointer\n");
+
+ if(IS_OP_VOLATILE(IC_LEFT(ic)))
+ debugLog (" is volatile\n");
+
+ isData(etype);
+
+ printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
+ }
+
+ if(IS_SYMOP ( IC_RIGHT(ic))) {
+ debugAopGet (" right:", IC_RIGHT (ic));
+ printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
+ }
+
+ if(IS_SYMOP ( IC_RESULT(ic))) {
+ debugAopGet (" result:", IC_RESULT (ic));
+ printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
+ }
+
+ if (POINTER_SET (ic))
+ debugLog (" %d - Pointer set\n", __LINE__);
+
+
+ /* Look for two subsequent iCodes with */
+ /* iTemp := _c; */
+ /* _c = iTemp & op; */
+ /* and replace them by */
+ /* iTemp := _c; */
+ /* _c = _c & op; */
+ if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^') &&
+ ic->prev &&
+ ic->prev->op == '=' &&
+ IS_ITEMP (IC_LEFT (ic)) &&
+ IC_LEFT (ic) == IC_RESULT (ic->prev) &&
+ isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
{
- iCode* ic_prev = ic->prev;
- symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
-
- ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
- if (IC_RESULT (ic_prev) != IC_RIGHT (ic))
+ iCode* ic_prev = ic->prev;
+ symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
+
+ ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
+ if (IC_RESULT (ic_prev) != IC_RIGHT (ic))
{
- bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
- if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
- prev_result_sym->liveTo == ic->seq)
+ bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
+ if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
+ prev_result_sym->liveTo == ic->seq)
{
- prev_result_sym->liveTo = ic_prev->seq;
+ prev_result_sym->liveTo = ic_prev->seq;
}
}
- bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
-
- bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
-
- if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev))))
+ bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
+
+ bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
+
+ if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev))))
{
- bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
- bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
- remiCodeFromeBBlock (ebp, ic_prev);
- hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
+ bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
+ bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
+ remiCodeFromeBBlock (ebp, ic_prev);
+ hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
}
}
-
- /* if this is an itemp & result of a address of a true sym
- then mark this as rematerialisable */
- if (ic->op == ADDRESS_OF &&
- IS_ITEMP (IC_RESULT (ic)) &&
- IS_TRUE_SYMOP (IC_LEFT (ic)) &&
- bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
- !OP_SYMBOL (IC_LEFT (ic))->onStack)
- {
-
- debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
-
- OP_SYMBOL (IC_RESULT (ic))->remat = 1;
- OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
- OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
-
- }
-
- /* if straight assignment then carry remat flag if
- this is the only definition */
- if (ic->op == '=' &&
- !POINTER_SET (ic) &&
- IS_SYMOP (IC_RIGHT (ic)) &&
- OP_SYMBOL (IC_RIGHT (ic))->remat &&
- bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
- {
- debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
-
- OP_SYMBOL (IC_RESULT (ic))->remat =
- OP_SYMBOL (IC_RIGHT (ic))->remat;
- OP_SYMBOL (IC_RESULT (ic))->rematiCode =
- OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
- }
-
- /* if this is a +/- operation with a rematerizable
- then mark this as rematerializable as well */
- if ((ic->op == '+' || ic->op == '-') &&
- (IS_SYMOP (IC_LEFT (ic)) &&
- IS_ITEMP (IC_RESULT (ic)) &&
- OP_SYMBOL (IC_LEFT (ic))->remat &&
- bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
- IS_OP_LITERAL (IC_RIGHT (ic))))
- {
- debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
- //int i =
- operandLitValue (IC_RIGHT (ic));
- OP_SYMBOL (IC_RESULT (ic))->remat = 1;
- OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
- OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
- }
-
- /* mark the pointer usages */
- if (POINTER_SET (ic) && IS_SYMOP(IC_RESULT(ic)))
- {
- OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
- debugLog (" marking as a pointer (set) =>");
- debugAopGet (" result:", IC_RESULT (ic));
- }
- if (POINTER_GET (ic) && IS_SYMOP(IC_LEFT(ic)))
- {
- OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
- debugLog (" marking as a pointer (get) =>");
- debugAopGet (" left:", IC_LEFT (ic));
- }
-
- if (!SKIP_IC2 (ic))
- {
- /* if we are using a symbol on the stack
- then we should say pic14_ptrRegReq */
- if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
- pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
- OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
- else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
- pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
- OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
- else
- {
- if (IS_SYMOP (IC_LEFT (ic)))
- pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
- OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
- if (IS_SYMOP (IC_RIGHT (ic)))
- pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
- OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
- if (IS_SYMOP (IC_RESULT (ic)))
- pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
- OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
- }
-
- debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
-
- }
-
- /* if the condition of an if instruction
- is defined in the previous instruction then
- mark the itemp as a conditional */
- if ((IS_CONDITIONAL (ic) ||
- ((ic->op == BITWISEAND ||
- ic->op == '|' ||
- ic->op == '^') &&
- isBitwiseOptimizable (ic))) &&
- ic->next && ic->next->op == IFX &&
- isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
- OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
- {
-
- debugLog (" %d\n", __LINE__);
- OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
- continue;
- }
-
- /* reduce for support function calls */
- if (ic->supportRtn || ic->op == '+' || ic->op == '-')
- packRegsForSupport (ic, ebp);
-
- /* if a parameter is passed, it's in W, so we may not
- need to place a copy in a register */
- if (ic->op == RECEIVE)
- packForReceive (ic, ebp);
-
- /* some cases the redundant moves can
- can be eliminated for return statements */
- if ((ic->op == RETURN || ic->op == SEND) &&
- !isOperandInFarSpace (IC_LEFT (ic)) &&
- !options.model)
- packRegsForOneuse (ic, IC_LEFT (ic), ebp);
-
- /* if pointer set & left has a size more than
- one and right is not in far space */
- if (POINTER_SET (ic) &&
- !isOperandInFarSpace (IC_RIGHT (ic)) &&
- IS_SYMOP(IC_RESULT(ic)) &&
- !OP_SYMBOL (IC_RESULT (ic))->remat &&
- !IS_OP_RUONLY (IC_RIGHT (ic)) &&
- getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
-
- packRegsForOneuse (ic, IC_RESULT (ic), ebp);
-
- /* if pointer get */
- if (POINTER_GET (ic) &&
- !isOperandInFarSpace (IC_RESULT (ic)) &&
- IS_SYMOP(IC_LEFT(ic)) &&
- !OP_SYMBOL (IC_LEFT (ic))->remat &&
- !IS_OP_RUONLY (IC_RESULT (ic)) &&
- getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
-
- packRegsForOneuse (ic, IC_LEFT (ic), ebp);
-
-
- /* if this is cast for intergral promotion then
- check if only use of the definition of the
- operand being casted/ if yes then replace
- the result of that arithmetic operation with
- this result and get rid of the cast */
- if (ic->op == CAST) {
-
- sym_link *fromType = operandType (IC_RIGHT (ic));
- sym_link *toType = operandType (IC_LEFT (ic));
-
- debugLog (" %d - casting\n", __LINE__);
-
- if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
- getSize (fromType) != getSize (toType)) {
-
-
- iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
- if (dic) {
-
- if (IS_ARITHMETIC_OP (dic)) {
-
- bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
- IC_RESULT (dic) = IC_RESULT (ic);
- remiCodeFromeBBlock (ebp, ic);
- bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
- hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
- OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
- ic = ic->prev;
- } else
-
- OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
- }
- } else {
-
- /* if the type from and type to are the same
- then if this is the only use then packit */
- if (compareType (operandType (IC_RIGHT (ic)),
- operandType (IC_LEFT (ic))) == 1) {
-
- iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
- if (dic) {
-
- bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
- IC_RESULT (dic) = IC_RESULT (ic);
- bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
- remiCodeFromeBBlock (ebp, ic);
- hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
- OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
- ic = ic->prev;
- }
- }
- }
- }
-
- /* pack for PUSH
- iTempNN := (some variable in farspace) V1
- push iTempNN ;
- -------------
- push V1
- */
- if (ic->op == IPUSH)
- {
- packForPush (ic, ebp);
- }
-
-
- /* pack registers for accumulator use, when the
- result of an arithmetic or bit wise operation
- has only one use, that use is immediately following
- the defintion and the using iCode has only one
- operand or has two operands but one is literal &
- the result of that operation is not on stack then
- we can leave the result of this operation in acc:b
- combination */
- if ((IS_ARITHMETIC_OP (ic)
-
- || IS_BITWISE_OP (ic)
-
- || ic->op == LEFT_OP || ic->op == RIGHT_OP
-
- ) &&
- IS_ITEMP (IC_RESULT (ic)) &&
- getSize (operandType (IC_RESULT (ic))) <= 2)
-
- packRegsForAccUse (ic);
-
- }
+
+ /* if this is an itemp & result of a address of a true sym
+ then mark this as rematerialisable */
+ if (ic->op == ADDRESS_OF &&
+ IS_ITEMP (IC_RESULT (ic)) &&
+ IS_TRUE_SYMOP (IC_LEFT (ic)) &&
+ bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
+ !OP_SYMBOL (IC_LEFT (ic))->onStack)
+ {
+
+ debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
+
+ OP_SYMBOL (IC_RESULT (ic))->remat = 1;
+ OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
+ OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
+
+ }
+
+ /* if straight assignment then carry remat flag if
+ this is the only definition */
+ if (ic->op == '=' &&
+ !POINTER_SET (ic) &&
+ IS_SYMOP (IC_RIGHT (ic)) &&
+ OP_SYMBOL (IC_RIGHT (ic))->remat &&
+ bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
+ {
+ debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
+
+ OP_SYMBOL (IC_RESULT (ic))->remat =
+ OP_SYMBOL (IC_RIGHT (ic))->remat;
+ OP_SYMBOL (IC_RESULT (ic))->rematiCode =
+ OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
+ }
+
+ /* if this is a +/- operation with a rematerizable
+ then mark this as rematerializable as well */
+ if ((ic->op == '+' || ic->op == '-') &&
+ (IS_SYMOP (IC_LEFT (ic)) &&
+ IS_ITEMP (IC_RESULT (ic)) &&
+ OP_SYMBOL (IC_LEFT (ic))->remat &&
+ bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
+ IS_OP_LITERAL (IC_RIGHT (ic))))
+ {
+ debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
+ //int i =
+ operandLitValue (IC_RIGHT (ic));
+ OP_SYMBOL (IC_RESULT (ic))->remat = 1;
+ OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
+ OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
+ }
+
+ /* mark the pointer usages */
+ if (POINTER_SET (ic) && IS_SYMOP(IC_RESULT(ic)))
+ {
+ OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
+ debugLog (" marking as a pointer (set) =>");
+ debugAopGet (" result:", IC_RESULT (ic));
+ }
+ if (POINTER_GET (ic) && IS_SYMOP(IC_LEFT(ic)))
+ {
+ OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
+ debugLog (" marking as a pointer (get) =>");
+ debugAopGet (" left:", IC_LEFT (ic));
+ }
+
+ if (!SKIP_IC2 (ic))
+ {
+ /* if we are using a symbol on the stack
+ then we should say pic14_ptrRegReq */
+ if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
+ pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
+ OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
+ else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
+ pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
+ OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
+ else
+ {
+ if (IS_SYMOP (IC_LEFT (ic)))
+ pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
+ OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
+ if (IS_SYMOP (IC_RIGHT (ic)))
+ pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
+ OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
+ if (IS_SYMOP (IC_RESULT (ic)))
+ pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
+ OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
+ }
+
+ debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
+
+ }
+
+ /* if the condition of an if instruction
+ is defined in the previous instruction then
+ mark the itemp as a conditional */
+ if ((IS_CONDITIONAL (ic) ||
+ ((ic->op == BITWISEAND ||
+ ic->op == '|' ||
+ ic->op == '^') &&
+ isBitwiseOptimizable (ic))) &&
+ ic->next && ic->next->op == IFX &&
+ isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
+ OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
+ {
+
+ debugLog (" %d\n", __LINE__);
+ OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
+ continue;
+ }
+
+ /* reduce for support function calls */
+ if (ic->supportRtn || ic->op == '+' || ic->op == '-')
+ packRegsForSupport (ic, ebp);
+
+ /* if a parameter is passed, it's in W, so we may not
+ need to place a copy in a register */
+ if (ic->op == RECEIVE)
+ packForReceive (ic, ebp);
+
+ /* some cases the redundant moves can
+ can be eliminated for return statements */
+ if ((ic->op == RETURN || ic->op == SEND) &&
+ !isOperandInFarSpace (IC_LEFT (ic)) &&
+ !options.model)
+ packRegsForOneuse (ic, IC_LEFT (ic), ebp);
+
+ /* if pointer set & left has a size more than
+ one and right is not in far space */
+ if (POINTER_SET (ic) &&
+ !isOperandInFarSpace (IC_RIGHT (ic)) &&
+ IS_SYMOP(IC_RESULT(ic)) &&
+ !OP_SYMBOL (IC_RESULT (ic))->remat &&
+ !IS_OP_RUONLY (IC_RIGHT (ic)) &&
+ getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
+
+ packRegsForOneuse (ic, IC_RESULT (ic), ebp);
+
+ /* if pointer get */
+ if (POINTER_GET (ic) &&
+ !isOperandInFarSpace (IC_RESULT (ic)) &&
+ IS_SYMOP(IC_LEFT(ic)) &&
+ !OP_SYMBOL (IC_LEFT (ic))->remat &&
+ !IS_OP_RUONLY (IC_RESULT (ic)) &&
+ getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
+
+ packRegsForOneuse (ic, IC_LEFT (ic), ebp);
+
+
+ /* if this is cast for intergral promotion then
+ check if only use of the definition of the
+ operand being casted/ if yes then replace
+ the result of that arithmetic operation with
+ this result and get rid of the cast */
+ if (ic->op == CAST) {
+
+ sym_link *fromType = operandType (IC_RIGHT (ic));
+ sym_link *toType = operandType (IC_LEFT (ic));
+
+ debugLog (" %d - casting\n", __LINE__);
+
+ if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
+ getSize (fromType) != getSize (toType)) {
+
+
+ iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
+ if (dic) {
+
+ if (IS_ARITHMETIC_OP (dic)) {
+
+ bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
+ IC_RESULT (dic) = IC_RESULT (ic);
+ remiCodeFromeBBlock (ebp, ic);
+ bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
+ hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
+ OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
+ ic = ic->prev;
+ } else
+
+ OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
+ }
+ } else {
+
+ /* if the type from and type to are the same
+ then if this is the only use then packit */
+ if (compareType (operandType (IC_RIGHT (ic)),
+ operandType (IC_LEFT (ic))) == 1) {
+
+ iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
+ if (dic) {
+
+ bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
+ IC_RESULT (dic) = IC_RESULT (ic);
+ bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
+ remiCodeFromeBBlock (ebp, ic);
+ hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
+ OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
+ ic = ic->prev;
+ }
+ }
+ }
+ }
+
+ /* pack for PUSH
+ iTempNN := (some variable in farspace) V1
+ push iTempNN ;
+ -------------
+ push V1
+ */
+ if (ic->op == IPUSH)
+ {
+ packForPush (ic, ebp);
+ }
+
+
+ /* pack registers for accumulator use, when the
+ result of an arithmetic or bit wise operation
+ has only one use, that use is immediately following
+ the defintion and the using iCode has only one
+ operand or has two operands but one is literal &
+ the result of that operation is not on stack then
+ we can leave the result of this operation in acc:b
+ combination */
+ if ((IS_ARITHMETIC_OP (ic)
+
+ || IS_BITWISE_OP (ic)
+
+ || ic->op == LEFT_OP || ic->op == RIGHT_OP
+
+ ) &&
+ IS_ITEMP (IC_RESULT (ic)) &&
+ getSize (operandType (IC_RESULT (ic))) <= 2)
+
+ packRegsForAccUse (ic);
+
+ }
}
static void
dumpEbbsToDebug (eBBlock ** ebbs, int count)
{
- int i;
-
- if (!debug || !debugF)
- return;
-
- for (i = 0; i < count; i++)
- {
- fprintf (debugF, "\n----------------------------------------------------------------\n");
- fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
- ebbs[i]->entryLabel->name,
- ebbs[i]->depth,
- ebbs[i]->noPath,
- ebbs[i]->isLastInLoop);
- fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
- ebbs[i]->dfnum,
- ebbs[i]->bbnum,
- ebbs[i]->fSeq,
- ebbs[i]->lSeq);
- fprintf (debugF, "visited %d : hasFcall = %d\n",
- ebbs[i]->visited,
- ebbs[i]->hasFcall);
-
- fprintf (debugF, "\ndefines bitVector :");
- bitVectDebugOn (ebbs[i]->defSet, debugF);
- fprintf (debugF, "\nlocal defines bitVector :");
- bitVectDebugOn (ebbs[i]->ldefs, debugF);
- fprintf (debugF, "\npointers Set bitvector :");
- bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
- fprintf (debugF, "\nin pointers Set bitvector :");
- bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
- fprintf (debugF, "\ninDefs Set bitvector :");
- bitVectDebugOn (ebbs[i]->inDefs, debugF);
- fprintf (debugF, "\noutDefs Set bitvector :");
- bitVectDebugOn (ebbs[i]->outDefs, debugF);
- fprintf (debugF, "\nusesDefs Set bitvector :");
- bitVectDebugOn (ebbs[i]->usesDefs, debugF);
- fprintf (debugF, "\n----------------------------------------------------------------\n");
- printiCChain (ebbs[i]->sch, debugF);
- }
+ int i;
+
+ if (!debug || !debugF)
+ return;
+
+ for (i = 0; i < count; i++)
+ {
+ fprintf (debugF, "\n----------------------------------------------------------------\n");
+ fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
+ ebbs[i]->entryLabel->name,
+ ebbs[i]->depth,
+ ebbs[i]->noPath,
+ ebbs[i]->isLastInLoop);
+ fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
+ ebbs[i]->dfnum,
+ ebbs[i]->bbnum,
+ ebbs[i]->fSeq,
+ ebbs[i]->lSeq);
+ fprintf (debugF, "visited %d : hasFcall = %d\n",
+ ebbs[i]->visited,
+ ebbs[i]->hasFcall);
+
+ fprintf (debugF, "\ndefines bitVector :");
+ bitVectDebugOn (ebbs[i]->defSet, debugF);
+ fprintf (debugF, "\nlocal defines bitVector :");
+ bitVectDebugOn (ebbs[i]->ldefs, debugF);
+ fprintf (debugF, "\npointers Set bitvector :");
+ bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
+ fprintf (debugF, "\nin pointers Set bitvector :");
+ bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
+ fprintf (debugF, "\ninDefs Set bitvector :");
+ bitVectDebugOn (ebbs[i]->inDefs, debugF);
+ fprintf (debugF, "\noutDefs Set bitvector :");
+ bitVectDebugOn (ebbs[i]->outDefs, debugF);
+ fprintf (debugF, "\nusesDefs Set bitvector :");
+ bitVectDebugOn (ebbs[i]->usesDefs, debugF);
+ fprintf (debugF, "\n----------------------------------------------------------------\n");
+ printiCChain (ebbs[i]->sch, debugF);
+ }
}
/*-----------------------------------------------------------------*/
/* assignRegisters - assigns registers to each live range as need */
void
pic14_assignRegisters (ebbIndex * ebbi)
{
- eBBlock ** ebbs = ebbi->bbOrder;
- int count = ebbi->count;
- iCode *ic;
- int i;
-
- debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s\n", __FILE__, __FUNCTION__);
- debugLog ("ebbs before optimizing:\n");
- dumpEbbsToDebug (ebbs, count);
-
- setToNull ((void *) &_G.funcrUsed);
- pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
-
-
- /* change assignments this will remove some
- live ranges reducing some register pressure */
- for (i = 0; i < count; i++)
- packRegisters (ebbs[i]);
-
- {
- regs *reg;
- int hkey;
- int i=0;
-
- debugLog("dir registers allocated so far:\n");
- reg = hTabFirstItem(dynDirectRegNames, &hkey);
-
- while(reg) {
- debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
- reg = hTabNextItem(dynDirectRegNames, &hkey);
- }
-
- }
-
- if (options.dump_pack)
- dumpEbbsToFileExt (DUMP_PACK, ebbi);
-
- /* first determine for each live range the number of
- registers & the type of registers required for each */
- regTypeNum ();
-
- /* and serially allocate registers */
- serialRegAssign (ebbs, count);
-
- /* if stack was extended then tell the user */
- if (_G.stackExtend)
- {
- /* werror(W_TOOMANY_SPILS,"stack", */
- /* _G.stackExtend,currFunc->name,""); */
- _G.stackExtend = 0;
- }
-
- if (_G.dataExtend)
- {
- /* werror(W_TOOMANY_SPILS,"data space", */
- /* _G.dataExtend,currFunc->name,""); */
- _G.dataExtend = 0;
- }
-
- /* after that create the register mask
- for each of the instruction */
- createRegMask (ebbs, count);
-
- /* redo that offsets for stacked automatic variables */
- redoStackOffsets ();
-
- if (options.dump_rassgn)
- dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
-
- /* now get back the chain */
- ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
-
- debugLog ("ebbs after optimizing:\n");
- dumpEbbsToDebug (ebbs, count);
-
-
- genpic14Code (ic);
-
- /* free up any _G.stackSpil locations allocated */
- applyToSet (_G.stackSpil, deallocStackSpil);
- _G.slocNum = 0;
- setToNull ((void *) &_G.stackSpil);
- setToNull ((void *) &_G.spiltSet);
- /* mark all registers as free */
- //pic14_freeAllRegs ();
-
- debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");
- pic14_debugLogClose ();
- return;
+ eBBlock ** ebbs = ebbi->bbOrder;
+ int count = ebbi->count;
+ iCode *ic;
+ int i;
+
+ debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s\n", __FILE__, __FUNCTION__);
+ debugLog ("ebbs before optimizing:\n");
+ dumpEbbsToDebug (ebbs, count);
+
+ setToNull ((void *) &_G.funcrUsed);
+ pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
+
+
+ /* change assignments this will remove some
+ live ranges reducing some register pressure */
+ for (i = 0; i < count; i++)
+ packRegisters (ebbs[i]);
+
+ {
+ regs *reg;
+ int hkey;
+ int i=0;
+
+ debugLog("dir registers allocated so far:\n");
+ reg = hTabFirstItem(dynDirectRegNames, &hkey);
+
+ while(reg) {
+ debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
+ reg = hTabNextItem(dynDirectRegNames, &hkey);
+ }
+
+ }
+
+ if (options.dump_pack)
+ dumpEbbsToFileExt (DUMP_PACK, ebbi);
+
+ /* first determine for each live range the number of
+ registers & the type of registers required for each */
+ regTypeNum ();
+
+ /* and serially allocate registers */
+ serialRegAssign (ebbs, count);
+
+ /* if stack was extended then tell the user */
+ if (_G.stackExtend)
+ {
+ /* werror(W_TOOMANY_SPILS,"stack", */
+ /* _G.stackExtend,currFunc->name,""); */
+ _G.stackExtend = 0;
+ }
+
+ if (_G.dataExtend)
+ {
+ /* werror(W_TOOMANY_SPILS,"data space", */
+ /* _G.dataExtend,currFunc->name,""); */
+ _G.dataExtend = 0;
+ }
+
+ /* after that create the register mask
+ for each of the instruction */
+ createRegMask (ebbs, count);
+
+ /* redo that offsets for stacked automatic variables */
+ redoStackOffsets ();
+
+ if (options.dump_rassgn)
+ dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
+
+ /* now get back the chain */
+ ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
+
+ debugLog ("ebbs after optimizing:\n");
+ dumpEbbsToDebug (ebbs, count);
+
+
+ genpic14Code (ic);
+
+ /* free up any _G.stackSpil locations allocated */
+ applyToSet (_G.stackSpil, deallocStackSpil);
+ _G.slocNum = 0;
+ setToNull ((void *) &_G.stackSpil);
+ setToNull ((void *) &_G.spiltSet);
+ /* mark all registers as free */
+ //pic14_freeAllRegs ();
+
+ debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");
+ pic14_debugLogClose ();
+ return;
}
PIC16 port - Martin Dubuc m.dubuc@rogers.com (2002)
- Vangelis Rokas <vrokas AT users.sourceforge.net> (2003-2006)
Bug Fixes - Raphael Neider <rneider AT web.de> (2004,2005)
-
+
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+
In other words, you are welcome to use, share and improve this program.
You are forbidden to forbid anyone else to use, share and improve
what you give them. Help stamp out software-hoarding!
-
+
Notes:
- 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
- Made everything static
+ 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
+ Made everything static
-------------------------------------------------------------------------*/
#include <stdio.h>
#define USE_SIMPLE_GENCMP 1
/* The PIC port(s) do not need to distinguish between POINTER and FPOINTER. */
-#define PIC_IS_DATA_PTR(x) (IS_DATA_PTR(x) || IS_FARPTR(x))
-#define PIC_IS_FARPTR(x) (IS_DATA_PTR(x) || IS_FARPTR(x))
-#define PIC_IS_TAGGED(x) (IS_GENPTR(x) || IS_CODEPTR(x))
-#define IS_DIRECT(op) ((AOP_TYPE(op) == AOP_PCODE) && (AOP(op)->aopu.pcop->type == PO_DIR))
+#define PIC_IS_DATA_PTR(x) (IS_DATA_PTR(x) || IS_FARPTR(x))
+#define PIC_IS_FARPTR(x) (IS_DATA_PTR(x) || IS_FARPTR(x))
+#define PIC_IS_TAGGED(x) (IS_GENPTR(x) || IS_CODEPTR(x))
+#define IS_DIRECT(op) ((AOP_TYPE(op) == AOP_PCODE) && (AOP(op)->aopu.pcop->type == PO_DIR))
/* If you change these, you also have to update the library files
* device/lib/pic16/libsdcc/gptr{get,put}{1,2,3,4}.c */
-#define GPTR_TAG_DATA 0x80
-#define GPTR_TAG_EEPROM 0x40
-#define GPTR_TAG_CODE 0x00 /* must be 0 becaue of UPPER(sym)==0 */
+#define GPTR_TAG_DATA 0x80
+#define GPTR_TAG_EEPROM 0x40
+#define GPTR_TAG_CODE 0x00 /* must be 0 becaue of UPPER(sym)==0 */
/* Wrapper to execute `code' at most once. */
-#define PERFORM_ONCE(id,code) do { static char id = 0; if (!id) { id = 1; code } } while (0)
+#define PERFORM_ONCE(id,code) do { static char id = 0; if (!id) { id = 1; code } } while (0)
void pic16_genMult8X8_n (operand *, operand *,operand *);
#if 0
extern set *externs;
-/* max_key keeps track of the largest label number used in
+/* max_key keeps track of the largest label number used in
a function. This is then used to adjust the label offset
for the next function.
*/
/* set the following macro to 1 to enable passing the
* first byte of functions parameters via WREG */
-#define USE_WREG_IN_FUNC_PARAMS 0
+#define USE_WREG_IN_FUNC_PARAMS 0
-/* this is the down and dirty file with all kinds of
+/* this is the down and dirty file with all kinds of
kludgy & hacky stuff. This is what it is all about
CODE GENERATION for a specific MCU . some of the
routines may be reusable, will have to see */
/*
* Function return value policy (MSB-->LSB):
- * 8 bits -> WREG
- * 16 bits -> PRODL:WREG
- * 24 bits -> PRODH:PRODL:WREG
- * 32 bits -> FSR0L:PRODH:PRODL:WREG
- * >32 bits -> on stack, and FSR0 points to the beginning
+ * 8 bits -> WREG
+ * 16 bits -> PRODL:WREG
+ * 24 bits -> PRODH:PRODL:WREG
+ * 32 bits -> FSR0L:PRODH:PRODL:WREG
+ * >32 bits -> on stack, and FSR0 points to the beginning
*
*/
-
+
char *fReturnpic16[] = {"WREG", "PRODL", "PRODH", "FSR0L" };
int fReturnIdx[] = {IDX_WREG, IDX_PRODL, IDX_PRODH, IDX_FSR0L };
set *sendSet;
set *stackRegSet;
int usefastretfie;
- bitVect *fregsUsed; /* registers used in function */
+ bitVect *fregsUsed; /* registers used in function */
bitVect *sregsAlloc;
- set *sregsAllocSet; /* registers used to store stack variables */
- int stack_lat; /* stack offset latency */
+ set *sregsAllocSet; /* registers used to store stack variables */
+ int stack_lat; /* stack offset latency */
int resDirect;
- int useWreg; /* flag when WREG is used to pass function parameter */
+ int useWreg; /* flag when WREG is used to pass function parameter */
} _G;
extern int pic16_ptrRegReq ;
if( (num & (num-1)) == 0) {
int nshifts = -1;
while(num) {
- num>>=1;
- nshifts++;
+ num>>=1;
+ nshifts++;
}
return nshifts;
}
void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result)
{
DEBUGpic16_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
- line_no,
- ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
- ((result) ? pic16_aopGet(AOP(result),0,TRUE,FALSE) : "-"),
- ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
- ((left) ? pic16_aopGet(AOP(left),0,TRUE,FALSE) : "-"),
- ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
- ((right) ? pic16_aopGet(AOP(right),0,FALSE,FALSE) : "-"),
- ((result) ? AOP_SIZE(result) : 0));
+ line_no,
+ ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
+ ((result) ? pic16_aopGet(AOP(result),0,TRUE,FALSE) : "-"),
+ ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
+ ((left) ? pic16_aopGet(AOP(left),0,TRUE,FALSE) : "-"),
+ ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
+ ((right) ? pic16_aopGet(AOP(right),0,FALSE,FALSE) : "-"),
+ ((result) ? AOP_SIZE(result) : 0));
}
void DEBUGpic16_pic16_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
{
DEBUGpic16_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
- line_no,
- ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
- ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
- ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
- ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
- ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
- ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
+ line_no,
+ ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
+ ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
+ ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
+ ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
+ ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
+ ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
}
void pic16_emitpcomment (char *fmt, ...)
{
va_list ap;
- char lb[INITIAL_INLINEASM];
+ char lb[INITIAL_INLINEASM];
unsigned char *lbp = (unsigned char *)lb;
- va_start(ap,fmt);
+ va_start(ap,fmt);
lb[0] = ';';
vsprintf(lb+1,fmt,ap);
while (isspace(*lbp)) lbp++;
- if (lbp && *lbp)
+ if (lbp && *lbp)
lineCurr = (lineCurr ?
connectLine(lineCurr,newLineNode(lb)) :
(lineHead = newLineNode(lb)));
pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
va_end(ap);
-// fprintf(stderr, "%s\n", lb);
+// fprintf(stderr, "%s\n", lb);
}
void DEBUGpic16_emitcode (char *inst,char *fmt, ...)
{
va_list ap;
- char lb[INITIAL_INLINEASM];
+ char lb[INITIAL_INLINEASM];
unsigned char *lbp = (unsigned char *)lb;
if(!pic16_debug_verbose)
return;
- va_start(ap,fmt);
+ va_start(ap,fmt);
if (inst && *inst) {
- if (fmt && *fmt)
- sprintf(lb,"%s\t",inst);
- else
- sprintf(lb,"%s",inst);
+ if (fmt && *fmt)
+ sprintf(lb,"%s\t",inst);
+ else
+ sprintf(lb,"%s",inst);
vsprintf(lb+(strlen(lb)),fmt,ap);
} else
vsprintf(lb,fmt,ap);
while (isspace(*lbp)) lbp++;
- if (lbp && *lbp)
+ if (lbp && *lbp)
lineCurr = (lineCurr ?
connectLine(lineCurr,newLineNode(lb)) :
(lineHead = newLineNode(lb)));
pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
va_end(ap);
-// fprintf(stderr, "%s\n", lb);
+// fprintf(stderr, "%s\n", lb);
}
else
DEBUGpic16_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
}
-
+
void pic16_emitpcodeNULLop(PIC_OPCODE poc)
{
#if 1
-#define pic16_emitcode DEBUGpic16_emitcode
+#define pic16_emitcode DEBUGpic16_emitcode
#else
/*-----------------------------------------------------------------*/
/* pic16_emitcode - writes the code into a file : for now it is simple */
void pic16_emitcode (char *inst,char *fmt, ...)
{
va_list ap;
- char lb[INITIAL_INLINEASM];
+ char lb[INITIAL_INLINEASM];
unsigned char *lbp = lb;
- va_start(ap,fmt);
+ va_start(ap,fmt);
if (inst && *inst) {
- if (fmt && *fmt)
- sprintf(lb,"%s\t",inst);
- else
- sprintf(lb,"%s",inst);
+ if (fmt && *fmt)
+ sprintf(lb,"%s\t",inst);
+ else
+ sprintf(lb,"%s",inst);
vsprintf(lb+(strlen(lb)),fmt,ap);
} else
vsprintf(lb,fmt,ap);
while (isspace(*lbp)) lbp++;
- if (lbp && *lbp)
+ if (lbp && *lbp)
lineCurr = (lineCurr ?
connectLine(lineCurr,newLineNode(lb)) :
(lineHead = newLineNode(lb)));
// bool r0ou = FALSE , r1ou = FALSE;
bool fsr0iu = FALSE, fsr0ou;
bool fsr2iu = FALSE, fsr2ou;
-
+
//fprintf(stderr, "%s:%s:%d: getting free ptr from ic = %c result: %d\n", __FILE__, __FUNCTION__, __LINE__, ic->op, result);
-
+
fsr2iu = bitVectBitValue(ic->rUsed, IDX_FSR2);
fsr0iu = bitVectBitValue(ic->rUsed, IDX_FSR0);
-
+
fsr2ou = bitVectBitValue(ic->rMask, IDX_FSR2);
fsr0ou = bitVectBitValue(ic->rMask, IDX_FSR0);
if(bitVectBitValue(ic->rUsed, IDX_WREG)) {
- fprintf(stderr, "%s:%d WREG is used by this ic\n", __FILE__, __LINE__);
- DEBUGpic16_emitcode("%s:%d WREG is used by this ic", __FILE__, __LINE__);
+ fprintf(stderr, "%s:%d WREG is used by this ic\n", __FILE__, __LINE__);
+ DEBUGpic16_emitcode("%s:%d WREG is used by this ic", __FILE__, __LINE__);
}
if(!fsr0iu && !fsr0ou) {
- ic->rUsed = bitVectSetBit(ic->rUsed, IDX_FSR0);
- (*aopp)->type = AOP_FSR0;
+ ic->rUsed = bitVectSetBit(ic->rUsed, IDX_FSR0);
+ (*aopp)->type = AOP_FSR0;
+
+ //fprintf(stderr, "%s:%d returning plain FSR0\n", __FILE__, __LINE__);
- //fprintf(stderr, "%s:%d returning plain FSR0\n", __FILE__, __LINE__);
-
return ((*aopp)->aopu.aop_ptr = pic16_regWithIdx(IDX_FSR0));
}
#if 0
/* no usage of FSR2 */
if(!fsr2iu && !fsr2ou) {
- ic->rUsed = bitVectSetBit(ic->rUsed, IDX_FSR2);
- (*aopp)->type = AOP_FSR2;
+ ic->rUsed = bitVectSetBit(ic->rUsed, IDX_FSR2);
+ (*aopp)->type = AOP_FSR2;
return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(IDX_FSR2);
}
#endif
-
+
/* now we know they both have usage */
/* if fsr0 not used in this instruction */
if (!fsr0iu) {
- if (!_G.fsr0Pushed) {
- pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_fsr0l) );
- pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_fsr0h) );
- _G.fsr0Pushed++;
- }
+ if (!_G.fsr0Pushed) {
+ pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_fsr0l) );
+ pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_fsr0h) );
+ _G.fsr0Pushed++;
+ }
- ic->rUsed = bitVectSetBit (ic->rUsed, IDX_FSR0);
- (*aopp)->type = AOP_FSR0;
+ ic->rUsed = bitVectSetBit (ic->rUsed, IDX_FSR0);
+ (*aopp)->type = AOP_FSR0;
-// fprintf(stderr, "%s:%d returning FSR0 after pushing value to stack\n", __FILE__, __LINE__);
+// fprintf(stderr, "%s:%d returning FSR0 after pushing value to stack\n", __FILE__, __LINE__);
return (*aopp)->aopu.aop_ptr = pic16_regWithIdx (IDX_FSR0);
}
-
+
fprintf(stderr, "%s:%d could not allocate a free pointer\n", __FILE__, __LINE__);
assert( 0 );
/* first check if r0 & r1 are used by this
instruction, in which case we are in trouble */
if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
- (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
+ (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
{
- goto endOfWorld;
+ goto endOfWorld;
}
r0ou = bitVectBitValue(ic->rMask,R0_IDX);
/* if no usage of r0 then return it */
if (!r0iu && !r0ou) {
ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
- (*aopp)->type = AOP_R0;
-
+ (*aopp)->type = AOP_R0;
+
return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
}
(*aopp)->type = AOP_R1;
return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R1_IDX);
- }
+ }
/* now we know they both have usage */
/* if r0 not used in this instruction */
if (!r0iu) {
/* push it if not already pushed */
if (!_G.r0Pushed) {
- //pic16_emitcode ("push","%s",
- // pic16_regWithIdx(R0_IDX)->dname);
+ //pic16_emitcode ("push","%s",
+ // pic16_regWithIdx(R0_IDX)->dname);
_G.r0Pushed++ ;
}
-
+
ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
(*aopp)->type = AOP_R0;
if (!r1iu) {
/* push it if not already pushed */
if (!_G.r1Pushed) {
- //pic16_emitcode ("push","%s",
- // pic16_regWithIdx(R1_IDX)->dname);
+ //pic16_emitcode ("push","%s",
+ // pic16_regWithIdx(R1_IDX)->dname);
_G.r1Pushed++ ;
}
-
+
ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
(*aopp)->type = AOP_R1;
return pic16_regWithIdx(R1_IDX);
/* I said end of world but not quite end of world yet */
/* if this is a result then we can push it on the stack*/
if (result) {
- (*aopp)->type = AOP_STK;
+ (*aopp)->type = AOP_STK;
return NULL;
}
static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
{
FENTRY2;
-
+
// DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
- if(!resIfx)
+ if(!resIfx)
return;
#if 1
DEBUGpic16_emitcode("; ***","%s %d null ifx creating new label key =%d",
- __FUNCTION__,__LINE__,resIfx->lbl->key);
+ __FUNCTION__,__LINE__,resIfx->lbl->key);
#endif
} else {
}
#if 1
- if(IC_TRUE(ifx))
+ if(IC_TRUE(ifx))
DEBUGpic16_emitcode("; +++","ifx true is non-null");
else
DEBUGpic16_emitcode("; +++","ifx true is null");
- if(IC_FALSE(ifx))
+ if(IC_FALSE(ifx))
DEBUGpic16_emitcode("; +++","ifx false is non-null");
else
DEBUGpic16_emitcode("; +++","ifx false is null");
memmap *space= SPEC_OCLS(sym->etype);
FENTRY2;
-
- _G.resDirect = 0; /* clear flag that instructs the result is loaded directly from aopForSym */
-
+
+ _G.resDirect = 0; /* clear flag that instructs the result is loaded directly from aopForSym */
+
// sym = OP_SYMBOL(op);
/* if already has one */
if (sym->aop) {
- DEBUGpic16_emitcode("; ***", "already has sym %s %d", __FUNCTION__, __LINE__);
+ DEBUGpic16_emitcode("; ***", "already has sym %s %d", __FUNCTION__, __LINE__);
return sym->aop;
}
/* if symbol was initially placed onStack then we must re-place it
* to direct memory, since pic16 does not have a specific stack */
if(sym->onStack) {
- fprintf(stderr, "%s:%d symbol %s on stack\n", __FILE__, __LINE__, OP_SYMBOL(op)->name);
+ fprintf(stderr, "%s:%d symbol %s on stack\n", __FILE__, __LINE__, OP_SYMBOL(op)->name);
}
#endif
sym->aop = aop = newAsmop (AOP_PAGED);
aop->aopu.aop_dir = sym->rname ;
aop->size = getSize(sym->type);
- DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
- pic16_allocDirReg( IC_LEFT(ic) );
+ DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
+ pic16_allocDirReg( IC_LEFT(ic) );
return aop;
}
assert( 0 );
}
#endif
-
+
#if 1
/* assign depending on the storage class */
/* if it is on the stack or indirectly addressable */
- /* space we need to assign either r0 or r1 to it */
- if (sym->onStack) // || sym->iaccess)
+ /* space we need to assign either r0 or r1 to it */
+ if (sym->onStack) // || sym->iaccess)
{
pCodeOp *pcop[4];
int i;
-
- DEBUGpic16_emitcode("; ***", "%s:%d sym->onStack:%d || sym->iaccess:%d",
- __FUNCTION__, __LINE__, sym->onStack, sym->iaccess);
-
+
+ DEBUGpic16_emitcode("; ***", "%s:%d sym->onStack:%d || sym->iaccess:%d",
+ __FUNCTION__, __LINE__, sym->onStack, sym->iaccess);
+
/* acquire a temporary register -- it is saved in function */
sym->aop = aop = newAsmop(AOP_STA);
if((ic->op == '=' /*|| ic->op == CAST*/) && IC_RESULT(ic) && AOP( IC_RESULT(ic) )
&& (AOP_TYPE(IC_RESULT(ic)) == AOP_REG)) {
// pic16_DumpAop("aopForSym", AOP( IC_RESULT(ic) ));
-
+
for(i=0;i<aop->size;i++)
aop->aopu.stk.pop[i] = pcop[i] = pic16_popRegFromIdx( AOP(IC_RESULT(ic))->aopu.aop_reg[i]->rIdx);
- _G.resDirect = 1; /* notify that result will be loaded directly from aopForSym */
+ _G.resDirect = 1; /* notify that result will be loaded directly from aopForSym */
} else
if(1 && ic->op == SEND) {
/* if SEND do the send here */
_G.resDirect = 1;
} else {
-// debugf3("symbol `%s' level = %d / %d\n", sym->name, ic->level, ic->seq);
+// debugf3("symbol `%s' level = %d / %d\n", sym->name, ic->level, ic->seq);
for(i=0;i<aop->size;i++) {
aop->aopu.stk.pop[i] = pcop[i] = pic16_popGetTempRegCond(_G.fregsUsed, _G.sregsAlloc, 0 );
_G.sregsAlloc = bitVectSetBit(_G.sregsAlloc, PCOR(pcop[i])->r->rIdx);
// fprintf(stderr, "%s:%d\t%s\tsym size %d\n", __FILE__, __LINE__, __FUNCTION__, aop->size);
#if 1
- DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d stack = %d",__LINE__,sym->rname,aop->size, sym->stack);
+ DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d stack = %d",__LINE__,sym->rname,aop->size, sym->stack);
- // we do not need to load the value if it is to be defined...
- if (result) return aop;
+ // we do not need to load the value if it is to be defined...
+ if (result) return aop;
- if(_G.accInUse) {
- pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
- }
-
- for(i=0;i<aop->size;i++) {
+ if(_G.accInUse) {
+ pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
+ }
+
+ for(i=0;i<aop->size;i++) {
- /* initialise for stack access via frame pointer */
+ /* initialise for stack access via frame pointer */
// operands on stack are accessible via "{FRAME POINTER} + index" with index
// starting at 2 for arguments and growing from 0 downwards for
// local variables (index == 0 is not assigned so we add one here)
- {
- int soffs = sym->stack;
- if (soffs <= 0) {
- assert (soffs < 0);
- soffs++;
- } // if
+ {
+ int soffs = sym->stack;
+ if (soffs <= 0) {
+ assert (soffs < 0);
+ soffs++;
+ } // if
if(1 && ic->op == SEND) {
pic16_emitpcode(POC_MOVLW, pic16_popGetLit(soffs + aop->size - i - 1 /*+ _G.stack_lat*/));
} else {
pic16_emitpcode(POC_MOVLW, pic16_popGetLit(soffs + i /*+ _G.stack_lat*/));
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
- pic16_popCopyReg( pic16_frame_plusw ), pcop[i]));
+ pic16_popCopyReg( pic16_frame_plusw ), pcop[i]));
}
- }
- }
-
- if(_G.accInUse) {
- pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
- }
-
- return (aop);
+ }
+ }
+
+ if(_G.accInUse) {
+ pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
+ }
+
+ return (aop);
#endif
#if 0
- /* now assign the address of the variable to
+ /* now assign the address of the variable to
the pointer register */
if (aop->type != AOP_STK) {
pic16_emitcode("mov","a,_bp");
pic16_emitcode("add","a,#0x%02x",
((sym->stack < 0) ?
- ((char)(sym->stack - _G.nRegsSaved )) :
- ((char)sym->stack)) & 0xff);
+ ((char)(sym->stack - _G.nRegsSaved )) :
+ ((char)sym->stack)) & 0xff);
pic16_emitcode("mov","%s,a",
aop->aopu.aop_ptr->name);
/* It's on the 10 bit stack, which is located in
* far data space.
*/
-
+
//DEBUGpic16_emitcode(";","%d",__LINE__);
if ( _G.accInUse )
- pic16_emitcode("push","acc");
+ pic16_emitcode("push","acc");
pic16_emitcode("mov","a,_bp");
pic16_emitcode("add","a,#0x%02x",
((sym->stack < 0) ?
((char)(sym->stack - _G.nRegsSaved )) :
((char)sym->stack)) & 0xff);
-
+
genSetDPTR(1);
pic16_emitcode ("mov","dpx1,#0x40");
pic16_emitcode ("mov","dph1,#0x00");
pic16_emitcode ("mov","dpl1, a");
genSetDPTR(0);
-
+
if ( _G.accInUse )
pic16_emitcode("pop","acc");
-
+
sym->aop = aop = newAsmop(AOP_DPTR2);
- aop->size = getSize(sym->type);
- return aop;
+ aop->size = getSize(sym->type);
+ return aop;
}
#endif
#if 1
/* special case for a function */
- if (IS_FUNC(sym->type)) {
+ if (IS_FUNC(sym->type)) {
sym->aop = aop = newAsmop(AOP_PCODE);
//_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
- aop->aopu.pcop = pic16_popGetImmd(sym->rname, 0, 0);
- PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
- PCOI(aop->aopu.pcop)->index = 0;
- aop->size = FPTRSIZE;
- DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
+ aop->aopu.pcop = pic16_popGetImmd(sym->rname, 0, 0);
+ PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
+ PCOI(aop->aopu.pcop)->index = 0;
+ aop->size = FPTRSIZE;
+ DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
return aop;
}
#endif
sym->aop = aop = newAsmop (AOP_CRY);
aop->aopu.aop_dir = sym->rname ;
aop->size = getSize(sym->type);
- DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
+ DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
return aop;
}
/* if it is in direct space */
if (IN_DIRSPACE(space)) {
- if(!strcmp(sym->rname, "_WREG")) {
- sym->aop = aop = newAsmop (AOP_ACC);
- aop->size = getSize(sym->type); /* should always be 1 */
- assert(aop->size == 1);
- DEBUGpic16_emitcode(";","%d sym->rname (AOP_ACC) = %s, size = %d",__LINE__,sym->rname,aop->size);
- return (aop);
- } else {
- sym->aop = aop = newAsmop (AOP_DIR);
- aop->aopu.aop_dir = sym->rname ;
- aop->size = getSize(sym->type);
- DEBUGpic16_emitcode(";","%d sym->rname (AOP_DIR) = %s, size = %d",__LINE__,sym->rname,aop->size);
- pic16_allocDirReg( IC_LEFT(ic) );
- return (aop);
- }
- }
+ if(!strcmp(sym->rname, "_WREG")) {
+ sym->aop = aop = newAsmop (AOP_ACC);
+ aop->size = getSize(sym->type); /* should always be 1 */
+ assert(aop->size == 1);
+ DEBUGpic16_emitcode(";","%d sym->rname (AOP_ACC) = %s, size = %d",__LINE__,sym->rname,aop->size);
+ return (aop);
+ } else {
+ sym->aop = aop = newAsmop (AOP_DIR);
+ aop->aopu.aop_dir = sym->rname ;
+ aop->size = getSize(sym->type);
+ DEBUGpic16_emitcode(";","%d sym->rname (AOP_DIR) = %s, size = %d",__LINE__,sym->rname,aop->size);
+ pic16_allocDirReg( IC_LEFT(ic) );
+ return (aop);
+ }
+ }
if (IN_FARSPACE(space) && !IN_CODESPACE(space)) {
sym->aop = aop = newAsmop (AOP_DIR);
aop->aopu.aop_dir = sym->rname ;
aop->size = getSize(sym->type);
- DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
- pic16_allocDirReg( IC_LEFT(ic) );
+ DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
+ pic16_allocDirReg( IC_LEFT(ic) );
return aop;
}
sym->aop = aop = newAsmop(AOP_PCODE);
/* change the next if to 1 to revert to good old immediate code */
- if(IN_CODESPACE(space)) {
- aop->aopu.pcop = pic16_popGetImmd(sym->rname, 0, 0);
- PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
- PCOI(aop->aopu.pcop)->index = 0;
- } else {
- /* try to allocate via direct register */
- aop->aopu.pcop = pic16_popRegFromString(sym->rname, getSize(sym->type), sym->offset, op); // Patch 8
-// aop->size = getSize( sym->type );
- }
-
- DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
- __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
+ if(IN_CODESPACE(space)) {
+ aop->aopu.pcop = pic16_popGetImmd(sym->rname, 0, 0);
+ PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
+ PCOI(aop->aopu.pcop)->index = 0;
+ } else {
+ /* try to allocate via direct register */
+ aop->aopu.pcop = pic16_popRegFromString(sym->rname, getSize(sym->type), sym->offset, op); // Patch 8
+// aop->size = getSize( sym->type );
+ }
+
+ DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
+ __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
#if 0
- if(!pic16_allocDirReg (IC_LEFT(ic)))
- return NULL;
+ if(!pic16_allocDirReg (IC_LEFT(ic)))
+ return NULL;
#endif
- if(IN_DIRSPACE( space ))
- aop->size = PTRSIZE;
- else if(IN_CODESPACE( space ) || IN_FARSPACE( space ))
- aop->size = FPTRSIZE;
- else if(IC_LEFT(ic) && AOP(IC_LEFT(ic))) aop->size = AOP_SIZE( IC_LEFT(ic) );
- else if(IC_RIGHT(ic) && AOP(IC_RIGHT(ic))) aop->size = AOP_SIZE( IC_RIGHT(ic) );
- else if(sym->onStack) {
- aop->size = PTRSIZE;
+ if(IN_DIRSPACE( space ))
+ aop->size = PTRSIZE;
+ else if(IN_CODESPACE( space ) || IN_FARSPACE( space ))
+ aop->size = FPTRSIZE;
+ else if(IC_LEFT(ic) && AOP(IC_LEFT(ic))) aop->size = AOP_SIZE( IC_LEFT(ic) );
+ else if(IC_RIGHT(ic) && AOP(IC_RIGHT(ic))) aop->size = AOP_SIZE( IC_RIGHT(ic) );
+ else if(sym->onStack) {
+ aop->size = PTRSIZE;
} else {
if(SPEC_SCLS(sym->etype) == S_PDATA) {
fprintf(stderr, "%s: %d symbol in PDATA space\n", __FILE__, __LINE__);
aop->size = FPTRSIZE;
} else
- assert( 0 );
- }
+ assert( 0 );
+ }
DEBUGpic16_emitcode(";","%d size = %d",__LINE__,aop->size);
if (IN_CODESPACE(space))
aop->code = 1;
- return aop;
+ return aop;
}
/*-----------------------------------------------------------------*/
int viaimmd=0;
FENTRY2;
-
- ic = sym->rematiCode;
- if(IS_OP_POINTER(op)) {
- DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
- }
+ ic = sym->rematiCode;
+
+ if(IS_OP_POINTER(op)) {
+ DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
+ }
-// if(!result) /* fixme-vr */
- for (;;) {
- oldic = ic;
+// if(!result) /* fixme-vr */
+ for (;;) {
+ oldic = ic;
// chat *iLine = printILine(ic);
-// pic16_emitpcomment("ic: %s\n", iLine);
+// pic16_emitpcomment("ic: %s\n", iLine);
// dbuf_free(iLine);
-
- if (ic->op == '+') {
- val += (int) operandLitValue(IC_RIGHT(ic));
- } else if (ic->op == '-') {
- val -= (int) operandLitValue(IC_RIGHT(ic));
- } else
- break;
-
- ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
- }
-
- offset = OP_SYMBOL(IC_LEFT(ic))->offset;
- refop = IC_LEFT(ic);
-
- if(!op->isaddr)viaimmd++; else viaimmd=0;
-
+
+ if (ic->op == '+') {
+ val += (int) operandLitValue(IC_RIGHT(ic));
+ } else if (ic->op == '-') {
+ val -= (int) operandLitValue(IC_RIGHT(ic));
+ } else
+ break;
+
+ ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
+ }
+
+ offset = OP_SYMBOL(IC_LEFT(ic))->offset;
+ refop = IC_LEFT(ic);
+
+ if(!op->isaddr)viaimmd++; else viaimmd=0;
+
/* set the following if to 1 to revert to good old immediate code */
- if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(refop)))
- || viaimmd) {
+ if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(refop)))
+ || viaimmd) {
- DEBUGpic16_emitcode(";", "%s:%d immediate, size: %d", __FILE__, __LINE__, getSize( sym->type ));
+ DEBUGpic16_emitcode(";", "%s:%d immediate, size: %d", __FILE__, __LINE__, getSize( sym->type ));
- aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname, 0, val);
+ aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname, 0, val);
#if 0
- PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
+ PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
#else
- PCOI(aop->aopu.pcop)->_const = IS_CODEPTR(operandType(op));
+ PCOI(aop->aopu.pcop)->_const = IS_CODEPTR(operandType(op));
#endif
- PCOI(aop->aopu.pcop)->index = val;
-
- aop->size = getSize( sym->type );
- } else {
- DEBUGpic16_emitcode(";", "%s:%d dir size: %d", __FILE__, __LINE__, getSize( OP_SYMBOL( IC_LEFT(ic))->type));
+ PCOI(aop->aopu.pcop)->index = val;
+
+ aop->size = getSize( sym->type );
+ } else {
+ DEBUGpic16_emitcode(";", "%s:%d dir size: %d", __FILE__, __LINE__, getSize( OP_SYMBOL( IC_LEFT(ic))->type));
- aop->aopu.pcop = pic16_popRegFromString(OP_SYMBOL(IC_LEFT(ic))->rname,
- getSize( OP_SYMBOL( IC_LEFT(ic))->type), val, op);
+ aop->aopu.pcop = pic16_popRegFromString(OP_SYMBOL(IC_LEFT(ic))->rname,
+ getSize( OP_SYMBOL( IC_LEFT(ic))->type), val, op);
- aop->size = getSize( OP_SYMBOL( IC_LEFT(ic))->type );
- }
+ aop->size = getSize( OP_SYMBOL( IC_LEFT(ic))->type );
+ }
- DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
- __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
+ DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
+ __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
#if 0
- val, IS_PTR_CONST(operandType(op)));
+ val, IS_PTR_CONST(operandType(op)));
#else
- val, IS_CODEPTR(operandType(op)));
+ val, IS_CODEPTR(operandType(op)));
#endif
-// DEBUGpic16_emitcode(";","aop type %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic))));
+// DEBUGpic16_emitcode(";","aop type %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic))));
- pic16_allocDirReg (IC_LEFT(ic));
+ pic16_allocDirReg (IC_LEFT(ic));
- if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)) ))
- aop->code = 1;
+ if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)) ))
+ aop->code = 1;
- return aop;
+ return aop;
}
#if 0
if(aop->type != AOP_REG)
return -2;
-
+
return aop->aopu.aop_reg[offset]->rIdx;
}
/* if both are itemps & one is spilt
and the other is not then false */
if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
- sym1->isspilt != sym2->isspilt )
- return FALSE ;
+ sym1->isspilt != sym2->isspilt )
+ return FALSE ;
/* if they are the same */
if (sym1 == sym2)
/* if left is a tmp & right is not */
- if (IS_ITEMP(op1) &&
+ if (IS_ITEMP(op1) &&
!IS_ITEMP(op2) &&
sym1->isspilt &&
(sym1->usl.spillLoc == sym2))
return TRUE;
- if (IS_ITEMP(op2) &&
+ if (IS_ITEMP(op2) &&
!IS_ITEMP(op1) &&
sym2->isspilt &&
- sym1->level > 0 &&
+ sym1->level > 0 &&
(sym2->usl.spillLoc == sym1))
return TRUE ;
return TRUE ;
DEBUGpic16_emitcode(";***", "%s aop1->type = %s\taop2->type = %s\n", __FUNCTION__,
- pic16_AopType(aop1->type), pic16_AopType(aop2->type));
+ pic16_AopType(aop1->type), pic16_AopType(aop2->type));
if(aop1->type == AOP_ACC && aop2->type == AOP_ACC)return TRUE;
bool pic16_sameRegsOfs(asmop *aop1, asmop *aop2, int offset)
{
DEBUGpic16_emitcode(";***", "%s aop1->type = %s\taop2->type = %s (offset = %d)\n", __FUNCTION__,
- pic16_AopType(aop1->type), pic16_AopType(aop2->type), offset);
+ pic16_AopType(aop1->type), pic16_AopType(aop2->type), offset);
if(aop1 == aop2)return TRUE;
if(aop1->type != AOP_REG || aop2->type != AOP_REG)return FALSE;
-
+
if(strcmp(aop1->aopu.aop_reg[offset]->name, aop2->aopu.aop_reg[offset]->name))return FALSE;
-
+
return TRUE;
}
#else
if(IS_CODEPTR(type))
#endif
- DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
+ DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
}
/* if already has a asmop then continue */
}
/* if this is a true symbol */
- if (IS_TRUE_SYMOP(op)) {
- DEBUGpic16_emitcode(";","%d - true symop",__LINE__);
+ if (IS_TRUE_SYMOP(op)) {
+ DEBUGpic16_emitcode(";","%d - true symop",__LINE__);
op->aop = aopForSym(ic, op, result);
return ;
}
only four choices :
a) register
b) spillocation
- c) rematerialize
- d) conditional
+ c) rematerialize
+ d) conditional
e) can be a return use only */
sym = OP_SYMBOL(op);
}
/* if it is spilt then two situations
- a) is rematerialize
+ a) is rematerialize
b) has a spill location */
if (sym->isspilt || sym->nRegs == 0) {
sym->aop = op->aop = aop = aopForRemat (op, result);
// aop->size = getSize(sym->type);
-// DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
+// DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
return;
}
#if 1
- if (sym->accuse) {
- int i;
+ if (sym->accuse) {
+ int i;
aop = op->aop = sym->aop = newAsmop(AOP_ACC);
aop->size = getSize(sym->type);
for ( i = 0 ; i < 1 ; i++ ) {
- aop->aopu.aop_str[i] = accUse[i];
+ aop->aopu.aop_str[i] = accUse[i];
// aop->aopu.pcop = pic16_popRegFromString("WREG", aop->size, sym->usl.spillLoc->offset);
- }
- fprintf(stderr, "%s:%d allocating AOP_ACC for sym= %s\n", __FILE__, __LINE__, sym->name);
- DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size);
- return;
- }
+ }
+ fprintf(stderr, "%s:%d allocating AOP_ACC for sym= %s\n", __FILE__, __LINE__, sym->name);
+ DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size);
+ return;
+ }
#endif
#if 1
if (sym->ruonly) {
- /*
- sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
- aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
- //pic16_allocDirReg (IC_LEFT(ic));
- aop->size = getSize(sym->type);
- */
-
- unsigned i;
-
- aop = op->aop = sym->aop = newAsmop(AOP_REG);
- aop->size = getSize(sym->type);
- for ( i = 0 ; i < pic16_fReturnSizePic ; i++ )
- aop->aopu.aop_reg[i] = PCOR(pic16_popRegFromIdx( fReturnIdx[i] ))->r;
-
- DEBUGpic16_emitcode(";","%d",__LINE__);
- return;
+ /*
+ sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
+ aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
+ //pic16_allocDirReg (IC_LEFT(ic));
+ aop->size = getSize(sym->type);
+ */
+
+ unsigned i;
+
+ aop = op->aop = sym->aop = newAsmop(AOP_REG);
+ aop->size = getSize(sym->type);
+ for ( i = 0 ; i < pic16_fReturnSizePic ; i++ )
+ aop->aopu.aop_reg[i] = PCOR(pic16_popRegFromIdx( fReturnIdx[i] ))->r;
+
+ DEBUGpic16_emitcode(";","%d",__LINE__);
+ return;
}
#endif
/* else spill location */
- if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
- /* force a new aop if sizes differ */
- sym->usl.spillLoc->aop = NULL;
- }
+ if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
+ /* force a new aop if sizes differ */
+ sym->usl.spillLoc->aop = NULL;
+ }
#if 0
- DEBUGpic16_emitcode(";","%s %d %s sym->rname = %s, offset %d",
- __FUNCTION__,__LINE__,
- sym->usl.spillLoc->rname,
- sym->rname, sym->usl.spillLoc->offset);
+ DEBUGpic16_emitcode(";","%s %d %s sym->rname = %s, offset %d",
+ __FUNCTION__,__LINE__,
+ sym->usl.spillLoc->rname,
+ sym->rname, sym->usl.spillLoc->offset);
#endif
- //aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
- if (sym->usl.spillLoc && sym->usl.spillLoc->rname) {
- sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
- aop->aopu.pcop = pic16_popRegFromString(sym->usl.spillLoc->rname,
- getSize(sym->type),
- sym->usl.spillLoc->offset, op);
- } else if (getSize(sym->type) <= 1) {
- //fprintf (stderr, "%s:%d called for a spillLocation -- assigning WREG instead --- CHECK (size:%u)!\n", __FUNCTION__, __LINE__, getSize(sym->type));
- pic16_emitpcomment (";!!! %s:%d called for a spillLocation -- assigning WREG instead --- CHECK", __FUNCTION__, __LINE__);
- assert (getSize(sym->type) <= 1);
- sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
- aop->aopu.pcop = pic16_popCopyReg (&pic16_pc_wreg);
- } else {
- /* We need some kind of dummy area for getSize(sym->type) byte,
- * use WREG for all storage locations.
- * XXX: This only works if we are implementing a `dummy read',
- * the stored value will not be retrievable...
- * See #1503234 for a case requiring this. */
- sym->aop = op->aop = aop = newAsmop(AOP_REG);
- aop->size = getSize(sym->type);
- for ( i = 0 ; i < aop->size ;i++)
- aop->aopu.aop_reg[i] = pic16_pc_wreg.r;
- }
- aop->size = getSize(sym->type);
+ //aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
+ if (sym->usl.spillLoc && sym->usl.spillLoc->rname) {
+ sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
+ aop->aopu.pcop = pic16_popRegFromString(sym->usl.spillLoc->rname,
+ getSize(sym->type),
+ sym->usl.spillLoc->offset, op);
+ } else if (getSize(sym->type) <= 1) {
+ //fprintf (stderr, "%s:%d called for a spillLocation -- assigning WREG instead --- CHECK (size:%u)!\n", __FUNCTION__, __LINE__, getSize(sym->type));
+ pic16_emitpcomment (";!!! %s:%d called for a spillLocation -- assigning WREG instead --- CHECK", __FUNCTION__, __LINE__);
+ assert (getSize(sym->type) <= 1);
+ sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
+ aop->aopu.pcop = pic16_popCopyReg (&pic16_pc_wreg);
+ } else {
+ /* We need some kind of dummy area for getSize(sym->type) byte,
+ * use WREG for all storage locations.
+ * XXX: This only works if we are implementing a `dummy read',
+ * the stored value will not be retrievable...
+ * See #1503234 for a case requiring this. */
+ sym->aop = op->aop = aop = newAsmop(AOP_REG);
+ aop->size = getSize(sym->type);
+ for ( i = 0 ; i < aop->size ;i++)
+ aop->aopu.aop_reg[i] = pic16_pc_wreg.r;
+ }
+ aop->size = getSize(sym->type);
return;
}
{
sym_link *type = operandType(op);
#if 0
- if(IS_PTR_CONST(type))
+ if(IS_PTR_CONST(type))
#else
- if(IS_CODEPTR(type))
+ if(IS_CODEPTR(type))
#endif
- DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
+ DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
}
/* must be in a register */
/* pic16_freeAsmop - free up the asmop given to an operand */
/*----------------------------------------------------------------*/
void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
-{
+{
asmop *aop ;
if (!op)
aop = aaop;
- else
+ else
aop = op->aop;
if (!aop)
return ;
if (aop->freed)
- goto dealloc;
+ goto dealloc;
aop->freed = 1;
case AOP_FSR0 :
if (_G.fsr0Pushed ) {
if (pop) {
- pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_fsr0h) );
- pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_fsr0l) );
+ pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_fsr0h) );
+ pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_fsr0l) );
// pic16_emitcode ("pop","ar0");
_G.fsr0Pushed--;
}
case AOP_R0 :
if (_G.r0Pushed ) {
if (pop) {
- pic16_emitcode ("pop","ar0");
+ pic16_emitcode ("pop","ar0");
_G.r0Pushed--;
}
}
_G.r1Pushed--;
}
}
- bitVectUnSetBit(ic->rUsed,R1_IDX);
+ bitVectUnSetBit(ic->rUsed,R1_IDX);
break;
case AOP_STA:
} // if
if(_G.accInUse)pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
for(i=0;i<aop->size;i++) {
- /* initialise for stack access via frame pointer */
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(soffs + i /*+ _G.stack_lat*/));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ /* initialise for stack access via frame pointer */
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(soffs + i /*+ _G.stack_lat*/));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
aop->aopu.stk.pop[i], pic16_popCopyReg(pic16_frame_plusw)));
- }
-
+ }
+
if(_G.accInUse)pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_wreg) );
}
// pic16_popReleaseTempReg(aop->aopu.stk.pop[i], 0);
}
}
-
+
{
regs *sr;
-
+
_G.sregsAllocSet = reverseSet( _G.sregsAllocSet );
for(sr=setFirstItem(_G.sregsAllocSet) ; sr; sr=setFirstItem(_G.sregsAllocSet)) {
pic16_poppCodeOp( pic16_popRegFromIdx( sr->rIdx ) );
#if 0
case AOP_STK :
{
- int sz = aop->size;
+ int sz = aop->size;
int stk = aop->aopu.aop_stk + aop->size;
bitVectUnSetBit(ic->rUsed,R0_IDX);
- bitVectUnSetBit(ic->rUsed,R1_IDX);
+ bitVectUnSetBit(ic->rUsed,R1_IDX);
getFreePtr(ic,&aop,FALSE);
-
+
if (options.stack10bit)
{
/* I'm not sure what to do here yet... */
/* #STUB */
- fprintf(stderr,
- "*** Warning: probably generating bad code for "
- "10 bit stack mode.\n");
+ fprintf(stderr,
+ "*** Warning: probably generating bad code for "
+ "10 bit stack mode.\n");
}
-
+
if (stk) {
pic16_emitcode ("mov","a,_bp");
pic16_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
if (_G.r1Pushed) {
pic16_emitcode("pop","ar1");
_G.r1Pushed--;
- }
+ }
}
#endif
if (op ) {
op->aop = NULL;
if (IS_SYMOP(op)) {
- OP_SYMBOL(op)->aop = NULL;
+ OP_SYMBOL(op)->aop = NULL;
/* if the symbol has a spill */
- if (SPIL_LOC(op))
+ if (SPIL_LOC(op))
SPIL_LOC(op)->aop = NULL;
}
}
rs = Safe_calloc(1, strlen(s)+1);
strcpy(rs, s);
return (rs);
-
+
#if 0
/* if we need to increment it */
while (offset > aop->coff)
return rs;
#endif
-
+
case AOP_IMMD:
- if (bit16)
- sprintf (s,"%s",aop->aopu.aop_immd);
- else
- if (offset)
- sprintf(s,"(%s >> %d)",
- aop->aopu.aop_immd,
- offset*8);
- else
- sprintf(s,"%s",
- aop->aopu.aop_immd);
- DEBUGpic16_emitcode(";","%d immd %s",__LINE__,s);
- rs = Safe_calloc(1,strlen(s)+1);
- strcpy(rs,s);
- return rs;
-
+ if (bit16)
+ sprintf (s,"%s",aop->aopu.aop_immd);
+ else
+ if (offset)
+ sprintf(s,"(%s >> %d)",
+ aop->aopu.aop_immd,
+ offset*8);
+ else
+ sprintf(s,"%s",
+ aop->aopu.aop_immd);
+ DEBUGpic16_emitcode(";","%d immd %s",__LINE__,s);
+ rs = Safe_calloc(1,strlen(s)+1);
+ strcpy(rs,s);
+ return rs;
+
case AOP_DIR:
if (offset) {
- sprintf(s,"(%s + %d)",
- aop->aopu.aop_dir,
- offset);
- DEBUGpic16_emitcode(";","oops AOP_DIR did this %s\n",s);
+ sprintf(s,"(%s + %d)",
+ aop->aopu.aop_dir,
+ offset);
+ DEBUGpic16_emitcode(";","oops AOP_DIR did this %s\n",s);
} else
- sprintf(s,"%s",aop->aopu.aop_dir);
- rs = Safe_calloc(1,strlen(s)+1);
- strcpy(rs,s);
- return rs;
-
+ sprintf(s,"%s",aop->aopu.aop_dir);
+ rs = Safe_calloc(1,strlen(s)+1);
+ strcpy(rs,s);
+ return rs;
+
case AOP_REG:
return aop->aopu.aop_reg[offset]->name;
-
+
case AOP_CRY:
return aop->aopu.aop_dir;
-
+
case AOP_ACC:
DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d\toffset: %d",__LINE__, offset);
// fprintf(stderr, "%s:%d Warning -pic port ignoring get(AOP_ACC)\n",__FILE__, __LINE__);
// assert( 0 );
-// return aop->aopu.aop_str[offset]; //->"AOP_accumulator_bug";
- rs = Safe_strdup("WREG");
- return (rs);
+// return aop->aopu.aop_str[offset]; //->"AOP_accumulator_bug";
+ rs = Safe_strdup("WREG");
+ return (rs);
case AOP_LIT:
- sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset));
- rs = Safe_calloc(1,strlen(s)+1);
- strcpy(rs,s);
- return rs;
-
+ sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset));
+ rs = Safe_calloc(1,strlen(s)+1);
+ strcpy(rs,s);
+ return rs;
+
case AOP_STR:
- aop->coff = offset ;
+ aop->coff = offset ;
-// if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
-// dname)
-// return "acc";
+// if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
+// dname)
+// return "acc";
if(!strcmp(aop->aopu.aop_str[offset], "WREG")) {
aop->type = AOP_ACC;
return Safe_strdup("_WREG");
}
DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
-
- return aop->aopu.aop_str[offset];
-
+
+ return aop->aopu.aop_str[offset];
+
case AOP_PCODE:
{
- pCodeOp *pcop = aop->aopu.pcop;
- DEBUGpic16_emitcode(";","%d: pic16_aopGet AOP_PCODE type %s",__LINE__,pic16_pCodeOpType(pcop));
- if(pcop->name) {
- DEBUGpic16_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
- //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
- if (offset) {
- sprintf(s,"(%s + %d)", pic16_get_op (pcop, NULL, 0), offset);
- } else {
- sprintf(s,"%s", pic16_get_op (pcop, NULL, 0));
- }
- } else
- sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
+ pCodeOp *pcop = aop->aopu.pcop;
+ DEBUGpic16_emitcode(";","%d: pic16_aopGet AOP_PCODE type %s",__LINE__,pic16_pCodeOpType(pcop));
+ if(pcop->name) {
+ DEBUGpic16_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
+ //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
+ if (offset) {
+ sprintf(s,"(%s + %d)", pic16_get_op (pcop, NULL, 0), offset);
+ } else {
+ sprintf(s,"%s", pic16_get_op (pcop, NULL, 0));
+ }
+ } else
+ sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
}
rs = Safe_calloc(1,strlen(s)+1);
- strcpy(rs,s);
+ strcpy(rs,s);
return rs;
#if 0
case AOP_PAGED:
DEBUGpic16_emitcode(";","oops AOP_PAGED did this %s\n",s);
if (offset) {
- sprintf(s,"(%s + %d)",
- aop->aopu.aop_dir,
- offset);
+ sprintf(s,"(%s + %d)",
+ aop->aopu.aop_dir,
+ offset);
} else
- sprintf(s,"%s",aop->aopu.aop_dir);
+ sprintf(s,"%s",aop->aopu.aop_dir);
DEBUGpic16_emitcode(";","oops AOP_PAGED did this %s\n",s);
rs = Safe_calloc(1,strlen(s)+1);
- strcpy(rs,s);
+ strcpy(rs,s);
return rs;
#endif
case AOP_STA:
rs = Safe_strdup(PCOR(aop->aopu.stk.pop[offset])->r->name);
return (rs);
-
+
case AOP_STK:
// pCodeOp *pcop = aop->aop
- break;
+ break;
}
* lock=0 to allocate registers for stack use. lock=1 will emit a warning
* to inform the compiler developer about a possible bug. This is an internal
* feature for developing the compiler -- VR */
-
+
int _TempReg_lock = 0;
/*-----------------------------------------------------------------*/
/* pic16_popGetTempReg - create a new temporary pCodeOp */
if(_TempReg_lock) {
// werror(W_POSSBUG2, __FILE__, __LINE__);
}
-
+
_TempReg_lock += lock;
-
+
cfunc = currFunc;
currFunc = NULL;
#if 0
- {
- regs *rr;
- int i;
-
- /* this code might seem better but it does the *same* job with
- * the old code, it all depends on ralloc.c to get a free/unused
- * register */
-
- i=0;
- while(i < pic16_nRegs) {
- rr = pic16_typeRegWithIdx(i, REG_GPR, 0);
- fprintf(stderr, "%s:%d checking for TempReg Idx=%d rr=%p\n", __FILE__, __LINE__, i, rr);
- if((!rr || (rr && rr->isFree))
- && !bitVectBitValue(cfunc->regsUsed, i)) {
- pcop = pic16_newpCodeOpReg( i );
- PCOR(pcop)->r->wasUsed = 1;
- PCOR(pcop)->r->isFree = 0;
- break;
- }
- i++;
- }
-
- if(pcop) {
- pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) );
- }
- }
+ {
+ regs *rr;
+ int i;
+
+ /* this code might seem better but it does the *same* job with
+ * the old code, it all depends on ralloc.c to get a free/unused
+ * register */
+
+ i=0;
+ while(i < pic16_nRegs) {
+ rr = pic16_typeRegWithIdx(i, REG_GPR, 0);
+ fprintf(stderr, "%s:%d checking for TempReg Idx=%d rr=%p\n", __FILE__, __LINE__, i, rr);
+ if((!rr || (rr && rr->isFree))
+ && !bitVectBitValue(cfunc->regsUsed, i)) {
+ pcop = pic16_newpCodeOpReg( i );
+ PCOR(pcop)->r->wasUsed = 1;
+ PCOR(pcop)->r->isFree = 0;
+ break;
+ }
+ i++;
+ }
+
+ if(pcop) {
+ pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) );
+ }
+ }
#else
pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
/* bypass registers that are used by function */
if(!bitVectBitValue(f, i)) {
-
+
/* bypass registers that are already allocated for stack access */
if(!bitVectBitValue(v, i)) {
-
+
// debugf("getting register rIdx = %d\n", i);
/* ok, get the operand */
pcop = pic16_newpCodeOpReg( i );
-
+
/* should never by NULL */
assert( pcop != NULL );
-
+
/* sanity check */
if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
int found=0;
-
+
PCOR(pcop)->r->wasUsed=1;
PCOR(pcop)->r->isFree=0;
{
regs *sr;
-
+
for(sr=setFirstItem(_G.sregsAllocSet);sr;sr=setNextItem(_G.sregsAllocSet)) {
if(sr->rIdx == PCOR(pcop)->r->rIdx) {
/* already used in previous steps, break */
- found=1;
+ found=1;
break;
}
}
pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) );
addSet(&_G.sregsAllocSet, PCOR(pcop)->r);
}
-
+
break;
}
}
pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
memcpy (pcor, pc, sizeof (pCodeOpReg));
pcor->r->wasUsed = 1;
-
+
//pcor->pcop.type = pc->pcop.type;
if(pc->pcop.name) {
if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
/* make sure that register doesn't exist,
* and operand isn't NULL
* and symbol isn't in codespace (codespace symbols are handled elsewhere) */
- if((PCOR(pcop)->r == NULL)
+ if((PCOR(pcop)->r == NULL)
&& (op)
&& !IN_CODESPACE(SPEC_OCLS(OP_SYM_ETYPE(op)))) {
-// fprintf(stderr, "%s:%d - couldn't find %s in allocated regsters, size= %d ofs= %d\n",
-// __FUNCTION__, __LINE__, str, size, offset);
+// fprintf(stderr, "%s:%d - couldn't find %s in allocated regsters, size= %d ofs= %d\n",
+// __FUNCTION__, __LINE__, str, size, offset);
PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size, op);
//fprintf(stderr, "%s:%d: WARNING: need to allocate new register by name -> %s\n", __FILE__, __LINE__, str);
{
pCodeOp *pcop;
-// DEBUGpic16_emitcode ("; ***","%s,%d\trIdx=0x%x", __FUNCTION__,__LINE__,rIdx);
-// fprintf(stderr, "%s:%d rIdx = 0x%0x\n", __FUNCTION__, __LINE__, rIdx);
-
- pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
- PCOR(pcop)->rIdx = rIdx;
- PCOR(pcop)->r = pic16_regWithIdx(rIdx);
- if(!PCOR(pcop)->r)
- PCOR(pcop)->r = pic16_allocWithIdx(rIdx);
-
- PCOR(pcop)->r->isFree = 0;
- PCOR(pcop)->r->wasUsed = 1;
+// DEBUGpic16_emitcode ("; ***","%s,%d\trIdx=0x%x", __FUNCTION__,__LINE__,rIdx);
+// fprintf(stderr, "%s:%d rIdx = 0x%0x\n", __FUNCTION__, __LINE__, rIdx);
- pcop->type = PCOR(pcop)->r->pc_type;
+ pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
+ PCOR(pcop)->rIdx = rIdx;
+ PCOR(pcop)->r = pic16_regWithIdx(rIdx);
+ if(!PCOR(pcop)->r)
+ PCOR(pcop)->r = pic16_allocWithIdx(rIdx);
+
+ PCOR(pcop)->r->isFree = 0;
+ PCOR(pcop)->r->wasUsed = 1;
+
+ pcop->type = PCOR(pcop)->r->pc_type;
return pcop;
}
pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset)
{
pCodeOp2 *pcop2 = (pCodeOp2 *)pic16_newpCodeOp2(
- pic16_popGet(aop_src, offset), pic16_popGet(aop_dst, offset));
+ pic16_popGet(aop_src, offset), pic16_popGet(aop_dst, offset));
return PCOP(pcop2);
}
pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst, int noalloc)
{
pCodeOp2 *pcop2 = (pCodeOp2 *)pic16_newpCodeOp2(
- pic16_popCopyReg(src), pic16_popCopyReg(dst) );
+ pic16_popCopyReg(src), pic16_popCopyReg(dst) );
return PCOP(pcop2);
}
pCodeOp *pcop;
FENTRY2;
-
+
/* offset is greater than size then zero */
// if (offset > (aop->size - 1) &&
/* depending on type */
switch (aop->type) {
- case AOP_R0:
- case AOP_R1:
- case AOP_DPTR:
- case AOP_DPTR2:
- DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
- fprintf(stderr, ";8051 legacy %d type = %s\n",__LINE__,pic16_AopType(aop->type));
- assert( 0 );
- return NULL;
-
- case AOP_FSR0:
- case AOP_FSR2:
- pcop = Safe_calloc(1, sizeof(pCodeOpReg));
- PCOR(pcop)->rIdx = aop->aopu.aop_ptr->rIdx+2; /* access PLUSW register */
- PCOR(pcop)->r = pic16_regWithIdx( PCOR(pcop)->rIdx );
- PCOR(pcop)->r->wasUsed = 1;
- PCOR(pcop)->r->isFree = 0;
-
- PCOR(pcop)->instance = offset;
- pcop->type = PCOR(pcop)->r->pc_type;
- return (pcop);
-
- case AOP_IMMD:
- DEBUGpic16_emitcode(";","%d\tAOP_IMMD",__LINE__);
- return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
-
- case AOP_STA:
- /* pCodeOp is already allocated from aopForSym */
- DEBUGpic16_emitcode(";---", "%d getting stack + offset %d\n", __LINE__, offset);
- pcop = pic16_pCodeOpCopy(aop->aopu.stk.pop[offset]);
- return (pcop);
-
- case AOP_ACC:
- {
- int rIdx = IDX_WREG; //aop->aopu.aop_reg[offset]->rIdx;
-
- fprintf(stderr, "%s:%d returning register AOP_ACC %s\n", __FILE__, __LINE__, aop->aopu.aop_str[offset]);
-
- DEBUGpic16_emitcode(";","%d\tAOP_ACC", __LINE__);
-
- pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
- PCOR(pcop)->rIdx = rIdx;
- PCOR(pcop)->r = pic16_typeRegWithIdx(rIdx, REG_SFR, 1); // pic16_regWithIdx(rIdx);
- PCOR(pcop)->r->wasUsed=1;
- PCOR(pcop)->r->isFree=0;
-
- PCOR(pcop)->instance = offset;
- pcop->type = PCOR(pcop)->r->pc_type;
-// DEBUGpic16_emitcode(";","%d register idx = %d name =%s",__LINE__,rIdx,rs);
- return pcop;
-
-
-// return pic16_popRegFromString(aop->aopu.aop_str[offset], aop->size, offset);
+ case AOP_R0:
+ case AOP_R1:
+ case AOP_DPTR:
+ case AOP_DPTR2:
+ DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
+ fprintf(stderr, ";8051 legacy %d type = %s\n",__LINE__,pic16_AopType(aop->type));
+ assert( 0 );
+ return NULL;
+
+ case AOP_FSR0:
+ case AOP_FSR2:
+ pcop = Safe_calloc(1, sizeof(pCodeOpReg));
+ PCOR(pcop)->rIdx = aop->aopu.aop_ptr->rIdx+2; /* access PLUSW register */
+ PCOR(pcop)->r = pic16_regWithIdx( PCOR(pcop)->rIdx );
+ PCOR(pcop)->r->wasUsed = 1;
+ PCOR(pcop)->r->isFree = 0;
+
+ PCOR(pcop)->instance = offset;
+ pcop->type = PCOR(pcop)->r->pc_type;
+ return (pcop);
+
+ case AOP_IMMD:
+ DEBUGpic16_emitcode(";","%d\tAOP_IMMD",__LINE__);
+ return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
+
+ case AOP_STA:
+ /* pCodeOp is already allocated from aopForSym */
+ DEBUGpic16_emitcode(";---", "%d getting stack + offset %d\n", __LINE__, offset);
+ pcop = pic16_pCodeOpCopy(aop->aopu.stk.pop[offset]);
+ return (pcop);
+
+ case AOP_ACC:
+ {
+ int rIdx = IDX_WREG; //aop->aopu.aop_reg[offset]->rIdx;
+
+ fprintf(stderr, "%s:%d returning register AOP_ACC %s\n", __FILE__, __LINE__, aop->aopu.aop_str[offset]);
+
+ DEBUGpic16_emitcode(";","%d\tAOP_ACC", __LINE__);
+
+ pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
+ PCOR(pcop)->rIdx = rIdx;
+ PCOR(pcop)->r = pic16_typeRegWithIdx(rIdx, REG_SFR, 1); // pic16_regWithIdx(rIdx);
+ PCOR(pcop)->r->wasUsed=1;
+ PCOR(pcop)->r->isFree=0;
+
+ PCOR(pcop)->instance = offset;
+ pcop->type = PCOR(pcop)->r->pc_type;
+// DEBUGpic16_emitcode(";","%d register idx = %d name =%s",__LINE__,rIdx,rs);
+ return pcop;
+
+
+// return pic16_popRegFromString(aop->aopu.aop_str[offset], aop->size, offset);
// return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
-// assert( 0 );
- }
-
+// assert( 0 );
+ }
+
case AOP_DIR:
DEBUGpic16_emitcode(";","%d\tAOP_DIR (name = %s)", __LINE__, aop->aopu.aop_dir);
return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset, NULL);
-
+
#if 0
case AOP_PAGED:
DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__);
case AOP_REG:
{
- int rIdx;
-
-// debugf2("aop = %p\toffset = %d\n", aop, offset);
-// assert (aop && aop->aopu.aop_reg[offset] != NULL);
- rIdx = aop->aopu.aop_reg[offset]->rIdx;
-
- DEBUGpic16_emitcode(";","%d\tAOP_REG", __LINE__);
-
- pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
-// pcop->type = PO_GPR_REGISTER;
- PCOR(pcop)->rIdx = rIdx;
- PCOR(pcop)->r = pic16_allocWithIdx( rIdx ); //pic16_regWithIdx(rIdx);
- PCOR(pcop)->r->wasUsed=1;
- PCOR(pcop)->r->isFree=0;
-
- PCOR(pcop)->instance = offset;
- pcop->type = PCOR(pcop)->r->pc_type;
-
- DEBUGpic16_emitcode(";*+*", "%d\tAOP_REG type = %s", __LINE__, dumpPicOptype(pcop->type));
-// rs = aop->aopu.aop_reg[offset]->name;
-// DEBUGpic16_emitcode(";","%d register idx = %d name = %s",__LINE__,rIdx,rs);
- return pcop;
+ int rIdx;
+
+// debugf2("aop = %p\toffset = %d\n", aop, offset);
+// assert (aop && aop->aopu.aop_reg[offset] != NULL);
+ rIdx = aop->aopu.aop_reg[offset]->rIdx;
+
+ DEBUGpic16_emitcode(";","%d\tAOP_REG", __LINE__);
+
+ pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
+// pcop->type = PO_GPR_REGISTER;
+ PCOR(pcop)->rIdx = rIdx;
+ PCOR(pcop)->r = pic16_allocWithIdx( rIdx ); //pic16_regWithIdx(rIdx);
+ PCOR(pcop)->r->wasUsed=1;
+ PCOR(pcop)->r->isFree=0;
+
+ PCOR(pcop)->instance = offset;
+ pcop->type = PCOR(pcop)->r->pc_type;
+
+ DEBUGpic16_emitcode(";*+*", "%d\tAOP_REG type = %s", __LINE__, dumpPicOptype(pcop->type));
+// rs = aop->aopu.aop_reg[offset]->name;
+// DEBUGpic16_emitcode(";","%d register idx = %d name = %s",__LINE__,rIdx,rs);
+ return pcop;
}
case AOP_CRY:
- DEBUGpic16_emitcode(";","%d\tAOP_CRY", __LINE__);
+ DEBUGpic16_emitcode(";","%d\tAOP_CRY", __LINE__);
pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1, PO_GPR_REGISTER);
PCOR(pcop)->instance = offset;
//if(PCOR(pcop)->r == NULL)
//fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
return pcop;
-
+
case AOP_LIT:
- DEBUGpic16_emitcode(";","%d\tAOP_LIT", __LINE__);
+ DEBUGpic16_emitcode(";","%d\tAOP_LIT", __LINE__);
return pic16_newpCodeOpLit(pic16aopLiteral (aop->aopu.aop_lit,offset));
case AOP_STR:
case AOP_PCODE:
DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s offset %d",pic16_pCodeOpType(aop->aopu.pcop),
- __LINE__,
- ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"), offset);
+ __LINE__,
+ ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"), offset);
pcop = pic16_pCodeOpCopy(aop->aopu.pcop);
switch( aop->aopu.pcop->type ) {
case PO_DIR: PCOR(pcop)->instance += offset; break;
assert (offset==0);
break;
default:
- fprintf (stderr, "%s: unhandled aop->aopu.pcop->type %d\n", __FUNCTION__, aop->aopu.pcop->type);
- assert( 0 ); /* should never reach here */;
+ fprintf (stderr, "%s: unhandled aop->aopu.pcop->type %d\n", __FUNCTION__, aop->aopu.pcop->type);
+ assert( 0 ); /* should never reach here */;
}
return pcop;
}
switch (aop->type) {
case AOP_DIR:
if (offset) {
- sprintf(d,"(%s + %d)",
- aop->aopu.aop_dir,offset);
- fprintf(stderr,"oops pic16_aopPut:AOP_DIR did this %s\n",s);
+ sprintf(d,"(%s + %d)",
+ aop->aopu.aop_dir,offset);
+ fprintf(stderr,"oops pic16_aopPut:AOP_DIR did this %s\n",s);
} else
- sprintf(d,"%s",aop->aopu.aop_dir);
-
- if (strcmp(d,s)) {
- DEBUGpic16_emitcode(";","%d",__LINE__);
- if(strcmp(s,"W"))
- pic16_emitcode("movf","%s,w",s);
- pic16_emitcode("movwf","%s",d);
-
- if(strcmp(s,"W")) {
- pic16_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
- if(offset >= aop->size) {
- pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
- break;
- } else
- pic16_emitpcode(POC_MOVLW,pic16_popGetImmd(s,offset,0));
- }
-
- pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
-
-
- }
- break;
-
+ sprintf(d,"%s",aop->aopu.aop_dir);
+
+ if (strcmp(d,s)) {
+ DEBUGpic16_emitcode(";","%d",__LINE__);
+ if(strcmp(s,"W"))
+ pic16_emitcode("movf","%s,w",s);
+ pic16_emitcode("movwf","%s",d);
+
+ if(strcmp(s,"W")) {
+ pic16_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
+ if(offset >= aop->size) {
+ pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
+ break;
+ } else
+ pic16_emitpcode(POC_MOVLW,pic16_popGetImmd(s,offset,0));
+ }
+
+ pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
+
+
+ }
+ break;
+
case AOP_REG:
if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
- //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
- /*
- if (*s == '@' ||
- strcmp(s,"r0") == 0 ||
- strcmp(s,"r1") == 0 ||
- strcmp(s,"r2") == 0 ||
- strcmp(s,"r3") == 0 ||
- strcmp(s,"r4") == 0 ||
- strcmp(s,"r5") == 0 ||
- strcmp(s,"r6") == 0 ||
- strcmp(s,"r7") == 0 )
- pic16_emitcode("mov","%s,%s ; %d",
- aop->aopu.aop_reg[offset]->dname,s,__LINE__);
- else
- */
-
- if(strcmp(s,"W")==0 )
- pic16_emitcode("movf","%s,w ; %d",s,__LINE__);
-
- pic16_emitcode("movwf","%s",
- aop->aopu.aop_reg[offset]->name);
-
- if(strcmp(s,zero)==0) {
- pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
-
- } else if(strcmp(s,"W")==0) {
- pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
- pcop->type = PO_GPR_REGISTER;
-
- PCOR(pcop)->rIdx = -1;
- PCOR(pcop)->r = NULL;
-
- DEBUGpic16_emitcode(";","%d",__LINE__);
- pcop->name = Safe_strdup(s);
- pic16_emitpcode(POC_MOVFW,pcop);
- pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
- } else if(strcmp(s,one)==0) {
- pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
- pic16_emitpcode(POC_INCF,pic16_popGet(aop,offset));
- } else {
- pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
- }
- }
- break;
-
+ //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
+ /*
+ if (*s == '@' ||
+ strcmp(s,"r0") == 0 ||
+ strcmp(s,"r1") == 0 ||
+ strcmp(s,"r2") == 0 ||
+ strcmp(s,"r3") == 0 ||
+ strcmp(s,"r4") == 0 ||
+ strcmp(s,"r5") == 0 ||
+ strcmp(s,"r6") == 0 ||
+ strcmp(s,"r7") == 0 )
+ pic16_emitcode("mov","%s,%s ; %d",
+ aop->aopu.aop_reg[offset]->dname,s,__LINE__);
+ else
+ */
+
+ if(strcmp(s,"W")==0 )
+ pic16_emitcode("movf","%s,w ; %d",s,__LINE__);
+
+ pic16_emitcode("movwf","%s",
+ aop->aopu.aop_reg[offset]->name);
+
+ if(strcmp(s,zero)==0) {
+ pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
+
+ } else if(strcmp(s,"W")==0) {
+ pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
+ pcop->type = PO_GPR_REGISTER;
+
+ PCOR(pcop)->rIdx = -1;
+ PCOR(pcop)->r = NULL;
+
+ DEBUGpic16_emitcode(";","%d",__LINE__);
+ pcop->name = Safe_strdup(s);
+ pic16_emitpcode(POC_MOVFW,pcop);
+ pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
+ } else if(strcmp(s,one)==0) {
+ pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
+ pic16_emitpcode(POC_INCF,pic16_popGet(aop,offset));
+ } else {
+ pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
+ }
+ }
+ break;
+
case AOP_DPTR:
case AOP_DPTR2:
-
+
if (aop->type == AOP_DPTR2)
{
genSetDPTR(1);
}
-
- if (aop->code) {
- werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
- "pic16_aopPut writting to code space");
- exit(0);
- }
-
- while (offset > aop->coff) {
- aop->coff++;
- pic16_emitcode ("inc","dptr");
- }
-
- while (offset < aop->coff) {
- aop->coff-- ;
- pic16_emitcode("lcall","__decdptr");
- }
-
- aop->coff = offset;
-
- /* if not in accumulater */
- MOVA(s);
-
- pic16_emitcode ("movx","@dptr,a");
-
+
+ if (aop->code) {
+ werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
+ "pic16_aopPut writting to code space");
+ exit(0);
+ }
+
+ while (offset > aop->coff) {
+ aop->coff++;
+ pic16_emitcode ("inc","dptr");
+ }
+
+ while (offset < aop->coff) {
+ aop->coff-- ;
+ pic16_emitcode("lcall","__decdptr");
+ }
+
+ aop->coff = offset;
+
+ /* if not in accumulater */
+ MOVA(s);
+
+ pic16_emitcode ("movx","@dptr,a");
+
if (aop->type == AOP_DPTR2)
{
genSetDPTR(0);
}
- break;
-
+ break;
+
case AOP_R0:
case AOP_R1:
- while (offset > aop->coff) {
- aop->coff++;
- pic16_emitcode("inc","%s",aop->aopu.aop_ptr->name);
- }
- while (offset < aop->coff) {
- aop->coff-- ;
- pic16_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
- }
- aop->coff = offset;
-
- if (aop->paged) {
- MOVA(s);
- pic16_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
-
- } else
- if (*s == '@') {
- MOVA(s);
- pic16_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
- } else
- if (strcmp(s,"r0") == 0 ||
- strcmp(s,"r1") == 0 ||
- strcmp(s,"r2") == 0 ||
- strcmp(s,"r3") == 0 ||
- strcmp(s,"r4") == 0 ||
- strcmp(s,"r5") == 0 ||
- strcmp(s,"r6") == 0 ||
- strcmp(s,"r7") == 0 ) {
- char buffer[10];
- sprintf(buffer,"a%s",s);
- pic16_emitcode("mov","@%s,%s",
- aop->aopu.aop_ptr->name,buffer);
- } else
- pic16_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
-
- break;
-
+ while (offset > aop->coff) {
+ aop->coff++;
+ pic16_emitcode("inc","%s",aop->aopu.aop_ptr->name);
+ }
+ while (offset < aop->coff) {
+ aop->coff-- ;
+ pic16_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
+ }
+ aop->coff = offset;
+
+ if (aop->paged) {
+ MOVA(s);
+ pic16_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
+
+ } else
+ if (*s == '@') {
+ MOVA(s);
+ pic16_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
+ } else
+ if (strcmp(s,"r0") == 0 ||
+ strcmp(s,"r1") == 0 ||
+ strcmp(s,"r2") == 0 ||
+ strcmp(s,"r3") == 0 ||
+ strcmp(s,"r4") == 0 ||
+ strcmp(s,"r5") == 0 ||
+ strcmp(s,"r6") == 0 ||
+ strcmp(s,"r7") == 0 ) {
+ char buffer[10];
+ sprintf(buffer,"a%s",s);
+ pic16_emitcode("mov","@%s,%s",
+ aop->aopu.aop_ptr->name,buffer);
+ } else
+ pic16_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
+
+ break;
+
case AOP_STK:
- if (strcmp(s,"a") == 0)
- pic16_emitcode("push","acc");
- else
- pic16_emitcode("push","%s",s);
-
- break;
-
+ if (strcmp(s,"a") == 0)
+ pic16_emitcode("push","acc");
+ else
+ pic16_emitcode("push","%s",s);
+
+ break;
+
case AOP_CRY:
- /* if bit variable */
- if (!aop->aopu.aop_dir) {
- pic16_emitcode("clr","a");
- pic16_emitcode("rlc","a");
- } else {
- if (s == zero)
- pic16_emitcode("clr","%s",aop->aopu.aop_dir);
- else
- if (s == one)
- pic16_emitcode("setb","%s",aop->aopu.aop_dir);
- else
- if (!strcmp(s,"c"))
- pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
- else {
- lbl = newiTempLabel(NULL);
-
- if (strcmp(s,"a")) {
- MOVA(s);
- }
- pic16_emitcode("clr","c");
- pic16_emitcode("jz","%05d_DS_",lbl->key+100);
- pic16_emitcode("cpl","c");
- pic16_emitcode("","%05d_DS_:",lbl->key+100);
- pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
- }
- }
- break;
-
+ /* if bit variable */
+ if (!aop->aopu.aop_dir) {
+ pic16_emitcode("clr","a");
+ pic16_emitcode("rlc","a");
+ } else {
+ if (s == zero)
+ pic16_emitcode("clr","%s",aop->aopu.aop_dir);
+ else
+ if (s == one)
+ pic16_emitcode("setb","%s",aop->aopu.aop_dir);
+ else
+ if (!strcmp(s,"c"))
+ pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
+ else {
+ lbl = newiTempLabel(NULL);
+
+ if (strcmp(s,"a")) {
+ MOVA(s);
+ }
+ pic16_emitcode("clr","c");
+ pic16_emitcode("jz","%05d_DS_",lbl->key+100);
+ pic16_emitcode("cpl","c");
+ pic16_emitcode("","%05d_DS_:",lbl->key+100);
+ pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
+ }
+ }
+ break;
+
case AOP_STR:
- aop->coff = offset;
- if (strcmp(aop->aopu.aop_str[offset],s))
- pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
- break;
-
+ aop->coff = offset;
+ if (strcmp(aop->aopu.aop_str[offset],s))
+ pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
+ break;
+
case AOP_ACC:
- aop->coff = offset;
- if (!offset && (strcmp(s,"acc") == 0))
- break;
-
- if (strcmp(aop->aopu.aop_str[offset],s))
- pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
- break;
+ aop->coff = offset;
+ if (!offset && (strcmp(s,"acc") == 0))
+ break;
+
+ if (strcmp(aop->aopu.aop_str[offset],s))
+ pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
+ break;
default :
fprintf(stderr, "%s:%d: unknown aop->type = 0x%x\n", __FILE__, __LINE__, aop->type);
-// werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
-// "pic16_aopPut got unsupported aop->type");
-// exit(0);
- }
+// werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
+// "pic16_aopPut got unsupported aop->type");
+// exit(0);
+ }
}
void pic16_testStackOverflow(void)
{
-#define GSTACK_TEST_NAME "_gstack_test"
+#define GSTACK_TEST_NAME "_gstack_test"
pic16_emitpcode(POC_CALL, pic16_popGetWithString( GSTACK_TEST_NAME ));
-
+
{
symbol *sym;
/* push pcop into stack */
void pic16_pushpCodeOp(pCodeOp *pcop)
{
-// DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+// DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if (pcop->type == PO_LITERAL) {
pic16_emitpcode(POC_MOVLW, pcop);
pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postdec ));
}
if(pic16_options.gstack)
pic16_testStackOverflow();
-
+
}
/* pop pcop from stack */
pic16_testStackOverflow();
}
-
+
/*-----------------------------------------------------------------*/
/* pushaop - pushes aop to stack */
/*-----------------------------------------------------------------*/
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if(_G.resDirect)return;
-
+
if(is_LitAOp(aop)) {
pic16_emitpcode(POC_MOVLW, pic16_popGet(aop, offset));
pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postdec ));
case AOP_R1 :
while (size--)
pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
- break;
+ break;
case AOP_DPTR :
case AOP_DPTR2:
if (aop->type == AOP_DPTR2)
- {
+ {
genSetDPTR(1);
- }
+ }
while (size--)
{
pic16_emitcode("lcall","__decdptr");
}
-
- if (aop->type == AOP_DPTR2)
- {
+
+ if (aop->type == AOP_DPTR2)
+ {
genSetDPTR(0);
- }
- break;
+ }
+ break;
- }
+ }
}
#endif
#if 0
/*-----------------------------------------------------------------*/
-/* opIsGptr: returns non-zero if the passed operand is */
-/* a generic pointer type. */
-/*-----------------------------------------------------------------*/
+/* opIsGptr: returns non-zero if the passed operand is */
+/* a generic pointer type. */
+/*-----------------------------------------------------------------*/
static int opIsGptr(operand *op)
{
sym_link *type = operandType(op);
-
+
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
{
return 1;
}
- return 0;
+ return 0;
}
#endif
/* if the result is bit */
if (AOP_TYPE(result) == AOP_CRY) {
- fprintf(stderr, "%s:%d: pic16 port warning: unsupported case\n", __FILE__, __LINE__);
+ fprintf(stderr, "%s:%d: pic16 port warning: unsupported case\n", __FILE__, __LINE__);
pic16_aopPut(AOP(result),"c",0);
} else {
- i = AOP_SIZE(result);
- while(i--) {
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
- }
- pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result), 0));
+ i = AOP_SIZE(result);
+ while(i--) {
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
+ }
+ pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result), 0));
}
}
/* if the result is bit */
if (AOP_TYPE(result) == AOP_CRY) {
- fprintf(stderr, "%s:%d: pic16 port warning: unsupported case\n", __FILE__, __LINE__);
+ fprintf(stderr, "%s:%d: pic16 port warning: unsupported case\n", __FILE__, __LINE__);
pic16_aopPut(AOP(result),"c",0);
} else {
- i = AOP_SIZE(result);
- while(i--) {
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
- }
- pic16_emitpcode(POC_RRCF, pcop);
- pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result), 0));
+ i = AOP_SIZE(result);
+ while(i--) {
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i));
+ }
+ pic16_emitpcode(POC_RRCF, pcop);
+ pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result), 0));
}
}
static void genUminusFloat(operand *op,operand *result)
{
int size ,offset =0 ;
-
+
FENTRY;
- /* for this we just need to flip the
+ /* for this we just need to flip the
first it then copy the rest in place */
size = AOP_SIZE(op);
assert( size == AOP_SIZE(result) );
pic16_mov2f(AOP(result), AOP(op), offset);
offset++;
}
-
+
/* toggle the MSB's highest bit */
pic16_emitpcode(POC_BTG, pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), offset-1), 7));
}
symbol *label;
int needLabel=0;
- FENTRY;
-
+ FENTRY;
+
/* assign asmops */
pic16_aopOp(IC_LEFT(ic),ic,FALSE);
pic16_aopOp(IC_RESULT(ic),ic,TRUE);
/* if both in bit space then special case */
if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY
- && AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
-
+ && AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
+
pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0));
pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
- goto release;
- }
+ goto release;
+ }
optype = operandType(IC_LEFT(ic));
rtype = operandType(IC_RESULT(ic));
if (IS_FLOAT(optype) || IS_FIXED(optype)) {
if(IS_FIXED(optype))
debugf("implement fixed16x16 type\n", 0);
-
- genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
- goto release;
+
+ genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
+ goto release;
}
/* otherwise subtract from zero by taking the 2's complement */
size = AOP_SIZE(IC_LEFT(ic));
assert( size == AOP_SIZE(IC_RESULT(ic)) );
label = newiTempLabel ( NULL );
-
+
if (pic16_sameRegs (AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
for (i=size-1; i > 0; i--) {
pic16_emitpcode (POC_COMF, pic16_popGet (AOP(IC_LEFT(ic)), i));
} else {
for (i=size-1; i >= 0; i--) {
pic16_emitpcode (POC_COMFW, pic16_popGet (AOP(IC_LEFT(ic)), i));
- pic16_emitpcode (POC_MOVWF, pic16_popGet (AOP(IC_RESULT(ic)), i));
+ pic16_emitpcode (POC_MOVWF, pic16_popGet (AOP(IC_RESULT(ic)), i));
} // for
if (size > 1) {
for (i=0; i < size-2; i++) {
pic16_emitpcode (POC_INCF, pic16_popGet (AOP(IC_RESULT(ic)),i));
pic16_emitpcode (POC_BNZ, pic16_popGetLabel (label->key)); needLabel++;
- } // for
+ } // for
pic16_emitpcode (POC_INFSNZ, pic16_popGet (AOP(IC_RESULT(ic)), size-2));
} // if
pic16_emitpcode (POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)), size-1));
release:
/* release the aops */
pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
- pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
+ pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
}
#if 0
/*-----------------------------------------------------------------*/
/* saveRegisters - will look for a call and save the registers */
/*-----------------------------------------------------------------*/
-static void saveRegisters(iCode *lic)
+static void saveRegisters(iCode *lic)
{
int i;
iCode *ic;
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
/* look for call */
- for (ic = lic ; ic ; ic = ic->next)
+ for (ic = lic ; ic ; ic = ic->next)
if (ic->op == CALL || ic->op == PCALL)
break;
if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
return ;
- /* find the registers in use at this time
+ /* find the registers in use at this time
and push them away to safety */
rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
ic->rUsed);
ic->regsSaved = 1;
if (options.useXstack) {
- if (bitVectBitValue(rsave,R0_IDX))
- pic16_emitcode("mov","b,r0");
- pic16_emitcode("mov","r0,%s",spname);
- for (i = 0 ; i < pic16_nRegs ; i++) {
- if (bitVectBitValue(rsave,i)) {
- if (i == R0_IDX)
- pic16_emitcode("mov","a,b");
- else
- pic16_emitcode("mov","a,%s",pic16_regWithIdx(i)->name);
- pic16_emitcode("movx","@r0,a");
- pic16_emitcode("inc","r0");
- }
- }
- pic16_emitcode("mov","%s,r0",spname);
- if (bitVectBitValue(rsave,R0_IDX))
- pic16_emitcode("mov","r0,b");
+ if (bitVectBitValue(rsave,R0_IDX))
+ pic16_emitcode("mov","b,r0");
+ pic16_emitcode("mov","r0,%s",spname);
+ for (i = 0 ; i < pic16_nRegs ; i++) {
+ if (bitVectBitValue(rsave,i)) {
+ if (i == R0_IDX)
+ pic16_emitcode("mov","a,b");
+ else
+ pic16_emitcode("mov","a,%s",pic16_regWithIdx(i)->name);
+ pic16_emitcode("movx","@r0,a");
+ pic16_emitcode("inc","r0");
+ }
+ }
+ pic16_emitcode("mov","%s,r0",spname);
+ if (bitVectBitValue(rsave,R0_IDX))
+ pic16_emitcode("mov","r0,b");
}// else
//for (i = 0 ; i < pic16_nRegs ; i++) {
// if (bitVectBitValue(rsave,i))
- // pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
+ // pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
//}
dtype = operandType(IC_LEFT(ic));
- if (currFunc && dtype &&
+ if (currFunc && dtype &&
(FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
- IFFUNC_ISISR(currFunc->type) &&
- !ic->bankSaved)
+ IFFUNC_ISISR(currFunc->type) &&
+ !ic->bankSaved)
saverbank(FUNC_REGBANK(dtype),ic,TRUE);
bitVect *rsave;
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- /* find the registers in use at this time
+ /* find the registers in use at this time
and push them away to safety */
rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
ic->rUsed);
-
+
if (options.useXstack) {
- pic16_emitcode("mov","r0,%s",spname);
- for (i = pic16_nRegs ; i >= 0 ; i--) {
- if (bitVectBitValue(rsave,i)) {
- pic16_emitcode("dec","r0");
- pic16_emitcode("movx","a,@r0");
- if (i == R0_IDX)
- pic16_emitcode("mov","b,a");
- else
- pic16_emitcode("mov","%s,a",pic16_regWithIdx(i)->name);
- }
-
- }
- pic16_emitcode("mov","%s,r0",spname);
- if (bitVectBitValue(rsave,R0_IDX))
- pic16_emitcode("mov","r0,b");
+ pic16_emitcode("mov","r0,%s",spname);
+ for (i = pic16_nRegs ; i >= 0 ; i--) {
+ if (bitVectBitValue(rsave,i)) {
+ pic16_emitcode("dec","r0");
+ pic16_emitcode("movx","a,@r0");
+ if (i == R0_IDX)
+ pic16_emitcode("mov","b,a");
+ else
+ pic16_emitcode("mov","%s,a",pic16_regWithIdx(i)->name);
+ }
+
+ }
+ pic16_emitcode("mov","%s,r0",spname);
+ if (bitVectBitValue(rsave,R0_IDX))
+ pic16_emitcode("mov","r0,b");
} //else
//for (i = pic16_nRegs ; i >= 0 ; i--) {
// if (bitVectBitValue(rsave,i))
- // pic16_emitcode("pop","%s",pic16_regWithIdx(i)->dname);
+ // pic16_emitcode("pop","%s",pic16_regWithIdx(i)->dname);
//}
-}
+}
#endif
#if 0 // patch 14
/*-----------------------------------------------------------------*/
-/* pushSide - */
+/* pushSide - */
/*-----------------------------------------------------------------*/
static void pushSide(operand * oper, int size)
{
- int offset = 0;
+ int offset = 0;
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- while (size--) {
- char *l = pic16_aopGet(AOP(oper),offset++,FALSE,TRUE);
- if (AOP_TYPE(oper) != AOP_REG &&
- AOP_TYPE(oper) != AOP_DIR &&
- strcmp(l,"a") ) {
- pic16_emitcode("mov","a,%s",l);
- pic16_emitcode("push","acc");
- } else
- pic16_emitcode("push","%s",l);
- }
+ while (size--) {
+ char *l = pic16_aopGet(AOP(oper),offset++,FALSE,TRUE);
+ if (AOP_TYPE(oper) != AOP_REG &&
+ AOP_TYPE(oper) != AOP_DIR &&
+ strcmp(l,"a") ) {
+ pic16_emitcode("mov","a,%s",l);
+ pic16_emitcode("push","acc");
+ } else
+ pic16_emitcode("push","%s",l);
+ }
}
#endif // patch 14
{
int size = AOP_SIZE(oper);
int offset=0;
-
+
FENTRY2;
// DEBUGpic16_emitcode ("; ***","%s %d rescall:%d size:%d",__FUNCTION__,__LINE__,rescall,size); // patch 14
DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
if(rescall) {
/* assign result from a call/pcall function() */
-
+
/* function results are stored in a special order,
* see top of file with Function return policy, or manual */
if(size <= 4) {
/* 8-bits, result in WREG */
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper), 0));
-
+
if(size > 1 && res_size > 1) {
- /* 16-bits, result in PRODL:WREG */
- pic16_loadFromReturn(oper, 1, pic16_popCopyReg(&pic16_pc_prodl));
- }
-
- if(size > 2 && res_size > 2) {
- /* 24-bits, result in PRODH:PRODL:WREG */
- pic16_loadFromReturn(oper, 2, pic16_popCopyReg(&pic16_pc_prodh)); // patch 14
- }
-
- if(size > 3 && res_size > 3) {
- /* 32-bits, result in FSR0L:PRODH:PRODL:WREG */
- pic16_loadFromReturn(oper, 3, pic16_popCopyReg(&pic16_pc_fsr0l)); // patch14
- }
-
- pic16_addSign(oper, res_size, IS_UNSIGNED(operandType(oper)));
-
+ /* 16-bits, result in PRODL:WREG */
+ pic16_loadFromReturn(oper, 1, pic16_popCopyReg(&pic16_pc_prodl));
+ }
+
+ if(size > 2 && res_size > 2) {
+ /* 24-bits, result in PRODH:PRODL:WREG */
+ pic16_loadFromReturn(oper, 2, pic16_popCopyReg(&pic16_pc_prodh)); // patch 14
+ }
+
+ if(size > 3 && res_size > 3) {
+ /* 32-bits, result in FSR0L:PRODH:PRODL:WREG */
+ pic16_loadFromReturn(oper, 3, pic16_popCopyReg(&pic16_pc_fsr0l)); // patch14
+ }
+
+ pic16_addSign(oper, res_size, IS_UNSIGNED(operandType(oper)));
+
} else {
/* >32-bits, result on stack, and FSR0 points to beginning.
- * Fix stack when done */
- /* FIXME FIXME */
-// debugf("WARNING: Possible bug when returning more than 4-bytes\n");
- while (size--) {
-// DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
+ * Fix stack when done */
+ /* FIXME FIXME */
+// debugf("WARNING: Possible bug when returning more than 4-bytes\n");
+ while (size--) {
+// DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
// DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
-
+
popaopidx(AOP(oper), size, GpsuedoStkPtr);
GpsuedoStkPtr++;
- }
-
- /* fix stack */
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit( AOP_SIZE(oper) ));
- pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( pic16_stackpnt_lo )); //&pic16_pc_fsr1l ));
- if(STACK_MODEL_LARGE) {
- emitSKPNC;
- pic16_emitpcode(POC_INCF, pic16_popCopyReg( pic16_stackpnt_hi )); //&pic16_pc_fsr1h ));
- }
- }
+ }
+
+ /* fix stack */
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit( AOP_SIZE(oper) ));
+ pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( pic16_stackpnt_lo )); //&pic16_pc_fsr1l ));
+ if(STACK_MODEL_LARGE) {
+ emitSKPNC;
+ pic16_emitpcode(POC_INCF, pic16_popCopyReg( pic16_stackpnt_hi )); //&pic16_pc_fsr1h ));
+ }
+ }
} else {
- int areg = 0; /* matching argument register */
-
+ int areg = 0; /* matching argument register */
+
// debugf("_G.useWreg = %d\tGpsuedoStkPtr = %d\n", _G.useWreg, GpsuedoStkPtr);
areg = SPEC_ARGREG( OP_SYM_ETYPE( oper ) ) - 1;
/* its called from genReceive (probably) -- VR */
- /* I hope this code will not be called from somewhere else in the future!
+ /* I hope this code will not be called from somewhere else in the future!
* We manually set the pseudo stack pointer in genReceive. - dw
*/
if(!GpsuedoStkPtr && _G.useWreg) {
offset++;
// debugf("receive from WREG\n", 0);
}
- GpsuedoStkPtr++; /* otherwise the calculation below fails (-_G.useWreg) */
+ GpsuedoStkPtr++; /* otherwise the calculation below fails (-_G.useWreg) */
}
// GpsuedoStkPtr++;
_G.stack_lat = AOP_SIZE(oper)-1;
pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
}
-
+
#if 0
int size, offset = 0 ;
char *l;
- /* if this is not a parm push : ie. it is spill push
+ /* if this is not a parm push : ie. it is spill push
and spill push is always done on the local stack */
if (!ic->parmPush) {
}
pic16_emitcode("push","%s",l);
}
- return ;
+ return ;
}
pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
pic16_aopOp(IC_LEFT(ic),ic,FALSE);
size = AOP_SIZE(IC_LEFT(ic));
offset = (size-1);
- while (size--)
+ while (size--)
pic16_emitcode("pop","%s",pic16_aopGet(AOP(IC_LEFT(ic)),offset--,
FALSE,TRUE));
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if (popPsw) {
- if (options.useXstack) {
- aop = newAsmop(0);
- r = getFreePtr(ic,&aop,FALSE);
-
-
- pic16_emitcode("mov","%s,_spx",r->name);
- pic16_emitcode("movx","a,@%s",r->name);
- pic16_emitcode("mov","psw,a");
- pic16_emitcode("dec","%s",r->name);
-
- }else
- pic16_emitcode ("pop","psw");
+ if (options.useXstack) {
+ aop = newAsmop(0);
+ r = getFreePtr(ic,&aop,FALSE);
+
+
+ pic16_emitcode("mov","%s,_spx",r->name);
+ pic16_emitcode("movx","a,@%s",r->name);
+ pic16_emitcode("mov","psw,a");
+ pic16_emitcode("dec","%s",r->name);
+
+ }else
+ pic16_emitcode ("pop","psw");
}
for (i = (pic16_nRegs - 1) ; i >= 0 ;i--) {
- if (options.useXstack) {
+ if (options.useXstack) {
pic16_emitcode("movx","a,@%s",r->name);
//pic16_emitcode("mov","(%s+%d),a",
- // regspic16[i].base,8*bank+regspic16[i].offset);
+ // regspic16[i].base,8*bank+regspic16[i].offset);
pic16_emitcode("dec","%s",r->name);
- } else
- pic16_emitcode("pop",""); //"(%s+%d)",
- //regspic16[i].base,8*bank); //+regspic16[i].offset);
+ } else
+ pic16_emitcode("pop",""); //"(%s+%d)",
+ //regspic16[i].base,8*bank); //+regspic16[i].offset);
}
if (options.useXstack) {
- pic16_emitcode("mov","_spx,%s",r->name);
- pic16_freeAsmop(NULL,aop,ic,TRUE);
+ pic16_emitcode("mov","_spx,%s",r->name);
+ pic16_freeAsmop(NULL,aop,ic,TRUE);
}
-#endif
+#endif
}
/*-----------------------------------------------------------------*/
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if (options.useXstack) {
- aop = newAsmop(0);
- r = getFreePtr(ic,&aop,FALSE);
- pic16_emitcode("mov","%s,_spx",r->name);
+ aop = newAsmop(0);
+ r = getFreePtr(ic,&aop,FALSE);
+ pic16_emitcode("mov","%s,_spx",r->name);
}
pic16_emitcode("inc","%s",r->name);
//pic16_emitcode("mov","a,(%s+%d)",
// regspic16[i].base,8*bank+regspic16[i].offset);
- pic16_emitcode("movx","@%s,a",r->name);
- } else
- pic16_emitcode("push","");// "(%s+%d)",
+ pic16_emitcode("movx","@%s,a",r->name);
+ } else
+ pic16_emitcode("push","");// "(%s+%d)",
//regspic16[i].base,8*bank+regspic16[i].offset);
}
-
+
if (pushPsw) {
- if (options.useXstack) {
- pic16_emitcode("mov","a,psw");
- pic16_emitcode("movx","@%s,a",r->name);
- pic16_emitcode("inc","%s",r->name);
- pic16_emitcode("mov","_spx,%s",r->name);
- pic16_freeAsmop (NULL,aop,ic,TRUE);
-
- } else
- pic16_emitcode("push","psw");
-
- pic16_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
+ if (options.useXstack) {
+ pic16_emitcode("mov","a,psw");
+ pic16_emitcode("movx","@%s,a",r->name);
+ pic16_emitcode("inc","%s",r->name);
+ pic16_emitcode("mov","_spx,%s",r->name);
+ pic16_freeAsmop (NULL,aop,ic,TRUE);
+
+ } else
+ pic16_emitcode("push","psw");
+
+ pic16_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
}
ic->bankSaved = 1;
#endif
}
-#endif /* 0 */
+#endif /* 0 */
static int wparamCmp(void *p1, void *p2)
int inWparamList(char *s)
{
return isinSetWith(wparamList, s, wparamCmp);
-}
+}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static void genCall (iCode *ic)
{
- sym_link *ftype;
+ sym_link *ftype;
int stackParms=0;
int use_wreg=0;
int inwparam=0;
char *fname;
-
+
FENTRY;
ftype = OP_SYM_TYPE(IC_LEFT(ic));
// if (!ic->regsSaved)
// saveRegisters(ic);
- /* initialise stackParms for IPUSH pushes */
-// stackParms = psuedoStkPtr;
-// fprintf(stderr, "%s:%d ic parmBytes = %d\n", __FILE__, __LINE__, ic->parmBytes);
+ /* initialise stackParms for IPUSH pushes */
+// stackParms = psuedoStkPtr;
+// fprintf(stderr, "%s:%d ic parmBytes = %d\n", __FILE__, __LINE__, ic->parmBytes);
fname = OP_SYMBOL(IC_LEFT(ic))->rname[0]?OP_SYMBOL(IC_LEFT(ic))->rname:OP_SYMBOL(IC_LEFT(ic))->name;
inwparam = (inWparamList(OP_SYMBOL(IC_LEFT(ic))->name)) || (FUNC_ISWPARAM(OP_SYM_TYPE(IC_LEFT(ic))));
/* if send set is not empty the assign */
if (_G.sendSet) {
iCode *sic;
- int psuedoStkPtr=-1;
+ int psuedoStkPtr=-1;
int firstTimeThruLoop = 1;
if(!IFFUNC_ISREENT(ftype))
_G.sendSet = reverseSet(_G.sendSet);
- /* First figure how many parameters are getting passed */
+ /* First figure how many parameters are getting passed */
stackParms = 0;
use_wreg = 0;
-
+
for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
int size;
// int offset = 0;
* passed in W. */
pushw();
-// --psuedoStkPtr; // sanity check
+// --psuedoStkPtr; // sanity check
use_wreg = 1;
}
-
+
firstTimeThruLoop=0;
pic16_mov2w (AOP(IC_LEFT(sic)), size);
DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
// pushaop(AOP(IC_LEFT(sic)), size);
- pic16_mov2w( AOP(IC_LEFT(sic)), size );
-
+ pic16_mov2w( AOP(IC_LEFT(sic)), size );
+
if(!_G.resDirect)
pushw();
}
if(inwparam) {
if(IFFUNC_HASVARARGS(ftype) || IFFUNC_ISREENT(ftype)) {
- pushw(); /* save last parameter to stack if functions has varargs */
+ pushw(); /* save last parameter to stack if functions has varargs */
use_wreg = 0;
} else
use_wreg = 1;
pic16_emitpcode(POC_CALL,pic16_popGetWithString(fname));
GpsuedoStkPtr=0;
-
+
/* if we need to assign a result value */
if ((IS_ITEMP(IC_RESULT(ic))
&& (OP_SYMBOL(IC_RESULT(ic))->nRegs
DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
-
+
pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
}
if(!stackParms && ic->parmBytes) {
stackParms = ic->parmBytes;
}
-
+
stackParms -= use_wreg;
-
+
if(stackParms>0) {
if(stackParms == 1) {
- pic16_emitpcode(POC_INCF, pic16_popCopyReg(pic16_stackpnt_lo )); //&pic16_pc_fsr1l));
+ pic16_emitpcode(POC_INCF, pic16_popCopyReg(pic16_stackpnt_lo )); //&pic16_pc_fsr1l));
} else {
pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
- pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( pic16_stackpnt_lo )); //&pic16_pc_fsr1l ));
+ pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( pic16_stackpnt_lo )); //&pic16_pc_fsr1l ));
}
if(STACK_MODEL_LARGE) {
emitSKPNC;
- pic16_emitpcode(POC_INCF, pic16_popCopyReg( pic16_stackpnt_hi )); //&pic16_pc_fsr1h ));
+ pic16_emitpcode(POC_INCF, pic16_popCopyReg( pic16_stackpnt_hi )); //&pic16_pc_fsr1h ));
}
}
int stackParms=0;
symbol *retlbl = newiTempLabel(NULL);
pCodeOp *pcop_lbl = pic16_popGetLabel(retlbl->key);
-
+
FENTRY;
fntype = operandType( IC_LEFT(ic) )->next;
/* if send set is not empty the assign */
if (_G.sendSet) {
iCode *sic;
- int psuedoStkPtr=-1;
+ int psuedoStkPtr=-1;
/* reverse sendSet if function is not reentrant */
if(!IFFUNC_ISREENT(fntype))
_G.sendSet = reverseSet(_G.sendSet);
stackParms = 0;
-
+
for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
int size;
DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
-
+
pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
}
// stackParms -= use_wreg;
-
+
if(stackParms>0) {
pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( pic16_stackpnt_lo ));
if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
symbol *sym = OP_SYMBOL(IC_RESULT(ic));
- if (sym->remat && !POINTER_SET(ic))
+ if (sym->remat && !POINTER_SET(ic))
return 1;
}
{
DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
int i =0;
-
+
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if (options.excludeRegs[i] &&
STRCASECMP(options.excludeRegs[i],"none") == 0)
- return FALSE ;
+ return FALSE ;
for ( i = 0 ; options.excludeRegs[i]; i++) {
- if (options.excludeRegs[i] &&
+ if (options.excludeRegs[i] &&
STRCASECMP(s,options.excludeRegs[i]) == 0)
- return TRUE;
+ return TRUE;
}
return FALSE ;
}
{
symbol *sym;
sym_link *ftype;
-
+
FENTRY;
DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,pic16_labelOffset,max_key);
max_key=0;
GpsuedoStkPtr=0;
_G.nRegsSaved = 0;
-
+
ftype = operandType(IC_LEFT(ic));
sym = OP_SYMBOL(IC_LEFT(ic));
sprintf(asymname, "ivec_%s", sym->name);
else
sprintf(asymname, "ivec_0x%x_%s", FUNC_INTNO(sym->type), sym->name);
-
+
/* when an interrupt is declared as naked, do not emit the special
* wrapper segment at vector address. The user should take care for
* this instead. -- VR */
pic16_addpCode2pBlock(apb, pic16_newpCodeFunction(moduleName, asym->name));
//pic16_addpCode2pBlock(apb, pic16_newpCode(POC_GOTO, pic16_popGetWithString( sym->rname )));
//pic16_addpCode2pBlock(apb, pic16_newpCode(POC_GOTO, pic16_newpCodeOpLabel (sym->rname, 0)));
- pic16_addpCode2pBlock(apb, pic16_newpCodeAsmDir ("GOTO", "%s", sym->rname)); /* this suppresses a warning in LinkFlow */
-
+ pic16_addpCode2pBlock(apb, pic16_newpCodeAsmDir ("GOTO", "%s", sym->rname)); /* this suppresses a warning in LinkFlow */
+
/* mark the end of this tiny function */
pic16_addpCode2pBlock(apb,pic16_newpCodeFunction(NULL,NULL));
} else {
sprintf(asymname, "%s", sym->rname);
}
- {
- absSym *abSym;
+ {
+ absSym *abSym;
- abSym = Safe_calloc(1, sizeof(absSym));
- strcpy(abSym->name, asymname);
+ abSym = Safe_calloc(1, sizeof(absSym));
+ strcpy(abSym->name, asymname);
- switch( FUNC_INTNO(sym->type) ) {
- case 0: abSym->address = 0x000000; break;
+ switch( FUNC_INTNO(sym->type) ) {
+ case 0: abSym->address = 0x000000; break;
case 1: abSym->address = 0x000008; break;
case 2: abSym->address = 0x000018; break;
-
+
default:
// fprintf(stderr, "no interrupt number is given\n");
abSym->address = -1; break;
DEBUGpic16_emitcode("; ***", "_naked function, no prologue");
return;
}
-
+
/* if critical function then turn interrupts off */
if (IFFUNC_ISCRITICAL(ftype)) {
//pic16_emitcode("clr","ea");
}
- currFunc = sym; /* update the currFunc symbol */
+ currFunc = sym; /* update the currFunc symbol */
_G.fregsUsed = sym->regsUsed;
_G.sregsAlloc = newBitVect(128);
-
+
/* if this is an interrupt service routine then
* save wreg, status, bsr, prodl, prodh, fsr0l, fsr0h */
if (IFFUNC_ISISR(sym->type)) {
- _G.usefastretfie = 1; /* use shadow registers by default */
-
+ _G.usefastretfie = 1; /* use shadow registers by default */
+
/* an ISR should save: WREG, STATUS, BSR, PRODL, PRODH, FSR0L, FSR0H */
if(!FUNC_ISSHADOWREGS(sym->type)) {
/* do not save WREG,STATUS,BSR for high priority interrupts
pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_pclath ));
pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_pclatu ));
-
+
// pic16_pBlockConvert2ISR(pb);
}
/* emit code to setup stack frame if user enabled,
* and function is not main() */
-
+
// debugf(stderr, "function name: %s ARGS=%p\n", sym->name, FUNC_ARGS(sym->type));
if(strcmp(sym->name, "main")) {
- if(0
- || !options.ommitFramePtr
+ if(0
+ || !options.ommitFramePtr
// || sym->regsUsed
|| IFFUNC_ARGS(sym->type)
|| FUNC_HASSTACKPARM(sym->etype)
if (sym->stack > 127)werror(W_STACK_OVERFLOW, sym->name);
pic16_emitpcode(POC_MOVLW, pic16_popGetLit(sym->stack));
- pic16_emitpcode(POC_SUBWF, pic16_popCopyReg( pic16_stackpnt_lo )); //&pic16_pc_fsr1l));
+ pic16_emitpcode(POC_SUBWF, pic16_popCopyReg( pic16_stackpnt_lo )); //&pic16_pc_fsr1l));
emitSKPC;
- pic16_emitpcode(POC_DECF, pic16_popCopyReg( pic16_stackpnt_hi )); //&pic16_pc_fsr1h));
+ pic16_emitpcode(POC_DECF, pic16_popCopyReg( pic16_stackpnt_hi )); //&pic16_pc_fsr1h));
}
-
+
if(inWparamList(sym->name) || FUNC_ISWPARAM(sym->type)) {
if(IFFUNC_HASVARARGS(sym->type) || IFFUNC_ISREENT(sym->type))
_G.useWreg = 0;
/* if any registers used */
if (sym->regsUsed) {
- pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_BEGIN));
+ pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_BEGIN));
if(!xinst) {
/* save the registers used */
for ( i = 0 ; i < sym->regsUsed->size ; i++) {
if (bitVectBitValue(sym->regsUsed,i)) {
#if 0
- fprintf(stderr, "%s:%d local register w/rIdx = %d is used in function\n", __FUNCTION__, __LINE__, i);
+ fprintf(stderr, "%s:%d local register w/rIdx = %d is used in function\n", __FUNCTION__, __LINE__, i);
#endif
pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
_G.nRegsSaved++;
}
}
} else {
-
+
/* xinst */
DEBUGpic16_emitcode("; **", "Allocate a space in stack to be used as temporary registers");
for(i=0;i<sym->regsUsed->size;i++) {
_G.nRegsSaved++;
}
}
-
+
// pic16_emitpcode(POC_ADDFSR, pic16_popGetLit2(2, pic16_popGetLit(_G.nRegsSaved)));
}
}
}
-
+
DEBUGpic16_emitcode("; ", "need to adjust stack = %d", sym->stack);
// fprintf(stderr, "Function '%s' uses %d bytes of stack\n", sym->name, sym->stack);
}
/* add code for ISCRITICAL */
if(IFFUNC_ISCRITICAL(sym->type)) {
/* if critical function, turn on interrupts */
-
+
/* TODO: add code here -- VR */
}
-
+
// sym->regsUsed = _G.fregsUsed;
-
+
/* now we need to restore the registers */
/* if any registers used */
/* first restore registers that might be used for stack access */
if(_G.sregsAllocSet) {
regs *sr;
-
+
_G.sregsAllocSet = reverseSet( _G.sregsAllocSet );
for(sr=setFirstItem(_G.sregsAllocSet) ; sr; sr=setNextItem(_G.sregsAllocSet)) {
pic16_poppCodeOp( pic16_popRegFromIdx( sr->rIdx ) );
pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_EXIT_END));
}
-
+
if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)
&& sym->stack) {
pic16_emitpcode(POC_INCF, pic16_popCopyReg( pic16_stackpnt_hi ));
} else {
// we have to add more than one...
- pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postinc )); // this holds a return value!
+ pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postinc )); // this holds a return value!
pic16_emitpcode(POC_MOVLW, pic16_popGetLit(sym->stack-1));
pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( pic16_stackpnt_lo ));
emitSKPNC;
if(!FUNC_ISSHADOWREGS(sym->type)) {
/* do not restore interrupt vector for WREG,STATUS,BSR
* for high priority interrupt, see genFunction */
- pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
- pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_status ));
- pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
+ pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
+ pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_status ));
+ pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
}
-// _G.interruptvector = 0; /* sanity check */
+// _G.interruptvector = 0; /* sanity check */
/* if debug then send end of function */
-/* if (options.debug && currFunc) */
+/* if (options.debug && currFunc) */
if (currFunc) {
debugFile->writeEndFunction (currFunc, ic, 1);
}
-
+
if(_G.usefastretfie)
pic16_emitpcode(POC_RETFIE, pic16_newpCodeOpLit(1));
else
pic16_emitpcodeNULLop(POC_RETFIE);
pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
-
+
_G.usefastretfie = 0;
return;
}
/* insert code to restore stack frame, if user enabled it
* and function is not main() */
-
+
pic16_emitpcodeNULLop(POC_RETURN);
{
unsigned long lit=1;
operand *op;
-
+
op = IC_LEFT(ic);
-
+
// this fails for is_LitOp(op) (if op is an AOP_PCODE)
if(AOP_TYPE(op) == AOP_LIT) {
if(!IS_FLOAT(operandType( op ))) {
- lit = (unsigned long)floatFromVal(AOP(op)->aopu.aop_lit);
+ lit = ulFromVal (AOP(op)->aopu.aop_lit);
} else {
union {
unsigned long lit_int;
float lit_float;
} info;
-
+
/* take care if literal is a float */
info.lit_float = floatFromVal(AOP(op)->aopu.aop_lit);
lit = info.lit_int;
* (upper byte is 0x00 (__code space) instead of 0x80 (__data) */
pic16_movLit2f(dest, (lit >> (8ul*offset)));
} else if (AOP_TYPE(op) == AOP_PCODE
- && AOP(op)->aopu.pcop->type == PO_IMMEDIATE) {
+ && AOP(op)->aopu.pcop->type == PO_IMMEDIATE) {
/* char *s= "aaa"; return s; */
/* XXX: Using UPPER(__str_0) will yield 0b00XXXXXX, so
* that the generic pointer is interpreted correctly
pic16_emitpcode(POC_MOVWF, dest);
} else {
if(dest->type == PO_WREG && (offset == 0)) {
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op), offset));
- return;
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op), offset));
+ return;
}
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(op), offset), dest));
}
operand *left;
FENTRY;
- /* if we have no return value then
- * just generate the "ret" */
-
- if (!IC_LEFT(ic))
- goto jumpret;
-
- /* we have something to return then
- * move the return value into place */
- pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
- size = AOP_SIZE(IC_LEFT(ic));
-
- if(size <= 4) {
- if(size>3)
- pic16_storeForReturn(ic, /*IC_LEFT(ic),*/ 3, pic16_popCopyReg(&pic16_pc_fsr0l));
-
+ /* if we have no return value then
+ * just generate the "ret" */
+
+ if (!IC_LEFT(ic))
+ goto jumpret;
+
+ /* we have something to return then
+ * move the return value into place */
+ pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
+ size = AOP_SIZE(IC_LEFT(ic));
+
+ if(size <= 4) {
+ if(size>3)
+ pic16_storeForReturn(ic, /*IC_LEFT(ic),*/ 3, pic16_popCopyReg(&pic16_pc_fsr0l));
+
if(size>2)
pic16_storeForReturn(ic, /*IC_LEFT(ic),*/ 2, pic16_popCopyReg(&pic16_pc_prodh));
if(size>1)
pic16_storeForReturn(ic, /*IC_LEFT(ic),*/ 1, pic16_popCopyReg(&pic16_pc_prodl));
-
+
pic16_storeForReturn(ic, /*IC_LEFT(ic),*/ 0, pic16_popCopyReg(&pic16_pc_wreg));
- } else {
- /* >32-bits, setup stack and FSR0 */
- while (size--) {
-// DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
-// DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
-
- pic16_pushpCodeOp( pic16_popGet( AOP( IC_LEFT(ic) ), size) );
-
-// popaopidx(AOP(oper), size, GpseudoStkPtr);
- GpsuedoStkPtr++;
- }
-
- /* setup FSR0 */
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
- pic16_popCopyReg( pic16_stackpnt_lo ), pic16_popCopyReg(&pic16_pc_fsr0l)));
-
- if(STACK_MODEL_LARGE) {
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
- pic16_popCopyReg( pic16_stackpnt_hi ), pic16_popCopyReg(&pic16_pc_fsr0h)));
- } else {
- pic16_emitpcode(POC_CLRF, pic16_popCopyReg( pic16_stackpnt_hi ));
- }
- }
-
+ } else {
+ /* >32-bits, setup stack and FSR0 */
+ while (size--) {
+// DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
+// DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
+
+ pic16_pushpCodeOp( pic16_popGet( AOP( IC_LEFT(ic) ), size) );
+
+// popaopidx(AOP(oper), size, GpseudoStkPtr);
+ GpsuedoStkPtr++;
+ }
+
+ /* setup FSR0 */
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg( pic16_stackpnt_lo ), pic16_popCopyReg(&pic16_pc_fsr0l)));
+
+ if(STACK_MODEL_LARGE) {
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg( pic16_stackpnt_hi ), pic16_popCopyReg(&pic16_pc_fsr0h)));
+ } else {
+ pic16_emitpcode(POC_CLRF, pic16_popCopyReg( pic16_stackpnt_hi ));
+ }
+ }
+
#if 0
- /* old code, left here for reference -- VR */
- while (size--) {
- char *l ;
-
- if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
- /* #NOCHANGE */
- l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++, FALSE,TRUE);
- pic16_emitpcomment("push %s",l);
- pushed++;
- } else {
- DEBUGpic16_emitcode(";", "%d", __LINE__);
- l = pic16_aopGet(AOP(IC_LEFT(ic)),offset, FALSE,FALSE);
- DEBUGpic16_emitcode(";", "%d l= %s", __LINE__, l);
-
- if (strcmp(fReturn[offset],l)) {
- if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD)
- || ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
- pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
- } else {
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
- }
-
- if(size) {
- pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(offset + pic16_Gstack_base_addr));
- }
- offset++;
- }
- }
- }
-
- if (pushed) {
- while(pushed) {
- pushed--;
- if (strcmp(fReturn[pushed],"a"))
- pic16_emitcode("pop",fReturn[pushed]);
- else
- pic16_emitcode("pop","acc");
- }
- }
+ /* old code, left here for reference -- VR */
+ while (size--) {
+ char *l ;
+
+ if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
+ /* #NOCHANGE */
+ l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++, FALSE,TRUE);
+ pic16_emitpcomment("push %s",l);
+ pushed++;
+ } else {
+ DEBUGpic16_emitcode(";", "%d", __LINE__);
+ l = pic16_aopGet(AOP(IC_LEFT(ic)),offset, FALSE,FALSE);
+ DEBUGpic16_emitcode(";", "%d l= %s", __LINE__, l);
+
+ if (strcmp(fReturn[offset],l)) {
+ if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD)
+ || ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
+ pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
+ } else {
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
+ }
+
+ if(size) {
+ pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(offset + pic16_Gstack_base_addr));
+ }
+ offset++;
+ }
+ }
+ }
+
+ if (pushed) {
+ while(pushed) {
+ pushed--;
+ if (strcmp(fReturn[pushed],"a"))
+ pic16_emitcode("pop",fReturn[pushed]);
+ else
+ pic16_emitcode("pop","acc");
+ }
+ }
#endif
- pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
-
+ pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
+
jumpret:
- /* generate a jump to the return label
- * if the next is not the return statement */
- if (!(ic->next && ic->next->op == LABEL
- && IC_LABEL(ic->next) == returnLabel)) {
-
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
- pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + pic16_labelOffset);
- }
+ /* generate a jump to the return label
+ * if the next is not the return statement */
+ if (!(ic->next && ic->next->op == LABEL
+ && IC_LABEL(ic->next) == returnLabel)) {
+
+ pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
+ pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + pic16_labelOffset);
+ }
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
/* genMultbits :- multiplication of bits */
/*-----------------------------------------------------------------*/
-static void genMultbits (operand *left,
- operand *right,
+static void genMultbits (operand *left,
+ operand *right,
operand *result)
{
FENTRY;
left = t;
}
- /* size is already checked in genMult == 1 */
-// size = AOP_SIZE(result);
+ /* size is already checked in genMult == 1 */
+// size = AOP_SIZE(result);
+
+ if (AOP_TYPE(right) == AOP_LIT){
+ pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
+ pic16_aopGet(AOP(right),0,FALSE,FALSE),
+ pic16_aopGet(AOP(left),0,FALSE,FALSE),
+ pic16_aopGet(AOP(result),0,FALSE,FALSE));
+ } else {
+ pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
+ pic16_aopGet(AOP(right),0,FALSE,FALSE),
+ pic16_aopGet(AOP(left),0,FALSE,FALSE),
+ pic16_aopGet(AOP(result),0,FALSE,FALSE));
+ }
- if (AOP_TYPE(right) == AOP_LIT){
- pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
- pic16_aopGet(AOP(right),0,FALSE,FALSE),
- pic16_aopGet(AOP(left),0,FALSE,FALSE),
- pic16_aopGet(AOP(result),0,FALSE,FALSE));
- } else {
- pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
- pic16_aopGet(AOP(right),0,FALSE,FALSE),
- pic16_aopGet(AOP(left),0,FALSE,FALSE),
- pic16_aopGet(AOP(result),0,FALSE,FALSE));
- }
-
- pic16_genMult8X8_n (left, right,result);
+ pic16_genMult8X8_n (left, right,result);
}
#if 0
// size = AOP_SIZE(result);
if (AOP_TYPE(right) == AOP_LIT) {
- pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
- pic16_aopGet(AOP(right),0,FALSE,FALSE),
- pic16_aopGet(AOP(left),0,FALSE,FALSE),
+ pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
+ pic16_aopGet(AOP(right),0,FALSE,FALSE),
+ pic16_aopGet(AOP(left),0,FALSE,FALSE),
pic16_aopGet(AOP(result),0,FALSE,FALSE));
} else {
- pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
- pic16_aopGet(AOP(right),0,FALSE,FALSE),
- pic16_aopGet(AOP(left),0,FALSE,FALSE),
+ pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
+ pic16_aopGet(AOP(right),0,FALSE,FALSE),
+ pic16_aopGet(AOP(left),0,FALSE,FALSE),
pic16_aopGet(AOP(result),0,FALSE,FALSE));
}
-
+
pic16_genMult16X16_16(left, right,result);
}
#endif
// size = AOP_SIZE(result);
if (AOP_TYPE(right) == AOP_LIT) {
- pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
- pic16_aopGet(AOP(right),0,FALSE,FALSE),
- pic16_aopGet(AOP(left),0,FALSE,FALSE),
+ pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
+ pic16_aopGet(AOP(right),0,FALSE,FALSE),
+ pic16_aopGet(AOP(left),0,FALSE,FALSE),
pic16_aopGet(AOP(result),0,FALSE,FALSE));
} else {
- pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
- pic16_aopGet(AOP(right),0,FALSE,FALSE),
- pic16_aopGet(AOP(left),0,FALSE,FALSE),
+ pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
+ pic16_aopGet(AOP(right),0,FALSE,FALSE),
+ pic16_aopGet(AOP(left),0,FALSE,FALSE),
pic16_aopGet(AOP(result),0,FALSE,FALSE));
}
-
+
pic16_genMult32X32_32(left, right,result);
}
#endif
{
operand *left = IC_LEFT(ic);
operand *right = IC_RIGHT(ic);
- operand *result= IC_RESULT(ic);
+ operand *result= IC_RESULT(ic);
FENTRY;
- /* assign the amsops */
- pic16_aopOp (left,ic,FALSE);
- pic16_aopOp (right,ic,FALSE);
- pic16_aopOp (result,ic,TRUE);
-
- DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
-
- /* special cases first *
- * both are bits */
- if (AOP_TYPE(left) == AOP_CRY
- && AOP_TYPE(right)== AOP_CRY) {
- genMultbits(left,right,result);
- goto release ;
- }
-
- /* if both are of size == 1 */
- if(AOP_SIZE(left) == 1
- && AOP_SIZE(right) == 1) {
- genMultOneByte(left,right,result);
- goto release ;
- }
+ /* assign the amsops */
+ pic16_aopOp (left,ic,FALSE);
+ pic16_aopOp (right,ic,FALSE);
+ pic16_aopOp (result,ic,TRUE);
+
+ DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
+
+ /* special cases first *
+ * both are bits */
+ if (AOP_TYPE(left) == AOP_CRY
+ && AOP_TYPE(right)== AOP_CRY) {
+ genMultbits(left,right,result);
+ goto release ;
+ }
+
+ /* if both are of size == 1 */
+ if(AOP_SIZE(left) == 1
+ && AOP_SIZE(right) == 1) {
+ genMultOneByte(left,right,result);
+ goto release ;
+ }
#if 0
- /* if both are of size == 2 */
- if(AOP_SIZE(left) == 2
- && AOP_SIZE(right) == 2) {
- genMultOneWord(left, right, result);
- goto release;
- }
-
- /* if both are of size == 4 */
- if(AOP_SIZE(left) == 4
- && AOP_SIZE(right) == 4) {
- genMultOneLong(left, right, result);
- goto release;
- }
+ /* if both are of size == 2 */
+ if(AOP_SIZE(left) == 2
+ && AOP_SIZE(right) == 2) {
+ genMultOneWord(left, right, result);
+ goto release;
+ }
+
+ /* if both are of size == 4 */
+ if(AOP_SIZE(left) == 4
+ && AOP_SIZE(right) == 4) {
+ genMultOneLong(left, right, result);
+ goto release;
+ }
#endif
- fprintf( stderr, "%s: should have been transformed into function call\n",__FUNCTION__ );
- assert( !"Multiplication should have been transformed into function call!" );
+ fprintf( stderr, "%s: should have been transformed into function call\n",__FUNCTION__ );
+ assert( !"Multiplication should have been transformed into function call!" );
- pic16_emitcode("multiply ","sizes are greater than 4 ... need to insert proper algor.");
+ pic16_emitcode("multiply ","sizes are greater than 4 ... need to insert proper algor.");
- fprintf(stderr, "operand sizes result: %d left: %d right: %d\n", AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
- /* should have been converted to function call */
- assert(0) ;
+ fprintf(stderr, "operand sizes result: %d left: %d right: %d\n", AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
+ /* should have been converted to function call */
+ assert(0) ;
release :
- pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- pic16_freeAsmop(result,NULL,ic,TRUE);
+ pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ pic16_freeAsmop(result,NULL,ic,TRUE);
}
#if 0
/*-----------------------------------------------------------------*/
/* genDivbits :- division of bits */
/*-----------------------------------------------------------------*/
-static void genDivbits (operand *left,
- operand *right,
+static void genDivbits (operand *left,
+ operand *right,
operand *result)
{
char *l;
FENTRY;
- /* the result must be bit */
+ /* the result must be bit */
pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
- MOVA(l);
+ MOVA(l);
pic16_emitcode("div","ab");
pic16_emitcode("rrc","a");
symbol *lbl ;
int size,offset;
- /* result = divident / divisor
- * - divident may be a register or a literal,
- * - divisor may be a register or a literal,
- * so there are 3 cases (literal / literal is optimized
- * by the front-end) to handle.
- * In addition we must handle signed and unsigned, which
- * result in 6 final different cases -- VR */
+ /* result = divident / divisor
+ * - divident may be a register or a literal,
+ * - divisor may be a register or a literal,
+ * so there are 3 cases (literal / literal is optimized
+ * by the front-end) to handle.
+ * In addition we must handle signed and unsigned, which
+ * result in 6 final different cases -- VR */
FENTRY;
-
+
size = AOP_SIZE(result) - 1;
offset = 1;
/* signed or unsigned */
if (SPEC_USIGN(opetype)) {
- pCodeOp *pct1, /* count */
- *pct2, /* reste */
- *pct3; /* temp */
+ pCodeOp *pct1, /* count */
+ *pct2, /* reste */
+ *pct3; /* temp */
symbol *label1, *label2, *label3;;
/* unsigned is easy */
- pct1 = pic16_popGetTempReg(1);
- pct2 = pic16_popGetTempReg(1);
- pct3 = pic16_popGetTempReg(1);
-
- label1 = newiTempLabel(NULL);
- label2 = newiTempLabel(NULL);
- label3 = newiTempLabel(NULL);
-
- /* the following algorithm is extracted from divuint.c */
-
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit( 8 ));
- pic16_emitpcode(POC_MOVWF, pic16_pCodeOpCopy( pct1 ));
-
- pic16_emitpcode(POC_CLRF, pic16_pCodeOpCopy( pct2 ));
-
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
-
- pic16_emitpLabel(label1->key);
-
- emitCLRC;
- pic16_emitpcode(POC_RLCF, pic16_pCodeOpCopy( pct2 ));
-
-
- emitCLRC;
- pic16_emitpcode(POC_RLCF, pic16_popCopyReg( &pic16_pc_wreg ));
-
-
- emitSKPNC;
- pic16_emitpcode(POC_INCF, pic16_pCodeOpCopy( pct2 ));
-
- pic16_emitpcode(POC_MOVWF, pic16_pCodeOpCopy( pct3 ));
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), 0));
-
- pic16_emitpcode(POC_CPFSLT, pic16_pCodeOpCopy(pct2));
- pic16_emitpcode(POC_BRA, pic16_popGetLabel(label3->key));
- pic16_emitpcode(POC_BRA, pic16_popGetLabel(label2->key));
-
- pic16_emitpLabel( label3->key );
- pic16_emitpcode(POC_SUBWF, pic16_pCodeOpCopy(pct2));
- pic16_emitpcode(POC_INCF, pic16_pCodeOpCopy(pct3));
-
-
-
- pic16_emitpLabel(label2->key);
- pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct3));
- pic16_emitpcode(POC_DECFSZ, pic16_pCodeOpCopy(pct1));
- pic16_emitpcode(POC_BRA, pic16_popGetLabel( label1->key ));
-
- /* result is in wreg */
- if(AOP_TYPE(result) != AOP_ACC)
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
-
- pic16_popReleaseTempReg( pct3, 1);
- pic16_popReleaseTempReg( pct2, 1);
- pic16_popReleaseTempReg( pct1, 1);
+ pct1 = pic16_popGetTempReg(1);
+ pct2 = pic16_popGetTempReg(1);
+ pct3 = pic16_popGetTempReg(1);
+
+ label1 = newiTempLabel(NULL);
+ label2 = newiTempLabel(NULL);
+ label3 = newiTempLabel(NULL);
+
+ /* the following algorithm is extracted from divuint.c */
+
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit( 8 ));
+ pic16_emitpcode(POC_MOVWF, pic16_pCodeOpCopy( pct1 ));
+
+ pic16_emitpcode(POC_CLRF, pic16_pCodeOpCopy( pct2 ));
+
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
+
+ pic16_emitpLabel(label1->key);
+
+ emitCLRC;
+ pic16_emitpcode(POC_RLCF, pic16_pCodeOpCopy( pct2 ));
+
+
+ emitCLRC;
+ pic16_emitpcode(POC_RLCF, pic16_popCopyReg( &pic16_pc_wreg ));
+
+
+ emitSKPNC;
+ pic16_emitpcode(POC_INCF, pic16_pCodeOpCopy( pct2 ));
+
+ pic16_emitpcode(POC_MOVWF, pic16_pCodeOpCopy( pct3 ));
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), 0));
+
+ pic16_emitpcode(POC_CPFSLT, pic16_pCodeOpCopy(pct2));
+ pic16_emitpcode(POC_BRA, pic16_popGetLabel(label3->key));
+ pic16_emitpcode(POC_BRA, pic16_popGetLabel(label2->key));
+
+ pic16_emitpLabel( label3->key );
+ pic16_emitpcode(POC_SUBWF, pic16_pCodeOpCopy(pct2));
+ pic16_emitpcode(POC_INCF, pic16_pCodeOpCopy(pct3));
+
+
+
+ pic16_emitpLabel(label2->key);
+ pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct3));
+ pic16_emitpcode(POC_DECFSZ, pic16_pCodeOpCopy(pct1));
+ pic16_emitpcode(POC_BRA, pic16_popGetLabel( label1->key ));
+
+ /* result is in wreg */
+ if(AOP_TYPE(result) != AOP_ACC)
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
+
+ pic16_popReleaseTempReg( pct3, 1);
+ pic16_popReleaseTempReg( pct2, 1);
+ pic16_popReleaseTempReg( pct1, 1);
return ;
}
/* signed is a little bit more difficult */
/* save the signs of the operands */
- l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
- MOVA(l);
+ l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
+ MOVA(l);
pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,TRUE));
pic16_emitcode("push","acc"); /* save it on the stack */
/* now sign adjust for both left & right */
- l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
- MOVA(l);
+ l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
+ MOVA(l);
lbl = newiTempLabel(NULL);
- pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
- pic16_emitcode("cpl","a");
+ pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
+ pic16_emitcode("cpl","a");
pic16_emitcode("inc","a");
pic16_emitcode("","%05d_DS_:",(lbl->key+100));
pic16_emitcode("mov","b,a");
/* sign adjust left side */
- l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
+ l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
MOVA(l);
lbl = newiTempLabel(NULL);
only */
pic16_emitcode("mov","b,a");
lbl = newiTempLabel(NULL);
- pic16_emitcode("pop","acc");
- /* if there was an over flow we don't
+ pic16_emitcode("pop","acc");
+ /* if there was an over flow we don't
adjust the sign of the result */
pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
pic16_aopPut(AOP(result),"b",0);
if(size > 0){
pic16_emitcode("mov","c,b.7");
- pic16_emitcode("subb","a,acc");
+ pic16_emitcode("subb","a,acc");
}
while (size--)
pic16_aopPut(AOP(result),"a",offset++);
{
operand *left = IC_LEFT(ic);
operand *right = IC_RIGHT(ic);
- operand *result= IC_RESULT(ic);
+ operand *result= IC_RESULT(ic);
int negated = 0;
int leftVal = 0, rightVal = 0;
int signedLits = 0;
char *functions[2][2] = { { "__divschar", "__divuchar" }, { "__modschar", "__moduchar" } };
int op = 0;
-
- /* Division is a very lengthy algorithm, so it is better
- * to call support routines than inlining algorithm.
- * Division functions written here just in case someone
- * wants to inline and not use the support libraries -- VR */
+
+ /* Division is a very lengthy algorithm, so it is better
+ * to call support routines than inlining algorithm.
+ * Division functions written here just in case someone
+ * wants to inline and not use the support libraries -- VR */
FENTRY;
-
+
/* assign the amsops */
pic16_aopOp (left,ic,FALSE);
pic16_aopOp (right,ic,FALSE);
/* get literal values */
if (IS_VALOP(left)) {
- leftVal = (int)floatFromVal( OP_VALUE(left) );
+ leftVal = (int) ulFromVal ( OP_VALUE(left) );
assert( leftVal >= -128 && leftVal < 256 );
if (leftVal < 0) { signedLits++; }
}
if (IS_VALOP(right)) {
- rightVal = (int)floatFromVal( OP_VALUE(right) );
+ rightVal = (int) ulFromVal ( OP_VALUE(right) );
assert( rightVal >= -128 && rightVal < 256 );
if (rightVal < 0) { signedLits++; }
}
* u8_t x u8_t -> u8_t. All other cases should have been
* turned into calls to support routines beforehand... */
if ((AOP_SIZE(left) == 1 || IS_VALOP(left))
- && (AOP_SIZE(right) == 1 || IS_VALOP(right)))
+ && (AOP_SIZE(right) == 1 || IS_VALOP(right)))
{
if ((!IS_UNSIGNED(operandType(right)) || rightVal < 0)
- && (!IS_UNSIGNED(operandType(left)) || leftVal < 0))
+ && (!IS_UNSIGNED(operandType(left)) || leftVal < 0))
{
- /* Both operands are signed or negative, use _divschar
- * instead of _divuchar */
- pushaop(AOP(right), 0);
- pushaop(AOP(left), 0);
-
- /* call _divschar */
- pic16_emitpcode(POC_CALL, pic16_popGetWithString(functions[op][0]));
-
- {
- symbol *sym;
- sym = newSymbol( functions[op][0], 0 );
- sym->used++;
- strcpy(sym->rname, functions[op][0]);
- checkAddSym(&externs, sym);
- }
-
- /* assign result */
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
- if (AOP_SIZE(result) > 1)
- {
- pic16_emitpcode(POC_MOVFF,
- pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
- pic16_popGet(AOP(result), 1)));
- /* sign extend */
- pic16_addSign(result, 2, 1);
- }
-
- /* clean up stack */
- pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(pic16_stack_preinc));
- pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(pic16_stack_preinc));
-
- goto release;
+ /* Both operands are signed or negative, use _divschar
+ * instead of _divuchar */
+ pushaop(AOP(right), 0);
+ pushaop(AOP(left), 0);
+
+ /* call _divschar */
+ pic16_emitpcode(POC_CALL, pic16_popGetWithString(functions[op][0]));
+
+ {
+ symbol *sym;
+ sym = newSymbol( functions[op][0], 0 );
+ sym->used++;
+ strcpy(sym->rname, functions[op][0]);
+ checkAddSym(&externs, sym);
+ }
+
+ /* assign result */
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
+ if (AOP_SIZE(result) > 1)
+ {
+ pic16_emitpcode(POC_MOVFF,
+ pic16_popGet2p(pic16_popCopyReg(&pic16_pc_prodl),
+ pic16_popGet(AOP(result), 1)));
+ /* sign extend */
+ pic16_addSign(result, 2, 1);
+ }
+
+ /* clean up stack */
+ pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(pic16_stack_preinc));
+ pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(pic16_stack_preinc));
+
+ goto release;
}
-
+
/* push right operand */
if (IS_VALOP(right)) {
- if (rightVal < 0) {
- pic16_pushpCodeOp( pic16_popGetLit(-rightVal) );
- negated++;
- } else {
- pushaop(AOP(right), 0);
- }
+ if (rightVal < 0) {
+ pic16_pushpCodeOp( pic16_popGetLit(-rightVal) );
+ negated++;
+ } else {
+ pushaop(AOP(right), 0);
+ }
} else if (!IS_UNSIGNED(operandType(right))) {
- pic16_mov2w(AOP(right), 0);
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(right), 0, 7));
- pic16_emitpcode(POC_NEGF, pic16_popCopyReg(&pic16_pc_wreg));
- pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(pic16_stack_postdec));
- negated++;
+ pic16_mov2w(AOP(right), 0);
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(right), 0, 7));
+ pic16_emitpcode(POC_NEGF, pic16_popCopyReg(&pic16_pc_wreg));
+ pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(pic16_stack_postdec));
+ negated++;
} else {
- pushaop(AOP(right), 0);
+ pushaop(AOP(right), 0);
}
/* push left operand */
if (IS_VALOP(left)) {
- if (leftVal < 0) {
- pic16_pushpCodeOp(pic16_popGetLit(-leftVal));
- negated++;
- } else {
- pushaop(AOP(left), 0);
- }
+ if (leftVal < 0) {
+ pic16_pushpCodeOp(pic16_popGetLit(-leftVal));
+ negated++;
+ } else {
+ pushaop(AOP(left), 0);
+ }
} else if (!IS_UNSIGNED(operandType(left))) {
- pic16_mov2w(AOP(left),0);
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7));
- pic16_emitpcode(POC_NEGF, pic16_popCopyReg(&pic16_pc_wreg));
- pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(pic16_stack_postdec));
- negated++;
+ pic16_mov2w(AOP(left),0);
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7));
+ pic16_emitpcode(POC_NEGF, pic16_popCopyReg(&pic16_pc_wreg));
+ pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(pic16_stack_postdec));
+ negated++;
} else {
- pushaop(AOP(left), 0);
+ pushaop(AOP(left), 0);
}
-
+
/* call _divuchar */
pic16_emitpcode(POC_CALL, pic16_popGetWithString(functions[op][1]));
{
- symbol *sym;
- sym = newSymbol( functions[op][1], 0 );
- sym->used++;
- strcpy(sym->rname, functions[op][1]);
- checkAddSym(&externs, sym);
+ symbol *sym;
+ sym = newSymbol( functions[op][1], 0 );
+ sym->used++;
+ strcpy(sym->rname, functions[op][1]);
+ checkAddSym(&externs, sym);
}
/* Revert negation(s) from above.
*
* I negate WREG because either operand might share registers with
* result, so assigning first might destroy an operand. */
-
+
/* For the modulus operator, (a/b)*b == a shall hold.
* Thus: a>0, b>0 --> a/b >= 0 and a%b >= 0
* a>0, b<0 --> a/b <= 0 and a%b >= 0 (e.g. 128 / -5 = -25, -25*(-5) = 125 and +3 remaining)
*/
if (AOP_SIZE(result) <= 1 || !negated)
{
- if (ic->op == '/')
- {
- if (IS_VALOP(right)) {
- if (rightVal < 0) {
- /* we negated this operand above */
- pic16_emitpcode(POC_NEGF, pic16_popCopyReg(&pic16_pc_wreg));
- }
- } else if (!IS_UNSIGNED(operandType(right))) {
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(right), 0, 7));
- pic16_emitpcode(POC_NEGF, pic16_popCopyReg(&pic16_pc_wreg));
- }
- }
-
- if (IS_VALOP(left)) {
- if (leftVal < 0) {
- /* we negated this operand above */
- pic16_emitpcode(POC_NEGF, pic16_popCopyReg(&pic16_pc_wreg));
- }
- } else if (!IS_UNSIGNED(operandType(left))) {
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7));
- pic16_emitpcode(POC_NEGF, pic16_popCopyReg(&pic16_pc_wreg));
- }
-
- /* Move result to destination. */
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
-
- /* Zero-extend: no operand was signed (or result is just a byte). */
- pic16_addSign(result, 1, 0);
+ if (ic->op == '/')
+ {
+ if (IS_VALOP(right)) {
+ if (rightVal < 0) {
+ /* we negated this operand above */
+ pic16_emitpcode(POC_NEGF, pic16_popCopyReg(&pic16_pc_wreg));
+ }
+ } else if (!IS_UNSIGNED(operandType(right))) {
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(right), 0, 7));
+ pic16_emitpcode(POC_NEGF, pic16_popCopyReg(&pic16_pc_wreg));
+ }
+ }
+
+ if (IS_VALOP(left)) {
+ if (leftVal < 0) {
+ /* we negated this operand above */
+ pic16_emitpcode(POC_NEGF, pic16_popCopyReg(&pic16_pc_wreg));
+ }
+ } else if (!IS_UNSIGNED(operandType(left))) {
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7));
+ pic16_emitpcode(POC_NEGF, pic16_popCopyReg(&pic16_pc_wreg));
+ }
+
+ /* Move result to destination. */
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
+
+ /* Zero-extend: no operand was signed (or result is just a byte). */
+ pic16_addSign(result, 1, 0);
} else {
- assert( AOP_SIZE(result) > 1 );
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
- if (ic->op == '/')
- {
- if (IS_VALOP(right)) {
- if (rightVal < 0) {
- /* we negated this operand above */
- pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result), 1));
- }
- } else if (!IS_UNSIGNED(operandType(right))) {
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(right), 0, 7));
- pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result), 1));
- }
- }
-
- if (IS_VALOP(left)) {
- if (leftVal < 0) {
- /* we negated this operand above */
- pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result), 1));
- }
- } else if (!IS_UNSIGNED(operandType(left))) {
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7));
- pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result), 1));
- }
-
- /* Move result to destination. */
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
-
- /* Negate result if required. */
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(result), 1, 7));
- pic16_emitpcode(POC_NEGF, pic16_popGet(AOP(result), 0));
-
- /* Sign-extend. */
- pic16_addSign(result, 2, 1);
+ assert( AOP_SIZE(result) > 1 );
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
+ if (ic->op == '/')
+ {
+ if (IS_VALOP(right)) {
+ if (rightVal < 0) {
+ /* we negated this operand above */
+ pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result), 1));
+ }
+ } else if (!IS_UNSIGNED(operandType(right))) {
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(right), 0, 7));
+ pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result), 1));
+ }
+ }
+
+ if (IS_VALOP(left)) {
+ if (leftVal < 0) {
+ /* we negated this operand above */
+ pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result), 1));
+ }
+ } else if (!IS_UNSIGNED(operandType(left))) {
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7));
+ pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result), 1));
+ }
+
+ /* Move result to destination. */
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
+
+ /* Negate result if required. */
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(result), 1, 7));
+ pic16_emitpcode(POC_NEGF, pic16_popGet(AOP(result), 0));
+
+ /* Sign-extend. */
+ pic16_addSign(result, 2, 1);
}
/* clean up stack */
release :
pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- pic16_freeAsmop(result,NULL,ic,TRUE);
+ pic16_freeAsmop(result,NULL,ic,TRUE);
}
#if 0
/*-----------------------------------------------------------------*/
/* genModbits :- modulus of bits */
/*-----------------------------------------------------------------*/
-static void genModbits (operand *left,
- operand *right,
+static void genModbits (operand *left,
+ operand *right,
operand *result)
{
char *l;
- FENTRY;
-
+ FENTRY;
+
werror(W_POSSBUG2, __FILE__, __LINE__);
- /* the result must be bit */
+ /* the result must be bit */
pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
- MOVA(l);
+ MOVA(l);
pic16_emitcode("div","ab");
pic16_emitcode("mov","a,b");
/* unsigned is easy */
pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
- MOVA(l);
+ MOVA(l);
pic16_emitcode("div","ab");
pic16_aopPut(AOP(result),"b",0);
return ;
/* signed is a little bit more difficult */
/* save the signs of the operands */
- l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
+ l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
MOVA(l);
pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
pic16_emitcode("push","acc"); /* save it on the stack */
/* now sign adjust for both left & right */
- l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
+ l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
MOVA(l);
lbl = newiTempLabel(NULL);
- pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
- pic16_emitcode("cpl","a");
+ pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
+ pic16_emitcode("cpl","a");
pic16_emitcode("inc","a");
pic16_emitcode("","%05d_DS_:",(lbl->key+100));
- pic16_emitcode("mov","b,a");
+ pic16_emitcode("mov","b,a");
/* sign adjust left side */
- l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
+ l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
MOVA(l);
lbl = newiTempLabel(NULL);
pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
- pic16_emitcode("cpl","a");
+ pic16_emitcode("cpl","a");
pic16_emitcode("inc","a");
pic16_emitcode("","%05d_DS_:",(lbl->key+100));
/* we are interested in the lower order
only */
lbl = newiTempLabel(NULL);
- pic16_emitcode("pop","acc");
- /* if there was an over flow we don't
+ pic16_emitcode("pop","acc");
+ /* if there was an over flow we don't
adjust the sign of the result */
pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
#if 0
operand *left = IC_LEFT(ic);
operand *right = IC_RIGHT(ic);
- operand *result= IC_RESULT(ic);
+ operand *result= IC_RESULT(ic);
FENTRY;
-
+
/* assign the amsops */
pic16_aopOp (left,ic,FALSE);
pic16_aopOp (right,ic,FALSE);
release :
pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- pic16_freeAsmop(result,NULL,ic,TRUE);
+ pic16_freeAsmop(result,NULL,ic,TRUE);
#endif
}
static void genIfxJump (iCode *ic, char *jval)
{
FENTRY;
-
+
/* if true label then we jump if condition
supplied is true */
if ( IC_TRUE(ic) ) {
- if(strcmp(jval,"a") == 0)
- emitSKPZ;
- else if (strcmp(jval,"c") == 0)
- emitSKPNC;
- else {
- DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(jval,-1,1, PO_GPR_REGISTER));
- }
+ if(strcmp(jval,"a") == 0)
+ emitSKPZ;
+ else if (strcmp(jval,"c") == 0)
+ emitSKPNC;
+ else {
+ DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(jval,-1,1, PO_GPR_REGISTER));
+ }
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
- pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + pic16_labelOffset);
+ pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
+ pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + pic16_labelOffset);
}
else {
/* false label is present */
- if(strcmp(jval,"a") == 0)
- emitSKPNZ;
- else if (strcmp(jval,"c") == 0)
- emitSKPC;
- else {
- DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
- pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(jval,-1,1, PO_GPR_REGISTER));
- }
+ if(strcmp(jval,"a") == 0)
+ emitSKPNZ;
+ else if (strcmp(jval,"c") == 0)
+ emitSKPC;
+ else {
+ DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
+ pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(jval,-1,1, PO_GPR_REGISTER));
+ }
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
- pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + pic16_labelOffset);
+ pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
+ pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + pic16_labelOffset);
}
static void genIfxpCOpJump (iCode *ic, pCodeOp *jop)
{
FENTRY;
-
+
/* if true label then we jump if condition
supplied is true */
if ( IC_TRUE(ic) ) {
- DEBUGpic16_emitcode ("; ***","%d - assuming is in bit space",__LINE__);
+ DEBUGpic16_emitcode ("; ***","%d - assuming is in bit space",__LINE__);
pic16_emitpcode(POC_BTFSC, jop);
pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
/* false label is present */
DEBUGpic16_emitcode ("; ***","%d - assuming is in bit space",__LINE__);
pic16_emitpcode(POC_BTFSS, jop);
-
+
pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + pic16_labelOffset);
}
static void genSkipc(resolvedIfx *rifx)
{
DEBUGpic16_emitcode ("; ***","%s %d rifx= %p",__FUNCTION__,__LINE__, rifx);
-
+
if(!rifx)
return;
static void genSkipz2(resolvedIfx *rifx, int invert_condition)
{
DEBUGpic16_emitcode ("; ***","%s %d rifx= %p",__FUNCTION__,__LINE__, rifx);
-
+
if(!rifx)
return;
i = (lit >> (size*8)) & 0xff;
if(i==0) {
- if(flag)
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
+ if(flag)
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
else
- pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
+ pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
flag = 0;
}
}
/* genCmp :- greater or less than comparison */
/*-----------------------------------------------------------------*/
-#if USE_SIMPLE_GENCMP /* { */
+#if USE_SIMPLE_GENCMP /* { */
/* genCmp performs a left < right comparison, stores
* the outcome in result (if != NULL) and generates
int performedLt;
FENTRY;
-
+
assert (left && right);
assert (AOP_SIZE(left) == AOP_SIZE(right));
performedLt = 1;
templbl = NULL;
lit = 0;
-
+
resolveIfx (&rIfx, ifx);
/* handle for special cases */
assert (isAOP_REGlike(right));
// swap left and right
// left < right <==> right > left <==> (right >= left + 1)
- lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
+ lit = ulFromVal (AOP(left)->aopu.aop_lit);
if ( (!sign && (lit & mask) == mask) || (sign && (lit & mask) == (mask >> 1)) ) {
// MAXVALUE < right? always false
performedLt ^= 1; // instead of "left < right" we check for "right >= left+1, i.e. "right < left+1"
} else if (isAOP_LIT(right)) {
- lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
+ lit = ulFromVal (AOP(right)->aopu.aop_lit);
} // if
assert (isAOP_REGlike(left)); // left must be register or the like
// unsigned comparison to a literal
DEBUGpc ("unsigned compare: left %s lit(0x%X=%lu), size=%d", performedLt ? "<" : ">=", lit, lit, size+1);
if (lit == 0) {
- // unsigned left < 0? always false
- if (performedLt) emitCLRC; else emitSETC;
- goto correct_result_in_carry;
+ // unsigned left < 0? always false
+ if (performedLt) emitCLRC; else emitSETC;
+ goto correct_result_in_carry;
}
} else {
// signed comparison to a literal
DEBUGpc ("signed compare: left %s lit(0x%X=%ld), size=%d, mask=%x", performedLt ? "<" : ">=", lit, lit, size+1, mask);
if ((lit & mask) == ((0x80 << (size*8)) & mask)) {
- // signed left < 0x80000000? always false
- if (performedLt) emitCLRC; else emitSETC;
- goto correct_result_in_carry;
+ // signed left < 0x80000000? always false
+ if (performedLt) emitCLRC; else emitSETC;
+ goto correct_result_in_carry;
} else if (lit == 0) {
- // compare left < 0; set CARRY if SIGNBIT(left) is set
- if (performedLt) emitSETC; else emitCLRC;
- pic16_emitpcode (POC_BTFSS, pic16_popCopyGPR2Bit(pic16_popGet (AOP(left), size), 7));
- if (performedLt) emitCLRC; else emitSETC;
- goto correct_result_in_carry;
+ // compare left < 0; set CARRY if SIGNBIT(left) is set
+ if (performedLt) emitSETC; else emitCLRC;
+ pic16_emitpcode (POC_BTFSS, pic16_popCopyGPR2Bit(pic16_popGet (AOP(left), size), 7));
+ if (performedLt) emitCLRC; else emitSETC;
+ goto correct_result_in_carry;
}
} // if (!sign)
} // right is literal
unsigned char litbyte = (lit >> (8*size)) & 0xFF;
if (litbyte == 0x80) {
- // left >= 0x80 -- always true, but more bytes to come
- pic16_mov2w (AOP(left), size);
- pic16_emitpcode (POC_XORLW, pic16_popGetLit (0x80)); // set ZERO flag
- emitSETC;
+ // left >= 0x80 -- always true, but more bytes to come
+ pic16_mov2w (AOP(left), size);
+ pic16_emitpcode (POC_XORLW, pic16_popGetLit (0x80)); // set ZERO flag
+ emitSETC;
} else {
- // left >= LIT <-> left + (-LIT) >= 0 <-> left + (0x100-LIT) >= 0x100
- pic16_mov2w (AOP(left), size);
- pic16_emitpcode (POC_ADDLW, pic16_popGetLit (0x80));
- pic16_emitpcode (POC_ADDLW, pic16_popGetLit ((0x100 - (litbyte + 0x80)) & 0x00FF));
+ // left >= LIT <-> left + (-LIT) >= 0 <-> left + (0x100-LIT) >= 0x100
+ pic16_mov2w (AOP(left), size);
+ pic16_emitpcode (POC_ADDLW, pic16_popGetLit (0x80));
+ pic16_emitpcode (POC_ADDLW, pic16_popGetLit ((0x100 - (litbyte + 0x80)) & 0x00FF));
} // if
} else {
/* using PRODL as a temporary register here */
goto result_in_carry;
result_in_carry:
-
+
/****************************************************
* now CARRY contains the result of the comparison: *
* SUBWF sets CARRY iff *
} // if
}
-#elif 1 /* } */
- /* { */
+#elif 1 /* } */
+ /* { */
/* original code */
static void genCmp (operand *left,operand *right,
operand *result, iCode *ifx, int sign)
*/
FENTRY;
-
+
resolveIfx(&rFalseIfx,ifx);
truelbl = newiTempLabel(NULL);
size = max(AOP_SIZE(left),AOP_SIZE(right));
if ((AOP_TYPE(right) == AOP_LIT)) {
operand *tmp = right ;
unsigned long mask = (0x100 << (8*(size-1))) - 1;
- lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
+ lit = ulFromVal (AOP(right)->aopu.aop_lit);
#ifdef _swapp
lit = (lit - 1) & mask;
#endif
} else if ((AOP_TYPE(left) == AOP_LIT)) {
- lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
+ lit = ulFromVal (AOP(left)->aopu.aop_lit);
}
symbol *lbl = newiTempLabel(NULL);
#if 0
- fprintf(stderr, "%s:%s:%d truelbl: %d\tlbl: %d\n",
- __FILE__, __FUNCTION__, __LINE__, truelbl->key+100+pic16_labelOffset, lbl->key+100+pic16_labelOffset);
+ fprintf(stderr, "%s:%s:%d truelbl: %d\tlbl: %d\n",
+ __FILE__, __FUNCTION__, __LINE__, truelbl->key+100+pic16_labelOffset, lbl->key+100+pic16_labelOffset);
#endif
#ifndef _swapp
if(AOP_TYPE(right) == AOP_LIT) {
- //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
+ //lit = ulFromVal (AOP(right)->aopu.aop_lit);
DEBUGpic16_emitcode(";right lit","%d lit = 0x%x,sign=%d",__LINE__, lit,sign);
if(lit == 0) {
- if(sign != 0)
- genSkipCond(&rFalseIfx,left,size-1,7);
- else
- /* no need to compare to 0...*/
- /* NOTE: this is a de-generate compare that most certainly
- * creates some dead code. */
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
+ if(sign != 0)
+ genSkipCond(&rFalseIfx,left,size-1,7);
+ else
+ /* no need to compare to 0...*/
+ /* NOTE: this is a de-generate compare that most certainly
+ * creates some dead code. */
+ pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
- if(ifx) ifx->generated = 1;
- return;
+ if(ifx) ifx->generated = 1;
+ return;
}
size--;
if(size == 0) {
- //i = (lit >> (size*8)) & 0xff;
- DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
-
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
-
- i = ((0-lit) & 0xff);
- if(sign) {
- if( i == 0x81) {
- /* lit is 0x7f, all signed chars are less than
- * this except for 0x7f itself */
- pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
- genSkipz2(&rFalseIfx,0);
- } else {
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
- genSkipc(&rFalseIfx);
- }
-
- } else {
- if(lit == 1) {
- genSkipz2(&rFalseIfx,1);
- } else {
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
- genSkipc(&rFalseIfx);
- }
- }
-
- if(ifx) ifx->generated = 1;
- return;
+ //i = (lit >> (size*8)) & 0xff;
+ DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
+
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
+
+ i = ((0-lit) & 0xff);
+ if(sign) {
+ if( i == 0x81) {
+ /* lit is 0x7f, all signed chars are less than
+ * this except for 0x7f itself */
+ pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
+ genSkipz2(&rFalseIfx,0);
+ } else {
+ pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
+ pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
+ genSkipc(&rFalseIfx);
+ }
+
+ } else {
+ if(lit == 1) {
+ genSkipz2(&rFalseIfx,1);
+ } else {
+ pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
+ genSkipc(&rFalseIfx);
+ }
+ }
+
+ if(ifx) ifx->generated = 1;
+ return;
}
/* chars are out of the way. now do ints and longs */
DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
-
+
/* special cases */
if(sign) {
- if(lit == 0) {
- genSkipCond(&rFalseIfx,left,size,7);
- if(ifx) ifx->generated = 1;
- return;
- }
+ if(lit == 0) {
+ genSkipCond(&rFalseIfx,left,size,7);
+ if(ifx) ifx->generated = 1;
+ return;
+ }
+
+ if(lit <0x100) {
+ DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
+
+ //rFalseIfx.condition ^= 1;
+ //genSkipCond(&rFalseIfx,left,size,7);
+ //rFalseIfx.condition ^= 1;
+
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+ if(rFalseIfx.condition)
+ pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
+ else
+ pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
- if(lit <0x100) {
- DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x100-lit));
+ pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
- //rFalseIfx.condition ^= 1;
- //genSkipCond(&rFalseIfx,left,size,7);
- //rFalseIfx.condition ^= 1;
+ while(size > 1)
+ pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- if(rFalseIfx.condition)
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
- else
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
-
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x100-lit));
- pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
-
- while(size > 1)
- pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
+ if(rFalseIfx.condition) {
+ emitSKPZ;
+ pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
- if(rFalseIfx.condition) {
- emitSKPZ;
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
-
- } else {
- emitSKPNZ;
- }
+ } else {
+ emitSKPNZ;
+ }
- genSkipc(&rFalseIfx);
- pic16_emitpLabel(truelbl->key);
- if(ifx) ifx->generated = 1;
- return;
+ genSkipc(&rFalseIfx);
+ pic16_emitpLabel(truelbl->key);
+ if(ifx) ifx->generated = 1;
+ return;
- }
+ }
- if(size == 1) {
+ if(size == 1) {
- if( (lit & 0xff) == 0) {
- /* lower byte is zero */
- DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
- i = ((lit >> 8) & 0xff) ^0x80;
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
- genSkipc(&rFalseIfx);
+ if( (lit & 0xff) == 0) {
+ /* lower byte is zero */
+ DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
+ i = ((lit >> 8) & 0xff) ^0x80;
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
+ pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
+ pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
+ genSkipc(&rFalseIfx);
- if(ifx) ifx->generated = 1;
- return;
+ if(ifx) ifx->generated = 1;
+ return;
- }
- } else {
- /* Special cases for signed longs */
- if( (lit & 0xffffff) == 0) {
- /* lower byte is zero */
- DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
- i = ((lit >> 8*3) & 0xff) ^0x80;
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
- genSkipc(&rFalseIfx);
+ }
+ } else {
+ /* Special cases for signed longs */
+ if( (lit & 0xffffff) == 0) {
+ /* lower byte is zero */
+ DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
+ i = ((lit >> 8*3) & 0xff) ^0x80;
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
+ pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
+ pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
+ genSkipc(&rFalseIfx);
+
+
+ if(ifx) ifx->generated = 1;
+ return;
+ }
- if(ifx) ifx->generated = 1;
- return;
+ }
- }
- }
+ if(lit & (0x80 << (size*8))) {
+ /* lit is negative */
+ DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
+ //genSkipCond(&rFalseIfx,left,size,7);
- if(lit & (0x80 << (size*8))) {
- /* lit is negative */
- DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
+ pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- //genSkipCond(&rFalseIfx,left,size,7);
+ if(rFalseIfx.condition)
+ pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
+ else
+ pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
- pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- if(rFalseIfx.condition)
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
- else
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
+ } else {
+ /* lit is positive */
+ DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+ if(rFalseIfx.condition)
+ pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
+ else
+ pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
+ }
- } else {
- /* lit is positive */
- DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- if(rFalseIfx.condition)
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
- else
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
+ /*
+ This works, but is only good for ints.
+ It also requires a "known zero" register.
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
+ pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
+ pic16_emitpcode(POC_RLCFW, pic16_popCopyReg(&pic16_pc_kzero));
+ pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
+ pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
+ genSkipc(&rFalseIfx);
- }
+ pic16_emitpLabel(truelbl->key);
+ if(ifx) ifx->generated = 1;
+ return;
+ **/
- /*
- This works, but is only good for ints.
- It also requires a "known zero" register.
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
- pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_RLCFW, pic16_popCopyReg(&pic16_pc_kzero));
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
- pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
- genSkipc(&rFalseIfx);
+ /* There are no more special cases, so perform a general compare */
- pic16_emitpLabel(truelbl->key);
- if(ifx) ifx->generated = 1;
- return;
- **/
-
- /* There are no more special cases, so perform a general compare */
-
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
+ pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
- while(size--) {
+ while(size--) {
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
- emitSKPNZ;
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
- }
- //rFalseIfx.condition ^= 1;
- genSkipc(&rFalseIfx);
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
+ emitSKPNZ;
+ pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
+ }
+ //rFalseIfx.condition ^= 1;
+ genSkipc(&rFalseIfx);
- pic16_emitpLabel(truelbl->key);
+ pic16_emitpLabel(truelbl->key);
- if(ifx) ifx->generated = 1;
- return;
+ if(ifx) ifx->generated = 1;
+ return;
}
pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
while(size--) {
- i = (lit >> (size*8)) & 0xff;
-
- if(i) {
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
- emitSKPNZ;
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
- } else {
- /* this byte of the lit is zero,
- *if it's not the last then OR in the variable */
- if(size)
- pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
- }
+ i = (lit >> (size*8)) & 0xff;
+
+ if(i) {
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
+ emitSKPNZ;
+ pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
+ } else {
+ /* this byte of the lit is zero,
+ *if it's not the last then OR in the variable */
+ if(size)
+ pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
+ }
}
pic16_emitpLabel(lbl->key);
-// pic16_emitpLabel(truelbl->key);
+// pic16_emitpLabel(truelbl->key);
//if(emitFinalCheck)
genSkipc(&rFalseIfx);
if(sign)
- pic16_emitpLabel(truelbl->key);
+ pic16_emitpLabel(truelbl->key);
if(ifx) ifx->generated = 1;
return;
if(AOP_TYPE(left) == AOP_LIT) {
//symbol *lbl = newiTempLabel(NULL);
- //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
+ //EXPERIMENTAL lit = ulFromVal (AOP(left)->aopu.aop_lit);
DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
/* Special cases */
if((lit == 0) && (sign == 0)){
- size--;
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
- while(size)
- pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
+ size--;
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
+ while(size)
+ pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
- genSkipz2(&rFalseIfx,0);
- if(ifx) ifx->generated = 1;
- return;
+ genSkipz2(&rFalseIfx,0);
+ if(ifx) ifx->generated = 1;
+ return;
}
if(size==1) {
- /* Special cases */
- lit &= 0xff;
- if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
- /* degenerate compare can never be true */
- if(rFalseIfx.condition == 0)
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
-
- if(ifx) ifx->generated = 1;
- return;
- }
-
- if(sign) {
- /* signed comparisons to a literal byte */
-
- int lp1 = (lit+1) & 0xff;
-
- DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
- switch (lp1) {
- case 0:
- rFalseIfx.condition ^= 1;
- genSkipCond(&rFalseIfx,right,0,7);
- break;
- case 0x7f:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
- pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
- genSkipz2(&rFalseIfx,1);
- break;
- default:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
- rFalseIfx.condition ^= 1;
- genSkipc(&rFalseIfx);
- break;
- }
- } else {
- /* unsigned comparisons to a literal byte */
-
- switch(lit & 0xff ) {
- case 0:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
- genSkipz2(&rFalseIfx,0);
- break;
- case 0x7f:
- rFalseIfx.condition ^= 1;
- genSkipCond(&rFalseIfx,right,0,7);
- break;
-
- default:
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- rFalseIfx.condition ^= 1;
- if (AOP_TYPE(result) == AOP_CRY)
- genSkipc(&rFalseIfx);
- else {
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
- }
- break;
- }
- }
-
- if(ifx) ifx->generated = 1;
- if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
- goto check_carry;
- return;
+ /* Special cases */
+ lit &= 0xff;
+ if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
+ /* degenerate compare can never be true */
+ if(rFalseIfx.condition == 0)
+ pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
+
+ if(ifx) ifx->generated = 1;
+ return;
+ }
- } else {
+ if(sign) {
+ /* signed comparisons to a literal byte */
- /* Size is greater than 1 */
+ int lp1 = (lit+1) & 0xff;
- if(sign) {
- int lp1 = lit+1;
+ DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
+ switch (lp1) {
+ case 0:
+ rFalseIfx.condition ^= 1;
+ genSkipCond(&rFalseIfx,right,0,7);
+ break;
+ case 0x7f:
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
+ pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
+ genSkipz2(&rFalseIfx,1);
+ break;
+ default:
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
+ pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
+ pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
+ rFalseIfx.condition ^= 1;
+ genSkipc(&rFalseIfx);
+ break;
+ }
+ } else {
+ /* unsigned comparisons to a literal byte */
- size--;
+ switch(lit & 0xff ) {
+ case 0:
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
+ genSkipz2(&rFalseIfx,0);
+ break;
+ case 0x7f:
+ rFalseIfx.condition ^= 1;
+ genSkipCond(&rFalseIfx,right,0,7);
+ break;
- if(lp1 == 0) {
- /* this means lit = 0xffffffff, or -1 */
+ default:
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
+ pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ rFalseIfx.condition ^= 1;
+ if (AOP_TYPE(result) == AOP_CRY)
+ genSkipc(&rFalseIfx);
+ else {
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
+ }
+ break;
+ }
+ }
+ if(ifx) ifx->generated = 1;
+ if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
+ goto check_carry;
+ return;
- DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
- rFalseIfx.condition ^= 1;
- genSkipCond(&rFalseIfx,right,size,7);
- if(ifx) ifx->generated = 1;
+ } else {
- if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
- goto check_carry;
+ /* Size is greater than 1 */
- return;
- }
+ if(sign) {
+ int lp1 = lit+1;
- if(lit == 0) {
- int s = size;
+ size--;
- if(rFalseIfx.condition) {
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
- }
+ if(lp1 == 0) {
+ /* this means lit = 0xffffffff, or -1 */
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
- while(size--)
- pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
+ DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
+ rFalseIfx.condition ^= 1;
+ genSkipCond(&rFalseIfx,right,size,7);
+ if(ifx) ifx->generated = 1;
- emitSKPZ;
- if(rFalseIfx.condition) {
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
- pic16_emitpLabel(truelbl->key);
- }else {
- rFalseIfx.condition ^= 1;
- genSkipCond(&rFalseIfx,right,s,7);
- }
+ if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
+ goto check_carry;
- if(ifx) ifx->generated = 1;
+ return;
+ }
- if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
- goto check_carry;
+ if(lit == 0) {
+ int s = size;
- return;
- }
+ if(rFalseIfx.condition) {
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+ pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
+ }
- if((size == 1) && (0 == (lp1&0xff))) {
- /* lower byte of signed word is zero */
- DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
- i = ((lp1 >> 8) & 0xff) ^0x80;
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
+ while(size--)
+ pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
- if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result))) {
- emitTOGC;
- if(ifx) ifx->generated = 1;
- goto check_carry;
- } else {
- rFalseIfx.condition ^= 1;
- genSkipc(&rFalseIfx);
- if(ifx) ifx->generated = 1;
- }
- return;
- }
+ emitSKPZ;
+ if(rFalseIfx.condition) {
+ pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
+ pic16_emitpLabel(truelbl->key);
+ }else {
+ rFalseIfx.condition ^= 1;
+ genSkipCond(&rFalseIfx,right,s,7);
+ }
- if(lit & (0x80 << (size*8))) {
- /* Lit is less than zero */
- DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
- //rFalseIfx.condition ^= 1;
- //genSkipCond(&rFalseIfx,left,size,7);
- //rFalseIfx.condition ^= 1;
- pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
+ if(ifx) ifx->generated = 1;
- if(rFalseIfx.condition)
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
- else
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
+ if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
+ goto check_carry;
+
+ return;
+ }
+
+ if((size == 1) && (0 == (lp1&0xff))) {
+ /* lower byte of signed word is zero */
+ DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
+ i = ((lp1 >> 8) & 0xff) ^0x80;
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
+ pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
+ pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
+
+ if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result))) {
+ emitTOGC;
+ if(ifx) ifx->generated = 1;
+ goto check_carry;
+ } else {
+ rFalseIfx.condition ^= 1;
+ genSkipc(&rFalseIfx);
+ if(ifx) ifx->generated = 1;
+ }
+
+ return;
+ }
+ if(lit & (0x80 << (size*8))) {
+ /* Lit is less than zero */
+ DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
+ //rFalseIfx.condition ^= 1;
+ //genSkipCond(&rFalseIfx,left,size,7);
+ //rFalseIfx.condition ^= 1;
+ pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+ //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
+
+ if(rFalseIfx.condition)
+ pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
+ else
+ pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
- } else {
- /* Lit is greater than or equal to zero */
- DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
- //rFalseIfx.condition ^= 1;
- //genSkipCond(&rFalseIfx,right,size,7);
- //rFalseIfx.condition ^= 1;
- //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
- //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
+ } else {
+ /* Lit is greater than or equal to zero */
+ DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
+ //rFalseIfx.condition ^= 1;
+ //genSkipCond(&rFalseIfx,right,size,7);
+ //rFalseIfx.condition ^= 1;
+
+ //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
+ //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
+
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+ if(rFalseIfx.condition)
+ pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
+ else
+ pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- if(rFalseIfx.condition)
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
- else
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
+ }
- }
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
+ pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
+ while(size--) {
- while(size--) {
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
+ emitSKPNZ;
+ pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
+ }
+ rFalseIfx.condition ^= 1;
+ //rFalseIfx.condition = 1;
+ genSkipc(&rFalseIfx);
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
- emitSKPNZ;
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
- }
- rFalseIfx.condition ^= 1;
- //rFalseIfx.condition = 1;
- genSkipc(&rFalseIfx);
+ pic16_emitpLabel(truelbl->key);
- pic16_emitpLabel(truelbl->key);
-
- if(ifx) ifx->generated = 1;
+ if(ifx) ifx->generated = 1;
if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
goto check_carry;
- return;
- // end of if (sign)
- } else {
+ return;
+ // end of if (sign)
+ } else {
- /* compare word or long to an unsigned literal on the right.*/
+ /* compare word or long to an unsigned literal on the right.*/
- size--;
- if(lit < 0xff) {
- DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
- switch (lit) {
- case 0:
- break; /* handled above */
+ size--;
+ if(lit < 0xff) {
+ DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
+ switch (lit) {
+ case 0:
+ break; /* handled above */
/*
- case 0xff:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
- while(size--)
- pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
- genSkipz2(&rFalseIfx,0);
- break;
+ case 0xff:
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
+ while(size--)
+ pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
+ genSkipz2(&rFalseIfx,0);
+ break;
*/
- default:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
- while(--size)
- pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
+ default:
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
+ while(--size)
+ pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
- emitSKPZ;
- if(rFalseIfx.condition)
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
- else
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
+ emitSKPZ;
+ if(rFalseIfx.condition)
+ pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
+ else
+ pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
+ pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
- rFalseIfx.condition ^= 1;
- genSkipc(&rFalseIfx);
- }
+ rFalseIfx.condition ^= 1;
+ genSkipc(&rFalseIfx);
+ }
- pic16_emitpLabel(truelbl->key);
+ pic16_emitpLabel(truelbl->key);
- if(ifx) ifx->generated = 1;
+ if(ifx) ifx->generated = 1;
if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
goto check_carry;
- return;
- }
+ return;
+ }
- lit++;
- DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
- i = (lit >> (size*8)) & 0xff;
+ lit++;
+ DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
+ i = (lit >> (size*8)) & 0xff;
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
+ pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
- while(size--) {
- i = (lit >> (size*8)) & 0xff;
+ while(size--) {
+ i = (lit >> (size*8)) & 0xff;
- if(i) {
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
- emitSKPNZ;
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
- } else {
- /* this byte of the lit is zero,
- * if it's not the last then OR in the variable */
- if(size)
- pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
- }
- }
+ if(i) {
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
+ emitSKPNZ;
+ pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
+ } else {
+ /* this byte of the lit is zero,
+ * if it's not the last then OR in the variable */
+ if(size)
+ pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
+ }
+ }
- pic16_emitpLabel(lbl->key);
+ pic16_emitpLabel(lbl->key);
- rFalseIfx.condition ^= 1;
+ rFalseIfx.condition ^= 1;
- genSkipc(&rFalseIfx);
- }
+ genSkipc(&rFalseIfx);
+ }
- if(sign)
- pic16_emitpLabel(truelbl->key);
- if(ifx) ifx->generated = 1;
+ if(sign)
+ pic16_emitpLabel(truelbl->key);
+ if(ifx) ifx->generated = 1;
if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
goto check_carry;
- return;
+ return;
}
}
/* Compare two variables */
if(sign) {
/* Sigh. thus sucks... */
if(size) {
- pCodeOp *pctemp;
-
- pctemp = pic16_popGetTempReg(1);
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
- pic16_emitpcode(POC_MOVWF, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
- pic16_emitpcode(POC_XORWF, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
- pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
- pic16_emitpcode(POC_SUBFW, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
- pic16_popReleaseTempReg(pctemp, 1);
+ pCodeOp *pctemp;
+
+ pctemp = pic16_popGetTempReg(1);
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
+ pic16_emitpcode(POC_MOVWF, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
+ pic16_emitpcode(POC_XORWF, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
+ pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
+ pic16_emitpcode(POC_SUBFW, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
+ pic16_popReleaseTempReg(pctemp, 1);
} else {
- /* Signed char comparison */
- /* Special thanks to Nikolai Golovchenko for this snippet */
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
- pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
-
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- genSkipc(&rFalseIfx);
-
- if(ifx) ifx->generated = 1;
+ /* Signed char comparison */
+ /* Special thanks to Nikolai Golovchenko for this snippet */
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
+ pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
+ pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
+ pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
+ pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
+ pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
+
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ genSkipc(&rFalseIfx);
+
+ if(ifx) ifx->generated = 1;
if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
goto check_carry;
- return;
+ return;
}
} else {
pic16_emitpLabel(lbl->key);
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
- (AOP_TYPE(result) == AOP_REG)) {
+ if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
+ (AOP_TYPE(result) == AOP_REG)) {
pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
} else {
genSkipc(&rFalseIfx);
- }
+ }
//genSkipc(&rFalseIfx);
if(ifx) ifx->generated = 1;
}
check_carry:
- if ((AOP_TYPE(result) != AOP_CRY)
- && AOP_SIZE(result)) {
+ if ((AOP_TYPE(result) != AOP_CRY)
+ && AOP_SIZE(result)) {
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if(!ifx)pic16_emitpLabel( rFalseIfx.lbl->key );
}
-#elif 0 /* VR version of genCmp() */ /* } else { */
+#elif 0 /* VR version of genCmp() */ /* } else { */
/* check all condition and return appropriate instruction, POC_CPFSGT or POC_CPFFSLT */
static int selectCompareOp(resolvedIfx *rIfx, iCode *ifx,
operand *result, int offset, int invert_op)
{
/* add code here */
-
+
/* check condition, > or < ?? */
if(rIfx->condition != 0)invert_op ^= 1;
-
+
if(ifx && IC_FALSE(ifx))invert_op ^= 1;
if(!ifx)invert_op ^= 1;
DEBUGpic16_emitcode("; +++", "%s:%d %s] rIfx->condition= %d, ifx&&IC_FALSE(ifx)= %d, invert_op = %d",
__FILE__, __LINE__, __FUNCTION__, rIfx->condition, (ifx && IC_FALSE(ifx)), invert_op);
-
+
/* do selection */
if(!invert_op)return POC_CPFSGT;
else return POC_CPFSLT;
if(AOP_SIZE(result))invert_op ^= 1;
// if(sign && !offset)invert_op ^= 1;
-
+
// if(sign)invert_op ^= 1;
-
+
op = selectCompareOp(resIfx, ifx, result, offset, invert_op);
if(AOP_SIZE(result) && compareAopfirstpass) {
* to the next lower byte, current algorithm, considers operands
* inequal in these cases! -- VR 20041107 */
-
+
if(pcop)
pic16_emitpcode(op, pcop);
else
else
emitSETC;
}
-
+
/* don't emit final branch (offset == 0) */
if(offset) {
symbol *falselbl, *tlbl;
FENTRY;
-
+
DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
resolveIfx(&rFalseIfx, ifx);
size = max(AOP_SIZE(left), AOP_SIZE(right));
-
+
/* if left & right are bit variables */
if(AOP_TYPE(left) == AOP_CRY
&& AOP_TYPE(right) == AOP_CRY ) {
pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
-
+
werror(W_POSSBUG2, __FILE__, __LINE__);
exit(EXIT_FAILURE);
}
-
+
/* if literal is on the right then swap with left */
if((AOP_TYPE(right) == AOP_LIT)) {
operand *tmp = right ;
// unsigned long mask = (0x100 << (8*(size-1))) - 1;
- lit = /*(unsigned long)*/floatFromVal(AOP(right)->aopu.aop_lit);
+ lit = ulFromVal (AOP(right)->aopu.aop_lit);
// lit = (lit - 1) & mask;
right = left;
left = tmp;
- rFalseIfx.condition ^= 1; /* reverse compare */
+ rFalseIfx.condition ^= 1; /* reverse compare */
} else
if ((AOP_TYPE(left) == AOP_LIT)) {
/* float compares are handled by support functions */
- lit = /*(unsigned long)*/floatFromVal(AOP(left)->aopu.aop_lit);
+ lit = ulFromVal(AOP(left)->aopu.aop_lit);
}
/* actual comparing algorithm */
if(AOP_TYPE(left) == AOP_LIT) {
/* compare to literal */
DEBUGpic16_emitcode ("; ***","%s: %d: compare to literal", __FUNCTION__, __LINE__);
-
+
if(sign) {
pCodeOp *pct, *pct2;
symbol *tlbl1;
pct = pic16_popCopyReg(&pic16_pc_prodl);
pct2 = pic16_popCopyReg(&pic16_pc_prodh);
tlbl = newiTempLabel( NULL );
-
+
/* first compare signs:
* a. if both are positive, compare just like unsigned
* b. if both are negative, invert cmpop, compare just like unsigned
size--;
#if 1
- /* { */
+ /* { */
tlbl1 = newiTempLabel( NULL );
-// pic16_emitpcode(POC_RLCFW, pic16_popGet( AOP(right), size)); /* move sign to carry */
+// pic16_emitpcode(POC_RLCFW, pic16_popGet( AOP(right), size)); /* move sign to carry */
if(lit > 0) {
/* literal is zero or positive:
* a. if carry is zero, too, continue compare,
* b. if carry is set, then continue depending on cmpop ^ condition:
- * 1. '<' return false (literal < variable),
- * 2. '>' return true (literal > variable) */
+ * 1. '<' return false (literal < variable),
+ * 2. '>' return true (literal > variable) */
// pic16_emitpcode(POC_BNC, pic16_popGetLabel( tlbl1->key ));
pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(pic16_popGet(AOP(right), size), 7));
-
-
+
+
if(cmpop ^ rFalseIfx.condition)pic16_emitpcode(POC_GOTO, pic16_popGetLabel( tlbl->key ));
else pic16_emitpcode(POC_GOTO, pic16_popGetLabel( rFalseIfx.lbl->key ));
- } else
+ } else
if(lit < 0) {
-
+
/* literal is negative:
* a. if carry is set, too, continue compare,
* b. if carry is zero, then continue depending on cmpop ^ condition:
- * 1. '<' return true (literal < variable),
- * 2. '>' return false (literal > variable) */
+ * 1. '<' return true (literal < variable),
+ * 2. '>' return false (literal > variable) */
// pic16_emitpcode(POC_BC, pic16_popGetLabel( tlbl1->key ));
pic16_emitpcode(POC_BTFSS, pic16_popCopyGPR2Bit(pic16_popGet(AOP(right), size), 7));
-
+
if(!(cmpop ^ rFalseIfx.condition))pic16_emitpcode(POC_GOTO, pic16_popGetLabel( tlbl->key ));
else pic16_emitpcode(POC_GOTO, pic16_popGetLabel( rFalseIfx.lbl->key));
}
else {
/* lit == 0 */
pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(pic16_popGet(AOP(right), size), 7));
-
+
if(!(cmpop ^ rFalseIfx.condition))pic16_emitpcode(POC_GOTO, pic16_popGetLabel( tlbl->key ));
else pic16_emitpcode(POC_GOTO, pic16_popGetLabel( rFalseIfx.lbl->key));
}
#endif
-
-
+
+
pic16_emitpLabel( tlbl1->key );
-#endif /* } */
+#endif /* } */
compareAopfirstpass=1;
// pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
// compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl);
compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, pct2, tlbl);
- /* generic case */
+ /* generic case */
while( size-- ) {
// pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
// pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0));
// compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl);
// compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 0, pct, pct2, tlbl);
}
-
+
if(ifx)ifx->generated = 1;
if(AOP_SIZE(result)) {
}
} else {
- /* unsigned compare */
+ /* unsigned compare */
DEBUGpic16_emitcode ("; ***","%s: %d: unsigned compare", __FUNCTION__, __LINE__);
-
+
compareAopfirstpass=1;
while(size--) {
-
+
pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size)));
compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, NULL, NULL);
if(sign) {
pCodeOp *pct, *pct2;
-
+
/* signed compare */
DEBUGpic16_emitcode ("; ***","%s: %d: signed compare", __FUNCTION__, __LINE__);
- pct = pic16_popCopyReg(&pic16_pc_prodl); /* first temporary register */
- pct2 = pic16_popCopyReg(&pic16_pc_prodh); /* second temporary register */
+ pct = pic16_popCopyReg(&pic16_pc_prodl); /* first temporary register */
+ pct2 = pic16_popCopyReg(&pic16_pc_prodh); /* second temporary register */
tlbl = newiTempLabel( NULL );
-
+
compareAopfirstpass=1;
size--;
/* WREG already holds left + 0x80 */
compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl);
-
+
while( size-- ) {
pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), size));
// pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0));
pic16_emitpcode(POC_MOVWF, pct);
-
+
pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), size));
// pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0));
compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl);
// compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 0, pct, pct2, tlbl);
}
-
+
if(ifx)ifx->generated = 1;
if(AOP_SIZE(result)) {
}
} else {
- /* unsigned compare */
+ /* unsigned compare */
DEBUGpic16_emitcode ("; ***","%s: %d: unsigned compare", __FUNCTION__, __LINE__);
compareAopfirstpass=1;
while(size--) {
-
+
pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), size));
compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, NULL, NULL);
}
}
-#endif /* } */
+#endif /* } */
int sign ;
FENTRY;
-
+
left = IC_LEFT(ic);
right= IC_RIGHT(ic);
result = IC_RESULT(ic);
pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- pic16_freeAsmop(result,NULL,ic,TRUE);
+ pic16_freeAsmop(result,NULL,ic,TRUE);
}
/*-----------------------------------------------------------------*/
pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- pic16_freeAsmop(result,NULL,ic,TRUE);
+ pic16_freeAsmop(result,NULL,ic,TRUE);
}
#if 0
int i;
DEBUGpic16_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
- if( (lit&0xff) == 0)
+ if( (lit&0xff) == 0)
i=1;
else
i=0;
- switch( BYTEofLONG(lit,i)) {
+ switch( BYTEofLONG(lit,i)) {
case 0:
pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
break;
i ^= 1;
- switch( BYTEofLONG(lit,i)) {
+ switch( BYTEofLONG(lit,i)) {
case 0:
pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
break;
lbl_done = newiTempLabel(NULL);
- /* if the left side is a literal or
- if the right is in a pointer register and left
+ /* if the left side is a literal or
+ if the right is in a pointer register and left
is not */
- if ((AOP_TYPE(left) == AOP_LIT) ||
+ if ((AOP_TYPE(left) == AOP_LIT) ||
(IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
operand *t = right;
right = left;
left = t;
}
if(AOP_TYPE(right) == AOP_LIT)
- lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
+ lit = ulFromVal (AOP(right)->aopu.aop_lit);
if ( regsInCommon(left, result) || regsInCommon(right, result) )
preserve_result = 1;
default:
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
while (size--) {
- if(lit & 0xff) {
- pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
- pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
- } else {
- pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
- }
-
- emitSKPZ;
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
- offset++;
- if(res_offset < res_size-1)
- res_offset++;
- lit >>= 8;
+ if(lit & 0xff) {
+ pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
+ pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
+ } else {
+ pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
+ }
+
+ emitSKPZ;
+ pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
+ offset++;
+ if(res_offset < res_size-1)
+ res_offset++;
+ lit >>= 8;
}
break;
}
}
/* if the right side is in a register or in direct space or
- if the left is a pointer register & right is not */
+ if the left is a pointer register & right is not */
else if (AOP_TYPE(right) == AOP_REG ||
- AOP_TYPE(right) == AOP_DIR ||
- (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
- (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
+ AOP_TYPE(right) == AOP_DIR ||
+ (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
+ (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
//int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
int lbl_key = lbl->key;
}else {
DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
fprintf(stderr, "%s %d error - expecting result to be non_null\n",
- __FUNCTION__,__LINE__);
+ __FUNCTION__,__LINE__);
return;
}
-
+
/* switch(size) { */
/* case 2: */
/* genc16bit2lit(left, lit, 0); */
/* default: */
while (size--) {
int emit_skip=1;
- if((AOP_TYPE(left) == AOP_DIR) &&
- ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
+ if((AOP_TYPE(left) == AOP_DIR) &&
+ ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
- pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
- pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
+ pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
+ pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
} else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
-
- switch (lit & 0xff) {
- case 0:
- pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
- break;
- case 1:
- pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
- //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
- emit_skip=0;
- break;
- case 0xff:
- pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
- //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
- //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
- emit_skip=0;
- break;
- default:
- pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
- pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
- }
- lit >>= 8;
+
+ switch (lit & 0xff) {
+ case 0:
+ pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
+ break;
+ case 1:
+ pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
+ //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
+ pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
+ emit_skip=0;
+ break;
+ case 0xff:
+ pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
+ //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
+ //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
+ pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
+ emit_skip=0;
+ break;
+ default:
+ pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
+ pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
+ }
+ lit >>= 8;
} else {
- pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
+ pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
}
if(emit_skip) {
- if(AOP_TYPE(result) == AOP_CRY) {
- pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
- if(rIfx.condition)
- emitSKPNZ;
- else
- emitSKPZ;
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
- } else {
- /* fix me. probably need to check result size too */
- //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
- if(rIfx.condition)
- emitSKPZ;
- else
- emitSKPNZ;
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
- //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
- }
- if(ifx)
- ifx->generated=1;
+ if(AOP_TYPE(result) == AOP_CRY) {
+ pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
+ if(rIfx.condition)
+ emitSKPNZ;
+ else
+ emitSKPZ;
+ pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
+ } else {
+ /* fix me. probably need to check result size too */
+ //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
+ if(rIfx.condition)
+ emitSKPZ;
+ else
+ emitSKPNZ;
+ pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
+ //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
+ }
+ if(ifx)
+ ifx->generated=1;
}
emit_skip++;
offset++;
if(res_offset < res_size-1)
- res_offset++;
+ res_offset++;
}
/* break; */
/* } */
} else if(AOP_TYPE(right) == AOP_REG &&
- AOP_TYPE(left) != AOP_DIR){
+ AOP_TYPE(left) != AOP_DIR){
while(size--) {
pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
if(rIfx.condition)
- emitSKPNZ;
+ emitSKPNZ;
else
- emitSKPZ;
+ emitSKPZ;
pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
offset++;
if(res_offset < res_size-1)
- res_offset++;
+ res_offset++;
}
-
+
}else{
/* right is a pointer reg need both a & b */
while(size--) {
char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
if(strcmp(l,"b"))
- pic16_emitcode("mov","b,%s",l);
+ pic16_emitcode("mov","b,%s",l);
MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
- pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
+ pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
offset++;
}
}
unsigned long lit = -1;
FENTRY;
-
+
pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
-
+
DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
if( (AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(left) == AOP_CRY) )
}
if (AOP_TYPE(right) == AOP_LIT) {
- lit = (unsigned long) floatFromVal (AOP(right)->aopu.aop_lit);
+ lit = ulFromVal (AOP(right)->aopu.aop_lit);
}
if ( regsInCommon(left, result) || regsInCommon(right, result) )
}
if(is_LitOp(right)) {
if (is_LitOp(left) || (0 != ((lit >> (8*i))&0x00FF))) {
- pic16_emitpcode(POC_XORLW, pic16_popGet(AOP(right), i));
+ pic16_emitpcode(POC_XORLW, pic16_popGet(AOP(right), i));
}
} else
- pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right), i));
+ pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right), i));
pic16_emitpcode(POC_BNZ,pic16_popGetLabel(falselbl->key));
}
DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
- /* if literal, literal on the right or
- if the right is in a pointer register and left
+ /* if literal, literal on the right or
+ if the right is in a pointer register and left
is not */
- if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
+ if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
(IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
operand *tmp = right ;
right = left;
if(ifx && !AOP_SIZE(result)){
symbol *tlbl;
- DEBUGpic16_emitcode ("; ***","%s %d CASE 1",__FUNCTION__,__LINE__);
+ DEBUGpic16_emitcode ("; ***","%s %d CASE 1",__FUNCTION__,__LINE__);
/* if they are both bit variables */
if (AOP_TYPE(left) == AOP_CRY &&
((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
- DEBUGpic16_emitcode ("; ***","%s %d CASE 11",__FUNCTION__,__LINE__);
+ DEBUGpic16_emitcode ("; ***","%s %d CASE 11",__FUNCTION__,__LINE__);
if(AOP_TYPE(right) == AOP_LIT){
- unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
+ unsigned long lit = ulFromVal (AOP(right)->aopu.aop_lit);
if(lit == 0L){
pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
pic16_emitcode("cpl","c");
}
pic16_emitcode("","%05d_DS_:",tlbl->key+100+pic16_labelOffset);
- {
- /* left and right are both bit variables, result is carry */
- resolvedIfx rIfx;
-
- resolveIfx(&rIfx,ifx);
-
- pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
- pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
- genSkipz2(&rIfx,0);
- }
+ {
+ /* left and right are both bit variables, result is carry */
+ resolvedIfx rIfx;
+
+ resolveIfx(&rIfx,ifx);
+
+ pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
+ pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
+ pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
+ pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
+ genSkipz2(&rIfx,0);
+ }
} else {
- DEBUGpic16_emitcode ("; ***","%s %d CASE 12",__FUNCTION__,__LINE__);
-
- /* They're not both bit variables. Is the right a literal? */
- if(AOP_TYPE(right) == AOP_LIT) {
- lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
-
- switch(size) {
-
- case 1:
- switch(lit & 0xff) {
- case 1:
- if ( IC_TRUE(ifx) ) {
- pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
- emitSKPNZ;
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
- } else {
- pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
- }
- break;
- case 0xff:
- if ( IC_TRUE(ifx) ) {
- pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
- emitSKPNZ;
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
- } else {
- pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
- }
- break;
- default:
- pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
- if(lit)
- pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
- genSkip(ifx,'z');
- } // switch lit
-
-
- /* end of size == 1 */
- break;
-
- case 2:
- genc16bit2lit(left,lit,offset);
- genSkip(ifx,'z');
- break;
- /* end of size == 2 */
-
- default:
- /* size is 4 */
- if(lit==0) {
- pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
- pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
- pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
- genSkip(ifx,'z');
- } else {
- /* search for patterns that can be optimized */
-
- genc16bit2lit(left,lit,0);
- lit >>= 16;
- if(lit) {
- if(IC_TRUE(ifx))
- emitSKPZ; // if hi word unequal
- else
- emitSKPNZ; // if hi word equal
- // fail early
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(falselbl->key));
- genc16bit2lit(left,lit,2);
- genSkip(ifx,'z');
- } else {
- pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
- pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
- genSkip(ifx,'z');
- }
- }
- pic16_emitpLabel(falselbl->key);
- break;
-
- } // switch size
-
- ifx->generated = 1;
- goto release ;
-
-
- } else if(AOP_TYPE(right) == AOP_CRY ) {
- /* we know the left is not a bit, but that the right is */
- pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
- pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
- pic16_popGet(AOP(right),offset));
- pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
-
- /* if the two are equal, then W will be 0 and the Z bit is set
- * we could test Z now, or go ahead and check the high order bytes if
- * the variable we're comparing is larger than a byte. */
-
- while(--size)
- pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
-
- if ( IC_TRUE(ifx) ) {
- emitSKPNZ;
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
- // pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset);
- } else {
- emitSKPZ;
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
- // pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset);
- }
-
- } else {
- /* They're both variables that are larger than bits */
- int s = size;
-
- tlbl = newiTempLabel(NULL);
-
- while(size--) {
- pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
- pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
-
- if ( IC_TRUE(ifx) ) {
- if(size) {
- emitSKPZ;
-
- DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPZ");
-
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
- pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+pic16_labelOffset);
- } else {
- emitSKPNZ;
-
- DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPNZ");
-
-
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
- pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset);
- }
- } else {
- emitSKPZ;
-
- DEBUGpic16_emitcode (";","\tnot IC_TRUE emitSKPZ");
-
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
- pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset);
- }
- offset++;
- }
- if(s>1 && IC_TRUE(ifx)) {
- pic16_emitpLabel(tlbl->key);
- pic16_emitcode("","_%05d_DS_:",tlbl->key+100+pic16_labelOffset);
- }
- }
+ DEBUGpic16_emitcode ("; ***","%s %d CASE 12",__FUNCTION__,__LINE__);
+
+ /* They're not both bit variables. Is the right a literal? */
+ if(AOP_TYPE(right) == AOP_LIT) {
+ lit = ulFromVal (AOP(right)->aopu.aop_lit);
+
+ switch(size) {
+
+ case 1:
+ switch(lit & 0xff) {
+ case 1:
+ if ( IC_TRUE(ifx) ) {
+ pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
+ emitSKPNZ;
+ pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
+ } else {
+ pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
+ pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
+ }
+ break;
+ case 0xff:
+ if ( IC_TRUE(ifx) ) {
+ pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
+ emitSKPNZ;
+ pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
+ } else {
+ pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
+ pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
+ }
+ break;
+ default:
+ pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
+ if(lit)
+ pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
+ genSkip(ifx,'z');
+ } // switch lit
+
+
+ /* end of size == 1 */
+ break;
+
+ case 2:
+ genc16bit2lit(left,lit,offset);
+ genSkip(ifx,'z');
+ break;
+ /* end of size == 2 */
+
+ default:
+ /* size is 4 */
+ if(lit==0) {
+ pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
+ pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
+ pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
+ pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
+ genSkip(ifx,'z');
+ } else {
+ /* search for patterns that can be optimized */
+
+ genc16bit2lit(left,lit,0);
+ lit >>= 16;
+ if(lit) {
+ if(IC_TRUE(ifx))
+ emitSKPZ; // if hi word unequal
+ else
+ emitSKPNZ; // if hi word equal
+ // fail early
+ pic16_emitpcode(POC_GOTO,pic16_popGetLabel(falselbl->key));
+ genc16bit2lit(left,lit,2);
+ genSkip(ifx,'z');
+ } else {
+ pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
+ pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
+ genSkip(ifx,'z');
+ }
+ }
+ pic16_emitpLabel(falselbl->key);
+ break;
+
+ } // switch size
+
+ ifx->generated = 1;
+ goto release ;
+
+
+ } else if(AOP_TYPE(right) == AOP_CRY ) {
+ /* we know the left is not a bit, but that the right is */
+ pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
+ pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
+ pic16_popGet(AOP(right),offset));
+ pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
+
+ /* if the two are equal, then W will be 0 and the Z bit is set
+ * we could test Z now, or go ahead and check the high order bytes if
+ * the variable we're comparing is larger than a byte. */
+
+ while(--size)
+ pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
+
+ if ( IC_TRUE(ifx) ) {
+ emitSKPNZ;
+ pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
+ // pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset);
+ } else {
+ emitSKPZ;
+ pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
+ // pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset);
+ }
+
+ } else {
+ /* They're both variables that are larger than bits */
+ int s = size;
+
+ tlbl = newiTempLabel(NULL);
+
+ while(size--) {
+ pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
+ pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
+
+ if ( IC_TRUE(ifx) ) {
+ if(size) {
+ emitSKPZ;
+
+ DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPZ");
+
+ pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
+ pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+pic16_labelOffset);
+ } else {
+ emitSKPNZ;
+
+ DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPNZ");
+
+
+ pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
+ pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset);
+ }
+ } else {
+ emitSKPZ;
+
+ DEBUGpic16_emitcode (";","\tnot IC_TRUE emitSKPZ");
+
+ pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
+ pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset);
+ }
+ offset++;
+ }
+ if(s>1 && IC_TRUE(ifx)) {
+ pic16_emitpLabel(tlbl->key);
+ pic16_emitcode("","_%05d_DS_:",tlbl->key+100+pic16_labelOffset);
+ }
+ }
}
/* mark the icode as generated */
ifx->generated = 1;
/* if they are both bit variables */
if (AOP_TYPE(left) == AOP_CRY &&
((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
- DEBUGpic16_emitcode ("; ***","%s %d CASE 2",__FUNCTION__,__LINE__);
+ DEBUGpic16_emitcode ("; ***","%s %d CASE 2",__FUNCTION__,__LINE__);
if(AOP_TYPE(right) == AOP_LIT){
- unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
+ unsigned long lit = ulFromVal (AOP(right)->aopu.aop_lit);
if(lit == 0L){
pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
pic16_emitcode("cpl","c");
then put the result in place */
pic16_outBitC(result);
} else {
-
+
DEBUGpic16_emitcode ("; ***","%s %d CASE 3",__FUNCTION__,__LINE__);
gencjne(left,right,result,ifx);
/*
- if(ifx)
- gencjne(left,right,newiTempLabel(NULL));
+ if(ifx)
+ gencjne(left,right,newiTempLabel(NULL));
else {
- if(IC_TRUE(ifx)->key)
- gencjne(left,right,IC_TRUE(ifx)->key);
- else
- gencjne(left,right,IC_FALSE(ifx)->key);
- ifx->generated = 1;
- goto release ;
+ if(IC_TRUE(ifx)->key)
+ gencjne(left,right,IC_TRUE(ifx)->key);
+ else
+ gencjne(left,right,IC_FALSE(ifx)->key);
+ ifx->generated = 1;
+ goto release ;
}
if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
- pic16_aopPut(AOP(result),"a",0);
- goto release ;
+ pic16_aopPut(AOP(result),"a",0);
+ goto release ;
}
if (ifx) {
- genIfxJump (ifx,"a");
- goto release ;
+ genIfxJump (ifx,"a");
+ goto release ;
}
*/
/* if the result is used in an arithmetic operation
- then put the result in place */
+ then put the result in place */
/*
- if (AOP_TYPE(result) != AOP_CRY)
- pic16_outAcc(result);
+ if (AOP_TYPE(result) != AOP_CRY)
+ pic16_outAcc(result);
*/
/* leave the result in acc */
}
the next instruction is ifx with the same operand
and live to of the operand is upto the ifx only then */
if (ic->next
- && ic->next->op == IFX
+ && ic->next->op == IFX
&& IC_COND(ic->next)->key == op->key
&& OP_SYMBOL(op)->liveTo <= ic->next->seq
) {
- DEBUGpic16_emitcode(";", "%d %s", __LINE__, __FUNCTION__);
+ DEBUGpic16_emitcode(";", "%d %s", __LINE__, __FUNCTION__);
return ic->next;
}
IC_COND(ic->next)->key == op->key) {
DEBUGpic16_emitcode ("; "," key is okay");
DEBUGpic16_emitcode ("; "," key liveTo %d, next->seq = %d",
- OP_SYMBOL(op)->liveTo,
- ic->next->seq);
+ OP_SYMBOL(op)->liveTo,
+ ic->next->seq);
}
#if 0
/* the code below is completely untested
* it just allows ulong2fs.c compile -- VR */
-
+
ic = ic->next;
fprintf(stderr, "WARNING (%s:%s:%d) untested hack might produce wrong code\n",
- __FILE__, __FUNCTION__, __LINE__);
-
+ __FILE__, __FUNCTION__, __LINE__);
+
/* if this has register type condition and
the next instruction is ifx with the same operand
and live to of the operand is upto the ifx only then */
}
fprintf(stderr, "WARNING (%s:%s:%d) untested hack might produce wrong code (returning NULL)\n",
- __FILE__, __FUNCTION__, __LINE__);
+ __FILE__, __FUNCTION__, __LINE__);
-// return ic->next->next; /* this just might work */ /* FIXME FIXME */
+// return ic->next->next; /* this just might work */ /* FIXME FIXME */
#endif
return NULL;
operand *left,*right, *result;
symbol *tlbl;
- FENTRY;
+ FENTRY;
/* note here that || operations that are in an
if statement are taken away by backPatchLabels
AOP_TYPE(right) == AOP_CRY ) {
pic16_emitcode("clrc","");
pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
- AOP(left)->aopu.aop_dir,
- AOP(left)->aopu.aop_dir);
+ AOP(left)->aopu.aop_dir,
+ AOP(left)->aopu.aop_dir);
pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
- AOP(right)->aopu.aop_dir,
- AOP(right)->aopu.aop_dir);
+ AOP(right)->aopu.aop_dir,
+ AOP(right)->aopu.aop_dir);
pic16_emitcode("setc","");
} else {
tlbl = newiTempLabel(NULL);
pic16_toBoolean(left);
- emitSKPZ;
+ emitSKPZ;
pic16_emitcode("goto","%05d_DS_",tlbl->key+100+pic16_labelOffset);
pic16_toBoolean(right);
pic16_emitcode("","%05d_DS_:",tlbl->key+100+pic16_labelOffset);
pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- pic16_freeAsmop(result,NULL,ic,TRUE);
+ pic16_freeAsmop(result,NULL,ic,TRUE);
}
/*-----------------------------------------------------------------*/
0x1000000L,0x2000000L,0x4000000L,0x8000000L,
0x10000000L,0x20000000L,0x40000000L,0x80000000L};
int idx;
-
+
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
for(idx = 0; idx < 32; idx++)
if(lit == pw[idx])
FENTRY;
if(IC_TRUE(ic)){
symbol *nlbl = newiTempLabel(NULL);
- pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);
+ pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);
pic16_emitcode("","%05d_DS_:",tlbl->key+100);
pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
pic16_emitcode("","%05d_DS_:",nlbl->key+100);
static void genAnd (iCode *ic, iCode *ifx)
{
operand *left, *right, *result;
- int size, offset=0;
+ int size, offset=0;
unsigned long lit = 0L;
int bytelit = 0;
resolvedIfx rIfx;
FENTRY;
-
+
pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
left = tmp;
}
if(AOP_TYPE(right) == AOP_LIT)
- lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
+ lit = ulFromVal (AOP(right)->aopu.aop_lit);
size = AOP_SIZE(result);
// c = bit & literal;
if(AOP_TYPE(right) == AOP_LIT){
if(lit & 1) {
- if(size && pic16_sameRegs(AOP(result),AOP(left)))
- // no change
- goto release;
- pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
+ if(size && pic16_sameRegs(AOP(result),AOP(left)))
+ // no change
+ goto release;
+ pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
} else {
- // bit(result) = 0;
- if(size && (AOP_TYPE(result) == AOP_CRY)){
- pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
- goto release;
- }
- if((AOP_TYPE(result) == AOP_CRY) && ifx){
- jumpIfTrue(ifx);
- goto release;
- }
- pic16_emitcode("clr","c");
+ // bit(result) = 0;
+ if(size && (AOP_TYPE(result) == AOP_CRY)){
+ pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
+ goto release;
+ }
+ if((AOP_TYPE(result) == AOP_CRY) && ifx){
+ jumpIfTrue(ifx);
+ goto release;
+ }
+ pic16_emitcode("clr","c");
}
} else {
if (AOP_TYPE(right) == AOP_CRY){
- // c = bit & bit;
- pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
- pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
+ // c = bit & bit;
+ pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
+ pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
} else {
- // c = bit & val;
- MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
- // c = lsb
- pic16_emitcode("rrc","a");
- pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
+ // c = bit & val;
+ MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
+ // c = lsb
+ pic16_emitcode("rrc","a");
+ pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
}
}
// bit = c
pic16_outBitC(result);
// if(bit & ...)
else if((AOP_TYPE(result) == AOP_CRY) && ifx)
- genIfxJump(ifx, "c");
+ genIfxJump(ifx, "c");
goto release ;
}
//MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE));
// bit = left & 2^n
if(size)
- pic16_emitcode("mov","c,acc.%d",posbit&0x07);
+ pic16_emitcode("mov","c,acc.%d",posbit&0x07);
// if(left & 2^n)
else{
- if(ifx){
+ if(ifx){
/*
- if(IC_TRUE(ifx)) {
- pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
- } else {
- pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
- }
+ if(IC_TRUE(ifx)) {
+ pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
+ pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
+ } else {
+ pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
+ pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
+ }
*/
- DEBUGpic16_emitcode("***", "%d %s", __LINE__, __FUNCTION__);
- size = AOP_SIZE(left);
+ DEBUGpic16_emitcode("***", "%d %s", __LINE__, __FUNCTION__);
+ size = AOP_SIZE(left);
+
+ {
+ int bp = posbit, ofs=0;
- {
- int bp = posbit, ofs=0;
-
- while(bp > 7) {
- bp -= 8;
- ofs++;
- }
+ while(bp > 7) {
+ bp -= 8;
+ ofs++;
+ }
- pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
- pic16_newpCodeOpBit(pic16_aopGet(AOP(left),ofs,FALSE,FALSE),bp,0, PO_GPR_REGISTER));
+ pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
+ pic16_newpCodeOpBit(pic16_aopGet(AOP(left),ofs,FALSE,FALSE),bp,0, PO_GPR_REGISTER));
- }
+ }
/*
- pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
- pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
+ pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
+ pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
*/
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
-
- ifx->generated = 1;
- }
- goto release;
+ pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
+
+ ifx->generated = 1;
+ }
+ goto release;
}
} else {
symbol *tlbl = newiTempLabel(NULL);
pic16_emitpcode(((rIfx.condition) ? POC_BZ : POC_BNZ),
pic16_popGetLabel(tlbl->key));
}
-
+
#if 0
/* old code, left here for reference -- VR 09/2004 */
- MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
- // byte == 2^n ?
- if((posbit = isLiteralBit(bytelit)) != 0)
- pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
- else{
- if(bytelit != 0x0FFL)
- pic16_emitcode("anl","a,%s",
- pic16_aopGet(AOP(right),offset,FALSE,TRUE));
- pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
+ MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
+ // byte == 2^n ?
+ if((posbit = isLiteralBit(bytelit)) != 0)
+ pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
+ else{
+ if(bytelit != 0x0FFL)
+ pic16_emitcode("anl","a,%s",
+ pic16_aopGet(AOP(right),offset,FALSE,TRUE));
+ pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
}
#endif
- }
- offset++;
+ }
+ offset++;
}
// bit = left & literal
if(size) {
int know_W = -1;
for(;size--; offset++,lit>>=8) {
if(AOP_TYPE(right) == AOP_LIT){
- switch(lit & 0xff) {
- case 0x00:
- /* and'ing with 0 has clears the result */
-// pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
- pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
- break;
- case 0xff:
- /* and'ing with 0xff is a nop when the result and left are the same */
- break;
-
- default:
- {
- int p = pic16_my_powof2( (~lit) & 0xff );
- if(p>=0) {
- /* only one bit is set in the literal, so use a bcf instruction */
-// pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
- pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0, PO_GPR_REGISTER));
-
- } else {
- pic16_emitcode("movlw","0x%x", (lit & 0xff));
- pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
- if(know_W != (lit&0xff))
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
- know_W = lit &0xff;
- pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
- }
- }
- }
+ switch(lit & 0xff) {
+ case 0x00:
+ /* and'ing with 0 has clears the result */
+// pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
+ pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
+ break;
+ case 0xff:
+ /* and'ing with 0xff is a nop when the result and left are the same */
+ break;
+
+ default:
+ {
+ int p = pic16_my_powof2( (~lit) & 0xff );
+ if(p>=0) {
+ /* only one bit is set in the literal, so use a bcf instruction */
+// pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
+ pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0, PO_GPR_REGISTER));
+
+ } else {
+ pic16_emitcode("movlw","0x%x", (lit & 0xff));
+ pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
+ if(know_W != (lit&0xff))
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
+ know_W = lit &0xff;
+ pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
+ }
+ }
+ }
} else {
- if (AOP_TYPE(left) == AOP_ACC) {
- pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
- } else {
- pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
- pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
+ if (AOP_TYPE(left) == AOP_ACC) {
+ pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
+ } else {
+ pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
+ pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
- }
+ }
}
}
symbol *tlbl = newiTempLabel(NULL);
int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
if(size)
- pic16_emitcode("setb","c");
+ pic16_emitcode("setb","c");
while(sizer--){
- MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
- pic16_emitcode("anl","a,%s",
- pic16_aopGet(AOP(left),offset,FALSE,FALSE));
- pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
- offset++;
+ MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
+ pic16_emitcode("anl","a,%s",
+ pic16_aopGet(AOP(left),offset,FALSE,FALSE));
+ pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
+ offset++;
}
if(size){
- CLRC;
- pic16_emitcode("","%05d_DS_:",tlbl->key+100);
- pic16_outBitC(result);
+ CLRC;
+ pic16_emitcode("","%05d_DS_:",tlbl->key+100);
+ pic16_outBitC(result);
} else if(ifx)
- jmpTrueOrFalse(ifx, tlbl);
+ jmpTrueOrFalse(ifx, tlbl);
} else {
for(;(size--);offset++) {
- // normal case
- // result = left & right
- if(AOP_TYPE(right) == AOP_LIT){
- int t = (lit >> (offset*8)) & 0x0FFL;
- switch(t) {
- case 0x00:
- pic16_emitcode("clrf","%s",
- pic16_aopGet(AOP(result),offset,FALSE,FALSE));
- pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
- break;
- case 0xff:
- pic16_emitcode("movf","%s,w",
- pic16_aopGet(AOP(left),offset,FALSE,FALSE));
- pic16_emitcode("movwf","%s",
- pic16_aopGet(AOP(result),offset,FALSE,FALSE));
- pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
- pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
- break;
- default:
- pic16_emitcode("movlw","0x%x",t);
- pic16_emitcode("andwf","%s,w",
- pic16_aopGet(AOP(left),offset,FALSE,FALSE));
- pic16_emitcode("movwf","%s",
- pic16_aopGet(AOP(result),offset,FALSE,FALSE));
-
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
- pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
- pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
- }
- continue;
- }
-
- if (AOP_TYPE(left) == AOP_ACC) {
- pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
- pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
- } else {
- pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
- pic16_emitcode("andwf","%s,w",
- pic16_aopGet(AOP(left),offset,FALSE,FALSE));
- pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
- pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
- }
- pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
- pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
+ // normal case
+ // result = left & right
+ if(AOP_TYPE(right) == AOP_LIT){
+ int t = (lit >> (offset*8)) & 0x0FFL;
+ switch(t) {
+ case 0x00:
+ pic16_emitcode("clrf","%s",
+ pic16_aopGet(AOP(result),offset,FALSE,FALSE));
+ pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
+ break;
+ case 0xff:
+ pic16_emitcode("movf","%s,w",
+ pic16_aopGet(AOP(left),offset,FALSE,FALSE));
+ pic16_emitcode("movwf","%s",
+ pic16_aopGet(AOP(result),offset,FALSE,FALSE));
+ pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
+ pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
+ break;
+ default:
+ pic16_emitcode("movlw","0x%x",t);
+ pic16_emitcode("andwf","%s,w",
+ pic16_aopGet(AOP(left),offset,FALSE,FALSE));
+ pic16_emitcode("movwf","%s",
+ pic16_aopGet(AOP(result),offset,FALSE,FALSE));
+
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
+ pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
+ pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
+ }
+ continue;
+ }
+
+ if (AOP_TYPE(left) == AOP_ACC) {
+ pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
+ pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
+ } else {
+ pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
+ pic16_emitcode("andwf","%s,w",
+ pic16_aopGet(AOP(left),offset,FALSE,FALSE));
+ pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
+ pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
+ }
+ pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
+ pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
}
}
}
release :
pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- pic16_freeAsmop(result,NULL,ic,TRUE);
+ pic16_freeAsmop(result,NULL,ic,TRUE);
}
/*-----------------------------------------------------------------*/
/* if left is a literal & right is not then exchange them */
if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
- AOP_NEEDSACC(left)) {
+ AOP_NEEDSACC(left)) {
operand *tmp = right ;
right = left;
left = tmp;
DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
if(AOP_TYPE(right) == AOP_LIT)
- lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
+ lit = ulFromVal (AOP(right)->aopu.aop_lit);
size = AOP_SIZE(result);
if(lit){
// lit != 0 => result = 1
if(AOP_TYPE(result) == AOP_CRY){
- if(size)
- pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
- //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
- // AOP(result)->aopu.aop_dir,
- // AOP(result)->aopu.aop_dir);
+ if(size)
+ pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
+ //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
+ // AOP(result)->aopu.aop_dir,
+ // AOP(result)->aopu.aop_dir);
else if(ifx)
continueIfTrue(ifx);
goto release;
}
} else {
if (AOP_TYPE(right) == AOP_CRY){
- if(pic16_sameRegs(AOP(result),AOP(left))){
+ if(pic16_sameRegs(AOP(result),AOP(left))){
// c = bit | bit;
- pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
- pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
-
- pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
- AOP(result)->aopu.aop_dir,
- AOP(result)->aopu.aop_dir);
- pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
- AOP(right)->aopu.aop_dir,
- AOP(right)->aopu.aop_dir);
- pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
- AOP(result)->aopu.aop_dir,
- AOP(result)->aopu.aop_dir);
- } else {
- if( AOP_TYPE(result) == AOP_ACC) {
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
- pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
- pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
-
- } else {
-
- pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
- pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
-
- pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
- AOP(result)->aopu.aop_dir,
- AOP(result)->aopu.aop_dir);
- pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
- AOP(right)->aopu.aop_dir,
- AOP(right)->aopu.aop_dir);
- pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
- AOP(left)->aopu.aop_dir,
- AOP(left)->aopu.aop_dir);
- pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
- AOP(result)->aopu.aop_dir,
- AOP(result)->aopu.aop_dir);
- }
- }
+ pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
+ pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
+
+ pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
+ AOP(result)->aopu.aop_dir,
+ AOP(result)->aopu.aop_dir);
+ pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
+ AOP(right)->aopu.aop_dir,
+ AOP(right)->aopu.aop_dir);
+ pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
+ AOP(result)->aopu.aop_dir,
+ AOP(result)->aopu.aop_dir);
+ } else {
+ if( AOP_TYPE(result) == AOP_ACC) {
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
+ pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
+ pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
+
+ } else {
+
+ pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
+ pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
+ pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
+
+ pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
+ AOP(result)->aopu.aop_dir,
+ AOP(result)->aopu.aop_dir);
+ pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
+ AOP(right)->aopu.aop_dir,
+ AOP(right)->aopu.aop_dir);
+ pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
+ AOP(left)->aopu.aop_dir,
+ AOP(left)->aopu.aop_dir);
+ pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
+ AOP(result)->aopu.aop_dir,
+ AOP(result)->aopu.aop_dir);
+ }
+ }
} else {
// c = bit | val;
symbol *tlbl = newiTempLabel(NULL);
pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
- pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
- if( AOP_TYPE(right) == AOP_ACC) {
- pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
- emitSKPNZ;
- pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
- }
+ pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
+ if( AOP_TYPE(right) == AOP_ACC) {
+ pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
+ emitSKPNZ;
+ pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
+ pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
+ }
pic16_outBitC(result);
// if(bit | ...)
else if((AOP_TYPE(result) == AOP_CRY) && ifx)
- genIfxJump(ifx, "c");
+ genIfxJump(ifx, "c");
goto release ;
}
(AOP_TYPE(result) == AOP_CRY) &&
(AOP_TYPE(left) != AOP_CRY)){
if(lit){
- pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
+ pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
// result = 1
if(size)
pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
- else
+ else
continueIfTrue(ifx);
goto release;
} else {
- pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
+ pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
// lit = 0, result = boolean(left)
if(size)
pic16_emitcode(";XXX setb","c");
if(pic16_sameRegs(AOP(result),AOP(left))){
int know_W = -1;
for(;size--; offset++,lit>>=8) {
- if(AOP_TYPE(right) == AOP_LIT){
- if((lit & 0xff) == 0)
- /* or'ing with 0 has no effect */
- continue;
- else {
- int p = pic16_my_powof2(lit & 0xff);
- if(p>=0) {
- /* only one bit is set in the literal, so use a bsf instruction */
- pic16_emitpcode(POC_BSF,
- pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0, PO_GPR_REGISTER));
- } else {
- if(know_W != (lit & 0xff))
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
- know_W = lit & 0xff;
- pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
- }
-
- }
- } else {
- if (AOP_TYPE(left) == AOP_ACC) {
- pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),offset));
-// pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
- } else {
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
- pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
-
-// pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
-// pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
-
- }
- }
+ if(AOP_TYPE(right) == AOP_LIT){
+ if((lit & 0xff) == 0)
+ /* or'ing with 0 has no effect */
+ continue;
+ else {
+ int p = pic16_my_powof2(lit & 0xff);
+ if(p>=0) {
+ /* only one bit is set in the literal, so use a bsf instruction */
+ pic16_emitpcode(POC_BSF,
+ pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0, PO_GPR_REGISTER));
+ } else {
+ if(know_W != (lit & 0xff))
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
+ know_W = lit & 0xff;
+ pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
+ }
+
+ }
+ } else {
+ if (AOP_TYPE(left) == AOP_ACC) {
+ pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),offset));
+// pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
+ } else {
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
+ pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
+
+// pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
+// pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
+
+ }
+ }
}
} else {
// left & result in different registers
// if(!size && ifx), conditional oper: if(left | right)
symbol *tlbl = newiTempLabel(NULL);
int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
- pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
+ pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
if(size)
} else if(ifx)
jmpTrueOrFalse(ifx, tlbl);
} else for(;(size--);offset++){
- // normal case
- // result = left & right
- if(AOP_TYPE(right) == AOP_LIT){
- int t = (lit >> (offset*8)) & 0x0FFL;
- switch(t) {
- case 0x00:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
-
-// pic16_emitcode("movf","%s,w",
-// pic16_aopGet(AOP(left),offset,FALSE,FALSE));
-// pic16_emitcode("movwf","%s",
-// pic16_aopGet(AOP(result),offset,FALSE,FALSE));
- break;
- default:
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
- pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
-
-// pic16_emitcode("movlw","0x%x",t);
-// pic16_emitcode("iorwf","%s,w",
-// pic16_aopGet(AOP(left),offset,FALSE,FALSE));
-// pic16_emitcode("movwf","%s",
-// pic16_aopGet(AOP(result),offset,FALSE,FALSE));
-
- }
- continue;
- }
-
- // faster than result <- left, anl result,right
- // and better if result is SFR
- if (AOP_TYPE(left) == AOP_ACC) {
- pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(right),offset));
-// pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
- } else {
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
- pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
-
-// pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
-// pic16_emitcode("iorwf","%s,w",
-// pic16_aopGet(AOP(left),offset,FALSE,FALSE));
- }
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
-// pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
- }
+ // normal case
+ // result = left & right
+ if(AOP_TYPE(right) == AOP_LIT){
+ int t = (lit >> (offset*8)) & 0x0FFL;
+ switch(t) {
+ case 0x00:
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
+
+// pic16_emitcode("movf","%s,w",
+// pic16_aopGet(AOP(left),offset,FALSE,FALSE));
+// pic16_emitcode("movwf","%s",
+// pic16_aopGet(AOP(result),offset,FALSE,FALSE));
+ break;
+ default:
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
+ pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
+
+// pic16_emitcode("movlw","0x%x",t);
+// pic16_emitcode("iorwf","%s,w",
+// pic16_aopGet(AOP(left),offset,FALSE,FALSE));
+// pic16_emitcode("movwf","%s",
+// pic16_aopGet(AOP(result),offset,FALSE,FALSE));
+
+ }
+ continue;
+ }
+
+ // faster than result <- left, anl result,right
+ // and better if result is SFR
+ if (AOP_TYPE(left) == AOP_ACC) {
+ pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(right),offset));
+// pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
+ } else {
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
+ pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
+
+// pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
+// pic16_emitcode("iorwf","%s,w",
+// pic16_aopGet(AOP(left),offset,FALSE,FALSE));
+ }
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
+// pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
+ }
}
release :
pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- pic16_freeAsmop(result,NULL,ic,TRUE);
+ pic16_freeAsmop(result,NULL,ic,TRUE);
}
/*-----------------------------------------------------------------*/
left = tmp;
}
if(AOP_TYPE(right) == AOP_LIT)
- lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
+ lit = ulFromVal (AOP(right)->aopu.aop_lit);
size = AOP_SIZE(result);
if(AOP_TYPE(right) == AOP_LIT){
// c = bit & literal;
if(lit>>1){
- // lit>>1 != 0 => result = 1
- if(AOP_TYPE(result) == AOP_CRY){
- if(size)
- {pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),offset));
- pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
- else if(ifx)
- continueIfTrue(ifx);
- goto release;
- }
- pic16_emitcode("setb","c");
+ // lit>>1 != 0 => result = 1
+ if(AOP_TYPE(result) == AOP_CRY){
+ if(size)
+ {pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),offset));
+ pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
+ else if(ifx)
+ continueIfTrue(ifx);
+ goto release;
+ }
+ pic16_emitcode("setb","c");
} else{
- // lit == (0 or 1)
- if(lit == 0){
- // lit == 0, result = left
- if(size && pic16_sameRegs(AOP(result),AOP(left)))
- goto release;
- pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
- } else{
- // lit == 1, result = not(left)
- if(size && pic16_sameRegs(AOP(result),AOP(left))){
- pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),offset));
- pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offset));
- pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
- goto release;
- } else {
- pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
- pic16_emitcode("cpl","c");
- }
- }
+ // lit == (0 or 1)
+ if(lit == 0){
+ // lit == 0, result = left
+ if(size && pic16_sameRegs(AOP(result),AOP(left)))
+ goto release;
+ pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
+ } else{
+ // lit == 1, result = not(left)
+ if(size && pic16_sameRegs(AOP(result),AOP(left))){
+ pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),offset));
+ pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offset));
+ pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
+ goto release;
+ } else {
+ pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
+ pic16_emitcode("cpl","c");
+ }
+ }
}
} else {
// right != literal
symbol *tlbl = newiTempLabel(NULL);
if (AOP_TYPE(right) == AOP_CRY){
- // c = bit ^ bit;
- pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
+ // c = bit ^ bit;
+ pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
}
else{
- int sizer = AOP_SIZE(right);
- // c = bit ^ val
- // if val>>1 != 0, result = 1
- pic16_emitcode("setb","c");
- while(sizer){
- MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
- if(sizer == 1)
- // test the msb of the lsb
- pic16_emitcode("anl","a,#0xfe");
- pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
- sizer--;
- }
- // val = (0,1)
- pic16_emitcode("rrc","a");
+ int sizer = AOP_SIZE(right);
+ // c = bit ^ val
+ // if val>>1 != 0, result = 1
+ pic16_emitcode("setb","c");
+ while(sizer){
+ MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
+ if(sizer == 1)
+ // test the msb of the lsb
+ pic16_emitcode("anl","a,#0xfe");
+ pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
+ sizer--;
+ }
+ // val = (0,1)
+ pic16_emitcode("rrc","a");
}
pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
pic16_emitcode("cpl","c");
pic16_outBitC(result);
// if(bit | ...)
else if((AOP_TYPE(result) == AOP_CRY) && ifx)
- genIfxJump(ifx, "c");
+ genIfxJump(ifx, "c");
goto release ;
}
/* if left is same as result */
for(;size--; offset++) {
if(AOP_TYPE(right) == AOP_LIT){
- int t = (lit >> (offset*8)) & 0x0FFL;
- if(t == 0x00L)
- continue;
- else
- if (IS_AOP_PREG(left)) {
- MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
- pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
- pic16_aopPut(AOP(result),"a",offset);
- } else {
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
- pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
- pic16_emitcode("xrl","%s,%s",
- pic16_aopGet(AOP(left),offset,FALSE,TRUE),
- pic16_aopGet(AOP(right),offset,FALSE,FALSE));
- }
+ int t = (lit >> (offset*8)) & 0x0FFL;
+ if(t == 0x00L)
+ continue;
+ else
+ if (IS_AOP_PREG(left)) {
+ MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
+ pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
+ pic16_aopPut(AOP(result),"a",offset);
+ } else {
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
+ pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
+ pic16_emitcode("xrl","%s,%s",
+ pic16_aopGet(AOP(left),offset,FALSE,TRUE),
+ pic16_aopGet(AOP(right),offset,FALSE,FALSE));
+ }
} else {
- if (AOP_TYPE(left) == AOP_ACC)
- pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
- else {
- pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
- pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
+ if (AOP_TYPE(left) == AOP_ACC)
+ pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
+ else {
+ pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
+ pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
/*
- if (IS_AOP_PREG(left)) {
- pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
- pic16_aopPut(AOP(result),"a",offset);
- } else
- pic16_emitcode("xrl","%s,a",
- pic16_aopGet(AOP(left),offset,FALSE,TRUE));
+ if (IS_AOP_PREG(left)) {
+ pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
+ pic16_aopPut(AOP(result),"a",offset);
+ } else
+ pic16_emitcode("xrl","%s,a",
+ pic16_aopGet(AOP(left),offset,FALSE,TRUE));
*/
- }
+ }
}
}
} else {
symbol *tlbl = newiTempLabel(NULL);
int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
if(size)
- pic16_emitcode("setb","c");
+ pic16_emitcode("setb","c");
while(sizer--){
- if((AOP_TYPE(right) == AOP_LIT) &&
- (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
- MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
- } else {
- MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
- pic16_emitcode("xrl","a,%s",
- pic16_aopGet(AOP(left),offset,FALSE,FALSE));
- }
- pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
- offset++;
+ if((AOP_TYPE(right) == AOP_LIT) &&
+ (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
+ MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
+ } else {
+ MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
+ pic16_emitcode("xrl","a,%s",
+ pic16_aopGet(AOP(left),offset,FALSE,FALSE));
+ }
+ pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
+ offset++;
}
if(size){
- CLRC;
- pic16_emitcode("","%05d_DS_:",tlbl->key+100);
- pic16_outBitC(result);
+ CLRC;
+ pic16_emitcode("","%05d_DS_:",tlbl->key+100);
+ pic16_outBitC(result);
} else if(ifx)
- jmpTrueOrFalse(ifx, tlbl);
+ jmpTrueOrFalse(ifx, tlbl);
} else for(;(size--);offset++){
// normal case
// result = left & right
if(AOP_TYPE(right) == AOP_LIT){
- int t = (lit >> (offset*8)) & 0x0FFL;
- switch(t) {
- case 0x00:
- pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
- pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
- pic16_emitcode("movf","%s,w",
- pic16_aopGet(AOP(left),offset,FALSE,FALSE));
- pic16_emitcode("movwf","%s",
- pic16_aopGet(AOP(result),offset,FALSE,FALSE));
- break;
- case 0xff:
- pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
- pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
- pic16_emitcode("comf","%s,w",
- pic16_aopGet(AOP(left),offset,FALSE,FALSE));
- pic16_emitcode("movwf","%s",
- pic16_aopGet(AOP(result),offset,FALSE,FALSE));
- break;
- default:
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
- pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
- pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
- pic16_emitcode("movlw","0x%x",t);
- pic16_emitcode("xorwf","%s,w",
- pic16_aopGet(AOP(left),offset,FALSE,FALSE));
- pic16_emitcode("movwf","%s",
- pic16_aopGet(AOP(result),offset,FALSE,FALSE));
-
- }
- continue;
+ int t = (lit >> (offset*8)) & 0x0FFL;
+ switch(t) {
+ case 0x00:
+ pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
+ pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
+ pic16_emitcode("movf","%s,w",
+ pic16_aopGet(AOP(left),offset,FALSE,FALSE));
+ pic16_emitcode("movwf","%s",
+ pic16_aopGet(AOP(result),offset,FALSE,FALSE));
+ break;
+ case 0xff:
+ pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
+ pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
+ pic16_emitcode("comf","%s,w",
+ pic16_aopGet(AOP(left),offset,FALSE,FALSE));
+ pic16_emitcode("movwf","%s",
+ pic16_aopGet(AOP(result),offset,FALSE,FALSE));
+ break;
+ default:
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
+ pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
+ pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
+ pic16_emitcode("movlw","0x%x",t);
+ pic16_emitcode("xorwf","%s,w",
+ pic16_aopGet(AOP(left),offset,FALSE,FALSE));
+ pic16_emitcode("movwf","%s",
+ pic16_aopGet(AOP(result),offset,FALSE,FALSE));
+
+ }
+ continue;
}
// faster than result <- left, anl result,right
// and better if result is SFR
if (AOP_TYPE(left) == AOP_ACC) {
- pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
- pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
+ pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
+ pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
} else {
- pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
- pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
- pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
- pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
+ pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
+ pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
+ pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
+ pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
}
if ( AOP_TYPE(result) != AOP_ACC){
- pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
- pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
+ pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
+ pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
}
}
}
release :
pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- pic16_freeAsmop(result,NULL,ic,TRUE);
+ pic16_freeAsmop(result,NULL,ic,TRUE);
}
/*-----------------------------------------------------------------*/
{
char *buffer, *bp, *bp1;
bool inComment = FALSE;
-
+
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
_G.inLine += (!options.asmpeep);
buffer = bp = bp1 = Safe_strdup (IC_INLINE (ic));
-
+
while((bp1=strstr(bp, "\\n"))) {
*bp1++ = '\n';
*bp1++ = ' ';
bp++;
i = *bp - '0';
if(i>elementsInSet(asmInlineMap))break;
-
+
bp++;
s = indexSet(asmInlineMap, i);
DEBUGpc("searching symbol s = `%s'", s);
} else {
strcat(bp1, sym->rname);
}
-
+
while(*bp1)bp1++;
}
-
+
if(strlen(bp1) > cblen - 16) {
int i = strlen(cbuf);
cblen += 50;
bp1 = cbuf + i;
}
}
-
+
free(buffer);
buffer = Safe_strdup( cbuf );
free(cbuf);
-
+
bp = bp1 = buffer;
}
#endif /* 0 */
same = pic16_sameRegs(AOP(result),AOP(left));
- size = AOP_SIZE(result);
+ size = AOP_SIZE(result);
DEBUGpic16_emitcode ("; ***","%s %d size:%d same:%d",__FUNCTION__,__LINE__,size,same);
/* genRLC - generate code for rotate left with carry */
/*-----------------------------------------------------------------*/
static void genRLC (iCode *ic)
-{
+{
operand *left , *result ;
int size, offset = 0;
int same;
same = pic16_sameRegs(AOP(result),AOP(left));
/* move it to the result */
- size = AOP_SIZE(result);
+ size = AOP_SIZE(result);
/* get the msb and put it into the carry */
pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
/* gpasm can get the highest order bit with HIGH/UPPER
* so the following probably is not needed -- VR */
-
+
/*-----------------------------------------------------------------*/
/* genGetHbit - generates code get highest order bit */
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static void AccLsh (int shCount, int doMask)
{
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- switch(shCount){
- case 0 :
- return;
- break;
- case 1 :
- pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
- break;
- case 2 :
- pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
- pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
- break;
- case 3 :
- pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
- pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
- break;
- case 4 :
- pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
- break;
- case 5 :
- pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
- pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
- break;
- case 6 :
- pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
- pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
- break;
- case 7 :
- pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
- break;
- }
- if (doMask) {
- /* no masking is required in genPackBits */
- pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SLMask[shCount]));
- }
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ switch(shCount){
+ case 0 :
+ return;
+ break;
+ case 1 :
+ pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
+ break;
+ case 2 :
+ pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
+ pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
+ break;
+ case 3 :
+ pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
+ pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
+ break;
+ case 4 :
+ pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
+ break;
+ case 5 :
+ pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
+ pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
+ break;
+ case 6 :
+ pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
+ pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
+ break;
+ case 7 :
+ pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
+ break;
+ }
+ if (doMask) {
+ /* no masking is required in genPackBits */
+ pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SLMask[shCount]));
+ }
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static void AccRsh (int shCount, int andmask)
{
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- switch(shCount){
- case 0 :
- return; break;
- case 1 :
- pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
- break;
- case 2 :
- pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
- pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
- break;
- case 3 :
- pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
- pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
- break;
- case 4 :
- pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
- break;
- case 5 :
- pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
- pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
- break;
- case 6 :
- pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
- pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
- break;
- case 7 :
- pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
- break;
- }
-
- if(andmask)
- pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SRMask[shCount]));
- else
- DEBUGpic16_emitcode("; ***", "%s omitting masking the result", __FUNCTION__);
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ switch(shCount){
+ case 0 :
+ return; break;
+ case 1 :
+ pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
+ break;
+ case 2 :
+ pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
+ pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
+ break;
+ case 3 :
+ pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
+ pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
+ break;
+ case 4 :
+ pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
+ break;
+ case 5 :
+ pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
+ pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
+ break;
+ case 6 :
+ pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
+ pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
+ break;
+ case 7 :
+ pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
+ break;
+ }
+
+ if(andmask)
+ pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SRMask[shCount]));
+ else
+ DEBUGpic16_emitcode("; ***", "%s omitting masking the result", __FUNCTION__);
}
#if 0
switch(shCount) {
case 1:
pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
- if(same)
+ if(same)
pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
else {
pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
case 2:
pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
- if(same)
+ if(same)
pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
else {
pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
switch(shCount) {
case 1:
emitCLRC;
- if(same)
+ if(same)
pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
else {
pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
break;
-
+
case 4:
pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
}
} else { // just treat as different later on
- same = 0;
+ same = 0;
}
}
pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
while(--shCount) {
- emitCLRC;
- pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
- pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
+ emitCLRC;
+ pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
+ pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
}
break;
pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
if(shCount >=5) {
- pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
- pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
+ pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
+ pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
}
break;
case 6:
case 2:
case 3:
/* note, use a mov/add for the shift since the mov has a
- chance of getting optimized out */
+ chance of getting optimized out */
pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
while(--shCount) {
- emitCLRC;
- pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
- pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
+ emitCLRC;
+ pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
+ pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
}
break;
if(shCount == 5) {
- pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
- pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
+ pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
+ pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
}
break;
case 6:
pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
}
} else { // just treat as different later on
- same = 0;
+ same = 0;
}
}
while(--shCount) {
if(sign)
- /* now get sign from already assigned result (avoid BANKSEL) */
- pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
+ /* now get sign from already assigned result (avoid BANKSEL) */
+ pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
else
- emitCLRC;
+ emitCLRC;
pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
}
if(sign) {
pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
- pic16_emitpcode(POC_BTFSC,
- pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0, PO_GPR_REGISTER));
+ pic16_emitpcode(POC_BTFSC,
+ pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0, PO_GPR_REGISTER));
pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
}
pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
if(sign) {
- pic16_emitpcode(POC_BTFSC,
- pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0, PO_GPR_REGISTER));
- pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
+ pic16_emitpcode(POC_BTFSC,
+ pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0, PO_GPR_REGISTER));
+ pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
}
pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
if(sign) {
- pic16_emitpcode(POC_BTFSC,
- pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0, PO_GPR_REGISTER));
- pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
+ pic16_emitpcode(POC_BTFSC,
+ pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0, PO_GPR_REGISTER));
+ pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
}
pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
//pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
-
+
}
break;
if(sign) {
emitSKPNC;
pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
- } else
+ } else
pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
}
}
operand *result, int offr, int shCount)
{
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
+
pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
/* shift right accumulator */
AccRsh(shCount, 1);
/* genlshOne - left shift a one byte quantity by known count */
/*-----------------------------------------------------------------*/
static void genlshOne (operand *result, operand *left, int shCount)
-{
+{
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
shiftL1Left2Result(left, LSB, result, LSB, shCount);
}
static void genlshTwo (operand *result,operand *left, int shCount)
{
int size;
-
+
DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
size = pic16_getDataSize(result);
if (size > 1){
if (shCount)
shiftL1Left2Result(left, LSB, result, MSB16, shCount);
- else
+ else
movLeft2Result(left, LSB, result, MSB16);
}
- pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
+ pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
}
/* 1 <= shCount <= 7 */
- else {
+ else {
if(size == 1)
- shiftL1Left2Result(left, LSB, result, LSB, shCount);
- else
+ shiftL1Left2Result(left, LSB, result, LSB, shCount);
+ else
shiftL2Left2Result(left, LSB, result, LSB, shCount);
}
}
{
int size = AOP_SIZE(result);
int same = pic16_sameRegs(AOP(left),AOP(result));
- int i;
+ int i;
DEBUGpic16_emitcode ("; ***","%s %d offr:%d size:%d",__FUNCTION__,__LINE__,offr,size);
- if (same && (offr == MSB16)) { //shift one byte
- for(i=size-1;i>=MSB16;i--) {
- pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i-1));
- pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i));
- }
- } else {
- pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),LSB+offr));
- }
-
+ if (same && (offr == MSB16)) { //shift one byte
+ for(i=size-1;i>=MSB16;i--) {
+ pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i-1));
+ pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i));
+ }
+ } else {
+ pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),LSB+offr));
+ }
+
if (size > LSB+offr ){
- if (same) {
- pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(left),LSB+offr));
- } else {
- pic16_emitpcode(POC_ADDFW,pic16_popGet(AOP(left),LSB));
- pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),LSB+offr));
- }
- }
+ if (same) {
+ pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(left),LSB+offr));
+ } else {
+ pic16_emitpcode(POC_ADDFW,pic16_popGet(AOP(left),LSB));
+ pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),LSB+offr));
+ }
+ }
if(size > MSB16+offr){
- if (same) {
- pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB16+offr));
- } else {
- pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB16));
- pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB16+offr));
- }
+ if (same) {
+ pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB16+offr));
+ } else {
+ pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB16));
+ pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB16+offr));
+ }
}
if(size > MSB24+offr){
- if (same) {
- pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB24+offr));
- } else {
- pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB24));
- pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB24+offr));
- }
+ if (same) {
+ pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB24+offr));
+ } else {
+ pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB24));
+ pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB24+offr));
+ }
}
if(size > MSB32+offr){
- if (same) {
- pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB32+offr));
- } else {
- pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB32));
- pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB32+offr));
- }
+ if (same) {
+ pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB32+offr));
+ } else {
+ pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB32));
+ pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB32+offr));
+ }
}
if(offr != LSB)
- pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
+ pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
}
else
movLeft2Result(left, LSB, result, MSB32);
- pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
- pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
- pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB24));
+ pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
+ pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
+ pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB24));
return;
}
movLeft2Result(left, MSB16, result, MSB32);
movLeft2Result(left, LSB, result, MSB24);
}
- pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
- pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
+ pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
+ pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
return;
- }
+ }
/* if more than 1 byte */
else if ( shCount >= 8 ) {
movLeft2Result(left, MSB24, result, MSB32);
movLeft2Result(left, MSB16, result, MSB24);
movLeft2Result(left, LSB, result, MSB16);
- pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
+ pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
}
else if(shCount == 1)
shiftLLong(left, result, MSB16);
shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
shiftL1Left2Result(left, LSB, result, MSB16, shCount);
shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
- pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
+ pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
}
}
}
/* 1 <= shCount <= 7 */
else if(shCount <= 3)
- {
+ {
shiftLLong(left, result, LSB);
while(--shCount >= 1)
shiftLLong(result, result, LSB);
operand *right,
operand *result,
iCode *ic)
-{
- int shCount = abs((int)floatFromVal (AOP(right)->aopu.aop_lit));
+{
+ int shCount = abs((int) ulFromVal (AOP(right)->aopu.aop_lit));
int size;
FENTRY;
/*-----------------------------------------------------------------*
* genMultiAsm - repeat assembly instruction for size of register.
- * if endian == 1, then the high byte (i.e base address + size of
+ * if endian == 1, then the high byte (i.e base address + size of
* register) is used first else the low byte is used first;
*-----------------------------------------------------------------*/
static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
pic16_aopOp(right,ic,FALSE);
- /* if the shift count is known then do it
+ /* if the shift count is known then do it
as efficiently as possible */
if (AOP_TYPE(right) == AOP_LIT) {
pic16_genLeftShiftLiteral (left,right,result,ic);
* only the lower order byte since shifting
* more than 32 bits make no sense anyway, ( the
* largest size of an object can be only 32 bits ) */
-
+
pic16_aopOp(left,ic,FALSE);
pic16_aopOp(result,ic,FALSE);
}
goto release ;
}
-
+
if (pic16_sameRegs(AOP(left),AOP(result))) {
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
+
tlbl = newiTempLabel(NULL);
pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
genMultiAsm(POC_RRCF, result, size,1);
}
//tlbl = newiTempLabel(NULL);
- //offset = 0 ;
+ //offset = 0 ;
//tlbl1 = newiTempLabel(NULL);
- //reAdjustPreg(AOP(result));
-
- //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
- //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
+ //reAdjustPreg(AOP(result));
+
+ //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
+ //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
//l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
//MOVA(l);
- //pic16_emitcode("add","a,acc");
+ //pic16_emitcode("add","a,acc");
//pic16_aopPut(AOP(result),"a",offset++);
//while (--size) {
// l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
// MOVA(l);
- // pic16_emitcode("rlc","a");
+ // pic16_emitcode("rlc","a");
// pic16_aopPut(AOP(result),"a",offset++);
//}
//reAdjustPreg(AOP(result));
pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
/* offset should be 0, 1 or 3 */
-
+
pic16_emitpcode(POC_ANDLW, pic16_popGetLit((size<<3)-1));
emitSKPNZ;
pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
pic16_aopOp(right,ic,FALSE);
- /* if the shift count is known then do it
+ /* if the shift count is known then do it
as efficiently as possible */
if (AOP_TYPE(right) == AOP_LIT) {
pic16_genLeftShiftLiteral (left,right,result,ic);
return ;
}
- /* shift count is unknown then we have to form
+ /* shift count is unknown then we have to form
a loop get the loop count in B : Note: we take
only the lower order byte since shifting
more that 32 bits make no sense anyway, ( the
- largest size of an object can be only 32 bits ) */
+ largest size of an object can be only 32 bits ) */
+
-
pic16_aopOp(left,ic,FALSE);
pic16_aopOp(result,ic,FALSE);
/* now move the left to the result if they are not the
same */
- if (!pic16_sameRegs(AOP(left),AOP(result)) &&
+ if (!pic16_sameRegs(AOP(left),AOP(result)) &&
AOP_SIZE(result) > 1) {
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
if (*l == '@' && (IS_AOP_PREG(result))) {
- pic16_emitcode("mov","a,%s",l);
- pic16_aopPut(AOP(result),"a",offset);
+ pic16_emitcode("mov","a,%s",l);
+ pic16_aopPut(AOP(result),"a",offset);
} else {
/* we don't know if left is a literal or a register, take care -- VR */
tlbl = newiTempLabel(NULL);
if (!pic16_sameRegs(AOP(left),AOP(result))) {
pic16_mov2f(AOP(result), AOP(left), 0);
-
-// pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-// pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
+
+// pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
+// pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
}
pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
}
goto release ;
}
-
+
if (pic16_sameRegs(AOP(left),AOP(result))) {
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
+
tlbl = newiTempLabel(NULL);
pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
genMultiAsm(POC_RRCF, result, size,1);
}
//tlbl = newiTempLabel(NULL);
- //offset = 0 ;
+ //offset = 0 ;
//tlbl1 = newiTempLabel(NULL);
- //reAdjustPreg(AOP(result));
-
- //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
- //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
+ //reAdjustPreg(AOP(result));
+
+ //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
+ //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
//l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
//MOVA(l);
- //pic16_emitcode("add","a,acc");
+ //pic16_emitcode("add","a,acc");
//pic16_aopPut(AOP(result),"a",offset++);
//while (--size) {
// l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
// MOVA(l);
- // pic16_emitcode("rlc","a");
+ // pic16_emitcode("rlc","a");
// pic16_aopPut(AOP(result),"a",offset++);
//}
//reAdjustPreg(AOP(result));
pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
/* offset should be 0, 1 or 3 */
-
+
pic16_emitpcode(POC_ANDLW, pic16_popGetLit((size<<3)-1));
emitSKPNZ;
pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
shCount -= 8 ;
if (shCount)
shiftR1Left2Result(left, MSB16, result, LSB,
- shCount, sign);
+ shCount, sign);
else
movLeft2Result(left, MSB16, result, LSB);
/* 1 <= shCount <= 7 */
else
- shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
+ shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
}
/*-----------------------------------------------------------------*/
int i;
DEBUGpic16_emitcode ("; ***","%s %d offl:%d size:%d",__FUNCTION__,__LINE__,offl,size);
- if (same && (offl == MSB16)) { //shift one byte right
- for(i=MSB16;i<size;i++) {
- pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i));
- pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i-1));
- }
- }
+ if (same && (offl == MSB16)) { //shift one byte right
+ for(i=MSB16;i<size;i++) {
+ pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i));
+ pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i-1));
+ }
+ }
if(sign)
- pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(left),MSB32));
- else
- emitCLRC;
-
- if (same) {
- if (offl == LSB)
- pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB32));
- } else {
- pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB32));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB32-offl));
- }
+ pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(left),MSB32));
+ else
+ emitCLRC;
+
+ if (same) {
+ if (offl == LSB)
+ pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB32));
+ } else {
+ pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB32));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB32-offl));
+ }
if(offl == MSB16) {
/* add sign of "a" */
pic16_addSign(result, MSB32, sign);
- }
-
- if (same) {
- pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB24));
- } else {
- pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB24));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB24-offl));
- }
-
- if (same) {
- pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB16));
- } else {
- pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB16));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB16-offl));
- }
-
- if (same) {
- pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),LSB));
- } else {
- if(offl == LSB){
- pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),LSB));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),LSB));
- }
- }
+ }
+
+ if (same) {
+ pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB24));
+ } else {
+ pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB24));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB24-offl));
+ }
+
+ if (same) {
+ pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB16));
+ } else {
+ pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB16));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB16-offl));
+ }
+
+ if (same) {
+ pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),LSB));
+ } else {
+ if(offl == LSB){
+ pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),LSB));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),LSB));
+ }
+ }
}
/*-----------------------------------------------------------------*/
if(shCount <= 2){
shiftRLong(left, LSB, result, sign);
if(shCount == 2)
- shiftRLong(result, LSB, result, sign);
+ shiftRLong(result, LSB, result, sign);
}
else{
shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
operand *result,
iCode *ic,
int sign)
-{
- int shCount = abs((int)floatFromVal (AOP(right)->aopu.aop_lit));
+{
+ int shCount = abs((int) ulFromVal (AOP(right)->aopu.aop_lit));
int lsize,res_size;
pic16_freeAsmop(right,NULL,ic,TRUE);
#if VIEW_SIZE
pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
- AOP_SIZE(left));
+ AOP_SIZE(left));
#endif
lsize = pic16_getDataSize(left);
if(res_size == 1) {
pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
if(sign) {
- pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),LSB));
+ pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+ pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),LSB));
}
} else {
if(sign) {
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
- while(res_size--)
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
+ while(res_size--)
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
} else {
- while(res_size--)
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
+ while(res_size--)
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
}
}
} else {
left = IC_LEFT(ic);
result = IC_RESULT(ic);
- pic16_aopOp(right,ic,FALSE);
+ pic16_aopOp(right,ic,FALSE);
pic16_aopOp(left,ic,FALSE);
pic16_aopOp(result,ic,FALSE);
genRightShiftLiteral (left,right,result,ic,1);
return ;
}
- /* shift count is unknown then we have to form
+ /* shift count is unknown then we have to form
a loop get the loop count in B : Note: we take
only the lower order byte since shifting
more that 32 bits make no sense anyway, ( the
- largest size of an object can be only 32 bits ) */
+ largest size of an object can be only 32 bits ) */
//pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
//pic16_emitcode("inc","b");
/* now move the left to the result if they are not the
same */
- if (!pic16_sameRegs(AOP(left),AOP(result)) &&
+ if (!pic16_sameRegs(AOP(left),AOP(result)) &&
AOP_SIZE(result) > 1) {
size = AOP_SIZE(result);
offset=0;
- while (size--) {
+ while (size--) {
/*
- l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
- if (*l == '@' && IS_AOP_PREG(result)) {
+ l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
+ if (*l == '@' && IS_AOP_PREG(result)) {
- pic16_emitcode("mov","a,%s",l);
- pic16_aopPut(AOP(result),"a",offset);
- } else
- pic16_aopPut(AOP(result),l,offset);
+ pic16_emitcode("mov","a,%s",l);
+ pic16_aopPut(AOP(result),"a",offset);
+ } else
+ pic16_aopPut(AOP(result),l,offset);
*/
pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
}
}
- /* mov the highest order bit to OVR */
+ /* mov the highest order bit to OVR */
tlbl = newiTempLabel(NULL);
tlbl1= newiTempLabel(NULL);
reAdjustPreg(AOP(result));
pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
- pic16_emitcode("","%05d_DS_:",tlbl->key+100);
+ pic16_emitcode("","%05d_DS_:",tlbl->key+100);
pic16_emitcode("mov","c,ov");
while (size--) {
l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
MOVA(l);
- pic16_emitcode("rrc","a");
+ pic16_emitcode("rrc","a");
pic16_aopPut(AOP(result),"a",offset--);
}
reAdjustPreg(AOP(result));
pic16_aopOp(right,ic,FALSE);
- /* if the shift count is known then do it
+ /* if the shift count is known then do it
as efficiently as possible */
if (AOP_TYPE(right) == AOP_LIT) {
genRightShiftLiteral (left,right,result,ic, 0);
return ;
}
- /* shift count is unknown then we have to form
+ /* shift count is unknown then we have to form
a loop get the loop count in B : Note: we take
only the lower order byte since shifting
more that 32 bits make no sense anyway, ( the
- largest size of an object can be only 32 bits ) */
+ largest size of an object can be only 32 bits ) */
pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
pic16_emitcode("inc","b");
/* now move the left to the result if they are not the
same */
- if (!pic16_sameRegs(AOP(left),AOP(result)) &&
+ if (!pic16_sameRegs(AOP(left),AOP(result)) &&
AOP_SIZE(result) > 1) {
size = AOP_SIZE(result);
tlbl = newiTempLabel(NULL);
if (!pic16_sameRegs(AOP(left),AOP(result))) {
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
}
pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
reAdjustPreg(AOP(result));
pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
- pic16_emitcode("","%05d_DS_:",tlbl->key+100);
+ pic16_emitcode("","%05d_DS_:",tlbl->key+100);
CLRC;
while (size--) {
l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
MOVA(l);
- pic16_emitcode("rrc","a");
+ pic16_emitcode("rrc","a");
pic16_aopPut(AOP(result),"a",offset--);
}
reAdjustPreg(AOP(result));
sign = !SPEC_USIGN(operandType (left));
signedCount = !SPEC_USIGN(operandType (right));
- /* if the shift count is known then do it
+ /* if the shift count is known then do it
as efficiently as possible */
if (AOP_TYPE(right) == AOP_LIT) {
- long lit = (long)floatFromVal(AOP(right)->aopu.aop_lit);
+ long lit = (long) ulFromVal (AOP(right)->aopu.aop_lit);
if (signedCount && lit < 0) { lit = -lit; isShiftLeft = !isShiftLeft; }
// we should modify right->aopu.aop_lit here!
// Instead we use abs(shCount) in genXXXShiftLiteral()...
* Note: we perform arithmetic shifts if the left operand is
* signed and we do an (effective) right shift, i. e. we
* shift in the sign bit from the left. */
-
+
label_complete = newiTempLabel ( NULL );
label_loop_pos = newiTempLabel ( NULL );
label_loop_neg = NULL;
pic16_mov2w (AOP(right), 0);
pic16_emitpcode (POC_BZ, pic16_popGetLabel (label_complete->key));
if (signedCount) pic16_emitpcode (POC_BN, pic16_popGetLabel (label_negative->key));
-
+
#if 0
// perform a shift by one (shift count is positive)
// cycles used for shifting {unsigned,signed} values on n bytes by [unsigned,signed] shift count c>0:
- // 2n+[2,3]+({1,3}+n+3)c-2+[0,2]=({4,6}+n)c+2n+[0,3] ({5,7}c+[2,5] / {6,8}c+[4, 7] / {8,10}c+[ 8,11])
+ // 2n+[2,3]+({1,3}+n+3)c-2+[0,2]=({4,6}+n)c+2n+[0,3] ({5,7}c+[2,5] / {6,8}c+[4, 7] / {8,10}c+[ 8,11])
pic16_emitpLabel (label_loop_pos->key);
emitCLRC;
if (sign && (pos_shift == POC_RRCF)) {
#else
// perform a shift by one (shift count is positive)
// cycles used for shifting {unsigned,signed} values on n bytes by [unsigned,signed] shift count c>0:
- // 2n+[2,3]+2+({0,2}+n+3)c-1+[0,2]=({3,5}+n)c+2n+[3,6] ({4,6}c+[5,8] / {5,7}c+[7,10] / {7, 9}c+[11,14])
+ // 2n+[2,3]+2+({0,2}+n+3)c-1+[0,2]=({3,5}+n)c+2n+[3,6] ({4,6}c+[5,8] / {5,7}c+[7,10] / {7, 9}c+[11,14])
// This variant is slower for 0<c<3, equally fast for c==3, and faster for 3<c.
pic16_emitpcode (POC_NEGF, pic16_popCopyReg (&pic16_pc_wreg));
emitCLRC;
pic16_emitpLabel (label_negative->key);
// perform a shift by -1 (shift count is negative)
- // 2n+4+1+({0,2}+n+3)*c-1=({3,5}+n)c+2n+4 ({4,6}c+6 / {5,7}c+8 / {7,9}c+12)
+ // 2n+4+1+({0,2}+n+3)*c-1=({3,5}+n)c+2n+4 ({4,6}c+6 / {5,7}c+8 / {7,9}c+12)
emitCLRC;
pic16_emitpLabel (label_loop_neg->key);
if (sign && (neg_shift == POC_RRCF)) {
if((IS_SYMOP(op) && OP_SYMBOL(op)->remat) || is_LitOp( op )) {
if (AOP_TYPE(op) == AOP_LIT) {
/* handle 12 bit integers correctly */
- unsigned int val = (unsigned int)floatFromVal(AOP(op)->aopu.aop_lit);
+ unsigned int val = (unsigned int) ulFromVal (AOP(op)->aopu.aop_lit);
if ((val & 0x0fff) != val) {
fprintf (stderr, "WARNING: Accessing memory at 0x%x truncated to 0x%x.\n",
- val, (val & 0x0fff) );
- val &= 0x0fff;
+ val, (val & 0x0fff) );
+ val &= 0x0fff;
}
pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGetLit12(val)));
} else {
case GPOINTER:
if (AOP(ptr)->aopu.aop_reg[2]) {
if (doWrite) pic16_emitpcode (POC_MOVWF, pic16_popCopyReg(pic16_stack_postdec));
- // prepare call to __gptrget1, this is actually genGenPointerGet(result, WREG, ?ic?)
- mov2fp(pic16_popCopyReg(&pic16_pc_fsr0l), AOP(ptr), 0);
- mov2fp(pic16_popCopyReg(&pic16_pc_prodl), AOP(ptr), 1);
- pic16_mov2w(AOP(ptr), 2);
- pic16_callGenericPointerRW(doWrite, 1);
+ // prepare call to __gptrget1, this is actually genGenPointerGet(result, WREG, ?ic?)
+ mov2fp(pic16_popCopyReg(&pic16_pc_fsr0l), AOP(ptr), 0);
+ mov2fp(pic16_popCopyReg(&pic16_pc_prodl), AOP(ptr), 1);
+ pic16_mov2w(AOP(ptr), 2);
+ pic16_callGenericPointerRW(doWrite, 1);
} else {
- // data pointer (just 2 byte given)
- if (!fsr0_setup || !*fsr0_setup)
- {
- pic16_loadFSR0( ptr, 0 );
- if (fsr0_setup) *fsr0_setup = 1;
- }
- if (doWrite)
- pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
- else
- pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
+ // data pointer (just 2 byte given)
+ if (!fsr0_setup || !*fsr0_setup)
+ {
+ pic16_loadFSR0( ptr, 0 );
+ if (fsr0_setup) *fsr0_setup = 1;
+ }
+ if (doWrite)
+ pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
+ else
+ pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
}
break;
/* genUnpackBits - generates code for unpacking bits */
/*-----------------------------------------------------------------*/
static void genUnpackBits (operand *result, operand *left, char *rname, int ptype)
-{
+{
int shCnt ;
sym_link *etype, *letype;
int blen=0, bstr=0;
if(!IS_PTR(operandType(left)) || IS_DIRECT(left)) {
/* workaround to reduce the extra lfsr instruction */
pic16_emitpcode(POC_BTFSC,
- pic16_popCopyGPR2Bit(pic16_popGet(AOP(left), 0), bstr));
+ pic16_popCopyGPR2Bit(pic16_popGet(AOP(left), 0), bstr));
} else {
assert (PIC_IS_DATA_PTR (operandType(left)));
pic16_loadFSR0 (left, 0);
pic16_emitpcode(POC_BTFSC,
- pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr));
+ pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr));
}
if (SPEC_USIGN(OP_SYM_ETYPE(left))) {
AccRsh(shCnt, 0);
pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
- (((unsigned char) -1)>>(8 - SPEC_BLEN(etype))) & SRMask[ shCnt ]));
+ (((unsigned char) -1)>>(8 - SPEC_BLEN(etype))) & SRMask[ shCnt ]));
/* VR -- normally I would use the following, but since we use the hack,
* to avoid the masking from AccRsh, why not mask it right now? */
{
int size, offset = 0, leoffset=0 ;
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- pic16_aopOp(result, ic, TRUE);
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ pic16_aopOp(result, ic, TRUE);
- FENTRY;
+ FENTRY;
- size = AOP_SIZE(result);
-// fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
+ size = AOP_SIZE(result);
+// fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
#if 1
- if(!strcmp(pic16_aopGet(AOP(result), 0, TRUE, FALSE),
- pic16_aopGet(AOP(left), 0, TRUE, FALSE))) {
- DEBUGpic16_emitcode("; ***", "left and result names are same, skipping moving");
- goto release;
- }
+ if(!strcmp(pic16_aopGet(AOP(result), 0, TRUE, FALSE),
+ pic16_aopGet(AOP(left), 0, TRUE, FALSE))) {
+ DEBUGpic16_emitcode("; ***", "left and result names are same, skipping moving");
+ goto release;
+ }
#endif
- if(AOP(left)->aopu.pcop->type == PO_DIR)
- leoffset=PCOR(AOP(left)->aopu.pcop)->instance;
+ if(AOP(left)->aopu.pcop->type == PO_DIR)
+ leoffset=PCOR(AOP(left)->aopu.pcop)->instance;
- DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
+ DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
- while (size--) {
- DEBUGpic16_emitcode("; ***", "%s loop offset=%d leoffset=%d", __FUNCTION__, offset, leoffset);
-
-// pic16_DumpOp("(result)",result);
- if(is_LitAOp(AOP(result))) {
- pic16_mov2w(AOP(left), offset); // patch 8
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset));
- } else {
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
- pic16_popGet(AOP(left), offset), //patch 8
- pic16_popGet(AOP(result), offset)));
- }
+ while (size--) {
+ DEBUGpic16_emitcode("; ***", "%s loop offset=%d leoffset=%d", __FUNCTION__, offset, leoffset);
- offset++;
- leoffset++;
- }
+// pic16_DumpOp("(result)",result);
+ if(is_LitAOp(AOP(result))) {
+ pic16_mov2w(AOP(left), offset); // patch 8
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset));
+ } else {
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popGet(AOP(left), offset), //patch 8
+ pic16_popGet(AOP(result), offset)));
+ }
+
+ offset++;
+ leoffset++;
+ }
release:
pic16_freeAsmop(result,NULL,ic,TRUE);
/*-----------------------------------------------------------------*/
/* genNearPointerGet - pic16_emitcode for near pointer fetch */
/*-----------------------------------------------------------------*/
-static void genNearPointerGet (operand *left,
- operand *result,
- iCode *ic)
+static void genNearPointerGet (operand *left,
+ operand *result,
+ iCode *ic)
{
// asmop *aop = NULL;
//regs *preg = NULL ;
sym_link *ltype, *letype;
FENTRY;
-
+
rtype = operandType(result);
retype= getSpec(rtype);
ltype = operandType(left);
letype= getSpec(ltype);
-
+
pic16_aopOp(left,ic,FALSE);
// pic16_DumpOp("(left)",left);
* result is not bit variable type and
* the left is pointer to data space i.e
* lower 128 bytes of space */
-
+
if (AOP_TYPE(left) == AOP_PCODE
&& !IS_BITFIELD(retype)
&& DCL_TYPE(ltype) == POINTER) {
pic16_freeAsmop(left, NULL, ic, TRUE);
return ;
}
-
+
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
pic16_aopOp (result,ic,TRUE);
-
+
DEBUGpic16_pic16_AopType(__LINE__, left, NULL, result);
#if 1
if((nextic->op == IFX)
&& (result == IC_COND(nextic))
&& (OP_LIVETO(result) == nextic->seq)
- && (OP_SYMBOL(left)->remat) // below fails for "if (p->bitfield)"
+ && (OP_SYMBOL(left)->remat) // below fails for "if (p->bitfield)"
) {
/* everything is ok then */
/* find a way to optimize the genIfx iCode */
bytestrt = SPEC_BSTR(operandType(result))/8;
bitstrt = SPEC_BSTR(operandType(result))%8;
-
+
jop = pic16_popCopyGPR2Bit(pic16_popGet(AOP(left), 0), bitstrt);
genIfxpCOpJump(nextic, jop);
-
+
pic16_freeAsmop(left, NULL, ic, TRUE);
pic16_freeAsmop(result, NULL, ic, TRUE);
return;
#endif
/* if bitfield then unpack the bits */
- if (IS_BITFIELD(letype))
+ if (IS_BITFIELD(letype))
genUnpackBits (result, left, NULL, POINTER);
else {
/* we have can just get the values */
int size = AOP_SIZE(result);
- int offset = 0;
-
+ int offset = 0;
+
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
pic16_loadFSR0( left, 0 );
/* we had to allocate for this iCode */
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
pic16_freeAsmop(NULL,aop,ic,TRUE);
- } else {
+ } else {
/* we did not allocate which means left
* already in a pointer register, then
* if size > 0 && this could be used again
- * we have to point it back to where it
+ * we have to point it back to where it
* belongs */
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if (AOP_SIZE(result) > 1
// int size = AOP_SIZE(result) - 1;
// while (size--)
// pic16_emitcode("dec","%s",rname);
- }
+ }
}
#endif
/*-----------------------------------------------------------------*/
/* genPagedPointerGet - pic16_emitcode for paged pointer fetch */
/*-----------------------------------------------------------------*/
-static void genPagedPointerGet (operand *left,
- operand *result,
- iCode *ic)
+static void genPagedPointerGet (operand *left,
+ operand *result,
+ iCode *ic)
{
asmop *aop = NULL;
regs *preg = NULL ;
char *rname ;
- sym_link *rtype, *retype;
+ sym_link *rtype, *retype;
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
rtype = operandType(result);
retype= getSpec(rtype);
-
+
pic16_aopOp(left,ic,FALSE);
/* if the value is already in a pointer register
then don't need anything more */
if (!AOP_INPREG(AOP(left))) {
- /* otherwise get a free pointer register */
- aop = newAsmop(0);
- preg = getFreePtr(ic,&aop,FALSE);
- pic16_emitcode("mov","%s,%s",
- preg->name,
- pic16_aopGet(AOP(left),0,FALSE,TRUE));
- rname = preg->name ;
+ /* otherwise get a free pointer register */
+ aop = newAsmop(0);
+ preg = getFreePtr(ic,&aop,FALSE);
+ pic16_emitcode("mov","%s,%s",
+ preg->name,
+ pic16_aopGet(AOP(left),0,FALSE,TRUE));
+ rname = preg->name ;
} else
- rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
-
+ rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
+
pic16_freeAsmop(left,NULL,ic,TRUE);
pic16_aopOp (result,ic,TRUE);
/* if bitfield then unpack the bits */
- if (IS_BITFIELD(retype))
- genUnpackBits (result,left,rname,PPOINTER);
+ if (IS_BITFIELD(retype))
+ genUnpackBits (result,left,rname,PPOINTER);
else {
- /* we have can just get the values */
- int size = AOP_SIZE(result);
- int offset = 0 ;
-
- while (size--) {
-
- pic16_emitcode("movx","a,@%s",rname);
- pic16_aopPut(AOP(result),"a",offset);
-
- offset++ ;
-
- if (size)
- pic16_emitcode("inc","%s",rname);
- }
+ /* we have can just get the values */
+ int size = AOP_SIZE(result);
+ int offset = 0 ;
+
+ while (size--) {
+
+ pic16_emitcode("movx","a,@%s",rname);
+ pic16_aopPut(AOP(result),"a",offset);
+
+ offset++ ;
+
+ if (size)
+ pic16_emitcode("inc","%s",rname);
+ }
}
/* now some housekeeping stuff */
if (aop) {
- /* we had to allocate for this iCode */
- pic16_freeAsmop(NULL,aop,ic,TRUE);
- } else {
- /* we did not allocate which means left
- already in a pointer register, then
- if size > 0 && this could be used again
- we have to point it back to where it
- belongs */
- if (AOP_SIZE(result) > 1 &&
- !OP_SYMBOL(left)->remat &&
- ( OP_SYMBOL(left)->liveTo > ic->seq ||
- ic->depth )) {
- int size = AOP_SIZE(result) - 1;
- while (size--)
- pic16_emitcode("dec","%s",rname);
- }
+ /* we had to allocate for this iCode */
+ pic16_freeAsmop(NULL,aop,ic,TRUE);
+ } else {
+ /* we did not allocate which means left
+ already in a pointer register, then
+ if size > 0 && this could be used again
+ we have to point it back to where it
+ belongs */
+ if (AOP_SIZE(result) > 1 &&
+ !OP_SYMBOL(left)->remat &&
+ ( OP_SYMBOL(left)->liveTo > ic->seq ||
+ ic->depth )) {
+ int size = AOP_SIZE(result) - 1;
+ while (size--)
+ pic16_emitcode("dec","%s",rname);
+ }
}
/* done */
pic16_freeAsmop(result,NULL,ic,TRUE);
-
-
+
+
}
#if 0
pic16_aopOp(left,ic,FALSE);
- /* if the operand is already in dptr
+ /* if the operand is already in dptr
then we do nothing else we move the value to dptr */
if (AOP_TYPE(left) != AOP_STR) {
/* if this is remateriazable */
pic16_aopOp(result,ic,TRUE);
/* if bit then unpack */
- if (IS_BITFIELD(retype))
+ if (IS_BITFIELD(retype))
genUnpackBits(result,left,"dptr",FPOINTER);
else {
size = AOP_SIZE(result);
pic16_aopOp(left,ic,FALSE);
- /* if the operand is already in dptr
+ /* if the operand is already in dptr
then we do nothing else we move the value to dptr */
if (AOP_TYPE(left) != AOP_STR) {
/* if this is remateriazable */
pic16_aopOp(result,ic,FALSE);
/* if bit then unpack */
- if (IS_BITFIELD(retype))
+ if (IS_BITFIELD(retype))
genUnpackBits(result,left,"dptr",CPOINTER);
else {
size = AOP_SIZE(result);
int size, offset, lit;
sym_link *retype = getSpec(operandType(result));
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- pic16_aopOp(left,ic,FALSE);
- pic16_aopOp(result,ic,FALSE);
- size = AOP_SIZE(result);
-
- DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
-
- if (AOP_TYPE(left) == AOP_IMMD) { // do we ever get here? (untested!)
-
- lit = (unsigned)floatFromVal(AOP(left)->aopu.aop_lit);
- // load FSR0 from immediate
- pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
-
-// pic16_loadFSR0( left );
-
- offset = 0;
- while(size--) {
- if(size) {
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
- } else {
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
- }
- offset++;
- }
- goto release;
-
- }
- else { /* we need to get it byte by byte */
- // set up FSR0 with address from left
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
-
- offset = 0 ;
-
- while(size--) {
- if(size) {
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
- } else {
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
- }
- offset++;
- }
- goto release;
- }
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ pic16_aopOp(left,ic,FALSE);
+ pic16_aopOp(result,ic,FALSE);
+ size = AOP_SIZE(result);
+
+ DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
+
+ if (AOP_TYPE(left) == AOP_IMMD) { // do we ever get here? (untested!)
+
+ lit = (unsigned) ulFromVal (AOP(left)->aopu.aop_lit);
+ // load FSR0 from immediate
+ pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
+
+// pic16_loadFSR0( left );
+
+ offset = 0;
+ while(size--) {
+ if(size) {
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
+ } else {
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
+ }
+ offset++;
+ }
+ goto release;
+
+ }
+ else { /* we need to get it byte by byte */
+ // set up FSR0 with address from left
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
+
+ offset = 0 ;
+
+ while(size--) {
+ if(size) {
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
+ } else {
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
+ }
+ offset++;
+ }
+ goto release;
+ }
/* if bit then unpack */
- if (IS_BITFIELD(retype))
- genUnpackBits(result,left,"BAD",GPOINTER);
+ if (IS_BITFIELD(retype))
+ genUnpackBits(result,left,"BAD",GPOINTER);
- release:
- pic16_freeAsmop(left,NULL,ic,TRUE);
- pic16_freeAsmop(result,NULL,ic,TRUE);
+ release:
+ pic16_freeAsmop(left,NULL,ic,TRUE);
+ pic16_freeAsmop(result,NULL,ic,TRUE);
}
#endif
size = AOP_SIZE(result);
DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
-
+
/* if bit then unpack */
if (IS_BITFIELD(letype)) {
genUnpackBits(result,left,"BAD",GPOINTER);
if (AOP_TYPE(left) == AOP_IMMD) { // do we ever get here? (untested!)
- lit = (unsigned)floatFromVal(AOP(left)->aopu.aop_lit);
+ lit = (unsigned) ulFromVal (AOP(left)->aopu.aop_lit);
// load FSR0 from immediate
pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
offset = 0;
while(size--) {
if(size) {
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
- } else {
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
+ } else {
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
}
offset++;
mov2fp(pic16_popCopyReg(&pic16_pc_prodl), AOP(left), 1);
pic16_mov2w(AOP(left), 2);
pic16_callGenericPointerRW(0, size);
-
+
assignResultValue(result, size, 1);
-
+
goto release;
}
/* genConstPointerGet - get value from const generic pointer space */
/*-----------------------------------------------------------------*/
static void genConstPointerGet (operand *left,
- operand *result, iCode *ic)
+ operand *result, iCode *ic)
{
//sym_link *retype = getSpec(operandType(result));
- // symbol *albl = newiTempLabel(NULL); // patch 15
- // symbol *blbl = newiTempLabel(NULL); //
- // PIC_OPCODE poc; // patch 15
+ // symbol *albl = newiTempLabel(NULL); // patch 15
+ // symbol *blbl = newiTempLabel(NULL); //
+ // PIC_OPCODE poc; // patch 15
int size;
int offset = 0;
DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
// set up table pointer
- if( (AOP_TYPE(left) == AOP_PCODE)
+ if( (AOP_TYPE(left) == AOP_PCODE)
&& ((AOP(left)->aopu.pcop->type == PO_IMMEDIATE)
|| (AOP(left)->aopu.pcop->type == PO_DIR)))
{
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat), pic16_popGet(AOP(result),offset)));
offset++;
}
-
+
pic16_freeAsmop(left,NULL,ic,TRUE);
pic16_freeAsmop(result,NULL,ic,TRUE);
}
int p_type;
FENTRY;
-
+
left = IC_LEFT(ic);
result = IC_RESULT(ic) ;
DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
/* if left is of type of pointer then it is simple */
- if (IS_PTR(type) && !IS_FUNC(type->next))
+ if (IS_PTR(type) && !IS_FUNC(type->next))
p_type = DCL_TYPE(type);
else {
/* we have to go by the storage class */
if (SPEC_OCLS(etype)->codesp ) {
DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
- //p_type = CPOINTER ;
+ //p_type = CPOINTER ;
} else
if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) {
DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
- /*p_type = FPOINTER ;*/
+ /*p_type = FPOINTER ;*/
} else
if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) {
DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
/* now that we have the pointer type we assign
the pointer values */
switch (p_type) {
- case POINTER:
+ case POINTER:
case FPOINTER:
case IPOINTER:
- genNearPointerGet (left,result,ic);
- break;
+ genNearPointerGet (left,result,ic);
+ break;
case PPOINTER:
- genPagedPointerGet(left,result,ic);
- break;
+ genPagedPointerGet(left,result,ic);
+ break;
#if 0
/* PICs do not support FAR pointers... */
/* MUST move them somewhere; handle FPOINTERs like POINTERS or like GPOINTERs?!? */
case FPOINTER:
- genFarPointerGet (left,result,ic);
- break;
+ genFarPointerGet (left,result,ic);
+ break;
#endif
case CPOINTER:
- genConstPointerGet (left,result,ic);
- //pic16_emitcodePointerGet (left,result,ic);
- break;
+ genConstPointerGet (left,result,ic);
+ //pic16_emitcodePointerGet (left,result,ic);
+ break;
case GPOINTER:
#if 0
if (IS_PTR_CONST(type))
- genConstPointerGet (left,result,ic);
+ genConstPointerGet (left,result,ic);
else
#endif
- genGenPointerGet (left,result,ic);
+ genGenPointerGet (left,result,ic);
break;
default:
- werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "genPointerGet: illegal pointer type");
-
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "genPointerGet: illegal pointer type");
+
}
}
int shCnt = 0 ;
int offset = 0 ;
int rLen = 0 ;
- int blen, bstr ;
+ int blen, bstr ;
int shifted_and_masked = 0;
unsigned long lit = (unsigned long)-1;
sym_link *retype;
retype = getSpec(operandType(right));
if(AOP_TYPE(right) == AOP_LIT) {
- lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
-
+ lit = ulFromVal (AOP(right)->aopu.aop_lit);
+
if((blen == 1) && (bstr < 8)) {
/* it is a single bit, so use the appropriate bit instructions */
DEBUGpic16_emitcode (";","%s %d optimize bit assignment",__FUNCTION__,__LINE__);
if(!IS_PTR(operandType(result)) || IS_DIRECT(result)) {
- /* workaround to reduce the extra lfsr instruction */
- if(lit) {
- pic16_emitpcode(POC_BSF,
- pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), 0), bstr));
- } else {
- pic16_emitpcode(POC_BCF,
- pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), 0), bstr));
- }
+ /* workaround to reduce the extra lfsr instruction */
+ if(lit) {
+ pic16_emitpcode(POC_BSF,
+ pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), 0), bstr));
+ } else {
+ pic16_emitpcode(POC_BCF,
+ pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), 0), bstr));
+ }
} else {
- if (PIC_IS_DATA_PTR(operandType(result))) {
- pic16_loadFSR0(result, 0);
- pic16_emitpcode(lit ? POC_BSF : POC_BCF,
- pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr));
- } else {
- /* get old value */
- pic16_derefPtr (result, p_type, 0, NULL);
- pic16_emitpcode(lit ? POC_BSF : POC_BCF,
- pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_wreg), bstr));
- /* write back new value */
- pic16_derefPtr (result, p_type, 1, NULL);
- }
+ if (PIC_IS_DATA_PTR(operandType(result))) {
+ pic16_loadFSR0(result, 0);
+ pic16_emitpcode(lit ? POC_BSF : POC_BCF,
+ pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr));
+ } else {
+ /* get old value */
+ pic16_derefPtr (result, p_type, 0, NULL);
+ pic16_emitpcode(lit ? POC_BSF : POC_BCF,
+ pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_wreg), bstr));
+ /* write back new value */
+ pic16_derefPtr (result, p_type, 1, NULL);
+ }
}
return;
offset++;
} else
if (IS_DIRECT(result) && !IS_PTR(operandType(result))
- && IS_BITFIELD(retype)
- && (AOP_TYPE(right) == AOP_REG || AOP_TYPE(right) == AOP_DIR)
- && (blen == 1)) {
+ && IS_BITFIELD(retype)
+ && (AOP_TYPE(right) == AOP_REG || AOP_TYPE(right) == AOP_DIR)
+ && (blen == 1)) {
int rblen, rbstr;
rblen = SPEC_BLEN( retype );
rbstr = SPEC_BSTR( retype );
if(IS_BITFIELD(etype)) {
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result), 0));
- pic16_emitpcode(POC_BCF, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_wreg), bstr));
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result), 0));
+ pic16_emitpcode(POC_BCF, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_wreg), bstr));
} else {
- pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
+ pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
}
pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(pic16_popGet(AOP(right), 0), rbstr));
if(IS_BITFIELD(etype)) {
- pic16_emitpcode(POC_BSF, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_wreg), bstr));
+ pic16_emitpcode(POC_BSF, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_wreg), bstr));
} else {
- pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_wreg));
+ pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_wreg));
}
pic16_emitpcode(POC_MOVWF, pic16_popGet( AOP(result), 0));
// we need to combine the value with the old value
if(!shifted_and_masked)
{
- pic16_emitpcode(POC_ANDLW, pic16_popGetLit((1U << blen)-1));
+ pic16_emitpcode(POC_ANDLW, pic16_popGetLit((1U << blen)-1));
- DEBUGpic16_emitcode(";", "shCnt = %d SPEC_BSTR(etype) = %d:%d", shCnt,
- SPEC_BSTR(etype), SPEC_BLEN(etype));
+ DEBUGpic16_emitcode(";", "shCnt = %d SPEC_BSTR(etype) = %d:%d", shCnt,
+ SPEC_BSTR(etype), SPEC_BLEN(etype));
- /* shift left acc, do NOT mask the result again */
- AccLsh(shCnt, 0);
+ /* shift left acc, do NOT mask the result again */
+ AccLsh(shCnt, 0);
- /* using PRODH as a temporary register here */
- pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodh));
+ /* using PRODH as a temporary register here */
+ pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodh));
}
if ((IS_SYMOP(result) && !IS_PTR(operandType (result)))
- || IS_DIRECT(result)) {
- /* access symbol directly */
- pic16_mov2w (AOP(result), 0);
+ || IS_DIRECT(result)) {
+ /* access symbol directly */
+ pic16_mov2w (AOP(result), 0);
} else {
- /* get old value */
- pic16_derefPtr (result, p_type, 0, &fsr0_setup);
+ /* get old value */
+ pic16_derefPtr (result, p_type, 0, &fsr0_setup);
}
#if 1
pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
- (unsigned char)((unsigned char)(0xff << (blen+bstr)) |
- (unsigned char)(0xff >> (8-bstr))) ));
+ (unsigned char)((unsigned char)(0xff << (blen+bstr)) |
+ (unsigned char)(0xff >> (8-bstr))) ));
if (!shifted_and_masked) {
pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodh));
} else {
/* We have the shifted and masked (literal) right value in `lit' */
if (lit != 0)
- pic16_emitpcode(POC_IORLW, pic16_popGetLit(lit));
+ pic16_emitpcode(POC_IORLW, pic16_popGetLit(lit));
}
} else { // if (blen == 8 && (bstr % 8) == 0)
- if (shifted_and_masked) {
- // move right (literal) to WREG (only case where right is not yet in WREG)
- pic16_mov2w(AOP(right), (bstr / 8));
- }
+ if (shifted_and_masked) {
+ // move right (literal) to WREG (only case where right is not yet in WREG)
+ pic16_mov2w(AOP(right), (bstr / 8));
+ }
}
/* write new value back */
if ((IS_SYMOP(result) && !IS_PTR(operandType(result)))
- || IS_DIRECT(result)) {
+ || IS_DIRECT(result)) {
pic16_emitpcode (POC_MOVWF, pic16_popGet(AOP(result),0));
} else {
pic16_derefPtr (result, p_type, 1, &fsr0_setup);
#endif
- pic16_loadFSR0(result, 0); // load FSR0 with address of result
+ pic16_loadFSR0(result, 0); // load FSR0 with address of result
rLen = SPEC_BLEN(etype)-8;
/* now generate for lengths greater than one byte */
switch (p_type) {
case POINTER:
- pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postinc0));
- break;
-
- /*
- case FPOINTER:
- MOVA(l);
- pic16_emitcode("movx","@dptr,a");
- break;
-
- case GPOINTER:
- MOVA(l);
- DEBUGpic16_emitcode(";lcall","__gptrput");
- break;
- */
+ pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postinc0));
+ break;
+
+ /*
+ case FPOINTER:
+ MOVA(l);
+ pic16_emitcode("movx","@dptr,a");
+ break;
+
+ case GPOINTER:
+ MOVA(l);
+ DEBUGpic16_emitcode(";lcall","__gptrput");
+ break;
+ */
default:
- assert(0);
- }
+ assert(0);
+ }
pic16_mov2w(AOP(right), offset++);
/* save the byte & read byte */
switch (p_type) {
case POINTER:
- // pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodl));
- pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
- break;
-
- /*
- case FPOINTER:
- pic16_emitcode ("mov","b,a");
- pic16_emitcode("movx","a,@dptr");
- break;
-
- case GPOINTER:
- pic16_emitcode ("push","b");
- pic16_emitcode ("push","acc");
- pic16_emitcode ("lcall","__gptrget");
- pic16_emitcode ("pop","b");
- break;
- */
+ // pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodl));
+ pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
+ break;
+
+ /*
+ case FPOINTER:
+ pic16_emitcode ("mov","b,a");
+ pic16_emitcode("movx","a,@dptr");
+ break;
+
+ case GPOINTER:
+ pic16_emitcode ("push","b");
+ pic16_emitcode ("push","acc");
+ pic16_emitcode ("lcall","__gptrget");
+ pic16_emitcode ("pop","b");
+ break;
+ */
default:
- assert(0);
+ assert(0);
}
DEBUGpic16_emitcode(";", "rLen = %i", rLen);
pic16_emitpcode(POC_ANDLW, pic16_popGetLit((unsigned char)-1 << -rLen));
case POINTER:
pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
- // pic16_emitcode("mov","@%s,a",rname);
+ // pic16_emitcode("mov","@%s,a",rname);
break;
/*
- case FPOINTER:
- pic16_emitcode("movx","@dptr,a");
- break;
+ case FPOINTER:
+ pic16_emitcode("movx","@dptr,a");
+ break;
- case GPOINTER:
- DEBUGpic16_emitcode(";lcall","__gptrput");
- break;
+ case GPOINTER:
+ DEBUGpic16_emitcode(";lcall","__gptrput");
+ break;
*/
default:
assert(0);
/* genDataPointerSet - remat pointer to data space */
/*-----------------------------------------------------------------*/
static void genDataPointerSet(operand *right,
- operand *result,
- iCode *ic)
+ operand *result,
+ iCode *ic)
{
int size, offset = 0, resoffset=0 ;
size = AOP_SIZE(right);
-// fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
+// fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
#if 0
if ( AOP_TYPE(result) == AOP_PCODE) {
fprintf(stderr,"genDataPointerSet %s, %d\n",
- AOP(result)->aopu.pcop->name,
- (AOP(result)->aopu.pcop->type == PO_DIR)?
- PCOR(AOP(result)->aopu.pcop)->instance:
- PCOI(AOP(result)->aopu.pcop)->offset);
+ AOP(result)->aopu.pcop->name,
+ (AOP(result)->aopu.pcop->type == PO_DIR)?
+ PCOR(AOP(result)->aopu.pcop)->instance:
+ PCOI(AOP(result)->aopu.pcop)->offset);
}
#endif
while (size--) {
if (AOP_TYPE(right) == AOP_LIT) {
- unsigned int lit = pic16aopLiteral(AOP(IC_RIGHT(ic))->aopu.aop_lit, offset);
- pic16_movLit2f(pic16_popGet(AOP(result), offset), lit);
+ unsigned int lit = pic16aopLiteral(AOP(IC_RIGHT(ic))->aopu.aop_lit, offset);
+ pic16_movLit2f(pic16_popGet(AOP(result), offset), lit);
} else {
- pic16_mov2w(AOP(right), offset);
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset)); // patch 8
+ pic16_mov2w(AOP(right), offset);
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset)); // patch 8
}
offset++;
resoffset++;
/* genNearPointerSet - pic16_emitcode for near pointer put */
/*-----------------------------------------------------------------*/
static void genNearPointerSet (operand *right,
- operand *result,
+ operand *result,
iCode *ic)
{
asmop *aop = NULL;
sym_link *retype;
sym_link *ptype = operandType(result);
sym_link *resetype;
-
+
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
retype= getSpec(operandType(right));
resetype = getSpec(operandType(result));
-
+
pic16_aopOp(result,ic,FALSE);
-
+
/* if the result is rematerializable &
* in data space & not a bit variable */
-
+
/* and result is not a bit variable */
if (AOP_TYPE(result) == AOP_PCODE
// && AOP_TYPE(result) == AOP_IMMD
} else {
/* we have can just get the values */
int size = AOP_SIZE(right);
- int offset = 0 ;
+ int offset = 0 ;
pic16_loadFSR0(result, 0);
-
+
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
while (size--) {
if (is_LitOp(right)) {
pic16_popCopyReg(&pic16_pc_indf0)));
}
}
-
+
offset++;
}
}
if (aop) {
/* we had to allocate for this iCode */
pic16_freeAsmop(NULL,aop,ic,TRUE);
- } else {
+ } else {
/* we did not allocate which means left
* already in a pointer register, then
* if size > 0 && this could be used again
- * we have to point it back to where it
+ * we have to point it back to where it
* belongs */
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if (AOP_SIZE(right) > 1
/* genPagedPointerSet - pic16_emitcode for Paged pointer put */
/*-----------------------------------------------------------------*/
static void genPagedPointerSet (operand *right,
- operand *result,
- iCode *ic)
+ operand *result,
+ iCode *ic)
{
asmop *aop = NULL;
regs *preg = NULL ;
char *rname , *l;
sym_link *retype;
-
+
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
retype= getSpec(operandType(right));
-
+
pic16_aopOp(result,ic,FALSE);
-
+
/* if the value is already in a pointer register
then don't need anything more */
if (!AOP_INPREG(AOP(result))) {
- /* otherwise get a free pointer register */
- aop = newAsmop(0);
- preg = getFreePtr(ic,&aop,FALSE);
- pic16_emitcode("mov","%s,%s",
- preg->name,
- pic16_aopGet(AOP(result),0,FALSE,TRUE));
- rname = preg->name ;
+ /* otherwise get a free pointer register */
+ aop = newAsmop(0);
+ preg = getFreePtr(ic,&aop,FALSE);
+ pic16_emitcode("mov","%s,%s",
+ preg->name,
+ pic16_aopGet(AOP(result),0,FALSE,TRUE));
+ rname = preg->name ;
} else
- rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
-
+ rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
+
pic16_freeAsmop(result,NULL,ic,TRUE);
pic16_aopOp (right,ic,FALSE);
/* if bitfield then unpack the bits */
- if (IS_BITFIELD(retype))
- genPackBits (retype,result,right,rname,PPOINTER);
+ if (IS_BITFIELD(retype))
+ genPackBits (retype,result,right,rname,PPOINTER);
else {
- /* we have can just get the values */
- int size = AOP_SIZE(right);
- int offset = 0 ;
-
- while (size--) {
- l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
-
- MOVA(l);
- pic16_emitcode("movx","@%s,a",rname);
-
- if (size)
- pic16_emitcode("inc","%s",rname);
-
- offset++;
- }
- }
-
+ /* we have can just get the values */
+ int size = AOP_SIZE(right);
+ int offset = 0 ;
+
+ while (size--) {
+ l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
+
+ MOVA(l);
+ pic16_emitcode("movx","@%s,a",rname);
+
+ if (size)
+ pic16_emitcode("inc","%s",rname);
+
+ offset++;
+ }
+ }
+
/* now some housekeeping stuff */
if (aop) {
- /* we had to allocate for this iCode */
- pic16_freeAsmop(NULL,aop,ic,TRUE);
- } else {
- /* we did not allocate which means left
- already in a pointer register, then
- if size > 0 && this could be used again
- we have to point it back to where it
- belongs */
- if (AOP_SIZE(right) > 1 &&
- !OP_SYMBOL(result)->remat &&
- ( OP_SYMBOL(result)->liveTo > ic->seq ||
- ic->depth )) {
- int size = AOP_SIZE(right) - 1;
- while (size--)
- pic16_emitcode("dec","%s",rname);
- }
+ /* we had to allocate for this iCode */
+ pic16_freeAsmop(NULL,aop,ic,TRUE);
+ } else {
+ /* we did not allocate which means left
+ already in a pointer register, then
+ if size > 0 && this could be used again
+ we have to point it back to where it
+ belongs */
+ if (AOP_SIZE(right) > 1 &&
+ !OP_SYMBOL(result)->remat &&
+ ( OP_SYMBOL(result)->liveTo > ic->seq ||
+ ic->depth )) {
+ int size = AOP_SIZE(right) - 1;
+ while (size--)
+ pic16_emitcode("dec","%s",rname);
+ }
}
/* done */
pic16_freeAsmop(right,NULL,ic,TRUE);
-
-
+
+
}
#if 0
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
pic16_aopOp(result,ic,FALSE);
- /* if the operand is already in dptr
+ /* if the operand is already in dptr
then we do nothing else we move the value to dptr */
if (AOP_TYPE(result) != AOP_STR) {
/* if this is remateriazable */
pic16_aopOp(right,ic,FALSE);
/* if bit then unpack */
- if (IS_BITFIELD(retype))
+ if (IS_BITFIELD(retype))
genPackBits(retype,result,right,"dptr",FPOINTER);
else {
size = AOP_SIZE(right);
static void genGenPointerSet (operand *right,
operand *result, iCode *ic)
{
- int i, size, offset, lit;
- sym_link *retype = getSpec(operandType(right));
-
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- pic16_aopOp(result,ic,FALSE);
- pic16_aopOp(right,ic,FALSE);
- size = AOP_SIZE(right);
- offset = 0;
-
- DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
-
- /* if the operand is already in dptr
- then we do nothing else we move the value to dptr */
- if (AOP_TYPE(result) != AOP_STR) {
- /* if this is remateriazable */
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- // WARNING: anythig until "else" is untested!
- if (AOP_TYPE(result) == AOP_IMMD) {
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- lit = (unsigned)floatFromVal(AOP(result)->aopu.aop_lit);
- // load FSR0 from immediate
- pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
- offset = 0;
- while(size--) {
- if(size) {
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
- } else {
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
- }
- offset++;
- }
- goto release;
- }
- else { /* we need to get it byte by byte */
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
-
- // set up FSR0 with address of result
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
-
- /* hack hack! see if this the FSR. If so don't load W */
- if(AOP_TYPE(right) != AOP_ACC) {
-
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- if(AOP_TYPE(right) == AOP_LIT)
- {
- // copy literal
- // note: pic16_popGet handles sign extension
- for(i=0;i<size;i++) {
- pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),i));
- if(i < size-1)
- pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postinc0));
- else
- pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
- }
- } else {
- // copy regs
-
- for(i=0;i<size;i++) {
- if(i < size-1)
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),i),
- pic16_popCopyReg(&pic16_pc_postinc0)));
- else
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),i),
- pic16_popCopyReg(&pic16_pc_indf0)));
- }
- }
- goto release;
- }
- // right = ACC
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
- goto release;
- } // if (AOP_TYPE(result) != AOP_IMMD)
-
- } // if (AOP_TYPE(result) != AOP_STR)
- /* so dptr know contains the address */
-
-
- /* if bit then unpack */
- if (IS_BITFIELD(retype))
- genPackBits(retype,result,right,"dptr",GPOINTER);
- else {
- size = AOP_SIZE(right);
- offset = 0 ;
-
- DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
-
- // set up FSR0 with address of result
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
-
- while (size--) {
- if (AOP_TYPE(right) == AOP_LIT) {
- pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
- if (size) {
- pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0));
- } else {
- pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
- }
- } else { // no literal
- if(size) {
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
- } else {
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
- }
- }
- offset++;
- }
- }
-
- release:
- pic16_freeAsmop(right,NULL,ic,TRUE);
- pic16_freeAsmop(result,NULL,ic,TRUE);
+ int i, size, offset, lit;
+ sym_link *retype = getSpec(operandType(right));
+
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ pic16_aopOp(result,ic,FALSE);
+ pic16_aopOp(right,ic,FALSE);
+ size = AOP_SIZE(right);
+ offset = 0;
+
+ DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
+
+ /* if the operand is already in dptr
+ then we do nothing else we move the value to dptr */
+ if (AOP_TYPE(result) != AOP_STR) {
+ /* if this is remateriazable */
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ // WARNING: anythig until "else" is untested!
+ if (AOP_TYPE(result) == AOP_IMMD) {
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ lit = (unsigned) ulFromVal (AOP(result)->aopu.aop_lit);
+ // load FSR0 from immediate
+ pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
+ offset = 0;
+ while(size--) {
+ if(size) {
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
+ } else {
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
+ }
+ offset++;
+ }
+ goto release;
+ }
+ else { /* we need to get it byte by byte */
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
+
+ // set up FSR0 with address of result
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
+
+ /* hack hack! see if this the FSR. If so don't load W */
+ if(AOP_TYPE(right) != AOP_ACC) {
+
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ if(AOP_TYPE(right) == AOP_LIT)
+ {
+ // copy literal
+ // note: pic16_popGet handles sign extension
+ for(i=0;i<size;i++) {
+ pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),i));
+ if(i < size-1)
+ pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postinc0));
+ else
+ pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
+ }
+ } else {
+ // copy regs
+
+ for(i=0;i<size;i++) {
+ if(i < size-1)
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),i),
+ pic16_popCopyReg(&pic16_pc_postinc0)));
+ else
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),i),
+ pic16_popCopyReg(&pic16_pc_indf0)));
+ }
+ }
+ goto release;
+ }
+ // right = ACC
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
+ goto release;
+ } // if (AOP_TYPE(result) != AOP_IMMD)
+
+ } // if (AOP_TYPE(result) != AOP_STR)
+ /* so dptr know contains the address */
+
+
+ /* if bit then unpack */
+ if (IS_BITFIELD(retype))
+ genPackBits(retype,result,right,"dptr",GPOINTER);
+ else {
+ size = AOP_SIZE(right);
+ offset = 0 ;
+
+ DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
+
+ // set up FSR0 with address of result
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
+
+ while (size--) {
+ if (AOP_TYPE(right) == AOP_LIT) {
+ pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
+ if (size) {
+ pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0));
+ } else {
+ pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
+ }
+ } else { // no literal
+ if(size) {
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
+ } else {
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
+ }
+ }
+ offset++;
+ }
+ }
+
+ release:
+ pic16_freeAsmop(right,NULL,ic,TRUE);
+ pic16_freeAsmop(result,NULL,ic,TRUE);
}
#endif
if(size>1)mov2fp(pic16_popCopyReg(&pic16_pc_prodh), AOP(right), 1);
if(size>2)mov2fp(pic16_popCopyReg(&pic16_pc_tblptrl), AOP(right), 2);
if(size>3)mov2fp(pic16_popCopyReg(&pic16_pc_tblptrh), AOP(right), 3);
-
+
/* load address to write to in WREG:FSR0H:FSR0L */
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result), 0),
pic16_popCopyReg(&pic16_pc_fsr0l)));
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result), 1),
pic16_popCopyReg(&pic16_pc_prodl)));
pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result), 2));
-
+
pic16_callGenericPointerRW(1, size);
release:
/* genPointerSet - stores the value into a pointer location */
/*-----------------------------------------------------------------*/
static void genPointerSet (iCode *ic)
-{
+{
operand *right, *result ;
sym_link *type, *etype;
int p_type;
move it to the correct pointer register */
type = operandType(result);
etype = getSpec(type);
-
+
/* if left is of type of pointer then it is simple */
if (IS_PTR(type) && !IS_FUNC(type->next)) {
p_type = DCL_TYPE(type);
}
else {
- /* we have to go by the storage class */
- p_type = PTR_TYPE(SPEC_OCLS(etype));
-
-/* if (SPEC_OCLS(etype)->codesp ) { */
-/* p_type = CPOINTER ; */
-/* } */
-/* else */
-/* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
-/* p_type = FPOINTER ; */
-/* else */
-/* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
-/* p_type = PPOINTER ; */
-/* else */
-/* if (SPEC_OCLS(etype) == idata ) */
-/* p_type = IPOINTER ; */
-/* else */
-/* p_type = POINTER ; */
+ /* we have to go by the storage class */
+ p_type = PTR_TYPE(SPEC_OCLS(etype));
+
+/* if (SPEC_OCLS(etype)->codesp ) { */
+/* p_type = CPOINTER ; */
+/* } */
+/* else */
+/* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
+/* p_type = FPOINTER ; */
+/* else */
+/* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
+/* p_type = PPOINTER ; */
+/* else */
+/* if (SPEC_OCLS(etype) == idata ) */
+/* p_type = IPOINTER ; */
+/* else */
+/* p_type = POINTER ; */
}
/* now that we have the pointer type we assign
case PPOINTER:
genPagedPointerSet (right,result,ic);
- break;
+ break;
#if 0
/* MUST move them somewhere; handle FPOINTERs like POINTERS or like GPOINTERs?!? */
genFarPointerSet (right,result,ic);
break;
#endif
-
+
case GPOINTER:
genGenPointerSet (right,result,ic);
break;
default:
- werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
"genPointerSet: illegal pointer type");
}
}
genIpop(popIc);
/* if the condition is a bit variable */
- if (isbit && IS_ITEMP(cond) &&
+ if (isbit && IS_ITEMP(cond) &&
SPIL_LOC(cond)) {
genIfxJump(ic,"c");
DEBUGpic16_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
{
operand *result, *left;
int size;
- symbol *sym; // = OP_SYMBOL(IC_LEFT(ic));
+ symbol *sym; // = OP_SYMBOL(IC_LEFT(ic));
pCodeOp *pcop0, *pcop1, *pcop2;
FENTRY;
pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
sym = OP_SYMBOL( IC_LEFT(ic) );
-
+
if(sym->onStack) {
/* get address of symbol on stack */
DEBUGpic16_emitcode("; ", "%s symbol %s on stack", __FUNCTION__, sym->name);
goto release;
}
-
-// if(pic16_debug_verbose) {
-// fprintf(stderr, "%s:%d %s symbol %s , codespace=%d\n",
-// __FILE__, __LINE__, __FUNCTION__, sym->name, IN_CODESPACE( SPEC_OCLS(sym->etype)));
-// }
-
+
+// if(pic16_debug_verbose) {
+// fprintf(stderr, "%s:%d %s symbol %s , codespace=%d\n",
+// __FILE__, __LINE__, __FUNCTION__, sym->name, IN_CODESPACE( SPEC_OCLS(sym->etype)));
+// }
+
pic16_aopOp((left=IC_LEFT(ic)), ic, FALSE);
size = AOP_SIZE(IC_RESULT(ic));
pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
-
+
if (size == 3) {
pic16_emitpcode(POC_MOVLW, pcop0);
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
char *l ;
/* first push the right side on to the stack */
while (size--) {
- l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
- MOVA(l);
- pic16_emitcode ("push","acc");
+ l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
+ MOVA(l);
+ pic16_emitcode ("push","acc");
}
-
+
pic16_freeAsmop(right,NULL,ic,FALSE);
/* now assign DPTR to result */
pic16_aopOp(result,ic,FALSE);
size = AOP_SIZE(result);
while (size--) {
- pic16_emitcode ("pop","acc");
- pic16_aopPut(AOP(result),"a",--offset);
+ pic16_emitcode ("pop","acc");
+ pic16_aopPut(AOP(result),"a",--offset);
}
pic16_freeAsmop(result,NULL,ic,FALSE);
-
+
}
#endif
right = IC_RIGHT(ic) ;
FENTRY;
-
+
/* if they are the same */
if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
return ;
/* if the right size is a literal then
we know what the value is */
if (AOP_TYPE(right) == AOP_LIT) {
-
+
pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
- pic16_popGet(AOP(result),0));
+ pic16_popGet(AOP(result),0));
- if (((int) operandLitValue(right)))
+ if (((int) operandLitValue(right)))
pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
AOP(result)->aopu.aop_dir,
AOP(result)->aopu.aop_dir);
pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
AOP(result)->aopu.aop_dir,
AOP(result)->aopu.aop_dir);
-
+
goto release;
}
if(AOP_TYPE(right) == AOP_LIT) {
if(!(IS_FLOAT(operandType( right )) || IS_FIXED(operandType(right))))
{
- lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
+ lit = ulFromVal (AOP(right)->aopu.aop_lit);
/* patch tag for literals that are cast to pointers */
if (IS_CODEPTR(restype)) {
- //fprintf (stderr, "%s:%u: INFO: `(__code*)literal'\n", ic->filename, ic->lineno);
- lit = (lit & 0x00ffff) | (GPTR_TAG_CODE << 16);
+ //fprintf (stderr, "%s:%u: INFO: `(__code*)literal'\n", ic->filename, ic->lineno);
+ lit = (lit & 0x00ffff) | (GPTR_TAG_CODE << 16);
} else {
- if (IS_GENPTR(restype))
- {
- if (IS_CODEPTR(rtype)) {
- //fprintf (stderr, "%s:%u: INFO: `(generic*)(literal __code*)'\n", ic->filename, ic->lineno);
- lit = (lit & 0x00ffff) | (GPTR_TAG_CODE << 16);
- } else if (PIC_IS_DATA_PTR(rtype)) {
- //fprintf (stderr, "%s:%u: INFO: `(generic*)(literal __data*)'\n", ic->filename, ic->lineno);
- lit = (lit & 0x00ffff) | (GPTR_TAG_DATA << 16);
- } else if (!IS_PTR(rtype) || IS_GENPTR(rtype)) {
- //fprintf (stderr, "%s:%u: INFO: `(generic*)literal' -- accepting specified tag %02x\n", ic->filename, ic->lineno, (unsigned char)(lit >> 16));
- } else if (IS_PTR(rtype)) {
- fprintf (stderr, "%s:%u: WARNING: `(generic*)literal' -- assuming __data space\n", ic->filename, ic->lineno);
- lit = (lit & 0x00ffff) | (GPTR_TAG_DATA << 16);
- }
- }
+ if (IS_GENPTR(restype))
+ {
+ if (IS_CODEPTR(rtype)) {
+ //fprintf (stderr, "%s:%u: INFO: `(generic*)(literal __code*)'\n", ic->filename, ic->lineno);
+ lit = (lit & 0x00ffff) | (GPTR_TAG_CODE << 16);
+ } else if (PIC_IS_DATA_PTR(rtype)) {
+ //fprintf (stderr, "%s:%u: INFO: `(generic*)(literal __data*)'\n", ic->filename, ic->lineno);
+ lit = (lit & 0x00ffff) | (GPTR_TAG_DATA << 16);
+ } else if (!IS_PTR(rtype) || IS_GENPTR(rtype)) {
+ //fprintf (stderr, "%s:%u: INFO: `(generic*)literal' -- accepting specified tag %02x\n", ic->filename, ic->lineno, (unsigned char)(lit >> 16));
+ } else if (IS_PTR(rtype)) {
+ fprintf (stderr, "%s:%u: WARNING: `(generic*)literal' -- assuming __data space\n", ic->filename, ic->lineno);
+ lit = (lit & 0x00ffff) | (GPTR_TAG_DATA << 16);
+ }
+ }
}
} else {
union {
- unsigned long lit_int;
- float lit_float;
+ unsigned long lit_int;
+ float lit_float;
} info;
if(IS_FIXED16X16(operandType(right))) {
- lit = (unsigned long)fixed16x16FromDouble( floatFromVal( AOP(right)->aopu.aop_lit));
+ lit = (unsigned long)fixed16x16FromDouble( floatFromVal( AOP(right)->aopu.aop_lit));
} else {
- /* take care if literal is a float */
- info.lit_float = floatFromVal(AOP(right)->aopu.aop_lit);
- lit = info.lit_int;
+ /* take care if literal is a float */
+ info.lit_float = floatFromVal(AOP(right)->aopu.aop_lit);
+ lit = info.lit_int;
}
}
}
// fprintf(stderr, "%s:%d: assigning value 0x%04lx (%d:%d)\n", __FUNCTION__, __LINE__, lit,
-// sizeof(unsigned long int), sizeof(float));
+// sizeof(unsigned long int), sizeof(float));
if (AOP_TYPE(right) == AOP_REG) {
DEBUGpic16_emitcode("; ", "%s:%d symbol in code space, take special care\n", __FUNCTION__, __LINE__);
fprintf(stderr, "%s:%d symbol %s = [ %s ] is in code space\n", __FILE__, __LINE__, OP_SYMBOL(result)->name, OP_SYMBOL(right)->name);
-
+
// set up table pointer
if(is_LitOp(right)) {
// fprintf(stderr, "%s:%d inside block 1\n", __FILE__, __LINE__);
/* VR - What is this?! */
if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
+
if(aopIdx(AOP(result),0) == 4) {
/* this is a workaround to save value of right into wreg too,
* value of wreg is going to be used later */
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
goto release;
} else
-// assert(0);
+// assert(0);
DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
}
#endif
while (size--) {
DEBUGpic16_emitcode ("; ***","%s %d size %d",__FUNCTION__,__LINE__, size);
if(AOP_TYPE(right) == AOP_LIT) {
- if(lit&0xff) {
- if(know_W != (lit&0xff))
- pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
- know_W = lit&0xff;
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
- } else
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
+ if(lit&0xff) {
+ if(know_W != (lit&0xff))
+ pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
+ know_W = lit&0xff;
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
+ } else
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
- lit >>= 8;
+ lit >>= 8;
} else if (AOP_TYPE(right) == AOP_CRY) {
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
- if(offset == 0) {
- //debugf("%s: BTFSS offset == 0\n", __FUNCTION__);
- pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
- }
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
+ if(offset == 0) {
+ //debugf("%s: BTFSS offset == 0\n", __FUNCTION__);
+ pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
+ }
} else if ( (AOP_TYPE(right) == AOP_PCODE) && (AOP(right)->aopu.pcop->type == PO_IMMEDIATE) ) {
- pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
+ pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
} else {
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- if(!_G.resDirect) { /* use this aopForSym feature */
- if(AOP_TYPE(result) == AOP_ACC) {
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset));
- } else
- if(AOP_TYPE(right) == AOP_ACC) {
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset));
- } else {
- pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
- }
- }
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ if(!_G.resDirect) { /* use this aopForSym feature */
+ if(AOP_TYPE(result) == AOP_ACC) {
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset));
+ } else
+ if(AOP_TYPE(right) == AOP_ACC) {
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset));
+ } else {
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
+ }
+ }
}
offset++;
}
pic16_addSign(result, AOP_SIZE(right), !IS_UNSIGNED(operandType(right)));
-
+
release:
pic16_freeAsmop (right,NULL,ic,FALSE);
pic16_freeAsmop (result,NULL,ic,TRUE);
-}
+}
/*-----------------------------------------------------------------*/
/* genJumpTab - generates code for jump table */
for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
jtab = setNextItem(IC_JTLABELS(ic))) {
// pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
-
+ pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
+
}
pic16_emitpinfo (INF_OPTIMIZATION, pic16_newpCodeOpOpt (OPT_JUMPTABLE_END, ""));
/*-----------------------------------------------------------------*/
/*
TSD - Written for the PIC port - but this unfortunately is buggy.
- This routine is good in that it is able to efficiently promote
+ This routine is good in that it is able to efficiently promote
types to different (larger) sizes. Unfortunately, the temporary
variables that are optimized out by this routine are sometimes
- used in other places. So until I know how to really parse the
+ used in other places. So until I know how to really parse the
iCode tree, I'm going to not be using this routine :(.
*/
static int genMixedOperation (iCode *ic)
operand *t = right;
right = nextright;
- nextright = t;
+ nextright = t;
pic16_emitcode(";remove right +","");
/*
operand *t = right;
right = nextleft;
- nextleft = t;
+ nextleft = t;
*/
pic16_emitcode(";remove left +","");
} else
pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
- pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
- pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
+ pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
+ pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
} else
- pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
+ pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
offset = 0;
while(--big) {
- offset++;
+ offset++;
- if(--small) {
- if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
- pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
- pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
- }
+ if(--small) {
+ if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
+ pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
+ pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
+ }
- pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
- emitSKPNC;
- pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
- AOP(IC_RIGHT(nextic))->aopu.aop_dir,
- AOP(IC_RIGHT(nextic))->aopu.aop_dir);
- pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
- pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
+ pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
+ emitSKPNC;
+ pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
+ AOP(IC_RIGHT(nextic))->aopu.aop_dir,
+ AOP(IC_RIGHT(nextic))->aopu.aop_dir);
+ pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
+ pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
- } else {
- pic16_emitcode("rlf","known_zero,w");
+ } else {
+ pic16_emitcode("rlf","known_zero,w");
- /*
- if right is signed
- btfsc right,7
+ /*
+ if right is signed
+ btfsc right,7
addlw ff
- */
- if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
- pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
- pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
- } else {
- pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
- }
- }
+ */
+ if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
+ pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
+ pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
+ } else {
+ pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
+ }
+ }
}
ret = 1;
}
FENTRY;
- /* if they are equivalent then do nothing */
-// if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
-// return ;
-
- pic16_aopOp(result,ic,FALSE);
- pic16_aopOp(right,ic,FALSE) ;
-
- DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
-
-
- /* if the result is a bit */
- if (AOP_TYPE(result) == AOP_CRY) {
-
- /* if the right size is a literal then
- * we know what the value is */
- DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
-
- if (AOP_TYPE(right) == AOP_LIT) {
- pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
- pic16_popGet(AOP(result),0));
-
- if (((int) operandLitValue(right)))
- pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
- AOP(result)->aopu.aop_dir,
- AOP(result)->aopu.aop_dir);
- else
- pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
- AOP(result)->aopu.aop_dir,
- AOP(result)->aopu.aop_dir);
- goto release;
- }
-
- /* the right is also a bit variable */
- if (AOP_TYPE(right) == AOP_CRY) {
- emitCLRC;
- pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
-
- pic16_emitcode("clrc","");
- pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
- AOP(right)->aopu.aop_dir,
- AOP(right)->aopu.aop_dir);
- pic16_aopPut(AOP(result),"c",0);
- goto release ;
- }
-
- /* we need to or */
- if (AOP_TYPE(right) == AOP_REG) {
- pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0, PO_GPR_REGISTER));
- pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
- }
- pic16_toBoolean(right);
- pic16_aopPut(AOP(result),"a",0);
- goto release ;
- }
-
- if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
- int offset = 1;
-
- size = AOP_SIZE(result);
-
- DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
-
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
-
- while (size--)
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
-
- goto release;
- }
-
- if(IS_BITFIELD(getSpec(restype))
- && IS_BITFIELD(getSpec(rtype))) {
- DEBUGpic16_emitcode("***", "%d casting a bit to another bit", __LINE__);
- }
-
- /* port from pic14 to cope with generic pointers */
- if (PIC_IS_TAGGED(restype))
- {
- operand *result = IC_RESULT(ic);
- //operand *left = IC_LEFT(ic);
- operand *right = IC_RIGHT(ic);
- int tag = 0xff;
-
- /* copy common part */
- int max, size = AOP_SIZE(result);
- if (size > AOP_SIZE(right)) size = AOP_SIZE(right);
- DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
-
- max = size;
- while (size--)
- {
- pic16_mov2w (AOP(right), size);
- pic16_emitpcode(POC_MOVWF, pic16_popGet (AOP(result), size));
- } // while
-
- /* upcast into generic pointer type? */
- if (IS_GENPTR(restype)
- && !PIC_IS_TAGGED(rtype)
- && (AOP_SIZE(result) > max))
- {
- /* determine appropriate tag for right */
- if (PIC_IS_DATA_PTR(rtype))
- tag = GPTR_TAG_DATA;
- else if (IS_CODEPTR(rtype))
- tag = GPTR_TAG_CODE;
- else if (PIC_IS_DATA_PTR(ctype)) {
- //fprintf (stderr, "%s:%u: WARNING: casting `(generic*)(__data*)(non-pointer)'\n", ic->filename, ic->lineno);
- tag = GPTR_TAG_DATA;
- } else if (IS_CODEPTR(ctype)) {
- //fprintf (stderr, "%s:%u: WARNING: casting `(generic*)(__code*)(non-pointer)'\n", ic->filename, ic->lineno);
- tag = GPTR_TAG_CODE;
- } else if (IS_PTR(rtype)) {
- PERFORM_ONCE(weirdcast,
- fprintf (stderr, "%s:%u: WARNING: casting `(generic*)(unknown*)' -- assuming __data space\n", ic->filename, ic->lineno);
- );
- tag = GPTR_TAG_DATA;
- } else {
- PERFORM_ONCE(weirdcast,
- fprintf (stderr, "%s:%u: WARNING: casting `(generic*)(non-pointer)' -- assuming __data space\n", ic->filename, ic->lineno);
- );
- tag = GPTR_TAG_DATA;
- }
-
- assert (AOP_SIZE(result) == 3);
- /* zero-extend address... */
- for (size = max; size < AOP_SIZE(result)-1; size++)
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
- /* ...and add tag */
- pic16_movLit2f(pic16_popGet(AOP(result), AOP_SIZE(result)-1), tag);
- } else if (IS_CODEPTR(restype) && AOP_SIZE(result) > max) {
- //fprintf (stderr, "%s:%u: INFO: code pointer\n", ic->filename, ic->lineno);
- for (size = max; size < AOP_SIZE(result)-1; size++)
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), size));
- /* add __code tag */
- pic16_movLit2f (pic16_popGet(AOP(result), AOP_SIZE(result)-1), GPTR_TAG_CODE);
- } else if (AOP_SIZE(result) > max) {
- /* extend non-pointers */
- //fprintf (stderr, "%s:%u: zero-extending value cast to pointer\n", ic->filename, ic->lineno);
- pic16_addSign(result, max, 0);
- } // if
- goto release;
- }
-
- /* if they are the same size : or less */
- if (AOP_SIZE(result) <= AOP_SIZE(right)) {
-
- /* if they are in the same place */
- if (pic16_sameRegs(AOP(right),AOP(result)))
- goto release;
-
- DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
+ /* if they are equivalent then do nothing */
+// if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
+// return ;
+
+ pic16_aopOp(result,ic,FALSE);
+ pic16_aopOp(right,ic,FALSE) ;
+
+ DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
+
+
+ /* if the result is a bit */
+ if (AOP_TYPE(result) == AOP_CRY) {
+
+ /* if the right size is a literal then
+ * we know what the value is */
+ DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ if (AOP_TYPE(right) == AOP_LIT) {
+ pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
+ pic16_popGet(AOP(result),0));
+
+ if (((int) operandLitValue(right)))
+ pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
+ AOP(result)->aopu.aop_dir,
+ AOP(result)->aopu.aop_dir);
+ else
+ pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
+ AOP(result)->aopu.aop_dir,
+ AOP(result)->aopu.aop_dir);
+ goto release;
+ }
+
+ /* the right is also a bit variable */
+ if (AOP_TYPE(right) == AOP_CRY) {
+ emitCLRC;
+ pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
+
+ pic16_emitcode("clrc","");
+ pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
+ AOP(right)->aopu.aop_dir,
+ AOP(right)->aopu.aop_dir);
+ pic16_aopPut(AOP(result),"c",0);
+ goto release ;
+ }
+
+ /* we need to or */
+ if (AOP_TYPE(right) == AOP_REG) {
+ pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0, PO_GPR_REGISTER));
+ pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
+ }
+ pic16_toBoolean(right);
+ pic16_aopPut(AOP(result),"a",0);
+ goto release ;
+ }
+
+ if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
+ int offset = 1;
+
+ size = AOP_SIZE(result);
+
+ DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
+
+ while (size--)
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
+
+ goto release;
+ }
+
+ if(IS_BITFIELD(getSpec(restype))
+ && IS_BITFIELD(getSpec(rtype))) {
+ DEBUGpic16_emitcode("***", "%d casting a bit to another bit", __LINE__);
+ }
+
+ /* port from pic14 to cope with generic pointers */
+ if (PIC_IS_TAGGED(restype))
+ {
+ operand *result = IC_RESULT(ic);
+ //operand *left = IC_LEFT(ic);
+ operand *right = IC_RIGHT(ic);
+ int tag = 0xff;
+
+ /* copy common part */
+ int max, size = AOP_SIZE(result);
+ if (size > AOP_SIZE(right)) size = AOP_SIZE(right);
+ DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ max = size;
+ while (size--)
+ {
+ pic16_mov2w (AOP(right), size);
+ pic16_emitpcode(POC_MOVWF, pic16_popGet (AOP(result), size));
+ } // while
+
+ /* upcast into generic pointer type? */
+ if (IS_GENPTR(restype)
+ && !PIC_IS_TAGGED(rtype)
+ && (AOP_SIZE(result) > max))
+ {
+ /* determine appropriate tag for right */
+ if (PIC_IS_DATA_PTR(rtype))
+ tag = GPTR_TAG_DATA;
+ else if (IS_CODEPTR(rtype))
+ tag = GPTR_TAG_CODE;
+ else if (PIC_IS_DATA_PTR(ctype)) {
+ //fprintf (stderr, "%s:%u: WARNING: casting `(generic*)(__data*)(non-pointer)'\n", ic->filename, ic->lineno);
+ tag = GPTR_TAG_DATA;
+ } else if (IS_CODEPTR(ctype)) {
+ //fprintf (stderr, "%s:%u: WARNING: casting `(generic*)(__code*)(non-pointer)'\n", ic->filename, ic->lineno);
+ tag = GPTR_TAG_CODE;
+ } else if (IS_PTR(rtype)) {
+ PERFORM_ONCE(weirdcast,
+ fprintf (stderr, "%s:%u: WARNING: casting `(generic*)(unknown*)' -- assuming __data space\n", ic->filename, ic->lineno);
+ );
+ tag = GPTR_TAG_DATA;
+ } else {
+ PERFORM_ONCE(weirdcast,
+ fprintf (stderr, "%s:%u: WARNING: casting `(generic*)(non-pointer)' -- assuming __data space\n", ic->filename, ic->lineno);
+ );
+ tag = GPTR_TAG_DATA;
+ }
+
+ assert (AOP_SIZE(result) == 3);
+ /* zero-extend address... */
+ for (size = max; size < AOP_SIZE(result)-1; size++)
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
+ /* ...and add tag */
+ pic16_movLit2f(pic16_popGet(AOP(result), AOP_SIZE(result)-1), tag);
+ } else if (IS_CODEPTR(restype) && AOP_SIZE(result) > max) {
+ //fprintf (stderr, "%s:%u: INFO: code pointer\n", ic->filename, ic->lineno);
+ for (size = max; size < AOP_SIZE(result)-1; size++)
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), size));
+ /* add __code tag */
+ pic16_movLit2f (pic16_popGet(AOP(result), AOP_SIZE(result)-1), GPTR_TAG_CODE);
+ } else if (AOP_SIZE(result) > max) {
+ /* extend non-pointers */
+ //fprintf (stderr, "%s:%u: zero-extending value cast to pointer\n", ic->filename, ic->lineno);
+ pic16_addSign(result, max, 0);
+ } // if
+ goto release;
+ }
+
+ /* if they are the same size : or less */
+ if (AOP_SIZE(result) <= AOP_SIZE(right)) {
+
+ /* if they are in the same place */
+ if (pic16_sameRegs(AOP(right),AOP(result)))
+ goto release;
+
+ DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
#if 0
- if (IS_PTR_CONST(rtype))
+ if (IS_PTR_CONST(rtype))
#else
- if (IS_CODEPTR(rtype))
+ if (IS_CODEPTR(rtype))
#endif
- DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
+ DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
#if 0
- if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
+ if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
#else
- if (IS_CODEPTR(operandType(IC_RESULT(ic))))
+ if (IS_CODEPTR(operandType(IC_RESULT(ic))))
#endif
- DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
+ DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
#if 0
- if(AOP_TYPE(right) == AOP_IMMD) {
- pCodeOp *pcop0, *pcop1, *pcop2;
- symbol *sym = OP_SYMBOL( right );
-
- size = AOP_SIZE(result);
- /* low */
- pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
- /* high */
- pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
- /* upper */
- pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
-
- if (size == 3) {
- pic16_emitpcode(POC_MOVLW, pcop0);
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
- pic16_emitpcode(POC_MOVLW, pcop1);
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
- pic16_emitpcode(POC_MOVLW, pcop2);
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
- } else
- if (size == 2) {
- pic16_emitpcode(POC_MOVLW, pcop0);
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_MOVLW, pcop1);
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
- } else {
- pic16_emitpcode(POC_MOVLW, pcop0);
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
- }
- } else
+ if(AOP_TYPE(right) == AOP_IMMD) {
+ pCodeOp *pcop0, *pcop1, *pcop2;
+ symbol *sym = OP_SYMBOL( right );
+
+ size = AOP_SIZE(result);
+ /* low */
+ pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
+ /* high */
+ pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
+ /* upper */
+ pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
+
+ if (size == 3) {
+ pic16_emitpcode(POC_MOVLW, pcop0);
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
+ pic16_emitpcode(POC_MOVLW, pcop1);
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
+ pic16_emitpcode(POC_MOVLW, pcop2);
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
+ } else
+ if (size == 2) {
+ pic16_emitpcode(POC_MOVLW, pcop0);
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_MOVLW, pcop1);
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
+ } else {
+ pic16_emitpcode(POC_MOVLW, pcop0);
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
+ }
+ } else
#endif
- if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
- pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
+ if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
+ pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
- if(AOP_SIZE(result) < 2) {
- fprintf(stderr,"%d -- casting a ptr to a char\n",__LINE__);
+ if(AOP_SIZE(result) < 2) {
+ fprintf(stderr,"%d -- casting a ptr to a char\n",__LINE__);
} else {
pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
}
- } else {
- /* if they in different places then copy */
- size = AOP_SIZE(result);
- offset = 0 ;
- while (size--) {
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
- offset++;
- }
- }
- goto release;
- }
-
- /* if the result is of type pointer */
- if (IS_PTR(ctype)) {
- int p_type;
- sym_link *type = operandType(right);
- sym_link *etype = getSpec(type);
-
- DEBUGpic16_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
-
- /* pointer to generic pointer */
- if (IS_GENPTR(ctype)) {
- char *l = zero;
-
- if (IS_PTR(type))
- p_type = DCL_TYPE(type);
- else {
- /* we have to go by the storage class */
- p_type = PTR_TYPE(SPEC_OCLS(etype));
-
-/* if (SPEC_OCLS(etype)->codesp ) */
-/* p_type = CPOINTER ; */
-/* else */
-/* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
-/* p_type = FPOINTER ; */
-/* else */
-/* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
-/* p_type = PPOINTER; */
-/* else */
-/* if (SPEC_OCLS(etype) == idata ) */
-/* p_type = IPOINTER ; */
-/* else */
-/* p_type = POINTER ; */
- }
-
- /* the first two bytes are known */
+ } else {
+ /* if they in different places then copy */
+ size = AOP_SIZE(result);
+ offset = 0 ;
+ while (size--) {
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
+ offset++;
+ }
+ }
+ goto release;
+ }
+
+ /* if the result is of type pointer */
+ if (IS_PTR(ctype)) {
+ int p_type;
+ sym_link *type = operandType(right);
+ sym_link *etype = getSpec(type);
+
+ DEBUGpic16_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
+
+ /* pointer to generic pointer */
+ if (IS_GENPTR(ctype)) {
+ char *l = zero;
+
+ if (IS_PTR(type))
+ p_type = DCL_TYPE(type);
+ else {
+ /* we have to go by the storage class */
+ p_type = PTR_TYPE(SPEC_OCLS(etype));
+
+/* if (SPEC_OCLS(etype)->codesp ) */
+/* p_type = CPOINTER ; */
+/* else */
+/* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
+/* p_type = FPOINTER ; */
+/* else */
+/* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
+/* p_type = PPOINTER; */
+/* else */
+/* if (SPEC_OCLS(etype) == idata ) */
+/* p_type = IPOINTER ; */
+/* else */
+/* p_type = POINTER ; */
+ }
+
+ /* the first two bytes are known */
DEBUGpic16_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
- size = GPTRSIZE - 1;
- offset = 0 ;
- while (size--) {
- if(offset < AOP_SIZE(right)) {
+ size = GPTRSIZE - 1;
+ offset = 0 ;
+ while (size--) {
+ if(offset < AOP_SIZE(right)) {
DEBUGpic16_emitcode("; ***","%s %d - pointer cast3 ptype = 0x%x",__FUNCTION__,__LINE__, p_type);
pic16_mov2f(AOP(result), AOP(right), offset);
/*
- if ((AOP_TYPE(right) == AOP_PCODE) &&
- AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
- pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
- } else {
-
- pic16_aopPut(AOP(result),
- pic16_aopGet(AOP(right),offset,FALSE,FALSE),
- offset);
- }
+ if ((AOP_TYPE(right) == AOP_PCODE) &&
+ AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
+ pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
+ } else {
+
+ pic16_aopPut(AOP(result),
+ pic16_aopGet(AOP(right),offset,FALSE,FALSE),
+ offset);
+ }
*/
- } else
- pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
- offset++;
- }
- /* the last byte depending on type */
- switch (p_type) {
- case IPOINTER:
- case POINTER:
- case FPOINTER:
- pic16_movLit2f(pic16_popGet(AOP(result), GPTRSIZE-1), GPTR_TAG_DATA);
- break;
-
- case CPOINTER:
- pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), GPTRSIZE-1));
- break;
-
- case PPOINTER:
- pic16_emitcode(";BUG!? ","%d",__LINE__);
- l = "#0x03";
- break;
+ } else
+ pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
+ offset++;
+ }
+ /* the last byte depending on type */
+ switch (p_type) {
+ case IPOINTER:
+ case POINTER:
+ case FPOINTER:
+ pic16_movLit2f(pic16_popGet(AOP(result), GPTRSIZE-1), GPTR_TAG_DATA);
+ break;
+
+ case CPOINTER:
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), GPTRSIZE-1));
+ break;
+
+ case PPOINTER:
+ pic16_emitcode(";BUG!? ","%d",__LINE__);
+ l = "#0x03";
+ break;
case GPOINTER:
- if (GPTRSIZE > AOP_SIZE(right)) {
- // assume __data pointer... THIS MIGHT BE WRONG!
- pic16_movLit2f(pic16_popGet(AOP(result), GPTRSIZE-1), GPTR_TAG_DATA);
- } else {
- pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), GPTRSIZE-1));
- }
+ if (GPTRSIZE > AOP_SIZE(right)) {
+ // assume __data pointer... THIS MIGHT BE WRONG!
+ pic16_movLit2f(pic16_popGet(AOP(result), GPTRSIZE-1), GPTR_TAG_DATA);
+ } else {
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), GPTRSIZE-1));
+ }
break;
-
- default:
- /* this should never happen */
- werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
- "got unknown pointer type");
- exit(1);
- }
- //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);
- goto release ;
- }
-
-
- assert( 0 );
- /* just copy the pointers */
- size = AOP_SIZE(result);
- offset = 0 ;
- while (size--) {
- pic16_aopPut(AOP(result),
- pic16_aopGet(AOP(right),offset,FALSE,FALSE),
- offset);
- offset++;
- }
- goto release ;
- }
-
+
+ default:
+ /* this should never happen */
+ werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
+ "got unknown pointer type");
+ exit(1);
+ }
+ //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);
+ goto release ;
+ }
+
+
+ assert( 0 );
+ /* just copy the pointers */
+ size = AOP_SIZE(result);
+ offset = 0 ;
+ while (size--) {
+ pic16_aopPut(AOP(result),
+ pic16_aopGet(AOP(right),offset,FALSE,FALSE),
+ offset);
+ offset++;
+ }
+ goto release ;
+ }
+
/* so we now know that the size of destination is greater
goto release;
DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
-
+
/* we move to result for the size of source */
size = AOP_SIZE(right);
offset = 0 ;
/* if unsigned or not an integral type */
if (SPEC_USIGN( getSpec(rtype) ) || !IS_SPEC(rtype)) {
while (size--)
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
} else {
/* we need to extend the sign :( */
if(size == 1) {
- /* Save one instruction of casting char to int */
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),offset));
+ /* Save one instruction of casting char to int */
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+ pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),offset));
} else {
pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
- if(offset)
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- else
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0, PO_GPR_REGISTER));
-
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
+ if(offset)
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+ else
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
while (size--)
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset++));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset++));
}
}
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if (!ifx)
- return 0;
-
+ return 0;
+
/* if the if condition has a false label
then we cannot save */
if (IC_FALSE(ifx))
- return 0;
+ return 0;
- /* if the minus is not of the form
+ /* if the minus is not of the form
a = a - 1 */
if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
- !IS_OP_LITERAL(IC_RIGHT(ic)))
- return 0;
+ !IS_OP_LITERAL(IC_RIGHT(ic)))
+ return 0;
if (operandLitValue(IC_RIGHT(ic)) != 1)
- return 0;
+ return 0;
/* if the size of this greater than one then no
saving */
if (getSize(operandType(IC_RESULT(ic))) > 1)
- return 0;
+ return 0;
/* otherwise we can save BIG */
lbl = newiTempLabel(NULL);
lbl1= newiTempLabel(NULL);
pic16_aopOp(IC_RESULT(ic),ic,FALSE);
-
+
if (IS_AOP_PREG(IC_RESULT(ic))) {
- pic16_emitcode("dec","%s",
- pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
- pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
- pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
- } else {
+ pic16_emitcode("dec","%s",
+ pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
+ pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
+ pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
+ } else {
pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + pic16_labelOffset);
}
-
+
pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
ifx->generated = 1;
return 1;
/* genReceive - generate code for a receive iCode */
/*-----------------------------------------------------------------*/
static void genReceive (iCode *ic)
-{
+{
FENTRY;
DEBUGpic16_emitcode ("; ***","1 %s %d",__FUNCTION__,__LINE__);
- pic16_aopOp(IC_RESULT(ic),ic,FALSE);
+ pic16_aopOp(IC_RESULT(ic),ic,FALSE);
size = AOP_SIZE(IC_RESULT(ic));
offset = 0;
while (size--) {
} else {
DEBUGpic16_emitcode ("; ***","2 %s %d argreg = %d",__FUNCTION__,__LINE__, SPEC_ARGREG(OP_SYM_ETYPE(IC_RESULT(ic)) ));
_G.accInUse++;
- pic16_aopOp(IC_RESULT(ic),ic,FALSE);
+ pic16_aopOp(IC_RESULT(ic),ic,FALSE);
_G.accInUse--;
/* set pseudo stack pointer to where it should be - dw*/
if ( options.debug ) {
debugFile->writeCLine (ic);
}
-
+
if(!options.noCcodeInAsm) {
- pic16_addpCode2pBlock(pb, pic16_newpCodeCSource(ic->lineno, ic->filename,
+ pic16_addpCode2pBlock(pb, pic16_newpCodeCSource(ic->lineno, ic->filename,
printCLine(ic->filename, ic->lineno)));
}
cln = ic->lineno ;
}
-
+
if(options.iCodeInAsm) {
char *iLine;
* spilt and rematerializable or code for
* this has already been generated then
* do nothing */
- if (resultRemat(ic) || ic->generated )
+ if (resultRemat(ic) || ic->generated )
continue ;
-
+
/* depending on the operation */
switch (ic->op) {
case '!' :
pic16_genNot(ic);
break;
-
+
case '~' :
pic16_genCpl(ic);
break;
-
+
case UNARYMINUS:
genUminus (ic);
break;
-
+
case IPUSH:
genIpush (ic);
break;
-
+
case IPOP:
- /* IPOP happens only when trying to restore a
- * spilt live range, if there is an ifx statement
- * following this pop then the if statement might
- * be using some of the registers being popped which
- * would destroy the contents of the register so
- * we need to check for this condition and handle it */
- if (ic->next
- && ic->next->op == IFX
- && regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
- genIfx (ic->next,ic);
+ /* IPOP happens only when trying to restore a
+ * spilt live range, if there is an ifx statement
+ * following this pop then the if statement might
+ * be using some of the registers being popped which
+ * would destroy the contents of the register so
+ * we need to check for this condition and handle it */
+ if (ic->next
+ && ic->next->op == IFX
+ && regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
+ genIfx (ic->next,ic);
else
genIpop (ic);
- break;
-
+ break;
+
case CALL:
genCall (ic);
break;
-
+
case PCALL:
genPcall (ic);
break;
-
+
case FUNCTION:
genFunction (ic);
break;
-
+
case ENDFUNCTION:
genEndFunction (ic);
break;
-
+
case RETURN:
genRet (ic);
break;
-
+
case LABEL:
genLabel (ic);
break;
-
+
case GOTO:
genGoto (ic);
break;
-
+
case '+' :
pic16_genPlus (ic) ;
break;
-
+
case '-' :
if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
pic16_genMinus (ic);
case '*' :
genMult (ic);
break;
-
+
case '/' :
genDiv (ic) ;
break;
-
+
case '%' :
genMod (ic);
break;
-
+
case '>' :
- genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
+ genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
break;
-
+
case '<' :
genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
break;
-
+
case LE_OP:
case GE_OP:
case NE_OP:
case EQ_OP:
genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
- break;
-
+ break;
+
case AND_OP:
genAndOp (ic);
break;
-
+
case OR_OP:
genOrOp (ic);
break;
-
+
case '^' :
genXor (ic,ifxForOp(IC_RESULT(ic),ic));
break;
-
+
case '|' :
genOr (ic,ifxForOp(IC_RESULT(ic),ic));
break;
-
+
case BITWISEAND:
genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
break;
-
+
case INLINEASM:
genInline (ic);
break;
-
+
case RRC:
genRRC (ic);
break;
-
+
case RLC:
genRLC (ic);
break;
-
+
case GETHBIT:
genGetHbit (ic);
break;
-
+
case LEFT_OP:
genLeftShift (ic);
break;
-
+
case RIGHT_OP:
genRightShift (ic);
break;
-
+
case GET_VALUE_AT_ADDRESS:
genPointerGet(ic);
break;
-
+
case '=' :
if (POINTER_SET(ic))
genPointerSet(ic);
else
genAssign(ic);
break;
-
+
case IFX:
genIfx (ic,NULL);
break;
-
+
case ADDRESS_OF:
genAddrOf (ic);
break;
-
+
case JUMPTABLE:
genJumpTab (ic);
break;
-
+
case CAST:
genCast (ic);
break;
-
+
case RECEIVE:
genReceive(ic);
break;
-
+
case SEND:
addSet(&_G.sendSet,ic);
break;
/*-------------------------------------------------------------------------
- genarith.c - source file for code generation - arithmetic
-
+ genarith.c - source file for code generation - arithmetic
+
Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
and - Jean-Louis VERN.jlvern@writeme.com (1999)
Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a)
PIC port - Scott Dattalo scott@dattalo.com (2000)
PIC16 port - Martin Dubuc m.dubuc@rogers.com (2002)
-
+
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+
In other words, you are welcome to use, share and improve this program.
You are forbidden to forbid anyone else to use, share and improve
what you give them. Help stamp out software-hoarding!
-
+
Notes:
- 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
- Made everything static
+ 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
+ Made everything static
-------------------------------------------------------------------------*/
#include <stdio.h>
#include "newalloc.h"
#if defined(_MSC_VER) && (_MSC_VER < 1300)
-#define __FUNCTION__ __FILE__
+#define __FUNCTION__ __FILE__
#endif
#include "common.h"
#include "gen.h"
#if 1
-#define pic16_emitcode DEBUGpic16_emitcode
+#define pic16_emitcode DEBUGpic16_emitcode
#endif
#define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
const char *pic16_AopType(short type)
{
switch(type) {
- case AOP_LIT: return "AOP_LIT";
- case AOP_REG: return "AOP_REG";
- case AOP_DIR: return "AOP_DIR";
- case AOP_DPTR: return "AOP_DPTR";
- case AOP_DPTR2: return "AOP_DPTR2";
- case AOP_FSR0: return "AOP_FSR0";
- case AOP_FSR2: return "AOP_FSR2";
- case AOP_R0: return "AOP_R0";
- case AOP_R1: return "AOP_R1";
- case AOP_STK: return "AOP_STK";
- case AOP_IMMD: return "AOP_IMMD";
- case AOP_STR: return "AOP_STR";
- case AOP_CRY: return "AOP_CRY";
- case AOP_ACC: return "AOP_ACC";
- case AOP_PCODE: return "AOP_PCODE";
- case AOP_STA: return "AOP_STA";
+ case AOP_LIT: return "AOP_LIT";
+ case AOP_REG: return "AOP_REG";
+ case AOP_DIR: return "AOP_DIR";
+ case AOP_DPTR: return "AOP_DPTR";
+ case AOP_DPTR2: return "AOP_DPTR2";
+ case AOP_FSR0: return "AOP_FSR0";
+ case AOP_FSR2: return "AOP_FSR2";
+ case AOP_R0: return "AOP_R0";
+ case AOP_R1: return "AOP_R1";
+ case AOP_STK: return "AOP_STK";
+ case AOP_IMMD: return "AOP_IMMD";
+ case AOP_STR: return "AOP_STR";
+ case AOP_CRY: return "AOP_CRY";
+ case AOP_ACC: return "AOP_ACC";
+ case AOP_PCODE: return "AOP_PCODE";
+ case AOP_STA: return "AOP_STA";
}
return "BAD TYPE";
switch(pcop->type) {
- case PO_NONE: return "PO_NONE";
- case PO_W: return "PO_W";
- case PO_WREG: return "PO_WREG";
- case PO_STATUS: return "PO_STATUS";
- case PO_BSR: return "PO_BSR";
- case PO_FSR0: return "PO_FSR0";
- case PO_INDF0: return "PO_INDF0";
- case PO_INTCON: return "PO_INTCON";
- case PO_GPR_REGISTER: return "PO_GPR_REGISTER";
- case PO_GPR_BIT: return "PO_GPR_BIT";
- case PO_GPR_TEMP: return "PO_GPR_TEMP";
- case PO_SFR_REGISTER: return "PO_SFR_REGISTER";
- case PO_PCL: return "PO_PCL";
- case PO_PCLATH: return "PO_PCLATH";
- case PO_PCLATU: return "PO_PCLATU";
- case PO_PRODL: return "PO_PRODL";
- case PO_PRODH: return "PO_PRODH";
- case PO_LITERAL: return "PO_LITERAL";
- case PO_REL_ADDR: return "PO_REL_ADDR";
- case PO_IMMEDIATE: return "PO_IMMEDIATE";
- case PO_DIR: return "PO_DIR";
- case PO_CRY: return "PO_CRY";
- case PO_BIT: return "PO_BIT";
- case PO_STR: return "PO_STR";
- case PO_LABEL: return "PO_LABEL";
- case PO_WILD: return "PO_WILD";
- case PO_TWO_OPS: return "PO_TWO_OPS";
+ case PO_NONE: return "PO_NONE";
+ case PO_W: return "PO_W";
+ case PO_WREG: return "PO_WREG";
+ case PO_STATUS: return "PO_STATUS";
+ case PO_BSR: return "PO_BSR";
+ case PO_FSR0: return "PO_FSR0";
+ case PO_INDF0: return "PO_INDF0";
+ case PO_INTCON: return "PO_INTCON";
+ case PO_GPR_REGISTER: return "PO_GPR_REGISTER";
+ case PO_GPR_BIT: return "PO_GPR_BIT";
+ case PO_GPR_TEMP: return "PO_GPR_TEMP";
+ case PO_SFR_REGISTER: return "PO_SFR_REGISTER";
+ case PO_PCL: return "PO_PCL";
+ case PO_PCLATH: return "PO_PCLATH";
+ case PO_PCLATU: return "PO_PCLATU";
+ case PO_PRODL: return "PO_PRODL";
+ case PO_PRODH: return "PO_PRODH";
+ case PO_LITERAL: return "PO_LITERAL";
+ case PO_REL_ADDR: return "PO_REL_ADDR";
+ case PO_IMMEDIATE: return "PO_IMMEDIATE";
+ case PO_DIR: return "PO_DIR";
+ case PO_CRY: return "PO_CRY";
+ case PO_BIT: return "PO_BIT";
+ case PO_STR: return "PO_STR";
+ case PO_LABEL: return "PO_LABEL";
+ case PO_WILD: return "PO_WILD";
+ case PO_TWO_OPS: return "PO_TWO_OPS";
}
}
switch(PCORB(pcop)->subtype) {
- case PO_NONE: return "PO_NONE";
- case PO_W: return "PO_W";
- case PO_WREG: return "PO_WREG";
- case PO_STATUS: return "PO_STATUS";
- case PO_BSR: return "PO_BSR";
- case PO_FSR0: return "PO_FSR0";
- case PO_INDF0: return "PO_INDF0";
- case PO_INTCON: return "PO_INTCON";
- case PO_GPR_REGISTER: return "PO_GPR_REGISTER";
- case PO_GPR_BIT: return "PO_GPR_BIT";
- case PO_GPR_TEMP: return "PO_GPR_TEMP";
- case PO_SFR_REGISTER: return "PO_SFR_REGISTER";
- case PO_PCL: return "PO_PCL";
- case PO_PCLATH: return "PO_PCLATH";
- case PO_PCLATU: return "PO_PCLATU";
- case PO_PRODL: return "PO_PRODL";
- case PO_PRODH: return "PO_PRODH";
- case PO_LITERAL: return "PO_LITERAL";
- case PO_REL_ADDR: return "PO_REL_ADDR";
- case PO_IMMEDIATE: return "PO_IMMEDIATE";
- case PO_DIR: return "PO_DIR";
- case PO_CRY: return "PO_CRY";
- case PO_BIT: return "PO_BIT";
- case PO_STR: return "PO_STR";
- case PO_LABEL: return "PO_LABEL";
- case PO_WILD: return "PO_WILD";
- case PO_TWO_OPS: return "PO_TWO_OPS";
+ case PO_NONE: return "PO_NONE";
+ case PO_W: return "PO_W";
+ case PO_WREG: return "PO_WREG";
+ case PO_STATUS: return "PO_STATUS";
+ case PO_BSR: return "PO_BSR";
+ case PO_FSR0: return "PO_FSR0";
+ case PO_INDF0: return "PO_INDF0";
+ case PO_INTCON: return "PO_INTCON";
+ case PO_GPR_REGISTER: return "PO_GPR_REGISTER";
+ case PO_GPR_BIT: return "PO_GPR_BIT";
+ case PO_GPR_TEMP: return "PO_GPR_TEMP";
+ case PO_SFR_REGISTER: return "PO_SFR_REGISTER";
+ case PO_PCL: return "PO_PCL";
+ case PO_PCLATH: return "PO_PCLATH";
+ case PO_PCLATU: return "PO_PCLATU";
+ case PO_PRODL: return "PO_PRODL";
+ case PO_PRODH: return "PO_PRODH";
+ case PO_LITERAL: return "PO_LITERAL";
+ case PO_REL_ADDR: return "PO_REL_ADDR";
+ case PO_IMMEDIATE: return "PO_IMMEDIATE";
+ case PO_DIR: return "PO_DIR";
+ case PO_CRY: return "PO_CRY";
+ case PO_BIT: return "PO_BIT";
+ case PO_STR: return "PO_STR";
+ case PO_LABEL: return "PO_LABEL";
+ case PO_WILD: return "PO_WILD";
+ case PO_TWO_OPS: return "PO_TWO_OPS";
}
}
FENTRY;
DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
- pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
- pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
- pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
+ pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
+ pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
+ pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
/* will try to generate an increment */
- /* if the right side is not a literal
+ /* if the right side is not a literal
we cannot */
if (AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT)
return FALSE ;
-
+
DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
/* if the literal value of the right hand side
is greater than 2 then it is faster to add */
- if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
+ if ((icount = (unsigned int) ulFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
return FALSE ;
-
+
/* if increment 16 bits in register */
if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
(icount == 1)) {
//pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
while(--size) {
- emitSKPNC;
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++));
- //pic16_emitcode(" incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
+ emitSKPNC;
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),offset++));
+ //pic16_emitcode(" incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),offset++,FALSE,FALSE));
}
return TRUE;
}
-
+
// DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__);
- /* if left is in accumulator - probably a bit operation*/ // VR - why this is a bit operation?!
+ /* if left is in accumulator - probably a bit operation*/ // VR - why this is a bit operation?!
if( (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) &&
- (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
-
+ (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) {
+
pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
- AOP(IC_RESULT(ic))->aopu.aop_dir,
- AOP(IC_RESULT(ic))->aopu.aop_dir);
+ AOP(IC_RESULT(ic))->aopu.aop_dir,
+ AOP(IC_RESULT(ic))->aopu.aop_dir);
if(icount)
- pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
+ pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
//pic16_emitcode("xorlw","1");
else
- pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
+ pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
//pic16_emitcode("andlw","1");
emitSKPZ;
pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
- AOP(IC_RESULT(ic))->aopu.aop_dir,
- AOP(IC_RESULT(ic))->aopu.aop_dir);
+ AOP(IC_RESULT(ic))->aopu.aop_dir,
+ AOP(IC_RESULT(ic))->aopu.aop_dir);
return TRUE;
}
if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
AOP_SIZE(IC_LEFT(ic)) > 1 )
return FALSE ;
-
+
/* If we are incrementing the same register by two: */
if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
-
- while (icount--)
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
+
+ while (icount--)
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
//pic16_emitcode("incf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
-
+
return TRUE ;
}
-
+
DEBUGpic16_emitcode ("; ","couldn't increment ");
return FALSE ;
FENTRY;
DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
- pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
- pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
- pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
+ pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
+ pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
+ pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
/*
- The following block of code will add two bits.
+ The following block of code will add two bits.
Note that it'll even work if the destination is
the carry (C in the status register).
It won't work if the 'Z' bit is a source or destination.
pic16_emitcode("clrw","");
pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
- AOP(IC_RIGHT(ic))->aopu.aop_dir,
- AOP(IC_RIGHT(ic))->aopu.aop_dir);
+ AOP(IC_RIGHT(ic))->aopu.aop_dir,
+ AOP(IC_RIGHT(ic))->aopu.aop_dir);
pic16_emitcode("xorlw","1");
pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
- AOP(IC_LEFT(ic))->aopu.aop_dir,
- AOP(IC_LEFT(ic))->aopu.aop_dir);
+ AOP(IC_LEFT(ic))->aopu.aop_dir,
+ AOP(IC_LEFT(ic))->aopu.aop_dir);
pic16_emitcode("xorlw","1");
break;
case AOP_REG:
pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
pic16_emitcode("movlw","(1 << (%s & 7))",
- AOP(IC_RESULT(ic))->aopu.aop_dir,
- AOP(IC_RESULT(ic))->aopu.aop_dir);
+ AOP(IC_RESULT(ic))->aopu.aop_dir,
+ AOP(IC_RESULT(ic))->aopu.aop_dir);
pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
- AOP(IC_RESULT(ic))->aopu.aop_dir,
- AOP(IC_RESULT(ic))->aopu.aop_dir);
+ AOP(IC_RESULT(ic))->aopu.aop_dir,
+ AOP(IC_RESULT(ic))->aopu.aop_dir);
pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
- AOP(IC_RIGHT(ic))->aopu.aop_dir,
- AOP(IC_RIGHT(ic))->aopu.aop_dir);
+ AOP(IC_RIGHT(ic))->aopu.aop_dir,
+ AOP(IC_RIGHT(ic))->aopu.aop_dir);
pic16_emitcode("xorwf","(%s >>3),f",
- AOP(IC_RESULT(ic))->aopu.aop_dir);
+ AOP(IC_RESULT(ic))->aopu.aop_dir);
pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
- AOP(IC_LEFT(ic))->aopu.aop_dir,
- AOP(IC_LEFT(ic))->aopu.aop_dir);
+ AOP(IC_LEFT(ic))->aopu.aop_dir,
+ AOP(IC_LEFT(ic))->aopu.aop_dir);
pic16_emitcode("xorwf","(%s>>3),f",
- AOP(IC_RESULT(ic))->aopu.aop_dir);
+ AOP(IC_RESULT(ic))->aopu.aop_dir);
break;
}
#if 0
/* This is the original version of this code.
*
- * This is being kept around for reference,
+ * 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 &&
- !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
- pic16_aopPut(AOP(IC_RESULT(ic)),
- pic16_aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
- 2);
-
- if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
- AOP_SIZE(IC_RIGHT(ic)) == 3 &&
- !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
- pic16_aopPut(AOP(IC_RESULT(ic)),
- pic16_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 &&
- !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
- !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
- char buffer[5];
- sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
- pic16_aopPut(AOP(IC_RESULT(ic)),buffer,2);
+ AOP_SIZE(IC_LEFT(ic)) == 3 &&
+ !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
+ pic16_aopPut(AOP(IC_RESULT(ic)),
+ pic16_aopGet(AOP(IC_LEFT(ic)),2,FALSE,FALSE),
+ 2);
+
+ if (AOP_SIZE(IC_RESULT(ic)) == 3 &&
+ AOP_SIZE(IC_RIGHT(ic)) == 3 &&
+ !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
+ pic16_aopPut(AOP(IC_RESULT(ic)),
+ pic16_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 &&
+ !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
+ !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
+ char buffer[5];
+ sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
+ pic16_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
+ * 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)) &&
- !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
+ opIsGptr(IC_LEFT(ic)) &&
+ !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))))
{
- pic16_aopPut(AOP(IC_RESULT(ic)),
- pic16_aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
- GPTRSIZE - 1);
+ pic16_aopPut(AOP(IC_RESULT(ic)),
+ pic16_aopGet(AOP(IC_LEFT(ic)), GPTRSIZE - 1,FALSE,FALSE),
+ GPTRSIZE - 1);
}
if (opIsGptr(IC_RESULT(ic)) &&
opIsGptr(IC_RIGHT(ic)) &&
- !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
+ !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic))))
{
- pic16_aopPut(AOP(IC_RESULT(ic)),
- pic16_aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
- GPTRSIZE - 1);
+ pic16_aopPut(AOP(IC_RESULT(ic)),
+ pic16_aopGet(AOP(IC_RIGHT(ic)),GPTRSIZE - 1,FALSE,FALSE),
+ GPTRSIZE - 1);
}
- if (opIsGptr(IC_RESULT(ic)) &&
+ if (opIsGptr(IC_RESULT(ic)) &&
AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE &&
AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE &&
- !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
- !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
- char buffer[5];
- sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
- pic16_aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
+ !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) &&
+ !pic16_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_RIGHT(ic)))) {
+ char buffer[5];
+ sprintf(buffer,"#%d",pointerCode(getSpec(operandType(IC_LEFT(ic)))));
+ pic16_aopPut(AOP(IC_RESULT(ic)),buffer,GPTRSIZE - 1);
}
}
#endif
static void genAddLit2byte (operand *result, int offr, int lit)
{
FENTRY;
-
+
switch(lit & 0xff) {
case 0:
break;
if(same) {
/* Handle special cases first */
- if(size == 1)
+ if(size == 1)
genAddLit2byte (result, 0, lit);
-
+
else if(size == 2) {
int hi = 0xff & (lit >> 8);
lo = lit & 0xff;
switch(hi) {
- case 0:
-
- /* lit = 0x00LL */
- DEBUGpic16_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
- switch(lo) {
- case 0:
- break;
- case 1:
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
- emitSKPNZ;
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
- break;
- case 0xff:
- pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
-
- break;
- default:
- pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
- pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
- emitSKPNC;
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
-
-
- }
- break;
+ case 0:
+
+ /* lit = 0x00LL */
+ DEBUGpic16_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
+ switch(lo) {
+ case 0:
+ break;
+ case 1:
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
+ emitSKPNZ;
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
+ break;
+ case 0xff:
+ pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
+
+ break;
+ default:
+ pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
+ pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
+ emitSKPNC;
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
+
+
+ }
+ break;
case 1:
- /* lit = 0x01LL */
- DEBUGpic16_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
- switch(lo) {
- case 0: /* 0x0100 */
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
- break;
- case 1: /* 0x0101 */
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
- emitSKPNZ;
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
- break;
- case 0xff: /* 0x01ff */
- pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
- break;
- default: /* 0x01LL */
- pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
- pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
- emitSKPNC;
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
- }
- break;
+ /* lit = 0x01LL */
+ DEBUGpic16_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
+ switch(lo) {
+ case 0: /* 0x0100 */
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
+ break;
+ case 1: /* 0x0101 */
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
+ emitSKPNZ;
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
+ break;
+ case 0xff: /* 0x01ff */
+ pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
+ break;
+ default: /* 0x01LL */
+ pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
+ pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
+ emitSKPNC;
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
+ }
+ break;
case 0xff:
- DEBUGpic16_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
- /* lit = 0xffLL */
- switch(lo) {
- case 0: /* 0xff00 */
- pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
- break;
- case 1: /*0xff01 */
- pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
- break;
-/* case 0xff: * 0xffff *
- pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0,FALSE,FALSE));
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
- pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0,FALSE,FALSE));
- break;
+ DEBUGpic16_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
+ /* lit = 0xffLL */
+ switch(lo) {
+ case 0: /* 0xff00 */
+ pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
+ break;
+ case 1: /*0xff01 */
+ pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
+ break;
+/* case 0xff: * 0xffff *
+ pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0,FALSE,FALSE));
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
+ pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0,FALSE,FALSE));
+ break;
*/
- default:
- pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
- pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
- emitSKPC;
- pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
-
- }
-
- break;
-
+ default:
+ pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
+ pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
+ emitSKPC;
+ pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
+
+ }
+
+ break;
+
default:
- DEBUGpic16_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
-
- /* lit = 0xHHLL */
- switch(lo) {
- case 0: /* 0xHH00 */
- genAddLit2byte (result, MSB16, hi);
- break;
- case 1: /* 0xHH01 */
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
- pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
- break;
-/* case 0xff: * 0xHHff *
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE));
- pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
- pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
- pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
- break;
-*/ default: /* 0xHHLL */
- pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
- pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
- break;
- }
+ DEBUGpic16_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
+
+ /* lit = 0xHHLL */
+ switch(lo) {
+ case 0: /* 0xHH00 */
+ genAddLit2byte (result, MSB16, hi);
+ break;
+ case 1: /* 0xHH01 */
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
+ pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
+ break;
+/* case 0xff: * 0xHHff *
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE));
+ pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
+ pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
+ pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
+ break;
+*/ default: /* 0xHHLL */
+ pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
+ pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
+ pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
+ break;
+ }
}
} else {
DEBUGpic16_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
while(size--) {
- lo = BYTEofLONG(lit,0);
-
- if(carry_info) {
- pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
- pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
- }else {
- /* no carry info from previous step */
- /* this means this is the first time to add */
- switch(lo) {
- case 0:
- break;
- case 1:
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
- carry_info=1;
- break;
- default:
- pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
- if(lit <0x100)
- carry_info = 3; /* Were adding only one byte and propogating the carry */
- else
- carry_info = 2;
- break;
- }
- }
- offset++;
- lit >>= 8;
+ lo = BYTEofLONG(lit,0);
+
+ if(carry_info) {
+ pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
+ pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
+ }else {
+ /* no carry info from previous step */
+ /* this means this is the first time to add */
+ switch(lo) {
+ case 0:
+ break;
+ case 1:
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
+ carry_info=1;
+ break;
+ default:
+ pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
+ pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
+ if(lit <0x100)
+ carry_info = 3; /* Were adding only one byte and propogating the carry */
+ else
+ carry_info = 2;
+ break;
+ }
+ }
+ offset++;
+ lit >>= 8;
}
-
+
/*
lo = BYTEofLONG(lit,0);
if(lit < 0x100) {
- if(lo) {
- if(lo == 1) {
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0,FALSE,FALSE));
- emitSKPNZ;
- } else {
- pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
- emitSKPNC;
- }
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),1,FALSE,FALSE));
- emitSKPNZ;
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),2,FALSE,FALSE));
- emitSKPNZ;
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),3,FALSE,FALSE));
-
- }
- }
+ if(lo) {
+ if(lo == 1) {
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0,FALSE,FALSE));
+ emitSKPNZ;
+ } else {
+ pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
+ pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
+ emitSKPNC;
+ }
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),1,FALSE,FALSE));
+ emitSKPNZ;
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),2,FALSE,FALSE));
+ emitSKPNZ;
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),3,FALSE,FALSE));
+
+ }
+ }
*/
}
if(size == 1) {
if(AOP_TYPE(left) == AOP_ACC) {
- /* left addend is already in accumulator */
- switch(lit & 0xff) {
- case 0:
- //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
- emitMOVWF(result,0);
- break;
- default:
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
- //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
- emitMOVWF(result,0);
- }
+ /* left addend is already in accumulator */
+ switch(lit & 0xff) {
+ case 0:
+ //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
+ emitMOVWF(result,0);
+ break;
+ default:
+ pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
+ //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
+ emitMOVWF(result,0);
+ }
} else {
- /* left addend is in a register */
- switch(lit & 0xff) {
- case 0:
- pic16_mov2w(AOP(left),0);
- emitMOVWF(result, 0);
- break;
- case 1:
- pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
- //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
- emitMOVWF(result,0);
- break;
- case 0xff:
- pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
- //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
- emitMOVWF(result,0);
- break;
- default:
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
- pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
- //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
- emitMOVWF(result,0);
- }
+ /* left addend is in a register */
+ switch(lit & 0xff) {
+ case 0:
+ pic16_mov2w(AOP(left),0);
+ emitMOVWF(result, 0);
+ break;
+ case 1:
+ pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
+ //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
+ emitMOVWF(result,0);
+ break;
+ case 0xff:
+ pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
+ //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
+ emitMOVWF(result,0);
+ break;
+ default:
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
+ pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
+ //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
+ emitMOVWF(result,0);
+ }
}
} else {
/* left is not the accumulator */
if(lit & 0xff) {
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
- pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
+ pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
} else {
- pic16_mov2w(AOP(left),0);
- /* We don't know the state of the carry bit at this point */
- clear_carry = 1;
+ pic16_mov2w(AOP(left),0);
+ /* We don't know the state of the carry bit at this point */
+ clear_carry = 1;
}
//pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
emitMOVWF(result,0);
while(--size) {
- lit >>= 8;
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
- if (offset < AOP_SIZE(left)) {
- pic16_emitpcode(clear_carry ? POC_ADDFW : POC_ADDFWC, pic16_popGet(AOP(left),offset));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
- } else {
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
- if (!SPEC_USIGN(operandType(IC_LEFT(ic)))) {
- /* sign-extend left (in result) */
+ lit >>= 8;
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
+ if (offset < AOP_SIZE(left)) {
+ pic16_emitpcode(clear_carry ? POC_ADDFW : POC_ADDFWC, pic16_popGet(AOP(left),offset));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
+ } else {
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
+ if (!SPEC_USIGN(operandType(IC_LEFT(ic)))) {
+ /* sign-extend left (in result) */
pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left),AOP_SIZE(left)-1,7));
- pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),offset));
- }
- pic16_emitpcode(clear_carry ? POC_ADDWF : POC_ADDWFC, pic16_popGet(AOP(result),offset));
- }
- clear_carry = 0;
- offset++;
+ pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),offset));
+ }
+ pic16_emitpcode(clear_carry ? POC_ADDWF : POC_ADDWFC, pic16_popGet(AOP(result),offset));
+ }
+ clear_carry = 0;
+ offset++;
}
}
}
#else
/* this fails when result is an SFR because value is written there
* during addition and not at the end */
-
+
static void genAddLit (iCode *ic, int lit)
{
sizeL = pic16_getDataSize(left);
llit = lit;
-#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
/* move left to result -- possibly sign extend */
for (i=0; i < MIN(size, sizeL); i++) {
pic16_mov2f (AOP(result), AOP(left), i);
emitSKPNC;
break;
} // switch
-
+
pic16_emitpcode (POC_INCF, pic16_popGet (AOP(result), size-1));
} else {
/* general case */
pic16_emitpcode (POC_MOVLW, pic16_popGetLit (llit));
llit >>= 8; /* FIXME: arithmetic right shift for signed literals? */
pic16_emitpcode (i == 0 ? POC_ADDWF : POC_ADDWFC,
- pic16_popGet (AOP(result), i));
+ pic16_popGet (AOP(result), i));
}
}
if(same) {
/* Handle special cases first */
- if(size == 1)
+ if(size == 1)
genAddLit2byte (result, 0, lit);
-
+
else if(size == 2) {
int hi = 0xff & (lit >> 8);
lo = lit & 0xff;
switch(hi) {
- case 0:
-
- /* lit = 0x00LL */
- DEBUGpic16_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
- switch(lo) {
- case 0:
- break;
- case 1:
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
- emitSKPNZ;
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
- break;
- case 0xff:
- pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
-
- break;
- default:
- pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
- pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
- emitSKPNC;
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
-
-
- }
- break;
+ case 0:
+
+ /* lit = 0x00LL */
+ DEBUGpic16_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__);
+ switch(lo) {
+ case 0:
+ break;
+ case 1:
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
+ emitSKPNZ;
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
+ break;
+ case 0xff:
+ pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
+
+ break;
+ default:
+ pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
+ pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
+ emitSKPNC;
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
+
+
+ }
+ break;
case 1:
- /* lit = 0x01LL */
- DEBUGpic16_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
- switch(lo) {
- case 0: /* 0x0100 */
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
- break;
- case 1: /* 0x0101 */
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
- emitSKPNZ;
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
- break;
- case 0xff: /* 0x01ff */
- pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
- break;
- default: /* 0x01LL */
- pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
- pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
- emitSKPNC;
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
- }
- break;
+ /* lit = 0x01LL */
+ DEBUGpic16_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__);
+ switch(lo) {
+ case 0: /* 0x0100 */
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
+ break;
+ case 1: /* 0x0101 */
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
+ emitSKPNZ;
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
+ break;
+ case 0xff: /* 0x01ff */
+ pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
+ break;
+ default: /* 0x01LL */
+ pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
+ pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
+ emitSKPNC;
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16));
+ }
+ break;
case 0xff:
- DEBUGpic16_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
- /* lit = 0xffLL */
- switch(lo) {
- case 0: /* 0xff00 */
- pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
- break;
- case 1: /*0xff01 */
- pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
- break;
-/* case 0xff: * 0xffff *
- pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0,FALSE,FALSE));
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
- pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0,FALSE,FALSE));
- break;
+ DEBUGpic16_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__);
+ /* lit = 0xffLL */
+ switch(lo) {
+ case 0: /* 0xff00 */
+ pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
+ break;
+ case 1: /*0xff01 */
+ pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
+ break;
+/* case 0xff: * 0xffff *
+ pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0,FALSE,FALSE));
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
+ pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0,FALSE,FALSE));
+ break;
*/
- default:
- pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
- pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
- emitSKPC;
- pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
-
- }
-
- break;
-
+ default:
+ pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
+ pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0));
+ emitSKPC;
+ pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
+
+ }
+
+ break;
+
default:
- DEBUGpic16_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
-
- /* lit = 0xHHLL */
- switch(lo) {
- case 0: /* 0xHH00 */
- genAddLit2byte (result, MSB16, hi);
- break;
- case 1: /* 0xHH01 */
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
- pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
- break;
-/* case 0xff: * 0xHHff *
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE));
- pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
- pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
- pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
- break;
-*/ default: /* 0xHHLL */
- pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
- pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
- break;
- }
+ DEBUGpic16_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__);
+
+ /* lit = 0xHHLL */
+ switch(lo) {
+ case 0: /* 0xHH00 */
+ genAddLit2byte (result, MSB16, hi);
+ break;
+ case 1: /* 0xHH01 */
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
+ pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
+ break;
+/* case 0xff: * 0xHHff *
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE));
+ pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
+ pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
+ pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16,FALSE,FALSE));
+ break;
+*/ default: /* 0xHHLL */
+ pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
+ pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi));
+ pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16));
+ break;
+ }
}
} else {
DEBUGpic16_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__);
while(size--) {
- lo = BYTEofLONG(lit,0);
-
- if(carry_info) {
- pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
- pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
- }else {
- /* no carry info from previous step */
- /* this means this is the first time to add */
- switch(lo) {
- case 0:
- break;
- case 1:
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
- carry_info=1;
- break;
- default:
- pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
- if(lit <0x100)
- carry_info = 3; /* Were adding only one byte and propogating the carry */
- else
- carry_info = 2;
- break;
- }
- }
- offset++;
- lit >>= 8;
+ lo = BYTEofLONG(lit,0);
+
+ if(carry_info) {
+ pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
+ pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
+ }else {
+ /* no carry info from previous step */
+ /* this means this is the first time to add */
+ switch(lo) {
+ case 0:
+ break;
+ case 1:
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset));
+ carry_info=1;
+ break;
+ default:
+ pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
+ pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset));
+ if(lit <0x100)
+ carry_info = 3; /* Were adding only one byte and propogating the carry */
+ else
+ carry_info = 2;
+ break;
+ }
+ }
+ offset++;
+ lit >>= 8;
}
-
+
/*
lo = BYTEofLONG(lit,0);
if(lit < 0x100) {
- if(lo) {
- if(lo == 1) {
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0,FALSE,FALSE));
- emitSKPNZ;
- } else {
- pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
- emitSKPNC;
- }
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),1,FALSE,FALSE));
- emitSKPNZ;
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),2,FALSE,FALSE));
- emitSKPNZ;
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),3,FALSE,FALSE));
-
- }
- }
+ if(lo) {
+ if(lo == 1) {
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0,FALSE,FALSE));
+ emitSKPNZ;
+ } else {
+ pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo));
+ pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
+ emitSKPNC;
+ }
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),1,FALSE,FALSE));
+ emitSKPNZ;
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),2,FALSE,FALSE));
+ emitSKPNZ;
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),3,FALSE,FALSE));
+
+ }
+ }
*/
}
if(size == 1) {
if(AOP_TYPE(left) == AOP_ACC) {
- /* left addend is already in accumulator */
- switch(lit & 0xff) {
- case 0:
- //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
- emitMOVWF(result,0);
- break;
- default:
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
- //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
- emitMOVWF(result,0);
- }
+ /* left addend is already in accumulator */
+ switch(lit & 0xff) {
+ case 0:
+ //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
+ emitMOVWF(result,0);
+ break;
+ default:
+ pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff));
+ //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
+ emitMOVWF(result,0);
+ }
} else {
- /* left addend is in a register */
- switch(lit & 0xff) {
- case 0:
- pic16_mov2w(AOP(left),0);
- emitMOVWF(result, 0);
- break;
- case 1:
- pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
- //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
- emitMOVWF(result,0);
- break;
- case 0xff:
- pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
- //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
- emitMOVWF(result,0);
- break;
- default:
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
- pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
- //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
- emitMOVWF(result,0);
- }
+ /* left addend is in a register */
+ switch(lit & 0xff) {
+ case 0:
+ pic16_mov2w(AOP(left),0);
+ emitMOVWF(result, 0);
+ break;
+ case 1:
+ pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
+ //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
+ emitMOVWF(result,0);
+ break;
+ case 0xff:
+ pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0));
+ //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
+ emitMOVWF(result,0);
+ break;
+ default:
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
+ pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
+ //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
+ emitMOVWF(result,0);
+ }
}
} else {
/* left is not the accumulator */
if(lit & 0xff) {
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
- pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
+ pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
} else {
- pic16_mov2w(AOP(left),0);
- /* We don't know the state of the carry bit at this point */
- clear_carry = 1;
+ pic16_mov2w(AOP(left),0);
+ /* We don't know the state of the carry bit at this point */
+ clear_carry = 1;
}
//pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE));
emitMOVWF(result,0);
while(--size) {
-
- lit >>= 8;
- if(lit & 0xff) {
- if(clear_carry) {
- /* The ls byte of the lit must've been zero - that
- means we don't have to deal with carry */
-
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
- pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offset));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
-
- clear_carry = 0;
-
- } else {
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
- pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),offset));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
- }
-
- } else {
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
- pic16_mov2w(AOP(left),offset);
- pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
- }
- offset++;
+
+ lit >>= 8;
+ if(lit & 0xff) {
+ if(clear_carry) {
+ /* The ls byte of the lit must've been zero - that
+ means we don't have to deal with carry */
+
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
+ pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offset));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
+
+ clear_carry = 0;
+
+ } else {
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
+ pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),offset));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
+ }
+
+ } else {
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
+ pic16_mov2w(AOP(left),offset);
+ pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset));
+ }
+ offset++;
}
}
}
operand *result, *left, *right;
FENTRY;
-
+
/* special cases :- */
- result = IC_RESULT(ic);
- left = IC_LEFT(ic);
- right = IC_RIGHT(ic);
- pic16_aopOp (left,ic,FALSE);
- pic16_aopOp (right,ic,FALSE);
- pic16_aopOp (result,ic,TRUE);
- DEBUGpic16_pic16_AopType(__LINE__,left, right, result);
- // pic16_DumpOp("(left)",left);
-
- /* if literal, literal on the right or
- if left requires ACC or right is already
- in ACC */
-
- if ( (AOP_TYPE(left) == AOP_LIT) || (pic16_sameRegs(AOP(right), AOP(result))) ) {
- operand *t = right;
- right = IC_RIGHT(ic) = left;
- left = IC_LEFT(ic) = t;
- }
-
- /* if both left & right are in bit space */
- if (AOP_TYPE(left) == AOP_CRY &&
- AOP_TYPE(right) == AOP_CRY) {
- pic16_genPlusBits (ic);
- goto release ;
- }
-
- /* if left in bit space & right literal */
- if (AOP_TYPE(left) == AOP_CRY &&
- AOP_TYPE(right) == AOP_LIT) {
- /* if result in bit space */
- if(AOP_TYPE(result) == AOP_CRY){
- if((unsigned long)floatFromVal(AOP(right)->aopu.aop_lit) != 0L) {
- pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),0));
- if (!pic16_sameRegs(AOP(left), AOP(result)) )
- pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),0));
- }
- } else {
- unsigned long lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
- size = pic16_getDataSize(result);
- while (size--) {
- pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), offset));
- pic16_emitpcode (POC_MOVLW, pic16_popGetLit ((lit >> (8*offset)) & 0xFF));
- pic16_emitpcode (POC_ADDWFC, pic16_popGet(AOP(result), offset++));
- //MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
- //pic16_emitcode("addc","a,#00 ;%d",__LINE__);
- //pic16_aopPut(AOP(result),"a",offset++);
- }
- }
- goto release ;
- } // left == CRY
-
- /* if I can do an increment instead
- of add then GOOD for ME */
- if (pic16_genPlusIncr (ic) == TRUE)
- goto release;
-
- size = pic16_getDataSize(result);
-
- if(AOP(right)->type == AOP_LIT) {
- /* Add a literal to something else */
- //bool know_W=0;
- unsigned lit = (unsigned) floatFromVal(AOP(right)->aopu.aop_lit);
- //unsigned l1=0;
-
- //offset = 0;
- DEBUGpic16_emitcode(";","adding lit to something. size %d",size);
-
- genAddLit (ic, lit);
- goto release;
-
- } else if(AOP_TYPE(right) == AOP_CRY) {
-
- pic16_emitcode(";bitadd","right is bit: %s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
- pic16_emitcode(";bitadd","left is bit: %s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
- pic16_emitcode(";bitadd","result is bit: %s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
-
- /* here we are adding a bit to a char or int */
- if(size == 1) {
- if (pic16_sameRegs(AOP(left), AOP(result)) ) {
-
- pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
- pic16_emitpcode(POC_INCF , pic16_popGet(AOP(result),0));
-
- pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
- AOP(right)->aopu.aop_dir,
- AOP(right)->aopu.aop_dir);
- pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(result),0,FALSE,FALSE));
- } else { // not same
-
- if(AOP_TYPE(left) == AOP_ACC) {
- pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
- pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
-
- pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
- AOP(right)->aopu.aop_dir,
- AOP(right)->aopu.aop_dir);
- pic16_emitcode(" xorlw","1");
- } else {
- pic16_mov2w(AOP(left),0);
- pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
- pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(left),0));
-
- pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
- pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
- AOP(right)->aopu.aop_dir,
- AOP(right)->aopu.aop_dir);
- pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
- }
-
- if(AOP_TYPE(result) != AOP_ACC) {
-
- if(AOP_TYPE(result) == AOP_CRY) {
- pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
- pic16_emitpcode(POC_BCF , pic16_popGet(AOP(result),0));
- emitSKPZ;
- pic16_emitpcode(POC_BSF , pic16_popGet(AOP(result),0));
- } else {
- pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(result),0));
- pic16_emitcode("movwf","%s", pic16_aopGet(AOP(result),0,FALSE,FALSE));
- }
- }
- }
-
- } else {
- int offset = 1;
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if (pic16_sameRegs(AOP(left), AOP(result)) ) {
- emitCLRZ;
- pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
-
- pic16_emitcode("clrz","");
-
- pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
- AOP(right)->aopu.aop_dir,
- AOP(right)->aopu.aop_dir);
- pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(result),0,FALSE,FALSE));
-
- } else {
- emitCLRZ; // needed here as well: INCFW is not always executed, Z is undefined then
- pic16_mov2w(AOP(left),0);
- pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
- pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
- //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right),0,FALSE,FALSE));
- emitMOVWF(right,0);
-
- pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
- pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
- AOP(right)->aopu.aop_dir,
- AOP(right)->aopu.aop_dir);
- pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
- pic16_emitcode("movwf","%s", pic16_aopGet(AOP(result),0,FALSE,FALSE));
-
- }
-
- while(--size){
- emitSKPZ;
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset++));
- //pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(right),offset++,FALSE,FALSE));
- }
-
- }
-
- } else {
- // add bytes
-
- // Note: the following is an example of WISC code, eg.
- // it's supposed to run on a Weird Instruction Set Computer :o)
-
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- if ( AOP_TYPE(left) == AOP_ACC) {
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),0));
- if ( AOP_TYPE(result) != AOP_ACC)
- pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
- goto release; // we're done, since WREG is 1 byte
- }
-
-
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- size = min( AOP_SIZE(result), AOP_SIZE(right) );
- size = min( size, AOP_SIZE(left) );
- offset = 0;
-
- if(pic16_debug_verbose) {
-// fprintf(stderr, "%s:%d result: %d\tleft: %d\tright: %d\n", __FILE__, __LINE__,
-// AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
-// fprintf(stderr, "%s:%d size of operands: %d\n", __FILE__, __LINE__, size);
- }
-
-
-
- if ((AOP_TYPE(left) == AOP_PCODE) && (
- (AOP(left)->aopu.pcop->type == PO_LITERAL) ||
-// (AOP(left)->aopu.pcop->type == PO_DIR) || // patch 9
- (AOP(left)->aopu.pcop->type == PO_IMMEDIATE)))
- {
- // add to literal operand
-
- // add first bytes
- for(i=0; i<size; i++) {
- if (AOP_TYPE(right) == AOP_ACC) {
- pic16_emitpcode(POC_ADDLW, pic16_popGet(AOP(left),i));
- } else {
- pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
- if(i) { // add with carry
- pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(right),i));
- } else { // add without
- pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),i));
- }
- }
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
- }
-
- DEBUGpic16_pic16_AopTypeSign(__LINE__, NULL, right, NULL);
-
- // add leftover bytes
- if (SPEC_USIGN(getSpec(operandType(right)))) {
- // right is unsigned
- for(i=size; i< AOP_SIZE(result); i++) {
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
- pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
- pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
- }
-
- } else {
- // right is signed, oh dear ...
- for(i=size; i< AOP_SIZE(result); i++) {
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),i));
- pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
- pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
- }
-
- }
- goto release;
-
- } else {
- // add regs
-
- // add first bytes
- for(i=0; i<size; i++) {
- if (AOP_TYPE(right) != AOP_ACC)
- pic16_mov2w(AOP(right),i);
- if (pic16_sameRegs(AOP(left), AOP(result)))
- {
- if(i) { // add with carry
- pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
- } else { // add without
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),i));
- }
- } else { // not same
- if(i) { // add with carry
- pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
- } else { // add without
- pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),i));
- }
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
- }
- }
-
- // add leftover bytes
- // either left or right is too short
- for (i=size; i < AOP_SIZE(result); i++) {
- // get right operand into WREG
- if (i < AOP_SIZE(right)) {
- pic16_mov2w (AOP(right), i);
- } else {
- // right is too short
- pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
- if (!SPEC_USIGN(getSpec(operandType(right)))) {
- // right operand is signed
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),AOP_SIZE(right)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- pic16_emitpcode(POC_SETF, pic16_popCopyReg (&pic16_pc_wreg));
- }
- }
-
- // get left+WREG+CARRY into result
- if (i < AOP_SIZE(left)) {
- if (pic16_sameRegs (AOP(left), AOP(result))) {
- pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
- } else {
- pic16_emitpcode (POC_ADDFWC, pic16_popGet (AOP(left), i));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
- }
- } else {
- // left is too short
- pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), i));
- if (!SPEC_USIGN(getSpec(operandType(left)))) {
- // left operand is signed
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),AOP_SIZE(left)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- pic16_emitpcode(POC_SETF, pic16_popGet (AOP(result), i));
- }
- pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
- }
- } // for i
- goto release;
- }
-
- }
-
- assert( 0 );
-
+ result = IC_RESULT(ic);
+ left = IC_LEFT(ic);
+ right = IC_RIGHT(ic);
+ pic16_aopOp (left,ic,FALSE);
+ pic16_aopOp (right,ic,FALSE);
+ pic16_aopOp (result,ic,TRUE);
+ DEBUGpic16_pic16_AopType(__LINE__,left, right, result);
+ // pic16_DumpOp("(left)",left);
+
+ /* if literal, literal on the right or
+ if left requires ACC or right is already
+ in ACC */
+
+ if ( (AOP_TYPE(left) == AOP_LIT) || (pic16_sameRegs(AOP(right), AOP(result))) ) {
+ operand *t = right;
+ right = IC_RIGHT(ic) = left;
+ left = IC_LEFT(ic) = t;
+ }
+
+ /* if both left & right are in bit space */
+ if (AOP_TYPE(left) == AOP_CRY &&
+ AOP_TYPE(right) == AOP_CRY) {
+ pic16_genPlusBits (ic);
+ goto release ;
+ }
+
+ /* if left in bit space & right literal */
+ if (AOP_TYPE(left) == AOP_CRY &&
+ AOP_TYPE(right) == AOP_LIT) {
+ /* if result in bit space */
+ if(AOP_TYPE(result) == AOP_CRY){
+ if(ulFromVal (AOP(right)->aopu.aop_lit) != 0L) {
+ pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),0));
+ if (!pic16_sameRegs(AOP(left), AOP(result)) )
+ pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
+ pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),0));
+ }
+ } else {
+ unsigned long lit = ulFromVal (AOP(right)->aopu.aop_lit);
+ size = pic16_getDataSize(result);
+ while (size--) {
+ pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), offset));
+ pic16_emitpcode (POC_MOVLW, pic16_popGetLit ((lit >> (8*offset)) & 0xFF));
+ pic16_emitpcode (POC_ADDWFC, pic16_popGet(AOP(result), offset++));
+ //MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
+ //pic16_emitcode("addc","a,#00 ;%d",__LINE__);
+ //pic16_aopPut(AOP(result),"a",offset++);
+ }
+ }
+ goto release ;
+ } // left == CRY
+
+ /* if I can do an increment instead
+ of add then GOOD for ME */
+ if (pic16_genPlusIncr (ic) == TRUE)
+ goto release;
+
+ size = pic16_getDataSize(result);
+
+ if(AOP(right)->type == AOP_LIT) {
+ /* Add a literal to something else */
+ //bool know_W=0;
+ unsigned lit = (unsigned) ulFromVal (AOP(right)->aopu.aop_lit);
+ //unsigned l1=0;
+
+ //offset = 0;
+ DEBUGpic16_emitcode(";","adding lit to something. size %d",size);
+
+ genAddLit (ic, lit);
+ goto release;
+
+ } else if(AOP_TYPE(right) == AOP_CRY) {
+
+ pic16_emitcode(";bitadd","right is bit: %s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
+ pic16_emitcode(";bitadd","left is bit: %s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
+ pic16_emitcode(";bitadd","result is bit: %s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
+
+ /* here we are adding a bit to a char or int */
+ if(size == 1) {
+ if (pic16_sameRegs(AOP(left), AOP(result)) ) {
+
+ pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
+ pic16_emitpcode(POC_INCF , pic16_popGet(AOP(result),0));
+
+ pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
+ AOP(right)->aopu.aop_dir,
+ AOP(right)->aopu.aop_dir);
+ pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(result),0,FALSE,FALSE));
+ } else { // not same
+
+ if(AOP_TYPE(left) == AOP_ACC) {
+ pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
+ pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
+
+ pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
+ AOP(right)->aopu.aop_dir,
+ AOP(right)->aopu.aop_dir);
+ pic16_emitcode(" xorlw","1");
+ } else {
+ pic16_mov2w(AOP(left),0);
+ pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(right),0));
+ pic16_emitpcode(POC_INCFW , pic16_popGet(AOP(left),0));
+
+ pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
+ pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
+ AOP(right)->aopu.aop_dir,
+ AOP(right)->aopu.aop_dir);
+ pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
+ }
+
+ if(AOP_TYPE(result) != AOP_ACC) {
+
+ if(AOP_TYPE(result) == AOP_CRY) {
+ pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
+ pic16_emitpcode(POC_BCF , pic16_popGet(AOP(result),0));
+ emitSKPZ;
+ pic16_emitpcode(POC_BSF , pic16_popGet(AOP(result),0));
+ } else {
+ pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(result),0));
+ pic16_emitcode("movwf","%s", pic16_aopGet(AOP(result),0,FALSE,FALSE));
+ }
+ }
+ }
+
+ } else {
+ int offset = 1;
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ if (pic16_sameRegs(AOP(left), AOP(result)) ) {
+ emitCLRZ;
+ pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
+
+ pic16_emitcode("clrz","");
+
+ pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
+ AOP(right)->aopu.aop_dir,
+ AOP(right)->aopu.aop_dir);
+ pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(result),0,FALSE,FALSE));
+
+ } else {
+ emitCLRZ; // needed here as well: INCFW is not always executed, Z is undefined then
+ pic16_mov2w(AOP(left),0);
+ pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
+ pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0));
+ //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(right),0,FALSE,FALSE));
+ emitMOVWF(right,0);
+
+ pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
+ pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
+ AOP(right)->aopu.aop_dir,
+ AOP(right)->aopu.aop_dir);
+ pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(left),0,FALSE,FALSE));
+ pic16_emitcode("movwf","%s", pic16_aopGet(AOP(result),0,FALSE,FALSE));
+
+ }
+
+ while(--size){
+ emitSKPZ;
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset++));
+ //pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(right),offset++,FALSE,FALSE));
+ }
+
+ }
+
+ } else {
+ // add bytes
+
+ // Note: the following is an example of WISC code, eg.
+ // it's supposed to run on a Weird Instruction Set Computer :o)
+
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ if ( AOP_TYPE(left) == AOP_ACC) {
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),0));
+ if ( AOP_TYPE(result) != AOP_ACC)
+ pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
+ goto release; // we're done, since WREG is 1 byte
+ }
+
+
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ size = min( AOP_SIZE(result), AOP_SIZE(right) );
+ size = min( size, AOP_SIZE(left) );
+ offset = 0;
+
+ if(pic16_debug_verbose) {
+// fprintf(stderr, "%s:%d result: %d\tleft: %d\tright: %d\n", __FILE__, __LINE__,
+// AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
+// fprintf(stderr, "%s:%d size of operands: %d\n", __FILE__, __LINE__, size);
+ }
+
+
+
+ if ((AOP_TYPE(left) == AOP_PCODE) && (
+ (AOP(left)->aopu.pcop->type == PO_LITERAL) ||
+// (AOP(left)->aopu.pcop->type == PO_DIR) || // patch 9
+ (AOP(left)->aopu.pcop->type == PO_IMMEDIATE)))
+ {
+ // add to literal operand
+
+ // add first bytes
+ for(i=0; i<size; i++) {
+ if (AOP_TYPE(right) == AOP_ACC) {
+ pic16_emitpcode(POC_ADDLW, pic16_popGet(AOP(left),i));
+ } else {
+ pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
+ if(i) { // add with carry
+ pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(right),i));
+ } else { // add without
+ pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right),i));
+ }
+ }
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
+ }
+
+ DEBUGpic16_pic16_AopTypeSign(__LINE__, NULL, right, NULL);
+
+ // add leftover bytes
+ if (SPEC_USIGN(getSpec(operandType(right)))) {
+ // right is unsigned
+ for(i=size; i< AOP_SIZE(result); i++) {
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
+ pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
+ pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
+ }
+
+ } else {
+ // right is signed, oh dear ...
+ for(i=size; i< AOP_SIZE(result); i++) {
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+ pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),i));
+ pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i));
+ pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i));
+ }
+
+ }
+ goto release;
+
+ } else {
+ // add regs
+
+ // add first bytes
+ for(i=0; i<size; i++) {
+ if (AOP_TYPE(right) != AOP_ACC)
+ pic16_mov2w(AOP(right),i);
+ if (pic16_sameRegs(AOP(left), AOP(result)))
+ {
+ if(i) { // add with carry
+ pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i));
+ } else { // add without
+ pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),i));
+ }
+ } else { // not same
+ if(i) { // add with carry
+ pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i));
+ } else { // add without
+ pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),i));
+ }
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
+ }
+ }
+
+ // add leftover bytes
+ // either left or right is too short
+ for (i=size; i < AOP_SIZE(result); i++) {
+ // get right operand into WREG
+ if (i < AOP_SIZE(right)) {
+ pic16_mov2w (AOP(right), i);
+ } else {
+ // right is too short
+ pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
+ if (!SPEC_USIGN(getSpec(operandType(right)))) {
+ // right operand is signed
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),AOP_SIZE(right)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+ pic16_emitpcode(POC_SETF, pic16_popCopyReg (&pic16_pc_wreg));
+ }
+ }
+
+ // get left+WREG+CARRY into result
+ if (i < AOP_SIZE(left)) {
+ if (pic16_sameRegs (AOP(left), AOP(result))) {
+ pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
+ } else {
+ pic16_emitpcode (POC_ADDFWC, pic16_popGet (AOP(left), i));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
+ }
+ } else {
+ // left is too short
+ pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), i));
+ if (!SPEC_USIGN(getSpec(operandType(left)))) {
+ // left operand is signed
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),AOP_SIZE(left)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+ pic16_emitpcode(POC_SETF, pic16_popGet (AOP(result), i));
+ }
+ pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i));
+ }
+ } // for i
+ goto release;
+ }
+
+ }
+
+ assert( 0 );
+
release:
- pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- pic16_freeAsmop(result,NULL,ic,TRUE);
+ pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+ pic16_freeAsmop(result,NULL,ic,TRUE);
}
/*-----------------------------------------------------------------*/
FENTRY;
/* will try to generate an increment */
- /* if the right side is not a literal
+ /* if the right side is not a literal
we cannot */
- if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
- (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
- (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
+ if ((AOP_TYPE(IC_RIGHT(ic)) != AOP_LIT) ||
+ (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) ||
+ (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) )
return FALSE ;
- DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
+ DEBUGpic16_emitcode ("; lit val","%d",(unsigned int) ulFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit));
/* if the literal value of the right hand side
is greater than 4 then it is not worth it */
- if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
+ if ((icount = (unsigned int) ulFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
return FALSE ;
/* if decrement 16 bits in register */
(size > 1) &&
(icount == 1)) {
- if(size == 2) {
- pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
- emitSKPC;
- pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
+ if(size == 2) {
+ pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
+ emitSKPC;
+ pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
- pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
- pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
- pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
+ pic16_emitcode("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
+ pic16_emitcode("incfsz","%s,w",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
+ pic16_emitcode(" decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
} else {
- /* size is 3 or 4 */
- pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
- pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
- pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
- pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
+ /* size is 3 or 4 */
+ pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),LSB));
+ pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg));
+ pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB16));
+ pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB24));
- pic16_emitcode("movlw","0xff");
- pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
+ pic16_emitcode("movlw","0xff");
+ pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
- //emitSKPNC;
- pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
- //emitSKPNC;
- pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
+ //emitSKPNC;
+ pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE,FALSE));
+ //emitSKPNC;
+ pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB24,FALSE,FALSE));
- if(size > 3) {
- pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
+ if(size > 3) {
+ pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),MSB32));
- pic16_emitcode("skpnc","");
- //emitSKPNC;
- pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
- }
+ pic16_emitcode("skpnc","");
+ //emitSKPNC;
+ pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
+ }
}
same */
if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
- while (icount--)
- pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
+ while (icount--)
+ pic16_emitpcode(POC_DECF, pic16_popGet(AOP(IC_RESULT(ic)),0));
- //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
+ //pic16_emitcode ("decf","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
return TRUE ;
}
DEBUGpic16_emitcode ("; returning"," result=%s, left=%s",
- pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
- pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
+ pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),
+ pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
if(size==1) {
pic16_emitcode("decf","%s,w",pic16_aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE));
if(sign && offset) {
if(size == 1) {
- pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
- pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),offset));
+ pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
+ pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+ pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),offset));
} else {
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
- while(size--)
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset+size));
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
+ while(size--)
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset+size));
}
} else
while(size--)
- pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
+ pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
}
}
}
DEBUGpic16_emitcode ("; ","result %s, left %s, right %s",
- pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
- pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
- pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
+ pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
+ pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
+ pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
/* special cases :- */
/* if both left & right are in bit space */
/* if I can do an decrement instead
of subtract then GOOD for ME */
// if (pic16_genMinusDec (ic) == TRUE)
-// goto release;
+// goto release;
- size = pic16_getDataSize(IC_RESULT(ic));
+ size = pic16_getDataSize(IC_RESULT(ic));
same = pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)));
if(AOP(IC_RIGHT(ic))->type == AOP_LIT) {
/* Add a literal to something else */
- lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit);
+ lit = ulFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
lit = - (long)lit;
genAddLit ( ic, lit);
-
+
#if 0
/* add the first byte: */
pic16_emitcode("movlw","0x%x", lit & 0xff);
if(lit & 0xff) {
- if((lit & 0xff) == 0xff) {
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
- emitSKPC;
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
- } else {
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
- emitSKPNC;
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
- }
+ if((lit & 0xff) == 0xff) {
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
+ emitSKPC;
+ pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
+ } else {
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
+ emitSKPNC;
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
+ pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
+ }
} else {
- /* do the rlf known zero trick here */
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
- emitSKPNC;
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
+ /* do the rlf known zero trick here */
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
+ emitSKPNC;
+ pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(IC_LEFT(ic)),offset));
}
offset++;
}
if(size == 1) {
if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
- pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
- pic16_emitpcode(POC_DECF , pic16_popGet(AOP(IC_RESULT(ic)),0));
+ pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
+ pic16_emitpcode(POC_DECF , pic16_popGet(AOP(IC_RESULT(ic)),0));
- pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
- AOP(IC_RIGHT(ic))->aopu.aop_dir,
- AOP(IC_RIGHT(ic))->aopu.aop_dir);
- pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
+ pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
+ AOP(IC_RIGHT(ic))->aopu.aop_dir,
+ AOP(IC_RIGHT(ic))->aopu.aop_dir);
+ pic16_emitcode(" incf","%s,f", pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
} else {
- if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
- pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
- pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
- }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
- (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
-
- lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
-
- if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
- if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
- if(lit & 1) {
- pic16_emitpcode(POC_MOVLW , pic16_popGetLit(1));
- pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
- }
- }else{
- pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
- if(lit & 1)
- pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
- else
- pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
- pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
- }
- goto release;
- } else {
- pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
- pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
- pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
- //pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
-
- }
-
- } else {
- pic16_mov2w(AOP(IC_LEFT(ic)),0);
- pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
- pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
- }
-
- if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
-
- pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
-
- } else {
- pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
+ if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
+ pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
+ pic16_emitpcode(POC_XORLW , pic16_popGetLit(1));
+ }else if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
+ (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
+
+ lit = ulFromVal (AOP(IC_LEFT(ic))->aopu.aop_lit);
+
+ if(AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
+ if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
+ if(lit & 1) {
+ pic16_emitpcode(POC_MOVLW , pic16_popGetLit(1));
+ pic16_emitpcode(POC_XORWF , pic16_popGet(AOP(IC_RIGHT(ic)),0));
+ }
+ }else{
+ pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
+ if(lit & 1)
+ pic16_emitpcode(POC_BTFSS , pic16_popGet(AOP(IC_RIGHT(ic)),0));
+ else
+ pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
+ pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
+ }
+ goto release;
+ } else {
+ pic16_emitpcode(POC_MOVLW , pic16_popGetLit(lit & 0xff));
+ pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
+ pic16_emitpcode(POC_MOVLW , pic16_popGetLit((lit-1) & 0xff));
+ //pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
+
+ }
+
+ } else {
+ pic16_mov2w(AOP(IC_LEFT(ic)),0);
+ pic16_emitpcode(POC_BTFSC , pic16_popGet(AOP(IC_RIGHT(ic)),0));
+ pic16_emitpcode(POC_DECFW , pic16_popGet(AOP(IC_LEFT(ic)),0));
+ }
+
+ if(AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
+
+ pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(IC_RESULT(ic)),0));
+
+ } else {
+ pic16_emitpcode(POC_ANDLW , pic16_popGetLit(1));
/*
- pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
- emitSKPZ;
- pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
+ pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
+ emitSKPZ;
+ pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
*/
- }
+ }
}
}
- } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
- (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
- (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
+ } else if(// (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
+ (AOP(IC_LEFT(ic))->type == AOP_LIT) &&
+ (AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)) {
- lit = (unsigned long)floatFromVal(AOP(IC_LEFT(ic))->aopu.aop_lit);
+ lit = ulFromVal (AOP(IC_LEFT(ic))->aopu.aop_lit);
DEBUGpic16_emitcode ("; left is lit","line %d result %s, left %s, right %s",__LINE__,
- pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
- pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
- pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
+ pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
+ pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
+ pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
if( (size == 1) && ((lit & 0xff) == 0) ) {
/* res = 0 - right */
if (pic16_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic))) ) {
- pic16_emitpcode(POC_NEGF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
- } else {
- pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
+ pic16_emitpcode(POC_NEGF, pic16_popGet(AOP(IC_RIGHT(ic)),0));
+ } else {
+ pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),0));
+ pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
}
goto release;
}
pic16_mov2w(AOP(IC_RIGHT(ic)),0);
- pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
+ pic16_emitpcode(POC_SUBLW, pic16_popGetLit(lit & 0xff));
pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
lit >>= 8;
offset++;
if(same) {
- // here we have x = lit - x for sizeof(x)>1
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
- pic16_emitpcode(POC_SUBFWB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
+ // here we have x = lit - x for sizeof(x)>1
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
+ pic16_emitpcode(POC_SUBFWB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
} else {
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
- pic16_emitpcode(POC_SUBFWB_D0, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
+ pic16_emitpcode(POC_SUBFWB_D0, pic16_popGet(AOP(IC_RIGHT(ic)),offset));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
}
}
-
+
} else {
DEBUGpic16_emitcode ("; ","line %d result %s, left %s, right %s",__LINE__,
- pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
- pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
- pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
+ pic16_AopType(AOP_TYPE(IC_RESULT(ic))),
+ pic16_AopType(AOP_TYPE(IC_LEFT(ic))),
+ pic16_AopType(AOP_TYPE(IC_RIGHT(ic))));
if(AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) {
DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_RIGHT(ic)),0));
pic16_emitpcode(POC_SUBLW, pic16_popGetLit(0));
if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
- pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
+ pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
} else {
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
- pic16_mov2w(AOP(IC_RIGHT(ic)),0);
-
- if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
- pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
- else {
- if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
- (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
- pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
- } else {
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
- }
- if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
- if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
- pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
- emitSKPZ;
- pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
- }else
- pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
- }
- }
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ if(AOP_TYPE(IC_RIGHT(ic)) != AOP_ACC)
+ pic16_mov2w(AOP(IC_RIGHT(ic)),0);
+
+ if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
+ pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(IC_LEFT(ic)),0));
+ else {
+ if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) ||
+ (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) {
+ pic16_emitpcode(POC_SUBLW, pic16_popGet(AOP(IC_LEFT(ic)),0));
+ } else {
+ pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
+ }
+ if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) {
+ if ( AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
+ pic16_emitpcode(POC_BCF , pic16_popGet(AOP(IC_RESULT(ic)),0));
+ emitSKPZ;
+ pic16_emitpcode(POC_BSF , pic16_popGet(AOP(IC_RESULT(ic)),0));
+ }else
+ pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
+ }
+ }
}
/*
while(size--){
if (offset < AOP_SIZE(IC_RIGHT(ic)))
- pic16_mov2w(AOP(IC_RIGHT(ic)),offset);
+ pic16_mov2w(AOP(IC_RIGHT(ic)),offset);
else {
- pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
- if (!SPEC_USIGN(operandType(IC_RIGHT(ic)))) {
- // signed -- sign extend the right operand
- pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RIGHT(ic)),AOP_SIZE(IC_RIGHT(ic))-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- pic16_emitpcode (POC_SETF, pic16_popCopyReg (&pic16_pc_wreg));
- }
+ pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg));
+ if (!SPEC_USIGN(operandType(IC_RIGHT(ic)))) {
+ // signed -- sign extend the right operand
+ pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RIGHT(ic)),AOP_SIZE(IC_RIGHT(ic))-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+ pic16_emitpcode (POC_SETF, pic16_popCopyReg (&pic16_pc_wreg));
+ }
}
if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) {
- pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
+ pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
} else {
- if (offset < AOP_SIZE(IC_LEFT(ic))) {
- pic16_emitpcode(POC_SUBWFB_D0, pic16_popGet(AOP(IC_LEFT(ic)),offset));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
- } else {
- // zero extend the left operand
- pic16_emitpcode (POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)), offset));
- if (!SPEC_USIGN(operandType(IC_LEFT(ic)))) {
- // signed -- sign extend the left operand
- pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),AOP_SIZE(IC_LEFT(ic))-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- pic16_emitpcode (POC_SETF, pic16_popGet(AOP(IC_RESULT(ic)), offset)); // keep CARRY/#BORROW bit intact!
- }
- pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
- }
- }
+ if (offset < AOP_SIZE(IC_LEFT(ic))) {
+ pic16_emitpcode(POC_SUBWFB_D0, pic16_popGet(AOP(IC_LEFT(ic)),offset));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
+ } else {
+ // zero extend the left operand
+ pic16_emitpcode (POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)), offset));
+ if (!SPEC_USIGN(operandType(IC_LEFT(ic)))) {
+ // signed -- sign extend the left operand
+ pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),AOP_SIZE(IC_LEFT(ic))-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+ pic16_emitpcode (POC_SETF, pic16_popGet(AOP(IC_RESULT(ic)), offset)); // keep CARRY/#BORROW bit intact!
+ }
+ pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset));
+ }
+ }
offset++;
}
// adjustArithmeticResult(ic);
-
+
release:
pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
pic16_freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
/*-----------------------------------------------------------------*
* pic_genMult8XLit_n - multiplication of two 8-bit numbers.
- *
- *
+ *
+ *
*-----------------------------------------------------------------*/
void pic16_genMult8XLit_n (operand *left,
operand *right,
exit(1);
}
- lit = (int)floatFromVal(AOP(right)->aopu.aop_lit);
+ lit = (int) ulFromVal (AOP(right)->aopu.aop_lit);
assert( (lit >= -128) && (lit < 256) );
pic16_emitpcomment("Unrolled 8 X 8 multiplication");
pic16_emitpcomment("FIXME: the function does not support result==WREG");
if(same) {
switch(lit & 0x00ff) {
case 0:
- while (size--) {
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
- } // while
- return;
-
+ while (size--) {
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
+ } // while
+ return;
+
case 2:
- /* sign extend left in result */
- pic16_addSign(result, 1, !IS_UNSIGNED(operandType(left)));
- // its faster to left shift
- emitCLRC;
- pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
- if (size > 1)
- pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
- return;
+ /* sign extend left in result */
+ pic16_addSign(result, 1, !IS_UNSIGNED(operandType(left)));
+ // its faster to left shift
+ emitCLRC;
+ pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
+ if (size > 1)
+ pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
+ return;
default:
- if(AOP_TYPE(left) != AOP_ACC)
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
- pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit & 0x00ff));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(
- &pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
- /* Adjust result's high bytes below! */
+ if(AOP_TYPE(left) != AOP_ACC)
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
+ pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit & 0x00ff));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(
+ &pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
+ /* Adjust result's high bytes below! */
}
} else {
// operands different
switch(lit & 0x00ff) {
case 0:
- while (size--) {
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
- } // while
- return;
-
+ while (size--) {
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size));
+ } // while
+ return;
+
case 2:
- if (IS_UNSIGNED(operandType(result))) {
- for (i=1; i < size; i++) {
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
- } // for
- } else {
- /* sign extend left to result */
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7));
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
- for (i=1; i < size; i++) {
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
- } // for
- }
- emitCLRC;
- pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
- if (size > 1)
- pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
- return;
-
+ if (IS_UNSIGNED(operandType(result))) {
+ for (i=1; i < size; i++) {
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i));
+ } // for
+ } else {
+ /* sign extend left to result */
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7));
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
+ for (i=1; i < size; i++) {
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
+ } // for
+ }
+ emitCLRC;
+ pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
+ if (size > 1)
+ pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),1));
+ return;
+
default:
- if(AOP_TYPE(left) != AOP_ACC)
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
- pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(
- &pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
- /* Adjust result's high bytes below! */
+ if(AOP_TYPE(left) != AOP_ACC)
+ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
+ pic16_emitpcode(POC_MULLW, pic16_popGetLit(lit));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(
+ &pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
+ /* Adjust result's high bytes below! */
}
}
}
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(
- &pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
+ &pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
/* Need to sign-extend here. */
pic16_addSign(result, 2, !IS_UNSIGNED(operandType(result)));
* pic_genUMult16XLit_16 - unsigned multiplication of two 16-bit numbers *
*-----------------------------------------------------------------------*/
void pic16_genUMult16XLit_16 (operand *left,
- operand *right,
- operand *result)
+ operand *right,
+ operand *result)
{
pCodeOp *pct1, *pct2, *pct3, *pct4;
unsigned int lit;
FENTRY;
-
- if (AOP_TYPE(right) != AOP_LIT){
- fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
- exit(1);
- }
-
- lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
- lit &= 0xffff;
-
- same = pic16_sameRegs(AOP(left), AOP(result));
- if(same) {
- switch(lit) {
- case 0:
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
- return;
- case 2:
- // its faster to left shift
- emitCLRC;
- pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
- return;
-
- default: {
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- pct1 = pic16_popGetTempReg(1);
- pct2 = pic16_popGetTempReg(1);
- pct3 = pic16_popGetTempReg(1);
- pct4 = pic16_popGetTempReg(1);
-
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
- pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
- pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
- pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
-
- /* WREG still holds the low literal */
- pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
- pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
-
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
- pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
- pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
-
- /* load result */
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
- pct1, pic16_popGet(AOP(result), 0)));
- pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
- pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
- pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
-
- pic16_popReleaseTempReg(pct4,1);
- pic16_popReleaseTempReg(pct3,1);
- pic16_popReleaseTempReg(pct2,1);
- pic16_popReleaseTempReg(pct1,1);
- }; return;
- }
- } else {
- // operands different
- switch(lit) {
- case 0:
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
- return;
- case 2:
- emitCLRC;
- pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
- pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
- return;
- default: {
-
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
- pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
- pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
- pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
-
- /* WREG still holds the low literal */
- pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
- pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
-
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
- pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
- pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
- pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
-
- }; return;
- }
- }
+
+ if (AOP_TYPE(right) != AOP_LIT){
+ fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
+ exit(1);
+ }
+
+ lit = (unsigned int) ulFromVal (AOP(right)->aopu.aop_lit);
+ lit &= 0xffff;
+
+ same = pic16_sameRegs(AOP(left), AOP(result));
+ if(same) {
+ switch(lit) {
+ case 0:
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
+ return;
+ case 2:
+ // its faster to left shift
+ emitCLRC;
+ pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
+ pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
+ return;
+
+ default: {
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ pct1 = pic16_popGetTempReg(1);
+ pct2 = pic16_popGetTempReg(1);
+ pct3 = pic16_popGetTempReg(1);
+ pct4 = pic16_popGetTempReg(1);
+
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
+
+ /* WREG still holds the low literal */
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
+
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
+
+ /* load result */
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pct1, pic16_popGet(AOP(result), 0)));
+ pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
+ pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
+ pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
+
+ pic16_popReleaseTempReg(pct4,1);
+ pic16_popReleaseTempReg(pct3,1);
+ pic16_popReleaseTempReg(pct2,1);
+ pic16_popReleaseTempReg(pct1,1);
+ }; return;
+ }
+ } else {
+ // operands different
+ switch(lit) {
+ case 0:
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
+ return;
+ case 2:
+ emitCLRC;
+ pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
+ pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
+ return;
+ default: {
+
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
+
+ /* WREG still holds the low literal */
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
+ pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
+ pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
+
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
+ pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
+ pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
+
+ }; return;
+ }
+ }
}
#endif
/*-----------------------------------------------------------------*
* genMult8X8_n - multiplication of two 8-bit numbers.
- *
- *
+ *
+ *
*-----------------------------------------------------------------*/
void pic16_genMult8X8_n (operand *left, operand *right, operand *result)
}
/* cases:
- A = A x B B = A x B
+ A = A x B B = A x B
A = B x C
W = A x B
- W = W x B W = B x W
+ W = W x B W = B x W
*/
/* if result == right then exchange left and right */
if(pic16_sameRegs(AOP(result), AOP(right))) {
/* result is in PRODL:PRODH */
if(AOP_TYPE(result) != AOP_ACC) {
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(
- &pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
+ &pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
if(AOP_SIZE(result)>1) {
/* If s8 x s8 --> s16 multiplication was called for, fixup high byte.
* (left=a1a0, right=b1b0, X1: high byte, X0: low byte)
- *
+ *
* a1a0 * b1b0
* --------------
* a1b0 a0b0
* Currently, PRODH:PRODL holds a0b0 as 16 bit value; we need to
* subtract a0 and/or b0 from PRODH. */
if (!IS_UNSIGNED(operandType(right))) {
- /* right operand (b1) signed and < 0, then subtract left op (a0) */
- pic16_mov2w( AOP(left), 0 );
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(right), 0, 7));
- pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_prodh));
+ /* right operand (b1) signed and < 0, then subtract left op (a0) */
+ pic16_mov2w( AOP(left), 0 );
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(right), 0, 7));
+ pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_prodh));
}
if (!IS_UNSIGNED(getSpec(operandType(left)))) {
- /* left operand (a1) signed and < 0, then subtract right op (b0) */
- pic16_mov2w( AOP(right), 0 );
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7));
- pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_prodh));
+ /* left operand (a1) signed and < 0, then subtract right op (b0) */
+ pic16_mov2w( AOP(right), 0 );
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit_simple(AOP(left), 0, 7));
+ pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_prodh));
}
pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(
- &pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
+ &pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
/* Must sign-extend here. */
pic16_addSign(result, 2, !IS_UNSIGNED(operandType(left)));
* genUMult16X16_16 - unsigned multiplication of two 16-bit numbers *
*------------------------------------------------------------------*/
void pic16_genUMult16X16_16 (operand *left,
- operand *right,
- operand *result)
+ operand *right,
+ operand *result)
{
pCodeOp *pct1, *pct2, *pct3, *pct4;
FENTRY;
- if (AOP_TYPE(right) == AOP_LIT) {
- pic16_genMult8XLit_n(left,right,result);
- return;
- }
-
- /* cases:
- A = A x B B = A x B
- A = B x C
- */
- /* if result == right then exchange left and right */
- if(pic16_sameRegs(AOP(result), AOP(right))) {
- operand *tmp;
- tmp = left;
- left = right;
- right = tmp;
- }
-
-
- if(pic16_sameRegs(AOP(result), AOP(left))) {
-
- pct1 = pic16_popGetTempReg(1);
- pct2 = pic16_popGetTempReg(1);
- pct3 = pic16_popGetTempReg(1);
- pct4 = pic16_popGetTempReg(1);
-
- pic16_mov2w(AOP(left), 0);
- pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
- pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
- pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
-
- /* WREG still holds the lower left */
- pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
- pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
-
- pic16_mov2w(AOP(left), 1);
- pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
- pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
-
- /* load result */
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
- pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
- pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
- pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
- pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
-
- pic16_popReleaseTempReg( pct4, 1 );
- pic16_popReleaseTempReg( pct3, 1 );
- pic16_popReleaseTempReg( pct2, 1 );
- pic16_popReleaseTempReg( pct1, 1 );
-
- } else {
-
- pic16_mov2w(AOP(left), 0);
- pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
- pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
- pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
-
- /* WREG still holds the lower left */
- pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
- pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
-
- pic16_mov2w(AOP(left), 1);
- pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
- pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
- pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
- }
+ if (AOP_TYPE(right) == AOP_LIT) {
+ pic16_genMult8XLit_n(left,right,result);
+ return;
+ }
+
+ /* cases:
+ A = A x B B = A x B
+ A = B x C
+ */
+ /* if result == right then exchange left and right */
+ if(pic16_sameRegs(AOP(result), AOP(right))) {
+ operand *tmp;
+ tmp = left;
+ left = right;
+ right = tmp;
+ }
+
+
+ if(pic16_sameRegs(AOP(result), AOP(left))) {
+
+ pct1 = pic16_popGetTempReg(1);
+ pct2 = pic16_popGetTempReg(1);
+ pct3 = pic16_popGetTempReg(1);
+ pct4 = pic16_popGetTempReg(1);
+
+ pic16_mov2w(AOP(left), 0);
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
+
+ /* WREG still holds the lower left */
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
+
+ pic16_mov2w(AOP(left), 1);
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
+
+ /* load result */
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
+ pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
+ pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
+ pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
+
+ pic16_popReleaseTempReg( pct4, 1 );
+ pic16_popReleaseTempReg( pct3, 1 );
+ pic16_popReleaseTempReg( pct2, 1 );
+ pic16_popReleaseTempReg( pct1, 1 );
+
+ } else {
+
+ pic16_mov2w(AOP(left), 0);
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
+
+ /* WREG still holds the lower left */
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
+ pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
+ pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
+
+ pic16_mov2w(AOP(left), 1);
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
+ pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
+ pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
+ }
}
#endif
#if 0
void pic16_genSMult16X16_16(operand *left,
- operand *right,
- operand *result)
+ operand *right,
+ operand *result)
{
}
* post-fix the sign bit.
*-----------------------------------------------------------------*/
void pic16_genSMult8X8_8 (operand *left,
- operand *right,
- operand *result,
- pCodeOpReg *result_hi)
+ operand *right,
+ operand *result,
+ pCodeOpReg *result_hi)
{
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if(!result_hi) {
pic16_genUMult8X8_8(left,right,result);
-
+
#if 0
pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0, PO_GPR_REGISTER));
pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
* pic16_genMult8X8_8 - multiplication of two 8-bit numbers *
*-----------------------------------------------------------------*/
void pic16_genMult8X8_8 (operand *left,
- operand *right,
- operand *result)
+ operand *right,
+ operand *result)
{
FENTRY;
-
+
if(AOP_TYPE(right) == AOP_LIT)
pic16_genMult8XLit_n(left,right,result);
else
* pic16_genMult16X16_16 - multiplication of two 16-bit numbers *
*-----------------------------------------------------------------*/
void pic16_genMult16X16_16 (operand *left,
- operand *right,
- operand *result)
+ operand *right,
+ operand *result)
{
FENTRY;
-
+
if (AOP_TYPE(right) == AOP_LIT)
pic16_genUMult16XLit_16(left,right,result);
else
* pic_genUMult32XLit_32 - unsigned multiplication of two 32-bit numbers *
*-----------------------------------------------------------------------*/
void pic16_genUMult32XLit_32 (operand *left,
- operand *right,
- operand *result)
+ operand *right,
+ operand *result)
{
pCodeOp *pct1, *pct2, *pct3, *pct4;
unsigned int lit;
FENTRY;
-
- if (AOP_TYPE(right) != AOP_LIT){
- fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
- exit(1);
- }
-
- lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
- lit &= 0xffff;
-
- same = pic16_sameRegs(AOP(left), AOP(result));
- if(same) {
- switch(lit) {
- case 0:
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
- return;
- case 2:
- // its faster to left shift
- emitCLRC;
- pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
- return;
-
- default: {
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- pct1 = pic16_popGetTempReg(1);
- pct2 = pic16_popGetTempReg(1);
- pct3 = pic16_popGetTempReg(1);
- pct4 = pic16_popGetTempReg(1);
-
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
- pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
- pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
- pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
-
- /* WREG still holds the low literal */
- pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
- pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
-
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
- pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
- pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
-
- /* load result */
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
- pct1, pic16_popGet(AOP(result), 0)));
- pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
- pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
- pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
-
- pic16_popReleaseTempReg( pct4, 1 );
- pic16_popReleaseTempReg( pct3, 1 );
- pic16_popReleaseTempReg( pct2, 1 );
- pic16_popReleaseTempReg( pct1, 1 );
- }; return;
- }
- } else {
- // operands different
- switch(lit) {
- case 0:
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
- return;
- case 2:
- emitCLRC;
- pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
- pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
- return;
- default: {
-
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
- pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
- pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
- pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
-
- /* WREG still holds the low literal */
- pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
- pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
-
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
- pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
- pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
- pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
-
- }; return;
- }
- }
+
+ if (AOP_TYPE(right) != AOP_LIT){
+ fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
+ exit(1);
+ }
+
+ lit = (unsigned int) ulFromVal (AOP(right)->aopu.aop_lit);
+ lit &= 0xffff;
+
+ same = pic16_sameRegs(AOP(left), AOP(result));
+ if(same) {
+ switch(lit) {
+ case 0:
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
+ return;
+ case 2:
+ // its faster to left shift
+ emitCLRC;
+ pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
+ pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
+ return;
+
+ default: {
+ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ pct1 = pic16_popGetTempReg(1);
+ pct2 = pic16_popGetTempReg(1);
+ pct3 = pic16_popGetTempReg(1);
+ pct4 = pic16_popGetTempReg(1);
+
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
+
+ /* WREG still holds the low literal */
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
+
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
+
+ /* load result */
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pct1, pic16_popGet(AOP(result), 0)));
+ pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
+ pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
+ pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
+
+ pic16_popReleaseTempReg( pct4, 1 );
+ pic16_popReleaseTempReg( pct3, 1 );
+ pic16_popReleaseTempReg( pct2, 1 );
+ pic16_popReleaseTempReg( pct1, 1 );
+ }; return;
+ }
+ } else {
+ // operands different
+ switch(lit) {
+ case 0:
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
+ return;
+ case 2:
+ emitCLRC;
+ pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
+ pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
+ return;
+ default: {
+
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
+
+ /* WREG still holds the low literal */
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
+ pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
+ pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
+
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
+ pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
+ pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
+
+ }; return;
+ }
+ }
}
#endif
* genUMult32X32_32 - unsigned multiplication of two 32-bit numbers *
*------------------------------------------------------------------*/
void pic16_genUMult32X32_32 (operand *left,
- operand *right,
- operand *result)
+ operand *right,
+ operand *result)
{
pCodeOp *pct1, *pct2, *pct3, *pct4;
FENTRY;
-
- if (AOP_TYPE(right) == AOP_LIT) {
- pic16_genMult8XLit_n(left,right,result);
- return;
- }
-
- /* cases:
- A = A x B B = A x B
- A = B x C
- */
- /* if result == right then exchange left and right */
- if(pic16_sameRegs(AOP(result), AOP(right))) {
- operand *tmp;
- tmp = left;
- left = right;
- right = tmp;
- }
-
-
- if(pic16_sameRegs(AOP(result), AOP(left))) {
-
- pct1 = pic16_popGetTempReg(1);
- pct2 = pic16_popGetTempReg(1);
- pct3 = pic16_popGetTempReg(1);
- pct4 = pic16_popGetTempReg(1);
-
- pic16_mov2w(AOP(left), 0);
- pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
- pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
- pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
-
- /* WREG still holds the lower left */
- pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
- pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
-
- pic16_mov2w(AOP(left), 1);
- pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
- pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
-
- /* load result */
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
- pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
- pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
- pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
- pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
- pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
-
- pic16_popReleaseTempReg( pct4, 1 );
- pic16_popReleaseTempReg( pct3, 1 );
- pic16_popReleaseTempReg( pct2, 1 );
- pic16_popReleaseTempReg( pct1, 1 );
-
- } else {
-
- pic16_mov2w(AOP(left), 0);
- pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
- pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
- pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
- pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
-
- /* WREG still holds the lower left */
- pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
- pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
- pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
-
- pic16_mov2w(AOP(left), 1);
- pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
- pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
- pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
- }
+
+ if (AOP_TYPE(right) == AOP_LIT) {
+ pic16_genMult8XLit_n(left,right,result);
+ return;
+ }
+
+ /* cases:
+ A = A x B B = A x B
+ A = B x C
+ */
+ /* if result == right then exchange left and right */
+ if(pic16_sameRegs(AOP(result), AOP(right))) {
+ operand *tmp;
+ tmp = left;
+ left = right;
+ right = tmp;
+ }
+
+
+ if(pic16_sameRegs(AOP(result), AOP(left))) {
+
+ pct1 = pic16_popGetTempReg(1);
+ pct2 = pic16_popGetTempReg(1);
+ pct3 = pic16_popGetTempReg(1);
+ pct4 = pic16_popGetTempReg(1);
+
+ pic16_mov2w(AOP(left), 0);
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
+
+ /* WREG still holds the lower left */
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
+
+ pic16_mov2w(AOP(left), 1);
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
+
+ /* load result */
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
+ pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
+ pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
+ pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
+
+ pic16_popReleaseTempReg( pct4, 1 );
+ pic16_popReleaseTempReg( pct3, 1 );
+ pic16_popReleaseTempReg( pct2, 1 );
+ pic16_popReleaseTempReg( pct1, 1 );
+
+ } else {
+
+ pic16_mov2w(AOP(left), 0);
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
+ pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+ pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
+
+ /* WREG still holds the lower left */
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
+ pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
+ pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
+
+ pic16_mov2w(AOP(left), 1);
+ pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
+ pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
+ pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
+ }
}
#endif
* pic16_genMult32X32_32 - multiplication of two 32-bit numbers *
*-----------------------------------------------------------------*/
void pic16_genMult32X32_32 (operand *left,
- operand *right,
- operand *result)
+ operand *right,
+ operand *result)
{
FENTRY;
-
+
if (AOP_TYPE(right) == AOP_LIT)
pic16_genUMult32XLit_32(left,right,result);
else
if(isAOP_REGlike(left) && isAOP_LIT(right)) {
/* comparing register vs. literal */
- lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
+ lit = ulFromVal(AOP(right)->aopu.aop_lit);
if(size == 1) {
/* if it is a float then it gets tricky */
/* otherwise it is fairly simple */
if (!(IS_FLOAT(val->type) || IS_FIXED(val->type))) {
- unsigned long v = (unsigned long) floatFromVal(val);
+ unsigned long v = ulFromVal (val);
return ( (v >> (offset * 8)) & 0xff);
}
if(IS_FIXED16X16(val->type)) {
unsigned long v = (unsigned long)fixed16x16FromDouble( floatFromVal( val ) );
-
+
return ( (v >> (offset * 8)) & 0xff);
}
symbol *sym;
// int i, size, bitvars = 0;;
-// fprintf(stderr, "%s:%d map name= %s\n", __FUNCTION__, __LINE__, map->sname);
-
- if(addPublics)
- dbuf_printf (&map->oBuf, ";\t.area\t%s\n", map->sname);
- /* print the area name */
+// fprintf(stderr, "%s:%d map name= %s\n", __FUNCTION__, __LINE__, map->sname);
+
+ if(addPublics)
+ dbuf_printf (&map->oBuf, ";\t.area\t%s\n", map->sname);
+ /* print the area name */
- for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms)) {
+ for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms)) {
#if 0
- fprintf(stderr, "%s\t%s: sym: %s\tused: %d\textern: %d\tstatic: %d\taggregate: %d\tregister: 0x%x\tfunction: %d\n",
- __FUNCTION__,
- map->sname, sym->name, sym->used, IS_EXTERN(sym->etype), IS_STATIC(sym->etype),
- IS_AGGREGATE(sym->type), (SPEC_SCLS(sym->etype) == S_REGISTER), IS_FUNC(sym->type));
- printTypeChain( sym->type, stderr );
- fprintf(stderr, "\n");
+ fprintf(stderr, "%s\t%s: sym: %s\tused: %d\textern: %d\tstatic: %d\taggregate: %d\tregister: 0x%x\tfunction: %d\n",
+ __FUNCTION__,
+ map->sname, sym->name, sym->used, IS_EXTERN(sym->etype), IS_STATIC(sym->etype),
+ IS_AGGREGATE(sym->type), (SPEC_SCLS(sym->etype) == S_REGISTER), IS_FUNC(sym->type));
+ printTypeChain( sym->type, stderr );
+ fprintf(stderr, "\n");
#endif
- /* if extern then add to externs */
- if (IS_EXTERN (sym->etype)) {
- /* reduce overhead while linking by not declaring
- * extern unused external functions (usually declared
- * in header files) */
- if(IS_FUNC(sym->type) && !sym->used)continue;
-
- /* make sure symbol is not in publics section */
- if(!checkSym(publics, sym))
- checkAddSym(&externs, sym);
- continue;
- }
-
- /* if allocation required check is needed
- * then check if the symbol really requires
- * allocation only for local variables */
- if (arFlag && !IS_AGGREGATE (sym->type) &&
- !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
- !sym->allocreq && sym->level) {
-
-// fprintf(stderr, "%s:%d special case, continuing...\n", __FILE__, __LINE__);
-
- continue;
- }
-
- /* if global variable & not static or extern
- * and addPublics allowed then add it to the public set */
- if ((sym->used) && (sym->level == 0 ||
- (sym->_isparm && !IS_REGPARM (sym->etype))) &&
- addPublics &&
- !IS_STATIC (sym->etype) && !IS_FUNC(sym->type)) {
-
- checkAddSym(&publics, sym);
- } else
+ /* if extern then add to externs */
+ if (IS_EXTERN (sym->etype)) {
+ /* reduce overhead while linking by not declaring
+ * extern unused external functions (usually declared
+ * in header files) */
+ if(IS_FUNC(sym->type) && !sym->used)continue;
+
+ /* make sure symbol is not in publics section */
+ if(!checkSym(publics, sym))
+ checkAddSym(&externs, sym);
+ continue;
+ }
+
+ /* if allocation required check is needed
+ * then check if the symbol really requires
+ * allocation only for local variables */
+ if (arFlag && !IS_AGGREGATE (sym->type) &&
+ !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
+ !sym->allocreq && sym->level) {
+
+// fprintf(stderr, "%s:%d special case, continuing...\n", __FILE__, __LINE__);
+
+ continue;
+ }
+
+ /* if global variable & not static or extern
+ * and addPublics allowed then add it to the public set */
+ if ((sym->used) && (sym->level == 0 ||
+ (sym->_isparm && !IS_REGPARM (sym->etype))) &&
+ addPublics &&
+ !IS_STATIC (sym->etype) && !IS_FUNC(sym->type)) {
+
+ checkAddSym(&publics, sym);
+ } else
/* new version */
- if(IS_STATIC(sym->etype)
- && !sym->ival) /* && !sym->level*/ {
- regs *reg;
+ if(IS_STATIC(sym->etype)
+ && !sym->ival) /* && !sym->level*/ {
+ regs *reg;
sectSym *ssym;
int found=0;
// debugf("adding symbol %s\n", sym->name);
-#define SET_IMPLICIT 1
+#define SET_IMPLICIT 1
#if SET_IMPLICIT
- if(IS_STRUCT(sym->type))
- sym->implicit = 1;
+ if(IS_STRUCT(sym->type))
+ sym->implicit = 1;
#endif
- reg = pic16_allocDirReg( operandFromSymbol( sym ));
-
- if(reg) {
+ reg = pic16_allocDirReg( operandFromSymbol( sym ));
+
+ if(reg) {
for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
- if(!strcmp(ssym->name, reg->name))found=1;
+ if(!strcmp(ssym->name, reg->name))found=1;
}
if(!found)
#if 0
else
debugf("Did find %s in pic16_rel_udata already. Check!\n", reg->name);
-// checkAddSym(&publics, sym);
+// checkAddSym(&publics, sym);
#endif
}
- }
-
- /* if extern then do nothing or is a function
- * then do nothing */
- if (IS_FUNC (sym->type) && !IS_STATIC(sym->etype)) {
- if(SPEC_OCLS(sym->etype) == code) {
-// fprintf(stderr, "%s:%d: symbol added: %s\n", __FILE__, __LINE__, sym->rname);
- checkAddSym(&publics, sym);
- }
- continue;
- }
-
- /* if is has an absolute address then generate
- an equate for this no need to allocate space */
- if (SPEC_ABSA (sym->etype)) {
-// fprintf (stderr,"; %s == 0x%04x\t\treqv= %p nRegs= %d\n",
-// sym->name, SPEC_ADDR (sym->etype), sym->reqv, sym->regType);
-
- dbuf_printf (&map->oBuf, "%s\tEQU\t0x%04x\n",
- sym->rname,
- SPEC_ADDR (sym->etype));
-
- /* emit only if it is global */
- if(sym->level == 0) {
- regs *reg;
-
- reg = pic16_dirregWithName( sym->name );
- if(!reg) {
- /* here */
-// fprintf(stderr, "%s:%d: implicit add of symbol = %s\n",
-// __FUNCTION__, __LINE__, sym->name);
-
- /* if IS_STRUCT is omitted the following
- * fixes structures but break char/int etc */
+ }
+
+ /* if extern then do nothing or is a function
+ * then do nothing */
+ if (IS_FUNC (sym->type) && !IS_STATIC(sym->etype)) {
+ if(SPEC_OCLS(sym->etype) == code) {
+// fprintf(stderr, "%s:%d: symbol added: %s\n", __FILE__, __LINE__, sym->rname);
+ checkAddSym(&publics, sym);
+ }
+ continue;
+ }
+
+ /* if is has an absolute address then generate
+ an equate for this no need to allocate space */
+ if (SPEC_ABSA (sym->etype)) {
+// fprintf (stderr,"; %s == 0x%04x\t\treqv= %p nRegs= %d\n",
+// sym->name, SPEC_ADDR (sym->etype), sym->reqv, sym->regType);
+
+ dbuf_printf (&map->oBuf, "%s\tEQU\t0x%04x\n",
+ sym->rname,
+ SPEC_ADDR (sym->etype));
+
+ /* emit only if it is global */
+ if(sym->level == 0) {
+ regs *reg;
+
+ reg = pic16_dirregWithName( sym->name );
+ if(!reg) {
+ /* here */
+// fprintf(stderr, "%s:%d: implicit add of symbol = %s\n",
+// __FUNCTION__, __LINE__, sym->name);
+
+ /* if IS_STRUCT is omitted the following
+ * fixes structures but break char/int etc */
#if SET_IMPLICIT
- if(IS_STRUCT(sym->type))
- sym->implicit = 1; // mark as implicit
+ if(IS_STRUCT(sym->type))
+ sym->implicit = 1; // mark as implicit
#endif
- if(!sym->ival) {
- reg = pic16_allocDirReg( operandFromSymbol(sym) );
- if(reg) {
- if(checkAddReg(&pic16_fix_udata, reg)) {
- /* and add to globals list if not exist */
- addSet(&publics, sym);
- }
- }
- } else
- addSet(&publics, sym);
- }
- }
- } else {
- if(!sym->used && (sym->level == 0)) {
- regs *reg;
-
- /* symbol not used, just declared probably, but its in
- * level 0, so we must declare it fine as global */
-
-// fprintf(stderr, "EXTRA symbol declaration sym= %s\n", sym->name);
+ if(!sym->ival) {
+ reg = pic16_allocDirReg( operandFromSymbol(sym) );
+ if(reg) {
+ if(checkAddReg(&pic16_fix_udata, reg)) {
+ /* and add to globals list if not exist */
+ addSet(&publics, sym);
+ }
+ }
+ } else
+ addSet(&publics, sym);
+ }
+ }
+ } else {
+ if(!sym->used && (sym->level == 0)) {
+ regs *reg;
+
+ /* symbol not used, just declared probably, but its in
+ * level 0, so we must declare it fine as global */
+
+// fprintf(stderr, "EXTRA symbol declaration sym= %s\n", sym->name);
#if SET_IMPLICIT
- if(IS_STRUCT(sym->type))
- sym->implicit = 1; // mark as implicit
+ if(IS_STRUCT(sym->type))
+ sym->implicit = 1; // mark as implicit
#endif
- if(!sym->ival) {
- if(IS_AGGREGATE(sym->type)) {
- reg=pic16_allocRegByName(sym->rname, getSize( sym->type ), NULL);
- } else {
- reg = pic16_allocDirReg( operandFromSymbol( sym ) );
- }
-
- {
- sectSym *ssym;
- int found=0;
-
+ if(!sym->ival) {
+ if(IS_AGGREGATE(sym->type)) {
+ reg=pic16_allocRegByName(sym->rname, getSize( sym->type ), NULL);
+ } else {
+ reg = pic16_allocDirReg( operandFromSymbol( sym ) );
+ }
+
+ {
+ sectSym *ssym;
+ int found=0;
+
#if 0
- fprintf(stderr, "%s:%d sym->rname: %s reg: %p reg->name: %s\n", __FILE__, __LINE__,
- sym->rname, reg, (reg?reg->name:"<<NULL>>"));
+ fprintf(stderr, "%s:%d sym->rname: %s reg: %p reg->name: %s\n", __FILE__, __LINE__,
+ sym->rname, reg, (reg?reg->name:"<<NULL>>"));
#endif
if(reg) {
- for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
- if(!strcmp(ssym->name, reg->name))found=1;
+ for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
+ if(!strcmp(ssym->name, reg->name))found=1;
}
if(!found)
addSetHead(&publics, sym);
}
}
- }
+ }
+
-
- } else
+ } else
- addSetHead(&publics, sym);
- }
+ addSetHead(&publics, sym);
+ }
#if 0
- /* allocate space */
- /* If this is a bit variable, then allocate storage after 8 bits have been declared */
- /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
- /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
- if (IS_BITVAR (sym->etype)) {
- bitvars++;
- } else {
- dbuf_printf (map->oBuf, "\t%s\n", sym->rname);
- if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1) {
- for (i = 1; i < size; i++)
- dbuf_printf (map->oBuf, "\t%s_%d\n", sym->rname, i);
- }
- }
- dbuf_printf (map->oBuf, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
+ /* allocate space */
+ /* If this is a bit variable, then allocate storage after 8 bits have been declared */
+ /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
+ /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
+ if (IS_BITVAR (sym->etype)) {
+ bitvars++;
+ } else {
+ dbuf_printf (map->oBuf, "\t%s\n", sym->rname);
+ if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1) {
+ for (i = 1; i < size; i++)
+ dbuf_printf (map->oBuf, "\t%s_%d\n", sym->rname, i);
+ }
+ }
+ dbuf_printf (map->oBuf, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
#endif
- }
-
- /* FIXME -- VR Fix the following, so that syms to be placed
- * in the idata section and let linker decide about their fate */
+ }
+
+ /* FIXME -- VR Fix the following, so that syms to be placed
+ * in the idata section and let linker decide about their fate */
- /* if it has an initial value then do it only if
- it is a global variable */
+ /* if it has an initial value then do it only if
+ it is a global variable */
- if (sym->ival
- && ((sym->level == 0)
- || IS_STATIC(sym->etype)) ) {
- ast *ival = NULL;
+ if (sym->ival
+ && ((sym->level == 0)
+ || IS_STATIC(sym->etype)) ) {
+ ast *ival = NULL;
#if 0
- if(SPEC_OCLS(sym->etype)==data) {
- fprintf(stderr, "%s: sym %s placed in data segment\n", map->sname, sym->name);
- }
+ if(SPEC_OCLS(sym->etype)==data) {
+ fprintf(stderr, "%s: sym %s placed in data segment\n", map->sname, sym->name);
+ }
- if(SPEC_OCLS(sym->etype)==code) {
- fprintf(stderr, "%s: sym %s placed in code segment\n", map->sname, sym->name);
- }
+ if(SPEC_OCLS(sym->etype)==code) {
+ fprintf(stderr, "%s: sym %s placed in code segment\n", map->sname, sym->name);
+ }
#endif
#if 0
- fprintf(stderr, "'%s': sym '%s' has initial value SPEC_ABSA: %d, IS_AGGREGATE: %d\n",
- map->sname, sym->name, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type));
+ fprintf(stderr, "'%s': sym '%s' has initial value SPEC_ABSA: %d, IS_AGGREGATE: %d\n",
+ map->sname, sym->name, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type));
#endif
- if (IS_AGGREGATE (sym->type)) {
- if(SPEC_ABSA(sym->etype))
- addSet(&fix_idataSymSet, copySymbol(sym));
- else
- addSet(&rel_idataSymSet, copySymbol(sym));
-// ival = initAggregates (sym, sym->ival, NULL);
- } else {
- if(SPEC_ABSA(sym->etype))
- addSet(&fix_idataSymSet, copySymbol(sym));
- else
- addSet(&rel_idataSymSet, copySymbol(sym));
-
-// ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
-// decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_TYPE_NONE));
- }
-
- if(ival) {
- setAstLineno(ival, sym->lineDef);
- codeOutBuf = &statsg->oBuf;
- GcurMemmap = statsg;
- eBBlockFromiCode (iCodeFromAst (ival));
- sym->ival = NULL;
- }
- }
- }
+ if (IS_AGGREGATE (sym->type)) {
+ if(SPEC_ABSA(sym->etype))
+ addSet(&fix_idataSymSet, copySymbol(sym));
+ else
+ addSet(&rel_idataSymSet, copySymbol(sym));
+// ival = initAggregates (sym, sym->ival, NULL);
+ } else {
+ if(SPEC_ABSA(sym->etype))
+ addSet(&fix_idataSymSet, copySymbol(sym));
+ else
+ addSet(&rel_idataSymSet, copySymbol(sym));
+
+// ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
+// decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_TYPE_NONE));
+ }
+
+ if(ival) {
+ setAstLineno(ival, sym->lineDef);
+ codeOutBuf = &statsg->oBuf;
+ GcurMemmap = statsg;
+ eBBlockFromiCode (iCodeFromAst (ival));
+ sym->ival = NULL;
+ }
+ }
+ }
}
expr = decorateType(resolveSymbols( list2expr (ilist) ), FALSE);
// expr = list2expr( ilist );
-
+
if (!expr)
goto wrong;
-
+
/* try it the old way first */
if (expr->etype && (val = constExprValue (expr, FALSE)))
return val;
-
+
/* ( ptr + constant ) */
if (IS_AST_OP (expr) &&
(expr->opval.op == '+' || expr->opval.op == '-') &&
expr->right,
expr->opval.op);
}
-
+
/* (char *)&a */
if (IS_AST_OP(expr) && expr->opval.op==CAST &&
IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
{
char buf[256];
- sprintf(buf, "LOW(%s)", name);
- pic16_emitDS(buf, ptype, p);
- sprintf(buf, "HIGH(%s)", name);
- pic16_emitDS(buf, ptype, p);
+ sprintf(buf, "LOW(%s)", name);
+ pic16_emitDS(buf, ptype, p);
+ sprintf(buf, "HIGH(%s)", name);
+ pic16_emitDS(buf, ptype, p);
}
/*-----------------------------------------------------------------*/
char ptype, void *p)
{
char buf[256];
-
+
_pic16_printPointerType (iname, ptype, p);
switch( itype ) {
/* set to 0 to disable debug messages */
-#define DEBUG_PRINTIVAL 0
+#define DEBUG_PRINTIVAL 0
/*-----------------------------------------------------------------*/
/* pic16_printIvalType - generates ival for int/char */
/*-----------------------------------------------------------------*/
-static void
+static void
pic16_printIvalType (symbol *sym, sym_link * type, initList * ilist, char ptype, void *p)
{
value *val;
/*--------------------------------------------------------------------*/
/* pic16_printIvalChar - generates initital value for character array */
/*--------------------------------------------------------------------*/
-static int
+static int
pic16_printIvalChar (symbol *sym, sym_link * type, initList * ilist, char *s, char ptype, void *p)
{
value *val;
for(remain=0; remain<ilen; remain++)
pic16_emitDB(SPEC_CVAL(val->etype).v_char[ remain ], ptype, p);
- /* fill array with 0x00 */
+ /* fill array with 0x00 */
while(len--) {
pic16_emitDB(0x00, ptype, p);
}
for(remain=0; remain<DCL_ELEM (type); remain++)
pic16_emitDB(SPEC_CVAL(val->etype).v_char[ remain ], ptype, p);
}
-
+
// if((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0) {
// }
/*-----------------------------------------------------------------*/
/* pic16_printIvalArray - generates code for array initialization */
/*-----------------------------------------------------------------*/
-static void
+static void
pic16_printIvalArray (symbol * sym, sym_link * type, initList * ilist,
- char ptype, void *p)
+ char ptype, void *p)
{
initList *iloop;
int lcnt = 0, size = 0;
}
if(pic16_printIvalChar (sym, type,
- (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
- SPEC_CVAL (sym->etype).v_char, ptype, p))
+ (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
+ SPEC_CVAL (sym->etype).v_char, ptype, p))
return;
}
/* not the special case */
/* if not array limits given & we */
/* are out of initialisers then */
if (!DCL_ELEM (type) && !iloop)
- break;
+ break;
/* no of elements given and we */
/* have generated for all of them */
if (!--lcnt) {
- /* if initializers left */
- if (iloop) {
- werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
- }
- break;
+ /* if initializers left */
+ if (iloop) {
+ werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
+ }
+ break;
}
}
size = ((SPEC_BLEN (lsym->etype) / 8) +
(SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
}
- i = (unsigned long)floatFromVal(val);
+ i = ulFromVal (val);
i <<= SPEC_BSTR (lsym->etype);
ival |= i;
if (! ( lsym->next &&
} while (1);
switch (size) {
case 1:
- pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
- break;
+ pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
+ break;
case 2:
- pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
- pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
+ pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
+ pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
break;
case 4: /* EEP: why is this db and not dw? */
- pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
- pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
- pic16_emitDB(BYTE_IN_LONG(ival, 2), ptype, p);
- pic16_emitDB(BYTE_IN_LONG(ival, 3), ptype, p);
+ pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
+ pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
+ pic16_emitDB(BYTE_IN_LONG(ival, 2), ptype, p);
+ pic16_emitDB(BYTE_IN_LONG(ival, 3), ptype, p);
break;
default:
- /* VR - only 1,2,4 size long can be handled???? Why? */
- fprintf(stderr, "%s:%d: unhandled case. Contact author.\n", __FILE__, __LINE__);
- assert(0);
+ /* VR - only 1,2,4 size long can be handled???? Why? */
+ fprintf(stderr, "%s:%d: unhandled case. Contact author.\n", __FILE__, __LINE__);
+ assert(0);
}
*sym = lsym;
*ilist = lilist;
}
-
+
/*-----------------------------------------------------------------*/
/* printIvalStruct - generates initial value for structures */
if (i == 1 && size >= 0 && size <= sizeof(long))
{
- unsigned long val = (unsigned long)floatFromVal(list2val(ilist));
+ unsigned long val = ulFromVal (list2val(ilist));
while (size--)
{
pic16_emitDB(val, ptype, p);
{
if (size == 1) /* This appears to be Z80 specific?? */
{
- pic16_emitDS(val->name, ptype, p);
+ pic16_emitDS(val->name, ptype, p);
}
else if (size == 2)
{
{
fprintf (stderr, "*** internal error: unknown size in "
"printIvalCharPtr.\n");
- assert(0);
+ assert(0);
}
}
else
switch (size)
{
case 1:
- pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
+ pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
break;
case 2:
- pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
- pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
+ pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
+ pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
break;
case 3:
- pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
- pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
- pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
+ pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
+ pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
+ pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
break;
default:
}
}
- if (val->sym && val->sym->isstrlit) { // && !isinSet(statsg->syms, val->sym)) {
- if(ptype == 'p' && !isinSet(statsg->syms, val->sym))addSet (&statsg->syms, val->sym);
- else if(ptype == 'f' /*&& !isinSet(rel_idataSymSet, val->sym)*/)addSet(&rel_idataSymSet, val->sym);
+ if (val->sym && val->sym->isstrlit) { // && !isinSet(statsg->syms, val->sym)) {
+ if(ptype == 'p' && !isinSet(statsg->syms, val->sym))addSet (&statsg->syms, val->sym);
+ else if(ptype == 'f' /*&& !isinSet(rel_idataSymSet, val->sym)*/)addSet(&rel_idataSymSet, val->sym);
}
return 1;
pic16_printGPointerType (val->sym->rname, DCL_TYPE(val->type), ptype, p);
if(IS_FUNC(val->sym->type) && !val->sym->used && !IS_STATIC(val->sym->etype)) {
-
+
if(!checkSym(publics, val->sym))
- if(checkAddSym(&externs, val->sym) && (ptype == 'f')) {
- /* this has not been declared as extern
- * so declare it as a 'late extern' just after the symbol */
- fprintf((FILE *)p, ";\tdeclare symbol as extern\n");
- fprintf((FILE *)p, "\textern\t%s\n", val->sym->rname);
- fprintf((FILE *)p, ";\tcontinue variable declaration\n");
+ if(checkAddSym(&externs, val->sym) && (ptype == 'f')) {
+ /* this has not been declared as extern
+ * so declare it as a 'late extern' just after the symbol */
+ fprintf((FILE *)p, ";\tdeclare symbol as extern\n");
+ fprintf((FILE *)p, "\textern\t%s\n", val->sym->rname);
+ fprintf((FILE *)p, ";\tcontinue variable declaration\n");
}
}
}
int size;
#if 0
- fprintf(stderr, "%s:%d initialising pointer: %s size: %d\n", __FILE__, __LINE__,
- sym->rname, getSize(sym->type));
+ fprintf(stderr, "%s:%d initialising pointer: %s size: %d\n", __FILE__, __LINE__,
+ sym->rname, getSize(sym->type));
#endif
/* if deep then */
switch (getSize (type))
{
case 1:
- pic16_emitDB((unsigned int)floatFromVal(val) & 0xff, ptype, p);
+ pic16_emitDB((unsigned int) ulFromVal (val) & 0xff, ptype, p);
break;
case 2:
pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
break;
default:
- fprintf(stderr, "%s:%d size = %d\n", __FILE__, __LINE__, getSize(type));
- assert(0);
+ fprintf(stderr, "%s:%d size = %d\n", __FILE__, __LINE__, getSize(type));
+ assert(0);
}
return;
}
pic16_printGPointerType (val->name, (IS_PTR(type)?DCL_TYPE(type):PTR_TYPE(SPEC_OCLS(sym->etype))),
ptype, p);
} else
- assert(0);
+ assert(0);
return;
}
void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
{
// sym_link *itype;
-
+
if (!p)
return;
#if 0
- fprintf(stderr, "%s:%d generating init for %s\n", __FILE__, __LINE__, sym->name);
- fprintf(stderr, "%s: IS_STRUCT: %d IS_ARRAY: %d IS_PTR: %d IS_SPEC: %d\n", sym->name,
- IS_STRUCT(type), IS_ARRAY(type), IS_PTR(type), IS_SPEC(type));
+ fprintf(stderr, "%s:%d generating init for %s\n", __FILE__, __LINE__, sym->name);
+ fprintf(stderr, "%s: IS_STRUCT: %d IS_ARRAY: %d IS_PTR: %d IS_SPEC: %d\n", sym->name,
+ IS_STRUCT(type), IS_ARRAY(type), IS_PTR(type), IS_SPEC(type));
#endif
-
+
/* if structure then */
if (IS_STRUCT (type))
{
{
//fprintf(stderr,"%s union\n",__FUNCTION__);
pic16_printIvalUnion (sym, type, ilist, ptype, p);
- } else {
+ } else {
//fprintf(stderr,"%s struct\n",__FUNCTION__);
pic16_printIvalStruct (sym, type, ilist, ptype, p);
}
/* if this is an array */
if (IS_ARRAY (type))
{
-// fprintf(stderr,"%s array\n",__FUNCTION__);
+// fprintf(stderr,"%s array\n",__FUNCTION__);
pic16_printIvalArray (sym, type, ilist, ptype, p);
return;
}
/* if type is SPECIFIER */
if (IS_SPEC (type))
{
-// fprintf(stderr,"%s spec\n",__FUNCTION__);
+// fprintf(stderr,"%s spec\n",__FUNCTION__);
pic16_printIvalType (sym, type, ilist, ptype, p);
return;
}
{
#if 0
- fprintf(stderr, "%s\t%s: sym: %s\tused: %d\tSPEC_ABSA: %d\tSPEC_AGGREGATE: %d\tCODE: %d\n\
+ fprintf(stderr, "%s\t%s: sym: %s\tused: %d\tSPEC_ABSA: %d\tSPEC_AGGREGATE: %d\tCODE: %d\n\
CODESPACE: %d\tCONST: %d\tPTRCONST: %d\tSPEC_CONST: %d\n", __FUNCTION__,
- map->sname, sym->name, sym->used, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type),
- IS_CODE(sym->etype), IN_CODESPACE( SPEC_OCLS(sym->etype)), IS_CONSTANT(sym->etype),
- IS_PTR_CONST(sym->etype), SPEC_CONST(sym->etype));
- printTypeChain( sym->type, stderr );
- fprintf(stderr, "\n");
+ map->sname, sym->name, sym->used, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type),
+ IS_CODE(sym->etype), IN_CODESPACE( SPEC_OCLS(sym->etype)), IS_CONSTANT(sym->etype),
+ IS_PTR_CONST(sym->etype), SPEC_CONST(sym->etype));
+ printTypeChain( sym->type, stderr );
+ fprintf(stderr, "\n");
#endif
if(SPEC_ABSA(sym->etype) && PIC16_IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype))) {
- pic16_assignConfigWordValue(SPEC_ADDR(sym->etype),
- (int) floatFromVal(list2val(sym->ival)));
+ pic16_assignConfigWordValue(SPEC_ADDR(sym->etype),
+ (int) ulFromVal (list2val(sym->ival)));
- continue;
+ continue;
}
if(SPEC_ABSA(sym->etype) && PIC16_IS_IDLOC_ADDRESS(SPEC_ADDR(sym->etype))) {
- pic16_assignIdByteValue(SPEC_ADDR(sym->etype),
- (char) floatFromVal(list2val(sym->ival)));
+ pic16_assignIdByteValue(SPEC_ADDR(sym->etype),
+ (char) ulFromVal (list2val(sym->ival)));
- continue;
+ continue;
}
- /* if it is "extern" then do nothing */
- if (IS_EXTERN (sym->etype)/* && !SPEC_ABSA(sym->etype)*/) {
- checkAddSym(&externs, sym);
- continue;
- }
+ /* if it is "extern" then do nothing */
+ if (IS_EXTERN (sym->etype)/* && !SPEC_ABSA(sym->etype)*/) {
+ checkAddSym(&externs, sym);
+ continue;
+ }
- /* if it is not static add it to the public
- table */
- if (!IS_STATIC (sym->etype)) {
- /* do not emit if it is a config word declaration */
- checkAddSym(&publics, sym);
- }
+ /* if it is not static add it to the public
+ table */
+ if (!IS_STATIC (sym->etype)) {
+ /* do not emit if it is a config word declaration */
+ checkAddSym(&publics, sym);
+ }
/* print extra debug info if required */
if (options.debug || sym->level == 0) {
- /* NOTE to me - cdbFile may be null in which case,
- * the sym name will be printed to stdout. oh well */
- debugFile->writeSymbol(sym);
+ /* NOTE to me - cdbFile may be null in which case,
+ * the sym name will be printed to stdout. oh well */
+ debugFile->writeSymbol(sym);
}
-
+
/* if it has an absolute address */
if (SPEC_ABSA (sym->etype)) {
-// fprintf(stderr, "%s:%d spec_absa is true for symbol: %s\n",
-// __FILE__, __LINE__, sym->name);
-
- /* if it has an initial value */
- if (sym->ival)
- {
- pBlock *pb;
+// fprintf(stderr, "%s:%d spec_absa is true for symbol: %s\n",
+// __FILE__, __LINE__, sym->name);
+
+ /* if it has an initial value */
+ if (sym->ival)
+ {
+ pBlock *pb;
symbol *asym;
absSym *abSym;
pCode *pcf;
-
+
/* symbol has absolute address and initial value */
- noAlloc++;
- resolveIvalSym (sym->ival, sym->type);
- asym = newSymbol(sym->rname, 0);
- abSym = Safe_calloc(1, sizeof(absSym));
- strcpy(abSym->name, sym->rname);
- abSym->address = SPEC_ADDR( sym->etype );
- addSet(&absSymSet, abSym);
-
- pb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute Ival"));
- pic16_addpBlock(pb);
-
- pcf = pic16_newpCodeFunction(moduleName, asym->name);
- PCF(pcf)->absblock = 1;
-
- pic16_addpCode2pBlock(pb,pcf);
- pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
- //fprintf(stderr, "%s:%d [1] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
- pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
+ noAlloc++;
+ resolveIvalSym (sym->ival, sym->type);
+ asym = newSymbol(sym->rname, 0);
+ abSym = Safe_calloc(1, sizeof(absSym));
+ strcpy(abSym->name, sym->rname);
+ abSym->address = SPEC_ADDR( sym->etype );
+ addSet(&absSymSet, abSym);
+
+ pb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute Ival"));
+ pic16_addpBlock(pb);
+
+ pcf = pic16_newpCodeFunction(moduleName, asym->name);
+ PCF(pcf)->absblock = 1;
+
+ pic16_addpCode2pBlock(pb,pcf);
+ pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
+ //fprintf(stderr, "%s:%d [1] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
+ pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
pic16_flushDB('p', (void *)pb);
- pic16_addpCode2pBlock(pb, pic16_newpCodeFunction(NULL, NULL));
- noAlloc--;
- }
- else
- {
-
- /* symbol has absolute address but no initial value */
-
- /* allocate space */
- dbuf_printf (&code->oBuf, "%s:\n", sym->rname);
-
- /* special case for character strings */
- if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
- SPEC_CVAL (sym->etype).v_char) {
-
-// fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, sym->rname);
-
- pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
- } else {
- fprintf (stderr, "%s:%u(%s): do not know how to intialize symbol %s\n", __FILE__, __LINE__, __FUNCTION__, sym->rname);
- assert(0);
- }
- }
-
- } else {
-// fprintf(stderr, "%s:%d spec_absa is false for symbol: %s\n",
-// __FILE__, __LINE__, sym->name);
-
-
- /* if it has an initial value */
- if (sym->ival) {
- pBlock *pb;
-
- /* symbol doesn't have absolute address but has initial value */
- dbuf_printf (&code->oBuf, "%s:\n", sym->rname);
- noAlloc++;
- resolveIvalSym (sym->ival, sym->type);
-
- pb = pic16_newpCodeChain(NULL, 'P',pic16_newpCodeCharP("; Starting pCode block for Ival"));
- pic16_addpBlock(pb);
-
- if(!didcode) {
- /* make sure that 'code' directive is emitted before, once */
- pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir("code", NULL));
-
- didcode++;
- }
-
- pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
- //fprintf(stderr, "%s:%d [2] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
- pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
+ pic16_addpCode2pBlock(pb, pic16_newpCodeFunction(NULL, NULL));
+ noAlloc--;
+ }
+ else
+ {
+
+ /* symbol has absolute address but no initial value */
+
+ /* allocate space */
+ dbuf_printf (&code->oBuf, "%s:\n", sym->rname);
+
+ /* special case for character strings */
+ if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
+ SPEC_CVAL (sym->etype).v_char) {
+
+// fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, sym->rname);
+
+ pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
+ } else {
+ fprintf (stderr, "%s:%u(%s): do not know how to intialize symbol %s\n", __FILE__, __LINE__, __FUNCTION__, sym->rname);
+ assert(0);
+ }
+ }
+
+ } else {
+// fprintf(stderr, "%s:%d spec_absa is false for symbol: %s\n",
+// __FILE__, __LINE__, sym->name);
+
+
+ /* if it has an initial value */
+ if (sym->ival) {
+ pBlock *pb;
+
+ /* symbol doesn't have absolute address but has initial value */
+ dbuf_printf (&code->oBuf, "%s:\n", sym->rname);
+ noAlloc++;
+ resolveIvalSym (sym->ival, sym->type);
+
+ pb = pic16_newpCodeChain(NULL, 'P',pic16_newpCodeCharP("; Starting pCode block for Ival"));
+ pic16_addpBlock(pb);
+
+ if(!didcode) {
+ /* make sure that 'code' directive is emitted before, once */
+ pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir("code", NULL));
+
+ didcode++;
+ }
+
+ pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
+ //fprintf(stderr, "%s:%d [2] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
+ pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
pic16_flushDB('p', (void *)pb);
- noAlloc--;
- } else {
-
- /* symbol doesn't have absolute address and no initial value */
- /* allocate space */
-// fprintf(stderr, "%s:%d [3] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
- dbuf_printf (&code->oBuf, "%s:\n", sym->rname);
- /* special case for character strings */
- if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
- SPEC_CVAL (sym->etype).v_char) {
-
-// fprintf(stderr, "%s:%d printing code string for %s\n", __FILE__, __LINE__, sym->rname);
-
- pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
- } else {
- assert(0);
- }
- }
- }
+ noAlloc--;
+ } else {
+
+ /* symbol doesn't have absolute address and no initial value */
+ /* allocate space */
+// fprintf(stderr, "%s:%d [3] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
+ dbuf_printf (&code->oBuf, "%s:\n", sym->rname);
+ /* special case for character strings */
+ if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
+ SPEC_CVAL (sym->etype).v_char) {
+
+// fprintf(stderr, "%s:%d printing code string for %s\n", __FILE__, __LINE__, sym->rname);
+
+ pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
+ } else {
+ assert(0);
+ }
+ }
+ }
}
}
{
int i;
- for(i=0;i<=(pic16->cwInfo.confAddrEnd-pic16->cwInfo.confAddrStart);i++)
- if(pic16->cwInfo.crInfo[i].emit) //mask != -1)
- fprintf (of, "\t__config 0x%x, 0x%hhx\n",
- pic16->cwInfo.confAddrStart+i,
- pic16->cwInfo.crInfo[i].value);
+ for(i=0;i<=(pic16->cwInfo.confAddrEnd-pic16->cwInfo.confAddrStart);i++)
+ if(pic16->cwInfo.crInfo[i].emit) //mask != -1)
+ fprintf (of, "\t__config 0x%x, 0x%hhx\n",
+ pic16->cwInfo.confAddrStart+i,
+ pic16->cwInfo.crInfo[i].value);
}
void pic16_emitIDRegs(FILE *of)
{
int i;
- for(i=0;i<=(pic16->idInfo.idAddrEnd-pic16->idInfo.idAddrStart);i++)
- if(pic16->idInfo.irInfo[i].emit)
- fprintf (of, "\t__idlocs 0x%06x, 0x%hhx\n",
- pic16->idInfo.idAddrStart+i,
- pic16->idInfo.irInfo[i].value);
+ for(i=0;i<=(pic16->idInfo.idAddrEnd-pic16->idInfo.idAddrStart);i++)
+ if(pic16->idInfo.irInfo[i].emit)
+ fprintf (of, "\t__idlocs 0x%06x, 0x%hhx\n",
+ pic16->idInfo.idAddrStart+i,
+ pic16->idInfo.irInfo[i].value);
}
static void
pic16createInterruptVect (struct dbuf_s * vBuf)
{
- /* if the main is only a prototype ie. no body then do nothing */
+ /* if the main is only a prototype ie. no body then do nothing */
#if 0
- if (!IFFUNC_HASBODY(mainf->type)) {
- /* if ! compile only then main function should be present */
- if (!options.cc_only)
- werror (E_NO_MAIN);
- return;
- }
+ if (!IFFUNC_HASBODY(mainf->type)) {
+ /* if ! compile only then main function should be present */
+ if (!options.cc_only)
+ werror (E_NO_MAIN);
+ return;
+ }
#endif
#if 0
- if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
- dbuf_printf (vBuf, ";\t.area\t%s\n", CODE_NAME);
- dbuf_printf (vBuf, ".intvecs\tcode\t0x%06x\n", pic16_options.ivt_loc);
-
- /* this is an overkill since WE are the port,
- * and we know if we have a genIVT function! */
- if(port->genIVT) {
- port->genIVT(vFile, interrupts, maxInterrupts);
- }
- }
+ if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
+ dbuf_printf (vBuf, ";\t.area\t%s\n", CODE_NAME);
+ dbuf_printf (vBuf, ".intvecs\tcode\t0x%06x\n", pic16_options.ivt_loc);
+
+ /* this is an overkill since WE are the port,
+ * and we know if we have a genIVT function! */
+ if(port->genIVT) {
+ port->genIVT(vFile, interrupts, maxInterrupts);
+ }
+ }
#endif
-
+
}
static void
pic16initialComments (FILE * afile)
{
- initialComments (afile);
- fprintf (afile, "; PIC16 port for the Microchip 16-bit core micros\n");
- if(xinst)
- fprintf (afile, "; * Extended Instruction Set\n");
-
- if(pic16_mplab_comp)
- fprintf(afile, "; * MPLAB/MPASM/MPASMWIN/MPLINK compatibility mode enabled\n");
- fprintf (afile, iComments2);
-
- if(options.debug) {
- fprintf (afile, "\n\t.ident \"SDCC version %s #%s [pic16 port]%s\"\n",
- SDCC_VERSION_STR, getBuildNumber(), (!xinst?"":" {extended}") );
- }
+ initialComments (afile);
+ fprintf (afile, "; PIC16 port for the Microchip 16-bit core micros\n");
+ if(xinst)
+ fprintf (afile, "; * Extended Instruction Set\n");
+
+ if(pic16_mplab_comp)
+ fprintf(afile, "; * MPLAB/MPASM/MPASMWIN/MPLINK compatibility mode enabled\n");
+ fprintf (afile, iComments2);
+
+ if(options.debug) {
+ fprintf (afile, "\n\t.ident \"SDCC version %s #%s [pic16 port]%s\"\n",
+ SDCC_VERSION_STR, getBuildNumber(), (!xinst?"":" {extended}") );
+ }
}
int
{
symbol *sym;
- fprintf (afile, "\n%s", iComments2);
- fprintf (afile, "; public variables in this module\n");
- fprintf (afile, "%s", iComments2);
+ fprintf (afile, "\n%s", iComments2);
+ fprintf (afile, "; public variables in this module\n");
+ fprintf (afile, "%s", iComments2);
- for(sym = setFirstItem (publics); sym; sym = setNextItem (publics))
- /* sanity check */
- if(!IS_STATIC(sym->etype))
- pic16_emitSymbolIfNew(afile, "\tglobal %s\n", sym->rname, 0);
+ for(sym = setFirstItem (publics); sym; sym = setNextItem (publics))
+ /* sanity check */
+ if(!IS_STATIC(sym->etype))
+ pic16_emitSymbolIfNew(afile, "\tglobal %s\n", sym->rname, 0);
}
/*-----------------------------------------------------------------*/
{
symbol *sym;
- /* print nothing if no externs to declare */
- if(!elementsInSet(externs) && !elementsInSet(pic16_builtin_functions))
- return;
+ /* print nothing if no externs to declare */
+ if(!elementsInSet(externs) && !elementsInSet(pic16_builtin_functions))
+ return;
+
+ fprintf(afile, "\n%s", iComments2);
+ fprintf(afile, "; extern variables in this module\n");
+ fprintf(afile, "%s", iComments2);
- fprintf(afile, "\n%s", iComments2);
- fprintf(afile, "; extern variables in this module\n");
- fprintf(afile, "%s", iComments2);
-
- for(sym = setFirstItem(externs); sym; sym = setNextItem(externs))
- pic16_emitSymbolIfNew(afile, "\textern %s\n", sym->rname, 1);
+ for(sym = setFirstItem(externs); sym; sym = setNextItem(externs))
+ pic16_emitSymbolIfNew(afile, "\textern %s\n", sym->rname, 1);
- for(sym = setFirstItem(pic16_builtin_functions); sym; sym = setNextItem(pic16_builtin_functions))
- pic16_emitSymbolIfNew(afile, "\textern _%s\n", sym->name, 1);
+ for(sym = setFirstItem(pic16_builtin_functions); sym; sym = setNextItem(pic16_builtin_functions))
+ pic16_emitSymbolIfNew(afile, "\textern _%s\n", sym->name, 1);
}
/*-----------------------------------------------------------------*/
symbol *sym;
if (elementsInSet (ovrset))
- {
- /* this dummy area is used to fool the assembler
- otherwise the assembler will append each of these
- declarations into one chunk and will not overlay
- sad but true */
- dbuf_printf (aBuf, ";\t.area _DUMMY\n");
- /* output the area informtion */
- dbuf_printf (aBuf, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
- }
+ {
+ /* this dummy area is used to fool the assembler
+ otherwise the assembler will append each of these
+ declarations into one chunk and will not overlay
+ sad but true */
+ dbuf_printf (aBuf, ";\t.area _DUMMY\n");
+ /* output the area informtion */
+ dbuf_printf (aBuf, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
+ }
for (sym = setFirstItem (ovrset); sym;
- sym = setNextItem (ovrset))
- {
-
- /* if extern then do nothing */
- if (IS_EXTERN (sym->etype))
- continue;
-
- /* if allocation required check is needed
- then check if the symbol really requires
- allocation only for local variables */
- if (!IS_AGGREGATE (sym->type) &&
- !(sym->_isparm && !IS_REGPARM (sym->etype))
- && !sym->allocreq && sym->level)
- continue;
-
- /* if global variable & not static or extern
- and addPublics allowed then add it to the public set */
- if ((sym->_isparm && !IS_REGPARM (sym->etype))
- && !IS_STATIC (sym->etype)) {
-// fprintf(stderr, "%s:%d %s accessed\n", __FILE__, __LINE__, __FUNCTION__);
- checkAddSym(&publics, sym);
-// addSetHead (&publics, sym);
- }
-
- /* if extern then do nothing or is a function
- then do nothing */
- if (IS_FUNC (sym->type))
- continue;
-
-
- /* if is has an absolute address then generate
- an equate for this no need to allocate space */
- if (SPEC_ABSA (sym->etype))
- {
-
- if (options.debug || sym->level == 0)
- dbuf_printf (aBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
-
- dbuf_printf (aBuf, "%s\t=\t0x%04x\n",
- sym->rname,
- SPEC_ADDR (sym->etype));
- }
- else
- {
- if (options.debug || sym->level == 0)
- dbuf_printf (aBuf, "==.\n");
-
- /* allocate space */
- dbuf_printf (aBuf, "%s:\n", sym->rname);
- dbuf_printf (aBuf, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
- }
-
- }
+ sym = setNextItem (ovrset))
+ {
+
+ /* if extern then do nothing */
+ if (IS_EXTERN (sym->etype))
+ continue;
+
+ /* if allocation required check is needed
+ then check if the symbol really requires
+ allocation only for local variables */
+ if (!IS_AGGREGATE (sym->type) &&
+ !(sym->_isparm && !IS_REGPARM (sym->etype))
+ && !sym->allocreq && sym->level)
+ continue;
+
+ /* if global variable & not static or extern
+ and addPublics allowed then add it to the public set */
+ if ((sym->_isparm && !IS_REGPARM (sym->etype))
+ && !IS_STATIC (sym->etype)) {
+// fprintf(stderr, "%s:%d %s accessed\n", __FILE__, __LINE__, __FUNCTION__);
+ checkAddSym(&publics, sym);
+// addSetHead (&publics, sym);
+ }
+
+ /* if extern then do nothing or is a function
+ then do nothing */
+ if (IS_FUNC (sym->type))
+ continue;
+
+
+ /* if is has an absolute address then generate
+ an equate for this no need to allocate space */
+ if (SPEC_ABSA (sym->etype))
+ {
+
+ if (options.debug || sym->level == 0)
+ dbuf_printf (aBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
+
+ dbuf_printf (aBuf, "%s\t=\t0x%04x\n",
+ sym->rname,
+ SPEC_ADDR (sym->etype));
+ }
+ else
+ {
+ if (options.debug || sym->level == 0)
+ dbuf_printf (aBuf, "==.\n");
+
+ /* allocate space */
+ dbuf_printf (aBuf, "%s:\n", sym->rname);
+ dbuf_printf (aBuf, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
+ }
+
+ }
}
}
ramsize = pic16 ? pic16->RAMsize : 0x200;
ramsize -= 256; /* ignore access bank and SFRs */
if (ramsize == 0) ramsize = 64; /* prevent division by zero (below) */
-
+
fprintf (asmFile, "\n\n; Statistics:\n");
fprintf (asmFile, "; code size:\t%5ld (0x%04lx) bytes (%5.2f%%)\n; \t%5ld (0x%04lx) words\n",
isize, isize, (isize*100.0)/(128UL << 10),
#if 1
if(pic16_options.dumpcalltree) {
FILE *cFile;
-
+
sprintf(buffer, dstFileName);
strcat(buffer, ".calltree");
cFile = fopen(buffer, "w");
werror (E_FILE_OPEN_ERR, buffer);
exit (1);
}
-
+
/* initial comments */
pic16initialComments (asmFile);
if(port->genAssemblerPreamble) {
port->genAssemblerPreamble(asmFile);
}
-
+
/* Put all variables into a cblock */
pic16_AnalyzeBanking();
if(pic16_options.opt_banksel > 1) {
pic16_OptimizeBanksel();
}
-
+
/* turn GOTOs into BRAs -- added by RN 2004-11-16 */
if(pic16_options.opt_flags & OF_OPTIMIZE_GOTO) {
pic16_OptimizeJumps();
/* print the extern variables to this module */
pic16_printExterns(asmFile);
-
+
pic16_writeUsedRegs(asmFile);
#if 0
}
#endif
-#if 0
+#if 0
/* no xdata in pic */
/* copy xtern ram data */
fprintf (asmFile, "%s", iComments2);
fprintf (asmFile, "%s", iComments2);
dbuf_write_and_destroy (&vBuf, asmFile);
}
-
+
/* copy global & static initialisations */
fprintf (asmFile, "\n%s", iComments2);
fprintf (asmFile, "; global & static initialisations\n");
fprintf (asmFile, "%s", iComments2);
-
+
if(pic16_debug_verbose)
fprintf(asmFile, "; A code from now on!\n");
-
+
pic16_copypCode(asmFile, 'A');
if(pic16_options.no_crt) {
if(pic16_debug_verbose)
fprintf(asmFile, "; dbName from now on!\n");
-
+
pic16_copypCode(asmFile, statsg->dbName);
if(pic16_options.no_crt) {
fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
}
}
-
+
if(pic16_debug_verbose)
fprintf(asmFile, "; X code from now on!\n");
pic16_copypCode(asmFile, 'M');
pic16_copypCode(asmFile, code->dbName);
-
+
pic16_copypCode(asmFile, 'P');
emitStatistics(asmFile);
/* also allow literals [-128..256) for left/right operands */
if (IS_VALOP(IC_LEFT(ic)))
{
- long l = (long)floatFromVal( OP_VALUE( IC_LEFT(ic) ) );
+ long l = (long) ulFromVal ( OP_VALUE( IC_LEFT(ic) ) );
sizeL = 4;
//printf( "%s: val(left) = %ld\n", __FUNCTION__, l );
if (l >= -128 && l < 256)
}
if (IS_VALOP( IC_RIGHT(ic) ))
{
- long l = (long)floatFromVal( OP_VALUE( IC_RIGHT(ic) ) );
+ long l = (long) ulFromVal ( OP_VALUE( IC_RIGHT(ic) ) );
sizeR = 4;
//printf( "%s: val(right) = %ld\n", __FUNCTION__, l );
if (l >= -128 && l < 256)
/* What about literals? */
if (IS_VALOP( IC_LEFT(ic) ))
{
- long l = (long)floatFromVal( OP_VALUE( IC_LEFT(ic) ) );
+ long l = (long) ulFromVal ( OP_VALUE( IC_LEFT(ic) ) );
sizeL = 4;
//printf( "%s: val(left) = %ld\n", __FUNCTION__, l );
if (l >= -128 && l < 256)
}
if (IS_VALOP( IC_RIGHT(ic) ))
{
- long l = (long)floatFromVal( OP_VALUE( IC_RIGHT(ic) ) );
+ long l = (long) ulFromVal ( OP_VALUE( IC_RIGHT(ic) ) );
sizeR = 4;
//printf( "%s: val(right) = %ld\n", __FUNCTION__, l );
if (l >= -128 && l < 256)
/* otherwise it is fairly simple */
if (!IS_FLOAT (val->type))
{
- unsigned long v = (unsigned long) floatFromVal (val);
+ unsigned long v = ulFromVal (val);
if (offset == 2)
{
emitDebug ("; genPlusIncr");
- icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
+ icount = (unsigned int) ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
/* If result is a pair */
if (resultId != PAIR_INVALID)
/* if the literal value of the right hand side
is greater than 4 then it is not worth it */
- if ((icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 2)
+ if ((icount = (unsigned int) ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 2)
return FALSE;
size = getDataSize (IC_RESULT (ic));
}
else
{
- lit = (unsigned long) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
+ lit = ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
lit = -(long) lit;
}
wassertl (AOP_TYPE (IC_RIGHT (ic)) == AOP_LIT, "Right must be a literal");
- val = (int)floatFromVal ( AOP (IC_RIGHT (ic))->aopu.aop_lit);
+ val = (int) ulFromVal ( AOP (IC_RIGHT (ic))->aopu.aop_lit);
// wassertl (val > 0, "Multiply must be positive");
wassertl (val != 1, "Can't multiply by 1");
{
if (AOP_TYPE (right) == AOP_LIT)
{
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+ lit = ulFromVal (AOP (right)->aopu.aop_lit);
/* optimize if(x < 0) or if(x >= 0) */
if (lit == 0L)
{
bool fDidXor = FALSE;
if (AOP_TYPE (left) == AOP_LIT)
{
- unsigned long lit = (unsigned long)
- floatFromVal (AOP (left)->aopu.aop_lit);
+ unsigned long lit = ulFromVal (AOP (left)->aopu.aop_lit);
emit2 ("ld %s,!immedbyte", _fTmp[0],
0x80 ^ (unsigned int) ((lit >> ((size - 1) * 8)) & 0x0FFL));
}
}
if (AOP_TYPE (right) == AOP_LIT)
{
- unsigned long lit = (unsigned long)
- floatFromVal (AOP (right)->aopu.aop_lit);
+ unsigned long lit = ulFromVal (AOP (right)->aopu.aop_lit);
emit2 ("ld %s,!immedbyte", _fTmp[1],
0x80 ^ (unsigned int) ((lit >> ((size - 1) * 8)) & 0x0FFL));
}
if (AOP_TYPE (right) == AOP_LIT)
{
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+ lit = ulFromVal (AOP (right)->aopu.aop_lit);
/* optimize if(x < 0) or if(x >= 0) */
if (lit == 0)
{
/* if the right side is a literal then anything goes */
if (AOP_TYPE (right) == AOP_LIT)
{
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+ lit = ulFromVal (AOP (right)->aopu.aop_lit);
if (lit == 0)
{
_moveA (aopGet (AOP (left), offset, FALSE));
left = tmp;
}
if (AOP_TYPE (right) == AOP_LIT)
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+ lit = ulFromVal (AOP (right)->aopu.aop_lit);
size = AOP_SIZE (result);
left = tmp;
}
if (AOP_TYPE (right) == AOP_LIT)
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+ lit = ulFromVal (AOP (right)->aopu.aop_lit);
size = AOP_SIZE (result);
left = tmp;
}
if (AOP_TYPE (right) == AOP_LIT)
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+ lit = ulFromVal (AOP (right)->aopu.aop_lit);
size = AOP_SIZE (result);
operand * result,
iCode * ic)
{
- int shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+ int shCount = (int) ulFromVal (AOP (right)->aopu.aop_lit);
int size;
freeAsmop (right, NULL, ic);
iCode * ic,
int sign)
{
- int shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+ int shCount = (int) ulFromVal (AOP (right)->aopu.aop_lit);
int size;
freeAsmop (right, NULL, ic);
{
/* Case with a bitfield length <8 and literal source
*/
- litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+ litval = (int) ulFromVal (AOP (right)->aopu.aop_lit);
litval <<= bstr;
litval &= (~mask) & 0xff;
emit2 ("ld a,!*pair", _pairs[pair].name);
{
/* Case with partial byte and literal source
*/
- litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+ litval = (int) ulFromVal (AOP (right)->aopu.aop_lit);
litval >>= (blen-rlen);
litval &= (~mask) & 0xff;
emit2 ("ld a,!*pair", _pairs[pair].name);
if (AOP_TYPE (right) == AOP_LIT)
{
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+ lit = ulFromVal (AOP (right)->aopu.aop_lit);
}
if (isPair (AOP (result)))
wassert (aop->type == AOP_LIT);
wassert (!IS_FLOAT (val->type));
- v = (unsigned long) floatFromVal (val);
+ v = ulFromVal (val);
if (xor)
v ^= 0x8000;
The stack frame is the common ix-bp style. Basically:
- ix+4+n: param 1
- ix+4: param 0
- ix+2: return address
- ix+0: calling functions ix
- ix-n: local varibles
- ...
- sp: end of local varibles
+ ix+4+n: param 1
+ ix+4: param 0
+ ix+2: return address
+ ix+0: calling functions ix
+ ix-n: local varibles
+ ...
+ sp: end of local varibles
There is currently no support for bit spaces or banked functions.
-
+
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2, or (at
hope that it will be useful, but WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
USA. In other words, you are welcome to use, share and improve
this program. You are forbidden to forbid anyone else to use,
share and improve what you give them. Help stamp out
- software-hoarding!
+ software-hoarding!
*/
#include "z80.h"
};
#if 1
-#define D(_a, _s) if (_a) { printf _s; fflush(stdout); }
+#define D(_a, _s) if (_a) { printf _s; fflush(stdout); }
#else
#define D(_a, _s)
#endif
-#define DISABLE_PACKREGSFORSUPPORT 1
-#define DISABLE_PACKREGSFORACCUSE 1
+#define DISABLE_PACKREGSFORSUPPORT 1
+#define DISABLE_PACKREGSFORACCUSE 1
extern void genZ80Code (iCode *);
'type' is not used on the z80 version. It was used to select
between pointer and general purpose registers on the mcs51 version.
- @return Pointer to the newly allocated register.
+ @return Pointer to the newly allocated register.
*/
static regs *
allocReg (short type)
{
/* For now we allocate from any free */
if (regsZ80[i].isFree)
- {
- regsZ80[i].isFree = 0;
- if (currFunc)
+ {
+ regsZ80[i].isFree = 0;
+ if (currFunc)
{
currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, i);
}
- D (D_ALLOC, ("allocReg: alloced %p\n", ®sZ80[i]));
- return ®sZ80[i];
- }
+ D (D_ALLOC, ("allocReg: alloced %p\n", ®sZ80[i]));
+ return ®sZ80[i];
+ }
}
D (D_ALLOC, ("allocReg: No free.\n"));
return NULL;
/** Frees a register.
*/
-static void
+static void
freeReg (regs * reg)
{
wassert (!reg->isFree);
/** Returns number of free registers.
*/
-static int
+static int
nFreeRegs (int type)
{
int i;
/** Free registers with type.
*/
-static int
+static int
nfreeRegsType (int type)
{
int nfr;
{
bitVect *spillable;
- /* spillable live ranges are those that are live at this
+ /* spillable live ranges are those that are live at this
point . the following categories need to be subtracted
- from this set.
+ from this set.
a) - those that are already spilt
b) - if being used by this one
c) - defined by this one */
spillable = bitVectCopy (ic->rlive);
spillable =
- bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
+ bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
spillable =
- bitVectCplAnd (spillable, ic->uses); /* used in this one */
+ bitVectCplAnd (spillable, ic->uses); /* used in this one */
bitVectUnSetBit (spillable, ic->defKey);
spillable = bitVectIntersect (spillable, _G.regAssigned);
/*-----------------------------------------------------------------*/
/* noSpilLoc - return true if a variable has no spil location */
/*-----------------------------------------------------------------*/
-static int
+static int
noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
{
return (sym->usl.spillLoc ? 0 : 1);
/*-----------------------------------------------------------------*/
/* hasSpilLoc - will return 1 if the symbol has spil location */
/*-----------------------------------------------------------------*/
-static int
+static int
hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
{
return (sym->usl.spillLoc ? 1 : 0);
into registers at creation as it can be re-created at any time -
i.e. it's constant in some way.
*/
-static int
+static int
rematable (symbol * sym, eBBlock * ebp, iCode * ic)
{
return sym->remat;
/*-----------------------------------------------------------------*/
/* allLRs - return true for all */
/*-----------------------------------------------------------------*/
-static int
+static int
allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
{
return 1;
}
-/** liveRangesWith - applies function to a given set of live range
+/** liveRangesWith - applies function to a given set of live range
*/
static set *
liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
- eBBlock * ebp, iCode * ic)
+ eBBlock * ebp, iCode * ic)
{
set *rset = NULL;
int i;
{
symbol *sym;
if (!bitVectBitValue (lrs, i))
- continue;
+ continue;
- /* if we don't find it in the live range
+ /* if we don't find it in the live range
hash table we are in serious trouble */
if (!(sym = hTabItemWithKey (liveRanges, i)))
- {
+ {
wassertl (0, "liveRangesWith could not find liveRange");
- exit (1);
- }
+ exit (1);
+ }
if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
{
}
-/** leastUsedLR - given a set determines which is the least used
+/** leastUsedLR - given a set determines which is the least used
*/
static symbol *
leastUsedLR (set * sset)
/* if usage is the same then prefer
the spill the smaller of the two */
if (lsym->used == sym->used)
- if (getSize (lsym->type) < getSize (sym->type))
- sym = lsym;
+ if (getSize (lsym->type) < getSize (sym->type))
+ sym = lsym;
/* if less usage */
if (lsym->used < sym->used)
- sym = lsym;
+ sym = lsym;
}
/** noOverLap - will iterate through the list looking for over lap
*/
-static int
+static int
noOverLap (set * itmpStack, symbol * fsym)
{
symbol *sym;
for (sym = setFirstItem (itmpStack); sym;
sym = setNextItem (itmpStack))
{
- if (bitVectBitValue(sym->clashes,fsym->key))
+ if (bitVectBitValue(sym->clashes,fsym->key))
return 0;
#if 0
// if sym starts before (or on) our end point
- // and ends after (or on) our start point,
+ // and ends after (or on) our start point,
// it is an overlap.
- if (sym->liveFrom <= fsym->liveTo &&
- sym->liveTo >= fsym->liveFrom)
- {
- return 0;
- }
+ if (sym->liveFrom <= fsym->liveTo &&
+ sym->liveTo >= fsym->liveFrom)
+ {
+ return 0;
+ }
#endif
}
return 1;
D (D_ALLOC, ("createStackSpil: for sym %p\n", sym));
- /* first go try and find a free one that is already
+ /* first go try and find a free one that is already
existing on the stack */
if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
{
allocLocal (sloc);
- sloc->isref = 1; /* to prevent compiler warning */
+ sloc->isref = 1; /* to prevent compiler warning */
/* if it is on the stack then update the stack */
if (IN_STACK (sloc->etype))
sym->usl.spillLoc = sloc;
sym->stackSpil = 1;
- /* add it to the set of itempStack set
+ /* add it to the set of itempStack set
of the spill location */
addSetHead (&sloc->usl.itmpStack, sym);
/*-----------------------------------------------------------------*/
/* spillThis - spils a specific operand */
/*-----------------------------------------------------------------*/
-static void
+static void
spillThis (symbol * sym)
{
int i;
for (i = 0; i < sym->nRegs; i++)
{
if (sym->regs[i])
- {
- freeReg (sym->regs[i]);
- sym->regs[i] = NULL;
- }
+ {
+ freeReg (sym->regs[i]);
+ sym->regs[i] = NULL;
+ }
}
if (sym->usl.spillLoc && !sym->remat)
iCode *ic;
if (bitVectBitValue (defs, i) &&
- (ic = hTabItemWithKey (iCodehTab, i)) &&
- (ic->seq >= fseq && ic->seq <= toseq))
+ (ic = hTabItemWithKey (iCodehTab, i)) &&
+ (ic->seq >= fseq && ic->seq <= toseq))
- return FALSE;
+ return FALSE;
}
notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
{
return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
- allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
+ allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
}
#endif
{
sym = leastUsedLR (selectS);
strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
- sym->usl.spillLoc->rname :
- sym->usl.spillLoc->name));
+ sym->usl.spillLoc->rname :
+ sym->usl.spillLoc->name));
sym->spildir = 1;
/* mark it as allocation required */
sym->usl.spillLoc->allocreq++;
/* check if there are any live ranges allocated
to registers that are not used in this block */
if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
- {
- sym = leastUsedLR (selectS);
- /* if this is not rematerializable */
- if (!sym->remat)
- {
- _G.blockSpil++;
+ {
+ sym = leastUsedLR (selectS);
+ /* if this is not rematerializable */
+ if (!sym->remat)
+ {
+ _G.blockSpil++;
wassertl (0, "Attempted to do an unsupported block spill");
- sym->blockSpil = 1;
- }
- return sym;
- }
+ sym->blockSpil = 1;
+ }
+ return sym;
+ }
/* check if there are any live ranges that not
used in the remainder of the block */
if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
- {
- sym = leastUsedLR (selectS);
- if (sym != forSym)
- {
- if (!sym->remat)
- {
+ {
+ sym = leastUsedLR (selectS);
+ if (sym != forSym)
+ {
+ if (!sym->remat)
+ {
wassertl (0, "Attempted to do an unsupported remain spill");
- sym->remainSpil = 1;
- _G.blockSpil++;
- }
- return sym;
- }
- }
+ sym->remainSpil = 1;
+ _G.blockSpil++;
+ }
+ return sym;
+ }
+ }
}
/* find live ranges with spillocation && not used as pointers */
if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
/** Spil some variable & mark registers as free.
A spill occurs when an iTemp wont fit into the available registers.
*/
-bool
+bool
spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
{
symbol *ssym;
wassertl (ssym->blockSpil == 0, "Encountered a sym with a block spill");
wassertl (ssym->remainSpil == 0, "Encountered a sym with a remain spill");
#if 0
- /* if spilt on stack then free up r0 & r1
+ /* if spilt on stack then free up r0 & r1
if they could have been assigned to as gprs */
if (!ptrRegReq && isSpiltOnStack (ssym))
{
spillLRWithPtrReg (ssym);
}
- /* if this was a block level spil then insert push & pop
+ /* if this was a block level spil then insert push & pop
at the start & end of block respectively */
if (ssym->blockSpil)
{
iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
/* add push to the start of the block */
addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
- ebp->sch->next : ebp->sch));
+ ebp->sch->next : ebp->sch));
nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
/* add pop to the end of the block */
addiCodeToeBBlock (ebp, nic, NULL);
D (D_ALLOC, ("getRegGpr: have to spill.\n"));
return NULL;
}
-
+
/* make sure partially assigned registers aren't reused */
for (j=0; j<=sym->nRegs; j++)
if (sym->regs[j])
sym->regs[j]->isFree = 0;
- /* this looks like an infinite loop but
+ /* this looks like an infinite loop but
in really selectSpil will abort */
goto tryAgain;
}
/** Symbol has a given register.
*/
-static bool
+static bool
symHasReg (symbol * sym, regs * reg)
{
int i;
}
/** Check the live to and if they have registers & are not spilt then
- free up the registers
+ free up the registers
*/
-static void
+static void
deassignLRs (iCode * ic, eBBlock * ebp)
{
symbol *sym;
symbol *psym = NULL;
/* if it does not end here */
if (sym->liveTo > ic->seq)
- continue;
+ continue;
- /* if it was spilt on stack then we can
+ /* if it was spilt on stack then we can
mark the stack spil location as free */
if (sym->isspilt)
- {
- if (sym->stackSpil)
- {
- sym->usl.spillLoc->isFree = 1;
- sym->stackSpil = 0;
- }
- continue;
- }
+ {
+ if (sym->stackSpil)
+ {
+ sym->usl.spillLoc->isFree = 1;
+ sym->stackSpil = 0;
+ }
+ continue;
+ }
if (!bitVectBitValue (_G.regAssigned, sym->key))
- continue;
+ continue;
/* special case check if this is an IFX &
- the privious one was a pop and the
+ the privious one was a pop and the
previous one was not spilt then keep track
of the symbol */
if (ic->op == IFX && ic->prev &&
- ic->prev->op == IPOP &&
- !ic->prev->parmPush &&
- !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
- psym = OP_SYMBOL (IC_LEFT (ic->prev));
+ ic->prev->op == IPOP &&
+ !ic->prev->parmPush &&
+ !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
+ psym = OP_SYMBOL (IC_LEFT (ic->prev));
D (D_ALLOC, ("deassignLRs: in loop on sym %p nregs %u\n", sym, sym->nRegs));
if (sym->nRegs)
- {
- int i = 0;
-
- bitVectUnSetBit (_G.regAssigned, sym->key);
-
- /* if the result of this one needs registers
- and does not have it then assign it right
- away */
- if (IC_RESULT (ic) &&
- !(SKIP_IC2 (ic) || /* not a special icode */
- ic->op == JUMPTABLE ||
- ic->op == IFX ||
- ic->op == IPUSH ||
- ic->op == IPOP ||
- ic->op == RETURN) &&
- (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
- result->liveTo > ic->seq && /* and will live beyond this */
- result->liveTo <= ebp->lSeq && /* does not go beyond this block */
- result->liveFrom == ic->seq && /* does not start before here */
- result->regType == sym->regType && /* same register types */
- result->nRegs && /* which needs registers */
- !result->isspilt && /* and does not already have them */
- !result->remat &&
- !bitVectBitValue (_G.regAssigned, result->key) &&
- /* the number of free regs + number of regs in this LR
- can accomodate the what result Needs */
- ((nfreeRegsType (result->regType) +
- sym->nRegs) >= result->nRegs)
- )
- {
- for (i = 0; i < result->nRegs; i++)
- {
- if (i < sym->nRegs)
- result->regs[i] = sym->regs[i];
- else
- result->regs[i] = getRegGpr (ic, ebp, result);
-
- /* if the allocation falied which means
- this was spilt then break */
- if (!result->regs[i])
- {
- wassert (0);
- assert (0);
- break;
- }
- }
-
- _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
- _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, result->key);
- }
-
- /* free the remaining */
- for (; i < sym->nRegs; i++)
- {
- if (psym)
- {
- if (!symHasReg (psym, sym->regs[i]))
- freeReg (sym->regs[i]);
- }
- else
- freeReg (sym->regs[i]);
- // sym->regs[i] = NULL;
- }
- }
+ {
+ int i = 0;
+
+ bitVectUnSetBit (_G.regAssigned, sym->key);
+
+ /* if the result of this one needs registers
+ and does not have it then assign it right
+ away */
+ if (IC_RESULT (ic) &&
+ !(SKIP_IC2 (ic) || /* not a special icode */
+ ic->op == JUMPTABLE ||
+ ic->op == IFX ||
+ ic->op == IPUSH ||
+ ic->op == IPOP ||
+ ic->op == RETURN) &&
+ (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
+ result->liveTo > ic->seq && /* and will live beyond this */
+ result->liveTo <= ebp->lSeq && /* does not go beyond this block */
+ result->liveFrom == ic->seq && /* does not start before here */
+ result->regType == sym->regType && /* same register types */
+ result->nRegs && /* which needs registers */
+ !result->isspilt && /* and does not already have them */
+ !result->remat &&
+ !bitVectBitValue (_G.regAssigned, result->key) &&
+ /* the number of free regs + number of regs in this LR
+ can accomodate the what result Needs */
+ ((nfreeRegsType (result->regType) +
+ sym->nRegs) >= result->nRegs)
+ )
+ {
+ for (i = 0; i < result->nRegs; i++)
+ {
+ if (i < sym->nRegs)
+ result->regs[i] = sym->regs[i];
+ else
+ result->regs[i] = getRegGpr (ic, ebp, result);
+
+ /* if the allocation falied which means
+ this was spilt then break */
+ if (!result->regs[i])
+ {
+ wassert (0);
+ assert (0);
+ break;
+ }
+ }
+
+ _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
+ _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, result->key);
+ }
+
+ /* free the remaining */
+ for (; i < sym->nRegs; i++)
+ {
+ if (psym)
+ {
+ if (!symHasReg (psym, sym->regs[i]))
+ freeReg (sym->regs[i]);
+ }
+ else
+ freeReg (sym->regs[i]);
+ // sym->regs[i] = NULL;
+ }
+ }
}
}
/** Reassign this to registers.
*/
-static void
+static void
reassignLR (operand * op)
{
symbol *sym = OP_SYMBOL (op);
/** Determines if allocating will cause a spill.
*/
-static int
+static int
willCauseSpill (int nr, int rt)
{
/* first check if there are any avlb registers
for (i = 0; i < count; i++)
{
for (j = 0; j < count; j++)
- {
- if (result->regs[i] == opsym->regs[j] && i != j)
- {
- shared = 1;
- goto xchgPositions;
- }
- }
+ {
+ if (result->regs[i] == opsym->regs[j] && i != j)
+ {
+ shared = 1;
+ goto xchgPositions;
+ }
+ }
}
xchgPositions:
if (shared)
/** Try to allocate a pair of registers to the symbol.
*/
-bool
+bool
tryAllocatingRegPair (symbol * sym)
{
int i;
for (i = 0; i < _G.nRegs; i += 2)
{
if ((regsZ80[i].isFree) && (regsZ80[i + 1].isFree))
- {
- regsZ80[i].isFree = 0;
- sym->regs[0] = ®sZ80[i];
- regsZ80[i + 1].isFree = 0;
- sym->regs[1] = ®sZ80[i + 1];
+ {
+ regsZ80[i].isFree = 0;
+ sym->regs[0] = ®sZ80[i];
+ regsZ80[i + 1].isFree = 0;
+ sym->regs[1] = ®sZ80[i + 1];
sym->regType = REG_PAIR;
- if (currFunc)
- {
- currFunc->regsUsed =
- bitVectSetBit (currFunc->regsUsed, i);
- currFunc->regsUsed =
- bitVectSetBit (currFunc->regsUsed, i + 1);
- }
- D (D_ALLOC, ("tryAllocRegPair: succeded for sym %p\n", sym));
- return TRUE;
- }
+ if (currFunc)
+ {
+ currFunc->regsUsed =
+ bitVectSetBit (currFunc->regsUsed, i);
+ currFunc->regsUsed =
+ bitVectSetBit (currFunc->regsUsed, i + 1);
+ }
+ D (D_ALLOC, ("tryAllocRegPair: succeded for sym %p\n", sym));
+ return TRUE;
+ }
}
D (D_ALLOC, ("tryAllocRegPair: failed on sym %p\n", sym));
return FALSE;
verifyRegsAssigned (operand *op, iCode * ic)
{
symbol * sym;
-
+
if (!op) return;
if (!IS_ITEMP (op)) return;
-
+
sym = OP_SYMBOL (op);
if (sym->isspilt) return;
if (!sym->nRegs) return;
if (sym->regs[0]) return;
-
- werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
- sym->prereqv ? sym->prereqv->name : sym->name);
+
+ werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
+ sym->prereqv ? sym->prereqv->name : sym->name);
spillThis (sym);
}
This is the main register allocation function. It is called after
packing.
*/
-static void
+static void
serialRegAssign (eBBlock ** ebbs, int count)
{
int i;
iCode *ic;
if (ebbs[i]->noPath &&
- (ebbs[i]->entryLabel != entryLabel &&
- ebbs[i]->entryLabel != returnLabel))
- continue;
+ (ebbs[i]->entryLabel != entryLabel &&
+ ebbs[i]->entryLabel != returnLabel))
+ continue;
/* of all instructions do */
for (ic = ebbs[i]->sch; ic; ic = ic->next)
- {
-
- /* if this is an ipop that means some live
- range will have to be assigned again */
- if (ic->op == IPOP)
- {
- wassert (0);
- reassignLR (IC_LEFT (ic));
- }
-
- /* if result is present && is a true symbol */
- if (IC_RESULT (ic) && ic->op != IFX &&
- IS_TRUE_SYMOP (IC_RESULT (ic)))
- OP_SYMBOL (IC_RESULT (ic))->allocreq++;
-
- /* take away registers from live
- ranges that end at this instruction */
- deassignLRs (ic, ebbs[i]);
-
- /* some don't need registers */
- /* MLH: removed RESULT and POINTER_SET condition */
- if (SKIP_IC2 (ic) ||
- ic->op == JUMPTABLE ||
- ic->op == IFX ||
- ic->op == IPUSH ||
- ic->op == IPOP)
- continue;
-
- /* now we need to allocate registers only for the result */
- if (IC_RESULT (ic))
- {
- symbol *sym = OP_SYMBOL (IC_RESULT (ic));
- bitVect *spillable;
- int willCS;
- int j;
-
- D (D_ALLOC, ("serialRegAssign: in loop on result %p\n", sym));
-
- /* Make sure any spill location is definately allocated */
- if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
- !sym->usl.spillLoc->allocreq)
- {
- sym->usl.spillLoc->allocreq++;
- }
-
- /* if it does not need or is spilt
- or is already assigned to registers
- or will not live beyond this instructions */
- if (!sym->nRegs ||
- sym->isspilt ||
- bitVectBitValue (_G.regAssigned, sym->key) ||
- sym->liveTo <= ic->seq)
- {
- D (D_ALLOC, ("serialRegAssign: wont live long enough.\n"));
- continue;
- }
-
- /* if some liverange has been spilt at the block level
- and this one live beyond this block then spil this
- to be safe */
- if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
- {
- D (D_ALLOC, ("serialRegAssign: \"spilling to be safe.\"\n"));
- spillThis (sym);
- continue;
- }
- /* if trying to allocate this will cause
- a spill and there is nothing to spill
- or this one is rematerializable then
- spill this one */
- willCS = willCauseSpill (sym->nRegs, sym->regType);
- spillable = computeSpillable (ic);
- if (sym->remat ||
- (willCS && bitVectIsZero (spillable)))
- {
-
- D (D_ALLOC, ("serialRegAssign: \"remat spill\"\n"));
- spillThis (sym);
- continue;
-
- }
-
- /* If the live range preceeds the point of definition
- then ideally we must take into account registers that
- have been allocated after sym->liveFrom but freed
- before ic->seq. This is complicated, so spill this
- symbol instead and let fillGaps handle the allocation. */
- if (sym->liveFrom < ic->seq)
- {
- spillThis (sym);
- continue;
- }
-
- /* if it has a spillocation & is used less than
- all other live ranges then spill this */
- if (willCS) {
- if (sym->usl.spillLoc) {
- symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
- allLRs, ebbs[i], ic));
- if (leastUsed && leastUsed->used > sym->used) {
- spillThis (sym);
- continue;
- }
- } else {
- /* if none of the liveRanges have a spillLocation then better
- to spill this one than anything else already assigned to registers */
- if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
- /* if this is local to this block then we might find a block spil */
- if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
- spillThis (sym);
- continue;
- }
- }
- }
- }
-
- /* else we assign registers to it */
- _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
- _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
-
- /* Special case: Try to fit into a reg pair if
- available */
- D (D_ALLOC, ("serialRegAssign: actually allocing regs!\n"));
- if ((sym->nRegs == 2) && tryAllocatingRegPair (sym))
- {
- }
- else
- {
- for (j = 0; j < sym->nRegs; j++)
- {
- sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
-
- /* if the allocation falied which means
- this was spilt then break */
- if (!sym->regs[j])
- {
- D (D_ALLOC, ("Couldnt alloc (spill)\n"))
- break;
- }
- }
- }
- /* if it shares registers with operands make sure
- that they are in the same position */
- if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
- OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
- positionRegs (OP_SYMBOL (IC_RESULT (ic)),
- OP_SYMBOL (IC_LEFT (ic)));
- /* do the same for the right operand */
- if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
- OP_SYMBOL (IC_RIGHT (ic))->nRegs)
- positionRegs (OP_SYMBOL (IC_RESULT (ic)),
- OP_SYMBOL (IC_RIGHT (ic)));
-
- }
- }
+ {
+
+ /* if this is an ipop that means some live
+ range will have to be assigned again */
+ if (ic->op == IPOP)
+ {
+ wassert (0);
+ reassignLR (IC_LEFT (ic));
+ }
+
+ /* if result is present && is a true symbol */
+ if (IC_RESULT (ic) && ic->op != IFX &&
+ IS_TRUE_SYMOP (IC_RESULT (ic)))
+ OP_SYMBOL (IC_RESULT (ic))->allocreq++;
+
+ /* take away registers from live
+ ranges that end at this instruction */
+ deassignLRs (ic, ebbs[i]);
+
+ /* some don't need registers */
+ /* MLH: removed RESULT and POINTER_SET condition */
+ if (SKIP_IC2 (ic) ||
+ ic->op == JUMPTABLE ||
+ ic->op == IFX ||
+ ic->op == IPUSH ||
+ ic->op == IPOP)
+ continue;
+
+ /* now we need to allocate registers only for the result */
+ if (IC_RESULT (ic))
+ {
+ symbol *sym = OP_SYMBOL (IC_RESULT (ic));
+ bitVect *spillable;
+ int willCS;
+ int j;
+
+ D (D_ALLOC, ("serialRegAssign: in loop on result %p\n", sym));
+
+ /* Make sure any spill location is definately allocated */
+ if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
+ !sym->usl.spillLoc->allocreq)
+ {
+ sym->usl.spillLoc->allocreq++;
+ }
+
+ /* if it does not need or is spilt
+ or is already assigned to registers
+ or will not live beyond this instructions */
+ if (!sym->nRegs ||
+ sym->isspilt ||
+ bitVectBitValue (_G.regAssigned, sym->key) ||
+ sym->liveTo <= ic->seq)
+ {
+ D (D_ALLOC, ("serialRegAssign: wont live long enough.\n"));
+ continue;
+ }
+
+ /* if some liverange has been spilt at the block level
+ and this one live beyond this block then spil this
+ to be safe */
+ if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
+ {
+ D (D_ALLOC, ("serialRegAssign: \"spilling to be safe.\"\n"));
+ spillThis (sym);
+ continue;
+ }
+ /* if trying to allocate this will cause
+ a spill and there is nothing to spill
+ or this one is rematerializable then
+ spill this one */
+ willCS = willCauseSpill (sym->nRegs, sym->regType);
+ spillable = computeSpillable (ic);
+ if (sym->remat ||
+ (willCS && bitVectIsZero (spillable)))
+ {
+
+ D (D_ALLOC, ("serialRegAssign: \"remat spill\"\n"));
+ spillThis (sym);
+ continue;
+
+ }
+
+ /* If the live range preceeds the point of definition
+ then ideally we must take into account registers that
+ have been allocated after sym->liveFrom but freed
+ before ic->seq. This is complicated, so spill this
+ symbol instead and let fillGaps handle the allocation. */
+ if (sym->liveFrom < ic->seq)
+ {
+ spillThis (sym);
+ continue;
+ }
+
+ /* if it has a spillocation & is used less than
+ all other live ranges then spill this */
+ if (willCS) {
+ if (sym->usl.spillLoc) {
+ symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
+ allLRs, ebbs[i], ic));
+ if (leastUsed && leastUsed->used > sym->used) {
+ spillThis (sym);
+ continue;
+ }
+ } else {
+ /* if none of the liveRanges have a spillLocation then better
+ to spill this one than anything else already assigned to registers */
+ if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
+ /* if this is local to this block then we might find a block spil */
+ if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
+ spillThis (sym);
+ continue;
+ }
+ }
+ }
+ }
+
+ /* else we assign registers to it */
+ _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
+ _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
+
+ /* Special case: Try to fit into a reg pair if
+ available */
+ D (D_ALLOC, ("serialRegAssign: actually allocing regs!\n"));
+ if ((sym->nRegs == 2) && tryAllocatingRegPair (sym))
+ {
+ }
+ else
+ {
+ for (j = 0; j < sym->nRegs; j++)
+ {
+ sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
+
+ /* if the allocation falied which means
+ this was spilt then break */
+ if (!sym->regs[j])
+ {
+ D (D_ALLOC, ("Couldnt alloc (spill)\n"))
+ break;
+ }
+ }
+ }
+ /* if it shares registers with operands make sure
+ that they are in the same position */
+ if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
+ OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
+ positionRegs (OP_SYMBOL (IC_RESULT (ic)),
+ OP_SYMBOL (IC_LEFT (ic)));
+ /* do the same for the right operand */
+ if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
+ OP_SYMBOL (IC_RIGHT (ic))->nRegs)
+ positionRegs (OP_SYMBOL (IC_RESULT (ic)),
+ OP_SYMBOL (IC_RIGHT (ic)));
+
+ }
+ }
}
/* Check for and fix any problems with uninitialized operands */
for (i = 0; i < count; i++)
{
- iCode *ic;
-
- if (ebbs[i]->noPath &&
- (ebbs[i]->entryLabel != entryLabel &&
- ebbs[i]->entryLabel != returnLabel))
- continue;
-
- for (ic = ebbs[i]->sch; ic; ic = ic->next)
- {
- if (SKIP_IC2 (ic))
- continue;
-
- if (ic->op == IFX)
- {
- verifyRegsAssigned (IC_COND (ic), ic);
- continue;
- }
-
- if (ic->op == JUMPTABLE)
- {
- verifyRegsAssigned (IC_JTCOND (ic), ic);
- continue;
- }
-
- verifyRegsAssigned (IC_RESULT (ic), ic);
- verifyRegsAssigned (IC_LEFT (ic), ic);
- verifyRegsAssigned (IC_RIGHT (ic), ic);
+ iCode *ic;
+
+ if (ebbs[i]->noPath &&
+ (ebbs[i]->entryLabel != entryLabel &&
+ ebbs[i]->entryLabel != returnLabel))
+ continue;
+
+ for (ic = ebbs[i]->sch; ic; ic = ic->next)
+ {
+ if (SKIP_IC2 (ic))
+ continue;
+
+ if (ic->op == IFX)
+ {
+ verifyRegsAssigned (IC_COND (ic), ic);
+ continue;
+ }
+
+ if (ic->op == JUMPTABLE)
+ {
+ verifyRegsAssigned (IC_JTCOND (ic), ic);
+ continue;
+ }
+
+ verifyRegsAssigned (IC_RESULT (ic), ic);
+ verifyRegsAssigned (IC_LEFT (ic), ic);
+ verifyRegsAssigned (IC_RIGHT (ic), ic);
}
- }
+ }
}
static void fillGaps()
{
symbol *sym =NULL;
- int key =0;
-
+ int key =0;
+
if (getenv("DISABLE_FILL_GAPS")) return;
-
+
/* look for livernages that was spilt by the allocator */
- for (sym = hTabFirstItem(liveRanges,&key) ; sym ;
- sym = hTabNextItem(liveRanges,&key)) {
-
- int i;
- int pdone = 0;
-
- if (!sym->spillA || !sym->clashes || sym->remat) continue ;
-
- /* find the liveRanges this one clashes with, that are
- still assigned to registers & mark the registers as used*/
- for ( i = 0 ; i < sym->clashes->size ; i ++) {
- int k;
- symbol *clr;
-
- if (bitVectBitValue(sym->clashes,i) == 0 || /* those that clash with this */
- bitVectBitValue(_G.totRegAssigned,i) == 0) /* and are still assigned to registers */
- continue ;
-
- clr = hTabItemWithKey(liveRanges,i);
- assert(clr);
-
- /* mark these registers as used */
- for (k = 0 ; k < clr->nRegs ; k++ )
- useReg(clr->regs[k]);
- }
-
- if (willCauseSpill(sym->nRegs,sym->regType)) {
- /* NOPE :( clear all registers & and continue */
- freeAllRegs();
- continue ;
- }
-
- /* THERE IS HOPE !!!! */
- for (i=0; i < sym->nRegs ; i++ ) {
- sym->regs[i] = getRegGprNoSpil ();
- }
-
- /* for all its definitions check if the registers
- allocated needs positioning NOTE: we can position
- only ONCE if more than One positioning required
- then give up */
- sym->isspilt = 0;
- for (i = 0 ; i < sym->defs->size ; i++ ) {
- if (bitVectBitValue(sym->defs,i)) {
- iCode *ic;
- if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
- if (SKIP_IC(ic)) continue;
- assert(isSymbolEqual(sym,OP_SYMBOL(IC_RESULT(ic)))); /* just making sure */
- /* if left is assigned to registers */
- if (IS_SYMOP(IC_LEFT(ic)) &&
- bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_LEFT(ic))->key)) {
- pdone += positionRegs(sym,OP_SYMBOL(IC_LEFT(ic)));
- }
- if (IS_SYMOP(IC_RIGHT(ic)) &&
- bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) {
- pdone += positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic)));
- }
- if (pdone > 1) break;
- }
- }
- for (i = 0 ; i < sym->uses->size ; i++ ) {
- if (bitVectBitValue(sym->uses,i)) {
- iCode *ic;
- if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
- if (SKIP_IC(ic)) continue;
- if (!IS_ASSIGN_ICODE(ic)) continue ;
-
- /* if result is assigned to registers */
- if (IS_SYMOP(IC_RESULT(ic)) &&
- bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RESULT(ic))->key)) {
- pdone += positionRegs(sym,OP_SYMBOL(IC_RESULT(ic)));
- }
- if (pdone > 1) break;
- }
- }
- /* had to position more than once GIVE UP */
- if (pdone > 1) {
- /* UNDO all the changes we made to try this */
- sym->isspilt = 1;
- for (i=0; i < sym->nRegs ; i++ ) {
- sym->regs[i] = NULL;
- }
- freeAllRegs();
- D(D_FILL_GAPS,("Fill Gap gave up due to positioning for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
- continue ;
- }
- D(D_FILL_GAPS,("FILLED GAP for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
- _G.totRegAssigned = bitVectSetBit(_G.totRegAssigned,sym->key);
- sym->isspilt = sym->spillA = 0 ;
- sym->usl.spillLoc->allocreq--;
- freeAllRegs();
+ for (sym = hTabFirstItem(liveRanges,&key) ; sym ;
+ sym = hTabNextItem(liveRanges,&key)) {
+
+ int i;
+ int pdone = 0;
+
+ if (!sym->spillA || !sym->clashes || sym->remat) continue ;
+
+ /* find the liveRanges this one clashes with, that are
+ still assigned to registers & mark the registers as used*/
+ for ( i = 0 ; i < sym->clashes->size ; i ++) {
+ int k;
+ symbol *clr;
+
+ if (bitVectBitValue(sym->clashes,i) == 0 || /* those that clash with this */
+ bitVectBitValue(_G.totRegAssigned,i) == 0) /* and are still assigned to registers */
+ continue ;
+
+ clr = hTabItemWithKey(liveRanges,i);
+ assert(clr);
+
+ /* mark these registers as used */
+ for (k = 0 ; k < clr->nRegs ; k++ )
+ useReg(clr->regs[k]);
+ }
+
+ if (willCauseSpill(sym->nRegs,sym->regType)) {
+ /* NOPE :( clear all registers & and continue */
+ freeAllRegs();
+ continue ;
+ }
+
+ /* THERE IS HOPE !!!! */
+ for (i=0; i < sym->nRegs ; i++ ) {
+ sym->regs[i] = getRegGprNoSpil ();
+ }
+
+ /* for all its definitions check if the registers
+ allocated needs positioning NOTE: we can position
+ only ONCE if more than One positioning required
+ then give up */
+ sym->isspilt = 0;
+ for (i = 0 ; i < sym->defs->size ; i++ ) {
+ if (bitVectBitValue(sym->defs,i)) {
+ iCode *ic;
+ if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
+ if (SKIP_IC(ic)) continue;
+ assert(isSymbolEqual(sym,OP_SYMBOL(IC_RESULT(ic)))); /* just making sure */
+ /* if left is assigned to registers */
+ if (IS_SYMOP(IC_LEFT(ic)) &&
+ bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_LEFT(ic))->key)) {
+ pdone += positionRegs(sym,OP_SYMBOL(IC_LEFT(ic)));
+ }
+ if (IS_SYMOP(IC_RIGHT(ic)) &&
+ bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) {
+ pdone += positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic)));
+ }
+ if (pdone > 1) break;
+ }
+ }
+ for (i = 0 ; i < sym->uses->size ; i++ ) {
+ if (bitVectBitValue(sym->uses,i)) {
+ iCode *ic;
+ if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
+ if (SKIP_IC(ic)) continue;
+ if (!IS_ASSIGN_ICODE(ic)) continue ;
+
+ /* if result is assigned to registers */
+ if (IS_SYMOP(IC_RESULT(ic)) &&
+ bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RESULT(ic))->key)) {
+ pdone += positionRegs(sym,OP_SYMBOL(IC_RESULT(ic)));
+ }
+ if (pdone > 1) break;
+ }
+ }
+ /* had to position more than once GIVE UP */
+ if (pdone > 1) {
+ /* UNDO all the changes we made to try this */
+ sym->isspilt = 1;
+ for (i=0; i < sym->nRegs ; i++ ) {
+ sym->regs[i] = NULL;
+ }
+ freeAllRegs();
+ D(D_FILL_GAPS,("Fill Gap gave up due to positioning for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
+ continue ;
+ }
+ D(D_FILL_GAPS,("FILLED GAP for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
+ _G.totRegAssigned = bitVectSetBit(_G.totRegAssigned,sym->key);
+ sym->isspilt = sym->spillA = 0 ;
+ sym->usl.spillLoc->allocreq--;
+ freeAllRegs();
}
}
if (ic->op == IFX)
{
rmask = bitVectUnion (rmask,
- rUmaskForOp (IC_COND (ic)));
+ rUmaskForOp (IC_COND (ic)));
goto ret;
}
if (ic->op == JUMPTABLE)
{
rmask = bitVectUnion (rmask,
- rUmaskForOp (IC_JTCOND (ic)));
+ rUmaskForOp (IC_JTCOND (ic)));
goto ret;
}
/* of all other cases */
if (IC_LEFT (ic))
rmask = bitVectUnion (rmask,
- rUmaskForOp (IC_LEFT (ic)));
+ rUmaskForOp (IC_LEFT (ic)));
if (IC_RIGHT (ic))
rmask = bitVectUnion (rmask,
- rUmaskForOp (IC_RIGHT (ic)));
+ rUmaskForOp (IC_RIGHT (ic)));
if (IC_RESULT (ic))
rmask = bitVectUnion (rmask,
- rUmaskForOp (IC_RESULT (ic)));
+ rUmaskForOp (IC_RESULT (ic)));
ret:
return rmask;
/** For each instruction will determine the regsUsed.
*/
-static void
+static void
createRegMask (eBBlock ** ebbs, int count)
{
int i;
iCode *ic;
if (ebbs[i]->noPath &&
- (ebbs[i]->entryLabel != entryLabel &&
- ebbs[i]->entryLabel != returnLabel))
- continue;
+ (ebbs[i]->entryLabel != entryLabel &&
+ ebbs[i]->entryLabel != returnLabel))
+ continue;
/* for all instructions */
for (ic = ebbs[i]->sch; ic; ic = ic->next)
- {
-
- int j;
-
- if (SKIP_IC2 (ic) || !ic->rlive)
- continue;
-
- /* first mark the registers used in this
- instruction */
- ic->rUsed = regsUsedIniCode (ic);
- _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
-
- /* now create the register mask for those
- registers that are in use : this is a
- super set of ic->rUsed */
- ic->rMask = newBitVect (_G.nRegs + 1);
-
- /* for all live Ranges alive at this point */
- for (j = 1; j < ic->rlive->size; j++)
- {
- symbol *sym;
- int k;
-
- /* if not alive then continue */
- if (!bitVectBitValue (ic->rlive, j))
- continue;
-
- /* find the live range we are interested in */
- if (!(sym = hTabItemWithKey (liveRanges, j)))
- {
- werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "createRegMask cannot find live range");
- exit (0);
- }
-
- /* if no register assigned to it */
- if (!sym->nRegs || sym->isspilt)
- continue;
-
- /* for all the registers allocated to it */
- for (k = 0; k < sym->nRegs; k++)
- if (sym->regs[k])
- ic->rMask =
- bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
- }
- }
+ {
+
+ int j;
+
+ if (SKIP_IC2 (ic) || !ic->rlive)
+ continue;
+
+ /* first mark the registers used in this
+ instruction */
+ ic->rUsed = regsUsedIniCode (ic);
+ _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
+
+ /* now create the register mask for those
+ registers that are in use : this is a
+ super set of ic->rUsed */
+ ic->rMask = newBitVect (_G.nRegs + 1);
+
+ /* for all live Ranges alive at this point */
+ for (j = 1; j < ic->rlive->size; j++)
+ {
+ symbol *sym;
+ int k;
+
+ /* if not alive then continue */
+ if (!bitVectBitValue (ic->rlive, j))
+ continue;
+
+ /* find the live range we are interested in */
+ if (!(sym = hTabItemWithKey (liveRanges, j)))
+ {
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "createRegMask cannot find live range");
+ exit (0);
+ }
+
+ /* if no register assigned to it */
+ if (!sym->nRegs || sym->isspilt)
+ continue;
+
+ /* for all the registers allocated to it */
+ for (k = 0; k < sym->nRegs; k++)
+ if (sym->regs[k])
+ ic->rMask =
+ bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
+ }
+ }
}
}
/* if minus adjust offset to right hand side */
if (ic->op == '-')
- {
+ {
offset -= (int) operandLitValue (IC_RIGHT (ic));
- ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
- continue;
- }
+ ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
+ continue;
+ }
/* cast then continue */
if (IS_CAST_ICODE(ic)) {
/*-----------------------------------------------------------------*/
/* regTypeNum - computes the type & number of registers required */
/*-----------------------------------------------------------------*/
-static void
+static void
regTypeNum (void)
{
symbol *sym;
/* if used zero times then no registers needed */
if ((sym->liveTo - sym->liveFrom) == 0)
- continue;
+ continue;
D (D_ALLOC, ("regTypeNum: loop on sym %p\n", sym));
/* if the live range is a temporary */
if (sym->isitmp)
- {
-
- /* if the type is marked as a conditional */
- if (sym->regType == REG_CND)
- continue;
-
- /* if used in return only then we don't
- need registers */
- if (sym->ruonly || sym->accuse)
- {
- if (IS_AGGREGATE (sym->type) || sym->isptr)
- sym->type = aggrToPtr (sym->type, FALSE);
- continue;
- }
-
- /* if not then we require registers */
- D (D_ALLOC, ("regTypeNum: isagg %u nRegs %u type %p\n", IS_AGGREGATE (sym->type) || sym->isptr, sym->nRegs, sym->type));
- sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
- getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
- getSize (sym->type));
- D (D_ALLOC, ("regTypeNum: setting nRegs of %s (%p) to %u\n", sym->name, sym, sym->nRegs));
-
- D (D_ALLOC, ("regTypeNum: setup to assign regs sym %p\n", sym));
-
- if (sym->nRegs > 4)
- {
- fprintf (stderr, "allocated more than 4 or 0 registers for type ");
- printTypeChain (sym->type, stderr);
- fprintf (stderr, "\n");
- }
-
- /* determine the type of register required */
- /* Always general purpose */
- sym->regType = REG_GPR;
-
- }
+ {
+
+ /* if the type is marked as a conditional */
+ if (sym->regType == REG_CND)
+ continue;
+
+ /* if used in return only then we don't
+ need registers */
+ if (sym->ruonly || sym->accuse)
+ {
+ if (IS_AGGREGATE (sym->type) || sym->isptr)
+ sym->type = aggrToPtr (sym->type, FALSE);
+ continue;
+ }
+
+ /* if not then we require registers */
+ D (D_ALLOC, ("regTypeNum: isagg %u nRegs %u type %p\n", IS_AGGREGATE (sym->type) || sym->isptr, sym->nRegs, sym->type));
+ sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
+ getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
+ getSize (sym->type));
+ D (D_ALLOC, ("regTypeNum: setting nRegs of %s (%p) to %u\n", sym->name, sym, sym->nRegs));
+
+ D (D_ALLOC, ("regTypeNum: setup to assign regs sym %p\n", sym));
+
+ if (sym->nRegs > 4)
+ {
+ fprintf (stderr, "allocated more than 4 or 0 registers for type ");
+ printTypeChain (sym->type, stderr);
+ fprintf (stderr, "\n");
+ }
+
+ /* determine the type of register required */
+ /* Always general purpose */
+ sym->regType = REG_GPR;
+
+ }
else
- {
- /* for the first run we don't provide */
- /* registers for true symbols we will */
- /* see how things go */
- D (D_ALLOC, ("regTypeNum: #2 setting num of %p to 0\n", sym));
- sym->nRegs = 0;
- }
+ {
+ /* for the first run we don't provide */
+ /* registers for true symbols we will */
+ /* see how things go */
+ D (D_ALLOC, ("regTypeNum: #2 setting num of %p to 0\n", sym));
+ sym->nRegs = 0;
+ }
}
}
/** Mark all registers as free.
*/
-static void
+static void
freeAllRegs ()
{
int i;
/** Register reduction for assignment.
*/
-static int
+static int
packRegsForAssign (iCode * ic, eBBlock * ebp)
{
iCode *dic, *sic;
return 0;
}
- /* find the definition of iTempNN scanning backwards if we find a
- a use of the true symbol in before we find the definition then
+ /* find the definition of iTempNN scanning backwards if we find a
+ a use of the true symbol in before we find the definition then
we cannot */
for (dic = ic->prev; dic; dic = dic->prev)
{
/* PENDING: Don't pack across function calls. */
if (dic->op == CALL || dic->op == PCALL)
- {
- dic = NULL;
- break;
- }
+ {
+ dic = NULL;
+ break;
+ }
if (SKIP_IC2 (dic))
- continue;
+ continue;
if (dic->op == IFX)
{
if (IS_SYMOP (IC_COND (dic)) &&
- (IC_COND (dic)->key == IC_RESULT (ic)->key ||
- IC_COND (dic)->key == IC_RIGHT (ic)->key))
- {
- dic = NULL;
- break;
- }
+ (IC_COND (dic)->key == IC_RESULT (ic)->key ||
+ IC_COND (dic)->key == IC_RIGHT (ic)->key))
+ {
+ dic = NULL;
+ break;
+ }
}
else
{
if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
- IS_OP_VOLATILE (IC_RESULT (dic)))
- {
- dic = NULL;
- break;
- }
+ IS_OP_VOLATILE (IC_RESULT (dic)))
+ {
+ dic = NULL;
+ break;
+ }
if (IS_SYMOP (IC_RESULT (dic)) &&
- IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
- {
- if (POINTER_SET (dic))
- dic = NULL;
+ IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
+ {
+ if (POINTER_SET (dic))
+ dic = NULL;
- break;
- }
+ break;
+ }
if (IS_SYMOP (IC_RIGHT (dic)) &&
- (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
- IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
- {
- dic = NULL;
- break;
- }
+ (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
+ IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
+ {
+ dic = NULL;
+ break;
+ }
if (IS_SYMOP (IC_LEFT (dic)) &&
- (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
- IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
- {
- dic = NULL;
- break;
- }
+ (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
+ IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
+ {
+ dic = NULL;
+ break;
+ }
if (IS_SYMOP (IC_RESULT (dic)) &&
- IC_RESULT (dic)->key == IC_RESULT (ic)->key)
- {
- dic = NULL;
- break;
- }
-
- }
+ IC_RESULT (dic)->key == IC_RESULT (ic)->key)
+ {
+ dic = NULL;
+ break;
+ }
+
+ }
}
if (!dic)
- return 0; /* did not find */
+ return 0; /* did not find */
/* if assignment then check that right is not a bit */
if (ASSIGNMENT (ic) && !POINTER_SET (ic))
/* the operation has only one symbol
operator then we can pack */
if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
- (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
- goto pack;
+ (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
+ goto pack;
if (!((IC_LEFT (dic) &&
- IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
- (IC_RIGHT (dic) &&
- IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
- return 0;
+ IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
+ (IC_RIGHT (dic) &&
+ IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
+ return 0;
}
pack:
/* found the definition */
{
OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
}
- /* delete from liverange table also
+ /* delete from liverange table also
delete from all the points inbetween and the new
one */
for (sic = dic; sic != ic; sic = sic->next)
{
bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
if (IS_ITEMP (IC_RESULT (dic)))
- bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
+ bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
}
remiCodeFromeBBlock (ebp, ic);
/* if definition by assignment */
if (dic->op == '=' &&
- !POINTER_SET (dic) &&
- IC_RESULT (dic)->key == op->key)
- /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
- {
+ !POINTER_SET (dic) &&
+ IC_RESULT (dic)->key == op->key)
+ /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
+ {
- /* we are interested only if defined in far space */
- /* or in stack space in case of + & - */
+ /* we are interested only if defined in far space */
+ /* or in stack space in case of + & - */
- /* if assigned to a non-symbol then return
- true */
- if (!IS_SYMOP (IC_RIGHT (dic)))
- break;
+ /* if assigned to a non-symbol then return
+ true */
+ if (!IS_SYMOP (IC_RIGHT (dic)))
+ break;
- /* if the symbol is in far space then
- we should not */
- if (isOperandInFarSpace (IC_RIGHT (dic)))
- return NULL;
+ /* if the symbol is in far space then
+ we should not */
+ if (isOperandInFarSpace (IC_RIGHT (dic)))
+ return NULL;
- /* for + & - operations make sure that
- if it is on the stack it is the same
- as one of the three operands */
- if ((ic->op == '+' || ic->op == '-') &&
- OP_SYMBOL (IC_RIGHT (dic))->onStack)
- {
+ /* for + & - operations make sure that
+ if it is on the stack it is the same
+ as one of the three operands */
+ if ((ic->op == '+' || ic->op == '-') &&
+ OP_SYMBOL (IC_RIGHT (dic))->onStack)
+ {
- if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
- IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
- IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
- return NULL;
- }
+ if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
+ IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
+ IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
+ return NULL;
+ }
- break;
+ break;
- }
+ }
/* if we find an usage then we cannot delete it */
if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
- return NULL;
+ return NULL;
if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
- return NULL;
+ return NULL;
if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
- return NULL;
+ return NULL;
}
/* now make sure that the right side of dic
iCode *sic = dic->next;
for (; sic != ic; sic = sic->next)
- if (IC_RESULT (sic) &&
- IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
- return NULL;
+ if (IC_RESULT (sic) &&
+ IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
+ return NULL;
}
return dic;
/*-----------------------------------------------------------------*/
/* packRegsForSupport :- reduce some registers for support calls */
/*-----------------------------------------------------------------*/
-static int
+static int
packRegsForSupport (iCode * ic, eBBlock * ebp)
{
int change = 0;
iCode *sic;
if (!dic)
- goto right;
+ goto right;
/* found it we need to remove it from the
block */
for (sic = dic; sic != ic; sic = sic->next)
- bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
+ bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
IC_LEFT (ic)->operand.symOperand =
- IC_RIGHT (dic)->operand.symOperand;
+ IC_RIGHT (dic)->operand.symOperand;
IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
remiCodeFromeBBlock (ebp, dic);
bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
iCode *sic;
if (!dic)
- return change;
+ return change;
/* found it we need to remove it from the block */
for (sic = dic; sic != ic; sic = sic->next)
- bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
+ bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
IC_RIGHT (ic)->operand.symOperand =
- IC_RIGHT (dic)->operand.symOperand;
+ IC_RIGHT (dic)->operand.symOperand;
IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
remiCodeFromeBBlock (ebp, dic);
ic->op != SEND)
return NULL;
- /* this routine will mark the a symbol as used in one
- instruction use only && if the defintion is local
+ /* this routine will mark the a symbol as used in one
+ instruction use only && if the defintion is local
(ie. within the basic block) && has only one definition &&
- that definiion is either a return value from a
+ that definiion is either a return value from a
function or does not contain any variables in
far space */
uses = bitVectCopy (OP_USES (op));
- bitVectUnSetBit (uses, ic->key); /* take away this iCode */
- if (!bitVectIsZero (uses)) /* has other uses */
+ bitVectUnSetBit (uses, ic->key); /* take away this iCode */
+ if (!bitVectIsZero (uses)) /* has other uses */
return NULL;
/* if it has only one defintion */
if (bitVectnBitsOn (OP_DEFS (op)) > 1)
- return NULL; /* has more than one definition */
+ return NULL; /* has more than one definition */
/* get the that definition */
if (!(dic =
- hTabItemWithKey (iCodehTab,
- bitVectFirstBit (OP_DEFS (op)))))
+ hTabItemWithKey (iCodehTab,
+ bitVectFirstBit (OP_DEFS (op)))))
return NULL;
/* found the definition now check if it is local */
if (dic->seq < ebp->fSeq ||
dic->seq > ebp->lSeq)
- return NULL; /* non-local */
+ return NULL; /* non-local */
/* now check if it is the return from a function call */
if (dic->op == CALL || dic->op == PCALL)
{
if (ic->op != SEND && ic->op != RETURN &&
- !POINTER_SET(ic) && !POINTER_GET(ic))
- {
- OP_SYMBOL (op)->ruonly = 1;
- return dic;
- }
+ !POINTER_SET(ic) && !POINTER_GET(ic))
+ {
+ OP_SYMBOL (op)->ruonly = 1;
+ return dic;
+ }
dic = dic->next;
}
{
/* if there is an intervening function call then no */
if (dic->op == CALL || dic->op == PCALL)
- return NULL;
+ return NULL;
/* if pointer set then make sure the pointer
is one byte */
if (POINTER_SET (dic))
- return NULL;
+ return NULL;
if (POINTER_GET (dic))
- return NULL;
+ return NULL;
/* if address of & the result is remat the okay */
if (dic->op == ADDRESS_OF &&
- OP_SYMBOL (IC_RESULT (dic))->remat)
- continue;
+ OP_SYMBOL (IC_RESULT (dic))->remat)
+ continue;
/* if left or right or result is in far space */
if (isOperandInFarSpace (IC_LEFT (dic)) ||
- isOperandInFarSpace (IC_RIGHT (dic)) ||
- isOperandInFarSpace (IC_RESULT (dic)) ||
- IS_OP_RUONLY (IC_LEFT (dic)) ||
- IS_OP_RUONLY (IC_RIGHT (dic)) ||
- IS_OP_RUONLY (IC_RESULT (dic)))
- {
- return NULL;
- }
+ isOperandInFarSpace (IC_RIGHT (dic)) ||
+ isOperandInFarSpace (IC_RESULT (dic)) ||
+ IS_OP_RUONLY (IC_LEFT (dic)) ||
+ IS_OP_RUONLY (IC_RIGHT (dic)) ||
+ IS_OP_RUONLY (IC_RESULT (dic)))
+ {
+ return NULL;
+ }
}
OP_SYMBOL (op)->ruonly = 1;
/*-----------------------------------------------------------------*/
/* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
/*-----------------------------------------------------------------*/
-static bool
+static bool
isBitwiseOptimizable (iCode * ic)
{
sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
/* bitwise operations are considered optimizable
- under the following conditions (Jean-Louis VERN)
+ under the following conditions (Jean-Louis VERN)
x & lit
bit & bit
Certian assignments involving pointers can be temporarly stored
in HL. Esp.
genAssign
- ld iy,#_Blah
- ld bc,(iy)
+ ld iy,#_Blah
+ ld bc,(iy)
genAssign (ptr)
- ld hl,bc
- ld iy,#_Blah2
- ld (iy),(hl)
+ ld hl,bc
+ ld iy,#_Blah2
+ ld (iy),(hl)
*/
#if !DISABLE_PACKREGSFORACCUSE
When the result of this operation is small and short lived it may
be able to be stored in the accumelator.
*/
-static void
+static void
packRegsForAccUse (iCode * ic)
{
iCode *uic;
/* and the usage immediately follows this iCode */
if (!(uic = hTabItemWithKey (iCodehTab,
- bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
+ bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
return;
if (ic->next != uic)
return;
#if 0
- /* if the usage is not is an assignment or an
+ /* if the usage is not is an assignment or an
arithmetic / bitwise / shift operation then not */
if (POINTER_SET (uic) &&
getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
uic->op != RIGHT_OP)
return;
- /* if used in ^ operation then make sure right is not a
+ /* if used in ^ operation then make sure right is not a
literl */
if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
return;
}
#endif
-static void
+static void
packRegsForHLUse (iCode * ic)
{
iCode *uic;
/* and the usage immediately follows this iCode */
if (!(uic = hTabItemWithKey (iCodehTab,
- bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
+ bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
{
D (D_HLUSE, (" + Dropping as usage isn't in this block\n"));
return;
if (OP_SYMBOL(op)->remat)
{
- return NULL;
+ return NULL;
}
/* Only defined once */
/* first check if any overlapping liverange has already been
assigned to DPTR */
- if (OP_SYMBOL(op)->clashes)
+ if (OP_SYMBOL(op)->clashes)
{
- for (i = 0 ; i < OP_SYMBOL(op)->clashes->size ; i++ )
+ for (i = 0 ; i < OP_SYMBOL(op)->clashes->size ; i++ )
{
- if (bitVectBitValue(OP_SYMBOL(op)->clashes,i))
+ if (bitVectBitValue(OP_SYMBOL(op)->clashes,i))
{
sym = hTabItemWithKey(liveRanges,i);
if (sym->accuse == ACCUSE_SCRATCH)
dic = ic = hTabFirstItemWK(iCodeSeqhTab,OP_SYMBOL(op)->liveFrom);
for (; ic && ic->seq <= OP_SYMBOL(op)->liveTo;
- ic = hTabNextItem(iCodeSeqhTab, &key))
+ ic = hTabNextItem(iCodeSeqhTab, &key))
{
if (D_PACK_HLUSE3)
piCode(ic, NULL);
if (OP_SYMBOL(op)->remat)
{
- return NULL;
+ return NULL;
}
/* Only defined once */
/* first check if any overlapping liverange has already been
assigned to DPTR */
- if (OP_SYMBOL(op)->clashes)
+ if (OP_SYMBOL(op)->clashes)
{
- for (i = 0 ; i < OP_SYMBOL(op)->clashes->size ; i++ )
+ for (i = 0 ; i < OP_SYMBOL(op)->clashes->size ; i++ )
{
- if (bitVectBitValue(OP_SYMBOL(op)->clashes,i))
+ if (bitVectBitValue(OP_SYMBOL(op)->clashes,i))
{
sym = hTabItemWithKey(liveRanges,i);
if (sym->accuse == ACCUSE_IY)
uses = OP_USES(op);
for (; ic && ic->seq <= OP_SYMBOL(op)->liveTo;
- ic = hTabNextItem(iCodeSeqhTab,&key))
+ ic = hTabNextItem(iCodeSeqhTab,&key))
{
if (D_PACK_IY)
piCode(ic, NULL);
- if (ic->op == PCALL ||
+ if (ic->op == PCALL ||
ic->op == CALL ||
ic->op == JUMPTABLE
)
IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic)) ? isOperandInDirSpace(IC_RIGHT(ic)) : -1
));
- if (IC_RESULT(ic) && IS_SYMOP(IC_RESULT(ic)) &&
+ if (IC_RESULT(ic) && IS_SYMOP(IC_RESULT(ic)) &&
isOperandInDirSpace(IC_RESULT(ic)))
return NULL;
-
- if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic)) &&
+
+ if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic)) &&
isOperandInDirSpace(IC_RIGHT(ic)))
return NULL;
-
- if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic)) &&
+
+ if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic)) &&
isOperandInDirSpace(IC_LEFT(ic)))
return NULL;
/** Returns TRUE if this operation can use acc and if it preserves the value.
*/
-static bool
+static bool
opPreservesA (iCode * uic)
{
if (uic->op == IFX)
IS_ITEMP (IC_RESULT (uic)) &&
IS_OP_LITERAL (IC_RIGHT (uic)))
{
- unsigned int icount = (unsigned int) floatFromVal (IC_RIGHT (uic)->operand.valOperand);
+ unsigned int icount = (unsigned int) ulFromVal (IC_RIGHT (uic)->operand.valOperand);
/* Being an ITEMP means that we're already a symbol. */
if (icount == 1 &&
/* Some optimisation cases:
1. Part of memcpy
-; genPointerGet
- ld l,-4(ix)
- ld h,-3(ix)
- ld c,(hl)
-; genPlus
- inc -4(ix)
- jp nz,00108$
- inc -3(ix)
+; genPointerGet
+ ld l,-4(ix)
+ ld h,-3(ix)
+ ld c,(hl)
+; genPlus
+ inc -4(ix)
+ jp nz,00108$
+ inc -3(ix)
00108$:
-; genAssign (pointer)
- ld a,c
- ld (de),a
-
+; genAssign (pointer)
+ ld a,c
+ ld (de),a
+
want to optimise down to:
ld hl,-4(ix) ...
ld a,(hl)
genAssign (pointer) is OK
2. Part of _strcpy
-; genPointerGet
- ld a,(de)
- ld c,a
-; genIfx
- xor a,a
- or a,c
- jp z,00103$
-; _strcpy.c 40
-; genAssign (pointer)
-; AOP_STK for _strcpy_to_1_1
- ld l,-2(ix)
- ld h,-1(ix)
- ld (hl),c
+; genPointerGet
+ ld a,(de)
+ ld c,a
+; genIfx
+ xor a,a
+ or a,c
+ jp z,00103$
+; _strcpy.c 40
+; genAssign (pointer)
+; AOP_STK for _strcpy_to_1_1
+ ld l,-2(ix)
+ ld h,-1(ix)
+ ld (hl),c
want to optimise down to:
- ld a,(de)
- or a,a
- jp z,00103$
- ld (bc),a
-
+ ld a,(de)
+ or a,a
+ jp z,00103$
+ ld (bc),a
+
So genIfx where IC_COND has size of 1 and is a constant.
*/
Note that the 'A preserving' list is currently emperical :)
*/
-static void
+static void
packRegsForAccUse2 (iCode * ic)
{
iCode *uic;
*/
/* and the usage immediately follows this iCode */
if (!(uic = hTabItemWithKey (iCodehTab,
- bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
+ bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
{
D (D_ACCUSE2, (" + Dropping as usage does not follow first\n"));
return;
do
{
- setBit = bitVectFirstBit (uses);
- next = hTabItemWithKey (iCodehTab, setBit);
- if (scan->next == next)
- {
+ setBit = bitVectFirstBit (uses);
+ next = hTabItemWithKey (iCodehTab, setBit);
+ if (scan->next == next)
+ {
D (D_ACCUSE2_VERBOSE, (" ! Is next in line\n"));
- bitVectUnSetBit (uses, setBit);
- /* Still contigous. */
- if (!opPreservesA (next))
- {
+ bitVectUnSetBit (uses, setBit);
+ /* Still contigous. */
+ if (!opPreservesA (next))
+ {
D (D_ACCUSE2, (" + Dropping as operation doesn't preserve A\n"));
- return;
- }
+ return;
+ }
D (D_ACCUSE2_VERBOSE, (" ! Preserves A, so continue scanning\n"));
- scan = next;
- }
+ scan = next;
+ }
else if (scan->next == NULL && bitVectnBitsOn (uses) == 1 && next != NULL)
{
if (next->prev == NULL)
bitVectUnSetBit (uses, setBit);
scan = next;
}
- else
+ else
{
D (D_ACCUSE2, (" + Dropping as last in list and next doesn't start a block\n"));
return;
D (D_ACCUSE2, (" + Next in htab: %p\n", next));
return;
}
- else
- {
+ else
+ {
if (opIgnoresA (ic, scan->next))
{
/* Safe for now. */
D (D_ACCUSE2, (" + Dropping as parts are not consecuitive and intermediate might use A\n"));
return;
}
- }
+ }
}
while (!bitVectIsZero (uses));
/** Does some transformations to reduce register pressure.
*/
-static void
+static void
packRegisters (eBBlock * ebp)
{
iCode *ic;
/* .... */
/* TrueSym := iTempNN:1 */
for (ic = ebp->sch; ic; ic = ic->next)
- {
- /* find assignment of the form TrueSym := iTempNN:1 */
- if (ic->op == '=' && !POINTER_SET (ic))
- change += packRegsForAssign (ic, ebp);
- }
+ {
+ /* find assignment of the form TrueSym := iTempNN:1 */
+ if (ic->op == '=' && !POINTER_SET (ic))
+ change += packRegsForAssign (ic, ebp);
+ }
if (!change)
- break;
+ break;
}
for (ic = ebp->sch; ic; ic = ic->next)
{
/* Safe: address of a true sym is always constant. */
- /* if this is an itemp & result of a address of a true sym
+ /* if this is an itemp & result of a address of a true sym
then mark this as rematerialisable */
D (D_ALLOC, ("packRegisters: looping on ic %p\n", ic));
if (ic->op == ADDRESS_OF &&
- IS_ITEMP (IC_RESULT (ic)) &&
- IS_TRUE_SYMOP (IC_LEFT (ic)) &&
- bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
- !OP_SYMBOL (IC_LEFT (ic))->onStack)
- {
+ IS_ITEMP (IC_RESULT (ic)) &&
+ IS_TRUE_SYMOP (IC_LEFT (ic)) &&
+ bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
+ !OP_SYMBOL (IC_LEFT (ic))->onStack)
+ {
- OP_SYMBOL (IC_RESULT (ic))->remat = 1;
- OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
- OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
- }
+ OP_SYMBOL (IC_RESULT (ic))->remat = 1;
+ OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
+ OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
+ }
/* Safe: just propagates the remat flag */
/* if straight assignment then carry remat flag if this is the
only definition */
if (ic->op == '=' &&
- !POINTER_SET (ic) &&
- IS_SYMOP (IC_RIGHT (ic)) &&
- OP_SYMBOL (IC_RIGHT (ic))->remat &&
- bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
- {
-
- OP_SYMBOL (IC_RESULT (ic))->remat =
- OP_SYMBOL (IC_RIGHT (ic))->remat;
- OP_SYMBOL (IC_RESULT (ic))->rematiCode =
- OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
- }
+ !POINTER_SET (ic) &&
+ IS_SYMOP (IC_RIGHT (ic)) &&
+ OP_SYMBOL (IC_RIGHT (ic))->remat &&
+ bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
+ {
+
+ OP_SYMBOL (IC_RESULT (ic))->remat =
+ OP_SYMBOL (IC_RIGHT (ic))->remat;
+ OP_SYMBOL (IC_RESULT (ic))->rematiCode =
+ OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
+ }
/* if the condition of an if instruction is defined in the
previous instruction then mark the itemp as a conditional */
if ((IS_CONDITIONAL (ic) ||
- ((ic->op == BITWISEAND ||
- ic->op == '|' ||
- ic->op == '^') &&
- isBitwiseOptimizable (ic))) &&
- ic->next && ic->next->op == IFX &&
- bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
- isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
- OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
- {
-
- OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
- continue;
- }
+ ((ic->op == BITWISEAND ||
+ ic->op == '|' ||
+ ic->op == '^') &&
+ isBitwiseOptimizable (ic))) &&
+ ic->next && ic->next->op == IFX &&
+ bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 &&
+ isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
+ OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
+ {
+
+ OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
+ continue;
+ }
#if 0
/* reduce for support function calls */
if (ic->supportRtn || ic->op == '+' || ic->op == '-')
- packRegsForSupport (ic, ebp);
+ packRegsForSupport (ic, ebp);
#endif
/* some cases the redundant moves can
can be eliminated for return statements */
if (ic->op == RETURN || ic->op == SEND)
{
- packRegsForOneuse (ic, IC_LEFT (ic), ebp);
- }
+ packRegsForOneuse (ic, IC_LEFT (ic), ebp);
+ }
/* if pointer set & left has a size more than
one and right is not in far space */
POINTER_SET (ic) &&
/* MLH: no such thing.
!isOperandInFarSpace(IC_RIGHT(ic)) && */
- !OP_SYMBOL (IC_RESULT (ic))->remat &&
- !IS_OP_RUONLY (IC_RIGHT (ic)) &&
- getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
- {
+ !OP_SYMBOL (IC_RESULT (ic))->remat &&
+ !IS_OP_RUONLY (IC_RIGHT (ic)) &&
+ getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
+ {
- packRegsForOneuse (ic, IC_RESULT (ic), ebp);
- }
+ packRegsForOneuse (ic, IC_RESULT (ic), ebp);
+ }
/* if pointer get */
if (!DISABLE_PACK_ONE_USE &&
- POINTER_GET (ic) &&
- IS_SYMOP (IC_LEFT (ic)) &&
+ POINTER_GET (ic) &&
+ IS_SYMOP (IC_LEFT (ic)) &&
/* MLH: dont have far space
!isOperandInFarSpace(IC_RESULT(ic))&& */
- !OP_SYMBOL (IC_LEFT (ic))->remat &&
- !IS_OP_RUONLY (IC_RESULT (ic)) &&
- getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
- {
+ !OP_SYMBOL (IC_LEFT (ic))->remat &&
+ !IS_OP_RUONLY (IC_RESULT (ic)) &&
+ getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
+ {
- packRegsForOneuse (ic, IC_LEFT (ic), ebp);
- }
+ packRegsForOneuse (ic, IC_LEFT (ic), ebp);
+ }
/* pack registers for accumulator use, when the result of an
arithmetic or bit wise operation has only one use, that use is
result of this operation in acc:b combination */
if (!DISABLE_PACK_HL && IS_ITEMP (IC_RESULT (ic)))
- {
- /* PENDING */
+ {
+ /* PENDING */
if (IS_GB)
- {
- if (0)
- packRegsForHLUse (ic);
- }
+ {
+ if (0)
+ packRegsForHLUse (ic);
+ }
else
- {
- packRegsForHLUse3 (ic, IC_RESULT (ic), ebp);
- }
- }
+ {
+ packRegsForHLUse3 (ic, IC_RESULT (ic), ebp);
+ }
+ }
if (!DISABLE_PACK_IY && IS_ITEMP (IC_RESULT (ic)) && IS_Z80)
- {
+ {
packRegsForIYUse (ic, IC_RESULT (ic), ebp);
- }
+ }
if (!DISABLE_PACK_ACC && IS_ITEMP (IC_RESULT (ic)) &&
- getSize (operandType (IC_RESULT (ic))) == 1)
- {
- packRegsForAccUse2 (ic);
- }
+ getSize (operandType (IC_RESULT (ic))) == 1)
+ {
+ packRegsForAccUse2 (ic);
+ }
}
}
SPEC_NOUN (val->type) = V_INT;
IC_LEFT (ic) = operandFromOperand (IC_LEFT (ic));
IC_LEFT (ic)->operand.valOperand = val;
-
+
/* Now remove the second one from the list. */
ic->next = uic->next;
if (uic->next)
/*-----------------------------------------------------------------*/
/* assignRegisters - assigns registers to each live range as need */
/*-----------------------------------------------------------------*/
-void
+void
z80_assignRegisters (ebbIndex * ebbi)
{
eBBlock ** ebbs = ebbi->bbOrder;
D (D_ALLOC, ("\n-> z80_assignRegisters: entered.\n"));
setToNull ((void *) &_G.funcrUsed);
- setToNull ((void *) &_G.totRegAssigned);
+ setToNull ((void *) &_G.totRegAssigned);
_G.stackExtend = _G.dataExtend = 0;
if (IS_GB)
if (options.dump_pack)
dumpEbbsToFileExt (DUMP_PACK, ebbi);
- /* first determine for each live range the number of
+ /* first determine for each live range the number of
registers & the type of registers required for each */
regTypeNum ();