/*-------------------------------------------------------------------------
- gen.c - source file for code generation for 8051
+ gen.c - source file for code generation for DS80C390
Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
and - Jean-Louis VERN.jlvern@writeme.com (1999)
In other words, you are welcome to use, share and improve this program.
You are forbidden to forbid anyone else to use, share and improve
what you give them. Help stamp out software-hoarding!
-
- Notes:
- 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
- Made everything static
-------------------------------------------------------------------------*/
#include <stdio.h>
#endif
char *aopLiteral (value * val, int offset);
-#if 0
-//REMOVE ME!!!
-extern int allocInfo;
-#endif
/* this is the down and dirty file with all kinds of
kludgy & hacky stuff. This is what it is all about
#define D(x) x
-unsigned fReturnSize_390 = 5; /* shared with ralloc.c */
+unsigned fReturnSizeDS390 = 5; /* shared with ralloc.c */
static char *fReturn[] =
{"dpl", "dph", "dpx", "b", "a"};
static char *accUse[] =
#define CLRC emitcode("clr","c")
#define SETC emitcode("setb","c")
+// A scratch register which will be used to hold
+// result bytes from operands in far space via DPTR2.
+#define DP2_RESULT_REG "ap"
+
static lineNode *lineHead = NULL;
static lineNode *lineCurr = NULL;
return NULL;
}
- piCode (ic, stdout);
/* other wise this is true end of the world */
werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
"getFreePtr should never reach here");
aop = op->aop = sym->aop = newAsmop (AOP_STR);
aop->size = getSize (sym->type);
- for (i = 0; i < (int) fReturnSize_390; i++)
+ for (i = 0; i < (int) fReturnSizeDS390; i++)
aop->aopu.aop_str[i] = fReturn[i];
return;
}
/*------------------------------------------------------------------*/
/* aopGet - for fetching value of the aop */
/* */
-/* Set canClobberACC if you are aure it is OK to clobber the value */
+/* Set canClobberACC if you are sure it is OK to clobber the value */
/* in the accumulator. Set it FALSE otherwise; FALSE is always safe, */
/* just less efficient. */
/*------------------------------------------------------------------*/
if (aop->type == AOP_DPTR2)
{
genSetDPTR (1);
-
if (!canClobberACC)
{
- emitcode ("xch", "a, ap");
+ emitcode ("xch", "a, %s", DP2_RESULT_REG);
}
}
if (aop->type == AOP_DPTR2)
{
genSetDPTR (0);
-
if (!canClobberACC)
{
- emitcode ("xch", "a, ap");
- return "ap";
+ emitcode ("xch", "a, %s", DP2_RESULT_REG);
+ return DP2_RESULT_REG;
}
}
-
return (dname ? "acc" : "a");
case AOP_IMMD:
aopPut (asmop * aop, char *s, int offset)
{
char *d = buffer;
- symbol *lbl;
if (aop->size && offset > (aop->size - 1))
{
emitcode ("mov", "%s,c", aop->aopu.aop_dir);
else
{
- lbl = newiTempLabel (NULL);
-
if (strcmp (s, "a"))
{
MOVA (s);
}
- emitcode ("clr", "c");
- emitcode ("jz", "%05d$", lbl->key + 100);
- emitcode ("cpl", "c");
- emitcode ("", "%05d$:", lbl->key + 100);
- emitcode ("mov", "%s,c", aop->aopu.aop_dir);
+ {
+ symbol *lbl = newiTempLabel (NULL);
+ emitcode ("clr", "c");
+ emitcode ("jz", "%05d$", lbl->key + 100);
+ emitcode ("cpl", "c");
+ emitcode ("", "%05d$:", lbl->key + 100);
+ emitcode ("mov", "%s,c", aop->aopu.aop_dir);
+ }
}
}
break;
}
-/*-----------------------------------------------------------------*/
-/* reAdjustPreg - points a register back to where it should */
-/*-----------------------------------------------------------------*/
+/*--------------------------------------------------------------------*/
+/* reAdjustPreg - points a register back to where it should (coff==0) */
+/*--------------------------------------------------------------------*/
static void
reAdjustPreg (asmop * aop)
{
- int size;
-
- aop->coff = 0;
- if ((size = aop->size) <= 1)
+ if ((aop->coff==0) || (aop->size <= 1)) {
return;
- size--;
+ }
+
switch (aop->type)
{
case AOP_R0:
case AOP_R1:
- while (size--)
+ while (aop->coff--)
emitcode ("dec", "%s", aop->aopu.aop_ptr->name);
break;
case AOP_DPTR:
genSetDPTR (1);
_flushLazyDPS ();
}
- while (size--)
+ while (aop->coff--)
{
emitcode ("lcall", "__decdptr");
}
break;
}
-
+ aop->coff=0;
}
#define AOP(op) op->aop
offset++, FALSE, FALSE, FALSE));
}
_endLazyDPSEvaluation ();
- tlbl = newiTempLabel (NULL);
tlbl = newiTempLabel (NULL);
aopPut (res->aop, one, 1);
for (i = 0; i < ds390_nRegs; i++)
{
if (bitVectBitValue (rsave, i))
- emitcode ("push", "%s", ds390_regWithIdx (i)->dname);
+ emitcode ("push", "%s ;jwk saveRegisters", ds390_regWithIdx (i)->dname);
}
detype = getSpec (operandType (IC_LEFT (ic)));
for (i = ds390_nRegs; i >= 0; i--)
{
if (bitVectBitValue (rsave, i))
- emitcode ("pop", "%s", ds390_regWithIdx (i)->dname);
+ emitcode ("pop", "%s ;jwk unsaveRegisters", ds390_regWithIdx (i)->dname);
}
}
D (emitcode (";", "genIpush ");
);
-
/* if this is not a parm push : ie. it is spill push
and spill push is always done on the local stack */
if (!ic->parmPush)
MOVA (l);
l = "acc";
}
- emitcode ("push", "%s", l);
+ emitcode ("push", "%s ;jwk genIpush: !parm", l);
}
_endLazyDPSEvaluation ();
return;
emitcode ("push", "acc");
}
else
- emitcode ("push", "%s", l);
+ emitcode ("push", "%s ;jwk genIpush", l);
}
_endLazyDPSEvaluation ();
_startLazyDPSEvaluation ();
while (size--)
{
- emitcode ("pop", "%s", aopGet (AOP (IC_LEFT (ic)), offset--,
+ emitcode ("pop", "%s ;jwk genIpop", aopGet (AOP (IC_LEFT (ic)), offset--,
FALSE, TRUE, TRUE));
}
_endLazyDPSEvaluation ();
/* adjust the stack for parameters if
required */
- if (IC_LEFT (ic)->parmBytes)
+ if (ic->parmBytes)
{
int i;
- if (IC_LEFT (ic)->parmBytes > 3)
+ if (ic->parmBytes > 3)
{
emitcode ("mov", "a,%s", spname);
- emitcode ("add", "a,#0x%02x", (-IC_LEFT (ic)->parmBytes) & 0xff);
+ emitcode ("add", "a,#0x%02x", (-ic->parmBytes) & 0xff);
emitcode ("mov", "%s,a", spname);
}
else
- for (i = 0; i < IC_LEFT (ic)->parmBytes; i++)
+ for (i = 0; i < ic->parmBytes; i++)
emitcode ("dec", "%s", spname);
}
/* adjust the stack for parameters if
required */
- if (IC_LEFT (ic)->parmBytes)
+ if (ic->parmBytes)
{
int i;
- if (IC_LEFT (ic)->parmBytes > 3)
+ if (ic->parmBytes > 3)
{
emitcode ("mov", "a,%s", spname);
- emitcode ("add", "a,#0x%02x", (-IC_LEFT (ic)->parmBytes) & 0xff);
+ emitcode ("add", "a,#0x%02x", (-ic->parmBytes) & 0xff);
emitcode ("mov", "%s,a", spname);
}
else
- for (i = 0; i < IC_LEFT (ic)->parmBytes; i++)
+ for (i = 0; i < ic->parmBytes; i++)
emitcode ("dec", "%s", spname);
}
emitcode ("push", "dpl1");
emitcode ("push", "dph1");
emitcode ("push", "dpx1");
- emitcode ("push", "ap");
+ emitcode ("push", DP2_RESULT_REG);
}
}
/* if this isr has no bank i.e. is going to
{
if (options.stack10bit)
{
- emitcode ("pop", "ap");
+ emitcode ("pop", DP2_RESULT_REG);
emitcode ("pop", "dpx1");
emitcode ("pop", "dph1");
emitcode ("pop", "dpl1");
}
}
+// 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) \
aopOp (IC_RIGHT(ic),ic,FALSE, FALSE); \
aopOp (IC_LEFT(ic),ic,FALSE, (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR)); \
"Ack: three operands in far space! (%s:%d %s:%d)\n", __FILE__, __LINE__, ic->filename, ic->lineno); \
}
+// 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
+// will be set TRUE. The caller must then handle the case specially, noting
+// 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 the left & right operands of an ic.
#define AOP_OP_2(ic) \
aopOp (IC_RIGHT(ic),ic,FALSE, FALSE); \
aopOp (IC_LEFT(ic),ic,FALSE, (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR));
+// convienience macro.
#define AOP_SET_LOCALS(ic) \
left = IC_LEFT(ic); \
right = IC_RIGHT(ic); \
result = IC_RESULT(ic);
+
+// Given an integer value of pushedSize bytes on the stack,
+// adjust it to be resultSize bytes, either by discarding
+// the most significant bytes or by zero-padding.
+//
+// On exit from this macro, pushedSize will have been adjusted to
+// equal resultSize, and ACC may be trashed.
+#define ADJUST_PUSHED_RESULT(pushedSize, resultSize) \
+ /* If the pushed data is bigger than the result, \
+ * simply discard unused bytes. Icky, but works. \
+ */ \
+ while (pushedSize > resultSize) \
+ { \
+ D (emitcode (";", "discarding unused result byte."););\
+ emitcode ("pop", "acc"); \
+ pushedSize--; \
+ } \
+ if (pushedSize < resultSize) \
+ { \
+ emitcode ("clr", "a"); \
+ /* Conversly, we haven't pushed enough here. \
+ * just zero-pad, and all is well. \
+ */ \
+ while (pushedSize < resultSize) \
+ { \
+ emitcode("push", "acc"); \
+ pushedSize++; \
+ } \
+ } \
+ assert(pushedSize == resultSize);
+
/*-----------------------------------------------------------------*/
/* genPlus - generates code for addition */
/*-----------------------------------------------------------------*/
bool pushResult = FALSE;
int rSize;
- D (emitcode (";", "genPlus ");
- );
+ D (emitcode (";", "genPlus "););
/* special cases :- */
AOP_OP_3_NOFATAL (ic, pushResult);
if (pushResult)
{
- D (emitcode (";", "genPlus: must push result: 3 ops in far space");
- );
+ D (emitcode (";", "genPlus: must push result: 3 ops in far space"););
}
if (!pushResult)
size = getDataSize (IC_LEFT (ic));
rSize = getDataSize (IC_RESULT (ic));
- /* If the pushed data is bigger than the result,
- * simply discard unused bytes. Icky, but works.
- *
- * Should we throw a warning here? We're losing data...
- */
- while (size > rSize)
- {
- D (emitcode (";", "discarding unused result byte.");
- );
- emitcode ("pop", "acc");
- size--;
- offset--;
- }
- if (size < rSize)
- {
- emitcode ("clr", "a");
- /* Conversly, we haven't pushed enough here.
- * just zero-pad, and all is well.
- */
- while (size < rSize)
- {
- emitcode ("push", "acc");
- size++;
- offset++;
- }
- }
+ ADJUST_PUSHED_RESULT(size, rSize);
_startLazyDPSEvaluation ();
while (size--)
{
emitcode ("pop", "acc");
- aopPut (AOP (IC_RESULT (ic)), "a", --offset);
+ aopPut (AOP (IC_RESULT (ic)), "a", size);
}
_endLazyDPSEvaluation ();
}
unsigned long lit = 0L;
bool pushResult = FALSE;
- D (emitcode (";", "genMinus ");
- );
+ D (emitcode (";", "genMinus "););
aopOp (IC_LEFT (ic), ic, FALSE, FALSE);
aopOp (IC_RIGHT (ic), ic, FALSE, TRUE);
size = getDataSize (IC_LEFT (ic));
rSize = getDataSize (IC_RESULT (ic));
- /* If the pushed data is bigger than the result,
- * simply discard unused bytes. Icky, but works.
- *
- * Should we throw a warning here? We're losing data...
- */
- while (size > getDataSize (IC_RESULT (ic)))
- {
- emitcode (";", "discarding unused result byte.");
- emitcode ("pop", "acc");
- size--;
- offset--;
- }
- if (size < rSize)
- {
- emitcode ("clr", "a");
- /* Conversly, we haven't pushed enough here.
- * just zero-pad, and all is well.
- */
- while (size < rSize)
- {
- emitcode ("push", "acc");
- size++;
- offset++;
- }
- }
+ ADJUST_PUSHED_RESULT(size, rSize);
+ _startLazyDPSEvaluation ();
while (size--)
{
emitcode ("pop", "acc");
- aopPut (AOP (IC_RESULT (ic)), "a", --offset);
+ aopPut (AOP (IC_RESULT (ic)), "a", size);
}
+ _endLazyDPSEvaluation ();
}
adjustArithmeticResult (ic);
/*-----------------------------------------------------------------*/
-/* genMultOneByte : 8 bit multiplication & division */
+/* genMultOneByte : 8*8=8/16 bit multiplication */
/*-----------------------------------------------------------------*/
static void
genMultOneByte (operand * left,
operand * result)
{
sym_link *opetype = operandType (result);
- char *l;
symbol *lbl;
- int size, offset;
+ 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 two literals: the value is computed before) */
/* if one literal, literal on the right */
if (AOP_TYPE (left) == AOP_LIT)
{
operand *t = right;
right = left;
left = t;
+ emitcode (";", "swapped left and right");
+ }
+
+ if (SPEC_USIGN(opetype)
+ // ignore the sign of left and right, what else can we do?
+ || (SPEC_USIGN(operandType(left)) &&
+ SPEC_USIGN(operandType(right)))) {
+ // just an unsigned 8*8=8/16 multiply
+ //emitcode (";","unsigned");
+ emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE, TRUE));
+ MOVA (aopGet (AOP (left), 0, FALSE, FALSE, TRUE));
+ emitcode ("mul", "ab");
+ aopPut (AOP (result), "a", 0);
+ if (size==2) {
+ aopPut (AOP (result), "b", 1);
}
+ return;
+ }
- size = AOP_SIZE (result);
- /* signed or unsigned */
- emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE, FALSE));
- l = aopGet (AOP (left), 0, FALSE, FALSE, TRUE);
- MOVA (l);
- emitcode ("mul", "ab");
- /* if result size = 1, mul signed = mul unsigned */
- aopPut (AOP (result), "a", 0);
- if (size > 1)
- {
- if (SPEC_USIGN (opetype))
- {
- aopPut (AOP (result), "b", 1);
- if (size > 2)
- /* for filling the MSBs */
- emitcode ("clr", "a");
- }
- else
- {
- emitcode ("mov", "a,b");
+ // we have to do a signed multiply
- /* adjust the MSB if left or right neg */
+ 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));
- /* if one literal */
- if (AOP_TYPE (right) == AOP_LIT)
- {
- /* AND literal negative */
- if ((int) floatFromVal (AOP (right)->aopu.aop_lit) < 0)
- {
- /* adjust MSB (c==0 after mul) */
- emitcode ("subb", "a,%s", aopGet (AOP (left), 0, FALSE, FALSE, FALSE));
- }
- }
- else
- {
- lbl = newiTempLabel (NULL);
- emitcode ("xch", "a,%s", aopGet (AOP (right), 0, FALSE, FALSE, FALSE));
- emitcode ("cjne", "a,#0x80,%05d$", (lbl->key + 100));
- emitcode ("", "%05d$:", (lbl->key + 100));
- emitcode ("xch", "a,%s", aopGet (AOP (right), 0, FALSE, FALSE, FALSE));
- lbl = newiTempLabel (NULL);
- emitcode ("jc", "%05d$", (lbl->key + 100));
- emitcode ("subb", "a,%s", aopGet (AOP (left), 0, FALSE, FALSE, FALSE));
- emitcode ("", "%05d$:", (lbl->key + 100));
- }
+ lbl=newiTempLabel(NULL);
+ emitcode ("jnb", "acc.7,%05d$", lbl->key+100);
+ // left side is negative, 8-bit two's complement, this fails for -128
+ emitcode ("setb", "F0"); // set sign flag
+ emitcode ("cpl", "a");
+ emitcode ("inc", "a");
- lbl = newiTempLabel (NULL);
- emitcode ("xch", "a,%s", aopGet (AOP (left), 0, FALSE, FALSE, FALSE));
- emitcode ("cjne", "a,#0x80,%05d$", (lbl->key + 100));
- emitcode ("", "%05d$:", (lbl->key + 100));
- emitcode ("xch", "a,%s", aopGet (AOP (left), 0, FALSE, FALSE, FALSE));
- lbl = newiTempLabel (NULL);
- emitcode ("jc", "%05d$", (lbl->key + 100));
- emitcode ("subb", "a,%s", aopGet (AOP (right), 0, FALSE, FALSE, FALSE));
- emitcode ("", "%05d$:", (lbl->key + 100));
+ emitcode ("", "%05d$:", lbl->key+100);
+ emitcode ("xch", "a,b");
- aopPut (AOP (result), "a", 1);
- if (size > 2)
- {
- /* get the sign */
- emitcode ("rlc", "a");
- emitcode ("subb", "a,acc");
- }
- }
- size -= 2;
- offset = 2;
- if (size > 0)
- while (size--)
- aopPut (AOP (result), "a", offset++);
+ /* if literal */
+ if (AOP_TYPE(right)==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");
}
+ } else {
+ lbl=newiTempLabel(NULL);
+ 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", "a");
+ emitcode ("inc", "a");
+ emitcode ("", "%05d$:", lbl->key+100);
+ }
+ emitcode ("mul", "ab");
+
+ 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) {
+ emitcode ("inc", "a");
+ } else {
+ emitcode ("add", "a,#1");
+ emitcode ("xch", "a,b");
+ emitcode ("cpl", "a"); // msb
+ emitcode ("addc", "a,#0");
+ emitcode ("xch", "a,b");
+ }
+
+ emitcode ("", "%05d$:", lbl->key+100);
+ aopPut (AOP (result), "a", 0);
+ if (size==2) {
+ aopPut (AOP (result), "b", 1);
+ }
}
/*-----------------------------------------------------------------*/
operand *right = IC_RIGHT (ic);
operand *result = IC_RESULT (ic);
- D (emitcode (";", "genMult ");
- );
+ D (emitcode (";", "genMult "););
/* assign the amsops */
AOP_OP_3 (ic);
operand *left, *right, *result;
symbol *tlbl;
- D (emitcode (";", "genAndOp ");
- );
+ D (emitcode (";", "genAndOp "););
/* note here that && operations that are in an
if statement are taken away by backPatchLabels
only those used in arthmetic operations remain */
- AOP_OP_3 (ic);
+ AOP_OP_2 (ic);
AOP_SET_LOCALS (ic);
/* if both are bit variables */
{
emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
emitcode ("anl", "c,%s", AOP (right)->aopu.aop_dir);
+ freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+
+ aopOp (result,ic,FALSE, FALSE);
outBitC (result);
}
else
emitcode ("jz", "%05d$", tlbl->key + 100);
toBoolean (right);
emitcode ("", "%05d$:", tlbl->key + 100);
+ freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+
+ aopOp (result,ic,FALSE, FALSE);
outBitAcc (result);
}
-
- freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
- freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
- freeAsmop (result, NULL, ic, TRUE);
+ freeAsmop (result, NULL, ic, TRUE);
}
operand *left, *right, *result;
symbol *tlbl;
- D (emitcode (";", "genOrOp ");
- );
+ D (emitcode (";", "genOrOp "););
/* note here that || operations that are in an
if statement are taken away by backPatchLabels
only those used in arthmetic operations remain */
- AOP_OP_3 (ic);
+ AOP_OP_2 (ic);
AOP_SET_LOCALS (ic);
/* if both are bit variables */
{
emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
emitcode ("orl", "c,%s", AOP (right)->aopu.aop_dir);
+ freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+
+ aopOp (result,ic,FALSE, FALSE);
+
outBitC (result);
}
else
emitcode ("jnz", "%05d$", tlbl->key + 100);
toBoolean (right);
emitcode ("", "%05d$:", tlbl->key + 100);
+ freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+
+ aopOp (result,ic,FALSE, FALSE);
+
outBitAcc (result);
}
- freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
- freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
freeAsmop (result, NULL, ic, TRUE);
}
ic->generated = 1;
}
+// Generate code to perform a bit-wise logic operation
+// on two operands in far space (assumed to already have been
+// aopOp'd by the AOP_OP_3_NOFATAL macro), storing the result
+// in far space. This requires pushing the result on the stack
+// then popping it into the result.
+static void
+genFarFarLogicOp(iCode *ic, char *logicOp)
+{
+ int size, resultSize, compSize;
+ int offset = 0;
+
+ 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));
+
+ _startLazyDPSEvaluation();
+ for (size = compSize; (size--); offset++)
+ {
+ MOVA (aopGet (AOP (IC_LEFT(ic)), offset, FALSE, FALSE, TRUE));
+ emitcode ("mov", "%s, acc", DP2_RESULT_REG);
+ MOVA (aopGet (AOP (IC_RIGHT(ic)), offset, FALSE, FALSE, TRUE));
+
+ emitcode (logicOp, "a,%s", DP2_RESULT_REG);
+ emitcode ("push", "acc");
+ }
+ _endLazyDPSEvaluation();
+
+ freeAsmop (IC_LEFT(ic), NULL, ic, RESULTONSTACK (ic) ? FALSE : TRUE);
+ freeAsmop (IC_RIGHT(ic), NULL, ic, RESULTONSTACK (ic) ? FALSE : TRUE);
+ aopOp (IC_RESULT(ic),ic,TRUE, FALSE);
+
+ resultSize = AOP_SIZE(IC_RESULT(ic));
+
+ ADJUST_PUSHED_RESULT(compSize, resultSize);
+
+ _startLazyDPSEvaluation();
+ while (compSize--)
+ {
+ emitcode ("pop", "acc");
+ aopPut (AOP (IC_RESULT (ic)), "a", compSize);
+ }
+ _endLazyDPSEvaluation();
+ freeAsmop(IC_RESULT (ic), NULL, ic, TRUE);
+}
+
+
/*-----------------------------------------------------------------*/
/* genAnd - code for and */
/*-----------------------------------------------------------------*/
unsigned long lit = 0L;
int bytelit = 0;
char buffer[10];
+ bool pushResult;
- D (emitcode (";", "genAnd ");
- );
+ D (emitcode (";", "genAnd "););
- AOP_OP_3 (ic);
+ AOP_OP_3_NOFATAL (ic, pushResult);
AOP_SET_LOCALS (ic);
+ if (pushResult)
+ {
+ genFarFarLogicOp(ic, "anl");
+ return;
+ }
+
#ifdef DEBUG_TYPE
emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
AOP_TYPE (result),
freeAsmop (result, NULL, ic, TRUE);
}
+
/*-----------------------------------------------------------------*/
/* genOr - code for or */
/*-----------------------------------------------------------------*/
operand *left, *right, *result;
int size, offset = 0;
unsigned long lit = 0L;
+ bool pushResult;
- D (emitcode (";", "genOr ");
- );
+ D (emitcode (";", "genOr "););
- AOP_OP_3 (ic);
+ AOP_OP_3_NOFATAL (ic, pushResult);
AOP_SET_LOCALS (ic);
+ if (pushResult)
+ {
+ genFarFarLogicOp(ic, "orl");
+ return;
+ }
+
+
#ifdef DEBUG_TYPE
emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
AOP_TYPE (result),
operand *left, *right, *result;
int size, offset = 0;
unsigned long lit = 0L;
+ bool pushResult;
- D (emitcode (";", "genXor ");
- );
+ D (emitcode (";", "genXor "););
- AOP_OP_3 (ic);
+ AOP_OP_3_NOFATAL (ic, pushResult);
AOP_SET_LOCALS (ic);
+ if (pushResult)
+ {
+ genFarFarLogicOp(ic, "xrl");
+ return;
+ }
+
#ifdef DEBUG_TYPE
emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
AOP_TYPE (result),
break;
case 6: // AAAAAABB:CCCCCCDD
-
emitcode ("anl", "a,#0x%02x",
SRMask[shCount]); // 000000BB:CCCCCCDD
-
emitcode ("mov", "c,acc.0"); // c = B
-
emitcode ("xch", "a,%s", x); // CCCCCCDD:000000BB
-
+#if 0
AccAXRrl1 (x); // BCCCCCCD:D000000B
-
AccAXRrl1 (x); // BBCCCCCC:DD000000
-
+#else
+ emitcode("rrc","a");
+ emitcode("xch","a,%s", x);
+ emitcode("rrc","a");
+ emitcode("mov","c,acc.0"); //<< get correct bit
+ emitcode("xch","a,%s", x);
+
+ emitcode("rrc","a");
+ emitcode("xch","a,%s", x);
+ emitcode("rrc","a");
+ emitcode("xch","a,%s", x);
+#endif
break;
case 7: // a:x <<= 7
movLeft2Result (left, LSB, result, MSB32, 0);
aopPut (AOP (result), zero, LSB);
aopPut (AOP (result), zero, MSB16);
- aopPut (AOP (result), zero, MSB32);
+ aopPut (AOP (result), zero, MSB24);
return;
}
l=aopGet(AOP(left),0,FALSE,FALSE,TRUE);
genSetDPTR(0);
_flushLazyDPS();
- emitcode ("mov", "dpl,%s", l);
+ emitcode ("mov", "dpl,%s ;jwk lazy genGenPointerGet", l);
l=aopGet(AOP(left),1,FALSE,FALSE,TRUE);
genSetDPTR(0);
_flushLazyDPS();
- emitcode ("mov", "dph,%s", l);
+ emitcode ("mov", "dph,%s ;jwk lazy genGenPointerGet", l);
l=aopGet(AOP(left),2,FALSE,FALSE,TRUE);
genSetDPTR(0);
_flushLazyDPS();
- emitcode ("mov", "dpx,%s", l);
+ emitcode ("mov", "dpx,%s ;jwk lazy genGenPointerGet", l);
emitcode ("mov", "b,%s", aopGet (AOP(left),3,FALSE,FALSE,TRUE));
} else {
emitcode ("mov", "dpl,%s", aopGet (AOP(left),0,FALSE,FALSE,TRUE));
}
else
{
- emitcode ("djnz", "%s,%05d$", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE, FALSE),
+ emitcode ("djnz", "%s,%05d$", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, TRUE, FALSE),
lbl->key + 100);
}
emitcode ("sjmp", "%05d$", lbl1->key + 100);
IS_TRUE_SYMOP (IC_RESULT (ic))))
{
int size = getSize (operandType (IC_RESULT (ic)));
- int offset = fReturnSize_390 - size;
+ int offset = fReturnSizeDS390 - size;
while (size--)
{
- emitcode ("push", "%s", (strcmp (fReturn[fReturnSize_390 - offset - 1], "a") ?
- fReturn[fReturnSize_390 - offset - 1] : "acc"));
+ emitcode ("push", "%s", (strcmp (fReturn[fReturnSizeDS390 - offset - 1], "a") ?
+ fReturn[fReturnSizeDS390 - offset - 1] : "acc"));
offset++;
}
aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
default:
ic = ic;
- /* piCode(ic,stdout); */
-
}
}