{
short inLine;
short debugLine;
+ short stackExtend;
short nRegsSaved;
set *sendSet;
}
char *getStackOffset(int stack) {
static char gsoBuf[1024];
- sprintf (gsoBuf, "r7+(%d%+d%+d)", stack,
+ sprintf (gsoBuf, "r7+(%d%+d%+d%+d)", stack,
FUNC_ISISR(currFunc->type) ?
port->stack.isr_overhead : port->stack.call_overhead,
- _G.nRegsSaved);
+ currFunc->stack, _G.nRegsSaved);
return gsoBuf;
}
break;
case 4:
sprintf (aop->name[0], "#0x%04lx",
+ SPEC_CVAL(operandType(op)).v_ulong & 0xffff);
+ sprintf (aop->name[1], "#0x%04lx",
SPEC_CVAL(operandType(op)).v_ulong >> 16);
- sprintf (aop->name[1], "#0x%04x",
- SPEC_CVAL(operandType(op)).v_ulong && 0xffff);
break;
default:
bailOut("aopForVal");
/* toBoolean - return carry for operand!=0 */
/*-----------------------------------------------------------------*/
static char *toBoolean (operand * op) {
+ symbol *tlbl=newiTempLabel(NULL);
+
switch (AOP_SIZE(op))
{
case 1:
case 2:
- emitcode ("cmp", "%s,#0", AOP_NAME(op));
- emitcode ("mov", "c,z");
+ emitcode ("cjne", "%s,#1,%05d$; %s", AOP_NAME(op), tlbl->key+100,
+ "This needs a second thought");
+
+ emitcode ("", "%05d$:", tlbl->key+100);
return "c";
}
symbol *sym=OP_SYMBOL(IC_LEFT(ic));
sym_link *type=sym->type;
- emitcode (";", "-----------------------------------------");
- emitcode (";", " function %s", sym->name);
- emitcode (";", "-----------------------------------------");
-
+ emitcode (";", "genFunction %s", sym->rname);
+
+ /* print the allocation information */
+ printAllocInfo (currFunc, codeOutFile);
+
emitcode ("", "%s:", sym->rname);
if (IFFUNC_ISNAKED(type))
return;
}
- /* if critical function then turn interrupts off */
- if (IFFUNC_ISCRITICAL (type))
- emitcode ("clr", "ea");
-
+ /* adjust the stack for locals used in this function */
+ if (sym->stack) {
+ emitcode ("sub", "r7,#%d\t; create stack space for locals", sym->stack);
+ }
}
/*-----------------------------------------------------------------*/
{
symbol *sym = OP_SYMBOL (IC_LEFT (ic));
- if (IFFUNC_ISNAKED(sym->type))
- {
+ printIc ("genEndFunction", ic, 0,0,0);
+
+ if (IFFUNC_ISNAKED(sym->type)) {
emitcode(";", "naked function: no epilogue.");
return;
}
- printIc ("genEndFunction", ic, 0,0,0);
+ /* readjust the stock for locals used in this function */
+ if (sym->stack) {
+ emitcode ("add", "r7,#%d\t; release stack space for locals", sym->stack);
+ }
+
+ if (IFFUNC_ISISR(sym->type)) {
+ emitcode ("reti", "");
+ } else {
+ emitcode ("ret", "");
+ }
}
/*-----------------------------------------------------------------*/
/* genPlus - generates code for addition */
/*-----------------------------------------------------------------*/
static void genPlus (iCode * ic) {
+ operand *result=IC_RESULT(ic), *left=IC_LEFT(ic), *right=IC_RIGHT(ic);
+ int size;
+ char *instr;
+
printIc ("genPlus", ic, 1,1,1);
+
+ size=aopOp(result, TRUE, TRUE);
+
+ /* if left is a literal, then exchange them */
+ if (IS_LITERAL(operandType(left))) {
+ operand *tmp = right;
+ right = left;
+ left = tmp;
+ }
+
+ if (aopIsBit(result)) {
+ if (IS_LITERAL(operandType(right))) {
+ if (operandLitValue(right)) {
+ emitcode ("setb", AOP_NAME(result)[0]);
+ return;
+ }
+ aopOp(left, TRUE, TRUE);
+ emitcode ("mov", "%s,%s", AOP_NAME(result)[0], toBoolean(left));
+ return;
+ }
+ bailOut("genPlus: unfinished genPlus bit");
+ }
+
+ aopOp(left, !aopIsPtr(result), !aopIsDir(result));
+ aopOp(right, !aopIsPtr(result), !aopIsDir(result));
+
+ if (size>1) {
+ instr="add.w";
+ } else {
+ instr="add.b";
+ }
+ if (!aopEqual(result->aop, left->aop, 0)) {
+ emitcode ("mov", "%s,%s", AOP_NAME(result)[0], AOP_NAME(left)[0]);
+ }
+ emitcode (instr, "%s,%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
+ if (size>2) {
+ if (!aopEqual(result->aop, left->aop, 1)) {
+ emitcode ("mov", "%s,%s", AOP_NAME(result)[1], AOP_NAME(left)[1]);
+ }
+ if (size==3) {
+ // generic pointer
+ } else {
+ emitcode ("addc.w", "%s,%s", AOP_NAME(result)[1], AOP_NAME(right)[1]);
+ }
+ }
+ return;
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static void genOr (iCode * ic, iCode * ifx) {
operand *result=IC_RESULT(ic), *left=IC_LEFT(ic), *right=IC_RIGHT(ic);
- int size=aopOp(result, TRUE, TRUE);
+ int size;
char *instr;
printIc ("genOr", ic, 1,1,1);
+ size=aopOp(result, TRUE, TRUE);
+
/* if left is a literal, then exchange them */
if (IS_LITERAL(operandType(left))) {
operand *tmp = right;
size=aopOp(result,TRUE,aopIsDir(left));
if (IS_GENPTR(operandType(left))) {
- emitcode (";", "INLINE\t_gptrget ; %s %s = [%s %s]",
- AOP_NAME(result)[0], AOP_NAME(result)[1],
- AOP_NAME(left)[0], AOP_NAME(left)[1]);
+ symbol *tlbl1=newiTempLabel(NULL);
+ symbol *tlbl2=newiTempLabel(NULL);
+ emitcode ("cmp", "%s,#0x%02x", AOP_NAME(left)[1], CPOINTER);
+ emitcode ("bne", "%05d$", tlbl1->key+100);
+ // far/near pointer
+ emitcode ("mov", "%s,[%s]", AOP_NAME(result)[0], AOP_NAME(left)[0]);
+ if (size>2) {
+ emitcode ("mov", "%s,[%s+2]", AOP_NAME(result)[1], AOP_NAME(left)[0]);
+ }
+ emitcode ("br", "%05d$", tlbl2->key+100);
+ emitcode ("", "%05d$:", tlbl1->key+100);
+ // code pointer
+ emitcode ("mov", "r0,%s", AOP_NAME(left)[0]);
+ emitcode ("movc", "%s,[r0+]", AOP_NAME(result)[0]);
+ if (size>2) {
+ emitcode ("movc", "%s,[r0+]", AOP_NAME(result)[1], AOP_NAME(left)[1]);
+ }
+ emitcode ("", "%05d$:", tlbl2->key+100);
return;
}
emitcode (MOV, "%s,[%s]", scratchReg, AOP_NAME(left)[0]);
emitcode (MOV, "%s,%s", AOP_NAME(result)[0], scratchReg);
} else {
- emitcode (instr, "%s,[%s]", AOP_NAME(result)[0], AOP_NAME(left)[0]);
+ if (pi) {
+ emitcode (instr, "%s,[%s+]", AOP_NAME(result)[0], AOP_NAME(left)[0]);
+ pi->generated=1;
+ } else {
+ emitcode (instr, "%s,[%s]", AOP_NAME(result)[0], AOP_NAME(left)[0]);
+ }
}
if (size > 2) {
if (size==3) {
emitcode (MOV, "%s,[%s+2]", scratchReg, AOP_NAME(left)[0]);
emitcode (MOV, "%s,%s", AOP_NAME(result)[1], scratchReg);
} else {
- emitcode (instr, "%s,[%s+2]", AOP_NAME(result)[1],
- AOP_NAME(left)[0]);
+ if (pi) {
+ emitcode (instr, "%s,[%s+]", AOP_NAME(result)[1],
+ AOP_NAME(left)[0]);
+ } else {
+ emitcode (instr, "%s,[%s+2]", AOP_NAME(result)[1],
+ AOP_NAME(left)[0]);
+ }
}
}
return;
} else {
instr=MOVB;
}
- emitcode (instr, "[%s],%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
+ if (pi) {
+ emitcode (instr, "[%s+],%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
+ pi->generated=1;
+ } else {
+ emitcode (instr, "[%s],%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
+ }
if (size > 2) {
if (size==3) {
instr=MOVB;
}
- emitcode (instr, "[%s+2],%s", AOP_NAME(result)[0], AOP_NAME(right)[1]);
+ if (pi) {
+ emitcode (instr, "[%s+],%s", AOP_NAME(result)[0],
+ AOP_NAME(right)[1]);
+ } else {
+ emitcode (instr, "[%s+2],%s", AOP_NAME(result)[0],
+ AOP_NAME(right)[1]);
+ }
}
return;
}
emitcode (trueOrFalse ? "beq" : "bne", "%05d$", tlbl->key+100);
if (size > 2) {
if (size==3) {
- // generic pointer, just consider the pointer part
+ // generic pointer, forget the generic part
} else {
emitcode (instr, "%s,#0", AOP_NAME(cond)[1]);
emitcode (trueOrFalse ? "beq" : "bne", "%05d$", tlbl->key+100);
return;
}
/* we need to or */
- emitcode ("mov", "%s,%s", AOP_NAME(result), toBoolean(right));
+ emitcode ("mov", "%s,%s; toBoolean", AOP_NAME(result), toBoolean(right));
return;
}
lineHead = lineCurr = NULL;
- /* print the allocation information */
- if (allocInfo)
- printAllocInfo (currFunc, codeOutFile);
-
/* if debug information required */
if (options.debug && currFunc)
{
/*-----------------------------------------------------------------*/
/* isFree - will return 1 if the a free spil location is found */
/*-----------------------------------------------------------------*/
-static
-DEFSETFUNC (isFree)
-{
+static DEFSETFUNC (isFree) {
symbol *sym = item;
V_ARG (symbol **, sloc);
V_ARG (symbol *, fsym);
-
+
/* 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;
- }
-
+ /* TODO: this is a waste but causes to many problems
+ getSize (sym->type) >= getSize (fsym->type)) {
+ */
+ getSize (sym->type) == getSize (fsym->type)) {
+ *sloc = sym;
+ return 1;
+ }
+
return 0;
}
createStackSpil (symbol * sym)
{
symbol *sloc = NULL;
- int useXstack, model;
-
char slocBuffer[30];
D(fprintf (stderr, " createStackSpil: %s\n", sym->name));
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, "***Internal error: slocBuffer overflowed: %s:%d\n",
- __FILE__, __LINE__);
- exit (1);
- }
-
+ sprintf (slocBuffer, "sloc%d", _G.slocNum++);
sloc = newiTemp (slocBuffer);
/* set the type to the spilling symbol */
SPEC_VOLATILE(sloc->etype) = 0;
SPEC_ABSA(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
- */
-
- 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);
+ currFunc->stack += getSize (sloc->type);
+ _G.stackExtend += getSize (sloc->type);
/* add it to the _G.stackSpil set */
addSetHead (&_G.stackSpil, sloc);
iCode *ic;
int change = 0;
+ return; // that's it for now
while (1) {
change = 0;
if (!change)
break;
}
- return; // that's it for now
for (ic = ebp->sch; ic; ic = ic->next)
{