(((x)->type == AOP_REG) \
&& ((x)->aopu.aop_reg[0] == hc08_reg_h) \
&& ((x)->size == 1) )
-
+
#define CLRC emitcode("clc","")
static lineNode *lineHead = NULL;
srcidx = sreg->rIdx;
dstidx = dreg->rIdx;
-
+
if (srcidx==dstidx)
return;
-
+
switch (dstidx)
{
case A_IDX:
/* there is no frame unless there is a function */
if (!currFunc)
return;
-
+
debugFile->writeFrameAddress (NULL, hc08_reg_sp,
1 + _G.stackOfs + _G.stackPushes);
}
pushReg (regs *reg, bool freereg)
{
int regidx = reg->rIdx;
-
+
switch (regidx)
{
case A_IDX:
pullReg (regs *reg)
{
int regidx = reg->rIdx;
-
+
switch (regidx)
{
case A_IDX:
n = 0;
updateCFA();
}
- }
+ }
}
{
static char buffer[256];
char *buf = buffer;
-
+
if (!aop)
return "(asmop*)NULL";
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
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_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))
loadRegFromAop (hc08_reg_x, aop, loffset+1);
}
break;
- }
+ }
// ignore caching for now
#if 0
int loffset;
asmop *newaop = newAsmop (aop->type);
memcpy (newaop, aop, sizeof(*newaop));
-
+
DD(emitcode("", "; forcedStackAop %s", aopName(aop)));
if (copyOrig && hc08_reg_a->isFree)
reg = hc08_reg_x;
else
reg = NULL;
-
+
for (loffset=0; loffset < newaop->size; loffset++)
{
asmop *aopsof = newAsmop (AOP_SOF);
storeRegToAop (hc08_reg_x, aop, loffset+1);
}
break;
- }
+ }
/* Disable the register tracking for now */
#if 0
hc08_reg_xa->aop = NULL;
DD(emitcode("","; marking xa stale"));
}
-
+
reg->aop = aop;
reg->aopofs = loffset;
}
{
// int regidx = reg->rIdx;
int size = aop->size;
-
+
if (size<=loffset)
return;
-
+
if (!isSigned)
{
/* Unsigned case */
&& 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);
// aopName (srcaop), srcofs, aopName (dstaop), dstofs));
// DD(emitcode ("", "; srcaop->type = %d", srcaop->type));
// DD(emitcode ("", "; dstaop->type = %d", dstaop->type));
-
+
if (dstofs >= dstaop->size)
return;
{
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));
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);
}
rmwWithAop (rmwop, aop->stk_aop[loffset], 0);
return;
}
-
+
switch (aop->type)
{
case AOP_REG:
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");
exit(1);
-
+
/* if it is in code space */
if (IN_CODESPACE (space))
aop->code = 1;
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))
//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);
}
pullNull (stackAdjust);
}
-
+
dealloc:
/* all other cases just dealloc */
if (op)
asmop *newaop = NULL;
sym_link *type, *etype;
int p_type;
-
+
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:
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)))
{
if (resultInA)
hc08_freeReg(hc08_reg_a);
-
+
switch (aop->type)
{
case AOP_REG:
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;
-
+
D(emitcode ("; genCpl",""));
/* assign asmOps to operand & result */
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);
}
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),
+ rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
hc08_rUmaskForOp (IC_RESULT(ic)));
ic->regsSaved = 1;
/* restore the registers in use at this time but skip the
ones for the result */
- rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
+ rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
hc08_rUmaskForOp (IC_RESULT(ic)));
for (i = hc08_nRegs; i >= 0; i--)
hc08_aop_pass[offset+(sic->argreg-1)], 0);
offset--;
}
- }
+ }
freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
}
}
/* 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))->accuse ||
OP_SYMBOL (IC_RESULT (ic))->spildir)) ||
IS_TRUE_SYMOP (IC_RESULT (ic)))
{
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);
}
_G.stackOfs = sym->stack;
_G.stackPushes = 0;
-
+
/* if critical function then turn interrupts off */
if (IFFUNC_ISCRITICAL (ftype))
{
{
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);
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
+ 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;
unsigned int size = getDataSize (IC_RESULT (ic));
unsigned int offset;
symbol *tlbl = NULL;
-
+
left = IC_LEFT (ic);
result = IC_RESULT (ic);
icount = (unsigned int) ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
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;
}
- DD(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;
}
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));
unsigned int size = getDataSize (IC_RESULT (ic));
// int offset;
// symbol *tlbl;
-
+
left = IC_LEFT (ic);
result = IC_RESULT (ic);
pullOrFreeReg (hc08_reg_x, needpulx);
return TRUE;
}
-
+
if ((icount > 1) || (icount<0))
return FALSE;
D(emitcode ("; genMinusDec",""));
rmwWithAop ("dec", AOP (result), 0);
-
+
return TRUE;
}
{
char *sub;
int size, offset = 0;
-
+
asmop *leftOp, *rightOp;
D(emitcode ("; genMinus",""));
storeRegToAop (hc08_reg_a, AOP (IC_RESULT (ic)), offset++);
sub = "sbc";
}
-
-
+
+
// adjustArithmeticResult (ic);
release:
if (size<1 || size>2) {
// this should never happen
- fprintf (stderr, "size!=1||2 (%d) in %s at line:%d \n",
+ fprintf (stderr, "size!=1||2 (%d) in %s at line:%d \n",
AOP_SIZE(result), __FILE__, lineno);
exit (1);
}
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 */
hc08_dirtyReg (hc08_reg_xa, FALSE);
storeRegToFullAop (hc08_reg_xa, AOP (result), TRUE);
hc08_freeReg (hc08_reg_xa);
-
+
return;
}
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);
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;
}
-
+
/* case 3 */
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);
int offset = 0;
bool lUnsigned, rUnsigned;
bool runtimeSign, compiletimeSign;
-
+
lUnsigned = SPEC_USIGN (getSpec (operandType (left)));
rUnsigned = SPEC_USIGN (getSpec (operandType (right)));
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);
-
+
if (runtimeSign || compiletimeSign)
{
tlbl3 = newiTempLabel (NULL);
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 */
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);
-
+
if (lUnsigned && rUnsigned)
{
/* unsigned is easy */
}
/* signed is a little bit more difficult */
-
+
if (AOP_TYPE(right) == AOP_LIT)
{
signed char val = (char) ulFromVal (AOP (right)->aopu.aop_lit);
emitLabel (tlbl1);
}
}
-
+
/* let's see what's needed: */
/* apply negative sign during runtime */
runtimeSign = FALSE;
runtimeSign = TRUE;
adjustStack (-1);
emitcode ("clr", "1,s");
-
+
loadRegFromAop (hc08_reg_a, AOP (left), 0);
tlbl2 = newiTempLabel (NULL);
emitcode ("tsta", "");
emitLabel (tlbl2);
}
}
-
+
loadRegFromConst (hc08_reg_h, zero);
emitcode ("div", "");
hc08_freeReg (hc08_reg_a);
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 */
{
storeRegToFullAop (hc08_reg_h, AOP (result), FALSE);
}
-
+
hc08_freeReg (hc08_reg_a);
hc08_freeReg (hc08_reg_x);
hc08_freeReg (hc08_reg_h);
/*------------------------------------------------------------------*/
static void
genCmp (iCode * ic, iCode * ifx)
-{
+{
operand *left, *right, *result;
sym_link *letype, *retype;
int sign, opcode;
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_LIT) ||
((AOP_TYPE (right) == AOP_DIR) && (AOP_SIZE (right) == 2)) )
&& hc08_reg_hx->isFree)
{
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 */
right = temp;
opcode = exchangedCmp (opcode);
}
-
+
if ((AOP_TYPE (right) == AOP_LIT) && !isOperandVolatile (left, FALSE))
{
lit = ulFromVal (AOP (right)->aopu.aop_lit);
symbol *tlbl = newiTempLabel (NULL);
char *inst;
- freeAsmop (result, NULL, ic, TRUE);
-
+ freeAsmop (result, NULL, ic, TRUE);
+
inst = branchInstCmp (opcode, sign);
emitBranch (inst, tlbl);
emitBranch ("jmp", jlbl);
{
symbol *tlbl1 = newiTempLabel (NULL);
symbol *tlbl2 = newiTempLabel (NULL);
-
+
emitBranch (branchInstCmp (opcode, sign), tlbl1);
loadRegFromConst (hc08_reg_a, zero);
emitBranch ("bra", tlbl2);
loadRegFromConst (hc08_reg_a, one);
emitLabel (tlbl2);
storeRegToFullAop (hc08_reg_a, AOP(result), FALSE);
- freeAsmop (result, NULL, ic, TRUE);
+ freeAsmop (result, NULL, ic, TRUE);
}
-
+
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static void
genCmpEQorNE (iCode * ic, iCode * ifx)
-{
+{
operand *left, *right, *result;
sym_link *letype, *retype;
int sign, opcode;
symbol *jlbl = NULL;
symbol *tlbl_NE = NULL;
symbol *tlbl_EQ = NULL;
-
+
opcode = ic->op;
D(emitcode ("; genCmpEQorNE", "(%s)",nameCmp (opcode)));
aopOp (left, ic, FALSE);
aopOp (right, ic, FALSE);
aopOp (result, ic, TRUE);
-
+
/* need register operand on left, prefer literal operand on right */
if ((AOP_TYPE (right) == AOP_REG) || AOP_TYPE (left) == AOP_LIT)
{
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_LIT) ||
((AOP_TYPE (right) == AOP_DIR) && (AOP_SIZE (right) == 2)) )
&& hc08_reg_hx->isFree)
{
if (ifx)
{
- freeAsmop (result, NULL, ic, TRUE);
-
+ freeAsmop (result, NULL, ic, TRUE);
+
if (opcode == EQ_OP)
{
if (!tlbl_EQ)
else
{
symbol *tlbl = newiTempLabel (NULL);
-
+
if (opcode == EQ_OP)
{
if (!tlbl_EQ)
emitLabel (tlbl_NE);
loadRegFromConst (hc08_reg_a, one);
}
-
+
emitLabel (tlbl);
storeRegToFullAop (hc08_reg_a, AOP(result), FALSE);
- freeAsmop (result, NULL, ic, TRUE);
+ freeAsmop (result, NULL, ic, TRUE);
}
-
+
}
/* Make sure this is the only use of the pointer */
if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
return FALSE;
-
+
DD(emitcode("", "; checking pset operandsEqu"));
if (pset & !operandsEqu (IC_RESULT (ic), IC_RESULT (lic)))
return FALSE;
return FALSE;
sym = OP_SYMBOL (IC_LEFT (ic));
-
+
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;
-
+
while (size--)
{
emitcode ("lda", "%s,x",
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;
-
+
while (size--)
{
loadRegFromAop (hc08_reg_a, AOP (IC_RIGHT (lic)), size);
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) &&
+ isOperandEqual(IC_RESULT(lic),op) &&
isOperandLiteral(IC_RIGHT(lic)) &&
operandLitValue(IC_RIGHT(lic)) == isize) {
return lic;
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);
unsigned long litinv;
unsigned char bytemask;
-
+
// int bytelit = 0;
// char buffer[10];
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)))
/* this generates ugly code, but meets volatility requirements */
loadRegFromConst (hc08_reg_a, zero);
pushReg (hc08_reg_a, TRUE);
-
+
offset = 0;
while (size--)
{
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 == 0)
{
/* do nothing */
genIfxJump (ifx, "a");
goto release;
}
-
+
size = AOP_SIZE (result);
if (AOP_TYPE (right) == AOP_LIT)
goto release;
}
}
-
+
offset = 0;
while (size--)
{
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);
+ hc08_freeReg( hc08_reg_a);
}
storeConstToAop (zero, AOP (result), offset);
}
loadRegFromAop (hc08_reg_a, AOP (left), offset);
accopWithAop ("and", AOP (right), offset);
storeRegToAop (hc08_reg_a, AOP (result), offset);
- hc08_freeReg (hc08_reg_a);
+ hc08_freeReg (hc08_reg_a);
}
offset++;
}
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)))
/* this generates ugly code, but meets volatility requirements */
loadRegFromConst (hc08_reg_a, zero);
pushReg (hc08_reg_a, TRUE);
-
+
offset = 0;
while (size--)
{
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);
emitLabel (tlbl);
genIfxJump (ifx, "a");
}
-
+
if (AOP_TYPE (right) == AOP_LIT)
lit = ulFromVal (AOP (right)->aopu.aop_lit);
aopAdrStr (AOP (left), bitpos >> 3, FALSE));
goto release;
}
-
+
offset = 0;
while (size--)
{
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);
+ hc08_freeReg( hc08_reg_a);
}
transferAopAop (AOP (right), offset, AOP (result), offset);
}
loadRegFromAop (hc08_reg_a, AOP (left), offset);
accopWithAop ("ora", AOP (right), offset);
storeRegToAop (hc08_reg_a, AOP (result), offset);
- hc08_freeReg (hc08_reg_a);
+ hc08_freeReg (hc08_reg_a);
}
offset++;
}
{
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 = ulFromVal (AOP (right)->aopu.aop_lit);
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 == '_')
if ((2+bp-buffer)>sizeof(buffer))
fprintf(stderr, "Inline assembly buffer overflow\n");
-
+
//printf("%s\n",buffer);
emitcode (buffer,"");
}
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 */
default:
wassertl(FALSE, "unsupported SWAP operand size");
}
-
+
freeAsmop (left, NULL, ic, TRUE);
freeAsmop (result, NULL, ic, TRUE);
}
AccLsh (int shCount)
{
int i;
-
+
shCount &= 0x0007; // shCount : 0..7
/* Shift counts of 4 and 5 are currently optimized for code size. */
AccSRsh (int shCount)
{
int i;
-
+
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
/* Shift counts of 4 and 5 are currently optimized for code size. */
XAccLsh (int shCount)
{
int i;
-
+
shCount &= 0x000f; // shCount : 0..15
if (shCount>=8)
XAccSRsh (int shCount)
{
int i;
-
+
shCount &= 0x000f; // shCount : 0..7
/* if we can beat 2n cycles or bytes for some special case, do it here */
XAccRsh (int shCount, bool sign)
{
int i;
-
+
if (sign)
{
XAccSRsh (shCount);
return;
}
-
+
shCount &= 0x000f; // shCount : 0..f
/* if we can beat 2n cycles or bytes for some special case, do it here */
int i;
bool needpula = FALSE;
bool needpulx = FALSE;
-
+
needpula = pushRegIfUsed (hc08_reg_a);
needpulx = pushRegIfUsed (hc08_reg_x);
D(emitcode ("; genlshTwo",""));
-
+
size = getDataSize (result);
/* if shCount >= 8 */
genlshFour (result, left, shCount);
break;
default:
- werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
"*** ack! mystery literal shift!\n");
break;
}
aopResult = AOP (result);
if (sameRegs(AOP (right), AOP (result)) || IS_AOP_XA (AOP (result))
- || isOperandVolatile (result, FALSE))
+ || isOperandVolatile (result, FALSE))
aopResult = forceStackedAop (AOP (result), sameRegs ( AOP (left), AOP (result)));
/* now move the left to the result if they are not the
}
freeAsmop (left, NULL, ic, TRUE);
AOP (result) = aopResult;
-
+
tlbl = newiTempLabel (NULL);
size = AOP_SIZE (result);
offset = 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", hc08_reg_x);
emitBranch ("bne", tlbl);
emitLabel (tlbl1);
hc08_freeReg (hc08_reg_x);
-
+
freeAsmop (result, NULL, ic, TRUE);
freeAsmop (right, NULL, ic, TRUE);
}
int shCount, int sign)
{
/* TODO: handle cases where left == result */
-
+
D(emitcode ("; genrshFour",""));
/* if shifting more that 3 bytes */
char *shift;
bool sign;
asmop *aopResult;
-
+
D(emitcode ("; genRightShift",""));
/* if signed then we do it the hard way preserve the
aopResult = AOP (result);
if (sameRegs(AOP (right), AOP (result)) || IS_AOP_XA (AOP (result))
- || isOperandVolatile (result, FALSE))
+ || isOperandVolatile (result, FALSE))
aopResult = forceStackedAop (AOP (result), sameRegs ( AOP (left), AOP (result)));
/* now move the left to the result if they are not the
}
freeAsmop (left, NULL, ic, TRUE);
AOP (result) = aopResult;
-
+
tlbl = newiTempLabel (NULL);
size = AOP_SIZE (result);
offset = 0;
emitBranch ("bne", tlbl);
emitLabel (tlbl1);
hc08_freeReg (hc08_reg_x);
-
+
freeAsmop (result, NULL, ic, TRUE);
freeAsmop (right, NULL, ic, TRUE);
}
emitcode ("rola", "");
emitcode ("clra", "");
emitcode ("sbc", zero);
-
+
while (rsize--)
storeRegToAop (hc08_reg_a, AOP (result), offset++);
}
int blen; /* bitfield length */
int bstr; /* bitfield starting bit within byte */
asmop *derefaop;
-
+
D(emitcode ("; genUnpackBitsImmed",""));
aopOp (result, ic, TRUE);
derefaop = aopDerefAop (AOP (left));
freeAsmop (left, NULL, ic, TRUE);
derefaop->size = size;
-
+
etype = getSpec (operandType (result));
rsize = getSize (operandType (result));
blen = SPEC_BLEN (etype);
if (!ifx && bstr)
{
symbol *tlbl = newiTempLabel (NULL);
-
+
loadRegFromConst (hc08_reg_a, zero);
emitcode ("brclr", "#%d,%s,%05d$",
bstr, aopAdrStr (derefaop, 0, FALSE),
symbol *tlbl = newiTempLabel (NULL);
symbol *jlbl;
char * inst;
-
+
if (IC_TRUE (ifx))
{
jlbl = IC_TRUE (ifx);
storeRegToAop (hc08_reg_a, AOP (result), offset++);
}
}
-
+
freeAsmop (NULL, derefaop, ic, TRUE);
freeAsmop (result, NULL, ic, TRUE);
-
+
if (ifx && !ifx->generated)
{
genIfxJump (ifx, "a");
{
int size;
asmop *derefaop;
-
+
D(emitcode ("; genDataPointerGet",""));
aopOp (result, ic, TRUE);
derefaop = aopDerefAop (AOP (left));
freeAsmop (left, NULL, ic, TRUE);
derefaop->size = size;
-
+
while (size--)
{
if (!ifx)
freeAsmop (NULL, derefaop, ic, TRUE);
freeAsmop (result, NULL, ic, TRUE);
-
+
if (ifx && !ifx->generated)
{
genIfxJump (ifx, "a");
if (getSize (operandType (result))>1)
ifx = NULL;
-
+
aopOp (left, ic, FALSE);
/* if left is rematerialisable and
freeAsmop (left, NULL, ic, TRUE);
freeAsmop (result, NULL, ic, TRUE);
-
+
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;
}
-
+
if (ifx && !ifx->generated)
{
genIfxJump (ifx, "a");
}
hc08_freeReg (hc08_reg_hx);
-
+
}
/*-----------------------------------------------------------------*/
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 (rlen)
{
mask = (((unsigned char) -1 << rlen) & 0xff);
-
+
if (AOP_TYPE (right) == AOP_LIT)
{
/* Case with partial byte and literal source
hc08_freeReg (hc08_reg_a);
return;
}
-
+
/* Case with partial byte and arbitrary source
*/
loadRegFromAop (hc08_reg_a, AOP (right), offset);
if (AOP_TYPE (right) == AOP_LIT)
{
litval = (int) ulFromVal (AOP (right)->aopu.aop_lit);
-
- emitcode ((litval & 1) ? "bset" : "bclr",
+
+ 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);
}
goto release;
}
-
+
/* If the bitfield length is less than a byte */
if (blen < 8)
{
emitcode ("ora","#0x%02x", litval);
hc08_dirtyReg (hc08_reg_a, FALSE);
storeRegToAop (hc08_reg_a, derefaop, 0);
-
+
hc08_freeReg (hc08_reg_a);
goto release;
}
-
+
/* Case with a bitfield length < 8 and arbitrary source
*/
loadRegFromAop (hc08_reg_a, AOP (right), 0);
emitcode ("ora", "1,s");
storeRegToAop (hc08_reg_a, derefaop, 0);
pullReg (hc08_reg_a);
-
+
hc08_freeReg (hc08_reg_a);
goto release;
}
if (rlen)
{
mask = (((unsigned char) -1 << rlen) & 0xff);
-
+
if (AOP_TYPE (right) == AOP_LIT)
{
/* Case with partial byte and literal source
hc08_freeReg (hc08_reg_a);
goto release;
}
-
+
/* Case with partial byte and arbitrary source
*/
loadRegFromAop (hc08_reg_a, AOP (right), offset);
hc08_freeReg (hc08_reg_a);
-release:
+release:
freeAsmop (right, NULL, ic, TRUE);
freeAsmop (NULL, derefaop, ic, TRUE);
}
derefaop = aopDerefAop (AOP (result));
freeAsmop (result, NULL, ic, TRUE);
derefaop->size = size;
-
+
while (size--)
{
transferAopAop (AOP (right), size, derefaop, size);
type = operandType (result);
etype = getSpec (type);
-
+
aopOp (result, ic, FALSE);
/* if the result is rematerializable */
loadRegFromAop(hc08_reg_hx, AOP (right), 0);
goto release;
}
-
+
/* general case */
size = AOP_SIZE (result);
while (size--)
symbol *jtab;
symbol *jtablo = newiTempLabel (NULL);
symbol *jtabhi = newiTempLabel (NULL);
-
+
D(emitcode ("; genJumpTab",""));
aopOp (IC_JTCOND (ic), ic, FALSE);
-
+
if (hc08_reg_x->isFree && hc08_reg_x->isFree)
{
/* get the condition into x */
{
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);
emitcode ("sta", "3,s");
emitcode ("lda", "%05d$,x", jtablo->key + 100);
emitcode ("sta", "4,s");
-
+
pullReg(hc08_reg_hx);
emitcode ("rts", "");
_G.stackPushes += 2;
{
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;
}
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
{
emitcode ("dbnz", "%s,%05d$", aopAdrStr (AOP (IC_RESULT (ic)), 0, FALSE),
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,
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);
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)
clevel = ic->level;
cblock = ic->block;
}
-
+
if (ic->lineno && cln != ic->lineno)
{
if (options.debug)
#endif
}
if (!options.noCcodeInAsm) {
- emitcode ("", ";%s:%d: %s", ic->filename, ic->lineno,
+ emitcode ("", ";%s:%d: %s", ic->filename, ic->lineno,
printCLine(ic->filename, ic->lineno));
}
cln = ic->lineno;
if (options.iCodeInAsm) {
char regsInUse[80];
int i;
- char *iLine;
+ const char *iLine;
for (i=0; i<6; i++) {
sprintf (®sInUse[i],
- "%c", ic->riu & (1<<i) ? i+'0' : '-');
+ "%c", ic->riu & (1<<i) ? i+'0' : '-');
}
regsInUse[i]=0;
iLine = printILine(ic);
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 ENDCRITICAL:
genEndCritical (ic);
break;
-
+
case SWAP:
genSwap (ic);
break;
}
debugFile->writeFrameAddress (NULL, NULL, 0); /* have no idea where frame is now */
-
+
/* now we are ready to call the
peep hole optimizer */