X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fds390%2Fgen.c;h=ea5009fb7f9b5e6e429095826c17453cba3bc385;hb=ecb743f95f51372295752e39b08c9ae407c2af4c;hp=9d27211c2a728064c7ef45bfe326a802140c5ef7;hpb=7e064932af97f6cba3fa669b90b296f1ced6fe30;p=fw%2Fsdcc diff --git a/src/ds390/gen.c b/src/ds390/gen.c index 9d27211c..ea5009fb 100644 --- a/src/ds390/gen.c +++ b/src/ds390/gen.c @@ -4,6 +4,7 @@ Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998) and - Jean-Louis VERN.jlvern@writeme.com (1999) Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a) + DS390 adaptation by Kevin Vigor This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -38,6 +39,9 @@ #ifdef HAVE_SYS_ISA_DEFS_H #include #else +#ifdef HAVE_MACHINE_ENDIAN_H +#include +#else #ifdef HAVE_ENDIAN_H #include #else @@ -47,6 +51,7 @@ #endif #endif #endif +#endif #define BETTER_LITERAL_SHIFT @@ -465,7 +470,7 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool useDP2) { if (options.model == MODEL_FLAT24) emitcode ("mov", "dpx1,#0x40"); - TR_DPTR("#2"); + TR_DPTR("#2"); emitcode ("mov", "dph1,#0x00"); emitcode ("mov", "dpl1, a"); } @@ -506,8 +511,8 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool useDP2) 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; } @@ -543,7 +548,7 @@ aopForRemat (symbol * sym) { iCode *ic = sym->rematiCode; asmop *aop = newAsmop (AOP_IMMD); - + int ptr_type =0; int val = 0; for (;;) @@ -552,9 +557,14 @@ 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); + continue ; + } else break; + ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode; } @@ -566,8 +576,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; } @@ -983,8 +1000,8 @@ aopGet (asmop * aop, genSetDPTR (1); if (!canClobberACC) { - TR_AP("#1"); - emitcode ("xch", "a, %s", DP2_RESULT_REG); + TR_AP("#1"); + emitcode ("xch", "a, %s", DP2_RESULT_REG); } } @@ -1026,15 +1043,17 @@ aopGet (asmop * aop, return (dname ? "acc" : "a"); 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; @@ -1225,7 +1244,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; @@ -1770,8 +1794,8 @@ saveRegisters (iCode * lic) /* if the registers have been saved already 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 @@ -2182,7 +2206,7 @@ saveRBank (int bank, iCode * ic, bool pushPsw) static void genCall (iCode * ic) { - sym_link *detype; + sym_link *dtype; bool restoreBank = FALSE; bool swapBanks = FALSE; @@ -2191,17 +2215,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 (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; @@ -2269,7 +2293,7 @@ genCall (iCode * ic) if (swapBanks) { emitcode ("mov", "psw,#0x%02x", - ((SPEC_BANK(detype)) << 3) & 0xff); + ((FUNC_REGBANK(dtype)) << 3) & 0xff); } /* make the call */ @@ -2280,7 +2304,7 @@ 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 */ @@ -2339,12 +2363,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); } /*-----------------------------------------------------------------*/ @@ -2353,8 +2377,9 @@ genCall (iCode * ic) static void genPcall (iCode * ic) { - sym_link *detype; + sym_link *dtype; symbol *rlbl = newiTempLabel (NULL); + bool restoreBank=FALSE; D (emitcode (";", "genPcall "); ); @@ -2367,12 +2392,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 (dtype && !IFFUNC_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)); @@ -2462,14 +2488,12 @@ 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); } @@ -2527,7 +2551,7 @@ static void genFunction (iCode * ic) { symbol *sym; - sym_link *fetype; + sym_link *ftype; bool switchedPSW = FALSE; D (emitcode (";", "genFunction ");); @@ -2539,25 +2563,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 < ds390_nRegs; i++) { if (strcmp (regs390[i].base, "0") == 0) @@ -2574,7 +2598,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")) @@ -2603,13 +2627,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; @@ -2646,7 +2670,7 @@ genFunction (iCode * ic) */ unsigned long banksToSave = 0; - if (sym->hasFcall) + if (IFFUNC_HASFCALL(sym->type)) { #define MAX_REGISTER_BANKS 4 @@ -2664,20 +2688,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 @@ -2709,7 +2733,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; } @@ -2721,6 +2745,7 @@ genFunction (iCode * ic) } } } + // jwk: this needs a closer look SPEC_ISR_SAVED_BANKS(currFunc->etype) = banksToSave; } } @@ -2728,7 +2753,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; @@ -2750,14 +2775,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) || FUNC_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) @@ -2816,13 +2841,13 @@ genEndFunction (iCode * ic) D (emitcode (";", "genEndFunction ");); - 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); } @@ -2838,7 +2863,7 @@ genEndFunction (iCode * ic) } - if ((IS_RENT (sym->etype) || options.stackAuto)) + if ((IFFUNC_ISREENT (sym->type) || options.stackAuto)) { if (options.useXstack) { @@ -2854,9 +2879,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 @@ -2866,19 +2891,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; @@ -2910,6 +2935,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; @@ -2951,7 +2977,7 @@ 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 */ @@ -2971,10 +2997,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; @@ -3352,6 +3378,8 @@ adjustArithmeticResult (iCode * ic) } } +#if 0 // AOP_OP_3 is deprecated; nobody likes Ack errors. + // Please don't bring it back without a really good reason. // Macro to aopOp all three operands of an ic. Will fatal if this cannot be done // (because all three operands are in far space). #define AOP_OP_3(ic) \ @@ -3366,6 +3394,7 @@ adjustArithmeticResult (iCode * ic) fprintf(stderr, \ "Ack: three operands in far space! (%s:%d %s:%d)\n", __FILE__, __LINE__, ic->filename, ic->lineno); \ } +#endif // Macro to aopOp all three operands of an ic. If this cannot be done, // the IC_LEFT and IC_RIGHT operands will be aopOp'd, and the rc parameter @@ -3913,10 +3942,12 @@ release: static void genMultbits (operand * left, operand * right, - operand * result) + operand * result, + iCode * ic) { emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir); emitcode ("anl", "c,%s", AOP (right)->aopu.aop_dir); + aopOp(result, ic, TRUE, FALSE); outBitC (result); } @@ -3927,18 +3958,12 @@ genMultbits (operand * left, static void genMultOneByte (operand * left, operand * right, - operand * result) + operand * result, + iCode * ic) { sym_link *opetype = operandType (result); symbol *lbl; - int size=AOP_SIZE(result); - 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 one literal, literal on the right */ @@ -3959,8 +3984,22 @@ genMultOneByte (operand * left, emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE, TRUE)); MOVA (aopGet (AOP (left), 0, FALSE, FALSE, TRUE)); emitcode ("mul", "ab"); + + _G.accInUse++; + aopOp(result, ic, TRUE, FALSE); + + if (AOP_SIZE(result)<1 || AOP_SIZE(result)>2) + { + // this should never happen + fprintf (stderr, "size!=1||2 (%d) in %s at line:%d \n", + AOP_SIZE(result), __FILE__, lineno); + exit (1); + } + aopPut (AOP (result), "a", 0); - if (size==2) { + _G.accInUse--; + if (AOP_SIZE(result)==2) + { aopPut (AOP (result), "b", 1); } return; @@ -4004,11 +4043,22 @@ genMultOneByte (operand * left, } emitcode ("mul", "ab"); + _G.accInUse++; + aopOp(result, ic, TRUE, FALSE); + + if (AOP_SIZE(result)<1 || AOP_SIZE(result)>2) + { + // this should never happen + fprintf (stderr, "size!=1||2 (%d) in %s at line:%d \n", + AOP_SIZE(result), __FILE__, lineno); + exit (1); + } + 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) { + if (AOP_SIZE(result)==1) { emitcode ("inc", "a"); } else { emitcode ("add", "a,#1"); @@ -4020,11 +4070,172 @@ genMultOneByte (operand * left, emitcode ("", "%05d$:", lbl->key+100); aopPut (AOP (result), "a", 0); - if (size==2) { + _G.accInUse--; + if (AOP_SIZE(result)==2) { aopPut (AOP (result), "b", 1); } } +/*-----------------------------------------------------------------*/ +/* genMultTwoByte - use the DS390 MAC unit to do 16*16 multiply */ +/*-----------------------------------------------------------------*/ +static void genMultTwoByte (operand *left, operand *right, + operand *result, iCode *ic) +{ + sym_link *retype = getSpec(operandType(right)); + sym_link *letype = getSpec(operandType(left)); + int umult = SPEC_USIGN(retype) | SPEC_USIGN(letype); + symbol *lbl; + + if (AOP_TYPE (left) == AOP_LIT) { + operand *t = right; + right = left; + left = t; + } + /* save EA bit in F1 */ + lbl = newiTempLabel(NULL); + emitcode ("setb","F1"); + emitcode ("jbc","EA,%05d$",lbl->key+100); + emitcode ("clr","F1"); + emitcode("","%05d$:",lbl->key+100); + + /* load up MB with right */ + if (!umult) { + emitcode("clr","F0"); + if (AOP_TYPE(right) == AOP_LIT) { + int val=floatFromVal (AOP (right)->aopu.aop_lit); + if (val < 0) { + emitcode("setb","F0"); + val = -val; + } + emitcode ("mov","mb,#0x%02x",val & 0xff); + emitcode ("mov","mb,#0x%02x",(val >> 8) & 0xff); + } else { + lbl = newiTempLabel(NULL); + emitcode ("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE,TRUE)); + emitcode ("mov","a,%s",aopGet(AOP(right),1,FALSE,FALSE,TRUE)); + emitcode ("jnb","acc.7,%05d$",lbl->key+100); + emitcode ("xch", "a,b"); + emitcode ("cpl","a"); + emitcode ("add", "a,#1"); + emitcode ("xch", "a,b"); + emitcode ("cpl", "a"); // msb + emitcode ("addc", "a,#0"); + emitcode ("setb","F0"); + emitcode ("","%05d$:",lbl->key+100); + emitcode ("mov","mb,b"); + emitcode ("mov","mb,a"); + } + } else { + emitcode ("mov","mb,%s",aopGet(AOP(right),0,FALSE,FALSE,TRUE)); + emitcode ("mov","mb,%s",aopGet(AOP(right),1,FALSE,FALSE,TRUE)); + } + /* load up MA with left */ + if (!umult) { + lbl = newiTempLabel(NULL); + emitcode ("mov","b,%s",aopGet(AOP(left),0,FALSE,FALSE,TRUE)); + emitcode ("mov","a,%s",aopGet(AOP(left),1,FALSE,FALSE,TRUE)); + emitcode ("jnb","acc.7,%05d$",lbl->key+100); + emitcode ("xch", "a,b"); + emitcode ("cpl","a"); + emitcode ("add", "a,#1"); + emitcode ("xch", "a,b"); + emitcode ("cpl", "a"); // msb + emitcode ("addc","a,#0"); + emitcode ("jbc","F0,%05d$",lbl->key+100); + emitcode ("setb","F0"); + emitcode ("","%05d$:",lbl->key+100); + emitcode ("mov","ma,b"); + emitcode ("mov","ma,a"); + } else { + emitcode ("mov","ma,%s",aopGet(AOP(left),0,FALSE,FALSE,TRUE)); + emitcode ("mov","ma,%s",aopGet(AOP(left),1,FALSE,FALSE,TRUE)); + } + /* wait for multiplication to finish */ + lbl = newiTempLabel(NULL); + emitcode("","%05d$:", lbl->key+100); + emitcode("mov","a,mcnt1"); + emitcode("anl","a,#0x80"); + emitcode("jnz","%05d$",lbl->key+100); + + freeAsmop (left, NULL, ic, TRUE); + freeAsmop (right, NULL, ic,TRUE); + aopOp(result, ic, TRUE, FALSE); + + /* if unsigned then simple */ + if (umult) { + emitcode ("mov","a,ma"); + if (AOP_SIZE(result) >= 4) aopPut(AOP(result),"a",3); + emitcode ("mov","a,ma"); + if (AOP_SIZE(result) >= 3) aopPut(AOP(result),"a",2); + aopPut(AOP(result),"ma",1); + aopPut(AOP(result),"ma",0); + } else { + emitcode("push","ma"); + emitcode("push","ma"); + emitcode("push","ma"); + MOVA("ma"); + /* negate result if needed */ + lbl = newiTempLabel(NULL); + emitcode("jnb","F0,%05d$",lbl->key+100); + emitcode("cpl","a"); + emitcode("add","a,#1"); + emitcode("","%05d$:", lbl->key+100); + if (AOP_TYPE(result) == AOP_ACC) + { + D(emitcode(";", "ACC special case.");); + /* We know result is the only live aop, and + * it's obviously not a DPTR2, so AP is available. + */ + emitcode("mov", "%s,acc", DP2_RESULT_REG); + } + else + { + aopPut(AOP(result),"a",0); + } + + emitcode("pop","acc"); + lbl = newiTempLabel(NULL); + emitcode("jnb","F0,%05d$",lbl->key+100); + emitcode("cpl","a"); + emitcode("addc","a,#0"); + emitcode("","%05d$:", lbl->key+100); + aopPut(AOP(result),"a",1); + emitcode("pop","acc"); + if (AOP_SIZE(result) >= 3) { + lbl = newiTempLabel(NULL); + emitcode("jnb","F0,%05d$",lbl->key+100); + emitcode("cpl","a"); + emitcode("addc","a,#0"); + emitcode("","%05d$:", lbl->key+100); + aopPut(AOP(result),"a",2); + } + emitcode("pop","acc"); + if (AOP_SIZE(result) >= 4) { + lbl = newiTempLabel(NULL); + emitcode("jnb","F0,%05d$",lbl->key+100); + emitcode("cpl","a"); + emitcode("addc","a,#0"); + emitcode("","%05d$:", lbl->key+100); + aopPut(AOP(result),"a",3); + } + if (AOP_TYPE(result) == AOP_ACC) + { + /* We stashed the result away above. */ + emitcode("mov", "acc,%s", DP2_RESULT_REG); + } + + } + freeAsmop (result, NULL, ic, TRUE); + + /* restore EA bit in F1 */ + lbl = newiTempLabel(NULL); + emitcode ("jnb","F1,%05d$",lbl->key+100); + emitcode ("setb","EA"); + emitcode("","%05d$:",lbl->key+100); + return ; +} + /*-----------------------------------------------------------------*/ /* genMult - generates code for multiplication */ /*-----------------------------------------------------------------*/ @@ -4038,14 +4249,14 @@ genMult (iCode * ic) D (emitcode (";", "genMult ");); /* assign the amsops */ - AOP_OP_3 (ic); + AOP_OP_2 (ic); /* special cases first */ /* both are bits */ if (AOP_TYPE (left) == AOP_CRY && AOP_TYPE (right) == AOP_CRY) { - genMultbits (left, right, result); + genMultbits (left, right, result, ic); goto release; } @@ -4053,12 +4264,17 @@ genMult (iCode * ic) if (AOP_SIZE (left) == 1 && AOP_SIZE (right) == 1) { - genMultOneByte (left, right, result); + genMultOneByte (left, right, result, ic); goto release; } + if (AOP_SIZE (left) == 2 && AOP_SIZE(right) == 2) { + /* use the ds390 ARITHMETIC accel UNIT */ + genMultTwoByte (left, right, result, ic); + return ; + } /* should have been converted to function call */ - assert (1); + assert (0); release: freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE)); @@ -4072,7 +4288,8 @@ release: static void genDivbits (operand * left, operand * right, - operand * result) + operand * result, + iCode * ic) { char *l; @@ -4081,6 +4298,8 @@ genDivbits (operand * left, LOAD_AB_FOR_DIV (left, right, l); emitcode ("div", "ab"); emitcode ("rrc", "a"); + aopOp(result, ic, TRUE, FALSE); + aopPut (AOP (result), "c", 0); } @@ -4090,24 +4309,33 @@ genDivbits (operand * left, static void genDivOneByte (operand * left, operand * right, - operand * result) + operand * result, + iCode * ic) { sym_link *opetype = operandType (result); char *l; symbol *lbl; int size, offset; - size = AOP_SIZE (result) - 1; offset = 1; /* signed or unsigned */ if (SPEC_USIGN (opetype)) { - /* unsigned is easy */ - LOAD_AB_FOR_DIV (left, right, l); - emitcode ("div", "ab"); - aopPut (AOP (result), "a", 0); - while (size--) - aopPut (AOP (result), zero, offset++); + /* unsigned is easy */ + LOAD_AB_FOR_DIV (left, right, l); + emitcode ("div", "ab"); + + _G.accInUse++; + aopOp(result, ic, TRUE, FALSE); + aopPut (AOP (result), "a", 0); + _G.accInUse--; + + size = AOP_SIZE (result) - 1; + + while (size--) + { + aopPut (AOP (result), zero, offset++); + } return; } @@ -4158,15 +4386,141 @@ genDivOneByte (operand * left, emitcode ("", "%05d$:", (lbl->key + 100)); /* now we are done */ - aopPut (AOP (result), "b", 0); - if (size > 0) + _G.accInUse++; + aopOp(result, ic, TRUE, FALSE); + + aopPut (AOP (result), "b", 0); + + size = AOP_SIZE (result) - 1; + + if (size > 0) { emitcode ("mov", "c,b.7"); emitcode ("subb", "a,acc"); } - while (size--) - aopPut (AOP (result), "a", offset++); + while (size--) + { + aopPut (AOP (result), "a", offset++); + } + _G.accInUse--; + +} + +/*-----------------------------------------------------------------*/ +/* genDivTwoByte - use the DS390 MAC unit to do 16/16 divide */ +/*-----------------------------------------------------------------*/ +static void genDivTwoByte (operand *left, operand *right, + operand *result, iCode *ic) +{ + sym_link *retype = getSpec(operandType(right)); + sym_link *letype = getSpec(operandType(left)); + int umult = SPEC_USIGN(retype) | SPEC_USIGN(letype); + symbol *lbl; + + /* save EA bit in F1 */ + lbl = newiTempLabel(NULL); + emitcode ("setb","F1"); + emitcode ("jbc","EA,%05d$",lbl->key+100); + emitcode ("clr","F1"); + emitcode("","%05d$:",lbl->key+100); + + /* load up MA with left */ + if (!umult) { + emitcode("clr","F0"); + lbl = newiTempLabel(NULL); + emitcode ("mov","b,%s",aopGet(AOP(left),0,FALSE,FALSE,TRUE)); + emitcode ("mov","a,%s",aopGet(AOP(left),1,FALSE,FALSE,TRUE)); + emitcode ("jnb","acc.7,%05d$",lbl->key+100); + emitcode ("xch", "a,b"); + emitcode ("cpl","a"); + emitcode ("add", "a,#1"); + emitcode ("xch", "a,b"); + emitcode ("cpl", "a"); // msb + emitcode ("addc","a,#0"); + emitcode ("setb","F0"); + emitcode ("","%05d$:",lbl->key+100); + emitcode ("mov","ma,b"); + emitcode ("mov","ma,a"); + } else { + emitcode ("mov","ma,%s",aopGet(AOP(left),0,FALSE,FALSE,TRUE)); + emitcode ("mov","ma,%s",aopGet(AOP(left),1,FALSE,FALSE,TRUE)); + } + + /* load up MB with right */ + if (!umult) { + if (AOP_TYPE(right) == AOP_LIT) { + int val=floatFromVal (AOP (right)->aopu.aop_lit); + if (val < 0) { + lbl = newiTempLabel(NULL); + emitcode ("jbc","F0,%05d$",lbl->key+100); + emitcode("setb","F0"); + emitcode ("","%05d$:",lbl->key+100); + val = -val; + } + emitcode ("mov","mb,#0x%02x",val & 0xff); + emitcode ("mov","mb,#0x%02x",(val >> 8) & 0xff); + } else { + lbl = newiTempLabel(NULL); + emitcode ("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE,TRUE)); + emitcode ("mov","a,%s",aopGet(AOP(right),1,FALSE,FALSE,TRUE)); + emitcode ("jnb","acc.7,%05d$",lbl->key+100); + emitcode ("xch", "a,b"); + emitcode ("cpl","a"); + emitcode ("add", "a,#1"); + emitcode ("xch", "a,b"); + emitcode ("cpl", "a"); // msb + emitcode ("addc", "a,#0"); + emitcode ("jbc","F0,%05d$",lbl->key+100); + emitcode ("setb","F0"); + emitcode ("","%05d$:",lbl->key+100); + emitcode ("mov","mb,b"); + emitcode ("mov","mb,a"); + } + } else { + emitcode ("mov","mb,%s",aopGet(AOP(right),0,FALSE,FALSE,TRUE)); + emitcode ("mov","mb,%s",aopGet(AOP(right),1,FALSE,FALSE,TRUE)); + } + /* wait for multiplication to finish */ + lbl = newiTempLabel(NULL); + emitcode("","%05d$:", lbl->key+100); + emitcode("mov","a,mcnt1"); + emitcode("anl","a,#0x80"); + emitcode("jnz","%05d$",lbl->key+100); + + freeAsmop (left, NULL, ic, TRUE); + freeAsmop (right, NULL, ic,TRUE); + aopOp(result, ic, TRUE, FALSE); + + /* if unsigned then simple */ + if (umult) { + aopPut(AOP(result),"ma",1); + aopPut(AOP(result),"ma",0); + } else { + emitcode("push","ma"); + MOVA("ma"); + /* negate result if needed */ + lbl = newiTempLabel(NULL); + emitcode("jnb","F0,%05d$",lbl->key+100); + emitcode("cpl","a"); + emitcode("add","a,#1"); + emitcode("","%05d$:", lbl->key+100); + aopPut(AOP(result),"a",0); + emitcode("pop","acc"); + lbl = newiTempLabel(NULL); + emitcode("jnb","F0,%05d$",lbl->key+100); + emitcode("cpl","a"); + emitcode("addc","a,#0"); + emitcode("","%05d$:", lbl->key+100); + aopPut(AOP(result),"a",1); + } + freeAsmop (result, NULL, ic, TRUE); + /* restore EA bit in F1 */ + lbl = newiTempLabel(NULL); + emitcode ("jnb","F1,%05d$",lbl->key+100); + emitcode ("setb","EA"); + emitcode("","%05d$:",lbl->key+100); + return ; } /*-----------------------------------------------------------------*/ @@ -4179,18 +4533,17 @@ genDiv (iCode * ic) operand *right = IC_RIGHT (ic); operand *result = IC_RESULT (ic); - D (emitcode (";", "genDiv "); - ); + D (emitcode (";", "genDiv ");); /* assign the amsops */ - AOP_OP_3 (ic); + AOP_OP_2 (ic); /* special cases first */ /* both are bits */ if (AOP_TYPE (left) == AOP_CRY && AOP_TYPE (right) == AOP_CRY) { - genDivbits (left, right, result); + genDivbits (left, right, result, ic); goto release; } @@ -4198,12 +4551,17 @@ genDiv (iCode * ic) if (AOP_SIZE (left) == 1 && AOP_SIZE (right) == 1) { - genDivOneByte (left, right, result); + genDivOneByte (left, right, result, ic); goto release; } + if (AOP_SIZE (left) == 2 && AOP_SIZE(right) == 2) { + /* use the ds390 ARITHMETIC accel UNIT */ + genDivTwoByte (left, right, result, ic); + return ; + } /* 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)); @@ -4216,7 +4574,8 @@ release: static void genModbits (operand * left, operand * right, - operand * result) + operand * result, + iCode * ic) { char *l; @@ -4226,6 +4585,7 @@ genModbits (operand * left, emitcode ("div", "ab"); emitcode ("mov", "a,b"); emitcode ("rrc", "a"); + aopOp(result, ic, TRUE, FALSE); aopPut (AOP (result), "c", 0); } @@ -4235,7 +4595,8 @@ genModbits (operand * left, static void genModOneByte (operand * left, operand * right, - operand * result) + operand * result, + iCode * ic) { sym_link *opetype = operandType (result); char *l; @@ -4247,6 +4608,7 @@ genModOneByte (operand * left, /* unsigned is easy */ LOAD_AB_FOR_DIV (left, right, l); emitcode ("div", "ab"); + aopOp(result, ic, TRUE, FALSE); aopPut (AOP (result), "b", 0); return; } @@ -4299,10 +4661,101 @@ genModOneByte (operand * left, emitcode ("", "%05d$:", (lbl->key + 100)); /* now we are done */ + aopOp(result, ic, TRUE, FALSE); aopPut (AOP (result), "b", 0); } +/*-----------------------------------------------------------------*/ +/* genModTwoByte - use the DS390 MAC unit to do 16%16 modulus */ +/*-----------------------------------------------------------------*/ +static void genModTwoByte (operand *left, operand *right, + operand *result, iCode *ic) +{ + sym_link *retype = getSpec(operandType(right)); + sym_link *letype = getSpec(operandType(left)); + int umult = SPEC_USIGN(retype) | SPEC_USIGN(letype); + symbol *lbl; + + /* load up MA with left */ + /* save EA bit in F1 */ + lbl = newiTempLabel(NULL); + emitcode ("setb","F1"); + emitcode ("jbc","EA,%05d$",lbl->key+100); + emitcode ("clr","F1"); + emitcode("","%05d$:",lbl->key+100); + + if (!umult) { + lbl = newiTempLabel(NULL); + emitcode ("mov","b,%s",aopGet(AOP(left),0,FALSE,FALSE,TRUE)); + emitcode ("mov","a,%s",aopGet(AOP(left),1,FALSE,FALSE,TRUE)); + emitcode ("jnb","acc.7,%05d$",lbl->key+100); + emitcode ("xch", "a,b"); + emitcode ("cpl","a"); + emitcode ("add", "a,#1"); + emitcode ("xch", "a,b"); + emitcode ("cpl", "a"); // msb + emitcode ("addc","a,#0"); + emitcode ("","%05d$:",lbl->key+100); + emitcode ("mov","ma,b"); + emitcode ("mov","ma,a"); + } else { + emitcode ("mov","ma,%s",aopGet(AOP(left),0,FALSE,FALSE,TRUE)); + emitcode ("mov","ma,%s",aopGet(AOP(left),1,FALSE,FALSE,TRUE)); + } + + /* load up MB with right */ + if (!umult) { + if (AOP_TYPE(right) == AOP_LIT) { + int val=floatFromVal (AOP (right)->aopu.aop_lit); + if (val < 0) { + val = -val; + } + emitcode ("mov","mb,#0x%02x",val & 0xff); + emitcode ("mov","mb,#0x%02x",(val >> 8) & 0xff); + } else { + lbl = newiTempLabel(NULL); + emitcode ("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE,TRUE)); + emitcode ("mov","a,%s",aopGet(AOP(right),1,FALSE,FALSE,TRUE)); + emitcode ("jnb","acc.7,%05d$",lbl->key+100); + emitcode ("xch", "a,b"); + emitcode ("cpl","a"); + emitcode ("add", "a,#1"); + emitcode ("xch", "a,b"); + emitcode ("cpl", "a"); // msb + emitcode ("addc", "a,#0"); + emitcode ("","%05d$:",lbl->key+100); + emitcode ("mov","mb,b"); + emitcode ("mov","mb,a"); + } + } else { + emitcode ("mov","mb,%s",aopGet(AOP(right),0,FALSE,FALSE,TRUE)); + emitcode ("mov","mb,%s",aopGet(AOP(right),1,FALSE,FALSE,TRUE)); + } + + /* wait for multiplication to finish */ + lbl = newiTempLabel(NULL); + emitcode("","%05d$:", lbl->key+100); + emitcode("mov","a,mcnt1"); + emitcode("anl","a,#0x80"); + emitcode("jnz","%05d$",lbl->key+100); + + freeAsmop (left, NULL, ic, TRUE); + freeAsmop (right, NULL, ic,TRUE); + aopOp(result, ic, TRUE, FALSE); + + aopPut(AOP(result),"mb",1); + aopPut(AOP(result),"mb",0); + freeAsmop (result, NULL, ic, TRUE); + + /* restore EA bit in F1 */ + lbl = newiTempLabel(NULL); + emitcode ("jnb","F1,%05d$",lbl->key+100); + emitcode ("setb","EA"); + emitcode("","%05d$:",lbl->key+100); + return ; +} + /*-----------------------------------------------------------------*/ /* genMod - generates code for division */ /*-----------------------------------------------------------------*/ @@ -4313,18 +4766,17 @@ genMod (iCode * ic) operand *right = IC_RIGHT (ic); operand *result = IC_RESULT (ic); - D (emitcode (";", "genMod "); - ); + D (emitcode (";", "genMod "); ); /* assign the amsops */ - AOP_OP_3 (ic); + AOP_OP_2 (ic); /* special cases first */ /* both are bits */ if (AOP_TYPE (left) == AOP_CRY && AOP_TYPE (right) == AOP_CRY) { - genModbits (left, right, result); + genModbits (left, right, result, ic); goto release; } @@ -4332,12 +4784,18 @@ genMod (iCode * ic) if (AOP_SIZE (left) == 1 && AOP_SIZE (right) == 1) { - genModOneByte (left, right, result); + genModOneByte (left, right, result, ic); goto release; } + if (AOP_SIZE (left) == 2 && AOP_SIZE(right) == 2) { + /* use the ds390 ARITHMETIC accel UNIT */ + genModTwoByte (left, right, result, ic); + return ; + } + /* should have been converted to function call */ - assert (1); + assert (0); release: freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE)); @@ -4915,6 +5373,39 @@ 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 ; + + /* 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) { + /* 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(OP_USES(op),lic->key) || (unsigned) lic->defKey == op->key) { + return NULL; + } + lic = lic->next; + } + return NULL; +} + /*-----------------------------------------------------------------*/ /* genAndOp - for && operation */ /*-----------------------------------------------------------------*/ @@ -5157,8 +5648,11 @@ genAnd (iCode * ic, iCode * ifx) #endif /* if left is a literal & right is not then exchange them */ - if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) || - AOP_NEEDSACC (left)) + if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) +#ifdef LOGIC_OPS_BROKEN + || AOP_NEEDSACC (left) +#endif + ) { operand *tmp = right; right = left; @@ -5413,8 +5907,7 @@ genAnd (iCode * ic, iCode * ifx) aopPut (AOP (result), zero, offset); continue; } - D (emitcode (";", "better literal AND."); - ); + D (emitcode (";", "better literal AND.");); MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE)); emitcode ("anl", "a, %s", aopGet (AOP (right), offset, FALSE, FALSE, FALSE)); @@ -5431,10 +5924,16 @@ genAnd (iCode * ic, iCode * ifx) } else { - MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE)); - emitcode ("anl", "a,%s", - aopGet (AOP (left), offset, FALSE, FALSE, FALSE)); - } + char *rOp = aopGet (AOP (right), offset, FALSE, FALSE, TRUE); + if (!strcmp(rOp, "a") || !strcmp(rOp, "acc")) + { + emitcode("mov", "b,a"); + rOp = "b"; + } + + MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE)); + emitcode ("anl", "a,%s", rOp); + } } aopPut (AOP (result), "a", offset); } @@ -5481,8 +5980,11 @@ genOr (iCode * ic, iCode * ifx) #endif /* if left is a literal & right is not then exchange them */ - if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) || - AOP_NEEDSACC (left)) + if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) +#ifdef LOGIC_OPS_BROKEN + || AOP_NEEDSACC (left) // I think this is a net loss now. +#endif + ) { operand *tmp = right; right = left; @@ -5702,6 +6204,7 @@ genOr (iCode * ic, iCode * ifx) } else { + _startLazyDPSEvaluation(); for (; (size--); offset++) { // normal case @@ -5715,8 +6218,7 @@ genOr (iCode * ic, iCode * ifx) offset); continue; } - D (emitcode (";", "better literal OR."); - ); + D (emitcode (";", "better literal OR.");); MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE)); emitcode ("orl", "a, %s", aopGet (AOP (right), offset, FALSE, FALSE, FALSE)); @@ -5733,13 +6235,21 @@ genOr (iCode * ic, iCode * ifx) } else { - MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE)); - emitcode ("orl", "a,%s", - aopGet (AOP (left), offset, FALSE, FALSE, FALSE)); + char *rOp = aopGet (AOP (right), offset, FALSE, FALSE, TRUE); + + if (!strcmp(rOp, "a") || !strcmp(rOp, "acc")) + { + emitcode("mov", "b,a"); + rOp = "b"; + } + + MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE)); + emitcode ("orl", "a,%s", rOp); } } aopPut (AOP (result), "a", offset); } + _endLazyDPSEvaluation(); } } @@ -5782,8 +6292,11 @@ genXor (iCode * ic, iCode * ifx) /* if left is a literal & right is not || if left needs acc & right does not */ - if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) || - (AOP_NEEDSACC (left) && !AOP_NEEDSACC (right))) + if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) +#ifdef LOGIC_OPS_BROKEN + || (AOP_NEEDSACC (left) && !AOP_NEEDSACC (right)) +#endif + ) { operand *tmp = right; right = left; @@ -6011,9 +6524,15 @@ genXor (iCode * ic, iCode * ifx) } else { - MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE)); - emitcode ("xrl", "a,%s", - aopGet (AOP (left), offset, FALSE, TRUE, FALSE)); + char *rOp = aopGet (AOP (right), offset, FALSE, FALSE, TRUE); + if (!strcmp(rOp, "a") || !strcmp(rOp, "acc")) + { + emitcode("mov", "b,a"); + rOp = "b"; + } + + MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE)); + emitcode ("xrl", "a,%s", rOp); } } aopPut (AOP (result), "a", offset); @@ -8051,7 +8570,8 @@ genDataPointerGet (operand * left, static void genNearPointerGet (operand * left, operand * result, - iCode * ic) + iCode * ic, + iCode *pi) { asmop *aop = NULL; regs *preg = NULL; @@ -8120,7 +8640,7 @@ genNearPointerGet (operand * left, aopPut (AOP (result), buffer, offset); } offset++; - if (size) + if (size || pi) emitcode ("inc", "%s", rname); } } @@ -8129,6 +8649,9 @@ genNearPointerGet (operand * left, if (aop) { /* we had to allocate for this iCode */ + if (pi) { /* post increment present */ + aopPut(AOP ( left ),rname,0); + } freeAsmop (NULL, aop, ic, TRUE); } else @@ -8141,7 +8664,8 @@ genNearPointerGet (operand * left, if (AOP_SIZE (result) > 1 && !OP_SYMBOL (left)->remat && (OP_SYMBOL (left)->liveTo > ic->seq || - ic->depth)) + ic->depth) && + !pi) { int size = AOP_SIZE (result) - 1; while (size--) @@ -8151,7 +8675,7 @@ genNearPointerGet (operand * left, /* done */ freeAsmop (result, NULL, ic, TRUE); - + if (pi) pi->generated = 1; } /*-----------------------------------------------------------------*/ @@ -8160,7 +8684,8 @@ genNearPointerGet (operand * left, static void genPagedPointerGet (operand * left, operand * result, - iCode * ic) + iCode * ic, + iCode * pi) { asmop *aop = NULL; regs *preg = NULL; @@ -8207,7 +8732,7 @@ genPagedPointerGet (operand * left, offset++; - if (size) + if (size || pi) emitcode ("inc", "%s", rname); } } @@ -8216,6 +8741,7 @@ genPagedPointerGet (operand * left, if (aop) { /* we had to allocate for this iCode */ + if (pi) aopPut ( AOP (left), rname, 0); freeAsmop (NULL, aop, ic, TRUE); } else @@ -8228,7 +8754,8 @@ genPagedPointerGet (operand * left, if (AOP_SIZE (result) > 1 && !OP_SYMBOL (left)->remat && (OP_SYMBOL (left)->liveTo > ic->seq || - ic->depth)) + ic->depth) && + !pi) { int size = AOP_SIZE (result) - 1; while (size--) @@ -8238,8 +8765,7 @@ genPagedPointerGet (operand * left, /* done */ freeAsmop (result, NULL, ic, TRUE); - - + if (pi) pi->generated = 1; } /*-----------------------------------------------------------------*/ @@ -8247,7 +8773,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)); @@ -8312,13 +8838,20 @@ genFarPointerGet (operand * left, _flushLazyDPS (); emitcode ("movx", "a,@dptr"); - if (size) + if (size || pi) emitcode ("inc", "dptr"); aopPut (AOP (result), "a", offset++); } _endLazyDPSEvaluation (); } + if (pi && AOP_TYPE (left) != AOP_IMMD && AOP_TYPE (left) != AOP_STR) { + aopPut ( AOP (left), "dpl", 0); + aopPut ( AOP (left), "dph", 1); + if (options.model == MODEL_FLAT24) + aopPut ( AOP (left), "dpx", 2); + pi->generated = 1; + } freeAsmop (result, NULL, ic, TRUE); } @@ -8328,7 +8861,7 @@ genFarPointerGet (operand * left, /*-----------------------------------------------------------------*/ static void emitcodePointerGet (operand * left, - operand * result, iCode * ic) + operand * result, iCode * ic, iCode *pi) { int size, offset; sym_link *retype = getSpec (operandType (result)); @@ -8370,7 +8903,6 @@ emitcodePointerGet (operand * left, } } /* so dptr know contains the address */ - freeAsmop (left, NULL, ic, TRUE); aopOp (result, ic, FALSE, TRUE); /* if bit then unpack */ @@ -8389,13 +8921,21 @@ emitcodePointerGet (operand * left, emitcode ("clr", "a"); emitcode ("movc", "a,@a+dptr"); - if (size) + if (size || pi) emitcode ("inc", "dptr"); aopPut (AOP (result), "a", offset++); } _endLazyDPSEvaluation (); } + if (pi && AOP_TYPE (left) != AOP_IMMD && AOP_TYPE (left) != AOP_STR) { + aopPut ( AOP (left), "dpl", 0); + aopPut ( AOP (left), "dph", 1); + if (options.model == MODEL_FLAT24) + aopPut ( AOP (left), "dpx", 2); + pi->generated = 1; + } + freeAsmop (left, NULL, ic, TRUE); freeAsmop (result, NULL, ic, TRUE); } @@ -8404,7 +8944,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)); @@ -8422,7 +8962,10 @@ genGenPointerGet (operand * left, if (AOP_TYPE (left) == AOP_IMMD) { emitcode ("mov", "dptr,%s", aopGet (AOP (left), 0, TRUE, FALSE, 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, FALSE)); + else + emitcode ("mov", "b,#%d", pointerCode (retype)); } else { /* we need to get it byte by byte */ @@ -8460,7 +9003,6 @@ genGenPointerGet (operand * left, } } /* so dptr know contains the address */ - freeAsmop (left, NULL, ic, TRUE); aopOp (result, ic, FALSE, TRUE); /* if bit then unpack */ @@ -8475,11 +9017,21 @@ 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); + if (options.model == MODEL_FLAT24) { + aopPut ( AOP (left), "dpx", 2); + aopPut ( AOP (left), "b", 3); + } else aopPut ( AOP (left), "b", 2); + pi->generated = 1; + } + freeAsmop (left, NULL, ic, TRUE); freeAsmop (result, NULL, ic, TRUE); } @@ -8487,7 +9039,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; @@ -8511,7 +9063,13 @@ genPointerGet (iCode * ic) /* we have to go by the storage class */ 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) @@ -8519,23 +9077,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); + emitcodePointerGet (left, result, ic, pi); break; case GPOINTER: - genGenPointerGet (left, result, ic); + genGenPointerGet (left, result, ic, pi); break; } @@ -9029,7 +9587,10 @@ genGenPointerSet (operand * right, if (AOP_TYPE (result) == AOP_IMMD) { emitcode ("mov", "dptr,%s", aopGet (AOP (result), 0, TRUE, FALSE, FALSE)); - emitcode ("mov", "b,%s + 1", aopGet (AOP (result), 0, TRUE, FALSE, FALSE)); + if (AOP(result)->aopu.aop_immd.from_cast_remat) + emitcode ("mov", "b,%s",aopGet(AOP (result), AOP_SIZE(result)-1, FALSE, FALSE, FALSE)); + else + emitcode ("mov", "b,%s + 1", aopGet (AOP (result), 0, TRUE, FALSE, FALSE)); } else { /* we need to get it byte by byte */ @@ -9079,7 +9640,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; @@ -9105,6 +9666,13 @@ genPointerSet (iCode * ic) /* we have to go by the storage class */ 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 */ @@ -9259,6 +9827,7 @@ genArrayInit (iCode * ic) int elementSize = 0, eIndex; unsigned val, lastVal; sym_link *type; + operand *left=IC_LEFT(ic); D (emitcode (";", "genArrayInit ");); @@ -9272,9 +9841,17 @@ genArrayInit (iCode * ic) } else if (AOP_TYPE(IC_LEFT(ic)) != AOP_DPTR) { - werror (E_INTERNAL_ERROR, __FILE__, __LINE__, - "Unexpected operand to genArrayInit.\n"); - exit(1); +#if 0 + werror (E_INTERNAL_ERROR, __FILE__, __LINE__, + "Unexpected operand to genArrayInit.\n"); + exit(1); +#else + // a regression because of SDCCcse.c:1.52 + emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE, TRUE)); + emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE, TRUE)); + if (options.model == MODEL_FLAT24) + emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE)); +#endif } type = operandType(IC_LEFT(ic)); @@ -9491,9 +10068,8 @@ genAssign (iCode * ic) goto release; /* if the result is a bit */ - if (AOP_TYPE (result) == AOP_CRY) + if (AOP_TYPE (result) == AOP_CRY) /* works only for true symbols */ { - /* if the right size is a literal then we know what the value is */ if (AOP_TYPE (right) == AOP_LIT) @@ -9624,7 +10200,8 @@ genCast (iCode * ic) aopOp (result, ic, FALSE, AOP_TYPE (right) == AOP_DPTR); /* 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 */ @@ -10177,12 +10754,12 @@ gen390Code (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;