Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
and - Jean-Louis VERN.jlvern@writeme.com (1999)
Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a)
+ DS390 adaptation by Kevin Vigor <kevin@vigor.nu>
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
#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
-#if !defined(__BORLANDC__) && !defined(_MSC_VER)
+#if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
#warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
#warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
#endif
#endif
#endif
+#endif
-// #define BETTER_LITERAL_SHIFT
+#define BETTER_LITERAL_SHIFT
char *aopLiteral (value * val, int offset);
#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"};
}
_G;
-static void saverbank (int, iCode *, bool);
+static void saveRBank (int, iCode *, bool);
#define RESULTONSTACK(x) \
(IC_RESULT(x) && IC_RESULT(x)->aop && \
emitcode (char *inst, char *fmt,...)
{
va_list ap;
- char lb[MAX_INLINEASM];
+ char lb[INITIAL_INLINEASM];
char *lbp = lb;
va_start (ap, fmt);
/* first check if r0 & r1 are used by this
instruction, in which case we are in trouble */
- if ((r0iu = bitVectBitValue (ic->rUsed, R0_IDX)) &&
- (r1iu = bitVectBitValue (ic->rUsed, R1_IDX)))
- {
+ r0iu = bitVectBitValue (ic->rUsed, R0_IDX);
+ r1iu = bitVectBitValue (ic->rUsed, R1_IDX);
+ if (r0iu && r1iu) {
goto endOfWorld;
}
}
else
{
+ TR_DPTR("#1");
emitcode ("mov", "dps, #0x01");
}
}
{
_currentDPS = 0;
_desiredDPS = 0;
+#ifdef BETTER_LITERAL_SHIFT
+ _lazyDPS++;
+#else
_lazyDPS = 1;
+#endif
}
/*-----------------------------------------------------------------*/
static void
_endLazyDPSEvaluation (void)
{
- if (_currentDPS)
+#ifdef BETTER_LITERAL_SHIFT
+ _lazyDPS--;
+#else
+ _lazyDPS = 0;
+#endif
+ if (!_lazyDPS)
+ {
+ if (_currentDPS)
{
genSetDPTR (0);
_flushLazyDPS ();
}
- _lazyDPS = 0;
- _currentDPS = 0;
- _desiredDPS = 0;
+ _currentDPS = 0;
+ _desiredDPS = 0;
+ }
}
if (_G.accInUse)
emitcode ("push", "acc");
- emitcode ("mov", "a,_bp");
- emitcode ("add", "a,#0x%02x",
- ((sym->stack < 0) ?
- ((char) (sym->stack - _G.nRegsSaved)) :
- ((char) sym->stack)) & 0xff);
-
- if (useDP2)
- {
- /* genSetDPTR(1); */
- emitcode ("mov", "dpx1,#0x40");
- emitcode ("mov", "dph1,#0x00");
- emitcode ("mov", "dpl1, a");
- /* genSetDPTR(0); */
- }
- else
- {
- emitcode ("mov", "dpx,#0x40");
- emitcode ("mov", "dph,#0x00");
- emitcode ("mov", "dpl, a");
- }
+ emitcode ("mov", "a,_bpx");
+ emitcode ("clr","c");
+ emitcode ("subb", "a,#0x%02x",
+ -((sym->stack < 0) ?
+ ((short) (sym->stack - _G.nRegsSaved)) :
+ ((short) sym->stack)) & 0xff);
+ emitcode ("mov","b,a");
+ emitcode ("mov","a,#0x%02x",(-((sym->stack < 0) ?
+ ((short) (sym->stack - _G.nRegsSaved)) :
+ ((short) sym->stack)) >> 8) & 0xff);
+ emitcode ("subb","a,_bpx+1");
+ if (useDP2) {
+ if (options.model == MODEL_FLAT24)
+ emitcode ("mov", "dpx1,#0x40");
+ TR_DPTR("#2");
+ emitcode ("mov", "dph1,a");
+ emitcode ("mov", "dpl1,b");
+ } else {
+ if (options.model == MODEL_FLAT24)
+ emitcode ("mov", "dpx,#0x40");
+ emitcode ("mov", "dph,a");
+ emitcode ("mov", "dpl,b");
+ }
if (_G.accInUse)
emitcode ("pop", "acc");
if (IS_FUNC (sym->type))
{
sym->aop = aop = newAsmop (AOP_IMMD);
- aop->aopu.aop_immd = Safe_calloc (1, strlen (sym->rname) + 1);
- strcpy (aop->aopu.aop_immd, sym->rname);
+ aop->aopu.aop_immd.aop_immd1 = Safe_calloc (1, strlen (sym->rname) + 1);
+ strcpy (aop->aopu.aop_immd.aop_immd1, sym->rname);
aop->size = FPTRSIZE;
return aop;
}
{
iCode *ic = sym->rematiCode;
asmop *aop = newAsmop (AOP_IMMD);
-
+ int ptr_type =0;
int val = 0;
for (;;)
val += (int) operandLitValue (IC_RIGHT (ic));
else if (ic->op == '-')
val -= (int) operandLitValue (IC_RIGHT (ic));
- else
- break;
-
+ 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;
+
ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
}
else
strcpy (buffer, OP_SYMBOL (IC_LEFT (ic))->rname);
- aop->aopu.aop_immd = Safe_calloc (1, strlen (buffer) + 1);
- strcpy (aop->aopu.aop_immd, buffer);
+ aop->aopu.aop_immd.aop_immd1 = Safe_calloc (1, strlen (buffer) + 1);
+ strcpy (aop->aopu.aop_immd.aop_immd1, 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);
+ }
+
return aop;
}
/* a AOP_STR uses DPTR, but DPTR is already in use;
* we're just hosed.
*/
- fprintf (stderr, "*** Internal error: AOP_STR with DPTR in use!\n");
+ fprintf (stderr, "*** Internal error: AOP_STR with DPTR in use! for operand %s\n",sym->name);
}
aop = op->aop = sym->aop = newAsmop (AOP_STR);
genSetDPTR (1);
if (!canClobberACC)
{
- emitcode ("xch", "a, %s", DP2_RESULT_REG);
+ 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;
}
return (dname ? "acc" : "a");
case AOP_IMMD:
- if (bit16)
- sprintf (s, "#%s", aop->aopu.aop_immd);
+ if (aop->aopu.aop_immd.from_cast_remat && (offset == (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 (offset)
sprintf (s, "#(%s >> %d)",
- aop->aopu.aop_immd,
+ aop->aopu.aop_immd.aop_immd1,
offset * 8);
else
sprintf (s, "#%s",
- aop->aopu.aop_immd);
+ aop->aopu.aop_immd.aop_immd1);
rs = Safe_calloc (1, strlen (s) + 1);
strcpy (rs, s);
return rs;
if (strcmp (s, "a") == 0)
emitcode ("push", "acc");
else
- emitcode ("push", "%s", s);
+ if (*s=='@') {
+ MOVA(s);
+ emitcode ("push", "acc");
+ } else {
+ emitcode ("push", s);
+ }
break;
/* if the registers have been saved already then
do nothing */
- if (ic->regsSaved || (OP_SYMBOL (IC_LEFT (ic))->calleeSave))
- return;
-
- /* find the registers in use at this time
- and push them away to safety */
- rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
- ic->rUsed);
-
+ if (ic->regsSaved || IFFUNC_ISNAKED(OP_SYM_TYPE(IC_LEFT(ic)))) return ;
+
+ /* special case if DPTR alive across a function call then must save it
+ even though callee saves */
+ if (IFFUNC_CALLEESAVES(OP_SYMBOL (IC_LEFT (ic))->type)) {
+ int i =0;
+ rsave = newBitVect(ic->rMask->size);
+ for (i = DPL_IDX ; i <= B_IDX ; i++ ) {
+ if (bitVectBitValue(ic->rMask,i))
+ rsave = bitVectSetBit(rsave,i);
+ }
+ } else {
+ /* find the registers in use at this time
+ and push them away to safety */
+ rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
+ ic->rUsed);
+ }
ic->regsSaved = 1;
if (options.useXstack)
{
for (i = 0; i < ds390_nRegs; i++)
{
if (bitVectBitValue (rsave, i))
- emitcode ("push", "%s ;jwk saveRegisters", ds390_regWithIdx (i)->dname);
+ emitcode ("push", "%s", ds390_regWithIdx (i)->dname);
}
detype = getSpec (operandType (IC_LEFT (ic)));
- if (detype &&
- (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype)) &&
- IS_ISR (currFunc->etype) &&
- !ic->bankSaved)
-
- saverbank (SPEC_BANK (detype), ic, TRUE);
-
}
+
/*-----------------------------------------------------------------*/
/* unsaveRegisters - pop the pushed registers */
/*-----------------------------------------------------------------*/
{
int i;
bitVect *rsave;
- /* find the registers in use at this time
- and push them away to safety */
- rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
- ic->rUsed);
+ if (IFFUNC_CALLEESAVES(OP_SYMBOL (IC_LEFT (ic))->type)) {
+ int i =0;
+ rsave = newBitVect(ic->rMask->size);
+ for (i = DPL_IDX ; i <= B_IDX ; i++ ) {
+ if (bitVectBitValue(ic->rMask,i))
+ rsave = bitVectSetBit(rsave,i);
+ }
+ } else {
+ /* find the registers in use at this time
+ and push them away to safety */
+ rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
+ ic->rUsed);
+ }
if (options.useXstack)
{
emitcode ("mov", "r0,%s", spname);
for (i = ds390_nRegs; i >= 0; i--)
{
if (bitVectBitValue (rsave, i))
- emitcode ("pop", "%s ;jwk unsaveRegisters", ds390_regWithIdx (i)->dname);
+ emitcode ("pop", "%s", ds390_regWithIdx (i)->dname);
}
}
MOVA (l);
l = "acc";
}
- emitcode ("push", "%s ;jwk genIpush: !parm", l);
+ emitcode ("push", "%s", l);
}
_endLazyDPSEvaluation ();
return;
emitcode ("push", "acc");
}
else
- emitcode ("push", "%s ;jwk genIpush", l);
+ emitcode ("push", "%s", l);
}
_endLazyDPSEvaluation ();
_startLazyDPSEvaluation ();
while (size--)
{
- emitcode ("pop", "%s ;jwk genIpop", aopGet (AOP (IC_LEFT (ic)), offset--,
+ emitcode ("pop", "%s", aopGet (AOP (IC_LEFT (ic)), offset--,
FALSE, TRUE, TRUE));
}
_endLazyDPSEvaluation ();
}
/*-----------------------------------------------------------------*/
-/* unsaverbank - restores the resgister bank from stack */
+/* unsaveRBank - restores the resgister bank from stack */
/*-----------------------------------------------------------------*/
static void
-unsaverbank (int bank, iCode * ic, bool popPsw)
+unsaveRBank (int bank, iCode * ic, bool popPsw)
{
int i;
- asmop *aop;
+ asmop *aop = NULL;
regs *r = NULL;
+ if (options.useXstack)
+ {
+ if (!ic)
+ {
+ /* Assume r0 is available for use. */
+ r = ds390_regWithIdx (R0_IDX);;
+ }
+ else
+ {
+ aop = newAsmop (0);
+ r = getFreePtr (ic, &aop, FALSE);
+ }
+ emitcode ("mov", "%s,_spx", r->name);
+ }
+
if (popPsw)
{
if (options.useXstack)
- {
- aop = newAsmop (0);
- r = getFreePtr (ic, &aop, FALSE);
-
-
- emitcode ("mov", "%s,_spx", r->name);
+ {
emitcode ("movx", "a,@%s", r->name);
emitcode ("mov", "psw,a");
emitcode ("dec", "%s", r->name);
-
}
else
+ {
emitcode ("pop", "psw");
+ }
}
for (i = (ds390_nRegs - 1); i >= 0; i--)
if (options.useXstack)
{
-
emitcode ("mov", "_spx,%s", r->name);
- freeAsmop (NULL, aop, ic, TRUE);
-
}
+
+ if (aop)
+ {
+ freeAsmop (NULL, aop, ic, TRUE);
+ }
}
/*-----------------------------------------------------------------*/
-/* saverbank - saves an entire register bank on the stack */
+/* saveRBank - saves an entire register bank on the stack */
/*-----------------------------------------------------------------*/
static void
-saverbank (int bank, iCode * ic, bool pushPsw)
+saveRBank (int bank, iCode * ic, bool pushPsw)
{
int i;
- asmop *aop;
+ asmop *aop = NULL;
regs *r = NULL;
if (options.useXstack)
{
-
- aop = newAsmop (0);
- r = getFreePtr (ic, &aop, FALSE);
- emitcode ("mov", "%s,_spx", r->name);
-
+ if (!ic)
+ {
+ /* Assume r0 is available for use. */
+ r = ds390_regWithIdx (R0_IDX);;
+ }
+ else
+ {
+ aop = newAsmop (0);
+ r = getFreePtr (ic, &aop, FALSE);
+ }
+ emitcode ("mov", "%s,_spx", r->name);
}
for (i = 0; i < ds390_nRegs; i++)
emitcode ("movx", "@%s,a", r->name);
emitcode ("inc", "%s", r->name);
emitcode ("mov", "_spx,%s", r->name);
- freeAsmop (NULL, aop, ic, TRUE);
-
}
else
+ {
emitcode ("push", "psw");
+ }
emitcode ("mov", "psw,#0x%02x", (bank << 3) & 0x00ff);
}
- ic->bankSaved = 1;
-
+
+ if (aop)
+ {
+ freeAsmop (NULL, aop, ic, TRUE);
+ }
+
+ if (ic)
+ {
+ ic->bankSaved = 1;
+ }
}
/*-----------------------------------------------------------------*/
static void
genCall (iCode * ic)
{
- sym_link *detype;
-
- D (emitcode (";", "genCall ");
- );
+ sym_link *dtype;
+ bool restoreBank = FALSE;
+ bool swapBanks = FALSE;
- /* if caller saves & we have not saved then */
- if (!ic->regsSaved)
- saveRegisters (ic);
+ D (emitcode (";", "genCall "););
- /* if we are calling a function that is not using
+ /* 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_BANK (currFunc->etype) != SPEC_BANK (detype)) &&
- IS_ISR (currFunc->etype) &&
- !ic->bankSaved)
-
- saverbank (SPEC_BANK (detype), ic, TRUE);
-
+ 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 (FUNC_REGBANK (dtype), ic, FALSE);
+ restoreBank = TRUE;
+ }
+ swapBanks = TRUE;
+ }
+
+ /* if caller saves & we have not saved then */
+ if (!ic->regsSaved)
+ saveRegisters (ic);
+
/* if send set is not empty the assign */
+ /* We've saved all the registers we care about;
+ * therefore, we may clobber any register not used
+ * in the calling convention (i.e. anything not in
+ * fReturn.
+ */
if (_G.sendSet)
{
iCode *sic;
{
int size, offset = 0;
- aopOp (IC_LEFT (sic), sic, FALSE, TRUE);
+#if 0
+ aopOp (IC_LEFT (sic), sic, FALSE, FALSE);
size = AOP_SIZE (IC_LEFT (sic));
_startLazyDPSEvaluation ();
while (size--)
{
- char *l = aopGet (AOP (IC_LEFT (sic)), offset,
+ char *l = aopGet (AOP(IC_LEFT(sic)), offset,
FALSE, FALSE, TRUE);
- if (strcmp (l, fReturn[offset])) {
- genSetDPTR(0);
- _flushLazyDPS();
- emitcode ("mov", "%s,%s ;jwk lazy genCall",
- fReturn[offset],
- l);
+ if ((AOP_TYPE(IC_LEFT(sic)) == AOP_DPTR) && size)
+ {
+ emitcode("mov", "%s,%s", regs390[offset].name, l);
+ }
+ else if (strcmp (l, fReturn[offset]))
+ {
+ emitcode ("mov", "%s,%s",
+ fReturn[offset],
+ l);
+ }
+ offset++;
+ }
+ _endLazyDPSEvaluation ();
+ if (AOP_TYPE(IC_LEFT(sic)) == AOP_DPTR)
+ {
+ size = AOP_SIZE (IC_LEFT (sic));
+ if (size)
+ {
+ size--;
+ }
+ while (size)
+ {
+ size--;
+ emitcode("mov", "%s,%s",
+ fReturn[size], regs390[size].name);
}
+ }
+#else
+ // we know that dpl(hxb) is the result, so
+ _startLazyDPSEvaluation ();
+ size=getSize(operandType(IC_LEFT(sic)));
+ if (size>1) {
+ aopOp (IC_LEFT (sic), sic, FALSE, TRUE);
+ } else {
+ aopOp (IC_LEFT (sic), sic, FALSE, FALSE);
+ }
+ while (size--)
+ {
+ char *l = aopGet (AOP (IC_LEFT (sic)), offset,
+ FALSE, FALSE, TRUE);
+ if (strcmp (l, fReturn[offset]))
+ {
+ emitcode ("mov", "%s,%s",
+ fReturn[offset],
+ l);
+ }
offset++;
}
_endLazyDPSEvaluation ();
+#endif
freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
}
_G.sendSet = NULL;
- }
+ }
+
+ if (swapBanks)
+ {
+ emitcode ("mov", "psw,#0x%02x",
+ ((FUNC_REGBANK(dtype)) << 3) & 0xff);
+ }
+
/* make the call */
emitcode ("lcall", "%s", (OP_SYMBOL (IC_LEFT (ic))->rname[0] ?
OP_SYMBOL (IC_LEFT (ic))->rname :
OP_SYMBOL (IC_LEFT (ic))->name));
+ if (swapBanks)
+ {
+ emitcode ("mov", "psw,#0x%02x",
+ ((FUNC_REGBANK(currFunc->type)) << 3) & 0xff);
+ }
+
/* 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)) ||
IS_TRUE_SYMOP (IC_RESULT (ic)))
{
int size = getSize (operandType (IC_RESULT (ic)));
/* Special case for 1 or 2 byte return in far space. */
- emitcode (";", "Kevin function call abuse #1");
-
MOVA (fReturn[0]);
if (size > 1)
{
/* adjust the stack for parameters if
required */
- if (ic->parmBytes)
- {
- int i;
- if (ic->parmBytes > 3)
- {
- emitcode ("mov", "a,%s", spname);
- emitcode ("add", "a,#0x%02x", (-ic->parmBytes) & 0xff);
- emitcode ("mov", "%s,a", spname);
- }
- else
- for (i = 0; i < ic->parmBytes; i++)
- emitcode ("dec", "%s", spname);
-
- }
-
- /* if register bank was saved then pop them */
- if (ic->bankSaved)
- unsaverbank (SPEC_BANK (detype), ic, TRUE);
+ if (ic->parmBytes) {
+ if (options.stack10bit) {
+ emitcode ("clr","c");
+ emitcode ("mov","a,sp");
+ emitcode ("subb","a,#0x%02x",ic->parmBytes & 0xff);
+ emitcode ("mov","sp,a");
+ emitcode ("mov","a,#0x%02x",(ic->parmBytes >> 8) & 0xff);
+ emitcode ("subb","a,esp");
+ emitcode ("mov","esp,a");
+ } else {
+ int i;
+ if (ic->parmBytes > 3) {
+ emitcode ("mov", "a,%s", spname);
+ emitcode ("add", "a,#0x%02x", (-ic->parmBytes) & 0xff);
+ emitcode ("mov", "%s,a", spname);
+ } else
+ for (i = 0; i < ic->parmBytes; i++)
+ emitcode ("dec", "%s", spname);
+ }
+ }
/* if we hade saved some registers then unsave them */
- if (ic->regsSaved && !(OP_SYMBOL (IC_LEFT (ic))->calleeSave))
+ if (ic->regsSaved)
unsaveRegisters (ic);
-
+ /* if register bank was saved then pop them */
+ if (restoreBank)
+ unsaveRBank (FUNC_REGBANK (dtype), ic, FALSE);
}
/*-----------------------------------------------------------------*/
static void
genPcall (iCode * ic)
{
- sym_link *detype;
+ sym_link *dtype;
symbol *rlbl = newiTempLabel (NULL);
+ bool restoreBank=FALSE;
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_ISNAKED(dtype) &&
+ IFFUNC_ISISR (currFunc->type) &&
+ (FUNC_REGBANK (currFunc->type) != FUNC_REGBANK (dtype))) {
+ saveRBank (FUNC_REGBANK (dtype), ic, TRUE);
+ restoreBank=TRUE;
+ }
/* push the return address on to the stack */
emitcode ("mov", "a,#%05d$", (rlbl->key + 100));
{
int size, offset = 0;
- aopOp (IC_LEFT (sic), sic, FALSE, FALSE);
- size = AOP_SIZE (IC_LEFT (sic));
+ // we know that dpl(hxb) is the result, so
_startLazyDPSEvaluation ();
+ size=getSize(operandType(IC_LEFT(sic)));
+ if (size>1) {
+ aopOp (IC_LEFT (sic), sic, FALSE, TRUE);
+ } else {
+ aopOp (IC_LEFT (sic), sic, FALSE, FALSE);
+ }
while (size--)
{
char *l = aopGet (AOP (IC_LEFT (sic)), offset,
}
/* if register bank was saved then unsave them */
- if (detype &&
- (SPEC_BANK (currFunc->etype) !=
- SPEC_BANK (detype)))
- unsaverbank (SPEC_BANK (detype), ic, TRUE);
-
+ if (restoreBank)
+ unsaveRBank (FUNC_REGBANK (dtype), ic, TRUE);
+
/* if we hade saved some registers then
unsave them */
if (ic->regsSaved)
genFunction (iCode * ic)
{
symbol *sym;
- sym_link *fetype;
+ sym_link *ftype;
+ bool switchedPSW = FALSE;
- D (emitcode (";", "genFunction ");
- );
+ D (emitcode (";", "genFunction "););
_G.nRegsSaved = 0;
/* create the function header */
emitcode (";", "-----------------------------------------");
emitcode ("", "%s:", sym->rname);
- fetype = getSpec (operandType (IC_LEFT (ic)));
+ ftype = operandType (IC_LEFT (ic));
+
+ 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)
- emitcode ("", "%s = 0x%02x",
- regs390[i].dname,
- 8 * rbank + regs390[i].offset);
- else
- emitcode ("", "%s = %s + 0x%02x",
- regs390[i].dname,
- regs390[i].base,
- 8 * rbank + regs390[i].offset);
+ if (regs390[i].print) {
+ if (strcmp (regs390[i].base, "0") == 0)
+ emitcode ("", "%s = 0x%02x",
+ regs390[i].dname,
+ 8 * rbank + regs390[i].offset);
+ else
+ emitcode ("", "%s = %s + 0x%02x",
+ regs390[i].dname,
+ regs390[i].base,
+ 8 * rbank + regs390[i].offset);
+ }
}
}
/* 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;
else
{
/* this function has a function call cannot
- determines register usage so we will have the
+ determines register usage so we will have to push the
entire bank */
- saverbank (0, ic, FALSE);
+ saveRBank (0, ic, FALSE);
+ }
+ }
+ else
+ {
+ /* This ISR uses a non-zero bank.
+ *
+ * We assume that the bank is available for our
+ * exclusive use.
+ *
+ * However, if this ISR calls a function which uses some
+ * other bank, we must save that bank entirely.
+ */
+ unsigned long banksToSave = 0;
+
+ if (IFFUNC_HASFCALL(sym->type))
+ {
+
+#define MAX_REGISTER_BANKS 4
+
+ iCode *i;
+ int ix;
+
+ for (i = ic; i; i = i->next)
+ {
+ if (i->op == ENDFUNCTION)
+ {
+ /* we got to the end OK. */
+ break;
+ }
+
+ if (i->op == CALL)
+ {
+ sym_link *dtype;
+
+ dtype = operandType (IC_LEFT(i));
+ if (dtype
+ && FUNC_REGBANK(dtype) != FUNC_REGBANK(sym->type))
+ {
+ /* Mark this bank for saving. */
+ if (FUNC_REGBANK(dtype) >= MAX_REGISTER_BANKS)
+ {
+ werror(E_NO_SUCH_BANK, FUNC_REGBANK(dtype));
+ }
+ else
+ {
+ banksToSave |= (1 << FUNC_REGBANK(dtype));
+ }
+
+ /* And note that we don't need to do it in
+ * genCall.
+ */
+ i->bankSaved = 1;
+ }
+ }
+ if (i->op == PCALL)
+ {
+ /* This is a mess; we have no idea what
+ * register bank the called function might
+ * use.
+ *
+ * The only thing I can think of to do is
+ * throw a warning and hope.
+ */
+ werror(W_FUNCPTR_IN_USING_ISR);
+ }
+ }
+
+ if (banksToSave && options.useXstack)
+ {
+ /* Since we aren't passing it an ic,
+ * saveRBank will assume r0 is available to abuse.
+ *
+ * So switch to our (trashable) bank now, so
+ * the caller's R0 isn't trashed.
+ */
+ emitcode ("push", "psw");
+ emitcode ("mov", "psw,#0x%02x",
+ (FUNC_REGBANK (sym->type) << 3) & 0x00ff);
+ switchedPSW = TRUE;
+ }
+
+ for (ix = 0; ix < MAX_REGISTER_BANKS; ix++)
+ {
+ if (banksToSave & (1 << ix))
+ {
+ saveRBank(ix, NULL, FALSE);
+ }
+ }
}
+ // jwk: this needs a closer look
+ SPEC_ISR_SAVED_BANKS(currFunc->etype) = banksToSave;
}
}
else
{
/* 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);
- }
-
- if (IS_RENT (sym->etype) || options.stackAuto)
- {
-
- if (options.useXstack)
- {
- emitcode ("mov", "r0,%s", spname);
- emitcode ("mov", "a,_bp");
- emitcode ("movx", "@r0,a");
- emitcode ("inc", "%s", spname);
- }
- else
- {
- /* set up the stack */
- emitcode ("push", "_bp"); /* save the callers stack */
- }
- emitcode ("mov", "_bp,%s", spname);
- }
+ emitcode ("mov", "psw,#0x%02x", (FUNC_REGBANK (sym->type) << 3) & 0x00ff);
+ }
+
+ if (IFFUNC_ISREENT (sym->type) || options.stackAuto) {
+ if (options.stack10bit) {
+ emitcode ("push","_bpx");
+ emitcode ("push","_bpx+1");
+ emitcode ("mov","_bpx,%s",spname);
+ emitcode ("mov","_bpx+1,esp");
+ emitcode ("anl","_bpx+1,#3");
+ } else {
+ if (options.useXstack) {
+ emitcode ("mov", "r0,%s", spname);
+ emitcode ("mov", "a,_bp");
+ emitcode ("movx", "@r0,a");
+ emitcode ("inc", "%s", spname);
+ } else {
+ /* set up the stack */
+ emitcode ("push", "_bp"); /* save the callers stack */
+ }
+ emitcode ("mov", "_bp,%s", spname);
+ }
+ }
/* adjust the stack for the function */
- if (sym->stack)
- {
-
+ if (sym->stack) {
int i = sym->stack;
- if (i > 256)
- werror (W_STACK_OVERFLOW, sym->name);
-
- if (i > 3 && sym->recvSize < 4)
- {
-
- emitcode ("mov", "a,sp");
- emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff));
- emitcode ("mov", "sp,a");
-
- }
- else
- while (i--)
- emitcode ("inc", "sp");
- }
+ if (options.stack10bit) {
+ if ( i > 1024) werror (W_STACK_OVERFLOW, sym->name);
+ assert (sym->recvSize <= 4);
+ emitcode ("mov","a,sp");
+ emitcode ("add","a,#0x%02x", ((short) sym->stack & 0xff));
+ emitcode ("mov","sp,a");
+ emitcode ("mov","a,esp");
+ emitcode ("addc","a,0x%02x", (((short) sym->stack) >> 8) & 0xff);
+ emitcode ("mov","esp,a");
+ } else {
+ if (i > 256)
+ werror (W_STACK_OVERFLOW, sym->name);
+
+ if (i > 3 && sym->recvSize < 4) {
+
+ emitcode ("mov", "a,sp");
+ emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff));
+ emitcode ("mov", "sp,a");
+
+ } else
+ while (i--)
+ emitcode ("inc", "sp");
+ }
+ }
if (sym->xstack)
{
{
symbol *sym = OP_SYMBOL (IC_LEFT (ic));
- D (emitcode (";", "genEndFunction ");
- );
+ D (emitcode (";", "genEndFunction "););
- if (IS_RENT (sym->etype) || options.stackAuto)
- {
- emitcode ("mov", "%s,_bp", spname);
- }
+ if (IFFUNC_ISNAKED(sym->type))
+ {
+ emitcode(";", "naked function: no epilogue.");
+ return;
+ }
+
+ if (IFFUNC_ISREENT (sym->type) || options.stackAuto) {
+ if (options.stack10bit) {
+ emitcode ("mov", "sp,_bpx", spname);
+ emitcode ("mov", "esp,_bpx+1", spname);
+ } else {
+ emitcode ("mov", "%s,_bp", spname);
+ }
+ }
/* if use external stack but some variables were
added to the local stack then decrement the
local stack */
- if (options.useXstack && sym->stack)
- {
+ if (options.useXstack && sym->stack) {
emitcode ("mov", "a,sp");
emitcode ("add", "a,#0x%02x", ((char) -sym->stack) & 0xff);
emitcode ("mov", "sp,a");
- }
+ }
- if ((IS_RENT (sym->etype) || options.stackAuto))
- {
- if (options.useXstack)
- {
+ if ((IFFUNC_ISREENT (sym->type) || options.stackAuto)) {
+ if (options.useXstack) {
emitcode ("mov", "r0,%s", spname);
emitcode ("movx", "a,@r0");
emitcode ("mov", "_bp,a");
emitcode ("dec", "%s", spname);
- }
- else
- {
- emitcode ("pop", "_bp");
- }
- }
+ } else {
+ if (options.stack10bit) {
+ emitcode ("pop", "_bpx+1");
+ emitcode ("pop", "_bpx");
+ } else {
+ emitcode ("pop", "_bp");
+ }
+ }
+ }
/* restore the register bank */
- if (SPEC_BANK (sym->etype) || IS_ISR (sym->etype))
- emitcode ("pop", "psw");
+ if (FUNC_REGBANK (sym->type) || IFFUNC_ISISR (sym->type))
+ {
+ if (!FUNC_REGBANK (sym->type) || !IFFUNC_ISISR (sym->type)
+ || !options.useXstack)
+ {
+ /* Special case of ISR using non-zero bank with useXstack
+ * is handled below.
+ */
+ emitcode ("pop", "psw");
+ }
+ }
- 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;
else
{
/* this function has a function call cannot
- determines register usage so we will have the
+ determines register usage so we will have to pop the
entire bank */
- unsaverbank (0, ic, FALSE);
+ unsaveRBank (0, ic, FALSE);
+ }
+ }
+ else
+ {
+ /* This ISR uses a non-zero bank.
+ *
+ * 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;
+
+ for (ix = MAX_REGISTER_BANKS - 1; ix >= 0; ix--)
+ {
+ if (savedBanks & (1 << ix))
+ {
+ unsaveRBank(ix, NULL, FALSE);
+ }
+ }
+
+ if (options.useXstack)
+ {
+ /* Restore bank AFTER calling unsaveRBank,
+ * since it can trash r0.
+ */
+ emitcode ("pop", "psw");
}
}
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 */
-/* if (options.debug && currFunc) { */
- if (currFunc)
- {
+ if (options.debug && currFunc) {
_G.debugLine = 1;
emitcode ("", "C$%s$%d$%d$%d ==.",
FileBaseName (ic->filename), currFunc->lastLine,
}
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 debug then send end of function */
- if (currFunc)
+ if (options.debug && currFunc)
{
_G.debugLine = 1;
emitcode ("", "C$%s$%d$%d$%d ==.",
/* we have something to return then
move the return value into place */
- aopOp (IC_LEFT (ic), ic, FALSE, TRUE);
+ aopOp (IC_LEFT (ic), ic, FALSE,
+ (IS_SYMOP(IC_LEFT(ic)) && OP_SYMBOL(IC_LEFT(ic))->ruonly ? FALSE :TRUE));
size = AOP_SIZE (IC_LEFT (ic));
_startLazyDPSEvaluation ();
}
else
{
+ /* Since A is the last element of fReturn,
+ * is is OK to clobber it in the aopGet.
+ */
l = aopGet (AOP (IC_LEFT (ic)), offset,
- FALSE, FALSE, FALSE);
+ FALSE, FALSE, TRUE);
if (strcmp (fReturn[offset], l))
emitcode ("mov", "%s,%s", fReturn[offset++], l);
}
}
}
+#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
// that the IC_RESULT operand is not aopOp'd.
#define AOP_OP_3_NOFATAL(ic, rc) \
aopOp (IC_RIGHT(ic),ic,FALSE, FALSE); \
- aopOp (IC_LEFT(ic),ic,FALSE, (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR)); \
+ aopOp (IC_LEFT(ic),ic,FALSE, (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR) || \
+ (OP_SYMBOL(IC_RESULT(ic))->ruonly)); \
if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR2 && \
- isOperandInFarSpace(IC_RESULT(ic))) \
+ (isOperandInFarSpace(IC_RESULT(ic)) || OP_SYMBOL(IC_RESULT(ic))->ruonly )) \
{ \
/* No can do; DPTR & DPTR2 in use, and we need another. */ \
rc = TRUE; \
D (emitcode (";", "genPlus "););
/* special cases :- */
-
+ if (isOperandEqual(IC_LEFT(ic),IC_RESULT(ic)) &&
+ isOperandLiteral(IC_RIGHT(ic)) && OP_SYMBOL(IC_RESULT(ic))->ruonly) {
+ aopOp (IC_RIGHT (ic), ic, TRUE, FALSE);
+ size = floatFromVal (AOP (IC_RIGHT(ic))->aopu.aop_lit);
+ if (size <= 9) {
+ while (size--) emitcode ("inc","dptr");
+ } else {
+ emitcode ("mov","a,dpl");
+ emitcode ("add","a,#0x%02x",size & 0xff);
+ emitcode ("mov","dpl,a");
+ emitcode ("mov","a,dph");
+ emitcode ("addc","a,#0x%02x",(size >> 8) & 0xff);
+ emitcode ("mov","dph,a");
+ emitcode ("mov","a,dpx");
+ emitcode ("addc","a,#0x%02x",(size >> 16) & 0xff);
+ emitcode ("mov","dpx,a");
+ }
+ freeAsmop (IC_RIGHT (ic), NULL, ic, FALSE);
+ return ;
+ }
+ if ( IS_SYMOP(IC_LEFT(ic)) &&
+ OP_SYMBOL(IC_LEFT(ic))->remat &&
+ isOperandInFarSpace(IC_RIGHT(ic))) {
+ operand *op = IC_RIGHT(ic);
+ IC_RIGHT(ic) = IC_LEFT(ic);
+ IC_LEFT(ic) = op;
+ }
+
AOP_OP_3_NOFATAL (ic, pushResult);
if (pushResult)
{
_startLazyDPSEvaluation ();
while (size--)
{
- if (AOP_TYPE (IC_LEFT (ic)) == AOP_ACC)
+ if (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC && !AOP_NEEDSACC(IC_RIGHT(ic)))
{
MOVA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE, TRUE));
if (offset == 0)
}
else
{
+ if (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC && (offset == 0))
+ {
+ /* right is going to use ACC or we would have taken the
+ * above branch.
+ */
+ assert(AOP_NEEDSACC(IC_RIGHT(ic)));
+ TR_AP("#3");
+ D(emitcode(";", "+ AOP_ACC special case."););
+ emitcode("xch", "a, %s", DP2_RESULT_REG);
+ }
MOVA (aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE, TRUE));
if (offset == 0)
- emitcode ("add", "a,%s",
- aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE, FALSE));
+ {
+ if (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC)
+ {
+ TR_AP("#4");
+ emitcode("add", "a, %s", DP2_RESULT_REG);
+ }
+ else
+ {
+ emitcode ("add", "a,%s",
+ aopGet (AOP(IC_LEFT(ic)), offset, FALSE, FALSE, FALSE));
+ }
+ }
else
+ {
emitcode ("addc", "a,%s",
aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE, FALSE));
+ }
}
if (!pushResult)
{
int size = (getDataSize (result) - offset);
if (size > 0)
{
+ _startLazyDPSEvaluation();
if (sign)
{
emitcode ("rlc", "a");
emitcode ("subb", "a,acc");
while (size--)
+ {
aopPut (AOP (result), "a", offset++);
+ }
}
else
+ {
while (size--)
+ {
aopPut (AOP (result), zero, offset++);
+ }
+ }
+ _endLazyDPSEvaluation();
}
}
{
symbol *lbl = newiTempLabel (NULL);
- D (emitcode (";", "genMinusBits ");
- );
+ D (emitcode (";", "genMinusBits "););
if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY)
{
else
{
/* first add without previous c */
- if (!offset)
- emitcode ("add", "a,#0x%02x",
- (unsigned int) (lit & 0x0FFL));
- else
+ if (!offset) {
+ if (!size && lit==-1) {
+ emitcode ("dec", "a");
+ } else {
+ emitcode ("add", "a,#0x%02x",
+ (unsigned int) (lit & 0x0FFL));
+ }
+ } else {
emitcode ("addc", "a,#0x%02x",
(unsigned int) ((lit >> (offset * 8)) & 0x0FFL));
+ }
}
if (pushResult)
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);
- emitcode (";",__FUNCTION__);
- if (size<1 || size>2) {
- // this should never happen
- fprintf (stderr, "size!=1||2 (%d) in %s at line:%d \n",
- AOP_SIZE(result), __FUNCTION__, 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 (";", "signed");
emitcode ("clr", "F0"); // reset sign flag
- emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE, TRUE));
MOVA (aopGet (AOP (left), 0, FALSE, FALSE, TRUE));
lbl=newiTempLabel(NULL);
emitcode ("inc", "a");
emitcode ("", "%05d$:", lbl->key+100);
- emitcode ("xch", "a,b");
/* if literal */
if (AOP_TYPE(right)==AOP_LIT) {
+ signed char val=floatFromVal (AOP (right)->aopu.aop_lit);
/* AND literal negative */
- if ((int) floatFromVal (AOP (right)->aopu.aop_lit) < 0) {
- // two's complement for literal<0
- emitcode ("xrl", "PSW,#0x20"); // xrl sign flag
- emitcode ("cpl", "a");
- emitcode ("inc", "a");
+ if ((int) val < 0) {
+ emitcode ("cpl", "F0"); // complement sign flag
+ emitcode ("mov", "b,#0x%02x", -val);
+ } else {
+ emitcode ("mov", "b,#0x%02x", val);
}
} else {
lbl=newiTempLabel(NULL);
+ emitcode ("mov", "b,a");
+ emitcode ("mov", "a,%s", aopGet (AOP (right), 0, FALSE, FALSE, TRUE));
emitcode ("jnb", "acc.7,%05d$", lbl->key+100);
// right side is negative, 8-bit two's complement
- emitcode ("xrl", "PSW,#0x20"); // xrl sign flag
+ emitcode ("cpl", "F0"); // complement sign flag
emitcode ("cpl", "a");
emitcode ("inc", "a");
emitcode ("", "%05d$:", lbl->key+100);
}
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);
}
}
+/*-----------------------------------------------------------------*/
+/* genMultTwoByte - use the DS390 MAC unit to do 16*16 multiply */
+/*-----------------------------------------------------------------*/
+static void genMultTwoByte (operand *left, operand *right,
+ operand *result, iCode *ic)
+{
+ sym_link *retype = getSpec(operandType(right));
+ sym_link *letype = getSpec(operandType(left));
+ int umult = SPEC_USIGN(retype) | SPEC_USIGN(letype);
+ symbol *lbl;
+
+ if (AOP_TYPE (left) == AOP_LIT) {
+ operand *t = right;
+ right = left;
+ left = t;
+ }
+ /* save EA bit in F1 */
+ lbl = newiTempLabel(NULL);
+ emitcode ("setb","F1");
+ emitcode ("jbc","EA,%05d$",lbl->key+100);
+ emitcode ("clr","F1");
+ emitcode("","%05d$:",lbl->key+100);
+
+ /* load up MB with right */
+ if (!umult) {
+ emitcode("clr","F0");
+ if (AOP_TYPE(right) == AOP_LIT) {
+ int val=floatFromVal (AOP (right)->aopu.aop_lit);
+ if (val < 0) {
+ emitcode("setb","F0");
+ val = -val;
+ }
+ emitcode ("mov","mb,#0x%02x",val & 0xff);
+ emitcode ("mov","mb,#0x%02x",(val >> 8) & 0xff);
+ } else {
+ lbl = newiTempLabel(NULL);
+ emitcode ("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE,TRUE));
+ emitcode ("mov","a,%s",aopGet(AOP(right),1,FALSE,FALSE,TRUE));
+ emitcode ("jnb","acc.7,%05d$",lbl->key+100);
+ emitcode ("xch", "a,b");
+ emitcode ("cpl","a");
+ emitcode ("add", "a,#1");
+ emitcode ("xch", "a,b");
+ emitcode ("cpl", "a"); // msb
+ emitcode ("addc", "a,#0");
+ emitcode ("setb","F0");
+ emitcode ("","%05d$:",lbl->key+100);
+ emitcode ("mov","mb,b");
+ emitcode ("mov","mb,a");
+ }
+ } else {
+ emitcode ("mov","mb,%s",aopGet(AOP(right),0,FALSE,FALSE,TRUE));
+ emitcode ("mov","mb,%s",aopGet(AOP(right),1,FALSE,FALSE,TRUE));
+ }
+ /* load up MA with left */
+ if (!umult) {
+ lbl = newiTempLabel(NULL);
+ emitcode ("mov","b,%s",aopGet(AOP(left),0,FALSE,FALSE,TRUE));
+ emitcode ("mov","a,%s",aopGet(AOP(left),1,FALSE,FALSE,TRUE));
+ emitcode ("jnb","acc.7,%05d$",lbl->key+100);
+ emitcode ("xch", "a,b");
+ emitcode ("cpl","a");
+ emitcode ("add", "a,#1");
+ emitcode ("xch", "a,b");
+ emitcode ("cpl", "a"); // msb
+ emitcode ("addc","a,#0");
+ emitcode ("jbc","F0,%05d$",lbl->key+100);
+ emitcode ("setb","F0");
+ emitcode ("","%05d$:",lbl->key+100);
+ emitcode ("mov","ma,b");
+ emitcode ("mov","ma,a");
+ } else {
+ emitcode ("mov","ma,%s",aopGet(AOP(left),0,FALSE,FALSE,TRUE));
+ emitcode ("mov","ma,%s",aopGet(AOP(left),1,FALSE,FALSE,TRUE));
+ }
+ /* wait for multiplication to finish */
+ lbl = newiTempLabel(NULL);
+ emitcode("","%05d$:", lbl->key+100);
+ emitcode("mov","a,mcnt1");
+ emitcode("anl","a,#0x80");
+ emitcode("jnz","%05d$",lbl->key+100);
+
+ freeAsmop (left, NULL, ic, TRUE);
+ freeAsmop (right, NULL, ic,TRUE);
+ aopOp(result, ic, TRUE, FALSE);
+
+ /* if unsigned then simple */
+ if (umult) {
+ emitcode ("mov","a,ma");
+ if (AOP_SIZE(result) >= 4) aopPut(AOP(result),"a",3);
+ emitcode ("mov","a,ma");
+ if (AOP_SIZE(result) >= 3) aopPut(AOP(result),"a",2);
+ aopPut(AOP(result),"ma",1);
+ aopPut(AOP(result),"ma",0);
+ } else {
+ emitcode("push","ma");
+ emitcode("push","ma");
+ emitcode("push","ma");
+ MOVA("ma");
+ /* negate result if needed */
+ lbl = newiTempLabel(NULL);
+ emitcode("jnb","F0,%05d$",lbl->key+100);
+ emitcode("cpl","a");
+ emitcode("add","a,#1");
+ emitcode("","%05d$:", lbl->key+100);
+ if (AOP_TYPE(result) == AOP_ACC)
+ {
+ D(emitcode(";", "ACC special case."););
+ /* We know result is the only live aop, and
+ * it's obviously not a DPTR2, so AP is available.
+ */
+ emitcode("mov", "%s,acc", DP2_RESULT_REG);
+ }
+ else
+ {
+ aopPut(AOP(result),"a",0);
+ }
+
+ emitcode("pop","acc");
+ lbl = newiTempLabel(NULL);
+ emitcode("jnb","F0,%05d$",lbl->key+100);
+ emitcode("cpl","a");
+ emitcode("addc","a,#0");
+ emitcode("","%05d$:", lbl->key+100);
+ aopPut(AOP(result),"a",1);
+ emitcode("pop","acc");
+ if (AOP_SIZE(result) >= 3) {
+ lbl = newiTempLabel(NULL);
+ emitcode("jnb","F0,%05d$",lbl->key+100);
+ emitcode("cpl","a");
+ emitcode("addc","a,#0");
+ emitcode("","%05d$:", lbl->key+100);
+ aopPut(AOP(result),"a",2);
+ }
+ emitcode("pop","acc");
+ if (AOP_SIZE(result) >= 4) {
+ lbl = newiTempLabel(NULL);
+ emitcode("jnb","F0,%05d$",lbl->key+100);
+ emitcode("cpl","a");
+ emitcode("addc","a,#0");
+ emitcode("","%05d$:", lbl->key+100);
+ aopPut(AOP(result),"a",3);
+ }
+ if (AOP_TYPE(result) == AOP_ACC)
+ {
+ /* We stashed the result away above. */
+ emitcode("mov", "acc,%s", DP2_RESULT_REG);
+ }
+
+ }
+ freeAsmop (result, NULL, ic, TRUE);
+
+ /* restore EA bit in F1 */
+ lbl = newiTempLabel(NULL);
+ emitcode ("jnb","F1,%05d$",lbl->key+100);
+ emitcode ("setb","EA");
+ emitcode("","%05d$:",lbl->key+100);
+ return ;
+}
+
/*-----------------------------------------------------------------*/
/* genMult - generates code for multiplication */
/*-----------------------------------------------------------------*/
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;
}
+ if (AOP_SIZE (left) == 2 && AOP_SIZE(right) == 2) {
+ /* use the ds390 ARITHMETIC accel UNIT */
+ genMultTwoByte (left, right, result, ic);
+ return ;
+ }
/* 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--;
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genDivTwoByte - use the DS390 MAC unit to do 16/16 divide */
+/*-----------------------------------------------------------------*/
+static void genDivTwoByte (operand *left, operand *right,
+ operand *result, iCode *ic)
+{
+ sym_link *retype = getSpec(operandType(right));
+ sym_link *letype = getSpec(operandType(left));
+ int umult = SPEC_USIGN(retype) | SPEC_USIGN(letype);
+ symbol *lbl;
+
+ /* save EA bit in F1 */
+ lbl = newiTempLabel(NULL);
+ emitcode ("setb","F1");
+ emitcode ("jbc","EA,%05d$",lbl->key+100);
+ emitcode ("clr","F1");
+ emitcode("","%05d$:",lbl->key+100);
+
+ /* load up MA with left */
+ if (!umult) {
+ emitcode("clr","F0");
+ lbl = newiTempLabel(NULL);
+ emitcode ("mov","b,%s",aopGet(AOP(left),0,FALSE,FALSE,TRUE));
+ emitcode ("mov","a,%s",aopGet(AOP(left),1,FALSE,FALSE,TRUE));
+ emitcode ("jnb","acc.7,%05d$",lbl->key+100);
+ emitcode ("xch", "a,b");
+ emitcode ("cpl","a");
+ emitcode ("add", "a,#1");
+ emitcode ("xch", "a,b");
+ emitcode ("cpl", "a"); // msb
+ emitcode ("addc","a,#0");
+ emitcode ("setb","F0");
+ emitcode ("","%05d$:",lbl->key+100);
+ emitcode ("mov","ma,b");
+ emitcode ("mov","ma,a");
+ } else {
+ emitcode ("mov","ma,%s",aopGet(AOP(left),0,FALSE,FALSE,TRUE));
+ emitcode ("mov","ma,%s",aopGet(AOP(left),1,FALSE,FALSE,TRUE));
+ }
+
+ /* load up MB with right */
+ if (!umult) {
+ if (AOP_TYPE(right) == AOP_LIT) {
+ int val=floatFromVal (AOP (right)->aopu.aop_lit);
+ if (val < 0) {
+ lbl = newiTempLabel(NULL);
+ emitcode ("jbc","F0,%05d$",lbl->key+100);
+ emitcode("setb","F0");
+ emitcode ("","%05d$:",lbl->key+100);
+ val = -val;
+ }
+ emitcode ("mov","mb,#0x%02x",val & 0xff);
+ emitcode ("mov","mb,#0x%02x",(val >> 8) & 0xff);
+ } else {
+ lbl = newiTempLabel(NULL);
+ emitcode ("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE,TRUE));
+ emitcode ("mov","a,%s",aopGet(AOP(right),1,FALSE,FALSE,TRUE));
+ emitcode ("jnb","acc.7,%05d$",lbl->key+100);
+ emitcode ("xch", "a,b");
+ emitcode ("cpl","a");
+ emitcode ("add", "a,#1");
+ emitcode ("xch", "a,b");
+ emitcode ("cpl", "a"); // msb
+ emitcode ("addc", "a,#0");
+ emitcode ("jbc","F0,%05d$",lbl->key+100);
+ emitcode ("setb","F0");
+ emitcode ("","%05d$:",lbl->key+100);
+ emitcode ("mov","mb,b");
+ emitcode ("mov","mb,a");
+ }
+ } else {
+ emitcode ("mov","mb,%s",aopGet(AOP(right),0,FALSE,FALSE,TRUE));
+ emitcode ("mov","mb,%s",aopGet(AOP(right),1,FALSE,FALSE,TRUE));
+ }
+
+ /* wait for multiplication to finish */
+ lbl = newiTempLabel(NULL);
+ emitcode("","%05d$:", lbl->key+100);
+ emitcode("mov","a,mcnt1");
+ emitcode("anl","a,#0x80");
+ emitcode("jnz","%05d$",lbl->key+100);
+
+ freeAsmop (left, NULL, ic, TRUE);
+ freeAsmop (right, NULL, ic,TRUE);
+ aopOp(result, ic, TRUE, FALSE);
+
+ /* if unsigned then simple */
+ if (umult) {
+ aopPut(AOP(result),"ma",1);
+ aopPut(AOP(result),"ma",0);
+ } else {
+ emitcode("push","ma");
+ MOVA("ma");
+ /* negate result if needed */
+ lbl = newiTempLabel(NULL);
+ emitcode("jnb","F0,%05d$",lbl->key+100);
+ emitcode("cpl","a");
+ emitcode("add","a,#1");
+ emitcode("","%05d$:", lbl->key+100);
+ aopPut(AOP(result),"a",0);
+ emitcode("pop","acc");
+ lbl = newiTempLabel(NULL);
+ emitcode("jnb","F0,%05d$",lbl->key+100);
+ emitcode("cpl","a");
+ emitcode("addc","a,#0");
+ emitcode("","%05d$:", lbl->key+100);
+ aopPut(AOP(result),"a",1);
+ }
+ freeAsmop (result, NULL, ic, TRUE);
+ /* restore EA bit in F1 */
+ lbl = newiTempLabel(NULL);
+ emitcode ("jnb","F1,%05d$",lbl->key+100);
+ emitcode ("setb","EA");
+ emitcode("","%05d$:",lbl->key+100);
+ return ;
}
/*-----------------------------------------------------------------*/
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;
}
+ if (AOP_SIZE (left) == 2 && AOP_SIZE(right) == 2) {
+ /* use the ds390 ARITHMETIC accel UNIT */
+ genDivTwoByte (left, right, result, ic);
+ return ;
+ }
/* 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);
}
+/*-----------------------------------------------------------------*/
+/* genModTwoByte - use the DS390 MAC unit to do 16%16 modulus */
+/*-----------------------------------------------------------------*/
+static void genModTwoByte (operand *left, operand *right,
+ operand *result, iCode *ic)
+{
+ sym_link *retype = getSpec(operandType(right));
+ sym_link *letype = getSpec(operandType(left));
+ int umult = SPEC_USIGN(retype) | SPEC_USIGN(letype);
+ symbol *lbl;
+
+ /* load up MA with left */
+ /* save EA bit in F1 */
+ lbl = newiTempLabel(NULL);
+ emitcode ("setb","F1");
+ emitcode ("jbc","EA,%05d$",lbl->key+100);
+ emitcode ("clr","F1");
+ emitcode("","%05d$:",lbl->key+100);
+
+ if (!umult) {
+ lbl = newiTempLabel(NULL);
+ emitcode ("mov","b,%s",aopGet(AOP(left),0,FALSE,FALSE,TRUE));
+ emitcode ("mov","a,%s",aopGet(AOP(left),1,FALSE,FALSE,TRUE));
+ emitcode ("jnb","acc.7,%05d$",lbl->key+100);
+ emitcode ("xch", "a,b");
+ emitcode ("cpl","a");
+ emitcode ("add", "a,#1");
+ emitcode ("xch", "a,b");
+ emitcode ("cpl", "a"); // msb
+ emitcode ("addc","a,#0");
+ emitcode ("","%05d$:",lbl->key+100);
+ emitcode ("mov","ma,b");
+ emitcode ("mov","ma,a");
+ } else {
+ emitcode ("mov","ma,%s",aopGet(AOP(left),0,FALSE,FALSE,TRUE));
+ emitcode ("mov","ma,%s",aopGet(AOP(left),1,FALSE,FALSE,TRUE));
+ }
+
+ /* load up MB with right */
+ if (!umult) {
+ if (AOP_TYPE(right) == AOP_LIT) {
+ int val=floatFromVal (AOP (right)->aopu.aop_lit);
+ if (val < 0) {
+ val = -val;
+ }
+ emitcode ("mov","mb,#0x%02x",val & 0xff);
+ emitcode ("mov","mb,#0x%02x",(val >> 8) & 0xff);
+ } else {
+ lbl = newiTempLabel(NULL);
+ emitcode ("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE,TRUE));
+ emitcode ("mov","a,%s",aopGet(AOP(right),1,FALSE,FALSE,TRUE));
+ emitcode ("jnb","acc.7,%05d$",lbl->key+100);
+ emitcode ("xch", "a,b");
+ emitcode ("cpl","a");
+ emitcode ("add", "a,#1");
+ emitcode ("xch", "a,b");
+ emitcode ("cpl", "a"); // msb
+ emitcode ("addc", "a,#0");
+ emitcode ("","%05d$:",lbl->key+100);
+ emitcode ("mov","mb,b");
+ emitcode ("mov","mb,a");
+ }
+ } else {
+ emitcode ("mov","mb,%s",aopGet(AOP(right),0,FALSE,FALSE,TRUE));
+ emitcode ("mov","mb,%s",aopGet(AOP(right),1,FALSE,FALSE,TRUE));
+ }
+
+ /* wait for multiplication to finish */
+ lbl = newiTempLabel(NULL);
+ emitcode("","%05d$:", lbl->key+100);
+ emitcode("mov","a,mcnt1");
+ emitcode("anl","a,#0x80");
+ emitcode("jnz","%05d$",lbl->key+100);
+
+ freeAsmop (left, NULL, ic, TRUE);
+ freeAsmop (right, NULL, ic,TRUE);
+ aopOp(result, ic, TRUE, FALSE);
+
+ aopPut(AOP(result),"mb",1);
+ aopPut(AOP(result),"mb",0);
+ freeAsmop (result, NULL, ic, TRUE);
+
+ /* restore EA bit in F1 */
+ lbl = newiTempLabel(NULL);
+ emitcode ("jnb","F1,%05d$",lbl->key+100);
+ emitcode ("setb","EA");
+ emitcode("","%05d$:",lbl->key+100);
+ return ;
+}
+
/*-----------------------------------------------------------------*/
/* genMod - generates code for division */
/*-----------------------------------------------------------------*/
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;
}
+ if (AOP_SIZE (left) == 2 && AOP_SIZE(right) == 2) {
+ /* use the ds390 ARITHMETIC accel UNIT */
+ genModTwoByte (left, right, result, ic);
+ return ;
+ }
+
/* should have been converted to function call */
- assert (1);
+ assert (0);
release:
freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
return NULL;
}
+/*-----------------------------------------------------------------*/
+/* hasInc - operand is incremented before any other use */
+/*-----------------------------------------------------------------*/
+static iCode *
+hasInc (operand *op, iCode *ic)
+{
+ sym_link *type = operandType(op);
+ 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;
+
+ if (IS_BITVAR(retype)||!IS_PTR(type)) return NULL;
+ isize = getSize(type->next);
+ 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) {
+ return lic;
+ }
+ /* if the operand used or deffed */
+ if (bitVectBitValue(OP_USES(op),lic->key) || (unsigned) lic->defKey == op->key) {
+ return NULL;
+ }
+ /* if GOTO or IFX */
+ if (lic->op == IFX || lic->op == GOTO) break;
+ lic = lic->next;
+ }
+ return NULL;
+}
+
/*-----------------------------------------------------------------*/
/* genAndOp - for && operation */
/*-----------------------------------------------------------------*/
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;
emitcode ("setb", "c");
while (sizer--)
{
- MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
- emitcode ("anl", "a,%s",
- aopGet (AOP (left), offset, FALSE, FALSE, FALSE));
+ if (AOP_TYPE(right)==AOP_REG && AOP_TYPE(left)==AOP_ACC) {
+ emitcode ("anl", "a,%s",
+ aopGet (AOP (right), offset, FALSE, FALSE, FALSE));
+ } else {
+ if (AOP_TYPE(left)==AOP_ACC) {
+ emitcode("mov", "b,a");
+ MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
+ emitcode("anl", "a,b");
+ }else {
+ MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
+ emitcode ("anl", "a,%s",
+ aopGet (AOP (left), offset, FALSE, FALSE, FALSE));
+ }
+ }
emitcode ("jnz", "%05d$", tlbl->key + 100);
offset++;
}
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;
emitcode ("setb", "c");
while (sizer--)
{
- MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
- emitcode ("orl", "a,%s",
- aopGet (AOP (left), offset, FALSE, FALSE, FALSE));
+ if (AOP_TYPE(right)==AOP_REG && AOP_TYPE(left)==AOP_ACC) {
+ 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));
+ }
emitcode ("jnz", "%05d$", tlbl->key + 100);
offset++;
}
}
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;
// if(!size && ifx), conditional oper: if(left ^ right)
symbol *tlbl = newiTempLabel (NULL);
int sizer = max (AOP_SIZE (left), AOP_SIZE (right));
+
if (size)
emitcode ("setb", "c");
while (sizer--)
}
else
{
- MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
- emitcode ("xrl", "a,%s",
- aopGet (AOP (left), offset, FALSE, FALSE, FALSE));
+ if (AOP_TYPE(right)==AOP_REG && AOP_TYPE(left)==AOP_ACC) {
+ emitcode ("xrl", "a,%s",
+ aopGet (AOP (right), offset, FALSE, FALSE, FALSE));
+ } else {
+ 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);
+ }
}
emitcode ("jnz", "%05d$", tlbl->key + 100);
offset++;
jmpTrueOrFalse (ifx, tlbl);
}
else
+ {
for (; (size--); offset++)
{
// normal case
offset);
continue;
}
- D (emitcode (";", "better literal XOR.");
- );
+ D (emitcode (";", "better literal XOR."););
MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
emitcode ("xrl", "a, %s", aopGet (AOP (right), offset,
FALSE, FALSE, FALSE));
}
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);
}
+ }
+
}
release:
static void
genInline (iCode * ic)
{
- char buffer[MAX_INLINEASM];
- char *bp = buffer;
- char *bp1 = buffer;
+ char *buffer, *bp, *bp1;
D (emitcode (";", "genInline ");
);
_G.inLine += (!options.asmpeep);
+
+ buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
strcpy (buffer, IC_INLINE (ic));
/* emit each line as a code */
}
}
-#if 0
-//REMOVE ME!!!
+#ifdef BETTER_LITERAL_SHIFT
/*-----------------------------------------------------------------*/
/* AccSRsh - signed right shift accumulator by known count */
/*-----------------------------------------------------------------*/
}
#endif
-#if 0
-//REMOVE ME!!!
+#ifdef BETTER_LITERAL_SHIFT
/*-----------------------------------------------------------------*/
/* shiftR1Left2Result - shift right one byte from left to result */
/*-----------------------------------------------------------------*/
}
#endif
-#if 0
+#ifdef BETTER_LITERAL_SHIFT
//REMOVE ME!!!
/*-----------------------------------------------------------------*/
/* AccAXLrl1 - left rotate c<-a:x<-c by 1 */
}
#endif
-#if 0
+#ifdef BETTER_LITERAL_SHIFT
//REMOVE ME!!!
/*-----------------------------------------------------------------*/
/* AccAXRsh - right shift a:x known count (0..7) */
}
#endif
-#if 0
-//REMOVE ME!!!
+#ifdef BETTER_LITERAL_SHIFT
/*-----------------------------------------------------------------*/
/* AccAXRshS - right shift signed a:x known count (0..7) */
/*-----------------------------------------------------------------*/
#endif
#ifdef BETTER_LITERAL_SHIFT
-/*-----------------------------------------------------------------*/
-/* shiftL2Left2Result - shift left two bytes from left to result */
-/*-----------------------------------------------------------------*/
static void
-shiftL2Left2Result (operand * left, int offl,
- operand * result, int offr, int shCount)
+_loadLeftIntoAx(char **lsb,
+ operand *left,
+ operand *result,
+ int offl,
+ int offr)
{
- char *lsb;
-
// Get the initial value from left into a pair of registers.
// MSB must be in A, LSB can be any register.
//
{
char *leftByte;
- D(emitcode(";", "watch me do the hambone!"););
_startLazyDPSEvaluation();
- if (AOP_TYPE(left) == AOP_DPTR2)
+ if (AOP_TYPE(left) == AOP_DPTR2)
{
// Get MSB in A.
MOVA(aopGet(AOP(left), offl + MSB16, FALSE, FALSE, TRUE));
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.
MOVA(leftByte);
}
_endLazyDPSEvaluation();
- lsb = DP2_RESULT_REG;
+ *lsb = DP2_RESULT_REG;
}
else
{
movLeft2Result (left, offl, result, offr, 0);
MOVA (aopGet (AOP (left), offl + MSB16, FALSE, FALSE, TRUE));
}
- lsb = aopGet(AOP (result), offr, FALSE, FALSE, FALSE);
- assert(strcmp(lsb,"a"));
+ *lsb = aopGet(AOP (result), offr, FALSE, FALSE, FALSE);
+ assert(strcmp(*lsb,"a"));
}
- AccAXLsh (lsb, shCount);
-
+}
+
+static void
+_storeAxResults(char *lsb,
+ operand *result,
+ int offr)
+{
_startLazyDPSEvaluation();
if (AOP_NEEDSACC(result))
{
aopPut(AOP(result), "a", offr);
emitcode("mov","a,%s", lsb);
}
- aopPut (AOP (result), "a", offr + MSB16);
+ if (getDataSize (result) > 1)
+ {
+ aopPut (AOP (result), "a", offr + MSB16);
+ }
_endLazyDPSEvaluation();
}
+
+/*-----------------------------------------------------------------*/
+/* shiftL2Left2Result - shift left two bytes from left to result */
+/*-----------------------------------------------------------------*/
+static void
+shiftL2Left2Result (operand * left, int offl,
+ operand * result, int offr, int shCount)
+{
+ char *lsb;
+
+ _loadLeftIntoAx(&lsb, left, result, offl, offr);
+
+ AccAXLsh (lsb, shCount);
+
+ _storeAxResults(lsb, result, offr);
+}
#endif
-#if 0
-//REMOVE ME!!!
+#ifdef BETTER_LITERAL_SHIFT
/*-----------------------------------------------------------------*/
/* shiftR2Left2Result - shift right two bytes from left to result */
/*-----------------------------------------------------------------*/
operand * result, int offr,
int shCount, int sign)
{
- if (sameRegs (AOP (result), AOP (left)) &&
- ((offl + MSB16) == offr))
- {
- /* don't crash result[offr] */
- MOVA (aopGet (AOP (left), offl, FALSE, FALSE, TRUE));
- emitcode ("xch", "a,%s", aopGet (AOP (left), offl + MSB16, FALSE, FALSE, FALSE));
- }
- else
- {
- movLeft2Result (left, offl, result, offr, 0);
- MOVA (aopGet (AOP (left), offl + MSB16, FALSE, FALSE, TRUE));
- }
+ char *lsb;
+
+ _loadLeftIntoAx(&lsb, left, result, offl, offr);
+
/* a:x >> shCount (x = lsb(result)) */
if (sign)
- AccAXRshS (aopGet (AOP (result), offr, FALSE, FALSE, FALSE), shCount);
+ {
+ AccAXRshS(lsb, shCount);
+ }
else
- AccAXRsh (aopGet (AOP (result), offr, FALSE, FALSE, FALSE), shCount);
- if (getDataSize (result) > 1)
- aopPut (AOP (result), "a", offr + MSB16);
+ {
+ AccAXRsh(lsb, shCount);
+ }
+
+ _storeAxResults(lsb, result, offr);
}
#endif
shCount -= 8;
_startLazyDPSEvaluation();
- aopPut (AOP (result), zero, LSB);
+
if (size > 1)
{
if (shCount)
{
_endLazyDPSEvaluation();
shiftL1Left2Result (left, LSB, result, MSB16, shCount);
+ aopPut (AOP (result), zero, LSB);
}
else
{
movLeft2Result (left, LSB, result, MSB16, 0);
+ aopPut (AOP (result), zero, LSB);
_endLazyDPSEvaluation();
}
}
else
{
+ aopPut (AOP (result), zero, LSB);
_endLazyDPSEvaluation();
}
}
freeAsmop (result, NULL, ic, TRUE);
}
-#if 0
-//REMOVE ME!!!
+#ifdef BETTER_LITERAL_SHIFT
/*-----------------------------------------------------------------*/
/* genrshOne - right shift a one byte quantity by known count */
/*-----------------------------------------------------------------*/
genrshOne (operand * result, operand * left,
int shCount, int sign)
{
- D (emitcode (";", "genrshOne");
- );
+ D (emitcode (";", "genrshOne"););
shiftR1Left2Result (left, LSB, result, LSB, shCount, sign);
}
#endif
-#if 0
-//REMOVE ME!!!
+#ifdef BETTER_LITERAL_SHIFT
/*-----------------------------------------------------------------*/
/* genrshTwo - right shift two bytes by known amount != 0 */
/*-----------------------------------------------------------------*/
genrshTwo (operand * result, operand * left,
int shCount, int sign)
{
- D (emitcode (";", "genrshTwo");
- );
+ D (emitcode (";", "genrshTwo"););
/* if shCount >= 8 */
if (shCount >= 8)
{
shCount -= 8;
+ _startLazyDPSEvaluation();
if (shCount)
+ {
shiftR1Left2Result (left, MSB16, result, LSB,
shCount, sign);
+ }
else
+ {
movLeft2Result (left, MSB16, result, LSB, sign);
+ }
addSign (result, MSB16, sign);
+ _endLazyDPSEvaluation();
}
/* 1 <= shCount <= 7 */
else
+ {
shiftR2Left2Result (left, LSB, result, LSB, shCount, sign);
+ }
}
#endif
shiftRLong (operand * left, int offl,
operand * result, int sign)
{
- if (!sign)
+ int isSameRegs=sameRegs(AOP(left),AOP(result));
+
+ if (isSameRegs && offl>1) {
+ // we are in big trouble, but this shouldn't happen
+ werror(E_INTERNAL_ERROR, __FILE__, __LINE__);
+ }
+
+ MOVA (aopGet (AOP (left), MSB32, FALSE, FALSE));
+
+ if (offl==MSB16) {
+ // shift is > 8
+ if (sign) {
+ emitcode ("rlc", "a");
+ emitcode ("subb", "a,acc");
+ emitcode ("xch", "a,%s", aopGet(AOP(left), MSB32, FALSE, FALSE));
+ } else {
+ aopPut (AOP(result), zero, MSB32);
+ }
+ }
+
+ if (!sign) {
emitcode ("clr", "c");
- MOVA (aopGet (AOP (left), MSB32, FALSE, FALSE, TRUE));
- if (sign)
+ } else {
emitcode ("mov", "c,acc.7");
- emitcode ("rrc", "a");
- aopPut (AOP (result), "a", MSB32 - offl);
- if (offl == MSB16)
- /* add sign of "a" */
- addSign (result, MSB32, sign);
+ }
- MOVA (aopGet (AOP (left), MSB24, FALSE, FALSE, TRUE));
emitcode ("rrc", "a");
- aopPut (AOP (result), "a", MSB24 - offl);
- MOVA (aopGet (AOP (left), MSB16, FALSE, FALSE, TRUE));
+ if (isSameRegs && offl==MSB16) {
+ emitcode ("xch", "a,%s",aopGet (AOP (left), MSB24, FALSE, FALSE));
+ } else {
+ aopPut (AOP (result), "a", MSB32);
+ MOVA (aopGet (AOP (left), MSB24, FALSE, FALSE));
+ }
+
+ emitcode ("rrc", "a");
+ if (isSameRegs && offl==1) {
+ emitcode ("xch", "a,%s",aopGet (AOP (left), MSB16, FALSE, FALSE));
+ } else {
+ aopPut (AOP (result), "a", MSB24);
+ MOVA (aopGet (AOP (left), MSB16, FALSE, FALSE));
+ }
emitcode ("rrc", "a");
aopPut (AOP (result), "a", MSB16 - offl);
if (offl == LSB)
{
- MOVA (aopGet (AOP (left), LSB, FALSE, FALSE, TRUE));
+ MOVA (aopGet (AOP (left), LSB, FALSE, FALSE));
emitcode ("rrc", "a");
aopPut (AOP (result), "a", LSB);
}
}
#endif
-#if 0
-//REMOVE ME!!!
+#ifdef BETTER_LITERAL_SHIFT
/*-----------------------------------------------------------------*/
/* genRightShiftLiteral - right shifting by known count */
/*-----------------------------------------------------------------*/
-static void
+static bool
genRightShiftLiteral (operand * left,
operand * right,
operand * result,
int shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit);
int size;
- D (emitcode (";", "genRightShiftLiteral");
- );
+ size = getSize (operandType (result));
+
+ D(emitcode (";", "genRightShiftLiteral (%d), size %d", shCount, size););
+
+ /* We only handle certain easy cases so far. */
+ if ((shCount != 0)
+ && (shCount < (size * 8))
+ && (size != 1)
+ && (size != 2))
+ {
+ D(emitcode (";", "genRightShiftLiteral wimping out"););
+ return FALSE;
+ }
freeAsmop (right, NULL, ic, TRUE);
AOP_SIZE (left));
#endif
- size = getDataSize (left);
/* test the LEFT size !!! */
/* I suppose that the left size >= result size */
if (shCount == 0)
- {
+ {
size = getDataSize (result);
+ _startLazyDPSEvaluation();
while (size--)
+ {
movLeft2Result (left, size, result, size, 0);
- }
-
+ }
+ _endLazyDPSEvaluation();
+ }
else if (shCount >= (size * 8))
{
if (sign)
+ {
/* get sign in acc.7 */
MOVA (aopGet (AOP (left), size - 1, FALSE, FALSE, TRUE));
+ }
addSign (result, LSB, sign);
}
else
case 2:
genrshTwo (result, left, shCount, sign);
break;
-
+#if 0
case 4:
genrshFour (result, left, shCount, sign);
break;
+#endif
default:
break;
}
freeAsmop (left, NULL, ic, TRUE);
freeAsmop (result, NULL, ic, TRUE);
}
+ return TRUE;
}
#endif
aopOp (right, ic, FALSE, FALSE);
-#if 0
+#ifdef BETTER_LITERAL_SHIFT
if (AOP_TYPE (right) == AOP_LIT)
{
- genRightShiftLiteral (left, right, result, ic, 1);
- return;
+ if (genRightShiftLiteral (left, right, result, ic, 1))
+ {
+ return;
+ }
}
#endif
/* shift count is unknown then we have to form
aopOp (right, ic, FALSE, FALSE);
-#if 0
+#ifdef BETTER_LITERAL_SHIFT
/* if the shift count is known then do it
as efficiently as possible */
if (AOP_TYPE (right) == AOP_LIT)
{
- genRightShiftLiteral (left, right, result, ic, 0);
- return;
+ if (genRightShiftLiteral (left, right, result, ic, 0))
+ {
+ return;
+ }
}
#endif
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:
static void
genNearPointerGet (operand * left,
operand * result,
- iCode * ic)
+ iCode * ic,
+ iCode *pi)
{
asmop *aop = NULL;
regs *preg = NULL;
aopPut (AOP (result), buffer, offset);
}
offset++;
- if (size)
+ if (size || pi)
emitcode ("inc", "%s", rname);
}
}
if (aop)
{
/* we had to allocate for this iCode */
+ if (pi) { /* post increment present */
+ aopPut(AOP ( left ),rname,0);
+ }
freeAsmop (NULL, aop, ic, TRUE);
}
else
if (AOP_SIZE (result) > 1 &&
!OP_SYMBOL (left)->remat &&
(OP_SYMBOL (left)->liveTo > ic->seq ||
- ic->depth))
+ ic->depth) &&
+ !pi)
{
int size = AOP_SIZE (result) - 1;
while (size--)
/* done */
freeAsmop (result, NULL, ic, TRUE);
-
+ if (pi) pi->generated = 1;
}
/*-----------------------------------------------------------------*/
static void
genPagedPointerGet (operand * left,
operand * result,
- iCode * ic)
+ iCode * ic,
+ iCode * pi)
{
asmop *aop = NULL;
regs *preg = NULL;
offset++;
- if (size)
+ if (size || pi)
emitcode ("inc", "%s", rname);
}
}
if (aop)
{
/* we had to allocate for this iCode */
+ if (pi) aopPut ( AOP (left), rname, 0);
freeAsmop (NULL, aop, ic, TRUE);
}
else
if (AOP_SIZE (result) > 1 &&
!OP_SYMBOL (left)->remat &&
(OP_SYMBOL (left)->liveTo > ic->seq ||
- ic->depth))
+ ic->depth) &&
+ !pi)
{
int size = AOP_SIZE (result) - 1;
while (size--)
/* done */
freeAsmop (result, NULL, ic, TRUE);
-
-
+ if (pi) pi->generated = 1;
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
static void
genFarPointerGet (operand * left,
- operand * result, iCode * ic)
+ operand * result, iCode * ic, iCode *pi)
{
- int size, offset;
+ int size, offset, dopi=1;
sym_link *retype = getSpec (operandType (result));
sym_link *letype = getSpec (operandType (left));
D (emitcode (";", "genFarPointerGet");
{
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");
+ dopi =0;
}
_endLazyDPSEvaluation ();
}
}
/* so dptr know contains the address */
- freeAsmop (left, NULL, ic, TRUE);
aopOp (result, ic, FALSE, TRUE);
/* if bit then unpack */
_flushLazyDPS ();
emitcode ("movx", "a,@dptr");
- if (size)
+ if (size || (dopi && pi && AOP_TYPE (left) != AOP_IMMD))
emitcode ("inc", "dptr");
aopPut (AOP (result), "a", offset++);
}
_endLazyDPSEvaluation ();
}
+ if (dopi && pi && AOP_TYPE (left) != AOP_IMMD) {
+ aopPut ( AOP (left), "dpl", 0);
+ aopPut ( AOP (left), "dph", 1);
+ if (options.model == MODEL_FLAT24)
+ aopPut ( AOP (left), "dpx", 2);
+ pi->generated = 1;
+ } else if (OP_SYMBOL(left)->ruonly && AOP_SIZE(result) > 1 &&
+ (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) {
+
+ size = AOP_SIZE (result) - 1;
+ while (size--) emitcode ("lcall","__decdptr");
+ }
+ freeAsmop (left, NULL, ic, TRUE);
freeAsmop (result, NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
static void
emitcodePointerGet (operand * left,
- operand * result, iCode * ic)
+ operand * result, iCode * ic, iCode *pi)
{
- int size, offset;
+ int size, offset, dopi=1;
sym_link *retype = getSpec (operandType (result));
aopOp (left, ic, FALSE, FALSE);
{
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");
+ dopi=0;
}
_endLazyDPSEvaluation ();
}
}
/* so dptr know contains the address */
- freeAsmop (left, NULL, ic, TRUE);
aopOp (result, ic, FALSE, TRUE);
/* if bit then unpack */
emitcode ("clr", "a");
emitcode ("movc", "a,@a+dptr");
- if (size)
+ if (size || (dopi && pi && AOP_TYPE (left) != AOP_IMMD))
emitcode ("inc", "dptr");
aopPut (AOP (result), "a", offset++);
}
_endLazyDPSEvaluation ();
}
-
+ if (dopi && pi && AOP_TYPE (left) != AOP_IMMD) {
+ aopPut ( AOP (left), "dpl", 0);
+ aopPut ( AOP (left), "dph", 1);
+ if (options.model == MODEL_FLAT24)
+ aopPut ( AOP (left), "dpx", 2);
+ pi->generated = 1;
+ } else if (OP_SYMBOL(left)->ruonly && AOP_SIZE(result) > 1 &&
+ (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) {
+
+ size = AOP_SIZE (result) - 1;
+ while (size--) emitcode ("lcall","__decdptr");
+ }
+
+ freeAsmop (left, NULL, ic, TRUE);
freeAsmop (result, NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
static void
genGenPointerGet (operand * left,
- operand * result, iCode * ic)
+ operand * result, iCode * ic, iCode * pi)
{
int size, offset;
sym_link *retype = getSpec (operandType (result));
D (emitcode (";", "genGenPointerGet "); );
- aopOp (left, ic, FALSE, TRUE);
+ aopOp (left, ic, FALSE, (OP_SYMBOL(left)->ruonly ? FALSE : TRUE));
/* if the operand is already in dptr
then we do nothing else we move the value to dptr */
if (AOP_TYPE (left) == AOP_IMMD)
{
emitcode ("mov", "dptr,%s", aopGet (AOP (left), 0, TRUE, FALSE, FALSE));
- emitcode ("mov", "b,#%d", pointerCode (retype));
+ if (AOP(left)->aopu.aop_immd.from_cast_remat)
+ emitcode ("mov", "b,%s",aopGet(AOP (left), AOP_SIZE(left)-1, FALSE, FALSE, FALSE));
+ else
+ emitcode ("mov", "b,#%d", pointerCode (retype));
}
else
{ /* we need to get it byte by byte */
l=aopGet(AOP(left),0,FALSE,FALSE,TRUE);
genSetDPTR(0);
_flushLazyDPS();
- emitcode ("mov", "dpl,%s ;jwk lazy genGenPointerGet", l);
+ emitcode ("mov", "dpl,%s", l);
l=aopGet(AOP(left),1,FALSE,FALSE,TRUE);
genSetDPTR(0);
_flushLazyDPS();
- emitcode ("mov", "dph,%s ;jwk lazy genGenPointerGet", l);
- l=aopGet(AOP(left),2,FALSE,FALSE,TRUE);
- genSetDPTR(0);
- _flushLazyDPS();
- emitcode ("mov", "dpx,%s ;jwk lazy genGenPointerGet", l);
- emitcode ("mov", "b,%s", aopGet (AOP(left),3,FALSE,FALSE,TRUE));
+ emitcode ("mov", "dph,%s", l);
+ 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 ();
}
}
/* so dptr know contains the address */
- freeAsmop (left, NULL, ic, TRUE);
aopOp (result, ic, FALSE, TRUE);
/* if bit then unpack */
{
emitcode ("lcall", "__gptrget");
aopPut (AOP (result), "a", offset++);
- if (size)
+ if (size || (pi && AOP_TYPE (left) != AOP_IMMD))
emitcode ("inc", "dptr");
}
}
+ if (pi && AOP_TYPE (left) != AOP_IMMD) {
+ aopPut ( AOP (left), "dpl", 0);
+ aopPut ( AOP (left), "dph", 1);
+ if (options.model == MODEL_FLAT24) {
+ aopPut ( AOP (left), "dpx", 2);
+ aopPut ( AOP (left), "b", 3);
+ } else aopPut ( AOP (left), "b", 2);
+ pi->generated = 1;
+ } else if (OP_SYMBOL(left)->ruonly && AOP_SIZE(result) > 1 &&
+ (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) {
+
+ size = AOP_SIZE (result) - 1;
+ while (size--) emitcode ("lcall","__decdptr");
+ }
+
+ freeAsmop (left, NULL, ic, TRUE);
freeAsmop (result, NULL, ic, TRUE);
}
/* genPointerGet - generate code for pointer get */
/*-----------------------------------------------------------------*/
static void
-genPointerGet (iCode * ic)
+genPointerGet (iCode * ic, iCode *pi)
{
operand *left, *result;
sym_link *type, *etype;
/* 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(left)->remat &&
+ IS_CAST_ICODE(OP_SYMBOL(left)->rematiCode)) {
+ left = IC_RIGHT(OP_SYMBOL(left)->rematiCode);
+ type = 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:
- genNearPointerGet (left, result, ic);
+ genNearPointerGet (left, result, ic, pi);
break;
case PPOINTER:
- genPagedPointerGet (left, result, ic);
+ genPagedPointerGet (left, result, ic, pi);
break;
case FPOINTER:
- genFarPointerGet (left, result, ic);
+ genFarPointerGet (left, result, ic, pi);
break;
case CPOINTER:
- emitcodePointerGet (left, result, ic);
+ emitcodePointerGet (left, result, ic, pi);
break;
case GPOINTER:
- genGenPointerGet (left, result, ic);
+ genGenPointerGet (left, result, ic, pi);
break;
}
static void
genNearPointerSet (operand * right,
operand * result,
- iCode * ic)
+ iCode * ic,
+ iCode * pi)
{
asmop *aop = NULL;
regs *preg = NULL;
else
rname = aopGet (AOP (result), 0, FALSE, FALSE, FALSE);
- freeAsmop (result, NULL, ic, TRUE);
aopOp (right, ic, FALSE, FALSE);
/* if bitfield then unpack the bits */
}
else
emitcode ("mov", "@%s,%s", rname, l);
- if (size)
+ if (size || pi)
emitcode ("inc", "%s", rname);
offset++;
}
if (aop)
{
/* we had to allocate for this iCode */
+ if (pi) aopPut (AOP (result),rname,0);
freeAsmop (NULL, aop, ic, TRUE);
}
else
if (AOP_SIZE (right) > 1 &&
!OP_SYMBOL (result)->remat &&
(OP_SYMBOL (result)->liveTo > ic->seq ||
- ic->depth))
+ ic->depth) &&
+ !pi)
{
int size = AOP_SIZE (right) - 1;
while (size--)
}
/* done */
+ if (pi) pi->generated = 1;
+ freeAsmop (result, NULL, ic, TRUE);
freeAsmop (right, NULL, ic, TRUE);
static void
genPagedPointerSet (operand * right,
operand * result,
- iCode * ic)
+ iCode * ic,
+ iCode *pi)
{
asmop *aop = NULL;
regs *preg = NULL;
else
rname = aopGet (AOP (result), 0, FALSE, FALSE, FALSE);
- freeAsmop (result, NULL, ic, TRUE);
aopOp (right, ic, FALSE, FALSE);
/* if bitfield then unpack the bits */
MOVA (l);
emitcode ("movx", "@%s,a", rname);
- if (size)
+ if (size || pi)
emitcode ("inc", "%s", rname);
offset++;
/* now some housekeeping stuff */
if (aop)
{
+ if (pi) aopPut (AOP (result),rname,0);
/* we had to allocate for this iCode */
freeAsmop (NULL, aop, ic, TRUE);
}
if (AOP_SIZE (right) > 1 &&
!OP_SYMBOL (result)->remat &&
(OP_SYMBOL (result)->liveTo > ic->seq ||
- ic->depth))
+ ic->depth) &&
+ !pi)
{
int size = AOP_SIZE (right) - 1;
while (size--)
}
/* done */
+ if (pi) pi->generated = 1;
+ freeAsmop (result, NULL, ic, TRUE);
freeAsmop (right, NULL, ic, TRUE);
/*-----------------------------------------------------------------*/
static void
genFarPointerSet (operand * right,
- operand * result, iCode * ic)
+ operand * result, iCode * ic, iCode *pi)
{
- int size, offset;
+ int size, offset, dopi=1;
sym_link *retype = getSpec (operandType (right));
sym_link *letype = getSpec (operandType (result));
{
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");
+ dopi=0;
}
_endLazyDPSEvaluation ();
}
}
/* so dptr know contains the address */
- freeAsmop (result, NULL, ic, TRUE);
aopOp (right, ic, FALSE, TRUE);
/* if bit then unpack */
_flushLazyDPS ();
emitcode ("movx", "@dptr,a");
- if (size)
+ if (size || (dopi && pi && AOP_TYPE (result) != AOP_IMMD))
emitcode ("inc", "dptr");
}
_endLazyDPSEvaluation ();
}
+ if (dopi && pi && AOP_TYPE (result) != AOP_IMMD) {
+ aopPut (AOP(result),"dpl",0);
+ aopPut (AOP(result),"dph",1);
+ if (options.model == MODEL_FLAT24)
+ aopPut (AOP(result),"dpx",2);
+ pi->generated=1;
+ } else if (OP_SYMBOL(result)->ruonly && AOP_SIZE(right) > 1 &&
+ (OP_SYMBOL (result)->liveTo > ic->seq || ic->depth)) {
+
+ size = AOP_SIZE (right) - 1;
+ while (size--) emitcode ("lcall","__decdptr");
+ }
+ freeAsmop (result, NULL, ic, TRUE);
freeAsmop (right, NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
static void
genGenPointerSet (operand * right,
- operand * result, iCode * ic)
+ operand * result, iCode * ic, iCode *pi)
{
int size, offset;
sym_link *retype = getSpec (operandType (right));
sym_link *letype = getSpec (operandType (result));
- aopOp (result, ic, FALSE, TRUE);
+ aopOp (result, ic, FALSE, OP_SYMBOL(result)->ruonly ? FALSE : TRUE);
/* if the operand is already in dptr
then we do nothing else we move the value to dptr */
if (AOP_TYPE (result) == AOP_IMMD)
{
emitcode ("mov", "dptr,%s", aopGet (AOP (result), 0, TRUE, FALSE, FALSE));
- emitcode ("mov", "b,%s + 1", aopGet (AOP (result), 0, TRUE, FALSE, FALSE));
+ if (AOP(result)->aopu.aop_immd.from_cast_remat)
+ emitcode ("mov", "b,%s",aopGet(AOP (result), AOP_SIZE(result)-1, FALSE, FALSE, FALSE));
+ else
+ emitcode ("mov", "b,%s + 1", aopGet (AOP (result), 0, TRUE, FALSE, FALSE));
}
else
{ /* 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 ();
}
/* so dptr know contains the address */
- freeAsmop (result, NULL, ic, TRUE);
aopOp (right, ic, FALSE, TRUE);
/* if bit then unpack */
_flushLazyDPS ();
emitcode ("lcall", "__gptrput");
- if (size)
+ if (size || (pi && AOP_TYPE (result) != AOP_IMMD))
emitcode ("inc", "dptr");
}
_endLazyDPSEvaluation ();
}
+ if (pi && AOP_TYPE (result) != AOP_IMMD) {
+ aopPut (AOP(result),"dpl",0);
+ aopPut (AOP(result),"dph",1);
+ if (options.model == MODEL_FLAT24) {
+ aopPut (AOP(result),"dpx",2);
+ aopPut (AOP(result),"b",3);
+ } else {
+ aopPut (AOP(result),"b",2);
+ }
+ pi->generated=1;
+ } else if (OP_SYMBOL(result)->ruonly && AOP_SIZE(right) > 1 &&
+ (OP_SYMBOL (result)->liveTo > ic->seq || ic->depth)) {
+
+ size = AOP_SIZE (right) - 1;
+ while (size--) emitcode ("lcall","__decdptr");
+ }
+ freeAsmop (result, NULL, ic, TRUE);
freeAsmop (right, NULL, ic, TRUE);
}
/* genPointerSet - stores the value into a pointer location */
/*-----------------------------------------------------------------*/
static void
-genPointerSet (iCode * ic)
+genPointerSet (iCode * ic, iCode *pi)
{
operand *right, *result;
sym_link *type, *etype;
/* 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 = type = operandType (result);
+ p_type = DCL_TYPE (type);
+ }
/* now that we have the pointer type we assign
the pointer values */
case POINTER:
case IPOINTER:
- genNearPointerSet (right, result, ic);
+ genNearPointerSet (right, result, ic, pi);
break;
case PPOINTER:
- genPagedPointerSet (right, result, ic);
+ genPagedPointerSet (right, result, ic, pi);
break;
case FPOINTER:
- genFarPointerSet (right, result, ic);
+ genFarPointerSet (right, result, ic, pi);
break;
case GPOINTER:
- genGenPointerSet (right, result, ic);
+ genGenPointerSet (right, result, ic, pi);
break;
}
/* if the operand is on the stack then we
need to get the stack offset of this
variable */
- if (sym->onStack)
- {
- /* if it has an offset then we need to compute
- it */
- if (sym->stack)
- {
- emitcode ("mov", "a,_bp");
- emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff));
- aopPut (AOP (IC_RESULT (ic)), "a", 0);
- }
- else
- {
- /* we can just move _bp */
- aopPut (AOP (IC_RESULT (ic)), "_bp", 0);
- }
- /* fill the result with zero */
- size = AOP_SIZE (IC_RESULT (ic)) - 1;
-
-
- if (options.stack10bit && size < (FPTRSIZE - 1))
- {
- fprintf (stderr,
- "*** warning: pointer to stack var truncated.\n");
- }
+ if (sym->onStack) {
+
+ /* if 10 bit stack */
+ if (options.stack10bit) {
+ /* if it has an offset then we need to compute it */
+ emitcode ("subb", "a,#0x%02x",
+ -((sym->stack < 0) ?
+ ((short) (sym->stack - _G.nRegsSaved)) :
+ ((short) sym->stack)) & 0xff);
+ emitcode ("mov","b,a");
+ emitcode ("mov","a,#0x%02x",(-((sym->stack < 0) ?
+ ((short) (sym->stack - _G.nRegsSaved)) :
+ ((short) sym->stack)) >> 8) & 0xff);
+ if (sym->stack) {
+ emitcode ("mov", "a,_bpx");
+ emitcode ("add", "a,#0x%02x", ((sym->stack < 0) ?
+ ((char) (sym->stack - _G.nRegsSaved)) :
+ ((char) sym->stack )) & 0xff);
+ emitcode ("mov", "b,a");
+ emitcode ("mov", "a,_bpx+1");
+ emitcode ("addc","a,#0x%02x", (((sym->stack < 0) ?
+ ((short) (sym->stack - _G.nRegsSaved)) :
+ ((short) sym->stack )) >> 8) & 0xff);
+ aopPut (AOP (IC_RESULT (ic)), "b", 0);
+ aopPut (AOP (IC_RESULT (ic)), "a", 1);
+ aopPut (AOP (IC_RESULT (ic)), "#0x40", 2);
+ } else {
+ /* we can just move _bp */
+ aopPut (AOP (IC_RESULT (ic)), "_bpx", 0);
+ aopPut (AOP (IC_RESULT (ic)), "_bpx+1", 1);
+ aopPut (AOP (IC_RESULT (ic)), "#0x40", 2);
+ }
+ } else {
+ /* if it has an offset then we need to compute it */
+ if (sym->stack) {
+ emitcode ("mov", "a,_bp");
+ emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff));
+ aopPut (AOP (IC_RESULT (ic)), "a", 0);
+ } else {
+ /* we can just move _bp */
+ aopPut (AOP (IC_RESULT (ic)), "_bp", 0);
+ }
+ /* fill the result with zero */
+ size = AOP_SIZE (IC_RESULT (ic)) - 1;
+
+
+ if (options.stack10bit && size < (FPTRSIZE - 1)) {
+ fprintf (stderr,
+ "*** warning: pointer to stack var truncated.\n");
+ }
- offset = 1;
- while (size--)
- {
- /* Yuck! */
- if (options.stack10bit && offset == 2)
- {
- aopPut (AOP (IC_RESULT (ic)), "#0x40", offset++);
- }
- else
- {
+ offset = 1;
+ while (size--) {
aopPut (AOP (IC_RESULT (ic)), zero, offset++);
- }
- }
-
+ }
+ }
goto release;
- }
+ }
/* object not on stack then we need the name */
size = AOP_SIZE (IC_RESULT (ic));
}
+/*-----------------------------------------------------------------*/
+/* 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 */
/*-----------------------------------------------------------------*/
{
int size = AOP_SIZE (right);
int offset = 0;
- char *l;
-
- if (size > 1)
- {
- /* This is a net loss for size == 1, but a big gain
- * otherwise.
- */
- D (emitcode (";", "genFarFarAssign (improved)");
- );
+ symbol *rSym = NULL;
+ if (size == 1)
+ {
+ /* quick & easy case. */
+ D(emitcode(";","genFarFarAssign (1 byte case)"););
+ MOVA(aopGet(AOP(right), 0, FALSE, FALSE, TRUE));
+ freeAsmop (right, NULL, ic, FALSE);
+ /* now assign DPTR to result */
+ _G.accInUse++;
+ aopOp(result, ic, FALSE, FALSE);
+ _G.accInUse--;
+ aopPut(AOP(result), "a", 0);
+ freeAsmop(result, NULL, ic, FALSE);
+ return;
+ }
+
+ /* See if we've got an underlying symbol to abuse. */
+ if (IS_SYMOP(result) && OP_SYMBOL(result))
+ {
+ if (IS_TRUE_SYMOP(result))
+ {
+ rSym = OP_SYMBOL(result);
+ }
+ else if (IS_ITEMP(result) && OP_SYMBOL(result)->isspilt && OP_SYMBOL(result)->usl.spillLoc)
+ {
+ rSym = OP_SYMBOL(result)->usl.spillLoc;
+ }
+ }
+
+ if (size > 1 && rSym && rSym->rname && !rSym->onStack)
+ {
+ /* We can use the '390 auto-toggle feature to good effect here. */
+
+ 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. */
+ while (size)
+ {
+ emitcode("movx", "a,@dptr");
+ emitcode("movx", "@dptr,a");
+ if (--size)
+ {
+ emitcode("inc", "dptr");
+ emitcode("inc", "dptr");
+ }
+ }
+ 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
+ {
+ D (emitcode (";", "genFarFarAssign"););
aopOp (result, ic, TRUE, TRUE);
_startLazyDPSEvaluation ();
+
while (size--)
{
aopPut (AOP (result),
_endLazyDPSEvaluation ();
freeAsmop (result, NULL, ic, FALSE);
freeAsmop (right, NULL, ic, FALSE);
- }
- else
- {
- D (emitcode (";", "genFarFarAssign ");
- );
-
- /* first push the right side on to the stack */
- _startLazyDPSEvaluation ();
- while (size--)
- {
- l = aopGet (AOP (right), offset++, FALSE, FALSE, TRUE);
- MOVA (l);
- emitcode ("push", "acc");
- }
-
- freeAsmop (right, NULL, ic, FALSE);
- /* now assign DPTR to result */
- aopOp (result, ic, FALSE, FALSE);
- size = AOP_SIZE (result);
- while (size--)
- {
- emitcode ("pop", "acc");
- aopPut (AOP (result), "a", --offset);
- }
- freeAsmop (result, NULL, ic, FALSE);
- _endLazyDPSEvaluation ();
- }
+ }
}
/*-----------------------------------------------------------------*/
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)
(AOP_TYPE (right) == AOP_LIT) &&
!IS_FLOAT (operandType (right)))
{
- D (emitcode (";", "Kevin's better literal load code");
- );
_startLazyDPSEvaluation ();
while (size && ((unsigned int) (lit >> (offset * 8)) != 0))
{
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 */
break;
case GET_VALUE_AT_ADDRESS:
- genPointerGet (ic);
+ genPointerGet (ic,hasInc(IC_LEFT(ic),ic));
break;
case '=':
if (POINTER_SET (ic))
- genPointerSet (ic);
+ genPointerSet (ic,hasInc(IC_RESULT(ic),ic));
else
genAssign (ic);
break;
addSet (&_G.sendSet, ic);
break;
+ case ARRAYINIT:
+ genArrayInit(ic);
+ break;
+
default:
ic = ic;
}