X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fmcs51%2Fgen.c;h=9a81b0cf89a13d9b950b56a970c8b83f82fbf817;hb=25451c9197f0c42c161394e4587a16d08556e09b;hp=6863646aece3409c80311520566008d7e5d28f3d;hpb=f99d4b2c626ec803f1fb055b6cfa8a0807af1673;p=fw%2Fsdcc diff --git a/src/mcs51/gen.c b/src/mcs51/gen.c index 6863646a..9a81b0cf 100644 --- a/src/mcs51/gen.c +++ b/src/mcs51/gen.c @@ -28,8 +28,8 @@ Made everything static -------------------------------------------------------------------------*/ -#define D(x) -//#define D(x) x +//#define D(x) +#define D(x) x #include #include @@ -41,6 +41,9 @@ #ifdef HAVE_SYS_ISA_DEFS_H #include #else +#ifdef HAVE_MACHINE_ENDIAN_H +#include +#else #ifdef HAVE_ENDIAN_H #include #else @@ -50,6 +53,7 @@ #endif #endif #endif +#endif #include "common.h" #include "SDCCpeeph.h" @@ -346,8 +350,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; } @@ -373,6 +377,7 @@ aopForRemat (symbol * sym) { iCode *ic = sym->rematiCode; asmop *aop = newAsmop (AOP_IMMD); + int ptr_type=0; int val = 0; for (;;) @@ -381,8 +386,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; } @@ -395,8 +409,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; } @@ -533,7 +554,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 */ @@ -560,7 +581,6 @@ aopOp (operand * op, iCode * ic, bool result) sym = OP_SYMBOL (op); - /* if the type is a conditional */ if (sym->regType == REG_CND) { @@ -597,6 +617,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++) @@ -605,6 +626,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); @@ -798,15 +823,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; @@ -984,7 +1011,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; @@ -1011,7 +1043,7 @@ aopPut (asmop * aop, char *s, int offset) } { symbol *lbl = newiTempLabel (NULL); - emitcode ("clr", "c; oops"); + emitcode ("clr", "c"); emitcode ("jz", "%05d$", lbl->key + 100); emitcode ("cpl", "c"); emitcode ("", "%05d$:", lbl->key + 100); @@ -1122,6 +1154,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); @@ -1250,6 +1284,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); @@ -1294,6 +1330,8 @@ genCpl (iCode * ic) int size; + D(emitcode (";", "genCpl")); + /* assign asmOps to operand & result */ aopOp (IC_LEFT (ic), ic, FALSE); aopOp (IC_RESULT (ic), ic, TRUE); @@ -1334,6 +1372,9 @@ genUminusFloat (operand * op, operand * result) { int size, offset = 0; char *l; + + D(emitcode (";", "genUminusFloat")); + /* for this we just need to flip the first it then copy the rest in place */ size = AOP_SIZE (op) - 1; @@ -1363,6 +1404,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); @@ -1438,7 +1481,6 @@ saveRegisters (iCode * lic) int i; iCode *ic; bitVect *rsave; - sym_link *detype; /* look for call */ for (ic = lic; ic; ic = ic->next) @@ -1453,14 +1495,14 @@ saveRegisters (iCode * lic) /* 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) || - SPEC_NAKED(OP_SYM_ETYPE(IC_LEFT (ic)))) + if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type) || + IFFUNC_ISNAKED(OP_SYM_TYPE(IC_LEFT (ic)))) return; - /* find the registers in use at this time - and push them away to safety */ - rsave = bitVectCplAnd (bitVectCopy (ic->rMask), - ic->rUsed); + /* 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) @@ -1490,10 +1532,8 @@ saveRegisters (iCode * lic) if (bitVectBitValue (rsave, i)) emitcode ("push", "%s", mcs51_regWithIdx (i)->dname); } - - detype = getSpec (operandType (IC_LEFT (ic))); - } + /*-----------------------------------------------------------------*/ /* unsaveRegisters - pop the pushed registers */ /*-----------------------------------------------------------------*/ @@ -1502,10 +1542,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) { @@ -1585,6 +1626,8 @@ genXpush (iCode * ic) regs *r; int size, offset = 0; + D(emitcode (";", "genXpush")); + aopOp (IC_LEFT (ic), ic, FALSE); r = getFreePtr (ic, &aop, FALSE); @@ -1691,6 +1734,7 @@ genIpop (iCode * ic) { int size, offset; + D(emitcode (";", "genIpop")); /* if the temp was not pushed then */ if (OP_SYMBOL (IC_LEFT (ic))->isspilt) @@ -1845,11 +1889,12 @@ saveRBank (int bank, iCode * ic, bool pushPsw) static void genCall (iCode * ic) { - sym_link *detype; + sym_link *dtype; bool restoreBank = FALSE; bool swapBanks = FALSE; D(emitcode(";", "genCall")); + /* if send set is not empty the assign */ if (_G.sendSet) { @@ -1879,17 +1924,17 @@ genCall (iCode * ic) /* if we are calling a not _naked function that is not using the same register bank then we need to save the destination registers on the stack */ - detype = getSpec (operandType (IC_LEFT (ic))); - if (detype && !SPEC_NAKED(detype) && - (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype)) && - IS_ISR (currFunc->etype)) + dtype = operandType (IC_LEFT (ic)); + if (currFunc && dtype && !IFFUNC_ISNAKED(dtype) && + (FUNC_REGBANK (currFunc->type) != FUNC_REGBANK (dtype)) && + IFFUNC_ISISR (currFunc->type)) { if (!ic->bankSaved) { /* This is unexpected; the bank should have been saved in * genFunction. */ - saveRBank (SPEC_BANK (detype), ic, FALSE); + saveRBank (FUNC_REGBANK (dtype), ic, FALSE); restoreBank = TRUE; } swapBanks = TRUE; @@ -1902,7 +1947,7 @@ genCall (iCode * ic) if (swapBanks) { emitcode ("mov", "psw,#0x%02x", - ((SPEC_BANK(detype)) << 3) & 0xff); + ((FUNC_REGBANK(dtype)) << 3) & 0xff); } /* make the call */ @@ -1913,12 +1958,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))) { @@ -1949,12 +1995,12 @@ 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); + unsaveRBank (FUNC_REGBANK (dtype), ic, FALSE); } /*-----------------------------------------------------------------*/ @@ -1963,9 +2009,11 @@ genCall (iCode * ic) static void genPcall (iCode * ic) { - sym_link *detype; + sym_link *dtype; symbol *rlbl = newiTempLabel (NULL); + bool restoreBank=FALSE; + D(emitcode(";", "genPCall")); /* if caller saves & we have not saved then */ if (!ic->regsSaved) @@ -1974,12 +2022,13 @@ genPcall (iCode * ic) /* if we are calling a function that is not using the same register bank then we need to save the destination registers on the stack */ - detype = getSpec (operandType (IC_LEFT (ic))); - if (detype && - IS_ISR (currFunc->etype) && - (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype))) - saveRBank (SPEC_BANK (detype), ic, TRUE); - + dtype = operandType (IC_LEFT (ic)); + if (currFunc && dtype && !FUNC_ISNAKED(dtype) && + IFFUNC_ISISR (currFunc->type) && + (FUNC_REGBANK (currFunc->type) != FUNC_REGBANK (dtype))) { + saveRBank (FUNC_REGBANK (dtype), ic, TRUE); + restoreBank=TRUE; + } /* push the return address on to the stack */ emitcode ("mov", "a,#%05d$", (rlbl->key + 100)); @@ -2058,16 +2107,13 @@ 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 (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); - } /*-----------------------------------------------------------------*/ @@ -2123,8 +2169,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 */ @@ -2133,25 +2180,25 @@ genFunction (iCode * ic) emitcode (";", "-----------------------------------------"); emitcode ("", "%s:", sym->rname); - fetype = getSpec (operandType (IC_LEFT (ic))); + ftype = operandType (IC_LEFT (ic)); - if (SPEC_NAKED(fetype)) + if (IFFUNC_ISNAKED(ftype)) { emitcode(";", "naked function: no prologue."); return; } /* if critical function then turn interrupts off */ - if (SPEC_CRTCL (fetype)) + if (IFFUNC_ISCRITICAL (ftype)) emitcode ("clr", "ea"); /* here we need to generate the equates for the register bank if required */ - if (SPEC_BANK (fetype) != rbank) + if (FUNC_REGBANK (ftype) != rbank) { int i; - rbank = SPEC_BANK (fetype); + rbank = FUNC_REGBANK (ftype); for (i = 0; i < mcs51_nRegs; i++) { if (strcmp (regs8051[i].base, "0") == 0) @@ -2168,7 +2215,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")) @@ -2182,13 +2229,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; @@ -2225,7 +2272,7 @@ genFunction (iCode * ic) */ unsigned long banksToSave = 0; - if (sym->hasFcall) + if (IFFUNC_HASFCALL(sym->type)) { #define MAX_REGISTER_BANKS 4 @@ -2243,20 +2290,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 @@ -2288,7 +2335,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; } @@ -2300,6 +2347,7 @@ genFunction (iCode * ic) } } } + // jwk: this needs a closer look SPEC_ISR_SAVED_BANKS(currFunc->etype) = banksToSave; } } @@ -2307,7 +2355,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; @@ -2320,6 +2368,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++; } @@ -2329,14 +2380,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) @@ -2370,6 +2421,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 ar0 */ + emitcode ("mov", "ar0,a"); + emitcode ("mov", "a,sp"); + emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff)); + emitcode ("mov", "sp,a"); + emitcode ("mov", "a,ar0"); + } + } else while (i--) emitcode ("inc", "sp"); @@ -2393,13 +2472,13 @@ genEndFunction (iCode * ic) { symbol *sym = OP_SYMBOL (IC_LEFT (ic)); - if (SPEC_NAKED(sym->etype)) + if (IFFUNC_ISNAKED(sym->type)) { emitcode(";", "naked function: no epilogue."); return; } - if (IS_RENT (sym->etype) || options.stackAuto) + if (IFFUNC_ISREENT (sym->type) || options.stackAuto) { emitcode ("mov", "%s,_bp", spname); } @@ -2415,7 +2494,7 @@ genEndFunction (iCode * ic) } - if ((IS_RENT (sym->etype) || options.stackAuto)) + if ((IFFUNC_ISREENT (sym->type) || options.stackAuto)) { if (options.useXstack) { @@ -2431,9 +2510,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 @@ -2443,19 +2522,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; @@ -2487,6 +2566,7 @@ genEndFunction (iCode * ic) * Restore any register banks saved by genFunction * in reverse order. */ + // jwk: this needs a closer look unsigned savedBanks = SPEC_ISR_SAVED_BANKS(currFunc->etype); int ix; @@ -2516,11 +2596,10 @@ 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 (options.debug && currFunc) { _G.debugLine = 1; @@ -2538,10 +2617,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; @@ -2586,6 +2665,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)) @@ -2707,6 +2788,8 @@ genPlusIncr (iCode * ic) if ((icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 4) return FALSE; + D(emitcode (";", "genPlusIncr")); + /* if increment 16 bits in register */ if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))) && (size > 1) && @@ -2842,6 +2925,8 @@ outBitAcc (operand * result) static void genPlusBits (iCode * ic) { + D(emitcode (";", "genPlusBits")); + if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY) { symbol *lbl = newiTempLabel (NULL); @@ -2945,6 +3030,8 @@ genPlus (iCode * ic) /* special cases :- */ + D(emitcode (";", "genPlus")); + aopOp (IC_LEFT (ic), ic, FALSE); aopOp (IC_RIGHT (ic), ic, FALSE); aopOp (IC_RESULT (ic), ic, TRUE); @@ -3055,6 +3142,8 @@ genMinusDec (iCode * ic) if ((icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 4) return FALSE; + D(emitcode (";", "genMinusDec")); + /* if decrement 16 bits in register */ if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))) && (size > 1) && @@ -3182,6 +3271,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); @@ -3211,6 +3303,8 @@ 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); aopOp (IC_RESULT (ic), ic, TRUE); @@ -3283,6 +3377,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); @@ -3301,6 +3397,8 @@ genMultOneByte (operand * left, symbol *lbl; int size=AOP_SIZE(result); + D(emitcode (";", "genMultOneByte")); + if (size<1 || size>2) { // this should never happen fprintf (stderr, "size!=1||2 (%d) in %s at line:%d \n", @@ -3403,6 +3501,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); @@ -3418,15 +3518,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)); @@ -3445,6 +3551,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); @@ -3469,6 +3577,8 @@ genDivOneByte (operand * left, symbol *lbl; int size, offset; + D(emitcode (";", "genDivOneByte")); + size = AOP_SIZE (result) - 1; offset = 1; /* signed or unsigned */ @@ -3552,6 +3662,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); @@ -3575,7 +3687,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)); @@ -3593,6 +3705,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); @@ -3617,6 +3731,8 @@ genModOneByte (operand * left, char *l; symbol *lbl; + D(emitcode (";", "genModOneByte")); + /* signed or unsigned */ if (SPEC_USIGN (opetype)) { @@ -3690,6 +3806,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); @@ -3713,7 +3831,7 @@ genMod (iCode * ic) } /* should have been converted to function call */ - assert (1); + assert (0); release: freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE)); @@ -3731,6 +3849,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)) @@ -3767,6 +3887,8 @@ 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) @@ -3875,6 +3997,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); @@ -3902,6 +4026,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); @@ -4017,6 +4143,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); @@ -4207,6 +4335,9 @@ hasInc (operand *op, iCode *ic) iCode *lic = ic->next; int isize ; + /* this could from a cast, e.g.: "(char xdata *) 0x7654;" */ + if (!IS_SYMOP(op)) return NULL; + if (IS_BITVAR(retype)||!IS_PTR(type)) return NULL; isize = getSize(type->next); while (lic) { @@ -4221,6 +4352,8 @@ hasInc (operand *op, iCode *ic) if (bitVectBitValue(OP_USES(op),lic->key) || (unsigned) lic->defKey == op->key) { return NULL; } + /* if GOTO or IFX */ + if (lic->op == IFX || lic->op == GOTO) break; lic = lic->next; } return NULL; @@ -4235,6 +4368,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 */ @@ -4275,6 +4410,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 */ @@ -4384,6 +4521,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); @@ -4686,6 +4825,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); @@ -4953,6 +5094,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); @@ -5209,6 +5352,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); @@ -5253,6 +5398,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); @@ -5301,6 +5448,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); @@ -5351,6 +5500,9 @@ static void genGetHbit (iCode * ic) { operand *left, *result; + + D(emitcode (";", "genGetHbit")); + left = IC_LEFT (ic); result = IC_RESULT (ic); aopOp (left, ic, FALSE); @@ -5955,6 +6107,8 @@ shiftRLeftOrResult (operand * left, int offl, static void genlshOne (operand * result, operand * left, int shCount) { + D(emitcode (";", "genlshOne")); + shiftL1Left2Result (left, LSB, result, LSB, shCount); } @@ -5966,6 +6120,8 @@ genlshTwo (operand * result, operand * left, int shCount) { int size; + D(emitcode (";", "genlshTwo")); + size = getDataSize (result); /* if shCount >= 8 */ @@ -6070,6 +6226,8 @@ genlshFour (operand * result, operand * left, int shCount) { int size; + D(emitcode (";", "genlshFour")); + size = AOP_SIZE (result); /* if shifting more that 3 bytes */ @@ -6167,6 +6325,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); @@ -6226,6 +6386,8 @@ genLeftShift (iCode * ic) char *l; symbol *tlbl, *tlbl1; + D(emitcode (";", "genLeftShift")); + right = IC_RIGHT (ic); left = IC_LEFT (ic); result = IC_RESULT (ic); @@ -6327,6 +6489,8 @@ static void genrshOne (operand * result, operand * left, int shCount, int sign) { + D(emitcode (";", "genrshOne")); + shiftR1Left2Result (left, LSB, result, LSB, shCount, sign); } @@ -6337,6 +6501,8 @@ static void genrshTwo (operand * result, operand * left, int shCount, int sign) { + D(emitcode (";", "genrshTwo")); + /* if shCount >= 8 */ if (shCount >= 8) { @@ -6422,6 +6588,8 @@ static void genrshFour (operand * result, operand * left, int shCount, int sign) { + D(emitcode (";", "genrshFour")); + /* if shifting more that 3 bytes */ if (shCount >= 24) { @@ -6495,6 +6663,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); @@ -6558,6 +6728,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 */ @@ -6664,6 +6836,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))); @@ -6783,6 +6957,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 */ @@ -6904,6 +7080,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 */ @@ -6938,6 +7117,8 @@ genNearPointerGet (operand * left, sym_link *ltype = operandType (left); char buffer[80]; + D(emitcode (";", "genNearPointerGet")); + rtype = operandType (result); retype = getSpec (rtype); @@ -7048,6 +7229,8 @@ genPagedPointerGet (operand * left, char *rname; sym_link *rtype, *retype; + D(emitcode (";", "genPagedPointerGet")); + rtype = operandType (result); retype = getSpec (rtype); @@ -7134,6 +7317,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 @@ -7188,6 +7373,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 @@ -7243,6 +7430,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 @@ -7253,7 +7442,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 */ @@ -7285,6 +7477,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); @@ -7301,6 +7494,8 @@ genPointerGet (iCode * ic, iCode *pi) sym_link *type, *etype; int p_type; + D(emitcode (";", "genPointerGet")); + left = IC_LEFT (ic); result = IC_RESULT (ic); @@ -7317,6 +7512,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 = type = operandType (left); + p_type = DCL_TYPE (type); + } /* now that we have the pointer type we assign the pointer values */ switch (p_type) @@ -7360,6 +7562,8 @@ genPackBits (sym_link * etype, int blen, bstr; char *l; + D(emitcode (";", "genPackBits")); + blen = SPEC_BLEN (etype); bstr = SPEC_BSTR (etype); @@ -7525,6 +7729,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); @@ -7558,6 +7764,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); @@ -7577,19 +7785,42 @@ genNearPointerSet (operand * right, 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); @@ -7660,6 +7891,8 @@ genPagedPointerSet (operand * right, char *rname, *l; sym_link *retype, *letype; + D(emitcode (";", "genPagedPointerSet")); + retype = getSpec (operandType (right)); letype = getSpec (operandType (result)); @@ -7747,6 +7980,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 @@ -7802,6 +8038,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 @@ -7812,7 +8050,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 */ @@ -7845,6 +8086,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); @@ -7861,6 +8103,8 @@ genPointerSet (iCode * ic, iCode *pi) sym_link *type, *etype; int p_type; + D(emitcode (";", "genPointerSet")); + right = IC_RIGHT (ic); result = IC_RESULT (ic); @@ -7879,6 +8123,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 = type = operandType (result); + p_type = DCL_TYPE (type); + } /* now that we have the pointer type we assign the pointer values */ switch (p_type) @@ -7913,6 +8164,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 */ @@ -7948,6 +8201,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 @@ -7960,7 +8215,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 @@ -8010,6 +8267,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--) { @@ -8145,6 +8405,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); @@ -8187,7 +8449,8 @@ genCast (iCode * ic) aopOp (result, ic, FALSE); /* if the result is a bit */ - if (AOP_TYPE (result) == AOP_CRY) + // if (AOP_TYPE (result) == AOP_CRY /* works only for true symbols */ + if (IS_BITVAR(OP_SYMBOL(result)->type)) { /* if the right size is a literal then we know what the value is */ @@ -8367,6 +8630,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)) @@ -8443,6 +8708,8 @@ genDjnz (iCode * ic, iCode * ifx) static void genReceive (iCode * ic) { + D(emitcode (";", "genReceive")); + if (isOperandInFarSpace (IC_RESULT (ic)) && (OP_SYMBOL (IC_RESULT (ic))->isspilt || IS_TRUE_SYMOP (IC_RESULT (ic)))) @@ -8489,13 +8756,23 @@ void gen51AggregateAssign(iCode *ic) { int toSize=getSize(OP_SYMBOL(left)->type); int count=toSize; + D(emitcode (";", "gen51AggregateAssign")); + + if (SPEC_OCLS(OP_SYMBOL(left)->etype)!=xdata || + SPEC_OCLS(OP_SYMBOL(right)->etype)!=code) { + // well, this code isn't used yet from anywhere else as for initialising + fprintf (stderr, "*** error: %s:%d can only assign aggregates from cseg to xseg for now\n", ic->filename, ic->lineno); + exit (457); + } + if (fromSize!=toSize) { - fprintf (stderr, "*** error aggregates have different size"); - if (fromSizefilename, ic->lineno); + exit (821); } - - // memcpy from cseg to xseg + +#if 1 + // use the generic memcpy() for now emitcode (";", "initialize %s", OP_SYMBOL(IC_LEFT(ic))->name); emitcode ("mov", "dptr,#_memcpy_PARM_2"); emitcode ("mov", "a,#%s", fromName); @@ -8504,7 +8781,7 @@ void gen51AggregateAssign(iCode *ic) { emitcode ("mov", "a,#(%s>>8)", fromName); emitcode ("movx", "@dptr,a"); emitcode ("inc", "dptr"); - emitcode ("mov", "a,#%02x; from cseg", 2); + emitcode ("mov", "a,#%02x; only from cseg for now", 2); emitcode ("movx", "@dptr,a"); emitcode ("mov", "dptr,#_memcpy_PARM_3"); emitcode ("mov", "a,#(%d>>0); number of bytes", count); @@ -8515,6 +8792,16 @@ void gen51AggregateAssign(iCode *ic) { emitcode ("mov", "dptr,#%s", toName); emitcode ("mov", "b,#%02x; only to xseg for now", 1); emitcode ("lcall", "_memcpy"); +#else + // more efficient, but will require the native_memcpy_cs2xs + emitcode ("mov", "r0,#%s", fromName); + emitcode ("mov", "r1,#(%s>>8)", fromName); + emitcode ("mov", "r2,#%s", toName); + emitcode ("mov", "r3,#(%s>>8)", toName); + emitcode ("mov", "r4,#%d", count); + emitcode ("mov", "r5,#(%d>>8)", count); + emitcode ("lcall", "_native_memcpy_cs2xs"); +#endif } /*-----------------------------------------------------------------*/ @@ -8532,7 +8819,6 @@ gen51Code (iCode * lic) if (allocInfo) printAllocInfo (currFunc, codeOutFile); /* if debug information required */ - /* if (options.debug && currFunc) { */ if (options.debug && currFunc) { cdbSymbol (currFunc, cdbFile, FALSE, TRUE);