-------------------------------------------------------------------------*/
-#define D(x)
-//#define D(x) x
+/* Use the D macro for basic (unobtrusive) debugging messages */
+#define D(x) do if (options.verboseAsm) {x;} while(0)
+/* Use the DD macro for detailed debugging messages */
+#define DD(x)
+//#define DD(x) x
#include <stdio.h>
#include <stdlib.h>
extern int allocInfo;
static int pushReg (regs *reg, bool freereg);
static void pullReg (regs *reg);
+static void transferAopAop (asmop *srcaop, int srcofs, asmop *dstaop, int dstofs);
static char *zero = "#0x00";
static char *one = "#0x01";
char *fReturnhc08[] =
{"a", "x", "_ret2", "_ret3"};
-unsigned fReturnSizeHC08 = 4; /* shared with ralloc.c */
+unsigned fReturnSizeHC08 = 4; /* shared with ralloc.c */
char **fReturn2 = fReturnhc08;
extern int hc08_ptrRegReq;
extern int hc08_nRegs;
-extern FILE *codeOutFile;
+extern struct dbuf_s *codeOutBuf;
//static void saveRBank (int, iCode *, bool);
static bool operandsEqu (operand * op1, operand * op2);
static void loadRegFromConst (regs *reg, char *c);
(((x)->type == AOP_REG) \
&& ((x)->aopu.aop_reg[0] == hc08_reg_h) \
&& ((x)->size == 1) )
-
+
#define CLRC emitcode("clc","")
static lineNode *lineHead = NULL;
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
vsprintf (lb, fmt, ap);
- while (isspace (*lbp))
+ while (isspace ((unsigned char)*lbp))
lbp++;
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;
+ lineCurr->isComment = (*lbp==';');
//printf("%s\n", lb);
va_end (ap);
emitLabel (symbol *tlbl)
{
emitcode ("", "%05d$:", (tlbl->key +100));
+ lineCurr->isLabel = 1;
}
/*-----------------------------------------------------------------*/
if (!sreg)
{
werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "NULL sreg in transferRegReg");
+ "NULL sreg in transferRegReg");
return;
}
- D(emitcode ("", "; transferRegReg(%s,%s)",
+ DD(emitcode ("", "; transferRegReg(%s,%s)",
sreg->name, dreg->name));
srcidx = sreg->rIdx;
dstidx = dreg->rIdx;
-
+
if (srcidx==dstidx)
return;
-
+
switch (dstidx)
{
case A_IDX:
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;
/* there is no frame unless there is a function */
if (!currFunc)
return;
-
+
debugFile->writeFrameAddress (NULL, hc08_reg_sp,
- 1 + _G.stackOfs + _G.stackPushes);
+ 1 + _G.stackOfs + _G.stackPushes);
}
/*--------------------------------------------------------------------------*/
pushReg (regs *reg, bool freereg)
{
int regidx = reg->rIdx;
-
+
switch (regidx)
{
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:
pullReg (regs *reg)
{
int regidx = reg->rIdx;
-
+
switch (regidx)
{
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 ("pulx", "");
- _G.stackPushes--;
- updateCFA();
emitcode ("pulh", "");
_G.stackPushes--;
- updateCFA();
+ updateCFA();
+ emitcode ("pulx", "");
+ _G.stackPushes--;
+ updateCFA();
break;
case XA_IDX:
- emitcode ("pula", "");
- _G.stackPushes--;
- updateCFA();
emitcode ("pulx", "");
_G.stackPushes--;
- updateCFA();
+ updateCFA();
+ emitcode ("pula", "");
+ _G.stackPushes--;
+ 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();
}
- }
+ }
}
{
static char buffer[256];
char *buf = buffer;
-
+
if (!aop)
return "(asmop*)NULL";
printf(" reg missing operand link\n");
#endif
- D(emitcode ("", "; loadRegFromAop (%s, %s, %d)",
+ 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;
-
+
/* If this register already has this offset of the operand
then we need only mark it as in use. */
if (reg->aop && reg->aop->op && aop->op
&& (reg->aopofs == loffset))
{
hc08_useReg(reg);
- D(emitcode ("","; already had correct value for %s", reg->name));
+ DD(emitcode ("","; already had correct value for %s", reg->name));
return;
}
&& operandsEqu(hc08_reg_h->aop->op,aop->op)
&& (hc08_reg_h->aopofs == loffset))
{
- D(emitcode ("","; found correct value for %s in h", reg->name));
+ DD(emitcode ("","; found correct value for %s in h", reg->name));
transferRegReg (hc08_reg_h, reg, FALSE);
hc08_useReg (reg);
return;
}
-
+
if (hc08_reg_x->aop && hc08_reg_x->aop->op && aop->op
&& operandsEqu(hc08_reg_x->aop->op,aop->op)
&& (hc08_reg_x->aopofs == loffset))
{
- D(emitcode ("","; found correct value for %s in x", reg->name));
+ DD(emitcode ("","; found correct value for %s in x", reg->name));
transferRegReg (hc08_reg_x, reg, FALSE);
hc08_useReg (reg);
return;
}
-
+
if (hc08_reg_a->aop && hc08_reg_a->aop->op && aop->op
&& operandsEqu(hc08_reg_a->aop->op,aop->op)
&& (hc08_reg_a->aopofs == loffset))
{
- D(emitcode ("","; found correct value for %s in a", reg->name));
+ DD(emitcode ("","; found correct value for %s in a", reg->name));
transferRegReg (hc08_reg_a, reg, FALSE);
hc08_useReg (reg);
return;
emitcode ("clra", ""); /* TODO: handle sign extension */
}
else
- emitcode ("lda","%s", aopAdrStr (aop, loffset, FALSE));
+ {
+ char * l = aopAdrStr (aop, loffset, FALSE);
+ if (!strcmp (l, zero))
+ emitcode ("clra", "");
+ else
+ emitcode ("lda", "%s", l);
+ }
break;
case X_IDX:
if (aop->type == AOP_REG)
emitcode ("clrx", ""); /* TODO: handle sign extension */
}
else
- emitcode ("ldx","%s", aopAdrStr (aop, loffset, FALSE));
+ {
+ char * l = aopAdrStr (aop, loffset, FALSE);
+ if (!strcmp (l, zero))
+ emitcode ("clrx", "");
+ else
+ emitcode ("ldx", "%s", l);
+ }
break;
case H_IDX:
+ {
+ char * l = aopAdrStr (aop, loffset, FALSE);
+ if (!strcmp (l, zero))
+ {
+ emitcode ("clrh", "");
+ break;
+ }
+ }
if (hc08_reg_a->isFree)
{
loadRegFromAop (hc08_reg_a, aop, loffset);
loadRegFromAop (hc08_reg_x, aop, loffset+1);
}
break;
- }
+ }
// ignore caching for now
#if 0
/*--------------------------------------------------------------------------*/
/* forceStackedAop - Reserve space on the stack for asmop aop; when */
/* freeAsmop is called with aop, the stacked data will */
-/* be copied to the original aop location and */
+/* be copied to the original aop location. */
/*--------------------------------------------------------------------------*/
static asmop *
-forceStackedAop (asmop *aop)
+forceStackedAop (asmop *aop, bool copyOrig)
{
+ regs *reg;
int loffset;
asmop *newaop = newAsmop (aop->type);
memcpy (newaop, aop, sizeof(*newaop));
-
- D(emitcode("", "; forcedStackAop %s", aopName(aop)));
+
+ DD(emitcode("", "; forcedStackAop %s", aopName(aop)));
+
+ if (copyOrig && hc08_reg_a->isFree)
+ reg = hc08_reg_a;
+ else if (copyOrig && hc08_reg_x->isFree)
+ reg = hc08_reg_x;
+ else
+ reg = NULL;
+
for (loffset=0; loffset < newaop->size; loffset++)
{
asmop *aopsof = newAsmop (AOP_SOF);
aopsof->size = 1;
- aopsof->aopu.aop_stk = pushReg (hc08_reg_a, FALSE);
+ if (copyOrig && reg)
+ {
+ loadRegFromAop (reg, aop, loffset);
+ aopsof->aopu.aop_stk = pushReg (reg, FALSE);
+ }
+ else
+ {
+ aopsof->aopu.aop_stk = pushReg (hc08_reg_a, FALSE);
+ }
aopsof->op = aop->op;
newaop->stk_aop[loffset] = aopsof;
}
newaop->stacked = 1;
+
+ if (!reg && copyOrig)
+ {
+ for (loffset=0; loffset < newaop->size; loffset++)
+ {
+ transferAopAop (aop, loffset, newaop, loffset);
+ }
+ }
+
return newaop;
}
int otheridx;
#endif
- D(emitcode ("", "; storeRegToAop (%s, %s, %d), stacked=%d, isaddr=%d",
+ DD(emitcode ("", "; storeRegToAop (%s, %s, %d), stacked=%d, isaddr=%d",
reg->name, aopName (aop), loffset, aop->stacked, aop->isaddr));
if ((reg->rIdx == HX_IDX) && aop->stacked
if (aop->type == AOP_DUMMY)
return;
-
+
+ if (aop->type == AOP_CRY) /* This can only happen if IFX was optimized */
+ return; /* away, so just toss the result */
+
switch (regidx)
{
case A_IDX:
storeRegToAop (hc08_reg_x, aop, loffset+1);
}
break;
- }
+ }
/* Disable the register tracking for now */
#if 0
&& operandsEqu(otherreg->aop->op,aop->op)
&& (otherreg->aopofs == loffset))
{
- D(emitcode("","; marking %s stale", otherreg->name));
+ DD(emitcode("","; marking %s stale", otherreg->name));
otherreg->aop=NULL;
}
}
if ((!hc08_reg_x->aop || !hc08_reg_h->aop) && hc08_reg_hx->aop)
{
hc08_reg_hx->aop = NULL;
- D(emitcode("","; marking hx stale"));
+ DD(emitcode("","; marking hx stale"));
}
if ((!hc08_reg_x->aop || !hc08_reg_a->aop) && hc08_reg_xa->aop)
{
hc08_reg_xa->aop = NULL;
- D(emitcode("","; marking xa stale"));
+ DD(emitcode("","; marking xa stale"));
}
-
+
reg->aop = aop;
reg->aopofs = loffset;
}
break;
default:
werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "Bad rIdx in loadRegFromConst");
- return;
+ "Bad rIdx in loadRegFromConst");
+ return;
}
hc08_useReg (reg);
}
{
// int regidx = reg->rIdx;
int size = aop->size;
-
+
if (size<=loffset)
return;
-
+
if (!isSigned)
{
/* Unsigned case */
/*--------------------------------------------------------------------------*/
/* transferAopAop - Transfer the value at logical offset srcofs of asmop */
-/* srcaop to logical offset dstofs of asmop dstofs. */
+/* srcaop to logical offset dstofs of asmop dstaop. */
/*--------------------------------------------------------------------------*/
static void
transferAopAop (asmop *srcaop, int srcofs, asmop *dstaop, int dstofs)
int regIdx;
bool keepreg = FALSE;
+ /* ignore transfers at the same byte, unless its volatile */
+ if (srcaop->op && !isOperandVolatile (srcaop->op, FALSE)
+ && dstaop->op && !isOperandVolatile (dstaop->op, FALSE)
+ && operandsEqu(srcaop->op, dstaop->op) && srcofs == dstofs
+ && dstaop->type == srcaop->type)
+ return;
+
if (srcaop->stacked && srcaop->stk_aop[srcofs])
{
transferAopAop (srcaop->stk_aop[srcofs], 0, dstaop, dstofs);
return;
}
-// D(emitcode ("", "; transferAopAop (%s, %d, %s, %d)",
+// DD(emitcode ("", "; transferAopAop (%s, %d, %s, %d)",
// aopName (srcaop), srcofs, aopName (dstaop), dstofs));
-// D(emitcode ("", "; srcaop->type = %d", srcaop->type));
-// D(emitcode ("", "; dstaop->type = %d", dstaop->type));
-
+// DD(emitcode ("", "; srcaop->type = %d", srcaop->type));
+// DD(emitcode ("", "; dstaop->type = %d", dstaop->type));
+
if (dstofs >= dstaop->size)
return;
if ((dstaop->type == AOP_DIR)
&& ((srcaop->type == AOP_DIR) || (srcaop->type == AOP_LIT)) )
{
+ if (srcaop->type == AOP_LIT)
+ {
+ unsigned long lit;
+ unsigned long bytemask;
+
+ lit = ulFromVal (srcaop->aopu.aop_lit);
+ bytemask = (lit >> (srcofs*8)) & 0xff;
+
+ if (bytemask == 0)
+ {
+ emitcode ("clr", "%s", aopAdrStr(dstaop, dstofs, FALSE));
+ return;
+ }
+ }
+
emitcode("mov", "%s,%s", aopAdrStr(srcaop, srcofs, FALSE),
aopAdrStr(dstaop, dstofs, FALSE));
return;
if (hc08_reg_a->isFree)
reg = hc08_reg_a;
else if (hc08_reg_x->isFree)
- reg = hc08_reg_x;
+ reg = hc08_reg_x;
else
{
pushReg (hc08_reg_a, TRUE);
reg = hc08_reg_a;
}
}
-
+
loadRegFromAop (reg, srcaop, srcofs);
storeRegToAop (reg, dstaop, dstofs);
-
+
if (!keepreg)
pullOrFreeReg (hc08_reg_a, needpula);
}
/*--------------------------------------------------------------------------*/
/* accopWithAop - Emit read/modify/write instruction rmwop with the byte at */
/* logical offset loffset of asmop aop. */
-/* Supports: com, dec, inc, lsl, lsr, neg, rol, ror */
+/* Supports: com, dec, inc, lsl, lsr, neg, rol, ror, tst */
/*--------------------------------------------------------------------------*/
static void
rmwWithAop (char *rmwop, asmop *aop, int loffset)
rmwWithAop (rmwop, aop->stk_aop[loffset], 0);
return;
}
-
+
switch (aop->type)
{
case AOP_REG:
break;
case AOP_EXT:
needpula = pushRegIfUsed (hc08_reg_a);
- loadRegFromAop (hc08_reg_a, aop, loffset);
+ loadRegFromAop (hc08_reg_a, aop, loffset);
rmwWithReg (rmwop, hc08_reg_a);
- storeRegToAop (hc08_reg_a, aop, loffset);
+ if (strcmp ("tst", rmwop))
+ storeRegToAop (hc08_reg_a, aop, loffset);
pullOrFreeReg (hc08_reg_a, needpula);
break;
case AOP_DUMMY:
default:
emitcode (rmwop, "%s", aopAdrStr (aop, loffset, FALSE));
}
-
+
}
aop->aopu.aop_stk = sym->stack;
return aop;
}
-
+
werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "aopForSym should never reach here");
+ "aopForSym should never reach here");
exit(1);
-
+
/* if it is in code space */
if (IN_CODESPACE (space))
aop->code = 1;
}
/*-----------------------------------------------------------------*/
-/* aopForRemat - rematerialzes an object */
+/* aopForRemat - rematerializes an object */
/*-----------------------------------------------------------------*/
static asmop *
aopForRemat (symbol * sym)
{
iCode *ic = sym->rematiCode;
asmop *aop = NULL;
- int ptr_type=0;
+ int ptr_type = 0;
int val = 0;
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));
- 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 ;
- } else break;
+ val -= (int) operandLitValue (IC_RIGHT (ic));
+ else if (IS_CAST_ICODE(ic))
+ {
+ sym_link *from_type = operandType(IC_RIGHT(ic));
+ 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 (ic->op == ADDRESS_OF)
{
if (val)
- sprintf (buffer, "(%s %c 0x%04x)",
- OP_SYMBOL (IC_LEFT (ic))->rname,
- val >= 0 ? '+' : '-',
- abs (val) & 0xffff);
+ {
+ SNPRINTF (buffer, sizeof(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);
+ {
+ strncpyz (buffer, OP_SYMBOL (IC_LEFT (ic))->rname, sizeof(buffer));
+ }
aop = newAsmop (AOP_IMMD);
- aop->aopu.aop_immd.aop_immd1 = Safe_calloc (1, strlen (buffer) + 1);
- strcpy (aop->aopu.aop_immd.aop_immd1, buffer);
+ aop->aopu.aop_immd.aop_immd1 = Safe_strdup(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);
- }
}
else if (ic->op == '=')
{
val += (int) operandLitValue (IC_RIGHT (ic));
val &= 0xffff;
- sprintf (buffer, "0x%04x", val);
+ SNPRINTF (buffer, sizeof(buffer), "0x%04x", val);
aop = newAsmop (AOP_LIT);
aop->aopu.aop_lit = constVal (buffer);
}
else
- werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "unexpected rematerialization");
-
-
+ {
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "unexpected rematerialization");
+ }
return aop;
}
{
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;
if (sym1 == sym2)
return TRUE;
+ /* if they have the same rname */
if (sym1->rname[0] && sym2->rname[0]
&& strcmp (sym1->rname, sym2->rname) == 0)
return TRUE;
// printf("checking pre-existing\n");
/* if already has a asmop then continue */
- if (op->aop )
+ if (op->aop)
{
op->aop->op = op;
op->aop->isaddr = op->isaddr;
aop->size = getSize( operandType (op));
//printf ("reusing underlying symbol %s\n",OP_SYMBOL (op)->name);
//printf (" with size = %d\n", aop->size);
-
+
aop->op = op;
aop->isaddr = op->isaddr;
/* if (aop->isaddr & IS_ITEMP (op))
}
/* this is a temporary : this has
- only four choices :
+ only five choices :
a) register
b) spillocation
c) rematerialize
/* if the type is a conditional */
if (sym->regType == REG_CND)
{
- aop = op->aop = sym->aop = newAsmop (AOP_CRY);
+ sym->aop = op->aop = aop = newAsmop (AOP_CRY);
aop->size = 0;
aop->op = op;
aop->isaddr = op->isaddr;
// 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:
+ {
+ sym->aop = op->aop = 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];
+ sym->aop = op->aop = 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)
{
+ asmop *oldAsmOp = NULL;
+
if (sym->usl.spillLoc->aop
&& sym->usl.spillLoc->aop->size != getSize (sym->type))
{
- /* force a new aop if sizes differ */
- sym->usl.spillLoc->aop = NULL;
- //printf ("forcing new aop\n");
+ /* force a new aop if sizes differ */
+ oldAsmOp = sym->usl.spillLoc->aop;
+ sym->usl.spillLoc->aop = NULL;
+ //printf ("forcing new aop\n");
+ }
+ 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;
}
- sym->aop = op->aop = aop = aopForSym (ic, sym->usl.spillLoc, result);
- 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);
aop->size = getSize (sym->type);
int stackAdjust;
int loffset;
- D(emitcode ("","; freeAsmop restoring stacked %s", aopName(aop)));
+ DD(emitcode ("","; freeAsmop restoring stacked %s", aopName(aop)));
aop->stacked = 0;
stackAdjust = 0;
for (loffset=0; loffset<aop->size; loffset++)
}
pullNull (stackAdjust);
}
-
+
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;
- }
+ {
+ OP_SYMBOL (op)->aop = NULL;
+ /* if the symbol has a spill */
+ if (SPIL_LOC (op))
+ SPIL_LOC (op)->aop = NULL;
+ }
}
}
asmop *newaop = NULL;
sym_link *type, *etype;
int p_type;
-
- D(emitcode ("", "; aopDerefAop(%s)", aopName(aop)));
+
+ DD(emitcode ("", "; aopDerefAop(%s)", aopName(aop)));
if (aop->op)
{
-
+
type = operandType (aop->op);
etype = getSpec (type);
/* if op is of type of pointer then it is simple */
}
else
p_type = UPOINTER;
-
+
switch (aop->type)
{
case AOP_IMMD:
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;
return NULL;
}
-
+
return newaop;
}
char *s = buffer;
char *rs;
int offset = aop->size - 1 - loffset;
-
+
/* offset is greater than
size then zero */
case AOP_DUMMY:
return zero;
-
+
case AOP_IMMD:
- if (aop->aopu.aop_immd.from_cast_remat && (loffset == (aop->size-1))) {
- sprintf(s,"%s",aop->aopu.aop_immd.aop_immd2);
- } else if (bit16)
- sprintf (s, "#%s", aop->aopu.aop_immd.aop_immd1);
+ if (aop->aopu.aop_immd.from_cast_remat && (loffset == (aop->size-1)))
+ {
+ sprintf(s,"%s",aop->aopu.aop_immd.aop_immd2);
+ }
+ else if (bit16)
+ {
+ 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);
}
return size;
}
-/*-----------------------------------------------------------------*/
-/* outAcc - output Acc */
-/*-----------------------------------------------------------------*/
-static void
-outAcc (operand * result)
-{
- int size, offset;
- size = getDataSize (result);
- if (size)
- {
- storeRegToAop (hc08_reg_a, AOP (result), 0);
- size--;
- offset = 1;
- /* unsigned or positive */
- while (size--)
- {
- storeConstToAop (zero, AOP (result), offset++);
- }
- }
-}
-
-/*-----------------------------------------------------------------*/
-/* outBitC - output a bit C */
-/*-----------------------------------------------------------------*/
-static void
-outBitC (operand * result)
-{
-
-#if 0
- /* if the result is bit */
- if (AOP_TYPE (result) == AOP_CRY)
- aopPut (AOP (result), "c", 0);
- else
-#endif
- {
- emitcode ("clra", "");
- emitcode ("rola", "");
- outAcc (result);
- }
-}
-
-/*-----------------------------------------------------------------*/
-/* outBitNV - output a bit N^V */
-/*-----------------------------------------------------------------*/
-static void
-outBitNV (operand * result)
-{
- symbol *tlbl, *tlbl1;
-
- tlbl = newiTempLabel (NULL);
- tlbl1 = newiTempLabel (NULL);
-
- emitBranch ("blt", tlbl);
- loadRegFromConst (hc08_reg_a, zero);
- emitBranch ("bra", tlbl1);
- emitLabel (tlbl);
- loadRegFromConst (hc08_reg_a, one);
- emitLabel (tlbl1);
- outAcc (result);
-}
-
/*-----------------------------------------------------------------*/
/* asmopToBool - Emit code to convert an asmop to a boolean. */
if (resultInA)
hc08_freeReg(hc08_reg_a);
-
+
switch (aop->type)
{
case AOP_REG:
emitcode ("tsta", "");
emitcode ("bne", "%05d$", (tlbl->key + 100));
emitcode ("tstx", "");
- emitcode ("", "%05d$:", (tlbl->key + 100));
+ emitLabel (tlbl);
}
else
{
flagsonly = FALSE;
}
break;
+ case AOP_LIT:
+ /* Higher levels should optimize this case away but let's be safe */
+ if (ulFromVal (aop->aopu.aop_lit))
+ loadRegFromConst (hc08_reg_a, one);
+ else
+ loadRegFromConst (hc08_reg_a, zero);
+ hc08_freeReg(hc08_reg_a);
+ break;
default:
if (size==1)
{
emitcode ("tst", "%s", aopAdrStr (aop, 0, FALSE));
emitcode ("bne", "%05d$", (tlbl->key + 100));
emitcode ("tst", "%s", aopAdrStr (aop, 1, FALSE));
- emitcode ("", "%05d$:", (tlbl->key + 100));
+ emitLabel (tlbl);
break;
}
}
asmopToBool ( AOP (IC_LEFT (ic)), TRUE);
emitcode ("eor", one);
storeRegToFullAop (hc08_reg_a, AOP (IC_RESULT (ic)), FALSE);
-
+
freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
}
int offset = 0;
int size;
regs* reg = hc08_reg_a;
-
-// symbol *tlbl;
D(emitcode ("; genCpl",""));
hc08_useReg (reg);
storeRegToAop (reg, AOP (IC_RESULT (ic)), offset);
hc08_freeReg (reg);
+ offset++;
}
/* release the aops */
while (size--)
{
- if (!size)
- {
- needpula = pushRegIfUsed (hc08_reg_a);
- loadRegFromAop (hc08_reg_a, AOP (op), offset);
- emitcode ("eor", "#0x80");
- hc08_useReg (hc08_reg_a);
- storeRegToAop (hc08_reg_a, AOP (result), offset);
- pullOrFreeReg (hc08_reg_a, needpula);
- }
- else
- transferAopAop (AOP (op), offset, AOP (result), offset);
+ transferAopAop (AOP (op), offset, AOP (result), offset);
offset++;
}
+ needpula = pushRegIfUsed (hc08_reg_a);
+ loadRegFromAop (hc08_reg_a, AOP (op), offset);
+ emitcode ("eor", "#0x80");
+ hc08_useReg (hc08_reg_a);
+ storeRegToAop (hc08_reg_a, AOP (result), offset);
+ pullOrFreeReg (hc08_reg_a, needpula);
}
/*-----------------------------------------------------------------*/
loadRegFromAop (hc08_reg_a, AOP( IC_LEFT (ic)), 0);
emitcode ("nega", "");
hc08_freeReg (hc08_reg_a);
- storeRegToFullAop (hc08_reg_a, AOP( IC_RESULT (ic)),
+ storeRegToFullAop (hc08_reg_a, AOP( IC_RESULT (ic)),
SPEC_USIGN (operandType (IC_LEFT (ic))));
pullOrFreeReg (hc08_reg_a, needpula);
}
else
{
if (IS_AOP_XA (AOP (IC_RESULT (ic))))
- result = forceStackedAop (AOP (IC_RESULT (ic)));
+ result = forceStackedAop (AOP (IC_RESULT (ic)), FALSE);
else
result = AOP (IC_RESULT (ic));
-
+
needpula = pushRegIfUsed (hc08_reg_a);
sub="sub";
while (size--)
storeRegToAop (hc08_reg_a, result, offset++);
sub = "sbc";
}
- storeRegSignToUpperAop (hc08_reg_a, result, offset,
+ storeRegSignToUpperAop (hc08_reg_a, result, offset,
SPEC_USIGN (operandType (IC_LEFT (ic))));
pullOrFreeReg (hc08_reg_a, needpula);
-
+
if (IS_AOP_XA (AOP (IC_RESULT (ic))))
freeAsmop (NULL, result, ic, TRUE);
}
(IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type) ||
IFFUNC_ISNAKED(OP_SYM_TYPE(IC_LEFT (ic)))))
return;
-
+
/* 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)));
+ rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
+ 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)));
+ rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
+ hc08_rUmaskForOp (IC_RESULT(ic)));
for (i = hc08_nRegs; i >= 0; i--)
{
/*-----------------------------------------------------------------*/
-/* pushSide - */
+/* pushSide - */
/*-----------------------------------------------------------------*/
static void
-pushSide (operand * oper, int size)
+pushSide (operand * oper, int size, iCode * ic)
{
int offset = 0;
+
+ aopOp (oper, ic, FALSE);
+
while (size--)
{
loadRegFromAop (hc08_reg_a, AOP (oper), offset++);
pushReg ( hc08_reg_a, TRUE);
}
+
+ freeAsmop (oper, NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
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)
{
iCode *sic;
- 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));
-
- 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);
+ for (sic = setFirstItem (sendSet); sic;
+ sic = setNextItem (sendSet)) {
+ 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);
}
}
D(emitcode("; genCall",""));
dtype = operandType (IC_LEFT (ic));
- /* if send set is not empty the assign */
+ /* 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)))
{
// bool restoreBank=FALSE;
// bool swapBanks = FALSE;
- D(emitcode("; genPCall",""));
+ D (emitcode (";", "genPcall"));
/* if caller saves & we have not saved then */
if (!ic->regsSaved)
destination registers on the stack */
dtype = operandType (IC_LEFT (ic))->next;
- /* now push the calling address */
+ /* push the return address on to the stack */
emitBranch ("bsr", tlbl);
emitBranch ("bra", rlbl);
emitLabel (tlbl);
+ _G.stackPushes += 2; /* account for the bsr return address now on stack */
+ updateCFA();
- /* Push the function's address */
- aopOp (IC_LEFT (ic), ic, FALSE);
- pushSide (IC_LEFT (ic), FPTRSIZE);
- freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
+ /* now push the function address */
+ pushSide (IC_LEFT (ic), FPTRSIZE, ic);
- /* if send set is not empty the assign */
+ /* if send set is not empty then assign */
if (_G.sendSet)
{
- genSend(reverseSet(_G.sendSet));
- _G.sendSet = NULL;
+ genSend(reverseSet(_G.sendSet));
+ _G.sendSet = NULL;
}
emitcode ("rts", "");
emitLabel (rlbl);
+ _G.stackPushes -= 4; /* account for rts here & in called function */
+ updateCFA();
/* 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 defined(__BORLANDC__) || defined(_MSC_VER)
-#define STRCASECMP stricmp
-#else
-#define STRCASECMP strcasecmp
-#endif
-
/*-----------------------------------------------------------------*/
/* inExcludeList - return 1 if the string is in exclude Reg list */
/*-----------------------------------------------------------------*/
static void
genFunction (iCode * ic)
{
- symbol *sym;
+ symbol *sym = OP_SYMBOL (IC_LEFT (ic));
sym_link *ftype;
- 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 (";", "-----------------------------------------");
- emitcode (";", " function %s", (sym = OP_SYMBOL (IC_LEFT (ic)))->name);
+ emitcode (";", " function %s", sym->name);
emitcode (";", "-----------------------------------------");
emitcode ("", "%s:", sym->rname);
+ lineCurr->isLabel = 1;
ftype = operandType (IC_LEFT (ic));
-
+
_G.stackOfs = 0;
_G.stackPushes = 0;
debugFile->writeFrameAddress (NULL, hc08_reg_sp, 0);
return;
}
-
-
/* if this is an interrupt service routine then
save h */
if (IFFUNC_ISISR (sym->type))
if (!inExcludeList ("h"))
pushReg (hc08_reg_h, FALSE);
}
- 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))
- {
- /* remember one saved register for later usage */
- if (calleesaves_saved_register < 0)
- calleesaves_saved_register = i;
- pushReg (hc08_regWithIdx (i), FALSE);
- _G.nRegsSaved++;
- }
- }
- }
- }
- }
- if (IFFUNC_ISREENT (sym->type) || options.stackAuto)
+ /* 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))
{
+ symbol * rsym = OP_SYMBOL (IC_RESULT (ric));
+ int rsymSize = rsym ? getSize(rsym->type) : 0;
+
+ 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 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 */
- if (sym->stack)
+ if (stackAdjust)
{
-
- int i = sym->stack;
-// if (i > 256)
-// werror (W_STACK_OVERFLOW, sym->name);
-
- adjustStack (-i);
+ adjustStack (-stackAdjust);
}
_G.stackOfs = sym->stack;
_G.stackPushes = 0;
-
+
/* if critical function then turn interrupts off */
if (IFFUNC_ISCRITICAL (ftype))
{
- if (IFFUNC_ARGS (ftype))
+ if (!accIsFree)
{
/* Function was passed parameters, so make sure A is preserved */
pushReg (hc08_reg_a, FALSE);
/* 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));
{
int i;
regs *reg;
-
+
/* For the high level labels we cannot depend on any */
/* register's contents. Amnesia time. */
for (i=A_IDX;i<=XA_IDX;i++)
/* special case never generate */
if (IC_LABEL (ic) == entryLabel)
return;
-
+
debugFile->writeLabel(IC_LABEL (ic), ic);
- emitcode ("", "%05d$:", (IC_LABEL (ic)->key + 100));
+ 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;
bool needpulh;
bool needpula;
unsigned int size = getDataSize (IC_RESULT (ic));
- int offset;
+ unsigned int offset;
symbol *tlbl = NULL;
-
+
left = IC_LEFT (ic);
result = IC_RESULT (ic);
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))));
- D(emitcode ("", "; IS_AOP_HX = %d", IS_AOP_HX (AOP (left))));
-
if ((IS_AOP_HX (AOP (left)) ||
( (AOP_TYPE (left) == AOP_DIR) && (AOP_TYPE (result) == AOP_DIR) )
)
return TRUE;
}
- D(emitcode ("", "; icount = %d, sameRegs=%d", icount,
+ DD(emitcode ("", "; icount = %d, sameRegs=%d", icount,
sameRegs (AOP (left), AOP (result))));
-
+
if ((icount > 255) || (icount<0))
return FALSE;
if (size>1)
emitLabel (tlbl);
-
+
pullOrFreeReg (hc08_reg_a, needpula);
-
+
return TRUE;
}
if (genPlusIncr (ic) == TRUE)
goto release;
- D(emitcode("","; left size = %d", getDataSize (IC_LEFT(ic))));
- D(emitcode("","; right size = %d", getDataSize (IC_RIGHT(ic))));
- D(emitcode("","; result size = %d", getDataSize (IC_RESULT(ic))));
-
+ DD(emitcode("","; left size = %d", getDataSize (IC_LEFT(ic))));
+ DD(emitcode("","; right size = %d", getDataSize (IC_RIGHT(ic))));
+ DD(emitcode("","; result size = %d", getDataSize (IC_RESULT(ic))));
+
size = getDataSize (IC_RESULT (ic));
leftOp = AOP(IC_LEFT(ic));
}
/*-----------------------------------------------------------------*/
-/* genMinusDec :- does subtraction with deccrement if possible */
+/* genMinusDec :- does subtraction with decrement if possible */
/*-----------------------------------------------------------------*/
static bool
genMinusDec (iCode * ic)
unsigned int size = getDataSize (IC_RESULT (ic));
// int offset;
// symbol *tlbl;
-
+
left = IC_LEFT (ic);
result = IC_RESULT (ic);
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))
needpulh = FALSE;
}
loadRegFromAop (hc08_reg_hx, AOP(left), 0);
- emitcode ("aix","#%d", -icount);
+ emitcode ("aix","#%d", -(int) icount);
hc08_dirtyReg (hc08_reg_hx, FALSE);
storeRegToAop (hc08_reg_hx, AOP(result), 0);
pullOrFreeReg (hc08_reg_h, needpulh);
pullOrFreeReg (hc08_reg_x, needpulx);
return TRUE;
}
-
+
if ((icount > 1) || (icount<0))
return FALSE;
D(emitcode ("; genMinusDec",""));
rmwWithAop ("dec", AOP (result), 0);
-
+
return TRUE;
}
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++);
}
}
{
char *sub;
int size, offset = 0;
-
+
asmop *leftOp, *rightOp;
D(emitcode ("; genMinus",""));
leftOp = AOP(IC_LEFT(ic));
rightOp = AOP(IC_RIGHT(ic));
-
sub = "sub";
offset = 0;
+
+ if (IS_AOP_A (rightOp))
+ {
+ loadRegFromAop ( hc08_reg_a, rightOp, offset);
+ accopWithAop (sub, leftOp, offset);
+ accopWithMisc ("nega", "");
+ storeRegToAop (hc08_reg_a, AOP (IC_RESULT (ic)), offset++);
+ goto release;
+ }
+
while (size--)
{
loadRegFromAop ( hc08_reg_a, leftOp, offset);
- accopWithAop(sub, rightOp, offset);
+ accopWithAop (sub, rightOp, offset);
storeRegToAop (hc08_reg_a, AOP (IC_RESULT (ic)), offset++);
sub = "sbc";
}
-
-
+
+
// adjustArithmeticResult (ic);
release:
/*-----------------------------------------------------------------*/
static void
genMultOneByte (operand * left,
- operand * right,
- operand * result)
+ operand * right,
+ operand * result)
{
/* sym_link *opetype = operandType (result); */
symbol *tlbl1, *tlbl2, *tlbl3, *tlbl4;
int size=AOP_SIZE(result);
bool negLiteral = FALSE;
+ bool lUnsigned, rUnsigned;
D(emitcode ("; genMultOneByte",""));
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);
+ fprintf (stderr, "size!=1||2 (%d) in %s at line:%d \n",
+ AOP_SIZE(result), __FILE__, lineno);
exit (1);
}
operand *t = right;
right = left;
left = t;
- //D(emitcode (";", "swapped left and right"));
}
-
+ /* if an operand is in A, make sure it is on the left */
+ if (IS_AOP_A (AOP (right)))
+ {
+ operand *t = right;
+ right = left;
+ left = t;
+ }
+
+ lUnsigned = SPEC_USIGN (getSpec (operandType (left)));
+ rUnsigned = SPEC_USIGN (getSpec (operandType (right)));
+
+ /* lUnsigned rUnsigned negLiteral negate case */
+ /* false false false odd 3 */
+ /* false false true even 3 */
+ /* false true false odd 3 */
+ /* false true true impossible */
+ /* true false false odd 3 */
+ /* true false true always 2 */
+ /* true true false never 1 */
+ /* true true true impossible */
+
+ /* case 1 */
if (size == 1
- || (SPEC_USIGN(operandType(left)) &&
- SPEC_USIGN(operandType(right))))
+ || (lUnsigned && rUnsigned))
{
// just an unsigned 8*8=8/16 multiply
- //D(emitcode (";","unsigned"));
+ //DD(emitcode (";","unsigned"));
loadRegFromAop (hc08_reg_a, AOP (left), 0);
loadRegFromAop (hc08_reg_x, AOP (right), 0);
hc08_dirtyReg (hc08_reg_xa, FALSE);
storeRegToFullAop (hc08_reg_xa, AOP (result), TRUE);
hc08_freeReg (hc08_reg_xa);
-
+
return;
}
// we have to do a signed multiply
+ /* case 2 */
+ /* left unsigned, right signed literal -- literal determines sign handling */
+ if (AOP_TYPE(right)==AOP_LIT && lUnsigned && !rUnsigned)
+ {
+ signed char val=(signed char) ulFromVal (AOP (right)->aopu.aop_lit);
+
+ loadRegFromAop (hc08_reg_a, AOP (left), 0);
+ if (val < 0)
+ emitcode ("ldx", "#0x%02x", -val);
+ else
+ emitcode ("ldx", "#0x%02x", val);
+
+ emitcode ("mul", "");
+
+ if (val < 0)
+ {
+ rmwWithReg ("neg", hc08_reg_a);
+ tlbl4 = newiTempLabel (NULL);
+ emitBranch ("bcc", tlbl4);
+ rmwWithReg ("inc", hc08_reg_x);
+ emitLabel (tlbl4);
+ rmwWithReg ("neg", hc08_reg_x);
+ }
+
+ hc08_dirtyReg (hc08_reg_xa, FALSE);
+ storeRegToFullAop (hc08_reg_xa, AOP (result), TRUE);
+ hc08_freeReg (hc08_reg_xa);
+ return;
+ }
- //D(emitcode (";", "signed"));
+
+ /* case 3 */
adjustStack (-1);
emitcode ("clr", "1,s");
- tlbl1 = newiTempLabel (NULL);
loadRegFromAop (hc08_reg_a, AOP (left), 0);
- emitcode ("tsta","");
- emitBranch ("bpl", tlbl1);
- emitcode ("inc", "1,s");
- rmwWithReg ("neg", hc08_reg_a);
- emitLabel (tlbl1);
+ if (!lUnsigned)
+ {
+ tlbl1 = newiTempLabel (NULL);
+ emitcode ("tsta","");
+ emitBranch ("bpl", tlbl1);
+ emitcode ("inc", "1,s");
+ rmwWithReg ("neg", hc08_reg_a);
+ emitLabel (tlbl1);
+ }
- if (AOP_TYPE(right)==AOP_LIT)
+ if (AOP_TYPE(right)==AOP_LIT && !rUnsigned)
{
- signed char val=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);
}
else
{
- tlbl2 = newiTempLabel (NULL);
loadRegFromAop (hc08_reg_x, AOP (right), 0);
- emitcode ("tstx", "");
- emitBranch ("bpl", tlbl2);
- emitcode ("inc", "1,s");
- rmwWithReg ("neg", hc08_reg_x);
- emitLabel (tlbl2);
+ if (!rUnsigned)
+ {
+ tlbl2 = newiTempLabel (NULL);
+ emitcode ("tstx", "");
+ emitBranch ("bpl", tlbl2);
+ emitcode ("inc", "1,s");
+ rmwWithReg ("neg", hc08_reg_x);
+ emitLabel (tlbl2);
+ }
}
emitcode ("mul", "");
tlbl3 = newiTempLabel (NULL);
emitcode ("dec", "1,s");
- if (negLiteral)
- emitBranch ("bne", tlbl3);
- else
+ if (!lUnsigned && !rUnsigned && negLiteral)
emitBranch ("beq", tlbl3);
+ else
+ emitBranch ("bne", tlbl3);
rmwWithReg ("neg", hc08_reg_a);
- if (size>1)
- {
- tlbl4 = newiTempLabel (NULL);
- emitBranch ("bcc", tlbl4);
- rmwWithReg ("inc", hc08_reg_x);
- emitLabel (tlbl4);
- rmwWithReg ("neg", hc08_reg_x);
- }
+ tlbl4 = newiTempLabel (NULL);
+ emitBranch ("bcc", tlbl4);
+ rmwWithReg ("inc", hc08_reg_x);
+ emitLabel (tlbl4);
+ rmwWithReg ("neg", hc08_reg_x);
emitLabel (tlbl3);
adjustStack (1);
/* special cases first */
/* if both are of size == 1 */
-// if (getSize(operandType(left)) == 1 &&
+// if (getSize(operandType(left)) == 1 &&
// getSize(operandType(right)) == 1)
- if (AOP_SIZE (left) == 1 &&
+ if (AOP_SIZE (left) == 1 &&
AOP_SIZE (right) == 1)
{
genMultOneByte (left, right, result);
/* 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)
{
- sym_link *opetype = operandType (result);
-// char *l;
- symbol *tlbl1, *tlbl2, *tlbl3, *tlbl4;
+ symbol *tlbl1, *tlbl2, *tlbl3;
int size;
- bool negLiteral = FALSE;
+ int offset = 0;
+ bool lUnsigned, rUnsigned;
+ bool runtimeSign, compiletimeSign;
+
+ lUnsigned = SPEC_USIGN (getSpec (operandType (left)));
+ rUnsigned = SPEC_USIGN (getSpec (operandType (right)));
D(emitcode ("; genDivOneByte",""));
size = AOP_SIZE (result);
/* signed or unsigned */
- if (SPEC_USIGN (opetype))
+ if (lUnsigned && rUnsigned)
{
/* unsigned is easy */
loadRegFromAop (hc08_reg_h, AOP (left), 1);
- loadRegFromAop (hc08_reg_a, AOP (left), 0);
loadRegFromAop (hc08_reg_x, AOP (right), 0);
+ loadRegFromAop (hc08_reg_a, AOP (left), 0);
emitcode ("div", "");
hc08_dirtyReg (hc08_reg_a, FALSE);
hc08_dirtyReg (hc08_reg_h, FALSE);
/* signed is a little bit more difficult */
- adjustStack (-1);
- emitcode ("clr", "1,s");
+ /* now sign adjust for both left & right */
- tlbl1 = newiTempLabel (NULL);
- tlbl2 = newiTempLabel (NULL);
- loadRegFromAop (hc08_reg_a, AOP (left), 0);
- loadRegFromAop (hc08_reg_x, AOP (left), 1);
- emitBranch ("bpl", tlbl1);
- emitcode ("inc", "1,s");
- rmwWithReg ("neg", hc08_reg_a);
- emitBranch ("bcc", tlbl2);
- rmwWithReg ("inc", hc08_reg_x);
- emitLabel (tlbl2);
- rmwWithReg ("neg", hc08_reg_x);
- transferRegReg (hc08_reg_x, hc08_reg_h, TRUE);
- emitLabel (tlbl1);
+ /* let's see what's needed: */
+ /* apply negative sign during runtime */
+ runtimeSign = FALSE;
+ /* negative sign from literals */
+ compiletimeSign = FALSE;
- if (AOP_TYPE(right)==AOP_LIT)
+ if (!lUnsigned)
{
- signed char val=floatFromVal (AOP (right)->aopu.aop_lit);
- /* AND literal negative */
- if (val < 0) {
+ if (AOP_TYPE(left) == AOP_LIT)
+ {
+ /* signed literal */
+ signed char val = (char) ulFromVal (AOP (left)->aopu.aop_lit);
+ if (val < 0)
+ compiletimeSign = TRUE;
+ }
+ else
+ /* signed but not literal */
+ runtimeSign = TRUE;
+ }
+
+ if (!rUnsigned)
+ {
+ if (AOP_TYPE(right) == AOP_LIT)
+ {
+ /* signed literal */
+ signed char val = (char) ulFromVal (AOP (right)->aopu.aop_lit);
+ if (val < 0)
+ compiletimeSign ^= TRUE;
+ }
+ else
+ /* signed but not literal */
+ runtimeSign = TRUE;
+ }
+
+ /* initialize the runtime sign */
+ if (runtimeSign)
+ {
+ if (compiletimeSign)
+ loadRegFromConst (hc08_reg_x, "#1"); /* set sign flag */
+ else
+ loadRegFromConst (hc08_reg_x, zero); /* reset sign flag */
+ pushReg (hc08_reg_x, TRUE);
+ }
+
+ /* save the signs of the operands */
+ if (AOP_TYPE(right) == AOP_LIT)
+ {
+ signed char val = (char) ulFromVal (AOP (right)->aopu.aop_lit);
+
+ if (!rUnsigned && val < 0)
emitcode ("ldx", "#0x%02x", -val);
- negLiteral = TRUE;
- } else {
- emitcode ("ldx", "#0x%02x", val);
- }
- hc08_useReg (hc08_reg_x);
+ else
+ emitcode ("ldx", "#0x%02x", (unsigned char) val);
}
- else
+ else /* ! literal */
{
- tlbl3 = newiTempLabel (NULL);
loadRegFromAop (hc08_reg_x, AOP (right), 0);
- emitBranch ("bpl", tlbl3);
- emitcode ("inc", "1,s");
- rmwWithReg ("neg", hc08_reg_x);
- emitLabel (tlbl3);
+ if (!rUnsigned)
+ {
+ tlbl1 = newiTempLabel (NULL);
+ emitcode ("tstx", "");
+ emitBranch ("bpl", tlbl1);
+ emitcode ("inc", "1,s");
+ rmwWithReg ("neg", hc08_reg_x);
+ emitLabel (tlbl1);
+ }
+ }
+
+ if (AOP_TYPE(left) == AOP_LIT)
+ {
+ signed char val = (char) ulFromVal (AOP (left)->aopu.aop_lit);
+
+ if (!lUnsigned && val < 0)
+ emitcode ("lda", "#0x%02x", -val);
+ else
+ emitcode ("lda", "#0x%02x", (unsigned char) val);
+ }
+ else /* ! literal */
+ {
+ loadRegFromAop (hc08_reg_a, AOP (left), 0);
+ if (!lUnsigned)
+ {
+ tlbl2 = newiTempLabel (NULL);
+ emitcode ("tsta", "");
+ emitBranch ("bpl", tlbl2);
+ emitcode ("inc", "1,s");
+ rmwWithReg ("neg", hc08_reg_a);
+ emitLabel (tlbl2);
+ }
}
+ loadRegFromConst (hc08_reg_h, zero);
emitcode ("div", "");
hc08_dirtyReg (hc08_reg_x, FALSE);
hc08_dirtyReg (hc08_reg_a, FALSE);
hc08_dirtyReg (hc08_reg_h, FALSE);
- tlbl4 = newiTempLabel (NULL);
- emitcode ("dec", "1,s");
- if (negLiteral)
- emitBranch ("bne", tlbl4);
+ if (runtimeSign || compiletimeSign)
+ {
+ tlbl3 = newiTempLabel (NULL);
+ if (runtimeSign)
+ {
+ pullReg (hc08_reg_x);
+ rmwWithReg ("lsr", hc08_reg_x);
+ rmwWithReg ("ror", hc08_reg_x);
+ emitBranch ("bpl", tlbl3);
+ }
+
+ rmwWithReg ("neg", hc08_reg_a);
+ if (runtimeSign)
+ emitLabel (tlbl3);
+
+ storeRegToAop (hc08_reg_a, AOP (result), 0);
+
+ if (size > 1)
+ {
+ /* msb is 0x00 or 0xff depending on the sign */
+ if (runtimeSign)
+ {
+ rmwWithReg ("lsl", hc08_reg_x);
+ emitcode ("clra", "");
+ emitcode ("sbc", "#0");
+ while (--size)
+ storeRegToAop (hc08_reg_a, AOP (result), ++offset);
+ }
+ else /* compiletimeSign */
+ while (--size)
+ storeConstToAop ("#0xff", AOP (result), ++offset);
+ }
+ }
else
- emitBranch ("beq", tlbl4);
- rmwWithReg ("neg", hc08_reg_a);
+ {
+ storeRegToFullAop (hc08_reg_a, AOP (result), FALSE);
+ }
- emitLabel (tlbl4);
- adjustStack (1);
- storeRegToFullAop (hc08_reg_a, AOP (result), TRUE);
hc08_freeReg (hc08_reg_a);
hc08_freeReg (hc08_reg_x);
hc08_freeReg (hc08_reg_h);
-
-
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static void
genModOneByte (operand * left,
- operand * right,
- operand * result)
+ operand * right,
+ operand * result)
{
- sym_link *opetype = operandType (result);
-// symbol *lbl;
- symbol *tlbl1, *tlbl2, *tlbl3, *tlbl4;
+ symbol *tlbl1, *tlbl2, *tlbl3;
int size;
- bool negLiteral = FALSE;
+ int offset = 0;
+ bool lUnsigned, rUnsigned;
+ bool runtimeSign, compiletimeSign;
+
+ lUnsigned = SPEC_USIGN (getSpec (operandType (left)));
+ rUnsigned = SPEC_USIGN (getSpec (operandType (right)));
D(emitcode ("; genModOneByte",""));
size = AOP_SIZE (result);
- /* signed or unsigned */
- if (SPEC_USIGN (opetype))
+
+ if (lUnsigned && rUnsigned)
{
/* unsigned is easy */
+ loadRegFromAop (hc08_reg_x, AOP (right), 0);
loadRegFromAop (hc08_reg_h, AOP (left), 1);
loadRegFromAop (hc08_reg_a, AOP (left), 0);
- loadRegFromAop (hc08_reg_x, AOP (right), 0);
emitcode ("div", "");
- hc08_dirtyReg (hc08_reg_a, FALSE);
- hc08_dirtyReg (hc08_reg_h, FALSE);
- storeRegToFullAop (hc08_reg_h, AOP (result), FALSE);
hc08_freeReg (hc08_reg_a);
hc08_freeReg (hc08_reg_x);
+ hc08_dirtyReg (hc08_reg_h, FALSE);
+ storeRegToFullAop (hc08_reg_h, AOP (result), FALSE);
hc08_freeReg (hc08_reg_h);
return;
}
/* signed is a little bit more difficult */
- adjustStack (-1);
- emitcode ("clr", "1,s");
-
- tlbl1 = newiTempLabel (NULL);
- tlbl2 = newiTempLabel (NULL);
- loadRegFromAop (hc08_reg_a, AOP (left), 0);
- loadRegFromAop (hc08_reg_x, AOP (left), 1);
- emitBranch ("bpl", tlbl1);
- emitcode ("inc", "1,s");
- rmwWithReg ("neg", hc08_reg_a);
- emitBranch ("bcc", tlbl2);
- rmwWithReg ("inc", hc08_reg_x);
- emitLabel (tlbl2);
- rmwWithReg ("neg", hc08_reg_x);
- transferRegReg (hc08_reg_x, hc08_reg_h, TRUE);
- emitLabel (tlbl1);
-
- if (AOP_TYPE(right)==AOP_LIT)
+ if (AOP_TYPE(right) == AOP_LIT)
{
- signed char val=floatFromVal (AOP (right)->aopu.aop_lit);
- /* AND literal negative */
- if (val < 0) {
+ signed char val = (char) ulFromVal (AOP (right)->aopu.aop_lit);
+
+ if (!rUnsigned && val < 0)
emitcode ("ldx", "#0x%02x", -val);
- negLiteral = TRUE;
- } else {
- emitcode ("ldx", "#0x%02x", val);
- }
- hc08_useReg (hc08_reg_x);
+ else
+ emitcode ("ldx", "#0x%02x", (unsigned char) val);
}
- else
+ else /* ! literal */
{
- tlbl3 = newiTempLabel (NULL);
loadRegFromAop (hc08_reg_x, AOP (right), 0);
- emitBranch ("bpl", tlbl3);
- emitcode ("inc", "1,s");
- rmwWithReg ("neg", hc08_reg_x);
- emitLabel (tlbl3);
+ if (!rUnsigned)
+ {
+ tlbl1 = newiTempLabel (NULL);
+ emitcode ("tstx", "");
+ emitBranch ("bpl", tlbl1);
+ rmwWithReg ("neg", hc08_reg_x);
+ emitLabel (tlbl1);
+ }
}
+ /* let's see what's needed: */
+ /* apply negative sign during runtime */
+ runtimeSign = FALSE;
+ /* negative sign from literals */
+ compiletimeSign = FALSE;
+
+ /* sign adjust left side */
+ if (AOP_TYPE(left) == AOP_LIT)
+ {
+ signed char val = (char) ulFromVal (AOP (left)->aopu.aop_lit);
+
+ if (!lUnsigned && val < 0)
+ {
+ compiletimeSign = TRUE; /* set sign flag */
+ emitcode ("lda", "#0x%02x", -val);
+ }
+ else
+ emitcode ("lda", "#0x%02x", (unsigned char) val);
+ }
+ else /* ! literal */
+ {
+ if (lUnsigned)
+ loadRegFromAop (hc08_reg_a, AOP (left), 0);
+ else
+ {
+ runtimeSign = TRUE;
+ adjustStack (-1);
+ emitcode ("clr", "1,s");
+
+ loadRegFromAop (hc08_reg_a, AOP (left), 0);
+ tlbl2 = newiTempLabel (NULL);
+ emitcode ("tsta", "");
+ emitBranch ("bpl", tlbl2);
+ emitcode ("inc", "1,s");
+ rmwWithReg ("neg", hc08_reg_a);
+ emitLabel (tlbl2);
+ }
+ }
+
+ loadRegFromConst (hc08_reg_h, zero);
emitcode ("div", "");
- hc08_dirtyReg (hc08_reg_x, FALSE);
- hc08_dirtyReg (hc08_reg_a, FALSE);
+ hc08_freeReg (hc08_reg_a);
+ hc08_freeReg (hc08_reg_x);
hc08_dirtyReg (hc08_reg_h, FALSE);
- tlbl4 = newiTempLabel (NULL);
- transferRegReg (hc08_reg_h, hc08_reg_a, TRUE);
- emitcode ("dec", "1,s");
- if (negLiteral)
- emitBranch ("bne", tlbl4);
+ if (runtimeSign || compiletimeSign)
+ {
+ transferRegReg (hc08_reg_h, hc08_reg_a, TRUE);
+ tlbl3 = newiTempLabel (NULL);
+ if (runtimeSign)
+ {
+ pullReg (hc08_reg_x);
+ rmwWithReg ("lsr", hc08_reg_x);
+ rmwWithReg ("ror", hc08_reg_x);
+ emitBranch ("bpl", tlbl3);
+ }
+
+ rmwWithReg ("neg", hc08_reg_a);
+ if (runtimeSign)
+ emitLabel (tlbl3);
+
+ storeRegToAop (hc08_reg_a, AOP (result), 0);
+
+ if (size > 1)
+ {
+ /* msb is 0x00 or 0xff depending on the sign */
+ if (runtimeSign)
+ {
+ rmwWithReg ("lsl", hc08_reg_x);
+ emitcode ("clra", "");
+ emitcode ("sbc", "#0");
+ while (--size)
+ storeRegToAop (hc08_reg_a, AOP (result), ++offset);
+ }
+ else /* compiletimeSign */
+ while (--size)
+ storeConstToAop ("#0xff", AOP (result), ++offset);
+ }
+ }
else
- emitBranch ("beq", tlbl4);
- rmwWithReg ("neg", hc08_reg_a);
+ {
+ storeRegToFullAop (hc08_reg_h, AOP (result), FALSE);
+ }
- emitLabel (tlbl4);
- adjustStack (1);
- storeRegToFullAop (hc08_reg_a, AOP (result), TRUE);
hc08_freeReg (hc08_reg_a);
hc08_freeReg (hc08_reg_x);
hc08_freeReg (hc08_reg_h);
-
}
/*-----------------------------------------------------------------*/
ic->generated = 1;
}
+
/*-----------------------------------------------------------------*/
-/* genCmp :- greater or less than comparison */
+/* exchangedCmp : returns the opcode need if the two operands are */
+/* exchanged in a comparison */
/*-----------------------------------------------------------------*/
-static void
-genCmp (operand * left, operand * right,
- operand * result, iCode * ifx, int sign, iCode *ic)
-{
- int size, offset = 0;
- unsigned long lit = 0L;
- char *sub;
- bool needpula = FALSE;
-
- D(emitcode ("; genCmp",""));
-
- /* subtract right from left if at the
- end the carry flag is set then we know that
- left is greater than right */
- size = max (AOP_SIZE (left), AOP_SIZE (right));
+static int
+exchangedCmp (int opcode)
+{
+ switch (opcode)
+ {
+ case '<':
+ return '>';
+ case '>':
+ return '<';
+ case LE_OP:
+ return GE_OP;
+ case GE_OP:
+ return LE_OP;
+ case NE_OP:
+ return NE_OP;
+ case EQ_OP:
+ return EQ_OP;
+ default:
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "opcode not a comparison");
+ }
+ return EQ_OP; /* shouldn't happen, but need to return something */
+}
- if (AOP_TYPE (right) == AOP_LIT)
- {
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
- /* optimize if(x < 0) or if(x >= 0) */
- if (lit == 0L)
- {
- if (!sign)
- {
- CLRC;
- }
- else
- {
- loadRegFromAop (hc08_reg_a, AOP (left), AOP_SIZE (left) -1);
- emitcode ("rola", "");
- hc08_useReg (hc08_reg_a);
- }
- sign = 0;
- goto release;
- }
+/*------------------------------------------------------------------*/
+/* negatedCmp : returns the equivalent opcode for when a comparison */
+/* if not true */
+/*------------------------------------------------------------------*/
+static int
+negatedCmp (int opcode)
+{
+ switch (opcode)
+ {
+ case '<':
+ return GE_OP;
+ case '>':
+ return LE_OP;
+ case LE_OP:
+ return '>';
+ case GE_OP:
+ return '<';
+ case NE_OP:
+ return EQ_OP;
+ case EQ_OP:
+ return NE_OP;
+ default:
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "opcode not a comparison");
}
+ return EQ_OP; /* shouldn't happen, but need to return something */
+}
- if ((size==2)
- && ((AOP_TYPE (right) == AOP_LIT) ||
- ((AOP_TYPE (right) == AOP_DIR) && (AOP_SIZE (right) == 2)) )
- && hc08_reg_hx->isFree)
- {
- loadRegFromAop (hc08_reg_hx, AOP (left), 0);
- emitcode ("cphx","%s", aopAdrStr (AOP (right), 1, TRUE));
- hc08_freeReg (hc08_reg_hx);
- goto release;
+/*------------------------------------------------------------------*/
+/* nameCmp : helper function for human readable debug output */
+/*------------------------------------------------------------------*/
+static char *
+nameCmp (int opcode)
+{
+ switch (opcode)
+ {
+ case '<':
+ return "<";
+ case '>':
+ return ">";
+ case LE_OP:
+ return "<=";
+ case GE_OP:
+ return ">=";
+ case NE_OP:
+ return "!=";
+ case EQ_OP:
+ return "==";
+ default:
+ return "invalid";
}
+}
- offset = 0;
- if (size==1)
- sub="cmp";
- else
- sub="sub";
- while (size--)
- {
- loadRegFromAop (hc08_reg_a, AOP (left), offset);
- accopWithAop (sub, AOP (right), offset);
- hc08_freeReg (hc08_reg_a);
- offset++;
- sub="sbc";
- }
-
-release:
- freeAsmop (right, NULL, ic, TRUE);
- freeAsmop (left, NULL, ic, TRUE);
- if (AOP_TYPE (result) == AOP_CRY && AOP_SIZE (result))
- {
- outBitC (result);
- }
- else
+/*------------------------------------------------------------------*/
+/* branchInstCmp : returns the conditional branch instruction that */
+/* will branch if the comparison is true */
+/*------------------------------------------------------------------*/
+static char *
+branchInstCmp (int opcode, int sign)
+{
+ switch (opcode)
{
- /* if the result is used in the next
- ifx conditional branch then generate
- code a little differently */
- if (ifx)
- {
- pullOrFreeReg(hc08_reg_a,needpula);
- genIfxJump (ifx, sign ? "s" : "c");
- }
+ case '<':
+ if (sign)
+ return "blt";
+ else
+ return "bcs"; /* same as blo */
+ case '>':
+ if (sign)
+ return "bgt";
+ else
+ return "bhi";
+ case LE_OP:
+ if (sign)
+ return "ble";
+ else
+ return "bls";
+ case GE_OP:
+ if (sign)
+ return "bge";
else
- if (!sign)
- outBitC (result);
- else
- outBitNV (result);
- pullOrFreeReg(hc08_reg_a,needpula);
+ 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");
}
+ return "brn";
}
-/*-----------------------------------------------------------------*/
-/* genCmpGt :- greater than comparison */
-/*-----------------------------------------------------------------*/
+
+/*------------------------------------------------------------------*/
+/* genCmp :- greater or less than (and maybe with equal) comparison */
+/*------------------------------------------------------------------*/
static void
-genCmpGt (iCode * ic, iCode * ifx)
+genCmp (iCode * ic, iCode * ifx)
{
operand *left, *right, *result;
sym_link *letype, *retype;
- int sign;
+ int sign, opcode;
+ int size, offset = 0;
+ unsigned long lit = 0L;
+ char *sub;
+ symbol *jlbl = NULL;
+
+ opcode = ic->op;
- D(emitcode ("; genCmpGt",""));
+ D(emitcode ("; genCmp", "(%s)",nameCmp (opcode)));
result = IC_RESULT (ic);
left = IC_LEFT (ic);
aopOp (right, ic, FALSE);
aopOp (result, ic, TRUE);
- genCmp (right, left, result, ifx, sign,ic);
+ /* need register operand on left, prefer literal operand on right */
+ if ((AOP_TYPE (right) == AOP_REG) || AOP_TYPE (left) == AOP_LIT)
+ {
+ operand *temp = left;
+ left = right;
+ right = temp;
+ opcode = exchangedCmp (opcode);
+ }
+
+ if (ifx)
+ {
+ if (IC_TRUE (ifx))
+ {
+ jlbl = IC_TRUE (ifx);
+ opcode = negatedCmp (opcode);
+ }
+ else
+ {
+ /* false label is present */
+ jlbl = IC_FALSE (ifx);
+ }
+ }
+
+ size = max (AOP_SIZE (left), AOP_SIZE (right));
+
+ if ((size == 2)
+ && ((AOP_TYPE (left) == AOP_DIR) && (AOP_SIZE (left) == 2))
+ && ((AOP_TYPE (right) == AOP_LIT) ||
+ ((AOP_TYPE (right) == AOP_DIR) && (AOP_SIZE (right) == 2)) )
+ && hc08_reg_hx->isFree)
+ {
+ loadRegFromAop (hc08_reg_hx, AOP (left), 0);
+ emitcode ("cphx","%s", aopAdrStr (AOP (right), 1, TRUE));
+ hc08_freeReg (hc08_reg_hx);
+ }
+ else
+ {
+ offset = 0;
+ if (size == 1)
+ sub = "cmp";
+ else
+ {
+ sub = "sub";
+
+ /* These conditions depend on the Z flag bit, but Z is */
+ /* only valid for the last byte of the comparison, not */
+ /* the whole value. So exchange the operands to get a */
+ /* comparison that doesn't depend on Z. (This is safe */
+ /* to do here since ralloc won't assign multi-byte */
+ /* operands to registers for comparisons) */
+ if ((opcode == '>') || (opcode == LE_OP))
+ {
+ operand *temp = left;
+ left = right;
+ right = temp;
+ opcode = exchangedCmp (opcode);
+ }
+
+ if ((AOP_TYPE (right) == AOP_LIT) && !isOperandVolatile (left, FALSE))
+ {
+ lit = ulFromVal (AOP (right)->aopu.aop_lit);
+ while ((size > 1) && (((lit >> (8*offset)) & 0xff) == 0))
+ {
+ offset++;
+ size--;
+ }
+ }
+ }
+ while (size--)
+ {
+ loadRegFromAop (hc08_reg_a, AOP (left), offset);
+ accopWithAop (sub, AOP (right), offset);
+ hc08_freeReg (hc08_reg_a);
+ offset++;
+ sub = "sbc";
+ }
+ }
+ freeAsmop (right, NULL, ic, FALSE);
+ freeAsmop (left, NULL, ic, FALSE);
+
+ if (ifx)
+ {
+ symbol *tlbl = newiTempLabel (NULL);
+ char *inst;
+
+ freeAsmop (result, NULL, ic, TRUE);
+
+ inst = branchInstCmp (opcode, sign);
+ emitBranch (inst, tlbl);
+ emitBranch ("jmp", jlbl);
+ emitLabel (tlbl);
+
+ /* mark the icode as generated */
+ ifx->generated = 1;
+ }
+ else
+ {
+ symbol *tlbl1 = newiTempLabel (NULL);
+ symbol *tlbl2 = newiTempLabel (NULL);
+
+ emitBranch (branchInstCmp (opcode, sign), tlbl1);
+ loadRegFromConst (hc08_reg_a, zero);
+ emitBranch ("bra", tlbl2);
+ emitLabel (tlbl1);
+ loadRegFromConst (hc08_reg_a, one);
+ emitLabel (tlbl2);
+ storeRegToFullAop (hc08_reg_a, AOP(result), FALSE);
+ freeAsmop (result, NULL, ic, TRUE);
+ }
- freeAsmop (result, NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
-/* genCmpLt - less than comparisons */
+/* genCmpEQorNE - equal or not equal comparison */
/*-----------------------------------------------------------------*/
static void
-genCmpLt (iCode * ic, iCode * ifx)
+genCmpEQorNE (iCode * ic, iCode * ifx)
{
operand *left, *right, *result;
sym_link *letype, *retype;
- int sign;
+ int sign, opcode;
+ int size, offset = 0;
+ char *sub;
+ symbol *jlbl = NULL;
+ symbol *tlbl_NE = NULL;
+ symbol *tlbl_EQ = NULL;
- D(emitcode ("; genCmpLt",""));
+ opcode = ic->op;
+
+ D(emitcode ("; genCmpEQorNE", "(%s)",nameCmp (opcode)));
result = IC_RESULT (ic);
left = IC_LEFT (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,ic);
-
- freeAsmop (result, NULL, ic, TRUE);
-}
-
-/*-----------------------------------------------------------------*/
-/* - compare and branch if not equal */
-/*-----------------------------------------------------------------*/
-static void
-gencbneshort (operand * left, operand * right, symbol * lbl)
-{
- int size = max (AOP_SIZE (left), AOP_SIZE (right));
- int offset = 0;
- unsigned long lit = 0L;
-
- /* 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)
+ /* need register operand on left, prefer literal operand on right */
+ if ((AOP_TYPE (right) == AOP_REG) || AOP_TYPE (left) == AOP_LIT)
{
- operand *t = right;
- right = left;
- left = t;
+ operand *temp = left;
+ left = right;
+ right = temp;
+ opcode = exchangedCmp (opcode);
}
- if (AOP_TYPE (right) == AOP_LIT)
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
- while (size--)
+ if (ifx)
{
- loadRegFromAop (hc08_reg_a, AOP (left), offset);
- accopWithAop ("cmp", AOP (right), offset);
- hc08_useReg (hc08_reg_a);
- hc08_freeReg (hc08_reg_a);
- emitBranch ("bne", lbl);
- offset++;
+ if (IC_TRUE (ifx))
+ {
+ jlbl = IC_TRUE (ifx);
+ opcode = negatedCmp (opcode);
+ }
+ else
+ {
+ /* false label is present */
+ jlbl = IC_FALSE (ifx);
+ }
}
-}
-
-/*-----------------------------------------------------------------*/
-/* gencjne - compare and jump if not equal */
-/*-----------------------------------------------------------------*/
-static void
-gencjne (operand * left, operand * right, symbol * lbl)
-{
- symbol *tlbl = newiTempLabel (NULL);
-
- gencbneshort (left, right, lbl);
-
- loadRegFromConst (hc08_reg_a, one);
- emitBranch ("bra", tlbl);
- emitLabel (lbl);
- loadRegFromConst (hc08_reg_a, zero);
- emitLabel (tlbl);
-
- hc08_useReg(hc08_reg_a);
- hc08_freeReg(hc08_reg_a);
-}
-
-/*-----------------------------------------------------------------*/
-/* genCmpEq - generates code for equal to */
-/*-----------------------------------------------------------------*/
-static void
-genCmpEq (iCode * ic, iCode * ifx)
-{
- operand *left, *right, *result;
-
- D(emitcode ("; genCmpEq",""));
-
- aopOp ((left = IC_LEFT (ic)), ic, FALSE);
- aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
- aopOp ((result = IC_RESULT (ic)), ic, TRUE);
+ size = max (AOP_SIZE (left), AOP_SIZE (right));
- /* 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 ((size == 2)
+ && ((AOP_TYPE (left) == AOP_DIR) && (AOP_SIZE (left) == 2))
+ && ((AOP_TYPE (right) == AOP_LIT) ||
+ ((AOP_TYPE (right) == AOP_DIR) && (AOP_SIZE (right) == 2)) )
+ && hc08_reg_hx->isFree)
{
- operand *t = IC_RIGHT (ic);
- IC_RIGHT (ic) = IC_LEFT (ic);
- IC_LEFT (ic) = t;
+ loadRegFromAop (hc08_reg_hx, AOP (left), 0);
+ emitcode ("cphx","%s", aopAdrStr (AOP (right), 1, TRUE));
+ hc08_freeReg (hc08_reg_hx);
+ }
+ else
+ {
+ offset = 0;
+ sub = "cmp";
+ while (size--)
+ {
+ loadRegFromAop (hc08_reg_a, AOP (left), offset);
+ accopWithAop (sub, AOP (right), offset);
+ if (size)
+ {
+ if (!tlbl_NE)
+ tlbl_NE = newiTempLabel (NULL);
+ emitBranch ("bne", tlbl_NE);
+ }
+ hc08_freeReg (hc08_reg_a);
+ offset++;
+ }
}
+ freeAsmop (right, NULL, ic, FALSE);
+ freeAsmop (left, NULL, ic, FALSE);
- if (ifx && !AOP_SIZE (result))
+ if (ifx)
{
- symbol *tlbl;
- tlbl = newiTempLabel (NULL);
- gencbneshort (left, right, tlbl);
- if (IC_TRUE (ifx))
+ freeAsmop (result, NULL, ic, TRUE);
+
+ if (opcode == EQ_OP)
{
- emitBranch ("jmp", IC_TRUE (ifx));
- emitLabel (tlbl);
+ if (!tlbl_EQ)
+ tlbl_EQ = newiTempLabel (NULL);
+ emitBranch ("beq", tlbl_EQ);
+ if (tlbl_NE)
+ emitLabel (tlbl_NE);
+ emitBranch ("jmp", jlbl);
+ emitLabel (tlbl_EQ);
}
else
- {
- symbol *lbl = newiTempLabel (NULL);
- emitBranch ("bra", lbl);
- emitLabel (tlbl);
- emitBranch ("jmp", IC_FALSE (ifx));
- emitLabel (lbl);
- }
-
+ {
+ if (!tlbl_NE)
+ tlbl_NE = newiTempLabel (NULL);
+ emitBranch ("bne", tlbl_NE);
+ emitBranch ("jmp", jlbl);
+ emitLabel (tlbl_NE);
+ }
+
/* mark the icode as generated */
ifx->generated = 1;
- goto release;
- }
-
- gencjne (left, right, newiTempLabel (NULL));
- if (AOP_TYPE (result) == AOP_CRY && AOP_SIZE (result))
- {
- storeRegToAop (hc08_reg_a, AOP (result), 0);
- goto release;
}
- if (ifx)
+ else
{
- genIfxJump (ifx, "a");
- goto release;
+ symbol *tlbl = newiTempLabel (NULL);
+
+ if (opcode == EQ_OP)
+ {
+ if (!tlbl_EQ)
+ tlbl_EQ = newiTempLabel (NULL);
+ emitBranch ("beq", tlbl_EQ);
+ if (tlbl_NE)
+ emitLabel (tlbl_NE);
+ loadRegFromConst (hc08_reg_a, zero);
+ emitBranch ("bra", tlbl);
+ emitLabel (tlbl_EQ);
+ loadRegFromConst (hc08_reg_a, one);
+ }
+ else
+ {
+ if (!tlbl_NE)
+ tlbl_NE = newiTempLabel (NULL);
+ emitBranch ("bne", tlbl_NE);
+ loadRegFromConst (hc08_reg_a, zero);
+ emitBranch ("bra", tlbl);
+ emitLabel (tlbl_NE);
+ loadRegFromConst (hc08_reg_a, one);
+ }
+
+ emitLabel (tlbl);
+ storeRegToFullAop (hc08_reg_a, AOP(result), FALSE);
+ freeAsmop (result, NULL, ic, TRUE);
}
- /* if the result is used in an arithmetic operation
- then put the result in place */
- if (AOP_TYPE (result) != AOP_CRY)
- outAcc (result);
-release:
- freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
- freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
- freeAsmop (result, NULL, ic, TRUE);
}
+
/*-----------------------------------------------------------------*/
/* ifxForOp - returns the icode containing the ifx for operand */
/*-----------------------------------------------------------------*/
{
iCode *lic = ic->next;
bool pset, pget;
- int offset, size;
+ int size;
symbol *sym;
asmop *derefaop;
/* Make sure we have a next iCode */
- D(emitcode("","; checking lic"));
+ DD(emitcode("","; checking lic"));
if (!lic)
return FALSE;
/* Make sure the result of the addition is an iCode */
- D(emitcode("","; checking IS_ITEMP"));
+ DD(emitcode("","; checking IS_ITEMP"));
if (!IS_ITEMP (IC_RESULT (ic)))
return FALSE;
/* Make sure the next iCode is a pointer set or get */
pset = POINTER_SET(lic);
pget = POINTER_GET(lic);
- D(emitcode("","; pset=%d, pget=%d",pset,pget));
+ DD(emitcode("","; pset=%d, pget=%d",pset,pget));
if (!pset && !pget)
return FALSE;
/* Make sure this is the only use of the pointer */
if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
return FALSE;
-
- D(emitcode("", "; checking pset operandsEqu"));
+
+ DD(emitcode("", "; checking pset operandsEqu"));
if (pset & !operandsEqu (IC_RESULT (ic), IC_RESULT (lic)))
return FALSE;
- D(emitcode("", "; checking pget operandsEqu"));
+ DD(emitcode("", "; checking pget operandsEqu"));
if (pget & !operandsEqu (IC_RESULT (ic), IC_LEFT (lic)))
return FALSE;
- D(emitcode("", "; checking IS_SYMOP"));
+ DD(emitcode("", "; checking IS_SYMOP"));
if (!IS_SYMOP (IC_LEFT (ic)))
return FALSE;
- D(emitcode("", "; checking !IS_TRUE_SYMOP"));
+ DD(emitcode("", "; checking !IS_TRUE_SYMOP"));
if (IS_TRUE_SYMOP (IC_LEFT (ic)))
return FALSE;
sym = OP_SYMBOL (IC_LEFT (ic));
-
- D(emitcode("", "; checking remat"));
+
+ DD(emitcode("", "; checking remat"));
if (!sym->remat)
return FALSE;
-
-
+
+
if (pget)
{
D(emitcode ("; genPointerGetOfs",""));
aopOp (IC_LEFT(ic), ic, FALSE);
derefaop = aopDerefAop (AOP (IC_LEFT (ic)));
freeAsmop (IC_LEFT(ic), NULL, ic, TRUE);
-
+
aopOp (IC_RIGHT(ic), ic, FALSE);
aopOp (IC_RESULT(lic), lic, FALSE);
loadRegFromAop (hc08_reg_hx, AOP (IC_RIGHT (ic)), 0);
size = AOP_SIZE (IC_RESULT(lic));
derefaop->size = size;
- offset=0;
-
+
while (size--)
{
emitcode ("lda", "%s,x",
- aopAdrStr (derefaop, offset, TRUE));
+ aopAdrStr (derefaop, size, TRUE));
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);
}
freeAsmop (NULL, derefaop, ic, TRUE);
freeAsmop (IC_RIGHT(ic), NULL, ic, TRUE);
freeAsmop (IC_RESULT(lic), NULL, lic, TRUE);
-
+
return TRUE;
}
aopOp (IC_RIGHT(ic), ic, FALSE);
aopOp (IC_RIGHT(lic), lic, FALSE);
-
+
if (AOP_SIZE (IC_RIGHT (ic)) == 1)
{
if (SPEC_USIGN (getSpec (operandType (IC_RIGHT (ic)))))
loadRegFromAop (hc08_reg_hx, AOP (IC_RIGHT (ic)), 0);
size = AOP_SIZE (IC_RIGHT(lic));
derefaop->size = size;
- offset=0;
-
+
while (size--)
{
- loadRegFromAop (hc08_reg_a, AOP (IC_RIGHT (lic)), offset);
+ loadRegFromAop (hc08_reg_a, AOP (IC_RIGHT (lic)), size);
emitcode ("sta", "%s,x",
- aopAdrStr (derefaop, offset, TRUE));
+ aopAdrStr (derefaop, size, TRUE));
hc08_freeReg (hc08_reg_a);
- offset++;
}
lic->generated = 1;
freeAsmop (NULL, derefaop, ic, TRUE);
freeAsmop (IC_RIGHT(ic), NULL, ic, TRUE);
freeAsmop (IC_RIGHT(lic), NULL, lic, TRUE);
-
+
return TRUE;
}
-
+
return FALSE;
}
sym_link *retype = getSpec (type);
iCode *lic = ic->next;
int isize ;
-
+
/* this could from a cast, e.g.: "(char xdata *) 0x7654;" */
if (!IS_SYMOP(op)) return NULL;
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 */
- if (bitVectBitValue(OP_USES(op),lic->key) || (unsigned) lic->defKey == op->key) {
+ if (bitVectBitValue(OP_USES(op),lic->key) || lic->defKey == op->key) {
return NULL;
}
/* if GOTO or IFX */
tlbl = newiTempLabel (NULL);
tlbl0 = newiTempLabel (NULL);
-
+
asmopToBool (AOP (left), FALSE);
emitBranch ("beq", tlbl0);
asmopToBool (AOP (right), FALSE);
hc08_useReg (hc08_reg_a);
hc08_freeReg (hc08_reg_a);
-
+
storeRegToFullAop (hc08_reg_a, AOP (result), FALSE);
freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
tlbl = newiTempLabel (NULL);
tlbl0 = newiTempLabel (NULL);
-
+
asmopToBool (AOP (left), FALSE);
emitBranch ("bne", tlbl0);
asmopToBool (AOP (right), FALSE);
hc08_useReg (hc08_reg_a);
hc08_freeReg (hc08_reg_a);
-
+
storeRegToFullAop (hc08_reg_a, AOP (result), FALSE);
int size, offset = 0;
unsigned long lit = 0L;
unsigned long litinv;
+ unsigned char bytemask;
+
-
// int bytelit = 0;
// char buffer[10];
aopOp ((result = IC_RESULT (ic)), ic, TRUE);
#ifdef DEBUG_TYPE
- D(emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
- AOP_TYPE (result),
- AOP_TYPE (left), AOP_TYPE (right)));
- D(emitcode ("", "; Size res[%d] = l[%d]&r[%d]",
- AOP_SIZE (result),
- AOP_SIZE (left), AOP_SIZE (right)));
+ DD(emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
+ 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)));
#endif
/* if left is a literal & right is not then exchange them */
left = tmp;
}
- /* if left is accumulator & right is not then exchange them */
+ /* if right is accumulator & left is not then exchange them */
if (AOP_TYPE (right) == AOP_REG && AOP_TYPE (left) != AOP_REG)
{
operand *tmp = right;
left = tmp;
}
+ if (AOP_TYPE (right) == 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 (result) == AOP_CRY)
+ if (AOP_TYPE (result) == AOP_CRY
+ && size > 1
+ && (isOperandVolatile (left, FALSE) || isOperandVolatile (right, FALSE)))
{
- symbol *tlbl;
- wassertl (ifx, "AOP_CPY result without ifx");
-
- tlbl = newiTempLabel (NULL);
- size = (AOP_SIZE (left) >= AOP_SIZE (right)) ? AOP_SIZE (left) : AOP_SIZE (right);
+ /* this generates ugly code, but meets volatility requirements */
+ loadRegFromConst (hc08_reg_a, zero);
+ pushReg (hc08_reg_a, TRUE);
+
offset = 0;
while (size--)
{
loadRegFromAop (hc08_reg_a, AOP (left), offset);
- if ((AOP_TYPE (right) == AOP_LIT)
- && (((lit >> (offset*8)) & 0xff) == 0xff))
- emitcode ("tsta","");
- else
- accopWithAop ("and", AOP (right), offset);
- hc08_freeReg( hc08_reg_a);
- if (size)
- emitBranch ("bne", tlbl);
- else
- {
- emitLabel (tlbl);
- genIfxJump (ifx, "a");
- }
+ accopWithAop ("and", AOP (right), offset);
+ emitcode ("ora", "1,s");
+ emitcode ("sta", "1,s");
offset++;
}
+
+ pullReg (hc08_reg_a);
+ emitcode ("tsta", "");
+ genIfxJump (ifx, "a");
+ goto release;
}
-
- size = AOP_SIZE (result);
+
+ if (AOP_TYPE (result) == AOP_CRY)
+ {
+ symbol *tlbl = NULL;
+ wassertl (ifx, "AOP_CRY result without ifx");
+
+ offset = 0;
+ while (size--)
+ {
+ bytemask = (lit >> (offset*8)) & 0xff;
+
+ if (AOP_TYPE (right) == AOP_LIT && bytemask == 0)
+ {
+ /* do nothing */
+ }
+ else if (AOP_TYPE (right) == AOP_LIT && bytemask == 0xff)
+ {
+ rmwWithAop ("tst", AOP (left), offset);
+ if (size)
+ {
+ if (!tlbl)
+ tlbl = newiTempLabel (NULL);
+ emitBranch ("bne", tlbl);
+ }
+ }
+ else
+ {
+ loadRegFromAop (hc08_reg_a, AOP (left), offset);
+ accopWithAop ("and", AOP (right), offset);
+ hc08_freeReg( hc08_reg_a);
+ if (size)
+ {
+ if (!tlbl)
+ tlbl = newiTempLabel (NULL);
+ emitBranch ("bne", tlbl);
+ }
+ }
+ offset++;
+ }
+ if (tlbl)
+ emitLabel (tlbl);
+ genIfxJump (ifx, "a");
+ goto release;
+ }
+
+ size = AOP_SIZE (result);
if (AOP_TYPE (right) == AOP_LIT)
{
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
litinv = (~lit) & (((unsigned int)0xffffffff) >> (8*(4-size))) ;
-
if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))) &&
(AOP_TYPE (left) == AOP_DIR) && isLiteralBit(litinv))
{
goto release;
}
}
-
+
offset = 0;
while (size--)
{
- loadRegFromAop (hc08_reg_a, AOP (left), offset);
- if ((AOP_TYPE (right) != AOP_LIT)
- || (((lit >> (offset*8)) & 0xff) != 0xff))
- accopWithAop ("and", AOP (right), offset);
- storeRegToAop (hc08_reg_a, AOP (result), offset++);
- hc08_freeReg( hc08_reg_a);
+ bytemask = (lit >> (offset*8)) & 0xff;
+
+ if (AOP_TYPE (right) == AOP_LIT && bytemask == 0)
+ {
+ if (isOperandVolatile (left, FALSE))
+ {
+ loadRegFromAop (hc08_reg_a, AOP (left), offset);
+ hc08_freeReg( hc08_reg_a);
+ }
+ storeConstToAop (zero, AOP (result), offset);
+ }
+ else if (AOP_TYPE (right) == AOP_LIT && bytemask == 0xff)
+ {
+ transferAopAop (AOP (left), offset, AOP (result), offset);
+ }
+ else
+ {
+ loadRegFromAop (hc08_reg_a, AOP (left), offset);
+ accopWithAop ("and", AOP (right), offset);
+ storeRegToAop (hc08_reg_a, AOP (result), offset);
+ hc08_freeReg (hc08_reg_a);
+ }
+ offset++;
}
release:
operand *left, *right, *result;
int size, offset = 0;
unsigned long lit = 0L;
+ unsigned char bytemask;
D(emitcode ("; genOr",""));
aopOp ((result = IC_RESULT (ic)), ic, TRUE);
#ifdef DEBUG_TYPE
- D(emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
- AOP_TYPE (result),
- AOP_TYPE (left), AOP_TYPE (right)));
- D(emitcode ("", "; Size res[%d] = l[%d]&r[%d]",
- AOP_SIZE (result),
- AOP_SIZE (left), AOP_SIZE (right)));
+ DD(emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
+ 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)));
#endif
/* if left is a literal & right is not then exchange them */
left = tmp;
}
- if (AOP_TYPE (result) == AOP_CRY)
+ if (AOP_TYPE (right) == 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 (result) == AOP_CRY
+ && size > 1
+ && (isOperandVolatile (left, FALSE) || isOperandVolatile (right, FALSE)))
{
- symbol *tlbl;
- wassertl (ifx, "AOP_CPY result without ifx");
-
- tlbl = newiTempLabel (NULL);
- size = (AOP_SIZE (left) >= AOP_SIZE (right)) ? AOP_SIZE (left) : AOP_SIZE (right);
+ /* this generates ugly code, but meets volatility requirements */
+ loadRegFromConst (hc08_reg_a, zero);
+ pushReg (hc08_reg_a, TRUE);
+
offset = 0;
while (size--)
{
loadRegFromAop (hc08_reg_a, AOP (left), offset);
- if ((AOP_TYPE (right) == AOP_LIT)
- && (((lit >> (offset*8)) & 0xff) == 0))
- emitcode ("tsta","");
- else
- accopWithAop ("ora", AOP (right), offset);
- hc08_freeReg( hc08_reg_a);
- if (size)
- emitBranch ("bne", tlbl);
+ accopWithAop ("ora", AOP (right), offset);
+ emitcode ("ora", "1,s");
+ emitcode ("sta", "1,s");
+ offset++;
+ }
+
+ pullReg (hc08_reg_a);
+ emitcode ("tsta", "");
+ genIfxJump (ifx, "a");
+ goto release;
+ }
+
+ if (AOP_TYPE (result) == AOP_CRY)
+ {
+ symbol *tlbl = NULL;
+ wassertl (ifx, "AOP_CRY result without ifx");
+
+ offset = 0;
+ while (size--)
+ {
+ bytemask = (lit >> (offset*8)) & 0xff;
+
+ if (AOP_TYPE (right) == AOP_LIT && bytemask == 0x00)
+ {
+ rmwWithAop ("tst", AOP (left), offset);
+ if (size)
+ {
+ if (!tlbl)
+ tlbl = newiTempLabel (NULL);
+ emitBranch ("bne", tlbl);
+ }
+ }
else
{
- emitLabel (tlbl);
- genIfxJump (ifx, "a");
+ loadRegFromAop (hc08_reg_a, AOP (left), offset);
+ accopWithAop ("ora", AOP (right), offset);
+ hc08_freeReg( hc08_reg_a);
+ if (size)
+ {
+ if (!tlbl)
+ tlbl = newiTempLabel (NULL);
+ emitBranch ("bne", tlbl);
+ }
}
offset++;
}
+ if (tlbl)
+ emitLabel (tlbl);
+ genIfxJump (ifx, "a");
}
-
+
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);
aopAdrStr (AOP (left), bitpos >> 3, FALSE));
goto release;
}
-
+
offset = 0;
while (size--)
{
- loadRegFromAop (hc08_reg_a, AOP (left), offset);
- accopWithAop ("ora", AOP (right), offset);
- storeRegToAop (hc08_reg_a, AOP (result), offset++);
- hc08_freeReg( hc08_reg_a);
+ bytemask = (lit >> (offset*8)) & 0xff;
+
+ if (AOP_TYPE (right) == AOP_LIT && bytemask == 0xff)
+ {
+ if (isOperandVolatile (left, FALSE))
+ {
+ loadRegFromAop (hc08_reg_a, AOP (left), offset);
+ hc08_freeReg( hc08_reg_a);
+ }
+ transferAopAop (AOP (right), offset, AOP (result), offset);
+ }
+ else if (AOP_TYPE (right) == AOP_LIT && bytemask == 0)
+ {
+ transferAopAop (AOP (left), offset, AOP (result), offset);
+ }
+ else
+ {
+ loadRegFromAop (hc08_reg_a, AOP (left), offset);
+ accopWithAop ("ora", AOP (right), offset);
+ storeRegToAop (hc08_reg_a, AOP (result), offset);
+ hc08_freeReg (hc08_reg_a);
+ }
+ offset++;
}
aopOp ((result = IC_RESULT (ic)), ic, TRUE);
#ifdef DEBUG_TYPE
- D(emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
- AOP_TYPE (result),
- AOP_TYPE (left), AOP_TYPE (right)));
- D(emitcode ("", "; Size res[%d] = l[%d]&r[%d]",
- AOP_SIZE (result),
- AOP_SIZE (left), AOP_SIZE (right)));
+ DD(emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
+ 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)));
#endif
/* if left is a literal & right is not ||
{
symbol *tlbl;
wassertl (ifx, "AOP_CPY result without ifx");
-
+
tlbl = newiTempLabel (NULL);
size = (AOP_SIZE (left) >= AOP_SIZE (right)) ? AOP_SIZE (left) : AOP_SIZE (right);
offset = 0;
emitcode ("tsta","");
else
accopWithAop ("eor", AOP (right), offset);
- hc08_freeReg( hc08_reg_a);
+ hc08_freeReg( hc08_reg_a);
if (size)
emitBranch ("bne", tlbl);
else
offset++;
}
}
-
+
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;
loadRegFromAop (hc08_reg_a, AOP (left), offset);
accopWithAop ("eor", AOP (right), offset);
storeRegToAop (hc08_reg_a, AOP (result), offset++);
- hc08_freeReg( hc08_reg_a);
+ hc08_freeReg( hc08_reg_a);
}
//release:
symbol *sym, *tempsym;
asmop *aop;
char *l;
-
+
while (*inlin)
{
if (*inlin == '_')
{
symname = ++inlin;
- while (isalnum(*inlin) || (*inlin == '_'))
+ while (isalnum((unsigned char)*inlin) || (*inlin == '_'))
inlin++;
c = *inlin;
*inlin = '\0';
if (*l=='#')
l++;
sym->isref = 1;
- if (!sym->allocreq && !sym->ismyparm)
+ if (sym->level && !sym->allocreq && !sym->ismyparm)
{
werror (E_ID_UNDEF, sym->name);
werror (W_CONTINUE,
if ((2+bp-buffer)>sizeof(buffer))
fprintf(stderr, "Inline assembly buffer overflow\n");
-
+
//printf("%s\n",buffer);
emitcode (buffer,"");
}
genInline (iCode * ic)
{
char *buffer, *bp, *bp1;
+ bool inComment = FALSE;
D(emitcode ("; genInline",""));
_G.inLine += (!options.asmpeep);
- buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
- strcpy (buffer, IC_INLINE (ic));
+ buffer = bp = bp1 = Safe_strdup (IC_INLINE(ic));
/* emit each line as a code */
while (*bp)
{
- if (*bp == '\n')
- {
- *bp++ = '\0';
- /* emitcode (bp1, ""); */
- emitinline (ic, bp1);
- bp1 = bp;
- }
- else
- {
- if (*bp == ':')
- {
- bp++;
- *bp = '\0';
- bp++;
- emitcode (bp1, "");
- bp1 = bp;
- }
- else
- bp++;
- }
+ switch (*bp)
+ {
+ case ';':
+ inComment = TRUE;
+ ++bp;
+ break;
+
+ case '\n':
+ inComment = FALSE;
+ *bp++ = '\0';
+ emitinline (ic, bp1);
+ bp1 = bp;
+ break;
+
+ default:
+ /* Add \n for labels, not dirs such as c:\mydir */
+ if (!inComment && (*bp == ':') && (isspace((unsigned char)bp[1])))
+ {
+ ++bp;
+ *bp = '\0';
+ ++bp;
+ emitcode (bp1, "");
+ bp1 = bp;
+ }
+ else
+ ++bp;
+ break;
+ }
}
if (bp1 != bp)
- {
- /* emitcode (bp1, ""); */
- emitinline (ic, bp1);
- }
- /* emitcode("",buffer); */
+ emitinline (ic, bp1);
+
+ Safe_free (buffer);
+
_G.inLine -= (!options.asmpeep);
}
hc08_dirtyReg (hc08_reg_a, FALSE);
storeRegToFullAop (hc08_reg_a, AOP (result), FALSE);
hc08_freeReg (hc08_reg_a);
-
+
freeAsmop (left, NULL, ic, TRUE);
freeAsmop (result, NULL, ic, TRUE);
}
result = IC_RESULT (ic);
aopOp (left, ic, FALSE);
aopOp (result, ic, FALSE);
-
+
switch (AOP_SIZE (left))
{
case 1: /* swap nibbles in byte */
hc08_freeReg (hc08_reg_a);
break;
case 2: /* swap bytes in a word */
- if (operandsEqu (left, result))
+ if (operandsEqu (left, result) || sameRegs (AOP (left), AOP (result)))
{
loadRegFromAop (hc08_reg_a, AOP (left), 0);
hc08_useReg (hc08_reg_a);
default:
wassertl(FALSE, "unsupported SWAP operand size");
}
-
+
freeAsmop (left, NULL, ic, TRUE);
freeAsmop (result, NULL, ic, TRUE);
}
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;
}
}
AccLsh (int shCount)
{
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. */
switch (shCount)
{
case 4:
+ if (optimize.codeSpeed)
+ break;
accopWithMisc ("nsa", "");
accopWithMisc ("and", "#0xf0");
/* total: 5 cycles, 3 bytes */
return;
case 5:
+ if (optimize.codeSpeed)
+ break;
accopWithMisc ("nsa", "");
accopWithMisc ("and", "#0xf0");
accopWithMisc ("lsla", "");
AccSRsh (int shCount)
{
int i;
-
- shCount &= 0x0007; // shCount : 0..7
+
+ shCount &= 0x0007; // shCount : 0..7
if (shCount == 7)
{
AccRsh (int shCount, bool sign)
{
int i;
-
+
if (sign)
{
AccSRsh (shCount);
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. */
switch (shCount)
{
case 4:
+ if (optimize.codeSpeed)
+ break;
accopWithMisc ("nsa", "");
accopWithMisc ("and", "#0x0f");
/* total: 5 cycles, 3 bytes */
return;
case 5:
+ if (optimize.codeSpeed)
+ break;
accopWithMisc ("nsa", "");
accopWithMisc ("and", "#0x0f");
accopWithMisc ("lsra", "");
XAccLsh (int shCount)
{
int i;
-
- shCount &= 0x000f; // shCount : 0..15
+
+ shCount &= 0x000f; // shCount : 0..15
if (shCount>=8)
{
XAccSRsh (int shCount)
{
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)
;
}
- /* asrx/rola is only 2 cycles and bytes, so an unrolled loop is often */
+ /* asrx/rora is only 2 cycles and bytes, so an unrolled loop is often */
/* the fastest and shortest. */
for (i=0;i<shCount;i++)
{
XAccRsh (int shCount, bool sign)
{
int i;
-
+
if (sign)
{
XAccSRsh (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;
rmwWithReg ("rol", hc08_reg_x);
}
}
- storeRegToAop (hc08_reg_xa, AOP (result), offl);
+ storeRegToAop (hc08_reg_xa, AOP (result), offr);
pullOrFreeReg (hc08_reg_x, needpulx);
pullOrFreeReg (hc08_reg_a, needpula);
/*-----------------------------------------------------------------*/
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;
bool needpulx = FALSE;
-
+
needpula = pushRegIfUsed (hc08_reg_a);
needpulx = pushRegIfUsed (hc08_reg_x);
/*-----------------------------------------------------------------*/
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 */
D(emitcode ("; genlshTwo",""));
-
+
size = getDataSize (result);
/* if shCount >= 8 */
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);
}
/*-----------------------------------------------------------------*/
/* shiftLLong - shift left one long from left to result */
-/* offl = LSB or MSB16 */
+/* offr = LSB or MSB16 */
/*-----------------------------------------------------------------*/
static void
shiftLLong (operand * left, operand * result, int offr)
loadRegFromAop (hc08_reg_xa, AOP (left), LSB);
rmwWithReg ("lsl", hc08_reg_a);
rmwWithReg ("rol", hc08_reg_x);
- storeRegToAop (hc08_reg_xa, AOP (result), offr);
if (offr==LSB)
{
+ storeRegToAop (hc08_reg_xa, AOP (result), offr);
loadRegFromAop (hc08_reg_xa, AOP (left), MSB24);
rmwWithReg ("rol", hc08_reg_a);
rmwWithReg ("rol", hc08_reg_x);
}
else if (offr==MSB16)
{
+ storeRegToAop (hc08_reg_a, AOP (result), offr);
loadRegFromAop (hc08_reg_a, AOP (left), MSB24);
+ storeRegToAop (hc08_reg_x, AOP (result), offr+1);
rmwWithReg ("rol", hc08_reg_a);
storeRegToAop (hc08_reg_a, AOP (result), offr+2);
+ storeConstToAop (zero, AOP (result), 0);
}
pullOrFreeReg (hc08_reg_x, needpulx);
{
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",""));
size = AOP_SIZE (result);
#if VIEW_SIZE
- D(emitcode ("; shift left ", "result %d, left %d", size,
- AOP_SIZE (left)));
+ DD(emitcode ("; shift left ", "result %d, left %d", size,
+ 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);
operand *left, *right, *result;
int size, offset;
symbol *tlbl, *tlbl1;
-// int i;
char *shift;
- regs *reg;
+ asmop *aopResult;
D(emitcode ("; genLeftShift",""));
}
/* shift count is unknown then we have to form
- a loop get the loop count in A : Note: we take
+ a loop get the loop count in X : 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 ) */
- aopOp (left, ic, FALSE);
aopOp (result, ic, FALSE);
+ aopOp (left, ic, FALSE);
+ aopResult = AOP (result);
+
+ if (sameRegs(AOP (right), AOP (result)) || IS_AOP_XA (AOP (result))
+ || isOperandVolatile (result, FALSE))
+ aopResult = forceStackedAop (AOP (result), sameRegs ( AOP (left), AOP (result)));
/* now move the left to the result if they are not the
same */
- if (!sameRegs (AOP (left), AOP (result)))
+ if (!sameRegs (AOP (left), aopResult))
{
-
size = AOP_SIZE (result);
offset = 0;
while (size--)
- {
- transferAopAop (AOP (left), offset, AOP (result), offset);
- offset++;
- }
+ {
+ transferAopAop (AOP (left), offset, aopResult, offset);
+ offset++;
+ }
}
freeAsmop (left, NULL, ic, TRUE);
-
+ AOP (result) = aopResult;
+
tlbl = newiTempLabel (NULL);
size = AOP_SIZE (result);
offset = 0;
tlbl1 = newiTempLabel (NULL);
- reg = hc08_reg_a;
-
- loadRegFromAop (reg, AOP (right), 0);
- freeAsmop (right, NULL, ic, TRUE);
+ loadRegFromAop (hc08_reg_x, AOP (right), 0);
+ emitcode ("tstx", "");
emitBranch ("beq", tlbl1);
emitLabel (tlbl);
-
+
shift="lsl";
for (offset=0;offset<size;offset++)
{
- rmwWithAop (shift, AOP (result), offset);
+ rmwWithAop (shift, AOP (result), offset);
shift="rol";
}
- rmwWithReg ("dec", reg);
+ rmwWithReg ("dec", hc08_reg_x);
emitBranch ("bne", tlbl);
emitLabel (tlbl1);
- hc08_freeReg (reg);
-
+ hc08_freeReg (hc08_reg_x);
+
freeAsmop (result, NULL, ic, TRUE);
+ freeAsmop (right, NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
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);
rmwWithReg ("asr", hc08_reg_x);
else
rmwWithReg ("lsr", hc08_reg_x);
- rmwWithReg ("rol", hc08_reg_a);
+ rmwWithReg ("ror", hc08_reg_a);
storeRegToAop (hc08_reg_xa, AOP (result), MSB24);
+ loadRegFromAop (hc08_reg_xa, AOP (left), LSB);
}
else if (offl==MSB16)
{
rmwWithReg ("asr", hc08_reg_a);
else
rmwWithReg ("lsr", hc08_reg_a);
+ loadRegFromAop (hc08_reg_x, AOP (left), MSB24);
storeRegToAop (hc08_reg_a, AOP (result), MSB24);
+ loadRegFromAop (hc08_reg_a, AOP (left), MSB16);
}
- loadRegFromAop (hc08_reg_xa, AOP (left), offl);
rmwWithReg ("ror", hc08_reg_x);
rmwWithReg ("ror", hc08_reg_a);
storeRegToAop (hc08_reg_xa, AOP (result), LSB);
+ if (offl==MSB16)
+ {
+ if (sign)
+ {
+ loadRegFromAop (hc08_reg_a, AOP (left), MSB24);
+ storeRegSignToUpperAop (hc08_reg_a, AOP (result), MSB32, sign);
+ }
+ else
+ {
+ storeConstToAop (zero, AOP (result), MSB32);
+ }
+ }
pullOrFreeReg (hc08_reg_x, needpulx);
pullOrFreeReg (hc08_reg_a, needpula);
/*-----------------------------------------------------------------*/
static void
genrshFour (operand * result, operand * left,
- int shCount, int sign)
+ int shCount, int sign)
{
/* TODO: handle cases where left == result */
-
+
D(emitcode ("; genrshFour",""));
/* if shifting more that 3 bytes */
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);
- storeRegToFullAop (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);
- storeRegToFullAop (hc08_reg_xa, 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",""));
aopOp (result, ic, FALSE);
#if VIEW_SIZE
- D(emitcode ("; shift right ", "result %d, left %d", AOP_SIZE (result),
- AOP_SIZE (left)));
+ DD(emitcode ("; shift right ", "result %d, left %d", AOP_SIZE (result),
+ 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);
operand *right, *left, *result;
sym_link *retype;
int size, offset;
-// char *l;
symbol *tlbl, *tlbl1;
char *shift;
bool sign;
-
+ asmop *aopResult;
+
D(emitcode ("; genRightShift",""));
/* if signed then we do it the hard way preserve the
more that 32 bits make no sense anyway, ( the
largest size of an object can be only 32 bits ) */
- aopOp (left, ic, FALSE);
aopOp (result, ic, FALSE);
+ aopOp (left, ic, FALSE);
+ aopResult = AOP (result);
- if (sameRegs(AOP (right), AOP (result)) || IS_AOP_XA (AOP (result)))
- AOP (result) = forceStackedAop (AOP (result));
-
- size = AOP_SIZE (result);
- offset = size-1;
- while (size--)
+ if (sameRegs(AOP (right), AOP (result)) || IS_AOP_XA (AOP (result))
+ || isOperandVolatile (result, FALSE))
+ aopResult = forceStackedAop (AOP (result), sameRegs ( AOP (left), AOP (result)));
+
+ /* now move the left to the result if they are not the
+ same */
+ if (!sameRegs (AOP (left), aopResult))
{
- transferAopAop (AOP (left), offset, AOP (result), offset);
- offset--;
+ size = AOP_SIZE (result);
+ offset = 0;
+ while (size--)
+ {
+ transferAopAop (AOP (left), offset, aopResult, offset);
+ offset++;
+ }
}
-
+ freeAsmop (left, NULL, ic, TRUE);
+ AOP (result) = aopResult;
+
tlbl = newiTempLabel (NULL);
size = AOP_SIZE (result);
offset = 0;
loadRegFromAop (hc08_reg_x, AOP (right), 0);
emitcode ("tstx", "");
- emitcode ("beq", "%05d$", tlbl1->key + 100);
- emitcode ("", "%05d$:", tlbl->key + 100);
+ emitBranch ("beq", tlbl1);
+ emitLabel (tlbl);
+
shift= sign ? "asr" : "lsr";
for (offset=size-1;offset>=0;offset--)
{
shift="ror";
}
rmwWithReg ("dec", hc08_reg_x);
- emitcode ("bne","%05d$", tlbl->key + 100);
- emitcode ("", "%05d$:", tlbl1->key + 100);
-
+ emitBranch ("bne", tlbl);
+ emitLabel (tlbl1);
+ hc08_freeReg (hc08_reg_x);
+
freeAsmop (result, NULL, ic, TRUE);
- freeAsmop (left, NULL, ic, TRUE);
freeAsmop (right, NULL, ic, TRUE);
}
+
/*-----------------------------------------------------------------*/
/* genUnpackBits - generates code for unpacking bits */
/*-----------------------------------------------------------------*/
static void
-genUnpackBits (operand * result)
+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",""));
blen = SPEC_BLEN (etype);
bstr = SPEC_BSTR (etype);
+ if (ifx && blen <= 8)
+ {
+ emitcode ("lda", ",x");
+ hc08_dirtyReg (hc08_reg_a, FALSE);
+ if (blen < 8)
+ {
+ emitcode ("and", "#0x%02x",
+ (((unsigned char) -1) >> (8 - blen)) << bstr);
+ }
+ genIfxJump (ifx, "a");
+ return;
+ }
+ wassert (!ifx);
+
/* If the bitfield length is less than a byte */
if (blen < 8)
{
hc08_dirtyReg (hc08_reg_a, FALSE);
AccRsh (bstr, FALSE);
emitcode ("and", "#0x%02x", ((unsigned char) -1) >> (8 - blen));
+ if (!SPEC_USIGN (etype))
+ {
+ /* signed bitfield */
+ symbol *tlbl = newiTempLabel (NULL);
+
+ emitcode ("bit", "#0x%02x", 1<<(blen - 1));
+ emitcode ("beq", "%05d$", tlbl->key + 100);
+ emitcode ("ora", "#0x%02x", (unsigned char) (0xff << blen));
+ emitLabel (tlbl);
+ }
storeRegToAop (hc08_reg_a, AOP (result), offset++);
goto finish;
}
{
emitcode ("lda", ",x");
hc08_dirtyReg (hc08_reg_a, FALSE);
- storeRegToAop (hc08_reg_a, AOP (result), offset++);
+ storeRegToAop (hc08_reg_a, AOP (result), offset);
+ offset++;
if (rlen>8)
emitcode ("aix", "#1");
}
{
emitcode ("lda", ",x");
emitcode ("and", "#0x%02x", ((unsigned char) -1) >> (8-rlen));
+ if (!SPEC_USIGN (etype))
+ {
+ /* signed bitfield */
+ symbol *tlbl = newiTempLabel (NULL);
+
+ emitcode ("bit", "#0x%02x", 1<<(rlen - 1));
+ emitcode ("beq", "%05d$", tlbl->key + 100);
+ emitcode ("ora", "#0x%02x", (unsigned char) (0xff << rlen));
+ emitLabel (tlbl);
+ }
storeRegToAop (hc08_reg_a, AOP (result), offset++);
}
if (offset < rsize)
{
rsize -= offset;
- while (rsize--)
- storeConstToAop (zero, AOP (result), offset++);
+ if (SPEC_USIGN (etype))
+ {
+ while (rsize--)
+ storeConstToAop (zero, AOP (result), offset++);
+ }
+ else
+ {
+ /* signed bitfield: sign extension with 0x00 or 0xff */
+ emitcode ("rola", "");
+ emitcode ("clra", "");
+ emitcode ("sbc", zero);
+
+ while (rsize--)
+ storeRegToAop (hc08_reg_a, AOP (result), offset++);
+ }
}
}
/*-----------------------------------------------------------------*/
-/* genDataPointerGet - generates code when ptr offset is known */
+/* genUnpackBitsImmed - generates code for unpacking bits */
/*-----------------------------------------------------------------*/
static void
-genDataPointerGet (operand * left,
- operand * result,
- iCode * ic)
+genUnpackBitsImmed (operand * left,
+ operand * result,
+ iCode *ic,
+ iCode *ifx)
{
- int size, offset = 0;
+ 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 */
asmop *derefaop;
-
- D(emitcode ("; genDataPointerGet",""));
+
+ D(emitcode ("; genUnpackBitsImmed",""));
aopOp (result, ic, TRUE);
size = AOP_SIZE (result);
derefaop = aopDerefAop (AOP (left));
freeAsmop (left, NULL, ic, TRUE);
derefaop->size = size;
-
- while (size--)
+
+ etype = getSpec (operandType (result));
+ rsize = getSize (operandType (result));
+ blen = SPEC_BLEN (etype);
+ bstr = SPEC_BSTR (etype);
+
+ /* if the bitfield is a single bit in the direct page */
+ if (blen == 1 && derefaop->type == AOP_DIR)
{
- transferAopAop(derefaop, offset, AOP (result), offset);
+ if (!ifx && bstr)
+ {
+ symbol *tlbl = newiTempLabel (NULL);
+
+ loadRegFromConst (hc08_reg_a, zero);
+ emitcode ("brclr", "#%d,%s,%05d$",
+ bstr, aopAdrStr (derefaop, 0, FALSE),
+ (tlbl->key + 100));
+ if (SPEC_USIGN (etype))
+ rmwWithReg ("inc", hc08_reg_a);
+ else
+ rmwWithReg ("dec", hc08_reg_a);
+ emitLabel (tlbl);
+ storeRegToAop (hc08_reg_a, AOP (result), offset);
+ hc08_freeReg (hc08_reg_a);
+ offset++;
+ goto finish;
+ }
+ else if (ifx)
+ {
+ symbol *tlbl = newiTempLabel (NULL);
+ symbol *jlbl;
+ char * inst;
+
+ if (IC_TRUE (ifx))
+ {
+ jlbl = IC_TRUE (ifx);
+ inst = "brclr";
+ }
+ else
+ {
+ jlbl = IC_FALSE (ifx);
+ inst = "brset";
+ }
+ emitcode (inst, "#%d,%s,%05d$",
+ bstr, aopAdrStr (derefaop, 0, FALSE),
+ (tlbl->key + 100));
+ emitBranch ("jmp", jlbl);
+ emitLabel (tlbl);
+ ifx->generated = 1;
+ offset++;
+ goto finish;
+ }
+ }
+
+ /* If the bitfield length is less than a byte */
+ if (blen < 8)
+ {
+ loadRegFromAop (hc08_reg_a, derefaop, 0);
+ if (!ifx)
+ {
+ AccRsh (bstr, FALSE);
+ emitcode ("and", "#0x%02x", ((unsigned char) -1) >> (8 - blen));
+ hc08_dirtyReg (hc08_reg_a, FALSE);
+ if (!SPEC_USIGN (etype))
+ {
+ /* signed bitfield */
+ symbol *tlbl = newiTempLabel (NULL);
+
+ emitcode ("bit", "#0x%02x", 1<<(blen - 1));
+ emitcode ("beq", "%05d$", tlbl->key + 100);
+ emitcode ("ora", "#0x%02x", (unsigned char) (0xff << blen));
+ emitLabel (tlbl);
+ }
+ storeRegToAop (hc08_reg_a, AOP (result), offset);
+ }
+ else
+ {
+ emitcode ("and", "#0x%02x",
+ (((unsigned char) -1) >> (8 - blen)) << bstr);
+ hc08_dirtyReg (hc08_reg_a, FALSE);
+ }
offset++;
+ goto finish;
+ }
+
+ /* Bit field did not fit in a byte. Copy all
+ but the partial byte at the end. */
+ for (rlen=blen;rlen>=8;rlen-=8)
+ {
+ loadRegFromAop (hc08_reg_a, derefaop, size-offset-1);
+ if (!ifx)
+ storeRegToAop (hc08_reg_a, AOP (result), offset);
+ else
+ emitcode ("tsta", "");
+ offset++;
+ }
+
+ /* Handle the partial byte at the end */
+ if (rlen)
+ {
+ loadRegFromAop (hc08_reg_a, derefaop, size-offset-1);
+ emitcode ("and", "#0x%02x", ((unsigned char) -1) >> (8-rlen));
+ if (!SPEC_USIGN (etype))
+ {
+ /* signed bitfield */
+ symbol *tlbl = newiTempLabel (NULL);
+
+ emitcode ("bit", "#0x%02x", 1<<(rlen - 1));
+ emitcode ("beq", "%05d$", tlbl->key + 100);
+ emitcode ("ora", "#0x%02x", (unsigned char) (0xff << rlen));
+ emitLabel (tlbl);
+ }
+ storeRegToAop (hc08_reg_a, AOP (result), offset++);
+ }
+
+finish:
+ if (offset < rsize)
+ {
+ rsize -= offset;
+ if (SPEC_USIGN (etype))
+ {
+ while (rsize--)
+ storeConstToAop (zero, AOP (result), offset++);
+ }
+ else
+ {
+ /* signed bitfield: sign extension with 0x00 or 0xff */
+ emitcode ("rola", "");
+ emitcode ("clra", "");
+ emitcode ("sbc", zero);
+
+ while (rsize--)
+ storeRegToAop (hc08_reg_a, AOP (result), offset++);
+ }
}
freeAsmop (NULL, derefaop, ic, TRUE);
freeAsmop (result, NULL, ic, TRUE);
+
+ if (ifx && !ifx->generated)
+ {
+ genIfxJump (ifx, "a");
+ }
}
-#if 0
+
/*-----------------------------------------------------------------*/
-/* genNearPointerGet - emitcode for near pointer fetch */
+/* genDataPointerGet - generates code when ptr offset is known */
/*-----------------------------------------------------------------*/
static void
-genNearPointerGet (operand * left,
- operand * result,
- iCode * ic,
- iCode * pi)
+genDataPointerGet (operand * left,
+ operand * result,
+ iCode * ic,
+ iCode * ifx)
{
- int size, offset;
- sym_link *retype = getSpec (operandType (result));
+ int size;
+ asmop *derefaop;
- D(emitcode ("; genNearPointerGet",""));
+ D(emitcode ("; genDataPointerGet",""));
- aopOp (left, ic, FALSE);
+ aopOp (result, ic, TRUE);
+ size = AOP_SIZE (result);
- /* 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)
- || (AOP_TYPE (left) == AOP_LIT)
- /* !IS_BITVAR (retype) */
- /* && DCL_TYPE (ltype) == POINTER */ )
- {
- genDataPointerGet (left, result, ic);
- return;
- }
+ derefaop = aopDerefAop (AOP (left));
+ freeAsmop (left, NULL, ic, TRUE);
+ derefaop->size = size;
- /* if the operand is already in hx
- then we do nothing else we move the value to hx */
- if (AOP_TYPE (left) != AOP_STR)
+ while (size--)
{
- /* if this is remateriazable */
- loadRegFromAop (hc08_reg_x, AOP (left), 0);
- loadRegFromConst (hc08_reg_h, zero);
+ if (!ifx)
+ transferAopAop (derefaop, size, AOP (result), size);
+ else
+ loadRegFromAop (hc08_reg_a, derefaop, size);
}
- /* so hx now contains the address */
- aopOp (result, ic, FALSE);
+ freeAsmop (NULL, derefaop, ic, TRUE);
+ freeAsmop (result, NULL, ic, TRUE);
- /* if bit then unpack */
- if (IS_BITVAR (retype))
- genUnpackBits (result);
- else
+ if (ifx && !ifx->generated)
{
- size = AOP_SIZE (result);
- offset = size-1;
-
- while (size--)
- {
- accopWithMisc ("lda", ",x");
- if (size || pi)
- {
- rmwWithReg ("inc", hc08_reg_x);
- }
- storeRegToAop (hc08_reg_a, AOP (result), offset--);
- hc08_freeReg (hc08_reg_a);
- }
+ genIfxJump (ifx, "a");
}
-
- freeAsmop (left, NULL, ic, TRUE);
- freeAsmop (result, NULL, ic, TRUE);
-
- if (pi /* && AOP_TYPE (left) != AOP_IMMD && AOP_TYPE (left) != AOP_STR */) {
- aopOp (IC_RESULT (pi), pi, FALSE);
- storeRegToAop (hc08_reg_x, AOP (IC_RESULT (pi)), 0);
- freeAsmop (IC_RESULT (pi), NULL, pi, TRUE);
- pi->generated = 1;
- }
-
- hc08_freeReg (hc08_reg_hx);
}
-#endif
+
/*-----------------------------------------------------------------*/
-/* genFarPointerGet - get value from far space */
+/* genPointerGet - generate code for pointer get */
/*-----------------------------------------------------------------*/
static void
-genFarPointerGet (operand * left,
- operand * result, iCode * ic, iCode * pi)
+genPointerGet (iCode * ic, iCode *pi, iCode *ifx)
{
+ operand *left = IC_LEFT (ic);
+ operand *result = IC_RESULT (ic);
int size, offset;
sym_link *retype = getSpec (operandType (result));
- D(emitcode ("; genFarPointerGet",""));
+ D(emitcode ("; genPointerGet",""));
+
+ if (getSize (operandType (result))>1)
+ ifx = NULL;
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;
+ result is not bit variable type */
+ if (AOP_TYPE (left) == AOP_IMMD || AOP_TYPE (left) == AOP_LIT)
+ {
+ if (!IS_BITVAR (retype))
+ {
+ genDataPointerGet (left, result, ic, ifx);
+ return;
+ }
+ else
+ {
+ genUnpackBitsImmed (left, result, ic, ifx);
+ return;
+ }
}
/* if the operand is already in hx
/* if bit then unpack */
if (IS_BITVAR (retype))
- genUnpackBits (result);
+ genUnpackBits (result, ifx);
else
{
size = AOP_SIZE (result);
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);
}
- storeRegToAop (hc08_reg_a, AOP (result), offset--);
+ if (!ifx)
+ storeRegToAop (hc08_reg_a, AOP (result), offset);
+ offset--;
hc08_freeReg (hc08_reg_a);
- }
+ }
}
freeAsmop (left, NULL, ic, TRUE);
freeAsmop (result, NULL, ic, TRUE);
-
- if (pi /* && AOP_TYPE (left) != AOP_IMMD && AOP_TYPE (left) != AOP_STR */) {
+
+ if (pi) {
aopOp (IC_RESULT (pi), pi, FALSE);
storeRegToAop (hc08_reg_hx, AOP (IC_RESULT (pi)), 0);
freeAsmop (IC_RESULT (pi), NULL, pi, TRUE);
pi->generated = 1;
}
- hc08_freeReg (hc08_reg_hx);
-
-}
-
-
-
-/*-----------------------------------------------------------------*/
-/* genPointerGet - generate code for pointer get */
-/*-----------------------------------------------------------------*/
-static void
-genPointerGet (iCode * ic, iCode *pi)
-{
- operand *left, *result;
- sym_link *type, *etype;
- int p_type;
-
- D(emitcode ("; genPointerGet",""));
-
- 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
+ if (ifx && !ifx->generated)
{
- /* we have to go by the storage class */
- p_type = PTR_TYPE (SPEC_OCLS (etype));
+ genIfxJump (ifx, "a");
}
- /* special case when cast remat */
- if (p_type == GPOINTER && IS_SYMOP(left) && OP_SYMBOL(left)->remat &&
- IS_CAST_ICODE(OP_SYMBOL(left)->rematiCode)) {
- left = IC_RIGHT(OP_SYMBOL(left)->rematiCode);
- type = operandType (left);
- p_type = DCL_TYPE (type);
- }
- /* now that we have the pointer type we assign
- the pointer values */
- switch (p_type)
- {
-
- case POINTER:
- case IPOINTER:
-#if 0
- genNearPointerGet (left, result, ic, pi);
- break;
-#endif
- case GPOINTER:
- case CPOINTER:
- case FPOINTER:
- genFarPointerGet (left, result, ic, pi);
- break;
-
- }
+ hc08_freeReg (hc08_reg_hx);
}
/*-----------------------------------------------------------------*/
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",""));
blen = SPEC_BLEN (etype);
bstr = SPEC_BSTR (etype);
-
+
/* If the bitfield length is less than a byte */
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;
emitcode ("ora","#0x%02x", litval);
hc08_dirtyReg (hc08_reg_a, FALSE);
emitcode ("sta", ",x");
-
+
hc08_freeReg (hc08_reg_a);
return;
}
-
+
/* Case with a bitfield length < 8 and arbitrary source
*/
loadRegFromAop (hc08_reg_a, AOP (right), 0);
emitcode ("ora", "1,s");
emitcode ("sta", ",x");
pullReg (hc08_reg_a);
-
+
hc08_freeReg (hc08_reg_a);
return;
}
if (AOP (right)->type == AOP_DIR)
{
emitcode ("mov", "%s,x+", aopAdrStr(AOP (right), offset, FALSE));
- xoffset++;
+ xoffset++;
}
else
{
if (rlen)
{
mask = (((unsigned char) -1 << rlen) & 0xff);
-
+
if (AOP_TYPE (right) == AOP_LIT)
{
/* 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);
hc08_freeReg (hc08_reg_a);
return;
}
-
+
/* Case with partial byte and arbitrary source
*/
loadRegFromAop (hc08_reg_a, AOP (right), offset);
}
/*-----------------------------------------------------------------*/
-/* genDataPointerSet - remat pointer to data space */
+/* genPackBitsImmed - generates code for packed bit storage */
/*-----------------------------------------------------------------*/
static void
-genDataPointerSet (operand * right,
- operand * result,
- iCode * ic)
+genPackBitsImmed (operand *result, sym_link * etype, operand * right, iCode * ic)
{
- int size, offset = 0;
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 */
- D(emitcode ("; genDataPointerSet",""));
+ D(emitcode ("; genPackBitsImmed",""));
+
+ blen = SPEC_BLEN (etype);
+ bstr = SPEC_BSTR (etype);
aopOp (right, ic, FALSE);
size = AOP_SIZE (right);
derefaop = aopDerefAop (AOP (result));
freeAsmop (result, NULL, ic, TRUE);
derefaop->size = size;
-
- while (size--)
+
+ /* if the bitfield is a single bit in the direct page */
+ if (blen == 1 && derefaop->type == AOP_DIR)
{
- transferAopAop (AOP (right), offset, derefaop, offset);
- offset++;
+ if (AOP_TYPE (right) == AOP_LIT)
+ {
+ litval = (int) ulFromVal (AOP (right)->aopu.aop_lit);
+
+ emitcode ((litval & 1) ? "bset" : "bclr",
+ "#%d,%s", bstr, aopAdrStr (derefaop, 0, FALSE));
+ }
+ else
+ {
+ symbol *tlbl1 = newiTempLabel (NULL);
+ symbol *tlbl2 = newiTempLabel (NULL);
+
+ loadRegFromAop (hc08_reg_a, AOP (right), 0);
+ emitcode ("bit", "#1");
+ emitBranch ("bne", tlbl1);
+ emitcode ("bclr", "#%d,%s", bstr, aopAdrStr (derefaop, 0, FALSE));
+ emitBranch ("bra", tlbl2);
+ emitLabel (tlbl1);
+ emitcode ("bset", "#%d,%s", bstr, aopAdrStr (derefaop, 0, FALSE));
+ emitLabel (tlbl2);
+ hc08_freeReg (hc08_reg_a);
+ }
+ goto release;
}
- freeAsmop (right, NULL, ic, TRUE);
- freeAsmop (NULL, derefaop, ic, TRUE);
-}
+ /* If the bitfield length is less than a byte */
+ if (blen < 8)
+ {
+ mask = ((unsigned char) (0xFF << (blen + bstr)) |
+ (unsigned char) (0xFF >> (8 - bstr)));
-#if 0
-/*-----------------------------------------------------------------*/
-/* genNearPointerSet - emitcode for near pointer put */
-/*-----------------------------------------------------------------*/
-static void
-genNearPointerSet (operand * right,
- operand * result,
- iCode * ic,
- iCode * pi)
-{
- int size, offset;
- sym_link *retype = getSpec (operandType (right));
- sym_link *letype = getSpec (operandType (result));
+ if (AOP_TYPE (right) == AOP_LIT)
+ {
+ /* Case with a bitfield length <8 and literal source
+ */
+ litval = (int) ulFromVal (AOP (right)->aopu.aop_lit);
+ litval <<= bstr;
+ litval &= (~mask) & 0xff;
- D(emitcode ("; genNearPointerSet",""));
+ loadRegFromAop (hc08_reg_a, derefaop, 0);
+ if ((mask|litval)!=0xff)
+ emitcode ("and","#0x%02x", mask);
+ if (litval)
+ emitcode ("ora","#0x%02x", litval);
+ hc08_dirtyReg (hc08_reg_a, FALSE);
+ storeRegToAop (hc08_reg_a, derefaop, 0);
- aopOp (result, ic, FALSE);
+ hc08_freeReg (hc08_reg_a);
+ goto release;
+ }
- /* 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) &&
- !IS_BITVAR (letype))
- {
- genDataPointerSet (right, result, ic);
- return;
+ /* Case with a bitfield length < 8 and arbitrary source
+ */
+ loadRegFromAop (hc08_reg_a, AOP (right), 0);
+ /* shift and mask source value */
+ AccLsh (bstr);
+ emitcode ("and", "#0x%02x", (~mask) & 0xff);
+ hc08_dirtyReg (hc08_reg_a, FALSE);
+ pushReg (hc08_reg_a, TRUE);
+
+ loadRegFromAop (hc08_reg_a, derefaop, 0);
+ emitcode ("and", "#0x%02x", mask);
+ emitcode ("ora", "1,s");
+ storeRegToAop (hc08_reg_a, derefaop, 0);
+ pullReg (hc08_reg_a);
+
+ hc08_freeReg (hc08_reg_a);
+ goto release;
}
- /* if the operand is already in hx
- then we do nothing else we move the value to hx */
- if (AOP_TYPE (result) != AOP_STR)
+ /* Bit length is greater than 7 bits. In this case, copy */
+ /* all except the partial byte at the end */
+ for (rlen=blen;rlen>=8;rlen-=8)
{
- loadRegFromAop (hc08_reg_x, AOP (result), 0);
- loadRegFromConst (hc08_reg_h, zero);
+ transferAopAop (AOP (right), offset, derefaop, size-offset-1);
+ offset++;
}
- /* so hx now contains the address */
- aopOp (right, ic, FALSE);
- /* if bit then unpack */
- if (IS_BITVAR (retype) || IS_BITVAR (letype))
- genPackBits ((IS_BITVAR (retype) ? retype : letype), right);
- else
+ /* If there was a partial byte at the end */
+ if (rlen)
{
- size = AOP_SIZE (right);
- offset = size-1;
+ mask = (((unsigned char) -1 << rlen) & 0xff);
+
+ if (AOP_TYPE (right) == AOP_LIT)
+ {
+ /* Case with partial byte and literal source
+ */
+ litval = (int) ulFromVal (AOP (right)->aopu.aop_lit);
+ litval >>= (blen-rlen);
+ litval &= (~mask) & 0xff;
+ loadRegFromAop (hc08_reg_a, derefaop, size-offset-1);
+ if ((mask|litval)!=0xff)
+ emitcode ("and","#0x%02x", mask);
+ if (litval)
+ emitcode ("ora","#0x%02x", litval);
+ hc08_dirtyReg (hc08_reg_a, FALSE);
+ storeRegToAop (hc08_reg_a, derefaop, size-offset-1);
+ hc08_dirtyReg (hc08_reg_a, FALSE);
+ hc08_freeReg (hc08_reg_a);
+ goto release;
+ }
+
+ /* Case with partial byte and arbitrary source
+ */
+ loadRegFromAop (hc08_reg_a, AOP (right), offset);
+ emitcode ("and", "#0x%02x", (~mask) & 0xff);
+ hc08_dirtyReg (hc08_reg_a, FALSE);
+ pushReg (hc08_reg_a, TRUE);
+
+ loadRegFromAop (hc08_reg_a, derefaop, size-offset-1);
+ emitcode ("and", "#0x%02x", mask);
+ emitcode ("ora", "1,s");
+ storeRegToAop (hc08_reg_a, derefaop, size-offset-1);
+ pullReg (hc08_reg_a);
+ }
+
+ hc08_freeReg (hc08_reg_a);
+
+release:
+ freeAsmop (right, NULL, ic, TRUE);
+ freeAsmop (NULL, derefaop, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genDataPointerSet - remat pointer to data space */
+/*-----------------------------------------------------------------*/
+static void
+genDataPointerSet (operand * right,
+ operand * result,
+ iCode * ic)
+{
+ int size;
+ asmop *derefaop;
+
+ D(emitcode ("; genDataPointerSet",""));
- while (size--)
- {
- loadRegFromAop (hc08_reg_a, AOP (right), offset--);
- accopWithMisc ("sta", ",x");
- if (size || pi)
- {
- rmwWithReg ("inc", hc08_reg_x);
- }
- hc08_freeReg (hc08_reg_a);
- }
- }
+ aopOp (right, ic, FALSE);
+ size = AOP_SIZE (right);
+ derefaop = aopDerefAop (AOP (result));
freeAsmop (result, NULL, ic, TRUE);
- freeAsmop (right, NULL, ic, TRUE);
+ derefaop->size = size;
- if (pi /* && AOP_TYPE (result) != AOP_STR && AOP_TYPE (result) != AOP_IMMD */) {
- aopOp (IC_RESULT (pi), pi, FALSE);
- storeRegToAop (hc08_reg_x, AOP (IC_RESULT (pi)), 0);
- freeAsmop (IC_RESULT (pi), NULL, pi, TRUE);
- pi->generated=1;
- }
+ while (size--)
+ {
+ transferAopAop (AOP (right), size, derefaop, size);
+ }
- hc08_freeReg (hc08_reg_hx);
-
+ freeAsmop (right, NULL, ic, TRUE);
+ freeAsmop (NULL, derefaop, ic, TRUE);
}
-#endif
+
/*-----------------------------------------------------------------*/
-/* genFarPointerSet - set value from far space */
+/* genPointerSet - stores the value into a pointer location */
/*-----------------------------------------------------------------*/
static void
-genFarPointerSet (operand * right,
- operand * result, iCode * ic, iCode * pi)
+genPointerSet (iCode * ic, iCode *pi)
{
+ operand *right = IC_RIGHT (ic);
+ operand *result = IC_RESULT (ic);
+ sym_link *type, *etype;
int size, offset;
sym_link *retype = getSpec (operandType (right));
sym_link *letype = getSpec (operandType (result));
- D(emitcode ("; genFarPointerSet",""));
+ D(emitcode ("; genPointerSet",""));
+
+ type = operandType (result);
+ etype = getSpec (type);
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) &&
- !IS_BITVAR (letype))
+ /* if the result is rematerializable */
+ if (AOP_TYPE (result) == AOP_IMMD || AOP_TYPE (result) == AOP_LIT)
{
- genDataPointerSet (right, result, ic);
- return;
+ if (!IS_BITVAR (retype) && !IS_BITVAR (letype))
+ {
+ genDataPointerSet (right, result, ic);
+ return;
+ }
+ else
+ {
+ genPackBitsImmed (result, (IS_BITVAR (retype) ? retype : letype), right, ic);
+ return;
+ }
}
/* if the operand is already in hx
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);
freeAsmop (right, NULL, ic, TRUE);
- if (pi /* && AOP_TYPE (result) != AOP_STR && AOP_TYPE (result) != AOP_IMMD */) {
+ if (pi) {
aopOp (IC_RESULT (pi), pi, FALSE);
storeRegToAop (hc08_reg_hx, AOP (IC_RESULT (pi)), 0);
freeAsmop (IC_RESULT (pi), NULL, pi, TRUE);
}
hc08_freeReg (hc08_reg_hx);
-
-
-}
-
-
-/*-----------------------------------------------------------------*/
-/* genPointerSet - stores the value into a pointer location */
-/*-----------------------------------------------------------------*/
-static void
-genPointerSet (iCode * ic, iCode *pi)
-{
- operand *right, *result;
- sym_link *type, *etype;
- int p_type;
-
- D(emitcode ("; genPointerSet",""));
-
- 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));
- }
-
- /* special case when cast remat */
- if (p_type == GPOINTER && OP_SYMBOL(result)->remat &&
- IS_CAST_ICODE(OP_SYMBOL(result)->rematiCode)) {
- result = IC_RIGHT(OP_SYMBOL(result)->rematiCode);
- type = operandType (result);
- p_type = DCL_TYPE (type);
- }
- /* now that we have the pointer type we assign
- the pointer values */
- switch (p_type)
- {
-
- case POINTER:
- case IPOINTER:
-#if 0
- genNearPointerSet (right, result, ic, pi);
- break;
-#endif
-
- case GPOINTER:
- case FPOINTER:
- genFarPointerSet (right, result, ic, pi);
- break;
-
- default:
- werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "genPointerSet: illegal pointer type");
- }
}
aopOp (cond, ic, FALSE);
+ /* If the condition is a literal, we can just do an unconditional */
+ /* branch or no branch */
+ if (AOP_TYPE (cond) == 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 */
+ if (popIc)
+ genIpop (popIc);
+ if (lit)
+ {
+ if (IC_TRUE (ic))
+ emitBranch ("jmp", IC_TRUE (ic));
+ }
+ else
+ {
+ if (IC_FALSE (ic))
+ emitBranch ("jmp", IC_FALSE (ic));
+ }
+ ic->generated = 1;
+ return;
+ }
+
/* get the value into acc */
if (AOP_TYPE (cond) != AOP_CRY)
asmopToBool (AOP (cond), FALSE);
variable */
if (sym->onStack)
{
- /* if it has an offset then we need to compute
- it */
+ /* if it has an offset then we need to compute it */
+ offset = _G.stackOfs + _G.stackPushes + sym->stack;
hc08_useReg (hc08_reg_hx);
emitcode ("tsx", "");
- emitcode ("aix", "#%d", _G.stackOfs + _G.stackPushes +sym->stack);
+ while (offset > 127)
+ {
+ emitcode ("aix", "#127");
+ offset -= 127;
+ }
+ while (offset < -128)
+ {
+ emitcode ("aix", "#-128");
+ offset += 128;
+ }
+ emitcode ("aix", "#%d", offset);
storeRegToFullAop (hc08_reg_hx, AOP (IC_RESULT (ic)), FALSE);
hc08_freeReg (hc08_reg_hx);
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++);
}
genAssign (iCode * ic)
{
operand *result, *right;
- int size, offset;
+ int size;
// unsigned long lit = 0L;
D(emitcode("; genAssign",""));
loadRegFromAop(hc08_reg_hx, AOP (right), 0);
goto release;
}
-
+
/* general case */
size = AOP_SIZE (result);
- offset = 0;
-
while (size--)
{
- transferAopAop (AOP (right), offset, AOP (result), offset);
- offset++;
+ transferAopAop (AOP (right), size, AOP (result), size);
}
release:
}
/*-----------------------------------------------------------------*/
-/* genJumpTab - genrates code for jump table */
+/* genJumpTab - generates code for jump table */
/*-----------------------------------------------------------------*/
static void
genJumpTab (iCode * ic)
{
symbol *jtab;
-// char *l;
+ symbol *jtablo = newiTempLabel (NULL);
+ symbol *jtabhi = newiTempLabel (NULL);
D(emitcode ("; genJumpTab",""));
aopOp (IC_JTCOND (ic), ic, FALSE);
- /* get the condition into accumulator */
- loadRegFromAop (hc08_reg_a, AOP (IC_JTCOND (ic)), 0);
- freeAsmop (IC_JTCOND (ic), NULL, ic, TRUE);
- /* multiply by three */
- pushReg (hc08_reg_a, FALSE);
- emitcode ("lsla", "");
- emitcode ("add","1,s");
- transferRegReg (hc08_reg_a, hc08_reg_x, TRUE);
- loadRegFromConst (hc08_reg_h, zero);
- pullReg (hc08_reg_a);
- jtab = newiTempLabel (NULL);
- emitcode ("jmp", "%05d$,x", jtab->key + 100);
- emitcode ("", "%05d$:", jtab->key + 100);
+ if (hc08_reg_x->isFree && hc08_reg_x->isFree)
+ {
+ /* get the condition into x */
+ loadRegFromAop (hc08_reg_x, AOP (IC_JTCOND (ic)), 0);
+ freeAsmop (IC_JTCOND (ic), NULL, ic, TRUE);
+ loadRegFromConst (hc08_reg_h, zero);
+
+ emitcode ("lda", "%05d$,x", jtabhi->key + 100);
+ emitcode ("ldx", "%05d$,x", jtablo->key + 100);
+ transferRegReg (hc08_reg_a, hc08_reg_h, TRUE);
+ emitcode ("jmp", ",x");
+
+ hc08_dirtyReg (hc08_reg_a, TRUE);
+ hc08_dirtyReg (hc08_reg_hx, TRUE);
+ }
+ else
+ {
+ adjustStack(-2);
+ pushReg(hc08_reg_hx, TRUE);
+
+ /* get the condition into x */
+ loadRegFromAop (hc08_reg_x, AOP (IC_JTCOND (ic)), 0);
+ freeAsmop (IC_JTCOND (ic), NULL, ic, TRUE);
+ loadRegFromConst (hc08_reg_h, zero);
+
+ emitcode ("lda", "%05d$,x", jtabhi->key + 100);
+ emitcode ("sta", "3,s");
+ emitcode ("lda", "%05d$,x", jtablo->key + 100);
+ emitcode ("sta", "4,s");
+
+ pullReg(hc08_reg_hx);
+ emitcode ("rts", "");
+ _G.stackPushes += 2;
+ updateCFA();
+ }
+
/* now generate the jump labels */
+ emitLabel (jtablo);
+ for (jtab = setFirstItem (IC_JTLABELS (ic)); jtab;
+ jtab = setNextItem (IC_JTLABELS (ic)))
+ emitcode (".db", "%05d$", jtab->key + 100);
+ emitLabel (jtabhi);
for (jtab = setFirstItem (IC_JTLABELS (ic)); jtab;
jtab = setNextItem (IC_JTLABELS (ic)))
- emitcode ("jmp", "%05d$", jtab->key + 100);
+ emitcode (".db", ">%05d$", jtab->key + 100);
- hc08_dirtyReg (hc08_reg_a, TRUE);
- hc08_dirtyReg (hc08_reg_hx, TRUE);
}
/*-----------------------------------------------------------------*/
/* 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%d", 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;
}
if (!IS_SPEC (rtype) || SPEC_USIGN (rtype) || AOP_TYPE(right)==AOP_CRY)
{
while (size--)
- storeConstToAop (zero, AOP (result), offset++);
+ storeConstToAop (zero, AOP (result), offset++);
}
else
{
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);
emitBranch ("jmp", IC_TRUE (ifx));
aopOp (IC_RESULT (ic), ic, FALSE);
size = AOP_SIZE (IC_RESULT (ic));
offset = 0;
-
+
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);
}
genCritical (iCode *ic)
{
D(emitcode("; genCritical",""));
-
+
if (IC_RESULT (ic))
aopOp (IC_RESULT (ic), ic, TRUE);
genEndCritical (iCode *ic)
{
D(emitcode("; genEndCritical",""));
-
+
if (IC_RIGHT (ic))
{
aopOp (IC_RIGHT (ic), ic, FALSE);
/* print the allocation information */
if (allocInfo && currFunc)
- printAllocInfo (currFunc, codeOutFile);
+ printAllocInfo (currFunc, codeOutBuf);
/* if debug information required */
if (options.debug && currFunc)
{
#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
}
spname = "_spx";
else
spname = "sp";
-
+
debugFile->writeFrameAddress (NULL, NULL, 0); /* have no idea where frame is now */
hc08_aop_pass[0] = newAsmop (AOP_REG);
for (ic = lic; ic; ic = ic->next)
{
-
+
_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;
-
- for (i=0; i<6; i++) {
- sprintf (®sInUse[i],
- "%c", ic->riu & (1<<i) ? i+'0' : '-');
- }
- regsInUse[i]=0;
- emitcode("", "; [%s] ic:%d: %s", regsInUse, ic->seq, printILine(ic));
+ char regsInUse[80];
+ int i;
+ const char *iLine;
+
+ 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));
+ 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;
+ continue;
{
int i;
regs *reg;
symbol *sym;
-
+
for (i=A_IDX;i<=XA_IDX;i++)
{
reg = hc08_regWithIdx(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 '>':
- 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, hasInc(IC_LEFT(ic),ic,getSize(operandType(IC_RESULT(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;
-
+ 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:
+ genCmpEQorNE (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,
+ 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;
+
case SWAP:
- genSwap (ic);
+ genSwap (ic);
break;
- default:
- ic = ic;
- }
+ default:
+ ic = ic;
+ }
if (!hc08_reg_a->isFree)
- D(emitcode("","; forgot to free a"));
+ DD(emitcode("","; forgot to free a"));
if (!hc08_reg_x->isFree)
- D(emitcode("","; forgot to free x"));
+ DD(emitcode("","; forgot to free x"));
if (!hc08_reg_h->isFree)
- D(emitcode("","; forgot to free h"));
+ DD(emitcode("","; forgot to free h"));
if (!hc08_reg_hx->isFree)
- D(emitcode("","; forgot to free hx"));
+ DD(emitcode("","; forgot to free hx"));
if (!hc08_reg_xa->isFree)
- D(emitcode("","; forgot to free xa"));
+ DD(emitcode("","; forgot to free xa"));
}
debugFile->writeFrameAddress (NULL, NULL, 0); /* have no idea where frame is now */
-
+
/* now we are ready to call the
peep hole optimizer */
peepHole (&lineHead);
/* now do the actual printing */
- printLine (lineHead, codeOutFile);
+ printLine (lineHead, codeOutBuf);
return;
}