-------------------------------------------------------------------------*/
-#define D(x)
-//#define D(x) x
+/* Use the D macro for basic (unobtrusive) debugging messages */
+//#define D(x)
+#define D(x) x
+/* 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";
else
vsprintf (lb, fmt, ap);
- while (isspace (*lbp))
+ while (isspace ((unsigned char)*lbp))
lbp++;
if (lbp && *lbp)
return;
}
- D(emitcode ("", "; transferRegReg(%s,%s)",
+ DD(emitcode ("", "; transferRegReg(%s,%s)",
sreg->name, dreg->name));
srcidx = sreg->rIdx;
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. */
&& (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;
&& 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;
&& 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;
/*--------------------------------------------------------------------------*/
/* 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:
&& 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;
/* 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)
+ && operandsEqu(srcaop->op, dstaop->op) && srcofs == dstofs
+ && dstaop->type == srcaop->type)
return;
if (srcaop->stacked && srcaop->stk_aop[srcofs])
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 (srcaop->type == AOP_LIT)
{
unsigned long lit;
- unsigned char bytemask;
+ unsigned long bytemask;
lit = (unsigned long) floatFromVal (srcaop->aopu.aop_lit);
bytemask = (lit >> (srcofs*8)) & 0xff;
/* 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 */
+ 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;
+ }
aop->size = getSize (sym->type);
aop->op = op;
aop->isaddr = op->isaddr;
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++)
sym_link *type, *etype;
int p_type;
- D(emitcode ("", "; aopDerefAop(%s)", aopName(aop)));
+ DD(emitcode ("", "; aopDerefAop(%s)", aopName(aop)));
if (aop->op)
{
flagsonly = FALSE;
}
break;
+ case AOP_LIT:
+ /* Higher levels should optimize this case away but let's be safe */
+ if ((unsigned long) floatFromVal (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)
{
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));
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);
emitcode ("rts", "");
emitLabel (rlbl);
+ _G.stackPushes -= 4; /* account for rts here & in called function */
+ updateCFA();
/* if we need assign a result value */
icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
- D(emitcode ("", "; IS_AOP_HX = %d", IS_AOP_HX (AOP (left))));
+ DD(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))
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));
}
/*-----------------------------------------------------------------*/
-/* genMinusDec :- does subtraction with deccrement if possible */
+/* genMinusDec :- does subtraction with decrement if possible */
/*-----------------------------------------------------------------*/
static bool
genMinusDec (iCode * ic)
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";
}
|| (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);
/* left unsigned, right signed literal -- literal determines sign handling */
if (AOP_TYPE(right)==AOP_LIT && lUnsigned && !rUnsigned)
{
- signed char val=floatFromVal (AOP (right)->aopu.aop_lit);
+ signed char val=(signed char)floatFromVal (AOP (right)->aopu.aop_lit);
loadRegFromAop (hc08_reg_a, AOP (left), 0);
if (val < 0)
if (AOP_TYPE(right)==AOP_LIT && !rUnsigned)
{
- signed char val=floatFromVal (AOP (right)->aopu.aop_lit);
+ signed char val=(signed char)floatFromVal (AOP (right)->aopu.aop_lit);
/* AND literal negative */
if (val < 0) {
emitcode ("ldx", "#0x%02x", -val);
loadRegFromAop (hc08_reg_h, AOP (left), 1);
loadRegFromAop (hc08_reg_a, AOP (left), 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;
}
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);
if (runtimeSign || compiletimeSign)
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;
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;
aopOp ((result = IC_RESULT (ic)), ic, TRUE);
#ifdef DEBUG_TYPE
- D(emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
+ DD(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]",
+ DD(emitcode ("", "; Size res[%d] = l[%d]&r[%d]",
AOP_SIZE (result),
AOP_SIZE (left), AOP_SIZE (right)));
#endif
aopOp ((result = IC_RESULT (ic)), ic, TRUE);
#ifdef DEBUG_TYPE
- D(emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
+ DD(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]",
+ DD(emitcode ("", "; Size res[%d] = l[%d]&r[%d]",
AOP_SIZE (result),
AOP_SIZE (left), AOP_SIZE (right)));
#endif
aopOp ((result = IC_RESULT (ic)), ic, TRUE);
#ifdef DEBUG_TYPE
- D(emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
+ DD(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]",
+ DD(emitcode ("", "; Size res[%d] = l[%d]&r[%d]",
AOP_SIZE (result),
AOP_SIZE (left), AOP_SIZE (right)));
#endif
if (*inlin == '_')
{
symname = ++inlin;
- while (isalnum(*inlin) || (*inlin == '_'))
+ while (isalnum((unsigned char)*inlin) || (*inlin == '_'))
inlin++;
c = *inlin;
*inlin = '\0';
/*-----------------------------------------------------------------*/
/* 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);
size = AOP_SIZE (result);
#if VIEW_SIZE
- D(emitcode ("; shift left ", "result %d, left %d", size,
+ DD(emitcode ("; shift left ", "result %d, left %d", size,
AOP_SIZE (left)));
#endif
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);
+ 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);
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);
}
/*-----------------------------------------------------------------*/
rmwWithReg ("lsr", hc08_reg_x);
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);
- storeRegSignToUpperAop (hc08_reg_a, AOP (result), MSB32, sign);
+ 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);
aopOp (result, ic, FALSE);
#if VIEW_SIZE
- D(emitcode ("; shift right ", "result %d, left %d", AOP_SIZE (result),
+ DD(emitcode ("; shift right ", "result %d, left %d", AOP_SIZE (result),
AOP_SIZE (left)));
#endif
operand *right, *left, *result;
sym_link *retype;
int size, offset;
-// char *l;
symbol *tlbl, *tlbl1;
char *shift;
bool sign;
+ asmop *aopResult;
D(emitcode ("; genRightShift",""));
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);
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);
}
blen = SPEC_BLEN (etype);
bstr = SPEC_BSTR (etype);
- /* If the bitfield length is less than a byte */
- if (blen < 8)
+ if (ifx && blen <= 8)
{
emitcode ("lda", ",x");
hc08_dirtyReg (hc08_reg_a, FALSE);
- if (!ifx)
- {
- AccRsh (bstr, FALSE);
- emitcode ("and", "#0x%02x", ((unsigned char) -1) >> (8 - blen));
- storeRegToAop (hc08_reg_a, AOP (result), offset++);
- }
- else
+ 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)
+ {
+ emitcode ("lda", ",x");
+ 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);
- if (!ifx)
- 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);
- if (ifx && !ifx->generated)
- {
- genIfxJump (ifx, "a");
+ while (rsize--)
+ storeRegToAop (hc08_reg_a, AOP (result), offset++);
+ }
}
}
emitcode ("brclr", "#%d,%s,%05d$",
bstr, aopAdrStr (derefaop, 0, FALSE),
(tlbl->key + 100));
- rmwWithReg ("inc", hc08_reg_a);
+ 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);
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
{
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++);
}
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++);
+ }
}
freeAsmop (NULL, derefaop, ic, TRUE);
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 = (unsigned long) floatFromVal (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);
}
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 */