X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fmcs51%2Fgen.c;h=529be381c2aeb3542a8c2f7e2680e27ca8104c27;hb=717cf743781d6240414f10bc16b532bf54c9efd1;hp=2d70a6af55b5b93cd6599ed7bfdd0ad03dd065b3;hpb=29f45bc8d565ff6138f0ee39b60b5d7d317a3f75;p=fw%2Fsdcc diff --git a/src/mcs51/gen.c b/src/mcs51/gen.c index 2d70a6af..529be381 100644 --- a/src/mcs51/gen.c +++ b/src/mcs51/gen.c @@ -28,6 +28,9 @@ Made everything static -------------------------------------------------------------------------*/ +//#define D(x) +#define D(x) x + #include #include #include @@ -35,19 +38,6 @@ #include "SDCCglobl.h" #include "newalloc.h" -#ifdef HAVE_SYS_ISA_DEFS_H -#include -#else -#ifdef HAVE_ENDIAN_H -#include -#else -#if !defined(__BORLANDC__) && !defined(_MSC_VER) -#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 - #include "common.h" #include "SDCCpeeph.h" #include "ralloc.h" @@ -86,6 +76,10 @@ static struct } _G; +static char *rb1regs[] = { + "b1_0","b1_1","b1_2","b1_3","b1_4","b1_5","b1_6","b1_7" +}; + extern int mcs51_ptrRegReq; extern int mcs51_nRegs; extern FILE *codeOutFile; @@ -94,7 +88,7 @@ static void saveRBank (int, iCode *, bool); (IC_RESULT(x) && IC_RESULT(x)->aop && \ IC_RESULT(x)->aop->type == AOP_STK ) -#define MOVA(x) if (strcmp(x,"a") && strcmp(x,"acc")) emitcode("mov","a,%s",x); +#define MOVA(x) mova(x) /* use function to avoid multiple eval */ #define CLRC emitcode("clr","c") #define SETC emitcode("setb","c") @@ -148,6 +142,19 @@ emitcode (char *inst, char *fmt,...) va_end (ap); } +/*-----------------------------------------------------------------*/ +/* mova - moves specified value into accumulator */ +/*-----------------------------------------------------------------*/ +static void +mova (char *x) +{ + /* do some early peephole optimization */ + if (!strcmp(x, "a") || !strcmp(x, "acc")) + return; + + emitcode("mov","a,%s", x); +} + /*-----------------------------------------------------------------*/ /* getFreePtr - returns r0 or r1 whichever is free or can be pushed */ /*-----------------------------------------------------------------*/ @@ -162,9 +169,9 @@ getFreePtr (iCode * ic, asmop ** aopp, bool result) /* 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; } @@ -223,20 +230,29 @@ getFreePtr (iCode * ic, asmop ** aopp, bool result) (*aopp)->type = AOP_R1; return mcs51_regWithIdx (R1_IDX); } - endOfWorld: - /* I said end of world but not quite end of world yet */ - /* if this is a result then we can push it on the stack */ - if (result) - { - (*aopp)->type = AOP_STK; - return NULL; + /* I said end of world, but not quite end of world yet */ + if (result) { + /* we can push it on the stack */ + (*aopp)->type = AOP_STK; + return NULL; + } else { + /* in the case that result AND left AND right needs a pointer reg + we can safely use the result's */ + if (bitVectBitValue (mcs51_rUmaskForOp(IC_RESULT(ic)), R0_IDX)) { + (*aopp)->type = AOP_R0; + return mcs51_regWithIdx (R0_IDX); } + if (bitVectBitValue (mcs51_rUmaskForOp(IC_RESULT(ic)), R1_IDX)) { + (*aopp)->type = AOP_R1; + return mcs51_regWithIdx (R1_IDX); + } + } - /* other wise this is true end of the world */ + /* now this is REALLY the end of the world */ werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "getFreePtr should never reach here"); - exit (0); + exit (1); } /*-----------------------------------------------------------------*/ @@ -270,7 +286,12 @@ static asmop * aopForSym (iCode * ic, symbol * sym, bool result) { asmop *aop; - memmap *space = SPEC_OCLS (sym->etype); + memmap *space; + + wassertl (ic != NULL, "Got a null iCode"); + wassertl (sym != NULL, "Got a null symbol"); + + space = SPEC_OCLS (sym->etype); /* if already has one */ if (sym->aop) @@ -338,8 +359,8 @@ aopForSym (iCode * ic, symbol * sym, bool result) 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; } @@ -365,6 +386,7 @@ aopForRemat (symbol * sym) { iCode *ic = sym->rematiCode; asmop *aop = newAsmop (AOP_IMMD); + int ptr_type=0; int val = 0; for (;;) @@ -373,8 +395,17 @@ aopForRemat (symbol * sym) 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; } @@ -387,8 +418,15 @@ aopForRemat (symbol * sym) 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; } @@ -525,7 +563,7 @@ aopOp (operand * op, iCode * ic, bool result) } /* if already has a asmop then continue */ - if (op->aop) + if (op->aop ) return; /* if the underlying symbol has a aop */ @@ -552,7 +590,6 @@ aopOp (operand * op, iCode * ic, bool result) sym = OP_SYMBOL (op); - /* if the type is a conditional */ if (sym->regType == REG_CND) { @@ -589,6 +626,7 @@ aopOp (operand * op, iCode * ic, bool result) if (sym->ruonly) { unsigned i; + aop = op->aop = sym->aop = newAsmop (AOP_STR); aop->size = getSize (sym->type); for (i = 0; i < fReturnSizeMCS51; i++) @@ -597,6 +635,10 @@ aopOp (operand * op, iCode * ic, bool result) } /* else spill location */ + if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) { + /* force a new aop if sizes differ */ + sym->usl.spillLoc->aop = NULL; + } sym->aop = op->aop = aop = aopForSym (ic, sym->usl.spillLoc, result); aop->size = getSize (sym->type); @@ -718,6 +760,51 @@ dealloc: } } +/*-----------------------------------------------------------------*/ +/* aopGetUsesAcc - indicates ahead of time whether aopGet() will */ +/* clobber the accumulator */ +/*-----------------------------------------------------------------*/ +static bool +aopGetUsesAcc (asmop *aop, int offset) +{ + if (offset > (aop->size - 1)) + return FALSE; + + switch (aop->type) + { + + case AOP_R0: + case AOP_R1: + if (aop->paged) + return TRUE; + return FALSE; + case AOP_DPTR: + return TRUE; + case AOP_IMMD: + return FALSE; + case AOP_DIR: + return FALSE; + case AOP_REG: + wassert(strcmp(aop->aopu.aop_reg[offset]->name, "a")); + return FALSE; + case AOP_CRY: + return TRUE; + case AOP_ACC: + return TRUE; + case AOP_LIT: + return FALSE; + case AOP_STR: + if (strcmp (aop->aopu.aop_str[offset], "a") == 0) + return TRUE; + return FALSE; + default: + /* Error case --- will have been caught already */ + wassert(0); + return FALSE; + } +} + + /*-----------------------------------------------------------------*/ /* aopGet - for fetching value of the aop */ /*-----------------------------------------------------------------*/ @@ -764,6 +851,12 @@ aopGet (asmop * aop, int offset, bool bit16, bool dname) return rs; case AOP_DPTR: + if (aop->code && aop->coff==0 && offset>=1) { + emitcode ("mov", "a,#0x%02x", offset); + emitcode ("movc", "a,@a+dptr"); + return (dname ? "acc" : "a"); + } + while (offset > aop->coff) { emitcode ("inc", "dptr"); @@ -790,15 +883,17 @@ aopGet (asmop * aop, int offset, bool bit16, bool dname) 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; @@ -846,7 +941,7 @@ aopGet (asmop * aop, int offset, bool bit16, bool dname) werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "aopget got unsupported aop->type"); - exit (0); + exit (1); } /*-----------------------------------------------------------------*/ /* aopPut - puts a string for a aop */ @@ -860,7 +955,7 @@ aopPut (asmop * aop, char *s, int offset) { werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "aopPut got offset > aop->size"); - exit (0); + exit (1); } /* will assign value to value */ @@ -905,7 +1000,7 @@ aopPut (asmop * aop, char *s, int offset) { werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "aopPut writting to code space"); - exit (0); + exit (1); } while (offset > aop->coff) @@ -976,7 +1071,12 @@ aopPut (asmop * aop, char *s, int offset) 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; @@ -1002,11 +1102,8 @@ aopPut (asmop * aop, char *s, int offset) MOVA (s); } { - symbol *lbl = newiTempLabel (NULL); - emitcode ("clr", "c"); - emitcode ("jz", "%05d$", lbl->key + 100); - emitcode ("cpl", "c"); - emitcode ("", "%05d$:", lbl->key + 100); + /* set C, if a >= 1 */ + emitcode ("add", "a,#0xff"); emitcode ("mov", "%s,c", aop->aopu.aop_dir); } } @@ -1031,7 +1128,7 @@ aopPut (asmop * aop, char *s, int offset) default: werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "aopPut got unsupported aop->type"); - exit (0); + exit (1); } } @@ -1114,6 +1211,8 @@ genNotFloat (operand * op, operand * res) char *l; symbol *tlbl; + D(emitcode ("; genNotFloat","")); + /* we will put 127 in the first byte of the result */ aopPut (AOP (res), "#127", 0); @@ -1242,6 +1341,8 @@ genNot (iCode * ic) symbol *tlbl; sym_link *optype = operandType (IC_LEFT (ic)); + D(emitcode ("; genNot","")); + /* assign asmOps to operand & result */ aopOp (IC_LEFT (ic), ic, FALSE); aopOp (IC_RESULT (ic), ic, TRUE); @@ -1284,23 +1385,29 @@ genCpl (iCode * ic) { int offset = 0; int size; + symbol *tlbl; + D(emitcode ("; genCpl","")); /* assign asmOps to operand & result */ aopOp (IC_LEFT (ic), ic, FALSE); aopOp (IC_RESULT (ic), ic, TRUE); - /* if both are in bit space then - a special case */ - if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY && - AOP_TYPE (IC_LEFT (ic)) == AOP_CRY) - { - + /* special case if in bit space */ + if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY) { + if (AOP_TYPE (IC_LEFT (ic)) == AOP_CRY) { emitcode ("mov", "c,%s", IC_LEFT (ic)->aop->aopu.aop_dir); emitcode ("cpl", "c"); emitcode ("mov", "%s,c", IC_RESULT (ic)->aop->aopu.aop_dir); goto release; } + tlbl=newiTempLabel(NULL); + emitcode ("cjne", "%s,#0x01,%05d$", + aopGet(AOP(IC_LEFT(ic)), 0, FALSE,FALSE), tlbl->key+100); + emitcode ("", "%05d$:", tlbl->key+100); + outBitC (IC_RESULT(ic)); + goto release; + } size = AOP_SIZE (IC_RESULT (ic)); while (size--) @@ -1326,15 +1433,12 @@ genUminusFloat (operand * op, operand * result) { int size, offset = 0; char *l; - /* for this we just need to flip the - first it then copy the rest in place */ - size = AOP_SIZE (op) - 1; - l = aopGet (AOP (op), 3, FALSE, FALSE); - MOVA (l); + D(emitcode ("; genUminusFloat","")); - emitcode ("cpl", "acc.7"); - aopPut (AOP (result), "a", 3); + /* for this we just copy and then flip the bit */ + + size = AOP_SIZE (op) - 1; while (size--) { @@ -1343,6 +1447,13 @@ genUminusFloat (operand * op, operand * result) offset); offset++; } + + l = aopGet (AOP (op), offset, FALSE, FALSE); + + MOVA (l); + + emitcode ("cpl", "acc.7"); + aopPut (AOP (result), "a", offset); } /*-----------------------------------------------------------------*/ @@ -1355,6 +1466,8 @@ genUminus (iCode * ic) sym_link *optype, *rtype; + D(emitcode ("; genUminus","")); + /* assign asmops */ aopOp (IC_LEFT (ic), ic, FALSE); aopOp (IC_RESULT (ic), ic, TRUE); @@ -1430,7 +1543,6 @@ saveRegisters (iCode * lic) int i; iCode *ic; bitVect *rsave; - sym_link *detype; /* look for call */ for (ic = lic; ic; ic = ic->next) @@ -1443,15 +1555,19 @@ saveRegisters (iCode * lic) return; } - /* if the registers have been saved already then + /* if the registers have been saved already or don't need to be then do nothing */ - if (ic->regsSaved || (OP_SYMBOL (IC_LEFT (ic))->calleeSave)) + if (ic->regsSaved) return; - - /* find the registers in use at this time - and push them away to safety */ - rsave = bitVectCplAnd (bitVectCopy (ic->rMask), - ic->rUsed); + if (IS_SYMOP(IC_LEFT(ic)) && + (IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type) || + IFFUNC_ISNAKED(OP_SYM_TYPE(IC_LEFT (ic))))) + return; + + /* safe the registers in use at this time but skip the + ones for the result */ + rsave = bitVectCplAnd (bitVectCopy (ic->rMask), + mcs51_rUmaskForOp (IC_RESULT(ic))); ic->regsSaved = 1; if (options.useXstack) @@ -1481,18 +1597,8 @@ saveRegisters (iCode * lic) if (bitVectBitValue (rsave, i)) emitcode ("push", "%s", mcs51_regWithIdx (i)->dname); } - - detype = getSpec (operandType (IC_LEFT (ic))); - -#if 0 // why should we do this here??? jwk20011105 - if (detype && - (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype)) && - IS_ISR (currFunc->etype) && - !ic->bankSaved) - saveRBank (SPEC_BANK (detype), ic, TRUE); -#endif - } + /*-----------------------------------------------------------------*/ /* unsaveRegisters - pop the pushed registers */ /*-----------------------------------------------------------------*/ @@ -1501,10 +1607,11 @@ unsaveRegisters (iCode * ic) { 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); + + /* restore the registers in use at this time but skip the + ones for the result */ + rsave = bitVectCplAnd (bitVectCopy (ic->rMask), + mcs51_rUmaskForOp (IC_RESULT(ic))); if (options.useXstack) { @@ -1584,6 +1691,8 @@ genXpush (iCode * ic) regs *r; int size, offset = 0; + D(emitcode ("; genXpush","")); + aopOp (IC_LEFT (ic), ic, FALSE); r = getFreePtr (ic, &aop, FALSE); @@ -1618,6 +1727,8 @@ genIpush (iCode * ic) int size, offset = 0; char *l; + 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) @@ -1688,6 +1799,7 @@ genIpop (iCode * ic) { int size, offset; + D(emitcode ("; genIpop","")); /* if the temp was not pushed then */ if (OP_SYMBOL (IC_LEFT (ic))->isspilt) @@ -1836,58 +1948,72 @@ saveRBank (int bank, iCode * ic, bool pushPsw) } } +/*-----------------------------------------------------------------*/ +/* genSend - gen code for SEND */ +/*-----------------------------------------------------------------*/ +static void genSend(set *sendSet) +{ + iCode *sic; + int rb1_count = 0 ; + + for (sic = setFirstItem (_G.sendSet); sic; + sic = setNextItem (_G.sendSet)) { + int size, offset = 0; + aopOp (IC_LEFT (sic), sic, FALSE); + size = AOP_SIZE (IC_LEFT (sic)); + + if (sic->argreg == 1) { + while (size--) { + char *l = aopGet (AOP (IC_LEFT (sic)), offset, + FALSE, FALSE); + if (strcmp (l, fReturn[offset])) + emitcode ("mov", "%s,%s", fReturn[offset], l); + offset++; + } + rb1_count = 0; + } else { + while (size--) { + emitcode ("mov","b1_%d,%s",rb1_count++, + aopGet (AOP (IC_LEFT (sic)), offset++,FALSE, FALSE)); + } + } + freeAsmop (IC_LEFT (sic), NULL, sic, TRUE); + } +} + /*-----------------------------------------------------------------*/ /* genCall - generates a call statement */ /*-----------------------------------------------------------------*/ static void genCall (iCode * ic) { - sym_link *detype; - bool restoreBank = FALSE; + sym_link *dtype; +// bool restoreBank = FALSE; bool swapBanks = FALSE; + D(emitcode("; genCall","")); + + dtype = operandType (IC_LEFT (ic)); /* 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; - aopOp (IC_LEFT (sic), sic, FALSE); - size = AOP_SIZE (IC_LEFT (sic)); - while (size--) - { - char *l = aopGet (AOP (IC_LEFT (sic)), offset, - FALSE, FALSE); - if (strcmp (l, fReturn[offset])) - emitcode ("mov", "%s,%s", - fReturn[offset], - l); - offset++; - } - 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 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)) + dtype = operandType (IC_LEFT (ic)); + if (currFunc && dtype && !IFFUNC_ISNAKED(dtype) && + (FUNC_REGBANK (currFunc->type) != FUNC_REGBANK (dtype)) && + !IFFUNC_ISISR (dtype)) { - if (!ic->bankSaved) - { - /* This is unexpected; the bank should have been saved in - * genFunction. - */ - saveRBank (SPEC_BANK (detype), ic, FALSE); - restoreBank = TRUE; - } swapBanks = TRUE; } @@ -1898,7 +2024,7 @@ genCall (iCode * ic) if (swapBanks) { emitcode ("mov", "psw,#0x%02x", - ((SPEC_BANK(detype)) << 3) & 0xff); + ((FUNC_REGBANK(dtype)) << 3) & 0xff); } /* make the call */ @@ -1909,12 +2035,13 @@ genCall (iCode * ic) if (swapBanks) { emitcode ("mov", "psw,#0x%02x", - ((SPEC_BANK(currFunc->etype)) << 3) & 0xff); + ((FUNC_REGBANK(currFunc->type)) << 3) & 0xff); } /* if we need assign a result value */ if ((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))) { @@ -1945,37 +2072,44 @@ genCall (iCode * ic) } /* if we hade saved some registers then unsave them */ - if (ic->regsSaved && !(OP_SYMBOL (IC_LEFT (ic))->calleeSave)) + if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype)) unsaveRegisters (ic); - /* if register bank was saved then pop them */ - if (restoreBank) - unsaveRBank (SPEC_BANK (detype), ic, FALSE); +// /* if register bank was saved then pop them */ +// if (restoreBank) +// unsaveRBank (FUNC_REGBANK (dtype), ic, FALSE); } /*-----------------------------------------------------------------*/ -/* genPcall - generates a call by pointer statement */ +/* -10l - generates a call by pointer statement */ /*-----------------------------------------------------------------*/ static void genPcall (iCode * ic) { - sym_link *detype; + sym_link *dtype; symbol *rlbl = newiTempLabel (NULL); +// bool restoreBank=FALSE; + bool swapBanks = FALSE; + D(emitcode("; genPCall","")); /* if caller saves & we have not saved then */ if (!ic->regsSaved) saveRegisters (ic); - /* 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 && - IS_ISR (currFunc->etype) && - (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype))) - saveRBank (SPEC_BANK (detype), ic, TRUE); - + dtype = operandType (IC_LEFT (ic))->next; + if (currFunc && dtype && !IFFUNC_ISNAKED(dtype) && + (FUNC_REGBANK (currFunc->type) != FUNC_REGBANK (dtype)) && + !IFFUNC_ISISR (dtype)) + { +// saveRBank (FUNC_REGBANK (dtype), ic, TRUE); +// restoreBank=TRUE; + swapBanks = TRUE; + // need caution message to user here + } /* push the return address on to the stack */ emitcode ("mov", "a,#%05d$", (rlbl->key + 100)); @@ -1993,33 +2127,27 @@ genPcall (iCode * ic) /* 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; - aopOp (IC_LEFT (sic), sic, FALSE); - size = AOP_SIZE (IC_LEFT (sic)); - while (size--) - { - char *l = aopGet (AOP (IC_LEFT (sic)), offset, - FALSE, FALSE); - if (strcmp (l, fReturn[offset])) - emitcode ("mov", "%s,%s", - fReturn[offset], - l); - offset++; - } - freeAsmop (IC_LEFT (sic), NULL, sic, TRUE); - } - _G.sendSet = NULL; + genSend(reverseSet(_G.sendSet)); + _G.sendSet = NULL; } + if (swapBanks) + { + emitcode ("mov", "psw,#0x%02x", + ((FUNC_REGBANK(dtype)) << 3) & 0xff); + } + + /* make the call */ emitcode ("ret", ""); emitcode ("", "%05d$:", (rlbl->key + 100)); + 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 || @@ -2053,17 +2181,14 @@ genPcall (iCode * ic) } - /* if register bank was saved then unsave them */ - if (detype && - (SPEC_BANK (currFunc->etype) != - SPEC_BANK (detype))) - unsaveRBank (SPEC_BANK (detype), ic, TRUE); +// /* if register bank was saved then unsave them */ +// if (restoreBank) +// unsaveRBank (FUNC_REGBANK (dtype), ic, TRUE); /* if we hade saved some registers then unsave them */ - if (ic->regsSaved) + if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype)) unsaveRegisters (ic); - } /*-----------------------------------------------------------------*/ @@ -2119,8 +2244,9 @@ static void genFunction (iCode * ic) { symbol *sym; - sym_link *fetype; + sym_link *ftype; bool switchedPSW = FALSE; + int calleesaves_saved_register = -1; _G.nRegsSaved = 0; /* create the function header */ @@ -2129,19 +2255,25 @@ genFunction (iCode * ic) 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 < mcs51_nRegs; i++) { if (strcmp (regs8051[i].base, "0") == 0) @@ -2158,7 +2290,7 @@ genFunction (iCode * ic) /* 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")) @@ -2172,13 +2304,13 @@ genFunction (iCode * ic) /* 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; @@ -2197,10 +2329,17 @@ genFunction (iCode * ic) } else { + /* this function has a function call cannot determines register usage so we will have to push the entire bank */ - saveRBank (0, ic, FALSE); + saveRBank (0, ic, FALSE); + if (options.parms_in_bank1) { + int i; + for (i=0; i < 8 ; i++ ) { + emitcode ("push","%s",rb1regs[i]); + } + } } } else @@ -2215,7 +2354,7 @@ genFunction (iCode * ic) */ unsigned long banksToSave = 0; - if (sym->hasFcall) + if (IFFUNC_HASFCALL(sym->type)) { #define MAX_REGISTER_BANKS 4 @@ -2233,20 +2372,20 @@ genFunction (iCode * ic) if (i->op == CALL) { - sym_link *detype; + sym_link *dtype; - detype = getSpec(operandType (IC_LEFT(i))); - if (detype - && SPEC_BANK(detype) != SPEC_BANK(sym->etype)) + dtype = operandType (IC_LEFT(i)); + if (dtype + && FUNC_REGBANK(dtype) != FUNC_REGBANK(sym->type)) { /* Mark this bank for saving. */ - if (SPEC_BANK(detype) >= MAX_REGISTER_BANKS) + if (FUNC_REGBANK(dtype) >= MAX_REGISTER_BANKS) { - werror(E_NO_SUCH_BANK, SPEC_BANK(detype)); + werror(E_NO_SUCH_BANK, FUNC_REGBANK(dtype)); } else { - banksToSave |= (1 << SPEC_BANK(detype)); + banksToSave |= (1 << FUNC_REGBANK(dtype)); } /* And note that we don't need to do it in @@ -2278,7 +2417,7 @@ genFunction (iCode * ic) */ emitcode ("push", "psw"); emitcode ("mov", "psw,#0x%02x", - (SPEC_BANK (sym->etype) << 3) & 0x00ff); + (FUNC_REGBANK (sym->type) << 3) & 0x00ff); switchedPSW = TRUE; } @@ -2290,6 +2429,7 @@ genFunction (iCode * ic) } } } + // TODO: this needs a closer look SPEC_ISR_SAVED_BANKS(currFunc->etype) = banksToSave; } } @@ -2297,7 +2437,7 @@ genFunction (iCode * ic) { /* 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; @@ -2310,6 +2450,9 @@ genFunction (iCode * ic) if (bitVectBitValue (sym->regsUsed, i) || (mcs51_ptrRegReq && (i == R0_IDX || i == R1_IDX))) { + /* remember one saved register for later usage */ + if (calleesaves_saved_register < 0) + calleesaves_saved_register = i; emitcode ("push", "%s", mcs51_regWithIdx (i)->dname); _G.nRegsSaved++; } @@ -2319,14 +2462,14 @@ genFunction (iCode * ic) } /* set the register bank to the desired value */ - if ((SPEC_BANK (sym->etype) || IS_ISR (sym->etype)) + if (( /* FUNC_REGBANK (sym->type) || */ IFFUNC_ISISR (sym->type)) && !switchedPSW) { emitcode ("push", "psw"); - emitcode ("mov", "psw,#0x%02x", (SPEC_BANK (sym->etype) << 3) & 0x00ff); + emitcode ("mov", "psw,#0x%02x", (FUNC_REGBANK (sym->type) << 3) & 0x00ff); } - if (IS_RENT (sym->etype) || options.stackAuto) + if (IFFUNC_ISREENT (sym->type) || options.stackAuto) { if (options.useXstack) @@ -2360,6 +2503,34 @@ genFunction (iCode * ic) emitcode ("mov", "sp,a"); } + else if (i > 5) + { + if (IFFUNC_CALLEESAVES(sym->type)) + { + /* if it's a callee-saves function we need a saved register */ + if (calleesaves_saved_register >= 0) + { + emitcode ("mov", "%s,a", mcs51_regWithIdx (calleesaves_saved_register)->dname); + emitcode ("mov", "a,sp"); + emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff)); + emitcode ("mov", "sp,a"); + emitcode ("mov", "a,%s", mcs51_regWithIdx (calleesaves_saved_register)->dname); + } + else + /* do it the hard way */ + while (i--) + emitcode ("inc", "sp"); + } + else + { + /* not callee-saves, we can clobber r0 */ + emitcode ("mov", "r0,a"); + emitcode ("mov", "a,sp"); + emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff)); + emitcode ("mov", "sp,a"); + emitcode ("mov", "a,r0"); + } + } else while (i--) emitcode ("inc", "sp"); @@ -2383,7 +2554,13 @@ genEndFunction (iCode * ic) { symbol *sym = OP_SYMBOL (IC_LEFT (ic)); - if (IS_RENT (sym->etype) || options.stackAuto) + if (IFFUNC_ISNAKED(sym->type)) + { + emitcode(";", "naked function: no epilogue."); + return; + } + + if (IFFUNC_ISREENT (sym->type) || options.stackAuto) { emitcode ("mov", "%s,_bp", spname); } @@ -2399,7 +2576,7 @@ genEndFunction (iCode * ic) } - if ((IS_RENT (sym->etype) || options.stackAuto)) + if ((IFFUNC_ISREENT (sym->type) || options.stackAuto)) { if (options.useXstack) { @@ -2415,9 +2592,9 @@ genEndFunction (iCode * ic) } /* restore the register bank */ - if (SPEC_BANK (sym->etype) || IS_ISR (sym->etype)) + if ( /* FUNC_REGBANK (sym->type) || */ IFFUNC_ISISR (sym->type)) { - if (!SPEC_BANK (sym->etype) || !IS_ISR (sym->etype) + if (/* !FUNC_REGBANK (sym->type) || */ !IFFUNC_ISISR (sym->type) || !options.useXstack) { /* Special case of ISR using non-zero bank with useXstack @@ -2427,19 +2604,19 @@ genEndFunction (iCode * ic) } } - 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; @@ -2458,6 +2635,12 @@ genEndFunction (iCode * ic) } else { + if (options.parms_in_bank1) { + int i; + for (i = 7 ; i >= 0 ; i-- ) { + emitcode ("pop","%s",rb1regs[i]); + } + } /* this function has a function call cannot determines register usage so we will have to pop the entire bank */ @@ -2500,12 +2683,11 @@ genEndFunction (iCode * ic) 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 ==.", @@ -2522,10 +2704,10 @@ genEndFunction (iCode * ic) } else { - if (SPEC_CRTCL (sym->etype)) + if (IFFUNC_ISCRITICAL (sym->type)) emitcode ("setb", "ea"); - if (sym->calleeSave) + if (IFFUNC_CALLEESAVES(sym->type)) { int i; @@ -2544,7 +2726,7 @@ genEndFunction (iCode * ic) } /* if debug then send end of function */ - if (currFunc) + if (options.debug && currFunc) { _G.debugLine = 1; emitcode ("", "C$%s$%d$%d$%d ==.", @@ -2570,6 +2752,8 @@ genRet (iCode * ic) { int size, offset = 0, pushed = 0; + D(emitcode ("; genRet","")); + /* if we have no return value then just generate the "ret" */ if (!IC_LEFT (ic)) @@ -2661,9 +2845,15 @@ findLabelBackwards (iCode * ic, int key) ic = ic->prev; count++; + /* If we have any pushes or pops, we cannot predict the distance. + I don't like this at all, this should be dealt with in the + back-end */ + if (ic->op == IPUSH || ic->op == IPOP) { + return 0; + } + if (ic->op == LABEL && IC_LABEL (ic)->key == key) { - /* printf("findLabelBackwards = %d\n", count); */ return count; } } @@ -2691,8 +2881,11 @@ genPlusIncr (iCode * ic) if ((icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 4) return FALSE; - /* if increment 16 bits in register */ - if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))) && + D(emitcode ("; genPlusIncr","")); + + /* if increment >=16 bits in register or direct space */ + if ((AOP_TYPE(IC_LEFT(ic)) == AOP_REG || AOP_TYPE(IC_LEFT(ic)) == AOP_DIR ) && + sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))) && (size > 1) && (icount == 1)) { @@ -2720,15 +2913,15 @@ genPlusIncr (iCode * ic) emitcode ("inc", "%s", aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE)); if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG || IS_AOP_PREG (IC_RESULT (ic))) - emitcode ("cjne", "%s,#0x00,%05d$" - ,aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE) - ,tlbl->key + 100); + emitcode ("cjne", "%s,#0x00,%05d$", + aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE), + tlbl->key + 100); else { emitcode ("clr", "a"); - emitcode ("cjne", "a,%s,%05d$" - ,aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE) - ,tlbl->key + 100); + emitcode ("cjne", "a,%s,%05d$", + aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE), + tlbl->key + 100); } emitcode ("inc", "%s", aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE)); @@ -2736,13 +2929,13 @@ genPlusIncr (iCode * ic) { if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG || IS_AOP_PREG (IC_RESULT (ic))) - emitcode ("cjne", "%s,#0x00,%05d$" - ,aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE) - ,tlbl->key + 100); + emitcode ("cjne", "%s,#0x00,%05d$", + aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE), + tlbl->key + 100); else - emitcode ("cjne", "a,%s,%05d$" - ,aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE) - ,tlbl->key + 100); + emitcode ("cjne", "a,%s,%05d$", + aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE), + tlbl->key + 100); emitcode ("inc", "%s", aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE)); } @@ -2750,14 +2943,14 @@ genPlusIncr (iCode * ic) { if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG || IS_AOP_PREG (IC_RESULT (ic))) - emitcode ("cjne", "%s,#0x00,%05d$" - ,aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE) - ,tlbl->key + 100); + emitcode ("cjne", "%s,#0x00,%05d$", + aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE), + tlbl->key + 100); else { - emitcode ("cjne", "a,%s,%05d$" - ,aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE) - ,tlbl->key + 100); + emitcode ("cjne", "a,%s,%05d$", + aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE), + tlbl->key + 100); } emitcode ("inc", "%s", aopGet (AOP (IC_RESULT (ic)), MSB32, FALSE, FALSE)); } @@ -2826,6 +3019,8 @@ outBitAcc (operand * result) static void genPlusBits (iCode * ic) { + D(emitcode ("; genPlusBits","")); + if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY) { symbol *lbl = newiTempLabel (NULL); @@ -2926,9 +3121,13 @@ static void genPlus (iCode * ic) { int size, offset = 0; + char *add; + asmop *leftOp, *rightOp; /* special cases :- */ + D(emitcode ("; genPlus","")); + aopOp (IC_LEFT (ic), ic, FALSE); aopOp (IC_RIGHT (ic), ic, FALSE); aopOp (IC_RESULT (ic), ic, TRUE); @@ -2986,29 +3185,32 @@ genPlus (iCode * ic) size = getDataSize (IC_RESULT (ic)); + leftOp = AOP(IC_LEFT(ic)); + rightOp = AOP(IC_RIGHT(ic)); + add = "add"; + while (size--) { - if (AOP_TYPE (IC_LEFT (ic)) == AOP_ACC) + if (aopGetUsesAcc (leftOp, offset) && aopGetUsesAcc (rightOp, offset)) { - MOVA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE)); - if (offset == 0) - emitcode ("add", "a,%s", - aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE)); - else - emitcode ("addc", "a,%s", - aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE)); + emitcode("mov", "b,a"); + MOVA (aopGet (leftOp, offset, FALSE, TRUE)); + emitcode("xch", "a,b"); + MOVA (aopGet (rightOp, offset, FALSE, TRUE)); + emitcode (add, "a,b"); + } + else if (aopGetUsesAcc (leftOp, offset)) + { + MOVA (aopGet (leftOp, offset, FALSE, TRUE)); + emitcode (add, "a,%s", aopGet (rightOp, offset, FALSE, TRUE)); } else { - MOVA (aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE)); - if (offset == 0) - emitcode ("add", "a,%s", - aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE)); - else - emitcode ("addc", "a,%s", - aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE)); + MOVA (aopGet (rightOp, offset, FALSE, TRUE)); + emitcode (add, "a,%s", aopGet (leftOp, offset, FALSE, TRUE)); } aopPut (AOP (IC_RESULT (ic)), "a", offset++); + add = "addc"; /* further adds must propagate carry */ } adjustArithmeticResult (ic); @@ -3039,8 +3241,11 @@ genMinusDec (iCode * ic) if ((icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 4) return FALSE; - /* if decrement 16 bits in register */ - if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))) && + D(emitcode ("; genMinusDec","")); + + /* if decrement >=16 bits in register or direct space */ + if ((AOP_TYPE(IC_LEFT(ic)) == AOP_REG || AOP_TYPE(IC_LEFT(ic)) == AOP_DIR) && + sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))) && (size > 1) && (icount == 1)) { @@ -3166,6 +3371,9 @@ static void genMinusBits (iCode * ic) { symbol *lbl = newiTempLabel (NULL); + + D(emitcode ("; genMinusBits","")); + if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY) { emitcode ("mov", "c,%s", AOP (IC_LEFT (ic))->aopu.aop_dir); @@ -3193,7 +3401,8 @@ static void genMinus (iCode * ic) { int size, offset = 0; - unsigned long lit = 0L; + + D(emitcode ("; genMinus","")); aopOp (IC_LEFT (ic), ic, FALSE); aopOp (IC_RIGHT (ic), ic, FALSE); @@ -3215,36 +3424,62 @@ genMinus (iCode * ic) size = getDataSize (IC_RESULT (ic)); - if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT) - { - CLRC; - } - else + /* if literal, add a,#-lit, else normal subb */ + if (AOP_TYPE (IC_RIGHT (ic)) == AOP_LIT) { + unsigned long lit = 0L; + lit = (unsigned long) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit); lit = -(long) lit; - } - /* if literal, add a,#-lit, else normal subb */ - while (size--) - { - MOVA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE)); - if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT) - emitcode ("subb", "a,%s", - aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE)); - else + while (size--) { + MOVA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE)); /* 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)); + } + aopPut (AOP (IC_RESULT (ic)), "a", offset++); } - aopPut (AOP (IC_RESULT (ic)), "a", offset++); } + else + { + asmop *leftOp, *rightOp; + + leftOp = AOP(IC_LEFT(ic)); + rightOp = AOP(IC_RIGHT(ic)); + while (size--) + { + if (aopGetUsesAcc(rightOp, offset)) { + wassertl(!aopGetUsesAcc(leftOp, offset), "accumulator clash"); + MOVA (aopGet(rightOp, offset, FALSE, TRUE)); + if (offset == 0) { + emitcode( "setb", "c"); + } + emitcode("subb", "a,%s", aopGet(leftOp, offset, FALSE, TRUE)); + emitcode("cpl", "a"); + } else { + MOVA (aopGet (leftOp, offset, FALSE, FALSE)); + if (offset == 0) + CLRC; + emitcode ("subb", "a,%s", + aopGet(rightOp, offset, FALSE, TRUE)); + } + + aopPut (AOP (IC_RESULT (ic)), "a", offset++); + } + } + + adjustArithmeticResult (ic); release: @@ -3262,6 +3497,8 @@ genMultbits (operand * left, operand * right, operand * result) { + D(emitcode ("; genMultbits","")); + emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir); emitcode ("anl", "c,%s", AOP (right)->aopu.aop_dir); outBitC (result); @@ -3280,7 +3517,8 @@ genMultOneByte (operand * left, symbol *lbl; int size=AOP_SIZE(result); - //emitcode (";",__FUNCTION__); + D(emitcode ("; genMultOneByte","")); + if (size<1 || size>2) { // this should never happen fprintf (stderr, "size!=1||2 (%d) in %s at line:%d \n", @@ -3304,6 +3542,7 @@ genMultOneByte (operand * left, SPEC_USIGN(operandType(right)))) { // just an unsigned 8*8=8/16 multiply //emitcode (";","unsigned"); + // TODO: check for accumulator clash between left & right aops? emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE)); MOVA (aopGet (AOP (left), 0, FALSE, FALSE)); emitcode ("mul", "ab"); @@ -3318,7 +3557,6 @@ genMultOneByte (operand * left, //emitcode (";", "signed"); emitcode ("clr", "F0"); // reset sign flag - emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE)); MOVA (aopGet (AOP (left), 0, FALSE, FALSE)); lbl=newiTempLabel(NULL); @@ -3329,22 +3567,24 @@ genMultOneByte (operand * left, 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 (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)); 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); @@ -3382,6 +3622,8 @@ genMult (iCode * ic) operand *right = IC_RIGHT (ic); operand *result = IC_RESULT (ic); + D(emitcode ("; genMult","")); + /* assign the amsops */ aopOp (left, ic, FALSE); aopOp (right, ic, FALSE); @@ -3397,15 +3639,21 @@ genMult (iCode * ic) } /* if both are of size == 1 */ - if (AOP_SIZE (left) == 1 && - AOP_SIZE (right) == 1) +#if 0 // one of them can be a sloc shared with the result + if (AOP_SIZE (left) == 1 && AOP_SIZE (right) == 1) +#else + if (getSize(operandType(left)) == 1 && + getSize(operandType(right)) == 1) +#endif { genMultOneByte (left, right, result); goto release; } /* should have been converted to function call */ - assert (1); + fprintf (stderr, "left: %d right: %d\n", getSize(OP_SYMBOL(left)->type), + getSize(OP_SYMBOL(right)->type)); + assert (0); release: freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE)); @@ -3424,6 +3672,8 @@ genDivbits (operand * left, char *l; + D(emitcode ("; genDivbits","")); + /* the result must be bit */ emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE)); l = aopGet (AOP (left), 0, FALSE, FALSE); @@ -3448,6 +3698,8 @@ genDivOneByte (operand * left, symbol *lbl; int size, offset; + D(emitcode ("; genDivOneByte","")); + size = AOP_SIZE (result) - 1; offset = 1; /* signed or unsigned */ @@ -3531,6 +3783,8 @@ genDiv (iCode * ic) operand *right = IC_RIGHT (ic); operand *result = IC_RESULT (ic); + D(emitcode ("; genDiv","")); + /* assign the amsops */ aopOp (left, ic, FALSE); aopOp (right, ic, FALSE); @@ -3554,7 +3808,7 @@ genDiv (iCode * ic) } /* 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)); @@ -3572,6 +3826,8 @@ genModbits (operand * left, char *l; + D(emitcode ("; genModbits","")); + /* the result must be bit */ emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE)); l = aopGet (AOP (left), 0, FALSE, FALSE); @@ -3596,6 +3852,8 @@ genModOneByte (operand * left, char *l; symbol *lbl; + D(emitcode ("; genModOneByte","")); + /* signed or unsigned */ if (SPEC_USIGN (opetype)) { @@ -3669,6 +3927,8 @@ genMod (iCode * ic) operand *right = IC_RIGHT (ic); operand *result = IC_RESULT (ic); + D(emitcode ("; genMod","")); + /* assign the amsops */ aopOp (left, ic, FALSE); aopOp (right, ic, FALSE); @@ -3692,7 +3952,7 @@ genMod (iCode * ic) } /* should have been converted to function call */ - assert (1); + assert (0); release: freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE)); @@ -3710,6 +3970,8 @@ genIfxJump (iCode * ic, char *jval) symbol *tlbl = newiTempLabel (NULL); char *inst; + D(emitcode ("; genIfxJump","")); + /* if true label then we jump if condition supplied is true */ if (IC_TRUE (ic)) @@ -3746,12 +4008,14 @@ genCmp (operand * left, operand * right, int size, offset = 0; unsigned long lit = 0L; + D(emitcode ("; genCmp","")); + /* if left & right are bit variables */ if (AOP_TYPE (left) == AOP_CRY && AOP_TYPE (right) == AOP_CRY) { emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir); - emitcode ("anl", "c,/%s", AOP (left)->aopu.aop_dir); + emitcode ("anl", "c,%s", AOP (left)->aopu.aop_dir); } else { @@ -3854,6 +4118,8 @@ genCmpGt (iCode * ic, iCode * ifx) sym_link *letype, *retype; int sign; + D(emitcode ("; genCmpGt","")); + left = IC_LEFT (ic); right = IC_RIGHT (ic); result = IC_RESULT (ic); @@ -3881,6 +4147,8 @@ genCmpLt (iCode * ic, iCode * ifx) sym_link *letype, *retype; int sign; + D(emitcode ("; genCmpLt","")); + left = IC_LEFT (ic); right = IC_RIGHT (ic); result = IC_RESULT (ic); @@ -3996,6 +4264,8 @@ genCmpEq (iCode * ic, iCode * ifx) { operand *left, *right, *result; + D(emitcode ("; genCmpEq","")); + aopOp ((left = IC_LEFT (ic)), ic, FALSE); aopOp ((right = IC_RIGHT (ic)), ic, FALSE); aopOp ((result = IC_RESULT (ic)), ic, TRUE); @@ -4179,15 +4449,20 @@ ifxForOp (operand * op, iCode * ic) /* hasInc - operand is incremented before any other use */ /*-----------------------------------------------------------------*/ static iCode * -hasInc (operand *op, iCode *ic) +hasInc (operand *op, iCode *ic,int osize) { 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); + if (IS_AGGREGATE(type->next)) return NULL; + if (osize != (isize = getSize(type->next))) return NULL; + while (lic) { /* if operand of the form op = op + */ if (lic->op == '+' && isOperandEqual(IC_LEFT(lic),op) && @@ -4197,9 +4472,11 @@ hasInc (operand *op, iCode *ic) return lic; } /* if the operand used or deffed */ - if (bitVectBitValue(ic->uses,op->key) || (unsigned) ic->defKey == op->key) { + 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 || lic->op == LABEL) break; lic = lic->next; } return NULL; @@ -4214,6 +4491,8 @@ genAndOp (iCode * ic) operand *left, *right, *result; symbol *tlbl; + 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 */ @@ -4254,6 +4533,8 @@ genOrOp (iCode * ic) operand *left, *right, *result; symbol *tlbl; + 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 */ @@ -4363,6 +4644,8 @@ genAnd (iCode * ic, iCode * ifx) int bytelit = 0; char buffer[10]; + D(emitcode ("; genAnd","")); + aopOp ((left = IC_LEFT (ic)), ic, FALSE); aopOp ((right = IC_RIGHT (ic)), ic, FALSE); aopOp ((result = IC_RESULT (ic)), ic, TRUE); @@ -4587,9 +4870,20 @@ genAnd (iCode * ic, iCode * ifx) emitcode ("setb", "c"); while (sizer--) { - MOVA (aopGet (AOP (right), offset, FALSE, FALSE)); - emitcode ("anl", "a,%s", - aopGet (AOP (left), offset, FALSE, FALSE)); + if (AOP_TYPE(right)==AOP_REG && AOP_TYPE(left)==AOP_ACC) { + emitcode ("anl", "a,%s", + aopGet (AOP (right), offset, FALSE, FALSE)); + } else { + if (AOP_TYPE(left)==AOP_ACC) { + emitcode("mov", "b,a"); + MOVA (aopGet (AOP (right), offset, FALSE, FALSE)); + emitcode("anl", "a,b"); + }else { + MOVA (aopGet (AOP (right), offset, FALSE, FALSE)); + emitcode ("anl", "a,%s", + aopGet (AOP (left), offset, FALSE, FALSE)); + } + } emitcode ("jnz", "%05d$", tlbl->key + 100); offset++; } @@ -4654,6 +4948,8 @@ genOr (iCode * ic, iCode * ifx) int size, offset = 0; unsigned long lit = 0L; + D(emitcode ("; genOr","")); + aopOp ((left = IC_LEFT (ic)), ic, FALSE); aopOp ((right = IC_RIGHT (ic)), ic, FALSE); aopOp ((result = IC_RESULT (ic)), ic, TRUE); @@ -4703,7 +4999,7 @@ genOr (iCode * ic, iCode * ifx) { if (AOP_TYPE (right) == AOP_LIT) { - // c = bit & literal; + // c = bit | literal; if (lit) { // lit != 0 => result = 1 @@ -4856,9 +5152,14 @@ genOr (iCode * ic, iCode * ifx) emitcode ("setb", "c"); while (sizer--) { - MOVA (aopGet (AOP (right), offset, FALSE, FALSE)); - emitcode ("orl", "a,%s", - aopGet (AOP (left), offset, FALSE, FALSE)); + if (AOP_TYPE(right)==AOP_REG && AOP_TYPE(left)==AOP_ACC) { + emitcode ("orl", "a,%s", + aopGet (AOP (right), offset, FALSE, FALSE)); + } else { + MOVA (aopGet (AOP (right), offset, FALSE, FALSE)); + emitcode ("orl", "a,%s", + aopGet (AOP (left), offset, FALSE, FALSE)); + } emitcode ("jnz", "%05d$", tlbl->key + 100); offset++; } @@ -4916,6 +5217,8 @@ genXor (iCode * ic, iCode * ifx) int size, offset = 0; unsigned long lit = 0L; + D(emitcode ("; genXor","")); + aopOp ((left = IC_LEFT (ic)), ic, FALSE); aopOp ((right = IC_RIGHT (ic)), ic, FALSE); aopOp ((result = IC_RESULT (ic)), ic, TRUE); @@ -5108,9 +5411,14 @@ genXor (iCode * ic, iCode * ifx) } else { - MOVA (aopGet (AOP (right), offset, FALSE, FALSE)); - emitcode ("xrl", "a,%s", - aopGet (AOP (left), offset, FALSE, FALSE)); + if (AOP_TYPE(right)==AOP_REG && AOP_TYPE(left)==AOP_ACC) { + emitcode ("xrl", "a,%s", + aopGet (AOP (right), offset, FALSE, FALSE)); + } else { + MOVA (aopGet (AOP (right), offset, FALSE, FALSE)); + emitcode ("xrl", "a,%s", + aopGet (AOP (left), offset, FALSE, FALSE)); + } } emitcode ("jnz", "%05d$", tlbl->key + 100); offset++; @@ -5167,6 +5475,8 @@ genInline (iCode * ic) { char *buffer, *bp, *bp1; + D(emitcode ("; genInline","")); + _G.inLine += (!options.asmpeep); buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1); @@ -5211,6 +5521,8 @@ genRRC (iCode * ic) int size, offset = 0; char *l; + D(emitcode ("; genRRC","")); + /* rotate right with carry */ left = IC_LEFT (ic); result = IC_RESULT (ic); @@ -5220,6 +5532,12 @@ genRRC (iCode * ic) /* move it to the result */ size = AOP_SIZE (result); offset = size - 1; + if (size == 1) { /* special case for 1 byte */ + l = aopGet (AOP (left), offset, FALSE, FALSE); + MOVA (l); + emitcode ("rr", "a"); + goto release; + } CLRC; while (size--) { @@ -5237,6 +5555,7 @@ genRRC (iCode * ic) MOVA (l); } emitcode ("mov", "acc.7,c"); + release: aopPut (AOP (result), "a", AOP_SIZE (result) - 1); freeAsmop (left, NULL, ic, TRUE); freeAsmop (result, NULL, ic, TRUE); @@ -5252,6 +5571,8 @@ genRLC (iCode * ic) int size, offset = 0; char *l; + D(emitcode ("; genRLC","")); + /* rotate right with carry */ left = IC_LEFT (ic); result = IC_RESULT (ic); @@ -5265,6 +5586,10 @@ genRLC (iCode * ic) { l = aopGet (AOP (left), offset, FALSE, FALSE); MOVA (l); + if (size == 0) { /* special case for 1 byte */ + emitcode("rl","a"); + goto release; + } emitcode ("add", "a,acc"); if (AOP_SIZE (result) > 1) aopPut (AOP (result), "a", offset++); @@ -5285,6 +5610,7 @@ genRLC (iCode * ic) MOVA (l); } emitcode ("mov", "acc.0,c"); + release: aopPut (AOP (result), "a", 0); freeAsmop (left, NULL, ic, TRUE); freeAsmop (result, NULL, ic, TRUE); @@ -5297,6 +5623,9 @@ static void genGetHbit (iCode * ic) { operand *left, *result; + + D(emitcode ("; genGetHbit","")); + left = IC_LEFT (ic); result = IC_RESULT (ic); aopOp (left, ic, FALSE); @@ -5684,6 +6013,7 @@ AccAXRsh (char *x, int shCount) emitcode ("mov", "c,acc.7"); AccAXLrl1 (x); // ABBBBBBC:CDDDDDDA + emitcode ("mov", "c,acc.7"); AccAXLrl1 (x); // BBBBBBCC:DDDDDDAA emitcode ("xch", "a,%s", x); // DDDDDDAA:BBBBBBCC @@ -5773,6 +6103,7 @@ AccAXRshS (char *x, int shCount) emitcode ("mov", "c,acc.7"); AccAXLrl1 (x); // ABBBBBBC:CDDDDDDA + emitcode ("mov", "c,acc.7"); AccAXLrl1 (x); // BBBBBBCC:DDDDDDAA emitcode ("xch", "a,%s", x); // DDDDDDAA:BBBBBBCC @@ -5901,6 +6232,8 @@ shiftRLeftOrResult (operand * left, int offl, static void genlshOne (operand * result, operand * left, int shCount) { + D(emitcode ("; genlshOne","")); + shiftL1Left2Result (left, LSB, result, LSB, shCount); } @@ -5912,6 +6245,8 @@ genlshTwo (operand * result, operand * left, int shCount) { int size; + D(emitcode ("; genlshTwo","")); + size = getDataSize (result); /* if shCount >= 8 */ @@ -6016,6 +6351,8 @@ genlshFour (operand * result, operand * left, int shCount) { int size; + D(emitcode ("; genlshFour","")); + size = AOP_SIZE (result); /* if shifting more that 3 bytes */ @@ -6113,6 +6450,8 @@ genLeftShiftLiteral (operand * left, int shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit); int size; + D(emitcode ("; genLeftShiftLiteral","")); + freeAsmop (right, NULL, ic, TRUE); aopOp (left, ic, FALSE); @@ -6146,13 +6485,16 @@ genLeftShiftLiteral (operand * left, break; case 2: - case 3: genlshTwo (result, left, shCount); break; case 4: genlshFour (result, left, shCount); break; + default: + werror (E_INTERNAL_ERROR, __FILE__, __LINE__, + "*** ack! mystery literal shift!\n"); + break; } } freeAsmop (left, NULL, ic, TRUE); @@ -6170,6 +6512,8 @@ genLeftShift (iCode * ic) char *l; symbol *tlbl, *tlbl1; + D(emitcode ("; genLeftShift","")); + right = IC_RIGHT (ic); left = IC_LEFT (ic); result = IC_RESULT (ic); @@ -6271,6 +6615,8 @@ static void genrshOne (operand * result, operand * left, int shCount, int sign) { + D(emitcode ("; genrshOne","")); + shiftR1Left2Result (left, LSB, result, LSB, shCount, sign); } @@ -6281,6 +6627,8 @@ static void genrshTwo (operand * result, operand * left, int shCount, int sign) { + D(emitcode ("; genrshTwo","")); + /* if shCount >= 8 */ if (shCount >= 8) { @@ -6306,22 +6654,53 @@ static void shiftRLong (operand * left, int offl, operand * result, int sign) { - if (!sign) - emitcode ("clr", "c"); + 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 (sign) + + if (offl==MSB16) { + // shift is > 8 + if (sign) { + emitcode ("rlc", "a"); + emitcode ("subb", "a,acc"); + if (isSameRegs) + emitcode ("xch", "a,%s", aopGet(AOP(left), MSB32, FALSE, FALSE)); + else { + aopPut (AOP (result), "a", MSB32); + MOVA (aopGet (AOP (left), MSB32, FALSE, FALSE)); + } + } else { + aopPut (AOP(result), zero, MSB32); + } + } + + if (!sign) { + emitcode ("clr", "c"); + } 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)); emitcode ("rrc", "a"); - aopPut (AOP (result), "a", MSB24 - offl); - MOVA (aopGet (AOP (left), MSB16, FALSE, FALSE)); + if (isSameRegs && offl==MSB16) { + emitcode ("xch", "a,%s",aopGet (AOP (left), MSB24, FALSE, FALSE)); + } else { + aopPut (AOP (result), "a", MSB32-offl); + 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-offl); + MOVA (aopGet (AOP (left), MSB16, FALSE, FALSE)); + } emitcode ("rrc", "a"); aopPut (AOP (result), "a", MSB16 - offl); @@ -6340,6 +6719,8 @@ static void genrshFour (operand * result, operand * left, int shCount, int sign) { + D(emitcode ("; genrshFour","")); + /* if shifting more that 3 bytes */ if (shCount >= 24) { @@ -6413,6 +6794,8 @@ genRightShiftLiteral (operand * left, int shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit); int size; + D(emitcode ("; genRightShiftLiteral","")); + freeAsmop (right, NULL, ic, TRUE); aopOp (left, ic, FALSE); @@ -6436,9 +6819,10 @@ genRightShiftLiteral (operand * left, else if (shCount >= (size * 8)) { - if (sign) + if (sign) { /* get sign in acc.7 */ MOVA (aopGet (AOP (left), size - 1, FALSE, FALSE)); + } addSign (result, LSB, sign); } else @@ -6459,10 +6843,9 @@ genRightShiftLiteral (operand * left, default: break; } - - freeAsmop (left, NULL, ic, TRUE); - freeAsmop (result, NULL, ic, TRUE); } + freeAsmop (left, NULL, ic, TRUE); + freeAsmop (result, NULL, ic, TRUE); } /*-----------------------------------------------------------------*/ @@ -6476,6 +6859,8 @@ genSignedRightShift (iCode * ic) char *l; symbol *tlbl, *tlbl1; + D(emitcode ("; genSignedRightShift","")); + /* we do it the hard way put the shift count in b and loop thru preserving the sign */ @@ -6582,6 +6967,8 @@ genRightShift (iCode * ic) char *l; symbol *tlbl, *tlbl1; + D(emitcode ("; genRightShift","")); + /* if signed then we do it the hard way preserve the sign bit moving it inwards */ retype = getSpec (operandType (IC_RESULT (ic))); @@ -6701,6 +7088,8 @@ genUnpackBits (operand * result, char *rname, int ptype) int offset = 0; int rsize; + D(emitcode ("; genUnpackBits","")); + etype = getSpec (operandType (result)); rsize = getSize (operandType (result)); /* read the first byte */ @@ -6722,7 +7111,7 @@ genUnpackBits (operand * result, char *rname, int ptype) case CPOINTER: emitcode ("clr", "a"); - emitcode ("movc", "a,%s", "@a+dptr"); + emitcode ("movc", "a,@a+dptr"); break; case GPOINTER: @@ -6775,7 +7164,7 @@ genUnpackBits (operand * result, char *rname, int ptype) case CPOINTER: emitcode ("clr", "a"); emitcode ("inc", "dptr"); - emitcode ("movc", "a", "@a+dptr"); + emitcode ("movc", "a,@a+dptr"); break; case GPOINTER: @@ -6822,6 +7211,9 @@ genDataPointerGet (operand * left, char *l; char buffer[256]; int size, offset = 0; + + D(emitcode ("; genDataPointerGet","")); + aopOp (result, ic, TRUE); /* get the string representation of the name */ @@ -6856,6 +7248,8 @@ genNearPointerGet (operand * left, sym_link *ltype = operandType (left); char buffer[80]; + D(emitcode ("; genNearPointerGet","")); + rtype = operandType (result); retype = getSpec (rtype); @@ -6887,8 +7281,9 @@ genNearPointerGet (operand * left, } else rname = aopGet (AOP (left), 0, FALSE, FALSE); - - aopOp (result, ic, FALSE); + + //aopOp (result, ic, FALSE); + aopOp (result, ic, result?TRUE:FALSE); /* if bitfield then unpack the bits */ if (IS_BITVAR (retype)) @@ -6965,6 +7360,8 @@ genPagedPointerGet (operand * left, char *rname; sym_link *rtype, *retype; + D(emitcode ("; genPagedPointerGet","")); + rtype = operandType (result); retype = getSpec (rtype); @@ -7051,6 +7448,8 @@ genFarPointerGet (operand * left, int size, offset; sym_link *retype = getSpec (operandType (result)); + D(emitcode ("; genFarPointerGet","")); + aopOp (left, ic, FALSE); /* if the operand is already in dptr @@ -7105,6 +7504,8 @@ genCodePointerGet (operand * left, int size, offset; sym_link *retype = getSpec (operandType (result)); + D(emitcode ("; genCodePointerGet","")); + aopOp (left, ic, FALSE); /* if the operand is already in dptr @@ -7133,11 +7534,19 @@ genCodePointerGet (operand * left, while (size--) { - emitcode ("clr", "a"); - emitcode ("movc", "a,@a+dptr"); - aopPut (AOP (result), "a", offset++); - if (size || pi) - emitcode ("inc", "dptr"); + if (pi) + { + emitcode ("clr", "a"); + emitcode ("movc", "a,@a+dptr"); + aopPut (AOP (result), "a", offset++); + emitcode ("inc", "dptr"); + } + else + { + emitcode ("mov", "a,#0x%02x", offset); + emitcode ("movc", "a,@a+dptr"); + aopPut (AOP (result), "a", offset++); + } } } @@ -7160,6 +7569,8 @@ genGenPointerGet (operand * left, int size, offset; sym_link *retype = getSpec (operandType (result)); + D(emitcode ("; genGenPointerGet","")); + aopOp (left, ic, FALSE); /* if the operand is already in dptr @@ -7170,7 +7581,10 @@ genGenPointerGet (operand * left, if (AOP_TYPE (left) == AOP_IMMD) { emitcode ("mov", "dptr,%s", aopGet (AOP (left), 0, TRUE, 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)); + else + emitcode ("mov", "b,#%d", pointerCode (retype)); } else { /* we need to get it byte by byte */ @@ -7202,6 +7616,7 @@ genGenPointerGet (operand * left, if (pi && AOP_TYPE (left) != AOP_IMMD && AOP_TYPE (left) != AOP_STR) { aopPut ( AOP (left), "dpl", 0); aopPut ( AOP (left), "dph", 1); + aopPut ( AOP (left), "b", 2); pi->generated = 1; } freeAsmop (left, NULL, ic, TRUE); @@ -7218,6 +7633,8 @@ genPointerGet (iCode * ic, iCode *pi) sym_link *type, *etype; int p_type; + D(emitcode ("; genPointerGet","")); + left = IC_LEFT (ic); result = IC_RESULT (ic); @@ -7234,6 +7651,13 @@ genPointerGet (iCode * ic, iCode *pi) 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 = operandType (left); + p_type = DCL_TYPE (type); + } /* now that we have the pointer type we assign the pointer values */ switch (p_type) @@ -7277,6 +7701,8 @@ genPackBits (sym_link * etype, int blen, bstr; char *l; + D(emitcode ("; genPackBits","")); + blen = SPEC_BLEN (etype); bstr = SPEC_BSTR (etype); @@ -7442,6 +7868,8 @@ genDataPointerSet (operand * right, int size, offset = 0; char *l, buffer[256]; + D(emitcode ("; genDataPointerSet","")); + aopOp (right, ic, FALSE); l = aopGet (AOP (result), 0, FALSE, TRUE); @@ -7475,6 +7903,8 @@ genNearPointerSet (operand * right, sym_link *retype, *letype; sym_link *ptype = operandType (result); + D(emitcode ("; genNearPointerSet","")); + retype = getSpec (operandType (right)); letype = getSpec (ptype); aopOp (result, ic, FALSE); @@ -7489,24 +7919,47 @@ genNearPointerSet (operand * right, genDataPointerSet (right, result, ic); return; } - + /* if the value is already in a pointer register then don't need anything more */ if (!AOP_INPREG (AOP (result))) { - /* otherwise get a free pointer register */ - aop = newAsmop (0); - preg = getFreePtr (ic, &aop, FALSE); - emitcode ("mov", "%s,%s", - preg->name, - aopGet (AOP (result), 0, FALSE, TRUE)); - rname = preg->name; + if ( + //AOP_TYPE (result) == AOP_STK + IS_AOP_PREG(result) + ) + { + // Aha, it is a pointer, just in disguise. + rname = aopGet (AOP (result), 0, FALSE, FALSE); + if (*rname != '@') + { + fprintf(stderr, "probable internal error: unexpected rname @ %s:%d\n", + __FILE__, __LINE__); + } + else + { + // Expected case. + rname++; // skip the '@'. + } + } + else + { + /* otherwise get a free pointer register */ + aop = newAsmop (0); + preg = getFreePtr (ic, &aop, FALSE); + emitcode ("mov", "%s,%s", + preg->name, + aopGet (AOP (result), 0, FALSE, TRUE)); + rname = preg->name; + } + } + else + { + rname = aopGet (AOP (result), 0, FALSE, FALSE); } - else - rname = aopGet (AOP (result), 0, FALSE, FALSE); aopOp (right, ic, FALSE); - + /* if bitfield then unpack the bits */ if (IS_BITVAR (retype) || IS_BITVAR (letype)) genPackBits ((IS_BITVAR (retype) ? retype : letype), right, rname, POINTER); @@ -7577,6 +8030,8 @@ genPagedPointerSet (operand * right, char *rname, *l; sym_link *retype, *letype; + D(emitcode ("; genPagedPointerSet","")); + retype = getSpec (operandType (right)); letype = getSpec (operandType (result)); @@ -7664,6 +8119,9 @@ genFarPointerSet (operand * right, int size, offset; sym_link *retype = getSpec (operandType (right)); sym_link *letype = getSpec (operandType (result)); + + D(emitcode ("; genFarPointerSet","")); + aopOp (result, ic, FALSE); /* if the operand is already in dptr @@ -7719,6 +8177,8 @@ genGenPointerSet (operand * right, sym_link *retype = getSpec (operandType (right)); sym_link *letype = getSpec (operandType (result)); + D(emitcode ("; genGenPointerSet","")); + aopOp (result, ic, FALSE); /* if the operand is already in dptr @@ -7729,7 +8189,10 @@ genGenPointerSet (operand * right, if (AOP_TYPE (result) == AOP_IMMD) { emitcode ("mov", "dptr,%s", aopGet (AOP (result), 0, TRUE, FALSE)); - emitcode ("mov", "b,%s + 1", aopGet (AOP (result), 0, TRUE, FALSE)); + if (AOP(result)->aopu.aop_immd.from_cast_remat) + emitcode ("mov", "b,%s",aopGet(AOP (result), AOP_SIZE(result)-1, FALSE, FALSE)); + else + emitcode ("mov", "b,%s + 1", aopGet (AOP (result), 0, TRUE, FALSE)); } else { /* we need to get it byte by byte */ @@ -7762,6 +8225,7 @@ genGenPointerSet (operand * right, if (pi && AOP_TYPE (result) != AOP_STR && AOP_TYPE (result) != AOP_IMMD) { aopPut (AOP(result),"dpl",0); aopPut (AOP(result),"dph",1); + aopPut (AOP(result),"b",2); pi->generated=1; } freeAsmop (result, NULL, ic, TRUE); @@ -7778,6 +8242,8 @@ genPointerSet (iCode * ic, iCode *pi) sym_link *type, *etype; int p_type; + D(emitcode ("; genPointerSet","")); + right = IC_RIGHT (ic); result = IC_RESULT (ic); @@ -7796,6 +8262,13 @@ genPointerSet (iCode * ic, iCode *pi) 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 = operandType (result); + p_type = DCL_TYPE (type); + } /* now that we have the pointer type we assign the pointer values */ switch (p_type) @@ -7817,6 +8290,10 @@ genPointerSet (iCode * ic, iCode *pi) case GPOINTER: genGenPointerSet (right, result, ic, pi); break; + + default: + werror (E_INTERNAL_ERROR, __FILE__, __LINE__, + "genPointerSet: illegal pointer type"); } } @@ -7830,6 +8307,8 @@ genIfx (iCode * ic, iCode * popIc) operand *cond = IC_COND (ic); int isbit = 0; + D(emitcode ("; genIfx","")); + aopOp (cond, ic, FALSE); /* get the value into acc */ @@ -7865,6 +8344,8 @@ genAddrOf (iCode * ic) symbol *sym = OP_SYMBOL (IC_LEFT (ic)); int size, offset; + D(emitcode ("; genAddrOf","")); + aopOp (IC_RESULT (ic), ic, FALSE); /* if the operand is on the stack then we @@ -7877,7 +8358,9 @@ genAddrOf (iCode * ic) if (sym->stack) { emitcode ("mov", "a,_bp"); - emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff)); + emitcode ("add", "a,#0x%02x", ((sym->stack < 0) ? + ((char) (sym->stack - _G.nRegsSaved)) : + ((char) sym->stack)) & 0xff); aopPut (AOP (IC_RESULT (ic)), "a", 0); } else @@ -7927,6 +8410,9 @@ genFarFarAssign (operand * result, operand * right, iCode * ic) int size = AOP_SIZE (right); int offset = 0; char *l; + + D(emitcode ("; genFarFarAssign","")); + /* first push the right side on to the stack */ while (size--) { @@ -7958,12 +8444,15 @@ genAssign (iCode * ic) int size, offset; unsigned long lit = 0L; + D(emitcode("; genAssign","")); + result = IC_RESULT (ic); right = IC_RIGHT (ic); /* if they are the same */ - if (operandsEqu (IC_RESULT (ic), IC_RIGHT (ic))) + if (operandsEqu (result, right)) { return; + } aopOp (right, ic, FALSE); @@ -8060,6 +8549,8 @@ genJumpTab (iCode * ic) symbol *jtab; char *l; + D(emitcode ("; genJumpTab","")); + aopOp (IC_JTCOND (ic), ic, FALSE); /* get the condition into accumulator */ l = aopGet (AOP (IC_JTCOND (ic)), 0, FALSE, FALSE); @@ -8092,6 +8583,8 @@ genCast (iCode * ic) operand *right = IC_RIGHT (ic); int size, offset; + D(emitcode("; genCast","")); + /* if they are equivalent then do nothing */ if (operandsEqu (IC_RESULT (ic), IC_RIGHT (ic))) return; @@ -8100,7 +8593,7 @@ genCast (iCode * ic) aopOp (result, ic, FALSE); /* if the result is a bit */ - if (AOP_TYPE (result) == AOP_CRY) + if (IS_BITVAR(OP_SYMBOL(result)->type)) { /* if the right size is a literal then we know what the value is */ @@ -8161,14 +8654,17 @@ genCast (iCode * ic) /* pointer to generic pointer */ if (IS_GENPTR (ctype)) { - char *l = zero; - if (IS_PTR (type)) p_type = DCL_TYPE (type); else { - /* we have to go by the storage class */ - p_type = PTR_TYPE (SPEC_OCLS (etype)); + if (SPEC_SCLS(etype)==S_REGISTER) { + // let's assume it is a generic pointer + p_type=GPOINTER; + } else { + /* we have to go by the storage class */ + p_type = PTR_TYPE (SPEC_OCLS (etype)); + } } /* the first two bytes are known */ @@ -8182,29 +8678,19 @@ genCast (iCode * ic) offset++; } /* the last byte depending on type */ - switch (p_type) { - case IPOINTER: - case POINTER: - l = zero; - break; - case FPOINTER: - l = one; - break; - case CPOINTER: - l = "#0x02"; - break; - case PPOINTER: - l = "#0x03"; - break; - - default: - /* this should never happen */ - werror (E_INTERNAL_ERROR, __FILE__, __LINE__, - "got unknown pointer type"); - exit (1); - } - aopPut (AOP (result), l, GPTRSIZE - 1); + int gpVal = pointerTypeToGPByte(p_type, NULL, NULL); + char gpValStr[10]; + + if (gpVal == -1) + { + // pointerTypeToGPByte will have bitched. + exit(1); + } + + sprintf(gpValStr, "#0x%d", gpVal); + aopPut (AOP (result), gpValStr, GPTRSIZE - 1); + } goto release; } @@ -8237,7 +8723,7 @@ genCast (iCode * ic) /* now depending on the sign of the source && destination */ size = AOP_SIZE (result) - AOP_SIZE (right); /* if unsigned or not an integral type */ - if (SPEC_USIGN (rtype) || !IS_SPEC (rtype)) + if (!IS_SPEC (rtype) || SPEC_USIGN (rtype) || AOP_TYPE(right)==AOP_CRY) { while (size--) aopPut (AOP (result), zero, offset++); @@ -8272,6 +8758,8 @@ genDjnz (iCode * ic, iCode * ifx) if (!ifx) return 0; + D(emitcode ("; genDjnz","")); + /* if the if condition has a false label then we cannot save */ if (IC_FALSE (ifx)) @@ -8348,37 +8836,43 @@ genDjnz (iCode * ic, iCode * ifx) static void genReceive (iCode * ic) { - 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 = fReturnSizeMCS51 - size; - while (size--) - { - emitcode ("push", "%s", (strcmp (fReturn[fReturnSizeMCS51 - offset - 1], "a") ? - fReturn[fReturnSizeMCS51 - offset - 1] : "acc")); - offset++; - } - aopOp (IC_RESULT (ic), ic, 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; + 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 = fReturnSizeMCS51 - size; + while (size--) { + emitcode ("push", "%s", (strcmp (fReturn[fReturnSizeMCS51 - offset - 1], "a") ? + fReturn[fReturnSizeMCS51 - offset - 1] : "acc")); + offset++; + } + aopOp (IC_RESULT (ic), ic, 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); + _G.accInUse--; + assignResultValue (IC_RESULT (ic)); + } + } else { /* second receive onwards */ + int rb1off ; aopOp (IC_RESULT (ic), ic, 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); } @@ -8394,13 +8888,12 @@ gen51Code (iCode * lic) lineHead = lineCurr = NULL; /* print the allocation information */ - if (allocInfo) + if (allocInfo && currFunc) printAllocInfo (currFunc, codeOutFile); /* if debug information required */ -/* if (options.debug && currFunc) { */ - if (currFunc) + if (options.debug && currFunc) { - cdbSymbol (currFunc, cdbFile, FALSE, TRUE); + debugFile->writeFunction(currFunc); _G.debugLine = 1; if (IS_STATIC (currFunc->etype)) emitcode ("", "F%s$%s$0$0 ==.", moduleName, currFunc->name); @@ -8418,7 +8911,7 @@ gen51Code (iCode * lic) for (ic = lic; ic; ic = ic->next) { - if (cln != ic->lineno) + if (ic->lineno && cln != ic->lineno) { if (options.debug) { @@ -8428,9 +8921,23 @@ gen51Code (iCode * lic) ic->level, ic->block); _G.debugLine = 0; } - emitcode (";", "%s %d", ic->filename, ic->lineno); + if (!options.noCcodeInAsm) { + emitcode ("", ";%s:%d: %s", ic->filename, ic->lineno, + printCLine(ic->filename, ic->lineno)); + } cln = ic->lineno; } + if (options.iCodeInAsm) { + char regsInUse[80]; + int i; + + for (i=0; i<8; i++) { + sprintf (®sInUse[i], + "%c", ic->riu & (1<seq, printILine(ic)); + } /* if the result is marked as spilt and rematerializable or code for this has already been generated then @@ -8588,12 +9095,12 @@ gen51Code (iCode * lic) break; case GET_VALUE_AT_ADDRESS: - genPointerGet (ic, hasInc(IC_LEFT(ic),ic)); + genPointerGet (ic, hasInc(IC_LEFT(ic),ic,getSize(operandType(IC_RESULT(ic))))); break; case '=': if (POINTER_SET (ic)) - genPointerSet (ic, hasInc (IC_RESULT(ic),ic)); + genPointerSet (ic, hasInc (IC_RESULT(ic),ic,getSize(operandType(IC_RIGHT(ic))))); else genAssign (ic); break;