static char **fReturn = fReturn24;
static char *accUse[] =
{"a", "b"};
+static char *dptrn[2][3];
static char *javaRet[] = { "r0","r1","r2","r3"};
static short rbank = -1;
}
_G;
+static char *rb1regs[] = {
+ "b1_0","b1_1","b1_2","b1_3","b1_4","b1_5","b1_6","b1_7"
+};
+
static void saveRBank (int, iCode *, bool);
#define RESULTONSTACK(x) \
#define MSB16 1
#define MSB24 2
#define MSB32 3
+#define PROTECT_SP {if (options.protect_sp_update) { \
+ symbol *lbl = newiTempLabel(NULL); \
+ emitcode ("setb","F1"); \
+ emitcode ("jbc","EA,!tlabel",lbl->key+100); \
+ emitcode ("clr","F1"); \
+ emitcode ("","!tlabeldef",lbl->key+100); \
+ }}
+#define UNPROTECT_SP { if (options.protect_sp_update) { \
+ symbol *lbl = newiTempLabel(NULL); \
+ emitcode ("jnb","F1,!tlabel",lbl->key+100); \
+ emitcode ("setb","EA"); \
+ emitcode ("","!tlabeldef",lbl->key+100); \
+ }}
+
/*-----------------------------------------------------------------*/
/* emitcode - writes the code into a file : for now it is simple */
/* It's on the 10 bit stack, which is located in
* far data space.
*/
- if (stack_val < 0 && stack_val > -3) { /* between -3 & -1 */
+ if (stack_val < 0 && stack_val > -5) { /* between -5 & -1 */
if (useDP2) {
if (options.model == MODEL_FLAT24)
emitcode ("mov", "dpx1,#!constbyte", (options.stack_loc >> 16) & 0xff);
aop->size = FPTRSIZE;
return aop;
}
-
+
/* only remaining is far space */
/* in which case DPTR gets the address */
sym->aop = aop = newAsmop ((short) (useDP2 ? AOP_DPTR2 : AOP_DPTR));
OP_SYMBOL (IC_LEFT (ic))->rname,
val >= 0 ? '+' : '-',
abs (val) & 0xffff);
- else
- strcpy (buffer, OP_SYMBOL (IC_LEFT (ic))->rname);
+ else {
+ if (IS_ASSIGN_ICODE(ic) && isOperandLiteral(IC_RIGHT(ic)))
+ sprintf(buffer,"0x%x",(int) operandLitValue (IC_RIGHT (ic)));
+ else
+ strcpy (buffer, OP_SYMBOL (IC_LEFT (ic))->rname);
+ }
aop->aopu.aop_immd.aop_immd1 = Safe_calloc (1, strlen (buffer) + 1);
strcpy (aop->aopu.aop_immd.aop_immd1, buffer);
/* 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! for operand %s\n",sym->name);
+ werror(E_INTERNAL_ERROR,__FILE__,__LINE__,"AOP_STR with DPTR in use!");
}
aop = op->aop = sym->aop = newAsmop (AOP_STR);
aop->aopu.aop_str[i] = fReturn[i];
return;
}
-
+
+ if (sym->dptr) { /* has been allocated to a DPTRn */
+ aop = op->aop = sym->aop = newAsmop (AOP_DPTRn);
+ aop->size = getSize (sym->type);
+ aop->aopu.dptr = sym->dptr;
+ return ;
+ }
/* else spill location */
if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
/* force a new aop if sizes differ */
strcpy (rs, s);
return rs;
+ case AOP_DPTRn:
+ assert(offset <= 3);
+ return dptrn[aop->aopu.dptr][offset];
+
case AOP_DPTR:
case AOP_DPTR2:
}
break;
+ case AOP_DPTRn:
+ emitcode ("mov","%s,%s",dptrn[aop->aopu.dptr][offset],s);
+ break;
+
case AOP_DPTR:
case AOP_DPTR2:
#define AOP_INPREG(x) (x && (x->type == AOP_REG && \
(x->aopu.aop_reg[0] == ds390_regWithIdx(R0_IDX) || \
x->aopu.aop_reg[0] == ds390_regWithIdx(R1_IDX) )))
+#define AOP_INDPTRn(x) (AOP_TYPE(x) == AOP_DPTRn)
+#define AOP_USESDPTR(x) (AOP_TYPE(x) == AOP_DPTR || AOP_TYPE(x) == AOP_STR)
/* Workaround for DS80C390 bug: div ab may return bogus results
* if A is accessed in instruction immediately before the div.
}
}
+/*-----------------------------------------------------------------*/
+/* genSend - gen code for SEND */
+/*-----------------------------------------------------------------*/
+static void genSend(set *sendSet)
+{
+ iCode *sic;
+ int sendCount = 0 ;
+ static int rb1_count = 0;
+
+ for (sic = setFirstItem (sendSet); sic;
+ sic = setNextItem (sendSet)) {
+ int size, offset = 0;
+
+ size=getSize(operandType(IC_LEFT(sic)));
+ D (emitcode (";", "genSend argreg = %d, size = %d ",sic->argreg,size));
+ if (sendCount == 0) { /* first parameter */
+ // we know that dpl(hxb) is the result, so
+ rb1_count = 0 ;
+ _startLazyDPSEvaluation ();
+ if (size>1) {
+ aopOp (IC_LEFT (sic), sic, FALSE,
+ (IS_SYMOP(IC_LEFT(sic)) && OP_SYMBOL(IC_LEFT(sic))->ruonly ? 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 ();
+ freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
+ rb1_count =0;
+ } else { /* if more parameter in registers */
+ aopOp (IC_LEFT (sic), sic, FALSE, TRUE);
+ while (size--) {
+ emitcode ("mov","b1_%d,%s",rb1_count++,aopGet (AOP (IC_LEFT (sic)), offset++,
+ FALSE, FALSE, TRUE));
+ }
+ freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
+ }
+ sendCount++;
+ }
+}
+
/*-----------------------------------------------------------------*/
/* genCall - generates a call statement */
/*-----------------------------------------------------------------*/
*/
if (_G.sendSet)
{
- iCode *sic;
-
- for (sic = setFirstItem (_G.sendSet); sic;
- sic = setNextItem (_G.sendSet))
- {
- int size, offset = 0;
-
- // 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,
- (IS_SYMOP(IC_LEFT(sic)) && OP_SYMBOL(IC_LEFT(sic))->ruonly ? 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 ();
- freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
+ if (IFFUNC_ISREENT(dtype)) { /* need to reverse the send set */
+ genSend(reverseSet(_G.sendSet));
+ } else {
+ genSend(_G.sendSet);
}
_G.sendSet = NULL;
}
if (ic->parmBytes) {
int i;
if (options.stack10bit) {
- if (ic->parmBytes <= 4) {
+ if (ic->parmBytes <= 10) {
emitcode(";","stack adjustment for parms");
for (i=0; i < ic->parmBytes ; i++) {
emitcode("pop","acc");
}
- } else {
+ } else {
+ PROTECT_SP;
emitcode ("clr","c");
emitcode ("mov","a,sp");
emitcode ("subb","a,#!constbyte",ic->parmBytes & 0xff);
emitcode ("mov","sp,a");
emitcode ("mov","a,esp");
+ emitcode ("anl","a,#3");
emitcode ("subb","a,#!constbyte",(ic->parmBytes >> 8) & 0xff);
emitcode ("mov","esp,a");
+ UNPROTECT_SP;
}
} else {
if (ic->parmBytes > 3) {
/* if send set is not empty the assign */
if (_G.sendSet)
{
- iCode *sic;
-
- for (sic = setFirstItem (_G.sendSet); sic;
- sic = setNextItem (_G.sendSet))
- {
- int size, offset = 0;
-
- // 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 ();
- freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
- }
- _G.sendSet = NULL;
+ genSend(reverseSet(_G.sendSet));
+ _G.sendSet = NULL;
}
emitcode ("ret", "");
if (ic->parmBytes)
{
int i;
- if (ic->parmBytes > 3)
- {
- emitcode ("mov", "a,%s", spname);
- emitcode ("add", "a,#!constbyte", (-ic->parmBytes) & 0xff);
- emitcode ("mov", "%s,a", spname);
- }
- else
- for (i = 0; i < ic->parmBytes; i++)
- emitcode ("dec", "%s", spname);
-
+ if (options.stack10bit) {
+ if (ic->parmBytes <= 10) {
+ emitcode(";","stack adjustment for parms");
+ for (i=0; i < ic->parmBytes ; i++) {
+ emitcode("pop","acc");
+ }
+ } else {
+ PROTECT_SP;
+ emitcode ("clr","c");
+ emitcode ("mov","a,sp");
+ emitcode ("subb","a,#!constbyte",ic->parmBytes & 0xff);
+ emitcode ("mov","sp,a");
+ emitcode ("mov","a,esp");
+ emitcode ("anl","a,#3");
+ emitcode ("subb","a,#!constbyte",(ic->parmBytes >> 8) & 0xff);
+ emitcode ("mov","esp,a");
+ UNPROTECT_SP;
+ }
+ } else {
+ if (ic->parmBytes > 3) {
+ emitcode ("mov", "a,%s", spname);
+ emitcode ("add", "a,#!constbyte", (-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 unsave them */
if (restoreBank)
unsaveRBank (FUNC_REGBANK (dtype), ic, TRUE);
/* if this is an interrupt service routine then
save acc, b, dpl, dph */
if (IFFUNC_ISISR (sym->type))
- {
-
+ { /* is ISR */
if (!inExcludeList ("acc"))
emitcode ("push", "acc");
if (!inExcludeList ("b"))
registers :-) */
if (!FUNC_REGBANK (sym->type))
{
+ int i;
/* if this function does not call any other
function then we can be economical and
save only those registers that are used */
if (!IFFUNC_HASFCALL(sym->type))
{
- int i;
/* if any registers used */
if (sym->regsUsed)
determines register usage so we will have to push the
entire bank */
saveRBank (0, ic, FALSE);
+ if (options.parms_in_bank1) {
+ for (i=0; i < 8 ; i++ ) {
+ emitcode ("push","%s",rb1regs[i]);
+ }
+ }
}
}
else
if (sym->stack) {
int i = sym->stack;
if (options.stack10bit) {
- if ( i > 1024) werror (W_STACK_OVERFLOW, sym->name);
+ if ( i > 1024) werror (W_STACK_OVERFLOW, sym->name);
assert (sym->recvSize <= 4);
- emitcode ("mov","a,sp");
- emitcode ("add","a,#!constbyte", ((short) sym->stack & 0xff));
- emitcode ("mov","sp,a");
- emitcode ("mov","a,esp");
- emitcode ("addc","a,#!constbyte", (((short) sym->stack) >> 8) & 0xff);
- emitcode ("mov","esp,a");
+ if (sym->stack <= 8) {
+ while (i--) emitcode ("push","acc");
+ } else {
+ PROTECT_SP;
+ emitcode ("mov","a,sp");
+ emitcode ("add","a,#!constbyte", ((short) sym->stack & 0xff));
+ emitcode ("mov","sp,a");
+ emitcode ("mov","a,esp");
+ emitcode ("anl","a,#3");
+ emitcode ("addc","a,#!constbyte", (((short) sym->stack) >> 8) & 0xff);
+ emitcode ("mov","esp,a");
+ UNPROTECT_SP;
+ }
} else {
if (i > 256)
werror (W_STACK_OVERFLOW, sym->name);
(sym->stack || FUNC_HASSTACKPARM(sym->type))) {
if (options.stack10bit) {
+ PROTECT_SP;
emitcode ("mov", "sp,_bpx", spname);
emitcode ("mov", "esp,_bpx+1", spname);
+ UNPROTECT_SP;
} else {
emitcode ("mov", "%s,_bp", spname);
}
*/
emitcode ("pop", "psw");
}
- }
+ }
if (IFFUNC_ISISR (sym->type))
- {
+ { /* is ISR */
/* now we need to restore the registers */
/* if this isr has no bank i.e. is going to
registers :-) */
if (!FUNC_REGBANK (sym->type))
{
+ int i;
/* if this function does not call any other
function then we can be economical and
save only those registers that are used */
if (!IFFUNC_HASFCALL(sym->type))
{
- int i;
/* if any registers used */
if (sym->regsUsed)
/* this function has a function call cannot
determines register usage so we will have to pop the
entire bank */
+ if (options.parms_in_bank1) {
+ for (i = 7 ; i >= 0 ; i-- ) {
+ emitcode ("pop","%s",rb1regs[i]);
+ }
+ }
unsaveRBank (0, ic, FALSE);
}
}
return TRUE;
}
+ if (AOP_INDPTRn(IC_LEFT(ic)) && AOP_INDPTRn(IC_RESULT(ic)) &&
+ AOP(IC_LEFT(ic))->aopu.dptr == AOP(IC_RESULT(ic))->aopu.dptr &&
+ icount <= 5 ) {
+ emitcode ("mov","dps,#!constbyte",AOP(IC_LEFT(ic))->aopu.dptr);
+ while (icount--) emitcode ("inc","dptr");
+ emitcode ("mov","dps,#0");
+ return TRUE;
+ }
+
/* if the sizes are greater than 1 then we cannot */
if (AOP_SIZE (IC_RESULT (ic)) > 1 ||
AOP_SIZE (IC_LEFT (ic)) > 1)
}
}
-#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) \
- aopOp (IC_RIGHT(ic),ic,FALSE, FALSE); \
- aopOp (IC_LEFT(ic),ic,FALSE, (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR)); \
- aopOp (IC_RESULT(ic),ic,TRUE, (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) || \
- (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR)); \
- if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR2 && \
- AOP_TYPE(IC_RESULT(ic)) == AOP_DPTR2) \
- { \
- /* werror(E_INTERNAL_ERROR,__FILE__,__LINE__, */ \
- 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
// will be set TRUE. The caller must then handle the case specially, noting
D (emitcode (";", "genMinus "););
aopOp (IC_LEFT (ic), ic, FALSE, FALSE);
- aopOp (IC_RIGHT (ic), ic, FALSE, TRUE);
+ aopOp (IC_RIGHT (ic), ic, FALSE,
+ (AOP_INDPTRn(IC_LEFT(ic)) ? FALSE : (AOP_USESDPTR(IC_LEFT(ic)) ? TRUE : FALSE)));
if ((AOP_TYPE (IC_LEFT (ic)) == AOP_DPTR) &&
(AOP_TYPE (IC_RIGHT (ic)) == AOP_DPTR2))
{
/* if literal, add a,#-lit, else normal subb */
_startLazyDPSEvaluation ();
- while (size--)
- {
+ while (size--) {
MOVA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE, TRUE));
- if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT)
- emitcode ("subb", "a,%s",
- aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE, FALSE));
- else
- {
+ if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT) {
+ if (AOP_USESDPTR(IC_RIGHT(ic))) {
+ emitcode ("mov","b,a");
+ MOVA(aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE, FALSE));
+ emitcode ("xch","a,b");
+ emitcode ("subb","a,b");
+ } else {
+ emitcode ("subb", "a,%s",
+ aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE, FALSE));
+ }
+ } else {
/* first add without previous c */
if (!offset) {
- if (!size && lit==-1) {
- emitcode ("dec", "a");
- } else {
- emitcode ("add", "a,#!constbyte",
- (unsigned int) (lit & 0x0FFL));
- }
+ if (!size && lit==-1) {
+ emitcode ("dec", "a");
+ } else {
+ emitcode ("add", "a,#!constbyte",
+ (unsigned int) (lit & 0x0FFL));
+ }
} else {
- emitcode ("addc", "a,#!constbyte",
- (unsigned int) ((lit >> (offset * 8)) & 0x0FFL));
+ emitcode ("addc", "a,#!constbyte",
+ (unsigned int) ((lit >> (offset * 8)) & 0x0FFL));
}
- }
-
- if (pushResult)
- {
+ }
+
+ if (pushResult) {
emitcode ("push", "acc");
- }
- else
- {
+ } else {
aopPut (AOP (IC_RESULT (ic)), "a", offset);
- }
+ }
offset++;
- }
+ }
_endLazyDPSEvaluation ();
-
+
if (pushResult)
{
aopOp (IC_RESULT (ic), ic, TRUE, FALSE);
sprintf (buffer, "acc.%d", posbit & 0x07);
genIfxJump (ifx, buffer);
}
+ else
+ {
+ emitcode ("anl","a,#!constbyte",1 << (posbit & 0x07));
+ }
goto release;
}
}
/* if the operand is already in dptr
then we do nothing else we move the value to dptr */
- if (AOP_TYPE (left) != AOP_STR)
+ if (AOP_TYPE (left) != AOP_STR && !AOP_INDPTRn(left) )
{
/* if this is remateriazable */
if (AOP_TYPE (left) == AOP_IMMD)
}
}
/* so dptr know contains the address */
- aopOp (result, ic, FALSE, TRUE);
+ aopOp (result, ic, FALSE, (AOP_INDPTRn(left) ? FALSE : TRUE));
/* if bit then unpack */
- if (IS_BITVAR (retype) || IS_BITVAR (letype))
- genUnpackBits (result, "dptr", FPOINTER);
- else
+ if (IS_BITVAR (retype) || IS_BITVAR (letype)) {
+ if (AOP_INDPTRn(left)) {
+ genSetDPTR(AOP(left)->aopu.dptr);
+ }
+ genUnpackBits (result, "dptr", FPOINTER);
+ if (AOP_INDPTRn(left)) {
+ genSetDPTR(0);
+ }
+ } else
{
size = AOP_SIZE (result);
offset = 0;
- _startLazyDPSEvaluation ();
- while (size--)
- {
-
- genSetDPTR (0);
- _flushLazyDPS ();
-
- emitcode ("movx", "a,@dptr");
- if (size || (dopi && pi && AOP_TYPE (left) != AOP_IMMD))
- emitcode ("inc", "dptr");
-
- aopPut (AOP (result), "a", offset++);
- }
- _endLazyDPSEvaluation ();
+ if (AOP_INDPTRn(left) && AOP_USESDPTR(result)) {
+ while (size--) {
+ genSetDPTR(AOP(left)->aopu.dptr);
+ emitcode ("movx", "a,@dptr");
+ if (size || (dopi && pi && AOP_TYPE (left) != AOP_IMMD))
+ emitcode ("inc", "dptr");
+ genSetDPTR (0);
+ aopPut (AOP (result), "a", offset++);
+ }
+ } else {
+ _startLazyDPSEvaluation ();
+ while (size--) {
+ if (AOP_INDPTRn(left)) {
+ genSetDPTR(AOP(left)->aopu.dptr);
+ } else {
+ genSetDPTR (0);
+ }
+ _flushLazyDPS ();
+
+ emitcode ("movx", "a,@dptr");
+ 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);
+ if (!AOP_INDPTRn(left)) {
+ 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 &&
+ } else if ((OP_SYMBOL(left)->ruonly || AOP_INDPTRn(left)) &&
+ AOP_SIZE(result) > 1 &&
(OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) {
size = AOP_SIZE (result) - 1;
+ if (AOP_INDPTRn(left)) {
+ genSetDPTR(AOP(left)->aopu.dptr);
+ }
while (size--) emitcode ("lcall","__decdptr");
+ if (AOP_INDPTRn(left)) {
+ genSetDPTR(0);
+ }
}
freeAsmop (left, NULL, ic, TRUE);
/* if the operand is already in dptr
then we do nothing else we move the value to dptr */
- if (AOP_TYPE (left) != AOP_STR)
+ if (AOP_TYPE (left) != AOP_STR && !AOP_INDPTRn(left))
{
/* if this is remateriazable */
if (AOP_TYPE (left) == AOP_IMMD)
}
}
/* so dptr know contains the address */
- aopOp (result, ic, FALSE, TRUE);
+ aopOp (result, ic, FALSE, (AOP_INDPTRn(left) ? FALSE : TRUE));
/* if bit then unpack */
- if (IS_BITVAR (retype))
- genUnpackBits (result, "dptr", CPOINTER);
- else
+ if (IS_BITVAR (retype)) {
+ if (AOP_INDPTRn(left)) {
+ genSetDPTR(AOP(left)->aopu.dptr);
+ }
+ genUnpackBits (result, "dptr", CPOINTER);
+ if (AOP_INDPTRn(left)) {
+ genSetDPTR(0);
+ }
+ } else
{
size = AOP_SIZE (result);
offset = 0;
-
- _startLazyDPSEvaluation ();
- while (size--)
- {
- genSetDPTR (0);
- _flushLazyDPS ();
-
- emitcode ("clr", "a");
- emitcode ("movc", "a,@a+dptr");
- if (size || (dopi && pi && AOP_TYPE (left) != AOP_IMMD))
- emitcode ("inc", "dptr");
- aopPut (AOP (result), "a", offset++);
- }
- _endLazyDPSEvaluation ();
+ if (AOP_INDPTRn(left) && AOP_USESDPTR(result)) {
+ while (size--) {
+ genSetDPTR(AOP(left)->aopu.dptr);
+ emitcode ("clr", "a");
+ emitcode ("movc", "a,@a+dptr");
+ if (size || (dopi && pi && AOP_TYPE (left) != AOP_IMMD))
+ emitcode ("inc", "dptr");
+ genSetDPTR (0);
+ aopPut (AOP (result), "a", offset++);
+ }
+ } else {
+ _startLazyDPSEvaluation ();
+ while (size--)
+ {
+ if (AOP_INDPTRn(left)) {
+ genSetDPTR(AOP(left)->aopu.dptr);
+ } else {
+ genSetDPTR (0);
+ }
+ _flushLazyDPS ();
+
+ emitcode ("clr", "a");
+ emitcode ("movc", "a,@a+dptr");
+ 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);
+ if (!AOP_INDPTRn(left)) {
+ 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 &&
+ } else if ((OP_SYMBOL(left)->ruonly || AOP_INDPTRn(left)) &&
+ AOP_SIZE(result) > 1 &&
(OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) {
size = AOP_SIZE (result) - 1;
+ if (AOP_INDPTRn(left)) {
+ genSetDPTR(AOP(left)->aopu.dptr);
+ }
while (size--) emitcode ("lcall","__decdptr");
+ if (AOP_INDPTRn(left)) {
+ genSetDPTR(0);
+ }
}
freeAsmop (left, NULL, ic, TRUE);
/* if the operand is already in dptr
then we do nothing else we move the value to dptr */
- if (AOP_TYPE (result) != AOP_STR)
+ if (AOP_TYPE (result) != AOP_STR && !AOP_INDPTRn(result))
{
/* if this is remateriazable */
if (AOP_TYPE (result) == AOP_IMMD)
}
}
/* so dptr know contains the address */
- aopOp (right, ic, FALSE, TRUE);
+ aopOp (right, ic, FALSE, (AOP_INDPTRn(result) ? FALSE : TRUE));
/* if bit then unpack */
- if (IS_BITVAR (retype) || IS_BITVAR (letype))
- genPackBits ((IS_BITVAR (retype) ? retype : letype), right, "dptr", FPOINTER);
- else
- {
+ if (IS_BITVAR (retype) || IS_BITVAR (letype)) {
+ if (AOP_INDPTRn(result)) {
+ genSetDPTR(AOP(result)->aopu.dptr);
+ }
+ genPackBits ((IS_BITVAR (retype) ? retype : letype), right, "dptr", FPOINTER);
+ if (AOP_INDPTRn(result)) {
+ genSetDPTR(0);
+ }
+ } else {
size = AOP_SIZE (right);
offset = 0;
-
- _startLazyDPSEvaluation ();
- while (size--)
- {
- char *l = aopGet (AOP (right), offset++, FALSE, FALSE, TRUE);
- MOVA (l);
-
- genSetDPTR (0);
- _flushLazyDPS ();
-
- emitcode ("movx", "@dptr,a");
- 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);
-}
+ if (AOP_INDPTRn(result) && AOP_USESDPTR(right)) {
+ while (size--) {
+ char *l = aopGet (AOP (right), offset++, FALSE, FALSE, TRUE);
+ MOVA (l);
+
+ genSetDPTR(AOP(result)->aopu.dptr);
+ emitcode ("movx", "@dptr,a");
+ if (size || (dopi && pi && AOP_TYPE (result) != AOP_IMMD))
+ emitcode ("inc", "dptr");
+ genSetDPTR (0);
+ }
+ } else {
+ _startLazyDPSEvaluation ();
+ while (size--) {
+ char *l = aopGet (AOP (right), offset++, FALSE, FALSE, TRUE);
+ MOVA (l);
+
+ if (AOP_INDPTRn(result)) {
+ genSetDPTR(AOP(result)->aopu.dptr);
+ } else {
+ genSetDPTR (0);
+ }
+ _flushLazyDPS ();
+
+ emitcode ("movx", "@dptr,a");
+ if (size || (dopi && pi && AOP_TYPE (result) != AOP_IMMD))
+ emitcode ("inc", "dptr");
+ }
+ _endLazyDPSEvaluation ();
+ }
+ }
+
+ if (dopi && pi && AOP_TYPE (result) != AOP_IMMD) {
+ if (!AOP_INDPTRn(result)) {
+ 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_INDPTRn(result)) &&
+ AOP_SIZE(right) > 1 &&
+ (OP_SYMBOL (result)->liveTo > ic->seq || ic->depth)) {
+
+ size = AOP_SIZE (right) - 1;
+ if (AOP_INDPTRn(result)) {
+ genSetDPTR(AOP(result)->aopu.dptr);
+ }
+ while (size--) emitcode ("lcall","__decdptr");
+ if (AOP_INDPTRn(result)) {
+ genSetDPTR(0);
+ }
+ }
+ freeAsmop (result, NULL, ic, TRUE);
+ freeAsmop (right, NULL, ic, TRUE);
+}
/*-----------------------------------------------------------------*/
/* genGenPointerSet - set value from generic pointer space */
genReceive (iCode * ic)
{
- D (emitcode (";", "genReceive ");
- );
-
- if (isOperandInFarSpace (IC_RESULT (ic)) &&
- (OP_SYMBOL (IC_RESULT (ic))->isspilt ||
- IS_TRUE_SYMOP (IC_RESULT (ic))))
- {
- int size = getSize (operandType (IC_RESULT (ic)));
- int offset = fReturnSizeDS390 - size;
- while (size--)
- {
- emitcode ("push", "%s", (strcmp (fReturn[fReturnSizeDS390 - offset - 1], "a") ?
- fReturn[fReturnSizeDS390 - offset - 1] : "acc"));
- offset++;
- }
- aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
- size = AOP_SIZE (IC_RESULT (ic));
- offset = 0;
- while (size--)
- {
- emitcode ("pop", "acc");
- aopPut (AOP (IC_RESULT (ic)), "a", offset++);
- }
+ int size = getSize (operandType (IC_RESULT (ic)));
+ int offset = 0;
+ int rb1off ;
+
+ D (emitcode (";", "genReceive ");
+ );
- }
- else
- {
- _G.accInUse++;
+ if (ic->argreg == 1) { /* first parameter */
+ if (isOperandInFarSpace (IC_RESULT (ic)) &&
+ (OP_SYMBOL (IC_RESULT (ic))->isspilt ||
+ IS_TRUE_SYMOP (IC_RESULT (ic))))
+ {
+ offset = fReturnSizeDS390 - size;
+ while (size--)
+ {
+ emitcode ("push", "%s", (strcmp (fReturn[fReturnSizeDS390 - offset - 1], "a") ?
+ fReturn[fReturnSizeDS390 - offset - 1] : "acc"));
+ offset++;
+ }
+ aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
+ size = AOP_SIZE (IC_RESULT (ic));
+ offset = 0;
+ while (size--)
+ {
+ emitcode ("pop", "acc");
+ aopPut (AOP (IC_RESULT (ic)), "a", offset++);
+ }
+
+ } else {
+ _G.accInUse++;
+ aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
+ _G.accInUse--;
+ assignResultValue (IC_RESULT (ic));
+ }
+ } else { /* second receive onwards */
+ /* this gets a little tricky since unused recevies will be
+ eliminated, we have saved the reg in the type field . and
+ we use that to figure out which register to use */
aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
- _G.accInUse--;
- assignResultValue (IC_RESULT (ic));
- }
-
+ rb1off = ic->argreg;
+ while (size--) {
+ aopPut (AOP (IC_RESULT (ic)), rb1regs[rb1off++ -5], offset++);
+ }
+
+ }
freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
}
}
+/*-----------------------------------------------------------------*/
+/* genMemcmpX2X - gen code for memcmp xdata to xdata */
+/*-----------------------------------------------------------------*/
+static void genMemcmpX2X( iCode *ic, int nparms, operand **parms, int fromc)
+{
+ operand *from , *to , *count;
+ symbol *lbl,*lbl2;
+ bitVect *rsave;
+ int i;
+
+ /* we know it has to be 3 parameters */
+ assert (nparms == 3);
+
+ rsave = newBitVect(16);
+ /* save DPTR if it needs to be saved */
+ for (i = DPL_IDX ; i <= B_IDX ; i++ ) {
+ if (bitVectBitValue(ic->rMask,i))
+ rsave = bitVectSetBit(rsave,i);
+ }
+ rsave = bitVectIntersect(rsave,bitVectCplAnd (bitVectCopy (ic->rMask),
+ ds390_rUmaskForOp (IC_RESULT(ic))));
+ savermask(rsave);
+
+ to = parms[0];
+ from = parms[1];
+ count = parms[2];
+
+ aopOp (from, ic->next, FALSE, FALSE);
+
+ /* get from into DPTR1 */
+ emitcode ("mov", "dpl1,%s", aopGet (AOP (from), 0, FALSE, FALSE, TRUE));
+ emitcode ("mov", "dph1,%s", aopGet (AOP (from), 1, FALSE, FALSE, TRUE));
+ if (options.model == MODEL_FLAT24) {
+ emitcode ("mov", "dpx1,%s", aopGet (AOP (from), 2, FALSE, FALSE, TRUE));
+ }
+
+ freeAsmop (from, NULL, ic, FALSE);
+ aopOp (to, ic, FALSE, FALSE);
+ /* get "to" into DPTR */
+ /* if the operand is already in dptr
+ then we do nothing else we move the value to dptr */
+ if (AOP_TYPE (to) != AOP_STR) {
+ /* if already in DPTR then we need to push */
+ if (AOP_TYPE(to) == AOP_DPTR) {
+ emitcode ("push", "%s", aopGet (AOP (to), 0, FALSE, TRUE, TRUE));
+ emitcode ("push", "%s", aopGet (AOP (to), 1, FALSE, TRUE, TRUE));
+ if (options.model == MODEL_FLAT24)
+ emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, TRUE));
+ emitcode ("pop", "dph");
+ emitcode ("pop", "dpl");
+ } else {
+ _startLazyDPSEvaluation ();
+ /* if this is remateriazable */
+ if (AOP_TYPE (to) == AOP_IMMD) {
+ emitcode ("mov", "dptr,%s", aopGet (AOP (to), 0, TRUE, FALSE, FALSE));
+ } else { /* we need to get it byte by byte */
+ emitcode ("mov", "dpl,%s", aopGet (AOP (to), 0, FALSE, FALSE, TRUE));
+ emitcode ("mov", "dph,%s", aopGet (AOP (to), 1, FALSE, FALSE, TRUE));
+ if (options.model == MODEL_FLAT24) {
+ emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, TRUE));
+ }
+ }
+ _endLazyDPSEvaluation ();
+ }
+ }
+ freeAsmop (to, NULL, ic, FALSE);
+
+ aopOp (count, ic->next->next, FALSE,FALSE);
+ lbl =newiTempLabel(NULL);
+ lbl2 =newiTempLabel(NULL);
+
+ /* now for the actual compare */
+ emitcode("push","ar0");
+ if (AOP_TYPE(count) == AOP_LIT &&
+ (int)floatFromVal (AOP(count)->aopu.aop_lit) <= 256) {
+ emitcode (";","OH JOY auto increment with djnz (very fast)");
+ emitcode ("mov", "dps,#!constbyte",0x21); /* Select DPTR2 & auto-toggle. */
+ emitcode ("mov", "b,%s",aopGet(AOP(count),0,FALSE,FALSE,FALSE));
+ emitcode ("","!tlabeldef",lbl->key+100);
+ if (fromc) {
+ emitcode ("clr","a");
+ emitcode ("movc", "a,@a+dptr");
+ } else
+ emitcode ("movx", "a,@dptr");
+ emitcode ("mov","r0,a");
+ emitcode ("movx", "a,@dptr");
+ emitcode ("clr","c");
+ emitcode ("subb","a,r0");
+ emitcode ("jnz","!tlabel",lbl2->key+100);
+ emitcode ("inc", "dptr");
+ emitcode ("inc", "dptr");
+ emitcode ("djnz","b,!tlabel",lbl->key+100);
+ emitcode ("clr","a");
+ } else {
+ symbol *lbl1 = newiTempLabel(NULL);
+
+ emitcode (";"," Auto increment but no djnz");
+ emitcode ("mov","_ap,%s",aopGet (AOP (count), 0, FALSE, TRUE, TRUE));
+ emitcode ("mov","b,%s",aopGet (AOP (count), 1, FALSE, TRUE, TRUE));
+ emitcode ("mov", "dps,#!constbyte",0x21); /* Select DPTR2 & auto-toggle. */
+ emitcode ("","!tlabeldef",lbl->key+100);
+ if (fromc) {
+ emitcode ("clr","a");
+ emitcode ("movc", "a,@a+dptr");
+ } else
+ emitcode ("movx", "a,@dptr");
+ emitcode ("mov","r0,a");
+ emitcode ("movx", "a,@dptr");
+ emitcode ("clr","c");
+ emitcode ("subb","a,r0");
+ emitcode ("jnz","!tlabel",lbl2->key+100);
+ emitcode ("inc", "dptr");
+ emitcode ("inc", "dptr");
+ emitcode ("mov","a,b");
+ emitcode ("orl","a,_ap");
+ emitcode ("jz","!tlabel",lbl1->key+100);
+ emitcode ("mov","a,_ap");
+ emitcode ("add","a,#!constbyte",0xFF);
+ emitcode ("mov","_ap,a");
+ emitcode ("mov","a,b");
+ emitcode ("addc","a,#!constbyte",0xFF);
+ emitcode ("mov","b,a");
+ emitcode ("sjmp","!tlabel",lbl->key+100);
+ emitcode ("","!tlabeldef",lbl1->key+100);
+ emitcode ("clr","a");
+ }
+ freeAsmop (count, NULL, ic, FALSE);
+ emitcode ("","!tlabeldef",lbl2->key+100);
+ aopOp (IC_RESULT(ic), ic, FALSE,FALSE);
+ aopPut(AOP(IC_RESULT(ic)),"a",0);
+ freeAsmop (IC_RESULT(ic), NULL, ic, FALSE);
+ emitcode("pop","ar0");
+ emitcode ("mov", "dps,#0");
+
+ unsavermask(rsave);
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genInp - gen code for __builtin_inp read data from a mem mapped */
+/* port, first parameter output area second parameter pointer to */
+/* port third parameter count */
+/*-----------------------------------------------------------------*/
+static void genInp( iCode *ic, int nparms, operand **parms)
+{
+ operand *from , *to , *count;
+ symbol *lbl;
+ bitVect *rsave;
+ int i;
+
+ /* we know it has to be 3 parameters */
+ assert (nparms == 3);
+
+ rsave = newBitVect(16);
+ /* save DPTR if it needs to be saved */
+ for (i = DPL_IDX ; i <= B_IDX ; i++ ) {
+ if (bitVectBitValue(ic->rMask,i))
+ rsave = bitVectSetBit(rsave,i);
+ }
+ rsave = bitVectIntersect(rsave,bitVectCplAnd (bitVectCopy (ic->rMask),
+ ds390_rUmaskForOp (IC_RESULT(ic))));
+ savermask(rsave);
+
+ to = parms[0];
+ from = parms[1];
+ count = parms[2];
+
+ aopOp (from, ic->next, FALSE, FALSE);
+
+ /* get from into DPTR1 */
+ emitcode ("mov", "dpl1,%s", aopGet (AOP (from), 0, FALSE, FALSE, TRUE));
+ emitcode ("mov", "dph1,%s", aopGet (AOP (from), 1, FALSE, FALSE, TRUE));
+ if (options.model == MODEL_FLAT24) {
+ emitcode ("mov", "dpx1,%s", aopGet (AOP (from), 2, FALSE, FALSE, TRUE));
+ }
+
+ freeAsmop (from, NULL, ic, FALSE);
+ aopOp (to, ic, FALSE, FALSE);
+ /* get "to" into DPTR */
+ /* if the operand is already in dptr
+ then we do nothing else we move the value to dptr */
+ if (AOP_TYPE (to) != AOP_STR) {
+ /* if already in DPTR then we need to push */
+ if (AOP_TYPE(to) == AOP_DPTR) {
+ emitcode ("push", "%s", aopGet (AOP (to), 0, FALSE, TRUE, TRUE));
+ emitcode ("push", "%s", aopGet (AOP (to), 1, FALSE, TRUE, TRUE));
+ if (options.model == MODEL_FLAT24)
+ emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, TRUE));
+ emitcode ("pop", "dph");
+ emitcode ("pop", "dpl");
+ } else {
+ _startLazyDPSEvaluation ();
+ /* if this is remateriazable */
+ if (AOP_TYPE (to) == AOP_IMMD) {
+ emitcode ("mov", "dptr,%s", aopGet (AOP (to), 0, TRUE, FALSE, FALSE));
+ } else { /* we need to get it byte by byte */
+ emitcode ("mov", "dpl,%s", aopGet (AOP (to), 0, FALSE, FALSE, TRUE));
+ emitcode ("mov", "dph,%s", aopGet (AOP (to), 1, FALSE, FALSE, TRUE));
+ if (options.model == MODEL_FLAT24) {
+ emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, TRUE));
+ }
+ }
+ _endLazyDPSEvaluation ();
+ }
+ }
+ freeAsmop (to, NULL, ic, FALSE);
+
+ aopOp (count, ic->next->next, FALSE,FALSE);
+ lbl =newiTempLabel(NULL);
+
+ /* now for the actual copy */
+ if (AOP_TYPE(count) == AOP_LIT &&
+ (int)floatFromVal (AOP(count)->aopu.aop_lit) <= 256) {
+ emitcode (";","OH JOY auto increment with djnz (very fast)");
+ emitcode ("mov", "dps,#!constbyte",0x1); /* Select DPTR2 */
+ emitcode ("mov", "b,%s",aopGet(AOP(count),0,FALSE,FALSE,FALSE));
+ emitcode ("","!tlabeldef",lbl->key+100);
+ emitcode ("movx", "a,@dptr"); /* read data from port */
+ emitcode ("dec","dps"); /* switch to DPTR */
+ emitcode ("movx", "@dptr,a"); /* save into location */
+ emitcode ("inc", "dptr"); /* point to next area */
+ emitcode ("inc","dps"); /* switch to DPTR2 */
+ emitcode ("djnz","b,!tlabel",lbl->key+100);
+ } else {
+ symbol *lbl1 = newiTempLabel(NULL);
+
+ emitcode (";"," Auto increment but no djnz");
+ emitcode ("mov","_ap,%s",aopGet (AOP (count), 0, FALSE, TRUE, TRUE));
+ emitcode ("mov","b,%s",aopGet (AOP (count), 1, FALSE, TRUE, TRUE));
+ emitcode ("mov", "dps,#!constbyte",0x1); /* Select DPTR2 */
+ emitcode ("","!tlabeldef",lbl->key+100);
+ emitcode ("movx", "a,@dptr");
+ emitcode ("dec","dps"); /* switch to DPTR */
+ emitcode ("movx", "@dptr,a");
+ emitcode ("inc", "dptr");
+ emitcode ("inc","dps"); /* switch to DPTR2 */
+/* emitcode ("djnz","b,!tlabel",lbl->key+100); */
+/* emitcode ("djnz","_ap,!tlabel",lbl->key+100); */
+ emitcode ("mov","a,b");
+ emitcode ("orl","a,_ap");
+ emitcode ("jz","!tlabel",lbl1->key+100);
+ emitcode ("mov","a,_ap");
+ emitcode ("add","a,#!constbyte",0xFF);
+ emitcode ("mov","_ap,a");
+ emitcode ("mov","a,b");
+ emitcode ("addc","a,#!constbyte",0xFF);
+ emitcode ("mov","b,a");
+ emitcode ("sjmp","!tlabel",lbl->key+100);
+ emitcode ("","!tlabeldef",lbl1->key+100);
+ }
+ emitcode ("mov", "dps,#0");
+ freeAsmop (count, NULL, ic, FALSE);
+ unsavermask(rsave);
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genOutp - gen code for __builtin_inp write data to a mem mapped */
+/* port, first parameter output area second parameter pointer to */
+/* port third parameter count */
+/*-----------------------------------------------------------------*/
+static void genOutp( iCode *ic, int nparms, operand **parms)
+{
+ operand *from , *to , *count;
+ symbol *lbl;
+ bitVect *rsave;
+ int i;
+
+ /* we know it has to be 3 parameters */
+ assert (nparms == 3);
+
+ rsave = newBitVect(16);
+ /* save DPTR if it needs to be saved */
+ for (i = DPL_IDX ; i <= B_IDX ; i++ ) {
+ if (bitVectBitValue(ic->rMask,i))
+ rsave = bitVectSetBit(rsave,i);
+ }
+ rsave = bitVectIntersect(rsave,bitVectCplAnd (bitVectCopy (ic->rMask),
+ ds390_rUmaskForOp (IC_RESULT(ic))));
+ savermask(rsave);
+
+ to = parms[0];
+ from = parms[1];
+ count = parms[2];
+
+ aopOp (from, ic->next, FALSE, FALSE);
+
+ /* get from into DPTR1 */
+ emitcode ("mov", "dpl1,%s", aopGet (AOP (from), 0, FALSE, FALSE, TRUE));
+ emitcode ("mov", "dph1,%s", aopGet (AOP (from), 1, FALSE, FALSE, TRUE));
+ if (options.model == MODEL_FLAT24) {
+ emitcode ("mov", "dpx1,%s", aopGet (AOP (from), 2, FALSE, FALSE, TRUE));
+ }
+
+ freeAsmop (from, NULL, ic, FALSE);
+ aopOp (to, ic, FALSE, FALSE);
+ /* get "to" into DPTR */
+ /* if the operand is already in dptr
+ then we do nothing else we move the value to dptr */
+ if (AOP_TYPE (to) != AOP_STR) {
+ /* if already in DPTR then we need to push */
+ if (AOP_TYPE(to) == AOP_DPTR) {
+ emitcode ("push", "%s", aopGet (AOP (to), 0, FALSE, TRUE, TRUE));
+ emitcode ("push", "%s", aopGet (AOP (to), 1, FALSE, TRUE, TRUE));
+ if (options.model == MODEL_FLAT24)
+ emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, TRUE));
+ emitcode ("pop", "dph");
+ emitcode ("pop", "dpl");
+ } else {
+ _startLazyDPSEvaluation ();
+ /* if this is remateriazable */
+ if (AOP_TYPE (to) == AOP_IMMD) {
+ emitcode ("mov", "dptr,%s", aopGet (AOP (to), 0, TRUE, FALSE, FALSE));
+ } else { /* we need to get it byte by byte */
+ emitcode ("mov", "dpl,%s", aopGet (AOP (to), 0, FALSE, FALSE, TRUE));
+ emitcode ("mov", "dph,%s", aopGet (AOP (to), 1, FALSE, FALSE, TRUE));
+ if (options.model == MODEL_FLAT24) {
+ emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, TRUE));
+ }
+ }
+ _endLazyDPSEvaluation ();
+ }
+ }
+ freeAsmop (to, NULL, ic, FALSE);
+
+ aopOp (count, ic->next->next, FALSE,FALSE);
+ lbl =newiTempLabel(NULL);
+
+ /* now for the actual copy */
+ if (AOP_TYPE(count) == AOP_LIT &&
+ (int)floatFromVal (AOP(count)->aopu.aop_lit) <= 256) {
+ emitcode (";","OH JOY auto increment with djnz (very fast)");
+ emitcode ("mov", "dps,#!constbyte",0x0); /* Select DPTR */
+ emitcode ("mov", "b,%s",aopGet(AOP(count),0,FALSE,FALSE,FALSE));
+ emitcode ("","!tlabeldef",lbl->key+100);
+ emitcode ("movx", "a,@dptr"); /* read data from port */
+ emitcode ("inc","dps"); /* switch to DPTR2 */
+ emitcode ("movx", "@dptr,a"); /* save into location */
+ emitcode ("inc", "dptr"); /* point to next area */
+ emitcode ("dec","dps"); /* switch to DPTR */
+ emitcode ("djnz","b,!tlabel",lbl->key+100);
+ } else {
+ symbol *lbl1 = newiTempLabel(NULL);
+
+ emitcode (";"," Auto increment but no djnz");
+ emitcode ("mov","_ap,%s",aopGet (AOP (count), 0, FALSE, TRUE, TRUE));
+ emitcode ("mov","b,%s",aopGet (AOP (count), 1, FALSE, TRUE, TRUE));
+ emitcode ("mov", "dps,#!constbyte",0x0); /* Select DPTR */
+ emitcode ("","!tlabeldef",lbl->key+100);
+/* emitcode ("push","acc"); */
+ emitcode ("movx", "a,@dptr");
+ emitcode ("inc", "dptr");
+ emitcode ("inc","dps"); /* switch to DPTR2 */
+ emitcode ("movx", "@dptr,a");
+ emitcode ("dec","dps"); /* switch to DPTR */
+/* emitcode ("pop","acc"); */
+/* emitcode ("djnz","acc,!tlabel",lbl->key+100); */
+/* emitcode ("djnz","b,!tlabel",lbl->key+100); */
+ emitcode ("mov","a,b");
+ emitcode ("orl","a,_ap");
+ emitcode ("jz","!tlabel",lbl1->key+100);
+ emitcode ("mov","a,_ap");
+ emitcode ("add","a,#!constbyte",0xFF);
+ emitcode ("mov","_ap,a");
+ emitcode ("mov","a,b");
+ emitcode ("addc","a,#!constbyte",0xFF);
+ emitcode ("mov","b,a");
+ emitcode ("sjmp","!tlabel",lbl->key+100);
+ emitcode ("","!tlabeldef",lbl1->key+100);
+ }
+ emitcode ("mov", "dps,#0");
+ freeAsmop (count, NULL, ic, FALSE);
+ unsavermask(rsave);
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genSwapW - swap lower & high order bytes */
+/*-----------------------------------------------------------------*/
+static void genSwapW(iCode *ic, int nparms, operand **parms)
+{
+ operand *dest;
+ operand *src;
+ assert (nparms==1);
+
+ src = parms[0];
+ dest=IC_RESULT(ic);
+
+ assert(getSize(operandType(src))==2);
+
+ aopOp (src, ic, FALSE, FALSE);
+ emitcode ("mov","a,%s",aopGet(AOP(src),0,FALSE,FALSE,TRUE));
+ _G.accInUse++;
+ emitcode ("mov","b,%s",aopGet(AOP(src),1,FALSE,FALSE,FALSE));
+ _G.accInUse--;
+ freeAsmop (src, NULL, ic, FALSE);
+
+ aopOp (dest,ic, FALSE, FALSE);
+ aopPut(AOP(dest),"b",0);
+ aopPut(AOP(dest),"a",1);
+ freeAsmop (dest, NULL, ic, FALSE);
+}
+
/*-----------------------------------------------------------------*/
/* genMemsetX - gencode for memSetX data */
/*-----------------------------------------------------------------*/
emitcode ("","!tlabeldef",lbl->key+100);
l = aopGet(AOP (val), 0, FALSE, FALSE, TRUE);
MOVA(l);
- emitcode ("movx", "a,@dptr");
+ emitcode ("movx", "@dptr,a");
emitcode ("inc", "dptr");
emitcode ("mov","a,b");
emitcode ("orl","a,_ap");
genMemcpyX2X(bi_iCode,nbi_parms,bi_parms,0);
} else if (strcmp(bif->name,"__builtin_memcpy_c2x")==0) {
genMemcpyX2X(bi_iCode,nbi_parms,bi_parms,1);
+ } else if (strcmp(bif->name,"__builtin_memcmp_x2x")==0) {
+ genMemcmpX2X(bi_iCode,nbi_parms,bi_parms,0);
+ } else if (strcmp(bif->name,"__builtin_memcmp_c2x")==0) {
+ genMemcmpX2X(bi_iCode,nbi_parms,bi_parms,1);
} else if (strcmp(bif->name,"__builtin_memset_x")==0) {
genMemsetX(bi_iCode,nbi_parms,bi_parms);
+ } else if (strcmp(bif->name,"__builtin_inp")==0) {
+ genInp(bi_iCode,nbi_parms,bi_parms);
+ } else if (strcmp(bif->name,"__builtin_outp")==0) {
+ genOutp(bi_iCode,nbi_parms,bi_parms);
+ } else if (strcmp(bif->name,"__builtin_swapw")==0) {
+ genSwapW(bi_iCode,nbi_parms,bi_parms);
+ /* JavaNative builtIns */
} else if (strcmp(bif->name,"NatLib_LoadByte")==0) {
genNatLibLoadPrimitive(bi_iCode,nbi_parms,bi_parms,1);
} else if (strcmp(bif->name,"NatLib_LoadShort")==0) {
int cln = 0;
lineHead = lineCurr = NULL;
-
+ dptrn[1][0] = "dpl1";
+ dptrn[1][1] = "dph1";
+ dptrn[1][2] = "dpx1";
+
if (options.model == MODEL_FLAT24) {
fReturnSizeDS390 = 5;
fReturn = fReturn24;
static void spillThis (symbol *);
static void freeAllRegs ();
static iCode * packRegsDPTRuse (operand *);
+static int packRegsDPTRnuse (operand *,int);
/*-----------------------------------------------------------------*/
/* allocReg - allocates register of given type */
static int isOperandInReg(operand *op)
{
if (!IS_SYMOP(op)) return 0;
-
+ if (OP_SYMBOL(op)->ruonly) return 1;
+ if (OP_SYMBOL(op)->accuse) return 1;
+ if (OP_SYMBOL(op)->dptr) return 1;
return bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(op)->key);
}
notUsedInBlock (symbol * sym, eBBlock * ebp, iCode * ic)
{
return (!bitVectBitsInCommon (sym->defs, ebp->usesDefs) &&
- allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
+ allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq) &&
+ allDefsOutOfRange (sym->uses, ebp->fSeq, ebp->lSeq));
/* return (!bitVectBitsInCommon(sym->defs,ebp->usesDefs)); */
}
(ebbs[i]->entryLabel != entryLabel &&
ebbs[i]->entryLabel != returnLabel))
continue;
-
+
+/* if (returnsAtEnd(ebbs[i])) */
+
/* of all instructions do */
for (ic = ebbs[i]->sch; ic; ic = ic->next)
{
{
symbol *sym =NULL;
int key =0;
-
+ int loop = 0, change;
+
if (getenv("DISABLE_FILL_GAPS")) return;
/* First try to do DPTRuse once more since now we know what got into
- registers */
-
- for (sym = hTabFirstItem(liveRanges,&key) ; sym ;
- sym = hTabNextItem(liveRanges,&key)) {
-
- if (sym->uptr && !sym->ruonly && getSize(sym->type) < 4) {
- if (packRegsDPTRuse(operandFromSymbol(sym))) {
-
- D (fprintf (stderr, "FILL GAPS: found more DPTR use for "
- "%s in func %s\n",
- sym->name, currFunc ? currFunc->name : "UNKNOWN"));
- /* if this was ssigned to registers then */
- if (bitVectBitValue(_G.totRegAssigned,sym->key)) {
-
- /* take it out of the register assigned set */
- bitVectUnSetBit(_G.totRegAssigned,sym->key);
+ registers */
+
+ while (loop++ < 10) {
+ change = 0;
+
+ for (sym = hTabFirstItem(liveRanges,&key) ; sym ;
+ sym = hTabNextItem(liveRanges,&key)) {
+ int size = getSize(sym->type);
+
+ if (sym->liveFrom == sym->liveTo) continue;
+
+ if (sym->uptr && sym->dptr==0 && !sym->ruonly &&
+ size < 4 && size > 1) {
+
+ if (packRegsDPTRuse(operandFromSymbol(sym))) {
+
+ /* if this was ssigned to registers then */
+ if (bitVectBitValue(_G.totRegAssigned,sym->key)) {
+ /* take it out of the register assigned set */
+ bitVectUnSetBit(_G.totRegAssigned,sym->key);
+ } else if (sym->usl.spillLoc) {
+ sym->usl.spillLoc->allocreq--;
+ sym->usl.spillLoc = NULL;
+ }
+
sym->nRegs = 0;
- } else if (sym->usl.spillLoc) sym->usl.spillLoc->allocreq--;
+ sym->isspilt = sym->spillA = 0;
+ continue ;
+ }
- sym->isspilt = sym->spillA = 0;
+ /* try assigning other dptrs */
+ if (sym->dptr == 0 && packRegsDPTRnuse(operandFromSymbol(sym),1) && !getenv("DPTRnDISABLE")) {
+ /* if this was ssigned to registers then */
+ if (bitVectBitValue(_G.totRegAssigned,sym->key)) {
+ /* take it out of the register assigned set */
+ bitVectUnSetBit(_G.totRegAssigned,sym->key);
+ } else if (sym->usl.spillLoc) {
+ sym->usl.spillLoc->allocreq--;
+ sym->usl.spillLoc = NULL;
+ }
+/* printf("Allocated %s in function %s to DPTR1\n",sym->name,currFunc->name); */
+ sym->nRegs = 0;
+ sym->isspilt = sym->spillA = 0;
+ }
}
}
- }
-
- /* look for livernages that was spilt by the allocator */
- for (sym = hTabFirstItem(liveRanges,&key) ; sym ;
- sym = hTabNextItem(liveRanges,&key)) {
-
- int i;
- int pdone = 0;
-
- if (!sym->spillA || !sym->clashes || sym->remat) continue ;
-
- /* find the liveRanges this one clashes with, that are
- still assigned to registers & mark the registers as used*/
- for ( i = 0 ; i < sym->clashes->size ; i ++) {
- int k;
- symbol *clr;
-
- if (bitVectBitValue(sym->clashes,i) == 0 || /* those that clash with this */
- bitVectBitValue(_G.totRegAssigned,i) == 0) /* and are still assigned to registers */
+
+ /* look for livernages that was spilt by the allocator */
+ for (sym = hTabFirstItem(liveRanges,&key) ; sym ;
+ sym = hTabNextItem(liveRanges,&key)) {
+
+ int i;
+ int pdone = 0;
+
+ if (!sym->spillA || !sym->clashes || sym->remat) continue ;
+ if (!sym->uses || !sym->defs) continue ;
+ /* find the liveRanges this one clashes with, that are
+ still assigned to registers & mark the registers as used*/
+ for ( i = 0 ; i < sym->clashes->size ; i ++) {
+ int k;
+ symbol *clr;
+
+ if (bitVectBitValue(sym->clashes,i) == 0 || /* those that clash with this */
+ bitVectBitValue(_G.totRegAssigned,i) == 0) /* and are still assigned to registers */
+ continue ;
+
+ assert (clr = hTabItemWithKey(liveRanges,i));
+
+ /* mark these registers as used */
+ for (k = 0 ; k < clr->nRegs ; k++ )
+ useReg(clr->regs[k]);
+ }
+
+ if (willCauseSpill(sym->nRegs,sym->regType)) {
+ /* NOPE :( clear all registers & and continue */
+ freeAllRegs();
continue ;
-
- assert (clr = hTabItemWithKey(liveRanges,i));
-
- /* mark these registers as used */
- for (k = 0 ; k < clr->nRegs ; k++ )
- useReg(clr->regs[k]);
- }
-
- if (willCauseSpill(sym->nRegs,sym->regType)) {
- /* NOPE :( clear all registers & and continue */
- freeAllRegs();
- continue ;
- }
-
- /* THERE IS HOPE !!!! */
- for (i=0; i < sym->nRegs ; i++ ) {
- if (sym->regType == REG_PTR)
- sym->regs[i] = getRegPtrNoSpil ();
- else
- sym->regs[i] = getRegGprNoSpil ();
- }
-
- /* for all its definitions & uses check if the registers
- allocated needs positioning NOTE: we can position
- only ONCE if more than One positioning required
- then give up */
- sym->isspilt = 0;
- for (i = 0 ; i < sym->defs->size ; i++ ) {
- if (bitVectBitValue(sym->defs,i)) {
- iCode *ic;
- if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
- if (SKIP_IC(ic)) continue;
- assert(isSymbolEqual(sym,OP_SYMBOL(IC_RESULT(ic)))); /* just making sure */
- /* if left is assigned to registers */
- if (IS_SYMOP(IC_LEFT(ic)) &&
- bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_LEFT(ic))->key)) {
- pdone += positionRegs(sym,OP_SYMBOL(IC_LEFT(ic)));
- }
- if (IS_SYMOP(IC_RIGHT(ic)) &&
- bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) {
- pdone += positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic)));
+ }
+
+ /* THERE IS HOPE !!!! */
+ for (i=0; i < sym->nRegs ; i++ ) {
+ if (sym->regType == REG_PTR)
+ sym->regs[i] = getRegPtrNoSpil ();
+ else
+ sym->regs[i] = getRegGprNoSpil ();
+ }
+
+ /* for all its definitions & uses check if the registers
+ allocated needs positioning NOTE: we can position
+ only ONCE if more than One positioning required
+ then give up */
+ sym->isspilt = 0;
+ for (i = 0 ; i < sym->defs->size ; i++ ) {
+ if (bitVectBitValue(sym->defs,i)) {
+ iCode *ic;
+ if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
+ if (SKIP_IC(ic)) continue;
+ assert(isSymbolEqual(sym,OP_SYMBOL(IC_RESULT(ic)))); /* just making sure */
+ /* if left is assigned to registers */
+ if (IS_SYMOP(IC_LEFT(ic)) &&
+ bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_LEFT(ic))->key)) {
+ pdone += positionRegs(sym,OP_SYMBOL(IC_LEFT(ic)));
+ }
+ if (IS_SYMOP(IC_RIGHT(ic)) &&
+ bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) {
+ pdone += positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic)));
+ }
+ if (pdone > 1) break;
}
- if (pdone > 1) break;
}
- }
- for (i = 0 ; i < sym->uses->size ; i++ ) {
- if (bitVectBitValue(sym->uses,i)) {
- iCode *ic;
- if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
- if (SKIP_IC(ic)) continue;
- if (!IS_ASSIGN_ICODE(ic)) continue ;
-
- /* if result is assigned to registers */
- if (IS_SYMOP(IC_RESULT(ic)) &&
- bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RESULT(ic))->key)) {
- pdone += positionRegs(sym,OP_SYMBOL(IC_RESULT(ic)));
+ for (i = 0 ; i < sym->uses->size ; i++ ) {
+ if (bitVectBitValue(sym->uses,i)) {
+ iCode *ic;
+ if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
+ if (SKIP_IC(ic)) continue;
+ if (!IS_ASSIGN_ICODE(ic)) continue ;
+
+ /* if result is assigned to registers */
+ if (IS_SYMOP(IC_RESULT(ic)) &&
+ bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RESULT(ic))->key)) {
+ pdone += positionRegs(sym,OP_SYMBOL(IC_RESULT(ic)));
+ }
+ if (pdone > 1) break;
}
- if (pdone > 1) break;
}
- }
- /* had to position more than once GIVE UP */
- if (pdone > 1) {
- /* UNDO all the changes we made to try this */
- sym->isspilt = 1;
- for (i=0; i < sym->nRegs ; i++ ) {
- sym->regs[i] = NULL;
+ /* had to position more than once GIVE UP */
+ if (pdone > 1) {
+ /* UNDO all the changes we made to try this */
+ sym->isspilt = 1;
+ for (i=0; i < sym->nRegs ; i++ ) {
+ sym->regs[i] = NULL;
+ }
+ freeAllRegs();
+ D (fprintf (stderr, "Fill Gap gave up due to positioning for "
+ "%s in function %s\n",
+ sym->name, currFunc ? currFunc->name : "UNKNOWN"));
+ continue ;
}
- freeAllRegs();
- D (fprintf (stderr, "Fill Gap gave up due to positioning for "
- "%s in function %s\n",
+ D (fprintf (stderr, "FILLED GAP for %s in function %s\n",
sym->name, currFunc ? currFunc->name : "UNKNOWN"));
- continue ;
+ _G.totRegAssigned = bitVectSetBit(_G.totRegAssigned,sym->key);
+ sym->isspilt = sym->spillA = 0 ;
+ sym->usl.spillLoc->allocreq--;
+ sym->usl.spillLoc = NULL;
+ freeAllRegs();
+ change ++;
}
- D (fprintf (stderr, "FILLED GAP for %s in function %s\n",
- sym->name, currFunc ? currFunc->name : "UNKNOWN"));
- _G.totRegAssigned = bitVectSetBit(_G.totRegAssigned,sym->key);
- sym->isspilt = sym->spillA = 0 ;
- sym->usl.spillLoc->allocreq--;
- freeAllRegs();
+ if (!change) break;
}
}
/* replace the result with the result of */
/* this assignment and remove this assignment */
bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
+
IC_RESULT (dic) = IC_RESULT (ic);
if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
#define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
+/*-----------------------------------------------------------------*/
+/* packRegsDPTRnuse - color live ranges that can go into extra DPTRS */
+/*-----------------------------------------------------------------*/
+static int packRegsDPTRnuse( operand *op , int dptr)
+{
+ int i,key;
+ iCode *ic;
+
+ if (!IS_SYMOP(op) || !IS_ITEMP(op)) return 0;
+ if (OP_SYMBOL(op)->remat || OP_SYMBOL(op)->ruonly || OP_SYMBOL(op)->dptr)
+ return 0;
+
+ /* first check if any overlapping liverange has already been
+ assigned to this DPTR */
+ if (OP_SYMBOL(op)->clashes) {
+ for (i = 0 ; i < OP_SYMBOL(op)->clashes->size ; i++ ) {
+ symbol *sym;
+ if (bitVectBitValue(OP_SYMBOL(op)->clashes,i)) {
+ sym = hTabItemWithKey(liveRanges,i);
+ if (sym->dptr == dptr) return 0;
+ }
+ }
+ }
+
+ /* future for more dptrs */
+ if (dptr > 1) {
+ OP_SYMBOL(op)->dptr = dptr;
+ return 1;
+ }
+
+ /* DPTR1 is special since it is also used as a scratch by the backend .
+ so we walk thru the entire live range of this operand and make sure
+ DPTR1 will not be used by the backed . The logic here is to find out if
+ more than one operand in an icode is in far space then we give up : we
+ don't keep it live across functions for now
+ */
+
+ ic = hTabFirstItemWK(iCodeSeqhTab,OP_SYMBOL(op)->liveFrom);
+ for (; ic && ic->seq <= OP_SYMBOL(op)->liveTo;
+ ic = hTabNextItem(iCodeSeqhTab,&key)) {
+ int nfs =0;
+
+ if (ic->op == CALL || ic->op == PCALL) return 0;
+
+ /* single operand icode are ok */
+ if (ic->op == IFX || ic->op == IPUSH)
+ continue ;
+
+ if (ic->op == SEND ) {
+ if (ic->argreg != 1) return 0;
+ else continue ;
+ }
+ /* two special cases first */
+ if (POINTER_GET(ic) && !isOperandEqual(IC_LEFT(ic),op) && /* pointer get */
+ !OP_SYMBOL(IC_LEFT(ic))->ruonly && /* with result in far space */
+ (isOperandInFarSpace(IC_RESULT(ic)) &&
+ !isOperandInReg(IC_RESULT(ic)))) {
+ return 0;
+ }
+
+ if (POINTER_SET(ic) && !isOperandEqual(IC_RESULT(ic),op) && /* pointer set */
+ !OP_SYMBOL(IC_RESULT(ic))->ruonly && /* with right in far space */
+ (isOperandInFarSpace(IC_RIGHT(ic)) &&
+ !isOperandInReg(IC_RIGHT(ic)))) {
+ return 0;
+ }
+
+ if (IC_RESULT(ic) && IS_SYMOP(IC_RESULT(ic)) && /* if symbol operand */
+ !isOperandEqual(IC_RESULT(ic),op) && /* not the same as this */
+ ((isOperandInFarSpace(IC_RESULT(ic)) || /* in farspace or */
+ OP_SYMBOL(IC_RESULT(ic))->onStack) && /* on the stack */
+ !isOperandInReg(IC_RESULT(ic)))) { /* and not in register */
+ nfs++;
+ }
+ /* same for left */
+ if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic)) && /* if symbol operand */
+ !isOperandEqual(IC_LEFT(ic),op) && /* not the same as this */
+ ((isOperandInFarSpace(IC_LEFT(ic)) || /* in farspace or */
+ OP_SYMBOL(IC_LEFT(ic))->onStack) && /* on the stack */
+ !isOperandInReg(IC_LEFT(ic)))) { /* and not in register */
+ nfs++;
+ }
+ /* same for right */
+ if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic)) && /* if symbol operand */
+ !isOperandEqual(IC_RIGHT(ic),op) && /* not the same as this */
+ ((isOperandInFarSpace(IC_RIGHT(ic)) || /* in farspace or */
+ OP_SYMBOL(IC_RIGHT(ic))->onStack) && /* on the stack */
+ !isOperandInReg(IC_RIGHT(ic)))) { /* and not in register */
+ nfs++;
+ }
+
+ if (nfs > 1) return 0;
+ }
+ OP_SYMBOL(op)->dptr = dptr;
+ return 1;
+}
+
/*-----------------------------------------------------------------*/
/* packRegsDPTRuse : - will reduce some registers for single Use */
/*-----------------------------------------------------------------*/
/* if PCALL cannot be sure give up */
if (ic->op == PCALL) return NULL;
+ /* if SEND & not the first parameter then giveup */
+ if (ic->op == SEND && ic->argreg != 1) return NULL;
+
/* if CALL then make sure it is VOID || return value not used
or the return value is assigned to this one */
if (ic->op == CALL) {
/* if this is a cast to a bigger type */
if (ic->op==CAST) {
- if (getSize(OP_SYM_TYPE(IC_RESULT(ic))) >
+ if (!IS_PTR(OP_SYM_TYPE(IC_RESULT(ic))) &&
+ getSize(OP_SYM_TYPE(IC_RESULT(ic))) >
getSize(OP_SYM_TYPE(IC_RIGHT(ic)))) {
return 0;
}
/* general case */
if (IC_RESULT(ic) && IS_SYMOP(IC_RESULT(ic)) &&
!isOperandEqual(IC_RESULT(ic),op) &&
- ((isOperandInFarSpace(IC_RESULT(ic)) && !isOperandInReg(IC_RESULT(ic))) ||
- OP_SYMBOL(IC_RESULT(ic))->ruonly ||
- OP_SYMBOL(IC_RESULT(ic))->onStack)) return NULL;
+ ( ( ( isOperandInFarSpace(IC_RESULT(ic)) || OP_SYMBOL(IC_RESULT(ic))->onStack) &&
+ !isOperandInReg(IC_RESULT(ic))) ||
+ OP_SYMBOL(IC_RESULT(ic))->ruonly)) return NULL;
if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic)) &&
!isOperandEqual(IC_RIGHT(ic),op) &&
(OP_SYMBOL(IC_RIGHT(ic))->liveTo >= ic->seq ||
IS_TRUE_SYMOP(IC_RIGHT(ic)) ||
OP_SYMBOL(IC_RIGHT(ic))->ruonly) &&
- ((isOperandInFarSpace(IC_RIGHT(ic)) && !isOperandInReg(IC_RIGHT(ic)))||
- OP_SYMBOL(IC_RIGHT(ic))->onStack)) return NULL;
+ ( ( isOperandInFarSpace(IC_RIGHT(ic)) || OP_SYMBOL(IC_RIGHT(ic))->onStack) &&
+ !isOperandInReg(IC_RIGHT(ic))) ) return NULL;
if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic)) &&
!isOperandEqual(IC_LEFT(ic),op) &&
(OP_SYMBOL(IC_LEFT(ic))->liveTo > ic->seq ||
IS_TRUE_SYMOP(IC_LEFT(ic)) ||
OP_SYMBOL(IC_LEFT(ic))->ruonly) &&
- ((isOperandInFarSpace(IC_LEFT(ic)) && !isOperandInReg(IC_LEFT(ic)))||
- OP_SYMBOL(IC_LEFT(ic))->onStack)) return NULL;
+ ( ( isOperandInFarSpace(IC_LEFT(ic)) || OP_SYMBOL(IC_LEFT(ic))->onStack) &&
+ !isOperandInReg(IC_LEFT(ic))) ) return NULL;
if (IC_LEFT(ic) && IC_RIGHT(ic) &&
IS_ITEMP(IC_LEFT(ic)) && IS_ITEMP(IC_RIGHT(ic)) &&
/* make sure that the result of this icode is not on the
stack, since acc is used to compute stack offset */
-#if 0
- if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
- OP_SYMBOL (IC_RESULT (uic))->onStack)
- return;
-#else
if (isOperandOnStack(IC_RESULT(uic)))
return;
-#endif
/* if either one of them in far space then we cannot */
if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
IC_LEFT (uic)->key != IC_RESULT (ic)->key)
return;
-#if 0
- // this is too dangerous and need further restrictions
- // see bug #447547
-
- /* if one of them is a literal then we can */
- if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
- (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
- {
- OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
- return;
- }
-#endif
-
/* if the other one is not on stack then we can */
if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
(IS_ITEMP (IC_RIGHT (uic)) ||
iCode *dic, *lic;
bitVect *dbv;
- if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
+ if ((ic->op != IPUSH && ic->op != SEND) || !IS_ITEMP (IC_LEFT (ic)))
return;
/* must have only definition & one usage */
if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) {
OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq;
}
+ for (lic = ic; lic && lic != dic; lic = lic->prev)
+ {
+ bitVectUnSetBit (lic->rlive, IC_LEFT (ic)->key);
+ if (IS_ITEMP (IC_RIGHT (dic)))
+ bitVectSetBit (lic->rlive, IC_RIGHT (dic)->key);
+ }
/* we now we know that it has one & only one def & use
and the that the definition is an assignment */
IC_LEFT (ic) = IC_RIGHT (dic);
}
+ /* if this is an itemp & used as a pointer
+ & assigned to a literal then remat */
+ if (IS_ASSIGN_ICODE(ic) &&
+ IS_ITEMP(IC_RESULT(ic)) &&
+ bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
+ isOperandLiteral(IC_RIGHT(ic)))
+ {
+ OP_SYMBOL (IC_RESULT (ic))->remat = 1;
+ OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
+ OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
+ }
+
/* if straight assignment then carry remat flag if
this is the only definition */
if (ic->op == '=' &&
cast is remat, then we can remat this cast as well */
if (ic->op == CAST &&
IS_SYMOP(IC_RIGHT(ic)) &&
+ !OP_SYMBOL(IC_RESULT(ic))->isreqv &&
OP_SYMBOL(IC_RIGHT(ic))->remat ) {
sym_link *to_type = operandType(IC_LEFT(ic));
sym_link *from_type = operandType(IC_RIGHT(ic));
if (ic->op == RETURN && IS_SYMOP (IC_LEFT(ic)))
OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
+ if (ic->op == RECEIVE && ic->argreg == 1 &&
+ getSize (operandType(IC_RESULT(ic))) <= 3)
+ OP_SYMBOL (IC_RESULT(ic))->uptr = 1;
+
if (!SKIP_IC2 (ic))
{
/* if we are using a symbol on the stack
}
}
-#if 0
- /* if the condition of an if instruction
- is defined in the previous instruction then
- mark the itemp as a conditional */
- if ((IS_CONDITIONAL (ic) ||
- (IS_BITWISE_OP(ic) && isBitwiseOptimizable(ic))) &&
- ic->next && ic->next->op == IFX &&
- isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
- OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
- {
-
- OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
- continue;
- }
-#else
/* if the condition of an if instruction
is defined in the previous instruction and
this is the only usage then
OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
continue;
}
-#endif
-
+#if 1
/* reduce for support function calls */
if (ic->supportRtn || ic->op == '+' || ic->op == '-')
packRegsForSupport (ic, ebp);
-
+#endif
/* some cases the redundant moves can
- can be eliminated for return statements */
- if ((ic->op == RETURN || ic->op == SEND) &&
+ can be eliminated for return statements . Can be elminated for the first SEND */
+ if ((ic->op == RETURN ||
+ ((ic->op == SEND || ic->op == RECEIVE)&& ic->argreg == 1)) &&
!isOperandInFarSpace (IC_LEFT (ic)) &&
!options.model) {
-------------
push V1
*/
- if (ic->op == IPUSH)
+ if (ic->op == IPUSH || ic->op == SEND)
{
packForPush (ic, ebp);
}
if ((IS_ARITHMETIC_OP (ic)
|| IS_CONDITIONAL(ic)
|| IS_BITWISE_OP (ic)
- || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == CALL
+ || ic->op == LEFT_OP || ic->op == RIGHT_OP
|| (ic->op == ADDRESS_OF && isOperandOnStack (IC_LEFT (ic)))
) &&
IS_ITEMP (IC_RESULT (ic)) &&