X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fmcs51%2Fgen.c;h=8fe501bab5eaf9bc2f9797dc71dff3e71a2ba4a0;hb=2f4eed72ea3a3f34795b26887679fdac2adc6b5d;hp=0b99a0242956dc098f62d09111bfa06f5a983acf;hpb=1e268ec9106bf4b907eff98c705e11689c9dcb64;p=fw%2Fsdcc diff --git a/src/mcs51/gen.c b/src/mcs51/gen.c index 0b99a024..8fe501ba 100644 --- a/src/mcs51/gen.c +++ b/src/mcs51/gen.c @@ -89,7 +89,7 @@ _G; extern int mcs51_ptrRegReq; extern int mcs51_nRegs; extern FILE *codeOutFile; -static void saverbank (int, iCode *, bool); +static void saveRBank (int, iCode *, bool); #define RESULTONSTACK(x) \ (IC_RESULT(x) && IC_RESULT(x)->aop && \ IC_RESULT(x)->aop->type == AOP_STK ) @@ -120,7 +120,7 @@ static void emitcode (char *inst, char *fmt,...) { va_list ap; - char lb[MAX_INLINEASM]; + char lb[INITIAL_INLINEASM]; char *lbp = lb; va_start (ap, fmt); @@ -233,7 +233,6 @@ endOfWorld: return NULL; } - piCode (ic, stdout); /* other wise this is true end of the world */ werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "getFreePtr should never reach here"); @@ -253,21 +252,6 @@ newAsmop (short type) return aop; } -static void -genSetDPTR (int n) -{ - if (!n) - { - emitcode (";", "Select standard DPTR"); - emitcode ("mov", "dps, #0x00"); - } - else - { - emitcode (";", "Select alternate DPTR"); - emitcode ("mov", "dps, #0x01"); - } -} - /*-----------------------------------------------------------------*/ /* pointerCode - returns the code for a pointer type */ /*-----------------------------------------------------------------*/ @@ -386,9 +370,9 @@ aopForRemat (symbol * sym) for (;;) { if (ic->op == '+') - val += operandLitValue (IC_RIGHT (ic)); + val += (int) operandLitValue (IC_RIGHT (ic)); else if (ic->op == '-') - val -= operandLitValue (IC_RIGHT (ic)); + val -= (int) operandLitValue (IC_RIGHT (ic)); else break; @@ -604,7 +588,7 @@ aopOp (operand * op, iCode * ic, bool result) if (sym->ruonly) { - int i; + unsigned i; aop = op->aop = sym->aop = newAsmop (AOP_STR); aop->size = getSize (sym->type); for (i = 0; i < fReturnSizeMCS51; i++) @@ -780,13 +764,6 @@ aopGet (asmop * aop, int offset, bool bit16, bool dname) return rs; case AOP_DPTR: - case AOP_DPTR2: - - if (aop->type == AOP_DPTR2) - { - genSetDPTR (1); - } - while (offset > aop->coff) { emitcode ("inc", "dptr"); @@ -809,12 +786,6 @@ aopGet (asmop * aop, int offset, bool bit16, bool dname) { emitcode ("movx", "a,@dptr"); } - - if (aop->type == AOP_DPTR2) - { - genSetDPTR (0); - } - return (dname ? "acc" : "a"); @@ -884,7 +855,6 @@ static void aopPut (asmop * aop, char *s, int offset) { char *d = buffer; - symbol *lbl; if (aop->size && offset > (aop->size - 1)) { @@ -931,13 +901,6 @@ aopPut (asmop * aop, char *s, int offset) break; case AOP_DPTR: - case AOP_DPTR2: - - if (aop->type == AOP_DPTR2) - { - genSetDPTR (1); - } - if (aop->code) { werror (E_INTERNAL_ERROR, __FILE__, __LINE__, @@ -963,11 +926,6 @@ aopPut (asmop * aop, char *s, int offset) MOVA (s); emitcode ("movx", "@dptr,a"); - - if (aop->type == AOP_DPTR2) - { - genSetDPTR (0); - } break; case AOP_R0: @@ -1039,17 +997,18 @@ aopPut (asmop * aop, char *s, int offset) emitcode ("mov", "%s,c", aop->aopu.aop_dir); else { - lbl = newiTempLabel (NULL); - if (strcmp (s, "a")) { MOVA (s); } - emitcode ("clr", "c"); - emitcode ("jz", "%05d$", lbl->key + 100); - emitcode ("cpl", "c"); - emitcode ("", "%05d$:", lbl->key + 100); - emitcode ("mov", "%s,c", aop->aopu.aop_dir); + { + symbol *lbl = newiTempLabel (NULL); + emitcode ("clr", "c"); + emitcode ("jz", "%05d$", lbl->key + 100); + emitcode ("cpl", "c"); + emitcode ("", "%05d$:", lbl->key + 100); + emitcode ("mov", "%s,c", aop->aopu.aop_dir); + } } } break; @@ -1112,38 +1071,24 @@ pointToEnd (asmop * aop) static void reAdjustPreg (asmop * aop) { - int size; - - aop->coff = 0; - if ((size = aop->size) <= 1) + if ((aop->coff==0) || aop->size <= 1) return; - size--; + switch (aop->type) { case AOP_R0: case AOP_R1: - while (size--) + while (aop->coff--) emitcode ("dec", "%s", aop->aopu.aop_ptr->name); break; case AOP_DPTR: - case AOP_DPTR2: - if (aop->type == AOP_DPTR2) - { - genSetDPTR (1); - } - while (size--) + while (aop->coff--) { emitcode ("lcall", "__decdptr"); } - - if (aop->type == AOP_DPTR2) - { - genSetDPTR (0); - } break; - } - + aop->coff = 0; } #define AOP(op) op->aop @@ -1153,8 +1098,7 @@ reAdjustPreg (asmop * aop) AOP_TYPE(x) == AOP_R0)) #define AOP_NEEDSACC(x) (AOP(x) && (AOP_TYPE(x) == AOP_CRY || \ - AOP_TYPE(x) == AOP_DPTR || AOP_TYPE(x) == AOP_DPTR2 || \ - AOP(x)->paged)) + AOP_TYPE(x) == AOP_DPTR || AOP(x)->paged)) #define AOP_INPREG(x) (x && (x->type == AOP_REG && \ (x->aopu.aop_reg[0] == mcs51_regWithIdx(R0_IDX) || \ @@ -1185,7 +1129,6 @@ genNotFloat (operand * op, operand * res) aopGet (op->aop, offset++, FALSE, FALSE)); } - tlbl = newiTempLabel (NULL); tlbl = newiTempLabel (NULL); aopPut (res->aop, one, 1); @@ -1540,12 +1483,14 @@ 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); + saveRBank (SPEC_BANK (detype), ic, TRUE); +#endif } /*-----------------------------------------------------------------*/ @@ -1760,10 +1705,10 @@ genIpop (iCode * ic) } /*-----------------------------------------------------------------*/ -/* unsaverbank - restores the resgister bank from stack */ +/* unsaveRBank - restores the resgister bank from stack */ /*-----------------------------------------------------------------*/ static void -unsaverbank (int bank, iCode * ic, bool popPsw) +unsaveRBank (int bank, iCode * ic, bool popPsw) { int i; asmop *aop; @@ -1812,10 +1757,10 @@ unsaverbank (int bank, iCode * ic, bool popPsw) } /*-----------------------------------------------------------------*/ -/* saverbank - saves an entire register bank on the stack */ +/* saveRBank - saves an entire register bank on the stack */ /*-----------------------------------------------------------------*/ static void -saverbank (int bank, iCode * ic, bool pushPsw) +saveRBank (int bank, iCode * ic, bool pushPsw) { int i; asmop *aop; @@ -1872,21 +1817,6 @@ genCall (iCode * ic) { sym_link *detype; - /* if caller saves & we have not saved then */ - if (!ic->regsSaved) - saveRegisters (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 && - (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype)) && - IS_ISR (currFunc->etype) && - !ic->bankSaved) - - saverbank (SPEC_BANK (detype), ic, TRUE); - /* if send set is not empty the assign */ if (_G.sendSet) { @@ -1912,6 +1842,22 @@ genCall (iCode * ic) } _G.sendSet = NULL; } + + /* 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 && + (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) + saveRegisters (ic); + } + /* make the call */ emitcode ("lcall", "%s", (OP_SYMBOL (IC_LEFT (ic))->rname[0] ? OP_SYMBOL (IC_LEFT (ic))->rname : @@ -1952,7 +1898,7 @@ genCall (iCode * ic) /* if register bank was saved then pop them */ if (ic->bankSaved) - unsaverbank (SPEC_BANK (detype), ic, TRUE); + unsaveRBank (SPEC_BANK (detype), ic, TRUE); /* if we hade saved some registers then unsave them */ if (ic->regsSaved && !(OP_SYMBOL (IC_LEFT (ic))->calleeSave)) @@ -1982,7 +1928,7 @@ genPcall (iCode * ic) if (detype && IS_ISR (currFunc->etype) && (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype))) - saverbank (SPEC_BANK (detype), ic, TRUE); + saveRBank (SPEC_BANK (detype), ic, TRUE); /* push the return address on to the stack */ @@ -2065,7 +2011,7 @@ genPcall (iCode * ic) if (detype && (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype))) - unsaverbank (SPEC_BANK (detype), ic, TRUE); + unsaveRBank (SPEC_BANK (detype), ic, TRUE); /* if we hade saved some registers then unsave them */ @@ -2205,9 +2151,9 @@ genFunction (iCode * ic) else { /* this function has a function call cannot - determines register usage so we will have the + determines register usage so we will have to push the entire bank */ - saverbank (0, ic, FALSE); + saveRBank (0, ic, FALSE); } } } @@ -2368,9 +2314,9 @@ genEndFunction (iCode * ic) else { /* this function has a function call cannot - determines register usage so we will have the + determines register usage so we will have to pop the entire bank */ - unsaverbank (0, ic, FALSE); + unsaveRBank (0, ic, FALSE); } } @@ -2571,7 +2517,7 @@ genPlusIncr (iCode * ic) /* if the literal value of the right hand side is greater than 4 then it is not worth it */ - if ((icount = floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 4) + if ((icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 4) return FALSE; /* if increment 16 bits in register */ @@ -3152,7 +3098,7 @@ genMultbits (operand * left, /*-----------------------------------------------------------------*/ -/* genMultOneByte : 8 bit multiplication & division */ +/* genMultOneByte : 8*8=8/16 bit multiplication */ /*-----------------------------------------------------------------*/ static void genMultOneByte (operand * left, @@ -3160,89 +3106,99 @@ genMultOneByte (operand * left, operand * result) { sym_link *opetype = operandType (result); - char *l; symbol *lbl; - int size, offset; + int size=AOP_SIZE(result); + + //emitcode (";",__FUNCTION__); + if (size<1 || size>2) { + // this should never happen + fprintf (stderr, "size!=1||2 (%d) in %s at line:%d \n", + AOP_SIZE(result), __FILE__, lineno); + exit (1); + } - /* (if two literals, the value is computed before) */ + /* (if two literals: the value is computed before) */ /* if one literal, literal on the right */ if (AOP_TYPE (left) == AOP_LIT) { operand *t = right; right = left; left = t; + //emitcode (";", "swapped left and right"); + } + + if (SPEC_USIGN(opetype) + // ignore the sign of left and right, what else can we do? + || (SPEC_USIGN(operandType(left)) && + SPEC_USIGN(operandType(right)))) { + // just an unsigned 8*8=8/16 multiply + //emitcode (";","unsigned"); + emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE)); + MOVA (aopGet (AOP (left), 0, FALSE, FALSE)); + emitcode ("mul", "ab"); + aopPut (AOP (result), "a", 0); + if (size==2) { + aopPut (AOP (result), "b", 1); } + return; + } - size = AOP_SIZE (result); - /* signed or unsigned */ - emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE)); - l = aopGet (AOP (left), 0, FALSE, FALSE); - MOVA (l); - emitcode ("mul", "ab"); - /* if result size = 1, mul signed = mul unsigned */ - aopPut (AOP (result), "a", 0); - if (size > 1) - { - if (SPEC_USIGN (opetype)) - { - aopPut (AOP (result), "b", 1); - if (size > 2) - /* for filling the MSBs */ - emitcode ("clr", "a"); - } - else - { - emitcode ("mov", "a,b"); + // we have to do a signed multiply - /* adjust the MSB if left or right neg */ + //emitcode (";", "signed"); + emitcode ("clr", "F0"); // reset sign flag + emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE)); + MOVA (aopGet (AOP (left), 0, FALSE, FALSE)); - /* if one literal */ - if (AOP_TYPE (right) == AOP_LIT) - { - /* AND literal negative */ - if ((int) floatFromVal (AOP (right)->aopu.aop_lit) < 0) - { - /* adjust MSB (c==0 after mul) */ - emitcode ("subb", "a,%s", aopGet (AOP (left), 0, FALSE, FALSE)); - } - } - else - { - lbl = newiTempLabel (NULL); - emitcode ("xch", "a,%s", aopGet (AOP (right), 0, FALSE, FALSE)); - emitcode ("cjne", "a,#0x80,%05d$", (lbl->key + 100)); - emitcode ("", "%05d$:", (lbl->key + 100)); - emitcode ("xch", "a,%s", aopGet (AOP (right), 0, FALSE, FALSE)); - lbl = newiTempLabel (NULL); - emitcode ("jc", "%05d$", (lbl->key + 100)); - emitcode ("subb", "a,%s", aopGet (AOP (left), 0, FALSE, FALSE)); - emitcode ("", "%05d$:", (lbl->key + 100)); - } + lbl=newiTempLabel(NULL); + emitcode ("jnb", "acc.7,%05d$", lbl->key+100); + // left side is negative, 8-bit two's complement, this fails for -128 + emitcode ("setb", "F0"); // set sign flag + emitcode ("cpl", "a"); + emitcode ("inc", "a"); - lbl = newiTempLabel (NULL); - emitcode ("xch", "a,%s", aopGet (AOP (left), 0, FALSE, FALSE)); - emitcode ("cjne", "a,#0x80,%05d$", (lbl->key + 100)); - emitcode ("", "%05d$:", (lbl->key + 100)); - emitcode ("xch", "a,%s", aopGet (AOP (left), 0, FALSE, FALSE)); - lbl = newiTempLabel (NULL); - emitcode ("jc", "%05d$", (lbl->key + 100)); - emitcode ("subb", "a,%s", aopGet (AOP (right), 0, FALSE, FALSE)); - emitcode ("", "%05d$:", (lbl->key + 100)); + emitcode ("", "%05d$:", lbl->key+100); + emitcode ("xch", "a,b"); - aopPut (AOP (result), "a", 1); - if (size > 2) - { - /* get the sign */ - emitcode ("rlc", "a"); - emitcode ("subb", "a,acc"); - } - } - size -= 2; - offset = 2; - if (size > 0) - while (size--) - aopPut (AOP (result), "a", offset++); + /* if literal */ + if (AOP_TYPE(right)==AOP_LIT) { + /* AND literal negative */ + if ((int) floatFromVal (AOP (right)->aopu.aop_lit) < 0) { + // two's complement for literal<0 + emitcode ("xrl", "PSW,#0x20"); // xrl sign flag + emitcode ("cpl", "a"); + emitcode ("inc", "a"); } + } else { + lbl=newiTempLabel(NULL); + emitcode ("jnb", "acc.7,%05d$", lbl->key+100); + // right side is negative, 8-bit two's complement + emitcode ("xrl", "PSW,#0x20"); // xrl sign flag + emitcode ("cpl", "a"); + emitcode ("inc", "a"); + emitcode ("", "%05d$:", lbl->key+100); + } + emitcode ("mul", "ab"); + + lbl=newiTempLabel(NULL); + emitcode ("jnb", "F0,%05d$", lbl->key+100); + // only ONE op was negative, we have to do a 8/16-bit two's complement + emitcode ("cpl", "a"); // lsb + if (size==1) { + emitcode ("inc", "a"); + } else { + emitcode ("add", "a,#1"); + emitcode ("xch", "a,b"); + emitcode ("cpl", "a"); // msb + emitcode ("addc", "a,#0"); + emitcode ("xch", "a,b"); + } + + emitcode ("", "%05d$:", lbl->key+100); + aopPut (AOP (result), "a", 0); + if (size==2) { + aopPut (AOP (result), "b", 1); + } } /*-----------------------------------------------------------------*/ @@ -3614,7 +3570,7 @@ genIfxJump (iCode * ic, char *jval) /*-----------------------------------------------------------------*/ static void genCmp (operand * left, operand * right, - operand * result, iCode * ifx, int sign) + operand * result, iCode * ifx, int sign, iCode *ic) { int size, offset = 0; unsigned long lit = 0L; @@ -3698,6 +3654,8 @@ genCmp (operand * left, operand * right, } release: + freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE)); + freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE)); if (AOP_TYPE (result) == AOP_CRY && AOP_SIZE (result)) { outBitC (result); @@ -3737,10 +3695,8 @@ genCmpGt (iCode * ic, iCode * ifx) aopOp (right, ic, FALSE); aopOp (result, ic, TRUE); - genCmp (right, left, result, ifx, sign); + genCmp (right, left, result, ifx, sign,ic); - freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE)); - freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE)); freeAsmop (result, NULL, ic, TRUE); } @@ -3767,10 +3723,8 @@ genCmpLt (iCode * ic, iCode * ifx) aopOp (right, ic, FALSE); aopOp (result, ic, TRUE); - genCmp (left, right, result, ifx, sign); + genCmp (left, right, result, ifx, sign,ic); - freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE)); - freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE)); freeAsmop (result, NULL, ic, TRUE); } @@ -4049,6 +4003,37 @@ ifxForOp (operand * op, iCode * ic) return NULL; } + +/*-----------------------------------------------------------------*/ +/* hasInc - operand is incremented before any other use */ +/*-----------------------------------------------------------------*/ +static iCode * +hasInc (operand *op, iCode *ic) +{ + sym_link *type = operandType(op); + sym_link *retype = getSpec (type); + iCode *lic = ic->next; + int isize ; + + if (IS_BITVAR(retype)||!IS_PTR(type)) return NULL; + isize = getSize(type->next); + while (lic) { + /* if operand of the form op = op + */ + if (lic->op == '+' && isOperandEqual(IC_LEFT(lic),op) && + isOperandEqual(IC_RESULT(lic),op) && + isOperandLiteral(IC_RIGHT(lic)) && + operandLitValue(IC_RIGHT(lic)) == isize) { + return lic; + } + /* if the operand used or deffed */ + if (bitVectBitValue(ic->uses,op->key) || (unsigned) ic->defKey == op->key) { + return NULL; + } + lic = lic->next; + } + return NULL; +} + /*-----------------------------------------------------------------*/ /* genAndOp - for && operation */ /*-----------------------------------------------------------------*/ @@ -5009,11 +4994,11 @@ release: static void genInline (iCode * ic) { - char buffer[MAX_INLINEASM]; - char *bp = buffer; - char *bp1 = buffer; + char *buffer, *bp, *bp1; _G.inLine += (!options.asmpeep); + + buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic)+1)); strcpy (buffer, IC_INLINE (ic)); /* emit each line as a code */ @@ -5436,18 +5421,25 @@ AccAXLsh (char *x, int shCount) break; case 6: // AAAAAABB:CCCCCCDD - emitcode ("anl", "a,#0x%02x", SRMask[shCount]); // 000000BB:CCCCCCDD - emitcode ("mov", "c,acc.0"); // c = B - emitcode ("xch", "a,%s", x); // CCCCCCDD:000000BB - +#if 0 // REMOVE ME AccAXRrl1 (x); // BCCCCCCD:D000000B - AccAXRrl1 (x); // BBCCCCCC:DD000000 - +#else + emitcode("rrc","a"); + emitcode("xch","a,%s", x); + emitcode("rrc","a"); + emitcode("mov","c,acc.0"); //<< get correct bit + emitcode("xch","a,%s", x); + + emitcode("rrc","a"); + emitcode("xch","a,%s", x); + emitcode("rrc","a"); + emitcode("xch","a,%s", x); +#endif break; case 7: // a:x <<= 7 @@ -5867,7 +5859,7 @@ genlshFour (operand * result, operand * left, int shCount) movLeft2Result (left, LSB, result, MSB32, 0); aopPut (AOP (result), zero, LSB); aopPut (AOP (result), zero, MSB16); - aopPut (AOP (result), zero, MSB32); + aopPut (AOP (result), zero, MSB24); return; } @@ -6683,7 +6675,8 @@ genDataPointerGet (operand * left, static void genNearPointerGet (operand * left, operand * result, - iCode * ic) + iCode * ic, + iCode * pi) { asmop *aop = NULL; regs *preg = NULL; @@ -6724,7 +6717,6 @@ genNearPointerGet (operand * left, else rname = aopGet (AOP (left), 0, FALSE, FALSE); - freeAsmop (left, NULL, ic, TRUE); aopOp (result, ic, FALSE); /* if bitfield then unpack the bits */ @@ -6750,15 +6742,17 @@ genNearPointerGet (operand * left, aopPut (AOP (result), buffer, offset); } offset++; - if (size) + if (size || pi) emitcode ("inc", "%s", rname); } } /* now some housekeeping stuff */ - if (aop) + if (aop) /* we had to allocate for this iCode */ { - /* we had to allocate for this iCode */ + if (pi) { /* post increment present */ + aopPut(AOP ( left ),rname,0); + } freeAsmop (NULL, aop, ic, TRUE); } else @@ -6768,10 +6762,11 @@ genNearPointerGet (operand * left, if size > 0 && this could be used again we have to point it back to where it belongs */ - if (AOP_SIZE (result) > 1 && - !OP_SYMBOL (left)->remat && - (OP_SYMBOL (left)->liveTo > ic->seq || - ic->depth)) + if ((AOP_SIZE (result) > 1 && + !OP_SYMBOL (left)->remat && + (OP_SYMBOL (left)->liveTo > ic->seq || + ic->depth)) && + !pi) { int size = AOP_SIZE (result) - 1; while (size--) @@ -6780,8 +6775,9 @@ genNearPointerGet (operand * left, } /* done */ + freeAsmop (left, NULL, ic, TRUE); freeAsmop (result, NULL, ic, TRUE); - + if (pi) pi->generated = 1; } /*-----------------------------------------------------------------*/ @@ -6790,7 +6786,8 @@ genNearPointerGet (operand * left, static void genPagedPointerGet (operand * left, operand * result, - iCode * ic) + iCode * ic, + iCode *pi) { asmop *aop = NULL; regs *preg = NULL; @@ -6817,7 +6814,6 @@ genPagedPointerGet (operand * left, else rname = aopGet (AOP (left), 0, FALSE, FALSE); - freeAsmop (left, NULL, ic, TRUE); aopOp (result, ic, FALSE); /* if bitfield then unpack the bits */ @@ -6837,15 +6833,15 @@ genPagedPointerGet (operand * left, offset++; - if (size) + if (size || pi) emitcode ("inc", "%s", rname); } } /* now some housekeeping stuff */ - if (aop) + if (aop) /* we had to allocate for this iCode */ { - /* we had to allocate for this iCode */ + if (pi) aopPut ( AOP (left), rname, 0); freeAsmop (NULL, aop, ic, TRUE); } else @@ -6855,10 +6851,11 @@ genPagedPointerGet (operand * left, if size > 0 && this could be used again we have to point it back to where it belongs */ - if (AOP_SIZE (result) > 1 && - !OP_SYMBOL (left)->remat && - (OP_SYMBOL (left)->liveTo > ic->seq || - ic->depth)) + if ((AOP_SIZE (result) > 1 && + !OP_SYMBOL (left)->remat && + (OP_SYMBOL (left)->liveTo > ic->seq || + ic->depth)) && + !pi) { int size = AOP_SIZE (result) - 1; while (size--) @@ -6867,8 +6864,9 @@ genPagedPointerGet (operand * left, } /* done */ + freeAsmop (left, NULL, ic, TRUE); freeAsmop (result, NULL, ic, TRUE); - + if (pi) pi->generated = 1; } @@ -6877,7 +6875,7 @@ genPagedPointerGet (operand * left, /*-----------------------------------------------------------------*/ static void genFarPointerGet (operand * left, - operand * result, iCode * ic) + operand * result, iCode * ic, iCode * pi) { int size, offset; sym_link *retype = getSpec (operandType (result)); @@ -6898,7 +6896,6 @@ genFarPointerGet (operand * left, } } /* so dptr know contains the address */ - freeAsmop (left, NULL, ic, TRUE); aopOp (result, ic, FALSE); /* if bit then unpack */ @@ -6913,20 +6910,26 @@ genFarPointerGet (operand * left, { emitcode ("movx", "a,@dptr"); aopPut (AOP (result), "a", offset++); - if (size) + if (size || pi) emitcode ("inc", "dptr"); } } - + + if (pi && AOP_TYPE (left) != AOP_IMMD && AOP_TYPE (left) != AOP_STR) { + aopPut ( AOP (left), "dpl", 0); + aopPut ( AOP (left), "dph", 1); + pi->generated = 1; + } + freeAsmop (left, NULL, ic, TRUE); freeAsmop (result, NULL, ic, TRUE); } /*-----------------------------------------------------------------*/ -/* emitcodePointerGet - gget value from code space */ +/* genCodePointerGet - gget value from code space */ /*-----------------------------------------------------------------*/ static void -emitcodePointerGet (operand * left, - operand * result, iCode * ic) +genCodePointerGet (operand * left, + operand * result, iCode * ic, iCode *pi) { int size, offset; sym_link *retype = getSpec (operandType (result)); @@ -6947,7 +6950,6 @@ emitcodePointerGet (operand * left, } } /* so dptr know contains the address */ - freeAsmop (left, NULL, ic, TRUE); aopOp (result, ic, FALSE); /* if bit then unpack */ @@ -6963,11 +6965,17 @@ emitcodePointerGet (operand * left, emitcode ("clr", "a"); emitcode ("movc", "a,@a+dptr"); aopPut (AOP (result), "a", offset++); - if (size) + if (size || pi) emitcode ("inc", "dptr"); } } + if (pi && AOP_TYPE (left) != AOP_IMMD && AOP_TYPE (left) != AOP_STR) { + aopPut ( AOP (left), "dpl", 0); + aopPut ( AOP (left), "dph", 1); + pi->generated = 1; + } + freeAsmop (left, NULL, ic, TRUE); freeAsmop (result, NULL, ic, TRUE); } @@ -6976,7 +6984,7 @@ emitcodePointerGet (operand * left, /*-----------------------------------------------------------------*/ static void genGenPointerGet (operand * left, - operand * result, iCode * ic) + operand * result, iCode * ic, iCode *pi) { int size, offset; sym_link *retype = getSpec (operandType (result)); @@ -7001,7 +7009,6 @@ genGenPointerGet (operand * left, } } /* so dptr know contains the address */ - freeAsmop (left, NULL, ic, TRUE); aopOp (result, ic, FALSE); /* if bit then unpack */ @@ -7016,11 +7023,17 @@ genGenPointerGet (operand * left, { emitcode ("lcall", "__gptrget"); aopPut (AOP (result), "a", offset++); - if (size) + if (size || pi) emitcode ("inc", "dptr"); } } + if (pi && AOP_TYPE (left) != AOP_IMMD && AOP_TYPE (left) != AOP_STR) { + aopPut ( AOP (left), "dpl", 0); + aopPut ( AOP (left), "dph", 1); + pi->generated = 1; + } + freeAsmop (left, NULL, ic, TRUE); freeAsmop (result, NULL, ic, TRUE); } @@ -7028,7 +7041,7 @@ genGenPointerGet (operand * left, /* genPointerGet - generate code for pointer get */ /*-----------------------------------------------------------------*/ static void -genPointerGet (iCode * ic) +genPointerGet (iCode * ic, iCode *pi) { operand *left, *result; sym_link *type, *etype; @@ -7048,21 +7061,6 @@ genPointerGet (iCode * ic) { /* we have to go by the storage class */ p_type = PTR_TYPE (SPEC_OCLS (etype)); - -/* if (SPEC_OCLS(etype)->codesp ) { */ -/* p_type = CPOINTER ; */ -/* } */ -/* else */ -/* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */ -/* p_type = FPOINTER ; */ -/* else */ -/* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */ -/* p_type = PPOINTER; */ -/* else */ -/* if (SPEC_OCLS(etype) == idata ) */ -/* p_type = IPOINTER; */ -/* else */ -/* p_type = POINTER ; */ } /* now that we have the pointer type we assign @@ -7072,23 +7070,23 @@ genPointerGet (iCode * ic) case POINTER: case IPOINTER: - genNearPointerGet (left, result, ic); + genNearPointerGet (left, result, ic, pi); break; case PPOINTER: - genPagedPointerGet (left, result, ic); + genPagedPointerGet (left, result, ic, pi); break; case FPOINTER: - genFarPointerGet (left, result, ic); + genFarPointerGet (left, result, ic, pi); break; case CPOINTER: - emitcodePointerGet (left, result, ic); + genCodePointerGet (left, result, ic, pi); break; case GPOINTER: - genGenPointerGet (left, result, ic); + genGenPointerGet (left, result, ic, pi); break; } @@ -7297,7 +7295,8 @@ genDataPointerSet (operand * right, static void genNearPointerSet (operand * right, operand * result, - iCode * ic) + iCode * ic, + iCode * pi) { asmop *aop = NULL; regs *preg = NULL; @@ -7335,7 +7334,6 @@ genNearPointerSet (operand * right, else rname = aopGet (AOP (result), 0, FALSE, FALSE); - freeAsmop (result, NULL, ic, TRUE); aopOp (right, ic, FALSE); /* if bitfield then unpack the bits */ @@ -7357,16 +7355,16 @@ genNearPointerSet (operand * right, } else emitcode ("mov", "@%s,%s", rname, l); - if (size) + if (size || pi) emitcode ("inc", "%s", rname); offset++; } } /* now some housekeeping stuff */ - if (aop) + if (aop) /* we had to allocate for this iCode */ { - /* we had to allocate for this iCode */ + if (pi) aopPut (AOP (result),rname,0); freeAsmop (NULL, aop, ic, TRUE); } else @@ -7376,10 +7374,11 @@ genNearPointerSet (operand * right, if size > 0 && this could be used again we have to point it back to where it belongs */ - if (AOP_SIZE (right) > 1 && - !OP_SYMBOL (result)->remat && - (OP_SYMBOL (result)->liveTo > ic->seq || - ic->depth)) + if ((AOP_SIZE (right) > 1 && + !OP_SYMBOL (result)->remat && + (OP_SYMBOL (result)->liveTo > ic->seq || + ic->depth)) && + !pi) { int size = AOP_SIZE (right) - 1; while (size--) @@ -7388,9 +7387,9 @@ genNearPointerSet (operand * right, } /* done */ + if (pi) pi->generated = 1; + freeAsmop (result, NULL, ic, TRUE); freeAsmop (right, NULL, ic, TRUE); - - } /*-----------------------------------------------------------------*/ @@ -7399,7 +7398,8 @@ genNearPointerSet (operand * right, static void genPagedPointerSet (operand * right, operand * result, - iCode * ic) + iCode * ic, + iCode * pi) { asmop *aop = NULL; regs *preg = NULL; @@ -7426,7 +7426,6 @@ genPagedPointerSet (operand * right, else rname = aopGet (AOP (result), 0, FALSE, FALSE); - freeAsmop (result, NULL, ic, TRUE); aopOp (right, ic, FALSE); /* if bitfield then unpack the bits */ @@ -7445,7 +7444,7 @@ genPagedPointerSet (operand * right, MOVA (l); emitcode ("movx", "@%s,a", rname); - if (size) + if (size || pi) emitcode ("inc", "%s", rname); offset++; @@ -7453,9 +7452,9 @@ genPagedPointerSet (operand * right, } /* now some housekeeping stuff */ - if (aop) + if (aop) /* we had to allocate for this iCode */ { - /* we had to allocate for this iCode */ + if (pi) aopPut (AOP (result),rname,0); freeAsmop (NULL, aop, ic, TRUE); } else @@ -7477,6 +7476,8 @@ genPagedPointerSet (operand * right, } /* done */ + if (pi) pi->generated = 1; + freeAsmop (result, NULL, ic, TRUE); freeAsmop (right, NULL, ic, TRUE); @@ -7487,7 +7488,7 @@ genPagedPointerSet (operand * right, /*-----------------------------------------------------------------*/ static void genFarPointerSet (operand * right, - operand * result, iCode * ic) + operand * result, iCode * ic, iCode * pi) { int size, offset; sym_link *retype = getSpec (operandType (right)); @@ -7508,7 +7509,6 @@ genFarPointerSet (operand * right, } } /* so dptr know contains the address */ - freeAsmop (result, NULL, ic, TRUE); aopOp (right, ic, FALSE); /* if bit then unpack */ @@ -7524,11 +7524,16 @@ genFarPointerSet (operand * right, char *l = aopGet (AOP (right), offset++, FALSE, FALSE); MOVA (l); emitcode ("movx", "@dptr,a"); - if (size) + if (size || pi) emitcode ("inc", "dptr"); } } - + if (pi && AOP_TYPE (result) != AOP_STR && AOP_TYPE (result) != AOP_IMMD) { + aopPut (AOP(result),"dpl",0); + aopPut (AOP(result),"dph",1); + pi->generated=1; + } + freeAsmop (result, NULL, ic, TRUE); freeAsmop (right, NULL, ic, TRUE); } @@ -7537,7 +7542,7 @@ genFarPointerSet (operand * right, /*-----------------------------------------------------------------*/ static void genGenPointerSet (operand * right, - operand * result, iCode * ic) + operand * result, iCode * ic, iCode * pi) { int size, offset; sym_link *retype = getSpec (operandType (right)); @@ -7563,7 +7568,6 @@ genGenPointerSet (operand * right, } } /* so dptr know contains the address */ - freeAsmop (result, NULL, ic, TRUE); aopOp (right, ic, FALSE); /* if bit then unpack */ @@ -7579,11 +7583,17 @@ genGenPointerSet (operand * right, char *l = aopGet (AOP (right), offset++, FALSE, FALSE); MOVA (l); emitcode ("lcall", "__gptrput"); - if (size) + if (size || pi) emitcode ("inc", "dptr"); } } + if (pi && AOP_TYPE (result) != AOP_STR && AOP_TYPE (result) != AOP_IMMD) { + aopPut (AOP(result),"dpl",0); + aopPut (AOP(result),"dph",1); + pi->generated=1; + } + freeAsmop (result, NULL, ic, TRUE); freeAsmop (right, NULL, ic, TRUE); } @@ -7591,7 +7601,7 @@ genGenPointerSet (operand * right, /* genPointerSet - stores the value into a pointer location */ /*-----------------------------------------------------------------*/ static void -genPointerSet (iCode * ic) +genPointerSet (iCode * ic, iCode *pi) { operand *right, *result; sym_link *type, *etype; @@ -7622,19 +7632,19 @@ genPointerSet (iCode * ic) case POINTER: case IPOINTER: - genNearPointerSet (right, result, ic); + genNearPointerSet (right, result, ic, pi); break; case PPOINTER: - genPagedPointerSet (right, result, ic); + genPagedPointerSet (right, result, ic, pi); break; case FPOINTER: - genFarPointerSet (right, result, ic); + genFarPointerSet (right, result, ic, pi); break; case GPOINTER: - genGenPointerSet (right, result, ic); + genGenPointerSet (right, result, ic, pi); break; } @@ -7787,8 +7797,7 @@ genAssign (iCode * ic) aopOp (right, ic, FALSE); /* special case both in far space */ - if ((AOP_TYPE (right) == AOP_DPTR || - AOP_TYPE (right) == AOP_DPTR2) && + if (AOP_TYPE (right) == AOP_DPTR && IS_TRUE_SYMOP (result) && isOperandInFarSpace (result)) { @@ -8117,7 +8126,30 @@ genDjnz (iCode * ic, iCode * ifx) aopOp (IC_RESULT (ic), ic, FALSE); - if (IS_AOP_PREG (IC_RESULT (ic))) + if (AOP_NEEDSACC(IC_RESULT(ic))) + { + /* If the result is accessed indirectly via + * the accumulator, we must explicitly write + * it back after the decrement. + */ + char *rByte = aopGet(AOP(IC_RESULT(ic)), 0, FALSE, FALSE); + + if (strcmp(rByte, "a")) + { + /* Something is hopelessly wrong */ + fprintf(stderr, "*** warning: internal error at %s:%d\n", + __FILE__, __LINE__); + /* We can just give up; the generated code will be inefficient, + * but what the hey. + */ + freeAsmop (IC_RESULT (ic), NULL, ic, TRUE); + return 0; + } + emitcode ("dec", "%s", rByte); + aopPut(AOP(IC_RESULT(ic)), rByte, 0); + emitcode ("jnz", "%05d$", lbl->key + 100); + } + else if (IS_AOP_PREG (IC_RESULT (ic))) { emitcode ("dec", "%s", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE)); @@ -8385,12 +8417,12 @@ gen51Code (iCode * lic) break; case GET_VALUE_AT_ADDRESS: - genPointerGet (ic); + genPointerGet (ic, hasInc(IC_LEFT(ic),ic)); break; case '=': if (POINTER_SET (ic)) - genPointerSet (ic); + genPointerSet (ic, hasInc (IC_RESULT(ic),ic)); else genAssign (ic); break; @@ -8421,8 +8453,6 @@ gen51Code (iCode * lic) default: ic = ic; - /* piCode(ic,stdout); */ - } }