X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fmcs51%2Fgen.c;h=7f2c239ef5a9cfd245984455a2484cf4b80fd392;hb=5efbd810e2cf3c65b3f005e529a6091c951e3ea7;hp=f30450882a0e82e3a2c129639e5bc548b2ff5d08;hpb=8bd26b251f0134ff20ce9102e1d844329525cbcb;p=fw%2Fsdcc diff --git a/src/mcs51/gen.c b/src/mcs51/gen.c index f3045088..7f2c239e 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 @@ -41,7 +44,7 @@ #ifdef HAVE_ENDIAN_H #include #else -#if !defined(__BORLANDC__) && !defined(_MSC_VER) +#if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__) #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN" #warning "If you running sdcc on an INTEL 80x86 Platform you are okay" #endif @@ -162,9 +165,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; } @@ -236,7 +239,7 @@ endOfWorld: /* other wise this is true end of the world */ werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "getFreePtr should never reach here"); - exit (0); + exit (1); } /*-----------------------------------------------------------------*/ @@ -270,7 +273,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) @@ -846,7 +854,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 +868,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 +913,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) @@ -1003,7 +1011,7 @@ aopPut (asmop * aop, char *s, int offset) } { symbol *lbl = newiTempLabel (NULL); - emitcode ("clr", "c"); + emitcode ("clr", "c; oops"); emitcode ("jz", "%05d$", lbl->key + 100); emitcode ("cpl", "c"); emitcode ("", "%05d$:", lbl->key + 100); @@ -1031,7 +1039,7 @@ aopPut (asmop * aop, char *s, int offset) default: werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "aopPut got unsupported aop->type"); - exit (0); + exit (1); } } @@ -1443,9 +1451,10 @@ 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 || (OP_SYMBOL (IC_LEFT (ic))->calleeSave) || + SPEC_NAKED(OP_SYM_ETYPE(IC_LEFT (ic)))) return; /* find the registers in use at this time @@ -1484,14 +1493,6 @@ saveRegisters (iCode * lic) 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 */ @@ -1618,6 +1619,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) @@ -1710,25 +1713,36 @@ static void unsaveRBank (int bank, iCode * ic, bool popPsw) { int i; - asmop *aop; + asmop *aop = NULL; regs *r = NULL; + if (options.useXstack) + { + if (!ic) + { + /* Assume r0 is available for use. */ + r = mcs51_regWithIdx (R0_IDX);; + } + else + { + aop = newAsmop (0); + r = getFreePtr (ic, &aop, FALSE); + } + emitcode ("mov", "%s,_spx", r->name); + } + if (popPsw) { if (options.useXstack) - { - aop = newAsmop (0); - r = getFreePtr (ic, &aop, FALSE); - - - emitcode ("mov", "%s,_spx", r->name); + { emitcode ("movx", "a,@%s", r->name); emitcode ("mov", "psw,a"); emitcode ("dec", "%s", r->name); - } else + { emitcode ("pop", "psw"); + } } for (i = (mcs51_nRegs - 1); i >= 0; i--) @@ -1748,11 +1762,13 @@ unsaveRBank (int bank, iCode * ic, bool popPsw) if (options.useXstack) { - emitcode ("mov", "_spx,%s", r->name); - freeAsmop (NULL, aop, ic, TRUE); - } + + if (aop) + { + freeAsmop (NULL, aop, ic, TRUE); + } } /*-----------------------------------------------------------------*/ @@ -1762,16 +1778,22 @@ static void saveRBank (int bank, iCode * ic, bool pushPsw) { int i; - asmop *aop; + asmop *aop = NULL; regs *r = NULL; if (options.useXstack) { - - aop = newAsmop (0); - r = getFreePtr (ic, &aop, FALSE); + if (!ic) + { + /* Assume r0 is available for use. */ + r = mcs51_regWithIdx (R0_IDX);; + } + else + { + aop = newAsmop (0); + r = getFreePtr (ic, &aop, FALSE); + } emitcode ("mov", "%s,_spx", r->name); - } for (i = 0; i < mcs51_nRegs; i++) @@ -1796,16 +1818,25 @@ saveRBank (int bank, iCode * ic, bool pushPsw) emitcode ("movx", "@%s,a", r->name); emitcode ("inc", "%s", r->name); emitcode ("mov", "_spx,%s", r->name); - freeAsmop (NULL, aop, ic, TRUE); } else + { emitcode ("push", "psw"); + } emitcode ("mov", "psw,#0x%02x", (bank << 3) & 0x00ff); } - ic->bankSaved = 1; + if (aop) + { + freeAsmop (NULL, aop, ic, TRUE); + } + + if (ic) + { + ic->bankSaved = 1; + } } /*-----------------------------------------------------------------*/ @@ -1815,7 +1846,10 @@ static void genCall (iCode * ic) { sym_link *detype; + bool restoreBank = FALSE; + bool swapBanks = FALSE; + D(emitcode(";", "genCall")); /* if send set is not empty the assign */ if (_G.sendSet) { @@ -1842,19 +1876,33 @@ genCall (iCode * ic) _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 && + if (detype && !SPEC_NAKED(detype) && (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype)) && - IS_ISR (currFunc->etype) && - !ic->bankSaved) { - saveRBank (SPEC_BANK (detype), ic, TRUE); - } else /* no need to save if we just saved the whole bank */ { - /* if caller saves & we have not saved then */ - if (!ic->regsSaved) + IS_ISR (currFunc->etype)) + { + if (!ic->bankSaved) + { + /* This is unexpected; the bank should have been saved in + * genFunction. + */ + saveRBank (SPEC_BANK (detype), ic, FALSE); + restoreBank = TRUE; + } + swapBanks = TRUE; + } + + /* if caller saves & we have not saved then */ + if (!ic->regsSaved) saveRegisters (ic); + + if (swapBanks) + { + emitcode ("mov", "psw,#0x%02x", + ((SPEC_BANK(detype)) << 3) & 0xff); } /* make the call */ @@ -1862,6 +1910,12 @@ genCall (iCode * ic) OP_SYMBOL (IC_LEFT (ic))->rname : OP_SYMBOL (IC_LEFT (ic))->name)); + if (swapBanks) + { + emitcode ("mov", "psw,#0x%02x", + ((SPEC_BANK(currFunc->etype)) << 3) & 0xff); + } + /* if we need assign a result value */ if ((IS_ITEMP (IC_RESULT (ic)) && (OP_SYMBOL (IC_RESULT (ic))->nRegs || @@ -1892,18 +1946,15 @@ genCall (iCode * ic) else for (i = 0; i < ic->parmBytes; i++) emitcode ("dec", "%s", spname); - } - /* if register bank was saved then pop them */ - if (ic->bankSaved) - unsaveRBank (SPEC_BANK (detype), ic, TRUE); - /* if we hade saved some registers then unsave them */ if (ic->regsSaved && !(OP_SYMBOL (IC_LEFT (ic))->calleeSave)) unsaveRegisters (ic); - + /* if register bank was saved then pop them */ + if (restoreBank) + unsaveRBank (SPEC_BANK (detype), ic, FALSE); } /*-----------------------------------------------------------------*/ @@ -2073,6 +2124,7 @@ genFunction (iCode * ic) { symbol *sym; sym_link *fetype; + bool switchedPSW = FALSE; _G.nRegsSaved = 0; /* create the function header */ @@ -2083,6 +2135,12 @@ genFunction (iCode * ic) emitcode ("", "%s:", sym->rname); fetype = getSpec (operandType (IC_LEFT (ic))); + if (SPEC_NAKED(fetype)) + { + emitcode(";", "naked function: no prologue."); + return; + } + /* if critical function then turn interrupts off */ if (SPEC_CRTCL (fetype)) emitcode ("clr", "ea"); @@ -2155,6 +2213,95 @@ genFunction (iCode * ic) saveRBank (0, ic, FALSE); } } + else + { + /* This ISR uses a non-zero bank. + * + * We assume that the bank is available for our + * exclusive use. + * + * However, if this ISR calls a function which uses some + * other bank, we must save that bank entirely. + */ + unsigned long banksToSave = 0; + + if (sym->hasFcall) + { + +#define MAX_REGISTER_BANKS 4 + + iCode *i; + int ix; + + for (i = ic; i; i = i->next) + { + if (i->op == ENDFUNCTION) + { + /* we got to the end OK. */ + break; + } + + if (i->op == CALL) + { + sym_link *detype; + + detype = getSpec(operandType (IC_LEFT(i))); + if (detype + && SPEC_BANK(detype) != SPEC_BANK(sym->etype)) + { + /* Mark this bank for saving. */ + if (SPEC_BANK(detype) >= MAX_REGISTER_BANKS) + { + werror(E_NO_SUCH_BANK, SPEC_BANK(detype)); + } + else + { + banksToSave |= (1 << SPEC_BANK(detype)); + } + + /* And note that we don't need to do it in + * genCall. + */ + i->bankSaved = 1; + } + } + if (i->op == PCALL) + { + /* This is a mess; we have no idea what + * register bank the called function might + * use. + * + * The only thing I can think of to do is + * throw a warning and hope. + */ + werror(W_FUNCPTR_IN_USING_ISR); + } + } + + if (banksToSave && options.useXstack) + { + /* Since we aren't passing it an ic, + * saveRBank will assume r0 is available to abuse. + * + * So switch to our (trashable) bank now, so + * the caller's R0 isn't trashed. + */ + emitcode ("push", "psw"); + emitcode ("mov", "psw,#0x%02x", + (SPEC_BANK (sym->etype) << 3) & 0x00ff); + switchedPSW = TRUE; + } + + for (ix = 0; ix < MAX_REGISTER_BANKS; ix++) + { + if (banksToSave & (1 << ix)) + { + saveRBank(ix, NULL, FALSE); + } + } + } + SPEC_ISR_SAVED_BANKS(currFunc->etype) = banksToSave; + } } else { @@ -2182,7 +2329,8 @@ genFunction (iCode * ic) } /* set the register bank to the desired value */ - if (SPEC_BANK (sym->etype) || IS_ISR (sym->etype)) + if ((SPEC_BANK (sym->etype) || IS_ISR (sym->etype)) + && !switchedPSW) { emitcode ("push", "psw"); emitcode ("mov", "psw,#0x%02x", (SPEC_BANK (sym->etype) << 3) & 0x00ff); @@ -2245,6 +2393,12 @@ genEndFunction (iCode * ic) { symbol *sym = OP_SYMBOL (IC_LEFT (ic)); + if (SPEC_NAKED(sym->etype)) + { + emitcode(";", "naked function: no epilogue."); + return; + } + if (IS_RENT (sym->etype) || options.stackAuto) { emitcode ("mov", "%s,_bp", spname); @@ -2278,7 +2432,16 @@ genEndFunction (iCode * ic) /* restore the register bank */ if (SPEC_BANK (sym->etype) || IS_ISR (sym->etype)) - emitcode ("pop", "psw"); + { + if (!SPEC_BANK (sym->etype) || !IS_ISR (sym->etype) + || !options.useXstack) + { + /* Special case of ISR using non-zero bank with useXstack + * is handled below. + */ + emitcode ("pop", "psw"); + } + } if (IS_ISR (sym->etype)) { @@ -2289,7 +2452,6 @@ genEndFunction (iCode * ic) registers :-) */ if (!SPEC_BANK (sym->etype)) { - /* if this function does not call any other function then we can be economical and save only those registers that are used */ @@ -2318,6 +2480,32 @@ genEndFunction (iCode * ic) unsaveRBank (0, ic, FALSE); } } + else + { + /* This ISR uses a non-zero bank. + * + * Restore any register banks saved by genFunction + * in reverse order. + */ + unsigned savedBanks = SPEC_ISR_SAVED_BANKS(currFunc->etype); + int ix; + + for (ix = MAX_REGISTER_BANKS - 1; ix >= 0; ix--) + { + if (savedBanks & (1 << ix)) + { + unsaveRBank(ix, NULL, FALSE); + } + } + + if (options.useXstack) + { + /* Restore bank AFTER calling unsaveRBank, + * since it can trash r0. + */ + emitcode ("pop", "psw"); + } + } if (!inExcludeList ("dph")) emitcode ("pop", "dph"); @@ -2332,8 +2520,8 @@ genEndFunction (iCode * ic) emitcode ("setb", "ea"); /* if debug then send end of function */ -/* if (options.debug && currFunc) { */ - if (currFunc) + /* if (options.debug && currFunc) */ + if (options.debug && currFunc) { _G.debugLine = 1; emitcode ("", "C$%s$%d$%d$%d ==.", @@ -2372,7 +2560,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 ==.", @@ -3063,12 +3251,17 @@ genMinus (iCode * ic) else { /* first add without previous c */ - if (!offset) - emitcode ("add", "a,#0x%02x", - (unsigned int) (lit & 0x0FFL)); - else + if (!offset) { + if (!size && lit==-1) { + emitcode ("dec", "a"); + } else { + emitcode ("add", "a,#0x%02x", + (unsigned int) (lit & 0x0FFL)); + } + } else { emitcode ("addc", "a,#0x%02x", (unsigned int) ((lit >> (offset * 8)) & 0x0FFL)); + } } aopPut (AOP (IC_RESULT (ic)), "a", offset++); } @@ -3108,7 +3301,6 @@ genMultOneByte (operand * left, symbol *lbl; int size=AOP_SIZE(result); - //emitcode (";",__FUNCTION__); if (size<1 || size>2) { // this should never happen fprintf (stderr, "size!=1||2 (%d) in %s at line:%d \n", @@ -3146,7 +3338,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); @@ -3157,22 +3348,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); @@ -4415,9 +4608,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++; } @@ -4684,9 +4888,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++; } @@ -4936,9 +5145,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++; @@ -5048,6 +5262,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--) { @@ -5065,6 +5285,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); @@ -5093,6 +5314,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++); @@ -5113,6 +5338,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); @@ -5974,13 +6200,15 @@ genLeftShiftLiteral (operand * left, break; case 2: - case 3: genlshTwo (result, left, shCount); break; case 4: genlshFour (result, left, shCount); break; + default: + fprintf(stderr, "*** ack! mystery literal shift!\n"); + break; } } freeAsmop (left, NULL, ic, TRUE); @@ -6134,22 +6362,48 @@ 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"); + emitcode ("xch", "a,%s", 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); + MOVA (aopGet (AOP (left), MSB24, FALSE, FALSE)); + } + + emitcode ("rrc", "a"); + if (isSameRegs && offl==1) { + emitcode ("xch", "a,%s",aopGet (AOP (left), MSB16, FALSE, FALSE)); + } else { + aopPut (AOP (result), "a", MSB24); + MOVA (aopGet (AOP (left), MSB16, FALSE, FALSE)); + } emitcode ("rrc", "a"); aopPut (AOP (result), "a", MSB16 - offl); @@ -6550,7 +6804,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: @@ -6603,7 +6857,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: @@ -6715,8 +6969,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)) @@ -7317,7 +7572,7 @@ 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))) @@ -7786,6 +8041,8 @@ genAssign (iCode * ic) int size, offset; unsigned long lit = 0L; + D(emitcode(";","genAssign")); + result = IC_RESULT (ic); right = IC_RIGHT (ic); @@ -7920,6 +8177,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; @@ -7995,8 +8254,13 @@ genCast (iCode * ic) 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 */ @@ -8022,7 +8286,10 @@ genCast (iCode * ic) case CPOINTER: l = "#0x02"; break; - case PPOINTER: + case GPOINTER: + l = "0x03"; + break; + case PPOINTER: // what the fck is this? l = "#0x03"; break; @@ -8065,7 +8332,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 (SPEC_USIGN (rtype) || !IS_SPEC (rtype) || AOP_TYPE(right)==AOP_CRY) { while (size--) aopPut (AOP (result), zero, offset++); @@ -8225,8 +8492,8 @@ gen51Code (iCode * lic) if (allocInfo) printAllocInfo (currFunc, codeOutFile); /* if debug information required */ -/* if (options.debug && currFunc) { */ - if (currFunc) + /* if (options.debug && currFunc) { */ + if (options.debug && currFunc) { cdbSymbol (currFunc, cdbFile, FALSE, TRUE); _G.debugLine = 1;