genDataPointerSet): ensure assignments always copy in MSB to LSB
order,
(loadRegFromAop): recognize CLRH optimization,
(genFunction): optimize RECEIVE iCodes in reentrant functions
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3581
4a8a32a2-be11-0410-ad9d-
d568d2c75423
+2004-11-23 Erik Petrich <epetrich AT ivorytower.norman.ok.us>
+
+ * src/hc08/gen.c (genAssign, genPointerGetSetOfs, genDataPointerGet,
+ genDataPointerSet): ensure assignments always copy in MSB to LSB
+ order,
+ (loadRegFromAop): recognize CLRH optimization,
+ (genFunction): optimize RECEIVE iCodes in reentrant functions
+
2004-11-20 Erik Petrich <epetrich AT ivorytower.norman.ok.us>
* src/SDCCmain.c (parseCmdLine, optionsTable[]): fixed bug with
2004-11-20 Erik Petrich <epetrich AT ivorytower.norman.ok.us>
* src/SDCCmain.c (parseCmdLine, optionsTable[]): fixed bug with
+ {
+ char * l = aopAdrStr (aop, loffset, FALSE);
+ if (!strcmp (l, zero))
+ {
+ emitcode ("clrh", "");
+ break;
+ }
+ }
if (hc08_reg_a->isFree)
{
loadRegFromAop (hc08_reg_a, aop, loffset);
if (hc08_reg_a->isFree)
{
loadRegFromAop (hc08_reg_a, aop, loffset);
static void
genFunction (iCode * ic)
{
static void
genFunction (iCode * ic)
{
+ symbol *sym = OP_SYMBOL (IC_LEFT (ic));
- int calleesaves_saved_register = -1;
+ iCode *ric = (ic->next && ic->next->op == RECEIVE) ? ic->next : NULL;
+ int stackAdjust = sym->stack;
+ int accIsFree = sym->recvSize != 0;
_G.nRegsSaved = 0;
_G.stackPushes = 0;
/* create the function header */
emitcode (";", "-----------------------------------------");
_G.nRegsSaved = 0;
_G.stackPushes = 0;
/* create the function header */
emitcode (";", "-----------------------------------------");
- emitcode (";", " function %s", (sym = OP_SYMBOL (IC_LEFT (ic)))->name);
+ emitcode (";", " function %s", sym->name);
emitcode (";", "-----------------------------------------");
emitcode ("", "%s:", sym->rname);
emitcode (";", "-----------------------------------------");
emitcode ("", "%s:", sym->rname);
/* if this is an interrupt service routine then
save h */
if (IFFUNC_ISISR (sym->type))
/* if this is an interrupt service routine then
save h */
if (IFFUNC_ISISR (sym->type))
if (!inExcludeList ("h"))
pushReg (hc08_reg_h, FALSE);
}
if (!inExcludeList ("h"))
pushReg (hc08_reg_h, FALSE);
}
+
+ /* For some cases it is worthwhile to perform a RECEIVE iCode */
+ /* before setting up the stack frame completely. */
+ while (ric && ric->next && ric->next->op == RECEIVE)
+ ric = ric->next;
+ while (ric && IC_RESULT (ric))
- /* 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;
+ symbol * rsym = OP_SYMBOL (IC_RESULT (ric));
+ int rsymSize = rsym ? getSize(rsym->type) : 0;
- /* if any registers used */
- if (sym->regsUsed)
- {
- /* save the registers used */
- for (i = 0; i < sym->regsUsed->size; i++)
- {
- if (bitVectBitValue (sym->regsUsed, i))
- {
- /* remember one saved register for later usage */
- if (calleesaves_saved_register < 0)
- calleesaves_saved_register = i;
- pushReg (hc08_regWithIdx (i), FALSE);
- _G.nRegsSaved++;
- }
- }
- }
- }
- }
+ if (rsym->isitmp)
+ {
+ if (rsym && rsym->regType == REG_CND)
+ rsym = NULL;
+ if (rsym && (rsym->accuse || rsym->ruonly))
+ rsym = NULL;
+ if (rsym && (rsym->isspilt || rsym->nRegs == 0) && rsym->usl.spillLoc)
+ rsym = rsym->usl.spillLoc;
+ }
- if (IFFUNC_ISREENT (sym->type) || options.stackAuto)
- {
+ /* If the RECEIVE operand immediately spills to the first entry on the */
+ /* stack, we can push it directly rather than use an sp relative store. */
+ if (rsym && rsym->onStack && rsym->stack == -_G.stackPushes-rsymSize)
+ {
+ int ofs;
+ _G.current_iCode = ric;
+ D(emitcode ("; genReceive",""));
+ for (ofs=0; ofs < rsymSize; ofs++)
+ {
+ regs * reg = hc08_aop_pass[ofs+(ric->argreg-1)]->aopu.aop_reg[0];
+ pushReg (reg, TRUE);
+ if (reg->rIdx == A_IDX)
+ accIsFree = 1;
+ stackAdjust--;
+ }
+ _G.current_iCode = ic;
+ ric->generated = 1;
+ }
+ ric = (ric->prev && ric->prev->op == RECEIVE) ? ric->prev : NULL;
}
/* adjust the stack for the function */
}
/* adjust the stack for the function */
-
- int i = sym->stack;
-// if (i > 256)
-// werror (W_STACK_OVERFLOW, sym->name);
-
- adjustStack (-i);
+ adjustStack (-stackAdjust);
}
_G.stackOfs = sym->stack;
_G.stackPushes = 0;
}
_G.stackOfs = sym->stack;
_G.stackPushes = 0;
/* if critical function then turn interrupts off */
if (IFFUNC_ISCRITICAL (ftype))
{
/* if critical function then turn interrupts off */
if (IFFUNC_ISCRITICAL (ftype))
{
- if (IFFUNC_ARGS (ftype))
{
/* Function was passed parameters, so make sure A is preserved */
pushReg (hc08_reg_a, FALSE);
{
/* Function was passed parameters, so make sure A is preserved */
pushReg (hc08_reg_a, FALSE);
{
iCode *lic = ic->next;
bool pset, pget;
{
iCode *lic = ic->next;
bool pset, pget;
symbol *sym;
asmop *derefaop;
symbol *sym;
asmop *derefaop;
loadRegFromAop (hc08_reg_hx, AOP (IC_RIGHT (ic)), 0);
size = AOP_SIZE (IC_RESULT(lic));
derefaop->size = size;
loadRegFromAop (hc08_reg_hx, AOP (IC_RIGHT (ic)), 0);
size = AOP_SIZE (IC_RESULT(lic));
derefaop->size = size;
while (size--)
{
emitcode ("lda", "%s,x",
while (size--)
{
emitcode ("lda", "%s,x",
- aopAdrStr (derefaop, offset, TRUE));
+ aopAdrStr (derefaop, size, TRUE));
hc08_useReg (hc08_reg_a);
hc08_useReg (hc08_reg_a);
- storeRegToAop (hc08_reg_a, AOP (IC_RESULT (lic)), offset++);
+ storeRegToAop (hc08_reg_a, AOP (IC_RESULT (lic)), size);
hc08_freeReg (hc08_reg_a);
}
hc08_freeReg (hc08_reg_a);
}
loadRegFromAop (hc08_reg_hx, AOP (IC_RIGHT (ic)), 0);
size = AOP_SIZE (IC_RIGHT(lic));
derefaop->size = size;
loadRegFromAop (hc08_reg_hx, AOP (IC_RIGHT (ic)), 0);
size = AOP_SIZE (IC_RIGHT(lic));
derefaop->size = size;
- loadRegFromAop (hc08_reg_a, AOP (IC_RIGHT (lic)), offset);
+ loadRegFromAop (hc08_reg_a, AOP (IC_RIGHT (lic)), size);
- aopAdrStr (derefaop, offset, TRUE));
+ aopAdrStr (derefaop, size, TRUE));
hc08_freeReg (hc08_reg_a);
hc08_freeReg (hc08_reg_a);
iCode * ic,
iCode * ifx)
{
iCode * ic,
iCode * ifx)
{
asmop *derefaop;
D(emitcode ("; genDataPointerGet",""));
asmop *derefaop;
D(emitcode ("; genDataPointerGet",""));
while (size--)
{
if (!ifx)
while (size--)
{
if (!ifx)
- transferAopAop (derefaop, offset, AOP (result), offset);
+ transferAopAop (derefaop, size, AOP (result), size);
- loadRegFromAop (hc08_reg_a, derefaop, offset);
- offset++;
+ loadRegFromAop (hc08_reg_a, derefaop, size);
}
freeAsmop (NULL, derefaop, ic, TRUE);
}
freeAsmop (NULL, derefaop, ic, TRUE);
operand * result,
iCode * ic)
{
operand * result,
iCode * ic)
{
asmop *derefaop;
D(emitcode ("; genDataPointerSet",""));
asmop *derefaop;
D(emitcode ("; genDataPointerSet",""));
- transferAopAop (AOP (right), offset, derefaop, offset);
- offset++;
+ transferAopAop (AOP (right), size, derefaop, size);
}
freeAsmop (right, NULL, ic, TRUE);
}
freeAsmop (right, NULL, ic, TRUE);
genAssign (iCode * ic)
{
operand *result, *right;
genAssign (iCode * ic)
{
operand *result, *right;
// unsigned long lit = 0L;
D(emitcode("; genAssign",""));
// unsigned long lit = 0L;
D(emitcode("; genAssign",""));
/* general case */
size = AOP_SIZE (result);
/* general case */
size = AOP_SIZE (result);
- transferAopAop (AOP (right), offset, AOP (result), offset);
- offset++;
+ transferAopAop (AOP (right), size, AOP (result), size);