#ifdef HAVE_SYS_ISA_DEFS_H
#include <sys/isa_defs.h>
#else
+#ifdef HAVE_MACHINE_ENDIAN_H
+#include <machine/endian.h>
+#else
#ifdef HAVE_ENDIAN_H
#include <endian.h>
#else
#endif
#endif
#endif
+#endif
#define BETTER_LITERAL_SHIFT
#define D(x) x
+#define TR_DPTR(s) if (options.model != MODEL_FLAT24) { emitcode(";", " Use_DPTR1 %s ", s); }
+#define TR_AP(s) if (options.model != MODEL_FLAT24) { emitcode(";", " Use_AP %s ", s); }
+
unsigned fReturnSizeDS390 = 5; /* shared with ralloc.c */
-static char *fReturn[] =
+static char *fReturn24[] =
{"dpl", "dph", "dpx", "b", "a"};
+static char *fReturn16[] =
+{"dpl", "dph", "b", "a"};
+static char **fReturn = fReturn24;
static char *accUse[] =
{"a", "b"};
}
else
{
+ TR_DPTR("#1");
emitcode ("mov", "dps, #0x01");
}
}
if (useDP2)
{
- emitcode ("mov", "dpx1,#0x40");
+ if (options.model == MODEL_FLAT24)
+ emitcode ("mov", "dpx1,#0x40");
+ TR_DPTR("#2");
emitcode ("mov", "dph1,#0x00");
emitcode ("mov", "dpl1, a");
}
else
{
- emitcode ("mov", "dpx,#0x40");
+ if (options.model == MODEL_FLAT24)
+ emitcode ("mov", "dpx,#0x40");
emitcode ("mov", "dph,#0x00");
emitcode ("mov", "dpl, a");
}
genSetDPTR (1);
if (!canClobberACC)
{
+ TR_AP("#1");
emitcode ("xch", "a, %s", DP2_RESULT_REG);
}
}
genSetDPTR (0);
if (!canClobberACC)
{
+ TR_AP("#2");
emitcode ("xch", "a, %s", DP2_RESULT_REG);
return DP2_RESULT_REG;
}
/* if the registers have been saved already then
do nothing */
- if (ic->regsSaved || (OP_SYMBOL (IC_LEFT (ic))->calleeSave) ||
- SPEC_NAKED(OP_SYM_ETYPE(IC_LEFT(ic))))
+ if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL (IC_LEFT (ic))->type) ||
+ IFFUNC_ISNAKED(OP_SYM_TYPE(IC_LEFT(ic))))
return;
/* find the registers in use at this time
static void
genCall (iCode * ic)
{
- sym_link *detype;
+ sym_link *dtype;
bool restoreBank = FALSE;
bool swapBanks = FALSE;
/* if we are calling a not _naked function that is not using
the same register bank then we need to save the
destination registers on the stack */
- detype = getSpec (operandType (IC_LEFT (ic)));
- if (detype && !SPEC_NAKED(detype) &&
- (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype)) &&
- IS_ISR (currFunc->etype))
+ dtype = operandType (IC_LEFT (ic));
+ if (dtype && !IFFUNC_ISNAKED(dtype) &&
+ (FUNC_REGBANK (currFunc->type) != FUNC_REGBANK (dtype)) &&
+ IFFUNC_ISISR (currFunc->type))
{
if (!ic->bankSaved)
{
/* This is unexpected; the bank should have been saved in
* genFunction.
*/
- saveRBank (SPEC_BANK (detype), ic, FALSE);
+ saveRBank (FUNC_REGBANK (dtype), ic, FALSE);
restoreBank = TRUE;
}
swapBanks = TRUE;
if (swapBanks)
{
emitcode ("mov", "psw,#0x%02x",
- ((SPEC_BANK(detype)) << 3) & 0xff);
+ ((FUNC_REGBANK(dtype)) << 3) & 0xff);
}
/* make the call */
if (swapBanks)
{
emitcode ("mov", "psw,#0x%02x",
- ((SPEC_BANK(currFunc->etype)) << 3) & 0xff);
+ ((FUNC_REGBANK(currFunc->type)) << 3) & 0xff);
}
/* if we need assign a result value */
}
/* if we hade saved some registers then unsave them */
- if (ic->regsSaved && !(OP_SYMBOL (IC_LEFT (ic))->calleeSave))
+ if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
unsaveRegisters (ic);
/* if register bank was saved then pop them */
if (restoreBank)
- unsaveRBank (SPEC_BANK (detype), ic, FALSE);
+ unsaveRBank (FUNC_REGBANK (dtype), ic, FALSE);
}
/*-----------------------------------------------------------------*/
static void
genPcall (iCode * ic)
{
- sym_link *detype;
+ sym_link *dtype;
symbol *rlbl = newiTempLabel (NULL);
D (emitcode (";", "genPcall ");
/* if we are calling a function that is not using
the same register bank then we need to save the
destination registers on the stack */
- detype = getSpec (operandType (IC_LEFT (ic)));
- if (detype &&
- IS_ISR (currFunc->etype) &&
- (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype)))
- saveRBank (SPEC_BANK (detype), ic, TRUE);
+ dtype = operandType (IC_LEFT (ic));
+ if (dtype &&
+ IFFUNC_ISISR (currFunc->type) &&
+ (FUNC_REGBANK (currFunc->type) != FUNC_REGBANK (dtype)))
+ saveRBank (FUNC_REGBANK (dtype), ic, TRUE);
/* push the return address on to the stack */
}
/* if register bank was saved then unsave them */
- if (detype &&
- (SPEC_BANK (currFunc->etype) !=
- SPEC_BANK (detype)))
- unsaveRBank (SPEC_BANK (detype), ic, TRUE);
+ if (dtype &&
+ (FUNC_REGBANK (currFunc->type) !=
+ FUNC_REGBANK (dtype)))
+ unsaveRBank (FUNC_REGBANK (dtype), ic, TRUE);
/* if we hade saved some registers then
unsave them */
genFunction (iCode * ic)
{
symbol *sym;
- sym_link *fetype;
+ sym_link *ftype;
bool switchedPSW = FALSE;
D (emitcode (";", "genFunction "););
emitcode (";", "-----------------------------------------");
emitcode ("", "%s:", sym->rname);
- fetype = getSpec (operandType (IC_LEFT (ic)));
+ ftype = operandType (IC_LEFT (ic));
- if (SPEC_NAKED(fetype))
+ if (IFFUNC_ISNAKED(ftype))
{
emitcode(";", "naked function: no prologue.");
return;
}
/* if critical function then turn interrupts off */
- if (SPEC_CRTCL (fetype))
+ if (IFFUNC_ISCRITICAL (ftype))
emitcode ("clr", "ea");
/* here we need to generate the equates for the
register bank if required */
- if (SPEC_BANK (fetype) != rbank)
+ if (FUNC_REGBANK (ftype) != rbank)
{
int i;
- rbank = SPEC_BANK (fetype);
+ rbank = FUNC_REGBANK (ftype);
for (i = 0; i < ds390_nRegs; i++)
{
if (strcmp (regs390[i].base, "0") == 0)
/* if this is an interrupt service routine then
save acc, b, dpl, dph */
- if (IS_ISR (sym->etype))
+ if (IFFUNC_ISISR (sym->type))
{
if (!inExcludeList ("acc"))
/* if this isr has no bank i.e. is going to
run with bank 0 , then we need to save more
registers :-) */
- if (!SPEC_BANK (sym->etype))
+ if (!FUNC_REGBANK (sym->type))
{
/* if this function does not call any other
function then we can be economical and
save only those registers that are used */
- if (!sym->hasFcall)
+ if (!IFFUNC_HASFCALL(sym->type))
{
int i;
*/
unsigned long banksToSave = 0;
- if (sym->hasFcall)
+ if (IFFUNC_HASFCALL(sym->type))
{
#define MAX_REGISTER_BANKS 4
if (i->op == CALL)
{
- sym_link *detype;
+ sym_link *dtype;
- detype = getSpec(operandType (IC_LEFT(i)));
- if (detype
- && SPEC_BANK(detype) != SPEC_BANK(sym->etype))
+ dtype = operandType (IC_LEFT(i));
+ if (dtype
+ && FUNC_REGBANK(dtype) != FUNC_REGBANK(sym->type))
{
/* Mark this bank for saving. */
- if (SPEC_BANK(detype) >= MAX_REGISTER_BANKS)
+ if (FUNC_REGBANK(dtype) >= MAX_REGISTER_BANKS)
{
- werror(E_NO_SUCH_BANK, SPEC_BANK(detype));
+ werror(E_NO_SUCH_BANK, FUNC_REGBANK(dtype));
}
else
{
- banksToSave |= (1 << SPEC_BANK(detype));
+ banksToSave |= (1 << FUNC_REGBANK(dtype));
}
/* And note that we don't need to do it in
*/
emitcode ("push", "psw");
emitcode ("mov", "psw,#0x%02x",
- (SPEC_BANK (sym->etype) << 3) & 0x00ff);
+ (FUNC_REGBANK (sym->type) << 3) & 0x00ff);
switchedPSW = TRUE;
}
}
}
}
+ // jwk: this needs a closer look
SPEC_ISR_SAVED_BANKS(currFunc->etype) = banksToSave;
}
}
{
/* if callee-save to be used for this function
then save the registers being used in this function */
- if (sym->calleeSave)
+ if (IFFUNC_CALLEESAVES(sym->type))
{
int i;
}
/* set the register bank to the desired value */
- if ((SPEC_BANK (sym->etype) || IS_ISR (sym->etype))
+ if ((FUNC_REGBANK (sym->type) || FUNC_ISISR (sym->type))
&& !switchedPSW)
{
emitcode ("push", "psw");
- emitcode ("mov", "psw,#0x%02x", (SPEC_BANK (sym->etype) << 3) & 0x00ff);
+ emitcode ("mov", "psw,#0x%02x", (FUNC_REGBANK (sym->type) << 3) & 0x00ff);
}
- if (IS_RENT (sym->etype) || options.stackAuto)
+ if (IFFUNC_ISREENT (sym->type) || options.stackAuto)
{
if (options.useXstack)
D (emitcode (";", "genEndFunction "););
- if (SPEC_NAKED(sym->etype))
+ if (IFFUNC_ISNAKED(sym->type))
{
emitcode(";", "naked function: no epilogue.");
return;
}
- if (IS_RENT (sym->etype) || options.stackAuto)
+ if (IFFUNC_ISREENT (sym->type) || options.stackAuto)
{
emitcode ("mov", "%s,_bp", spname);
}
}
- if ((IS_RENT (sym->etype) || options.stackAuto))
+ if ((IFFUNC_ISREENT (sym->type) || options.stackAuto))
{
if (options.useXstack)
{
}
/* restore the register bank */
- if (SPEC_BANK (sym->etype) || IS_ISR (sym->etype))
+ if (FUNC_REGBANK (sym->type) || IFFUNC_ISISR (sym->type))
{
- if (!SPEC_BANK (sym->etype) || !IS_ISR (sym->etype)
+ if (!FUNC_REGBANK (sym->type) || !IFFUNC_ISISR (sym->type)
|| !options.useXstack)
{
/* Special case of ISR using non-zero bank with useXstack
}
}
- if (IS_ISR (sym->etype))
+ if (IFFUNC_ISISR (sym->type))
{
/* now we need to restore the registers */
/* if this isr has no bank i.e. is going to
run with bank 0 , then we need to save more
registers :-) */
- if (!SPEC_BANK (sym->etype))
+ if (!FUNC_REGBANK (sym->type))
{
/* if this function does not call any other
function then we can be economical and
save only those registers that are used */
- if (!sym->hasFcall)
+ if (!IFFUNC_HASFCALL(sym->type))
{
int i;
* Restore any register banks saved by genFunction
* in reverse order.
*/
+ // jwk: this needs a closer look
unsigned savedBanks = SPEC_ISR_SAVED_BANKS(currFunc->etype);
int ix;
if (!inExcludeList ("acc"))
emitcode ("pop", "acc");
- if (SPEC_CRTCL (sym->etype))
+ if (IFFUNC_ISCRITICAL (sym->type))
emitcode ("setb", "ea");
/* if debug then send end of function */
}
else
{
- if (SPEC_CRTCL (sym->etype))
+ if (IFFUNC_ISCRITICAL (sym->type))
emitcode ("setb", "ea");
- if (sym->calleeSave)
+ if (IFFUNC_CALLEESAVES(sym->type))
{
int i;
}
}
+#if 0 // AOP_OP_3 is deprecated; nobody likes Ack errors.
+ // Please don't bring it back without a really good reason.
// Macro to aopOp all three operands of an ic. Will fatal if this cannot be done
// (because all three operands are in far space).
#define AOP_OP_3(ic) \
fprintf(stderr, \
"Ack: three operands in far space! (%s:%d %s:%d)\n", __FILE__, __LINE__, ic->filename, ic->lineno); \
}
+#endif
// Macro to aopOp all three operands of an ic. If this cannot be done,
// the IC_LEFT and IC_RIGHT operands will be aopOp'd, and the rc parameter
* above branch.
*/
assert(AOP_NEEDSACC(IC_RIGHT(ic)));
+ TR_AP("#3");
D(emitcode(";", "+ AOP_ACC special case."););
emitcode("xch", "a, %s", DP2_RESULT_REG);
}
{
if (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC)
{
+ TR_AP("#4");
emitcode("add", "a, %s", DP2_RESULT_REG);
}
else
static void
genMultbits (operand * left,
operand * right,
- operand * result)
+ operand * result,
+ iCode * ic)
{
emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
emitcode ("anl", "c,%s", AOP (right)->aopu.aop_dir);
+ aopOp(result, ic, TRUE, FALSE);
outBitC (result);
}
static void
genMultOneByte (operand * left,
operand * right,
- operand * result)
+ operand * result,
+ iCode * ic)
{
sym_link *opetype = operandType (result);
symbol *lbl;
- int size=AOP_SIZE(result);
- 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);
- exit (1);
- }
/* (if two literals: the value is computed before) */
/* if one literal, literal on the right */
emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE, TRUE));
MOVA (aopGet (AOP (left), 0, FALSE, FALSE, TRUE));
emitcode ("mul", "ab");
+
+ _G.accInUse++;
+ aopOp(result, ic, TRUE, FALSE);
+
+ if (AOP_SIZE(result)<1 || AOP_SIZE(result)>2)
+ {
+ // this should never happen
+ fprintf (stderr, "size!=1||2 (%d) in %s at line:%d \n",
+ AOP_SIZE(result), __FILE__, lineno);
+ exit (1);
+ }
+
aopPut (AOP (result), "a", 0);
- if (size==2) {
+ _G.accInUse--;
+ if (AOP_SIZE(result)==2)
+ {
aopPut (AOP (result), "b", 1);
}
return;
}
emitcode ("mul", "ab");
+ _G.accInUse++;
+ aopOp(result, ic, TRUE, FALSE);
+
+ if (AOP_SIZE(result)<1 || AOP_SIZE(result)>2)
+ {
+ // this should never happen
+ fprintf (stderr, "size!=1||2 (%d) in %s at line:%d \n",
+ AOP_SIZE(result), __FILE__, lineno);
+ exit (1);
+ }
+
lbl=newiTempLabel(NULL);
emitcode ("jnb", "F0,%05d$", lbl->key+100);
// only ONE op was negative, we have to do a 8/16-bit two's complement
emitcode ("cpl", "a"); // lsb
- if (size==1) {
+ if (AOP_SIZE(result)==1) {
emitcode ("inc", "a");
} else {
emitcode ("add", "a,#1");
emitcode ("", "%05d$:", lbl->key+100);
aopPut (AOP (result), "a", 0);
- if (size==2) {
+ _G.accInUse--;
+ if (AOP_SIZE(result)==2) {
aopPut (AOP (result), "b", 1);
}
}
D (emitcode (";", "genMult "););
/* assign the amsops */
- AOP_OP_3 (ic);
+ AOP_OP_2 (ic);
/* special cases first */
/* both are bits */
if (AOP_TYPE (left) == AOP_CRY &&
AOP_TYPE (right) == AOP_CRY)
{
- genMultbits (left, right, result);
+ genMultbits (left, right, result, ic);
goto release;
}
if (AOP_SIZE (left) == 1 &&
AOP_SIZE (right) == 1)
{
- genMultOneByte (left, right, result);
+ genMultOneByte (left, right, result, ic);
goto release;
}
/* should have been converted to function call */
- assert (1);
+ assert (0);
release:
freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
static void
genDivbits (operand * left,
operand * right,
- operand * result)
+ operand * result,
+ iCode * ic)
{
char *l;
LOAD_AB_FOR_DIV (left, right, l);
emitcode ("div", "ab");
emitcode ("rrc", "a");
+ aopOp(result, ic, TRUE, FALSE);
+
aopPut (AOP (result), "c", 0);
}
static void
genDivOneByte (operand * left,
operand * right,
- operand * result)
+ operand * result,
+ iCode * ic)
{
sym_link *opetype = operandType (result);
char *l;
symbol *lbl;
int size, offset;
- size = AOP_SIZE (result) - 1;
offset = 1;
/* signed or unsigned */
if (SPEC_USIGN (opetype))
{
- /* unsigned is easy */
- LOAD_AB_FOR_DIV (left, right, l);
- emitcode ("div", "ab");
- aopPut (AOP (result), "a", 0);
- while (size--)
- aopPut (AOP (result), zero, offset++);
+ /* unsigned is easy */
+ LOAD_AB_FOR_DIV (left, right, l);
+ emitcode ("div", "ab");
+
+ _G.accInUse++;
+ aopOp(result, ic, TRUE, FALSE);
+ aopPut (AOP (result), "a", 0);
+ _G.accInUse--;
+
+ size = AOP_SIZE (result) - 1;
+
+ while (size--)
+ {
+ aopPut (AOP (result), zero, offset++);
+ }
return;
}
emitcode ("", "%05d$:", (lbl->key + 100));
/* now we are done */
- aopPut (AOP (result), "b", 0);
- if (size > 0)
+ _G.accInUse++;
+ aopOp(result, ic, TRUE, FALSE);
+
+ aopPut (AOP (result), "b", 0);
+
+ size = AOP_SIZE (result) - 1;
+
+ if (size > 0)
{
emitcode ("mov", "c,b.7");
emitcode ("subb", "a,acc");
}
- while (size--)
- aopPut (AOP (result), "a", offset++);
+ while (size--)
+ {
+ aopPut (AOP (result), "a", offset++);
+ }
+ _G.accInUse--;
}
operand *right = IC_RIGHT (ic);
operand *result = IC_RESULT (ic);
- D (emitcode (";", "genDiv ");
- );
+ D (emitcode (";", "genDiv "););
/* assign the amsops */
- AOP_OP_3 (ic);
+ AOP_OP_2 (ic);
/* special cases first */
/* both are bits */
if (AOP_TYPE (left) == AOP_CRY &&
AOP_TYPE (right) == AOP_CRY)
{
- genDivbits (left, right, result);
+ genDivbits (left, right, result, ic);
goto release;
}
if (AOP_SIZE (left) == 1 &&
AOP_SIZE (right) == 1)
{
- genDivOneByte (left, right, result);
+ genDivOneByte (left, right, result, ic);
goto release;
}
/* should have been converted to function call */
- assert (1);
+ assert (0);
release:
freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
static void
genModbits (operand * left,
operand * right,
- operand * result)
+ operand * result,
+ iCode * ic)
{
char *l;
emitcode ("div", "ab");
emitcode ("mov", "a,b");
emitcode ("rrc", "a");
+ aopOp(result, ic, TRUE, FALSE);
aopPut (AOP (result), "c", 0);
}
static void
genModOneByte (operand * left,
operand * right,
- operand * result)
+ operand * result,
+ iCode * ic)
{
sym_link *opetype = operandType (result);
char *l;
/* unsigned is easy */
LOAD_AB_FOR_DIV (left, right, l);
emitcode ("div", "ab");
+ aopOp(result, ic, TRUE, FALSE);
aopPut (AOP (result), "b", 0);
return;
}
emitcode ("", "%05d$:", (lbl->key + 100));
/* now we are done */
+ aopOp(result, ic, TRUE, FALSE);
aopPut (AOP (result), "b", 0);
}
operand *right = IC_RIGHT (ic);
operand *result = IC_RESULT (ic);
- D (emitcode (";", "genMod ");
- );
+ D (emitcode (";", "genMod "); );
/* assign the amsops */
- AOP_OP_3 (ic);
+ AOP_OP_2 (ic);
/* special cases first */
/* both are bits */
if (AOP_TYPE (left) == AOP_CRY &&
AOP_TYPE (right) == AOP_CRY)
{
- genModbits (left, right, result);
+ genModbits (left, right, result, ic);
goto release;
}
if (AOP_SIZE (left) == 1 &&
AOP_SIZE (right) == 1)
{
- genModOneByte (left, right, result);
+ genModOneByte (left, right, result, ic);
goto release;
}
/* should have been converted to function call */
- assert (1);
+ assert (0);
release:
freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
int size, resultSize, compSize;
int offset = 0;
+ TR_AP("#5");
D(emitcode(";", "%s special case for 3 far operands.", logicOp););
compSize = AOP_SIZE(IC_LEFT(ic)) < AOP_SIZE(IC_RIGHT(ic)) ?
AOP_SIZE(IC_LEFT(ic)) : AOP_SIZE(IC_RIGHT(ic));
#endif
/* if left is a literal & right is not then exchange them */
- if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) ||
- AOP_NEEDSACC (left))
+ if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT)
+#ifdef LOGIC_OPS_BROKEN
+ || AOP_NEEDSACC (left)
+#endif
+ )
{
operand *tmp = right;
right = left;
aopPut (AOP (result), zero, offset);
continue;
}
- D (emitcode (";", "better literal AND.");
- );
+ D (emitcode (";", "better literal AND."););
MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
emitcode ("anl", "a, %s", aopGet (AOP (right), offset,
FALSE, FALSE, FALSE));
}
else
{
- MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
- emitcode ("anl", "a,%s",
- aopGet (AOP (left), offset, FALSE, FALSE, FALSE));
- }
+ char *rOp = aopGet (AOP (right), offset, FALSE, FALSE, TRUE);
+ if (!strcmp(rOp, "a") || !strcmp(rOp, "acc"))
+ {
+ emitcode("mov", "b,a");
+ rOp = "b";
+ }
+
+ MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
+ emitcode ("anl", "a,%s", rOp);
+ }
}
aopPut (AOP (result), "a", offset);
}
#endif
/* if left is a literal & right is not then exchange them */
- if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) ||
- AOP_NEEDSACC (left))
+ if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT)
+#ifdef LOGIC_OPS_BROKEN
+ || AOP_NEEDSACC (left) // I think this is a net loss now.
+#endif
+ )
{
operand *tmp = right;
right = left;
}
else
{
+ _startLazyDPSEvaluation();
for (; (size--); offset++)
{
// normal case
offset);
continue;
}
- D (emitcode (";", "better literal OR.");
- );
+ D (emitcode (";", "better literal OR."););
MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
emitcode ("orl", "a, %s", aopGet (AOP (right), offset,
FALSE, FALSE, FALSE));
}
else
{
- MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
- emitcode ("orl", "a,%s",
- aopGet (AOP (left), offset, FALSE, FALSE, FALSE));
+ char *rOp = aopGet (AOP (right), offset, FALSE, FALSE, TRUE);
+
+ if (!strcmp(rOp, "a") || !strcmp(rOp, "acc"))
+ {
+ emitcode("mov", "b,a");
+ rOp = "b";
+ }
+
+ MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
+ emitcode ("orl", "a,%s", rOp);
}
}
aopPut (AOP (result), "a", offset);
}
+ _endLazyDPSEvaluation();
}
}
/* if left is a literal & right is not ||
if left needs acc & right does not */
- if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) ||
- (AOP_NEEDSACC (left) && !AOP_NEEDSACC (right)))
+ if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT)
+#ifdef LOGIC_OPS_BROKEN
+ || (AOP_NEEDSACC (left) && !AOP_NEEDSACC (right))
+#endif
+ )
{
operand *tmp = right;
right = left;
}
else
{
- MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
- emitcode ("xrl", "a,%s",
- aopGet (AOP (left), offset, FALSE, TRUE, FALSE));
+ char *rOp = aopGet (AOP (right), offset, FALSE, FALSE, TRUE);
+ if (!strcmp(rOp, "a") || !strcmp(rOp, "acc"))
+ {
+ emitcode("mov", "b,a");
+ rOp = "b";
+ }
+
+ MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
+ emitcode ("xrl", "a,%s", rOp);
}
}
aopPut (AOP (result), "a", offset);
leftByte = aopGet (AOP(left), offl, FALSE, FALSE, TRUE);
if (strcmp(leftByte, DP2_RESULT_REG))
{
+ TR_AP("#7");
emitcode("mov","%s,%s", DP2_RESULT_REG, leftByte);
}
// And MSB in A.
case CPOINTER:
emitcode ("clr", "a");
- emitcode ("movc", "a", "@a+dptr");
+ emitcode ("movc", "a,@a+dptr");
break;
case GPOINTER:
case CPOINTER:
emitcode ("clr", "a");
emitcode ("inc", "dptr");
- emitcode ("movc", "a", "@a+dptr");
+ emitcode ("movc", "a,@a+dptr");
break;
case GPOINTER:
{
emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE, TRUE));
emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE, TRUE));
- emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
+ if (options.model == MODEL_FLAT24)
+ emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
}
else
{
);
emitcode ("push", "%s", aopGet (AOP (left), 0, FALSE, TRUE, TRUE));
emitcode ("push", "%s", aopGet (AOP (left), 1, FALSE, TRUE, TRUE));
- emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
+ if (options.model == MODEL_FLAT24)
+ emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
emitcode ("pop", "dph");
emitcode ("pop", "dpl");
}
{
emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE, TRUE));
emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE, TRUE));
- emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
+ if (options.model == MODEL_FLAT24)
+ emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
}
else
{
);
emitcode ("push", "%s", aopGet (AOP (left), 0, FALSE, TRUE, TRUE));
emitcode ("push", "%s", aopGet (AOP (left), 1, FALSE, TRUE, TRUE));
- emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
+ if (options.model == MODEL_FLAT24)
+ emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
emitcode ("pop", "dph");
emitcode ("pop", "dpl");
}
genSetDPTR(0);
_flushLazyDPS();
emitcode ("mov", "dph,%s", l);
- l=aopGet(AOP(left),2,FALSE,FALSE,TRUE);
- genSetDPTR(0);
- _flushLazyDPS();
- emitcode ("mov", "dpx,%s", l);
- emitcode ("mov", "b,%s", aopGet (AOP(left),3,FALSE,FALSE,TRUE));
+ if (options.model == MODEL_FLAT24) {
+ l=aopGet(AOP(left),2,FALSE,FALSE,TRUE);
+ genSetDPTR(0);
+ _flushLazyDPS();
+ emitcode ("mov", "dpx,%s", l);
+ emitcode ("mov", "b,%s", aopGet (AOP(left),3,FALSE,FALSE,TRUE));
+ } else {
+ emitcode ("mov", "b,%s", aopGet (AOP(left),2,FALSE,FALSE,TRUE));
+ }
} else {
emitcode ("mov", "dpl,%s", aopGet (AOP(left),0,FALSE,FALSE,TRUE));
emitcode ("mov", "dph,%s", aopGet (AOP(left),1,FALSE,FALSE,TRUE));
- emitcode ("mov", "dpx,%s", aopGet (AOP(left),2,FALSE,FALSE,TRUE));
- emitcode ("mov", "b,%s", aopGet (AOP(left),3,FALSE,FALSE,TRUE));
+ if (options.model == MODEL_FLAT24) {
+ emitcode ("mov", "dpx,%s", aopGet (AOP(left),2,FALSE,FALSE,TRUE));
+ emitcode ("mov", "b,%s", aopGet (AOP(left),3,FALSE,FALSE,TRUE));
+ } else {
+ emitcode ("mov", "b,%s", aopGet (AOP(left),2,FALSE,FALSE,TRUE));
+ }
}
_endLazyDPSEvaluation ();
}
{
emitcode ("mov", "dpl,%s", aopGet (AOP (result), 0, FALSE, FALSE, TRUE));
emitcode ("mov", "dph,%s", aopGet (AOP (result), 1, FALSE, FALSE, TRUE));
- emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE));
+ if (options.model == MODEL_FLAT24)
+ emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE));
}
else
{
);
emitcode ("push", "%s", aopGet (AOP (result), 0, FALSE, TRUE, TRUE));
emitcode ("push", "%s", aopGet (AOP (result), 1, FALSE, TRUE, TRUE));
- emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE));
+ if (options.model == MODEL_FLAT24)
+ emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE));
emitcode ("pop", "dph");
emitcode ("pop", "dpl");
}
{ /* we need to get it byte by byte */
emitcode ("mov", "dpl,%s", aopGet (AOP (result), 0, FALSE, FALSE, TRUE));
emitcode ("mov", "dph,%s", aopGet (AOP (result), 1, FALSE, FALSE, TRUE));
- emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE));
- emitcode ("mov", "b,%s", aopGet (AOP (result), 3, FALSE, FALSE, TRUE));
+ if (options.model == MODEL_FLAT24) {
+ emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE));
+ emitcode ("mov", "b,%s", aopGet (AOP (result), 3, FALSE, FALSE, TRUE));
+ } else {
+ emitcode ("mov", "b,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE));
+ }
}
_endLazyDPSEvaluation ();
}
}
+/*-----------------------------------------------------------------*/
+/* genArrayInit - generates code for address of */
+/*-----------------------------------------------------------------*/
+static void
+genArrayInit (iCode * ic)
+{
+ literalList *iLoop;
+ int ix, count;
+ int elementSize = 0, eIndex;
+ unsigned val, lastVal;
+ sym_link *type;
+ operand *left=IC_LEFT(ic);
+
+ D (emitcode (";", "genArrayInit "););
+
+ aopOp (IC_LEFT(ic), ic, FALSE, FALSE);
+
+ if (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD)
+ {
+ // Load immediate value into DPTR.
+ emitcode("mov", "dptr, %s",
+ aopGet(AOP(IC_LEFT(ic)), 0, TRUE, FALSE, TRUE));
+ }
+ else if (AOP_TYPE(IC_LEFT(ic)) != AOP_DPTR)
+ {
+#if 0
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "Unexpected operand to genArrayInit.\n");
+ exit(1);
+#else
+ // a regression because of SDCCcse.c:1.52
+ emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE, TRUE));
+ emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE, TRUE));
+ if (options.model == MODEL_FLAT24)
+ emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
+#endif
+ }
+
+ type = operandType(IC_LEFT(ic));
+
+ if (type && type->next)
+ {
+ elementSize = getSize(type->next);
+ }
+ else
+ {
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "can't determine element size in genArrayInit.\n");
+ exit(1);
+ }
+
+ iLoop = IC_ARRAYILIST(ic);
+ lastVal = 0xffff;
+
+ while (iLoop)
+ {
+ bool firstpass = TRUE;
+
+ emitcode(";", "store %d x 0x%x to DPTR (element size %d)",
+ iLoop->count, (int)iLoop->literalValue, elementSize);
+
+ ix = iLoop->count;
+
+ while (ix)
+ {
+ symbol *tlbl = NULL;
+
+ count = ix > 256 ? 256 : ix;
+
+ if (count > 1)
+ {
+ tlbl = newiTempLabel (NULL);
+ if (firstpass || (count & 0xff))
+ {
+ emitcode("mov", "b, #0x%x", count & 0xff);
+ }
+
+ emitcode ("", "%05d$:", tlbl->key + 100);
+ }
+
+ firstpass = FALSE;
+
+ for (eIndex = 0; eIndex < elementSize; eIndex++)
+ {
+ val = (((int)iLoop->literalValue) >> (eIndex * 8)) & 0xff;
+ if (val != lastVal)
+ {
+ emitcode("mov", "a, #0x%x", val);
+ lastVal = val;
+ }
+
+ emitcode("movx", "@dptr, a");
+ emitcode("inc", "dptr");
+ }
+
+ if (count > 1)
+ {
+ emitcode("djnz", "b, %05d$", tlbl->key + 100);
+ }
+
+ ix -= count;
+ }
+
+ iLoop = iLoop->next;
+ }
+
+ freeAsmop (IC_LEFT(ic), NULL, ic, TRUE);
+}
+
/*-----------------------------------------------------------------*/
/* genFarFarAssign - assignment when both are in far space */
/*-----------------------------------------------------------------*/
{
/* We can use the '390 auto-toggle feature to good effect here. */
- D(emitcode(";","genFarFarAssign ('390 auto-toggle fun)"););
+ D(emitcode(";","genFarFarAssign (390 auto-toggle fun)"););
emitcode("mov", "dps, #0x21"); /* Select DPTR2 & auto-toggle. */
emitcode ("mov", "dptr,#%s", rSym->rname);
/* DP2 = result, DP1 = right, DP1 is current. */
}
emitcode("mov", "dps, #0");
freeAsmop (right, NULL, ic, FALSE);
+#if 0
+some alternative code for processors without auto-toggle
+no time to test now, so later well put in...kpb
+ D(emitcode(";","genFarFarAssign (dual-dptr fun)"););
+ emitcode("mov", "dps, #0x01"); /* Select DPTR2. */
+ emitcode ("mov", "dptr,#%s", rSym->rname);
+ /* DP2 = result, DP1 = right, DP1 is current. */
+ while (size)
+ {
+ --size;
+ emitcode("movx", "a,@dptr");
+ if (size)
+ emitcode("inc", "dptr");
+ emitcode("inc", "dps");
+ emitcode("movx", "@dptr,a");
+ if (size)
+ emitcode("inc", "dptr");
+ emitcode("inc", "dps");
+ }
+ emitcode("mov", "dps, #0");
+ freeAsmop (right, NULL, ic, FALSE);
+#endif
}
else
{
goto release;
/* if the result is a bit */
- if (AOP_TYPE (result) == AOP_CRY)
+ if (AOP_TYPE (result) == AOP_CRY) /* works only for true symbols */
{
-
/* if the right size is a literal then
we know what the value is */
if (AOP_TYPE (right) == AOP_LIT)
aopOp (result, ic, FALSE, AOP_TYPE (right) == AOP_DPTR);
/* if the result is a bit */
- if (AOP_TYPE (result) == AOP_CRY)
+ // if (AOP_TYPE (result) == AOP_CRY) /* works only for true symbols */
+ if (IS_BITVAR(OP_SYMBOL(result)->type))
{
/* if the right size is a literal then
we know what the value is */
lineHead = lineCurr = NULL;
+ if (options.model == MODEL_FLAT24) {
+ fReturnSizeDS390 = 5;
+ fReturn = fReturn24;
+ } else {
+ fReturnSizeDS390 = 4;
+ fReturn = fReturn16;
+ options.stack10bit=0;
+ }
#if 0
//REMOVE ME!!!
/* print the allocation information */
addSet (&_G.sendSet, ic);
break;
+ case ARRAYINIT:
+ genArrayInit(ic);
+ break;
+
default:
ic = ic;
}