short debugLine;
short stackExtend;
short nRegsSaved;
+ short parmsPushed;
set *sendSet;
}
_G;
char *getStackOffset(int stack) {
static char gsoBuf[1024];
- sprintf (gsoBuf, "r7+(%d%+d%+d%+d)", stack,
- FUNC_ISISR(currFunc->type) ?
- port->stack.isr_overhead : port->stack.call_overhead,
+ sprintf (gsoBuf, "r7+(%d%+d%+d)", stack,
currFunc->stack, _G.nRegsSaved);
return gsoBuf;
}
}
}
-char *opRegName(operand *op, int offset, char *opName) {
+char *opRegName(operand *op, int offset, char *opName, bool decorate) {
if (IS_SYMOP(op)) {
if (OP_SYMBOL(op)->onStack) {
}
// fall through
case V_CHAR:
- sprintf (opName, "#0x%02x", SPEC_CVAL(OP_VALUE(op)->type).v_int);
+ sprintf (opName, "#%s0x%02x", decorate?"(char)":"",
+ SPEC_CVAL(OP_VALUE(op)->type).v_int);
break;
case V_INT:
if (SPEC_LONG(OP_VALUE(op)->type)) {
- sprintf (opName, "#0x%02lx", SPEC_CVAL(OP_VALUE(op)->type).v_long);
+ sprintf (opName, "#%s0x%02lx", decorate?"(long)":"",
+ SPEC_CVAL(OP_VALUE(op)->type).v_long);
} else {
- sprintf (opName, "#0x%02x", SPEC_CVAL(OP_VALUE(op)->type).v_int);
+ sprintf (opName, "#%s0x%02x", decorate?"(int)":"",
+ SPEC_CVAL(OP_VALUE(op)->type).v_int);
}
break;
case V_FLOAT:
- sprintf (opName, "#%f", SPEC_CVAL(OP_VALUE(op)->type).v_float);
+ sprintf (opName, "#%s%f", decorate?"(float)":"",
+ SPEC_CVAL(OP_VALUE(op)->type).v_float);
break;
default:
bailOut("opRegName: unexpected noun");
strcat (line, "unknown");
return line;
} else if (IS_VALOP(op)) {
- opRegName(op, 0, line);
+ opRegName(op, 0, line, 1);
} else if (IS_TYPOP(op)) {
- sprintf (line, "[");
+ sprintf (line, "(");
if (isPtr) {
if (DCL_TYPE(optype)==FPOINTER)
strcat (line, "far * ");
if (SPEC_USIGN(operandType(op))) strcat (line, "unsigned ");
if (SPEC_LONG(operandType(op))) strcat (line, "long ");
strcat (line, nounName(operandType(op)));
- strcat (line, "]");
+ strcat (line, ")");
} else {
bailOut("printOp: unexpected operand type");
}
}
/*-----------------------------------------------------------------*/
-/* genIpush - genrate code for pushing this gets a little complex */
+/* genIpush - generate code for pushing */
/*-----------------------------------------------------------------*/
static void genIpush (iCode * ic) {
+ operand *left=IC_LEFT(ic);
+
printIc ("genIpush", ic, 0,1,0);
+ aopOp(left,FALSE,FALSE);
+
+
+ if (AOP_TYPE(left)==AOP_LIT) {
+ switch (AOP_SIZE(left))
+ {
+ case 1:
+ emitcode ("mov", "r1l,%s", AOP_NAME(left)[0]);
+ emitcode ("push", "r1l");
+ _G.parmsPushed++;
+ return;
+ case 2:
+ emitcode ("mov", "r1,%s", AOP_NAME(left)[0]);
+ emitcode ("push", "r1");
+ _G.parmsPushed++;
+ return;
+ case 3:
+ emitcode ("mov", "r1l,%s", AOP_NAME(left)[1]);
+ emitcode ("push", "r1l");
+ emitcode ("mov", "r1,%s", AOP_NAME(left)[0]);
+ emitcode ("push", "r1");
+ _G.parmsPushed += 2;
+ return;
+ case 4:
+ emitcode ("mov", "r1,%s", AOP_NAME(left)[1]);
+ emitcode ("push", "r1");
+ emitcode ("mov", "r1,%s", AOP_NAME(left)[0]);
+ emitcode ("push", "r1");
+ _G.parmsPushed += 2;
+ return;
+ }
+ } else {
+ if (AOP_SIZE(left)>2) {
+ emitcode ("push", "%s", AOP_NAME(left)[1]);
+ _G.parmsPushed++;
+ }
+ emitcode ("push", "%s", AOP_NAME(left)[0]);
+ _G.parmsPushed++;
+ }
}
/*-----------------------------------------------------------------*/
/* genCall - generates a call statement */
/*-----------------------------------------------------------------*/
static void genCall (iCode * ic) {
- emitcode (";", "genCall %s result=%s", OP_SYMBOL(IC_LEFT(ic))->name,
+ operand *result=IC_RESULT(ic);
+
+ emitcode (";", "genCall(%d) %s result=%s", ic->lineno,
+ OP_SYMBOL(IC_LEFT(ic))->name,
printOp (IC_RESULT(ic)));
+ emitcode ("call", "%s", OP_SYMBOL(IC_LEFT(ic))->rname);
+
+ /* readjust the stack if we have pushed some parms */
+ if (_G.parmsPushed) {
+ emitcode ("add", "r7,#0x%02x", _G.parmsPushed*2);
+ _G.parmsPushed=0;
+ }
+
+ /* if we need to assign a result value */
+ if (IS_ITEMP (IC_RESULT(ic)) &&
+ OP_SYMBOL (IC_RESULT (ic))->nRegs) {
+ aopOp(result,FALSE,FALSE);
+ switch (AOP_SIZE(result))
+ {
+ case 1:
+ emitcode ("mov", "%s,r0l", AOP_NAME(result)[0]);
+ return;
+ case 2:
+ emitcode ("mov", "%s,r0", AOP_NAME(result)[0]);
+ return;
+ case 3:
+ // generic pointer
+ emitcode ("mov", "%s,r1l", AOP_NAME(result)[1]);
+ emitcode ("mov", "%s,r0", AOP_NAME(result)[0]);
+ return;
+ case 4:
+ emitcode ("mov", "%s,r1", AOP_NAME(result)[1]);
+ emitcode ("mov", "%s,r0", AOP_NAME(result)[0]);
+ return;
+ }
+ bailOut("genCall");
+ }
}
/*-----------------------------------------------------------------*/
case 4:
emitcode ("mov", "r1,%s", AOP_NAME(IC_LEFT(ic))[1]);
emitcode ("mov", "r0,%s", AOP_NAME(IC_LEFT(ic))[0]);
- return;
+ break;
case 3:
emitcode ("mov", "r1l,%s", AOP_NAME(IC_LEFT(ic))[1]);
// fall through
case 2:
emitcode ("mov", "r0,%s", AOP_NAME(IC_LEFT(ic))[0]);
- return;
+ break;
case 1:
emitcode ("mov", "r0l,%s", AOP_NAME(IC_LEFT(ic))[0]);
- return;
+ break;
+ default:
+ bailOut("genRet");
}
- bailOut("genRet");
+ emitcode ("jmp", "%05d$", returnLabel->key+100);
}
/*-----------------------------------------------------------------*/
if (IC_LABEL (ic) == entryLabel)
return;
- emitcode (";", "genLabel %s", IC_LABEL(ic)->name);
+ emitcode (";", "genLabel(%d) %s", ic->lineno, IC_LABEL(ic)->name);
emitcode ("", "%05d$:", (IC_LABEL (ic)->key + 100));
}
/* genGoto - generates a jmp */
/*-----------------------------------------------------------------*/
static void genGoto (iCode * ic) {
- emitcode (";", "genGoto %s", IC_LABEL(ic)->name);
+ emitcode (";", "genGoto(%d) %s", ic->lineno, IC_LABEL(ic)->name);
emitcode ("jmp", "%05d$", (IC_LABEL (ic)->key + 100));
}
while (lic) {
/* if operand of the form op = op + <sizeof *op> */
if (lic->op == '+') {
- fprintf (stderr, "isOperandEqual(IC_LEFT(lic),op):%d\n",
- isOperandEqual(IC_LEFT(lic),op));
- fprintf (stderr, "isOperandEqual(IC_RESULT(lic),op):%d\n",
- isOperandEqual(IC_RESULT(lic),op));
- fprintf (stderr, "isOperandLiteral(IC_RIGHT(lic)):%d\n",
- isOperandLiteral(IC_RIGHT(lic)));
- fprintf (stderr, "operandLitValue(IC_RIGHT(lic)) %f %d\n",
- operandLitValue(IC_RIGHT(lic)), isize);
if (isOperandEqual(IC_LEFT(lic),op) &&
//isOperandEqual(IC_RESULT(lic),op) &&
isOperandLiteral(IC_RIGHT(lic)) &&
symbol *tlbl1=newiTempLabel(NULL);
symbol *tlbl2=newiTempLabel(NULL);
emitcode ("cmp", "%s,#0x%02x", AOP_NAME(left)[1], CPOINTER);
- emitcode ("bne", "%05d$", tlbl1->key+100);
+ emitcode ("beq", "%05d$", tlbl1->key+100);
// far/near pointer
if (pi) {
emitcode ("mov", "%s,[%s+]", AOP_NAME(result)[0], AOP_NAME(left)[0]);
symbol *jlbl, *tlbl;
operand *cond=IC_COND(ic);
- emitcode (";", "genIfx cond=%s trueLabel:%s falseLabel:%s",
- printOp(cond),
+ emitcode (";", "genIfx(%d) cond=%s trueLabel:%s falseLabel:%s",
+ ic->lineno, printOp(cond),
IC_TRUE(ic) ? IC_TRUE(ic)->name : "NULL",
IC_FALSE(ic) ? IC_FALSE(ic)->name : "NULL");
switch (AOP_TYPE(cond) )
{
case AOP_BIT:
- emitcode (trueOrFalse ? "jb" : "jbc", "%s,%05d$",
+ emitcode (trueOrFalse ? "jb" : "jnb", "%s,%05d$",
AOP_NAME(cond)[0], jlbl->key+100);
return;
case AOP_REG:
/* genCast - gen code for casting */
/*-----------------------------------------------------------------*/
static void genCast (iCode * ic) {
+ int size;
+ operand *result=IC_RESULT(ic);
+ operand *right=IC_RIGHT(ic);
+ sym_link *ctype=operandType(IC_LEFT(ic));
+ sym_link *rtype=operandType(IC_RIGHT(ic));
+ sym_link *etype=getSpec(rtype);
+ short ptrType, signedness;
+
printIc ("genCast", ic, 1,1,1);
+
+ aopOp(result, TRUE, TRUE);
+ aopOp(right, !aopIsPtr(result), AOP_TYPE(result)!=AOP_DIR);
+ size=AOP_SIZE(result);
+
+ /* if result is a bit */
+ if (AOP_TYPE(result) == AOP_BIT) {
+ /* if right is literal, we know what the value is */
+ if (AOP_TYPE(right) == AOP_LIT) {
+ if (operandLitValue(right)) {
+ emitcode ("setb", AOP_NAME(result)[0]);
+ } else {
+ emitcode ("clr", AOP_NAME(result)[0]);
+ }
+ return;
+ }
+ /* if right is also a bit */
+ if (AOP_TYPE(right) == AOP_BIT) {
+ emitcode ("mov", "c,%s", AOP_NAME(right));
+ emitcode ("mov", "%s,c", AOP_NAME(result));
+ return;
+ }
+ /* we need to or */
+ emitcode ("mov", "%s,%s; toBoolean", AOP_NAME(result), toBoolean(right));
+ return;
+ }
+
+ /* if right is a bit */
+ if (AOP_TYPE(right)==AOP_BIT) {
+ emitcode ("mov", "c,%s", AOP_NAME(right));
+ emitcode ("mov", "%s,#0", AOP_NAME(result)[0]);
+ emitcode ("rlc", "%s,#1", AOP_NAME(result)[0]);
+ if (size>2) {
+ emitcode ("mov", "%s,#0", AOP_NAME(result)[1]);
+ }
+ return;
+ }
+
+ /* if the result is of type pointer */
+ if (IS_PTR (ctype)) {
+
+ if (AOP_SIZE(right)>1) {
+ emitcode ("mov", "%s,%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
+ } else {
+ emitcode ("mov", "r1l,%s", AOP_NAME(right)[0]);
+ emitcode ("sext", "r1h");
+ emitcode ("mov", "%s,r1", AOP_NAME(result)[0]);
+ }
+
+ /* if pointer to generic pointer */
+ if (IS_GENPTR (ctype)) {
+
+ if (IS_GENPTR (rtype)) {
+ bailOut("genCast: gptr -> gptr");
+ }
+
+ if (IS_PTR (rtype)) {
+ ptrType = DCL_TYPE (rtype);
+ } else {
+ /* we have to go by the storage class */
+ if (!SPEC_OCLS(etype)) {
+ bailOut("genCast: unknown storage class");
+ } else {
+ ptrType = PTR_TYPE (SPEC_OCLS (etype));
+ }
+ }
+
+ /* the generic part depends on the type */
+ switch (ptrType)
+ {
+ case POINTER:
+ emitcode ("mov", "%s,#0x00", AOP_NAME(result)[1]);
+ break;
+ case FPOINTER:
+ emitcode ("mov", "%s,#0x01", AOP_NAME(result)[1]);
+ break;
+ case CPOINTER:
+ emitcode ("mov", "%s,#0x02", AOP_NAME(result)[1]);
+ break;
+ default:
+ bailOut("genCast: got unknown storage class");
+ }
+ }
+ return;
+ }
+
+ /* do we have to sign extend? */
+ signedness = SPEC_USIGN(rtype);
+
+ /* now depending on the size */
+ switch ((AOP_SIZE(result)<<4) + AOP_SIZE(right))
+ {
+ case 0x44:
+ case 0x33:
+ emitcode("mov", "%s,%s", AOP_NAME(result)[1], AOP_NAME(right)[1]);
+ // fall through
+ case 0x24:
+ case 0x22:
+ case 0x11:
+ emitcode("mov", "%s,%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
+ return;
+ case 0x41:
+ case 0x21:
+ emitcode("mov", "r1l,%s", AOP_NAME(right)[0]);
+ if (signedness) {
+ emitcode("sext", "r1h");
+ } else {
+ emitcode("mov", "rlh,#0");
+ }
+ emitcode("mov", "%s,r1", AOP_NAME(result)[0]);
+ if (size==2)
+ return;
+ // fall through: case 0x41
+ emitcode("sext", AOP_NAME(result)[1]);
+ return;
+ case 14:
+ case 12:
+ emitcode("mov", "r1,%s", AOP_NAME(right)[0]);
+ emitcode("mov", "%s,r1l", AOP_NAME(result)[0]);
+ return;
+ case 24:
+ emitcode("mov", "%s,%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
+ return;
+ }
+ bailOut("genCast: unknown size");
}
+
/*-----------------------------------------------------------------*/
/* genDjnz - generate decrement & jump if not zero instrucion */
/*-----------------------------------------------------------------*/