X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fds390%2Fgen.c;h=61c367a3e5cc0dfafdfe3434b47d4da5e2751e9d;hb=91dd45a032c32b5925c0b8c6898423e3a980d6ba;hp=21315fde238ff9c08ee0b880e299298d9c8b0e28;hpb=c7213e51f3526a7559d03919d64907ccc0b25aa7;p=fw%2Fsdcc diff --git a/src/ds390/gen.c b/src/ds390/gen.c index 21315fde..61c367a3 100644 --- a/src/ds390/gen.c +++ b/src/ds390/gen.c @@ -38,6 +38,9 @@ #ifdef HAVE_SYS_ISA_DEFS_H #include #else +#ifdef HAVE_MACHINE_ENDIAN_H +#include +#else #ifdef HAVE_ENDIAN_H #include #else @@ -47,6 +50,7 @@ #endif #endif #endif +#endif #define BETTER_LITERAL_SHIFT @@ -63,9 +67,15 @@ static char *spname; #define D(x) x +#define TR_DPTR(s) if (options.model != MODEL_FLAT24) { emitcode(";", " Use_DPTR1 %s ", s); } +#define TR_AP(s) if (options.model != MODEL_FLAT24) { emitcode(";", " Use_AP %s ", s); } + unsigned fReturnSizeDS390 = 5; /* shared with ralloc.c */ -static char *fReturn[] = +static char *fReturn24[] = {"dpl", "dph", "dpx", "b", "a"}; +static char *fReturn16[] = +{"dpl", "dph", "b", "a"}; +static char **fReturn = fReturn24; static char *accUse[] = {"a", "b"}; @@ -286,6 +296,7 @@ genSetDPTR (int n) } else { + TR_DPTR("#1"); emitcode ("mov", "dps, #0x01"); } } @@ -456,13 +467,16 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool useDP2) if (useDP2) { - emitcode ("mov", "dpx1,#0x40"); + if (options.model == MODEL_FLAT24) + emitcode ("mov", "dpx1,#0x40"); + TR_DPTR("#2"); emitcode ("mov", "dph1,#0x00"); emitcode ("mov", "dpl1, a"); } else { - emitcode ("mov", "dpx,#0x40"); + if (options.model == MODEL_FLAT24) + emitcode ("mov", "dpx,#0x40"); emitcode ("mov", "dph,#0x00"); emitcode ("mov", "dpl, a"); } @@ -973,6 +987,7 @@ aopGet (asmop * aop, genSetDPTR (1); if (!canClobberACC) { + TR_AP("#1"); emitcode ("xch", "a, %s", DP2_RESULT_REG); } } @@ -1007,6 +1022,7 @@ aopGet (asmop * aop, genSetDPTR (0); if (!canClobberACC) { + TR_AP("#2"); emitcode ("xch", "a, %s", DP2_RESULT_REG); return DP2_RESULT_REG; } @@ -1758,8 +1774,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 @@ -2170,7 +2186,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; @@ -2179,17 +2195,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; @@ -2257,7 +2273,7 @@ genCall (iCode * ic) if (swapBanks) { emitcode ("mov", "psw,#0x%02x", - ((SPEC_BANK(detype)) << 3) & 0xff); + ((FUNC_REGBANK(dtype)) << 3) & 0xff); } /* make the call */ @@ -2268,7 +2284,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 */ @@ -2327,12 +2343,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); } /*-----------------------------------------------------------------*/ @@ -2341,7 +2357,7 @@ genCall (iCode * ic) static void genPcall (iCode * ic) { - sym_link *detype; + sym_link *dtype; symbol *rlbl = newiTempLabel (NULL); D (emitcode (";", "genPcall "); @@ -2355,11 +2371,11 @@ 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_ISISR (currFunc->type) && + (FUNC_REGBANK (currFunc->type) != FUNC_REGBANK (dtype))) + saveRBank (FUNC_REGBANK (dtype), ic, TRUE); /* push the return address on to the stack */ @@ -2450,10 +2466,10 @@ 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 (dtype && + (FUNC_REGBANK (currFunc->type) != + FUNC_REGBANK (dtype))) + unsaveRBank (FUNC_REGBANK (dtype), ic, TRUE); /* if we hade saved some registers then unsave them */ @@ -2515,7 +2531,7 @@ static void genFunction (iCode * ic) { symbol *sym; - sym_link *fetype; + sym_link *ftype; bool switchedPSW = FALSE; D (emitcode (";", "genFunction ");); @@ -2527,25 +2543,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) @@ -2562,7 +2578,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")) @@ -2591,13 +2607,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; @@ -2634,7 +2650,7 @@ genFunction (iCode * ic) */ unsigned long banksToSave = 0; - if (sym->hasFcall) + if (IFFUNC_HASFCALL(sym->type)) { #define MAX_REGISTER_BANKS 4 @@ -2652,20 +2668,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 @@ -2697,7 +2713,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; } @@ -2709,6 +2725,7 @@ genFunction (iCode * ic) } } } + // jwk: this needs a closer look SPEC_ISR_SAVED_BANKS(currFunc->etype) = banksToSave; } } @@ -2716,7 +2733,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; @@ -2738,14 +2755,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) @@ -2804,13 +2821,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); } @@ -2826,7 +2843,7 @@ genEndFunction (iCode * ic) } - if ((IS_RENT (sym->etype) || options.stackAuto)) + if ((IFFUNC_ISREENT (sym->type) || options.stackAuto)) { if (options.useXstack) { @@ -2842,9 +2859,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 @@ -2854,19 +2871,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; @@ -2898,6 +2915,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; @@ -2939,7 +2957,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 */ @@ -2959,10 +2977,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; @@ -3340,6 +3358,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) \ @@ -3354,6 +3374,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 @@ -3527,6 +3548,7 @@ genPlus (iCode * ic) * above branch. */ assert(AOP_NEEDSACC(IC_RIGHT(ic))); + TR_AP("#3"); D(emitcode(";", "+ AOP_ACC special case.");); emitcode("xch", "a, %s", DP2_RESULT_REG); } @@ -3535,6 +3557,7 @@ genPlus (iCode * ic) { if (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) { + TR_AP("#4"); emitcode("add", "a, %s", DP2_RESULT_REG); } else @@ -3899,10 +3922,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); } @@ -3913,18 +3938,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 */ @@ -3945,8 +3964,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; @@ -3990,11 +4023,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"); @@ -4006,7 +4050,8 @@ 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); } } @@ -4024,14 +4069,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; } @@ -4039,12 +4084,12 @@ genMult (iCode * ic) if (AOP_SIZE (left) == 1 && AOP_SIZE (right) == 1) { - genMultOneByte (left, right, result); + genMultOneByte (left, right, result, ic); goto release; } /* should have been converted to function call */ - assert (1); + assert (0); release: freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE)); @@ -4058,7 +4103,8 @@ release: static void genDivbits (operand * left, operand * right, - operand * result) + operand * result, + iCode * ic) { char *l; @@ -4067,6 +4113,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); } @@ -4076,24 +4124,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; } @@ -4144,14 +4201,23 @@ 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--; } @@ -4165,18 +4231,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; } @@ -4184,12 +4249,12 @@ genDiv (iCode * ic) if (AOP_SIZE (left) == 1 && AOP_SIZE (right) == 1) { - genDivOneByte (left, right, result); + genDivOneByte (left, right, result, ic); goto release; } /* 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)); @@ -4202,7 +4267,8 @@ release: static void genModbits (operand * left, operand * right, - operand * result) + operand * result, + iCode * ic) { char *l; @@ -4212,6 +4278,7 @@ genModbits (operand * left, emitcode ("div", "ab"); emitcode ("mov", "a,b"); emitcode ("rrc", "a"); + aopOp(result, ic, TRUE, FALSE); aopPut (AOP (result), "c", 0); } @@ -4221,7 +4288,8 @@ genModbits (operand * left, static void genModOneByte (operand * left, operand * right, - operand * result) + operand * result, + iCode * ic) { sym_link *opetype = operandType (result); char *l; @@ -4233,6 +4301,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; } @@ -4285,6 +4354,7 @@ genModOneByte (operand * left, emitcode ("", "%05d$:", (lbl->key + 100)); /* now we are done */ + aopOp(result, ic, TRUE, FALSE); aopPut (AOP (result), "b", 0); } @@ -4299,18 +4369,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; } @@ -4318,12 +4387,12 @@ genMod (iCode * ic) if (AOP_SIZE (left) == 1 && AOP_SIZE (right) == 1) { - genModOneByte (left, right, result); + genModOneByte (left, right, result, ic); goto release; } /* should have been converted to function call */ - assert (1); + assert (0); release: freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE)); @@ -5073,6 +5142,7 @@ genFarFarLogicOp(iCode *ic, char *logicOp) int size, resultSize, compSize; int offset = 0; + TR_AP("#5"); D(emitcode(";", "%s special case for 3 far operands.", logicOp);); compSize = AOP_SIZE(IC_LEFT(ic)) < AOP_SIZE(IC_RIGHT(ic)) ? AOP_SIZE(IC_LEFT(ic)) : AOP_SIZE(IC_RIGHT(ic)); @@ -5142,8 +5212,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; @@ -5398,8 +5471,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)); @@ -5416,10 +5488,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); } @@ -5466,8 +5544,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; @@ -5687,6 +5768,7 @@ genOr (iCode * ic, iCode * ifx) } else { + _startLazyDPSEvaluation(); for (; (size--); offset++) { // normal case @@ -5700,8 +5782,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)); @@ -5718,13 +5799,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(); } } @@ -5767,8 +5856,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; @@ -5996,9 +6088,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); @@ -6740,6 +6838,7 @@ _loadLeftIntoAx(char **lsb, leftByte = aopGet (AOP(left), offl, FALSE, FALSE, TRUE); if (strcmp(leftByte, DP2_RESULT_REG)) { + TR_AP("#7"); emitcode("mov","%s,%s", DP2_RESULT_REG, leftByte); } // And MSB in A. @@ -7918,7 +8017,7 @@ genUnpackBits (operand * result, char *rname, int ptype) case CPOINTER: emitcode ("clr", "a"); - emitcode ("movc", "a", "@a+dptr"); + emitcode ("movc", "a,@a+dptr"); break; case GPOINTER: @@ -7970,7 +8069,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: @@ -8258,7 +8357,8 @@ genFarPointerGet (operand * left, { emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE, TRUE)); emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE, TRUE)); - emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE)); + if (options.model == MODEL_FLAT24) + emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE)); } else { @@ -8267,7 +8367,8 @@ genFarPointerGet (operand * left, ); emitcode ("push", "%s", aopGet (AOP (left), 0, FALSE, TRUE, TRUE)); emitcode ("push", "%s", aopGet (AOP (left), 1, FALSE, TRUE, TRUE)); - emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE)); + if (options.model == MODEL_FLAT24) + emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE)); emitcode ("pop", "dph"); emitcode ("pop", "dpl"); } @@ -8333,7 +8434,8 @@ emitcodePointerGet (operand * left, { emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE, TRUE)); emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE, TRUE)); - emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE)); + if (options.model == MODEL_FLAT24) + emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE)); } else { @@ -8342,7 +8444,8 @@ emitcodePointerGet (operand * left, ); emitcode ("push", "%s", aopGet (AOP (left), 0, FALSE, TRUE, TRUE)); emitcode ("push", "%s", aopGet (AOP (left), 1, FALSE, TRUE, TRUE)); - emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE)); + if (options.model == MODEL_FLAT24) + emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE)); emitcode ("pop", "dph"); emitcode ("pop", "dpl"); } @@ -8417,16 +8520,24 @@ genGenPointerGet (operand * left, genSetDPTR(0); _flushLazyDPS(); emitcode ("mov", "dph,%s", l); - l=aopGet(AOP(left),2,FALSE,FALSE,TRUE); - genSetDPTR(0); - _flushLazyDPS(); - emitcode ("mov", "dpx,%s", l); - emitcode ("mov", "b,%s", aopGet (AOP(left),3,FALSE,FALSE,TRUE)); + if (options.model == MODEL_FLAT24) { + l=aopGet(AOP(left),2,FALSE,FALSE,TRUE); + genSetDPTR(0); + _flushLazyDPS(); + emitcode ("mov", "dpx,%s", l); + emitcode ("mov", "b,%s", aopGet (AOP(left),3,FALSE,FALSE,TRUE)); + } else { + emitcode ("mov", "b,%s", aopGet (AOP(left),2,FALSE,FALSE,TRUE)); + } } else { emitcode ("mov", "dpl,%s", aopGet (AOP(left),0,FALSE,FALSE,TRUE)); emitcode ("mov", "dph,%s", aopGet (AOP(left),1,FALSE,FALSE,TRUE)); - emitcode ("mov", "dpx,%s", aopGet (AOP(left),2,FALSE,FALSE,TRUE)); - emitcode ("mov", "b,%s", aopGet (AOP(left),3,FALSE,FALSE,TRUE)); + if (options.model == MODEL_FLAT24) { + emitcode ("mov", "dpx,%s", aopGet (AOP(left),2,FALSE,FALSE,TRUE)); + emitcode ("mov", "b,%s", aopGet (AOP(left),3,FALSE,FALSE,TRUE)); + } else { + emitcode ("mov", "b,%s", aopGet (AOP(left),2,FALSE,FALSE,TRUE)); + } } _endLazyDPSEvaluation (); } @@ -8930,7 +9041,8 @@ genFarPointerSet (operand * right, { emitcode ("mov", "dpl,%s", aopGet (AOP (result), 0, FALSE, FALSE, TRUE)); emitcode ("mov", "dph,%s", aopGet (AOP (result), 1, FALSE, FALSE, TRUE)); - emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE)); + if (options.model == MODEL_FLAT24) + emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE)); } else { @@ -8939,7 +9051,8 @@ genFarPointerSet (operand * right, ); emitcode ("push", "%s", aopGet (AOP (result), 0, FALSE, TRUE, TRUE)); emitcode ("push", "%s", aopGet (AOP (result), 1, FALSE, TRUE, TRUE)); - emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE)); + if (options.model == MODEL_FLAT24) + emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE)); emitcode ("pop", "dph"); emitcode ("pop", "dpl"); } @@ -9005,8 +9118,12 @@ genGenPointerSet (operand * right, { /* we need to get it byte by byte */ emitcode ("mov", "dpl,%s", aopGet (AOP (result), 0, FALSE, FALSE, TRUE)); emitcode ("mov", "dph,%s", aopGet (AOP (result), 1, FALSE, FALSE, TRUE)); - emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE)); - emitcode ("mov", "b,%s", aopGet (AOP (result), 3, FALSE, FALSE, TRUE)); + if (options.model == MODEL_FLAT24) { + emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE)); + emitcode ("mov", "b,%s", aopGet (AOP (result), 3, FALSE, FALSE, TRUE)); + } else { + emitcode ("mov", "b,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE)); + } } _endLazyDPSEvaluation (); } @@ -9214,6 +9331,115 @@ release: } +/*-----------------------------------------------------------------*/ +/* genArrayInit - generates code for address of */ +/*-----------------------------------------------------------------*/ +static void +genArrayInit (iCode * ic) +{ + literalList *iLoop; + int ix, count; + int elementSize = 0, eIndex; + unsigned val, lastVal; + sym_link *type; + operand *left=IC_LEFT(ic); + + D (emitcode (";", "genArrayInit ");); + + aopOp (IC_LEFT(ic), ic, FALSE, FALSE); + + if (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) + { + // Load immediate value into DPTR. + emitcode("mov", "dptr, %s", + aopGet(AOP(IC_LEFT(ic)), 0, TRUE, FALSE, TRUE)); + } + else if (AOP_TYPE(IC_LEFT(ic)) != AOP_DPTR) + { +#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)); + + if (type && type->next) + { + elementSize = getSize(type->next); + } + else + { + werror (E_INTERNAL_ERROR, __FILE__, __LINE__, + "can't determine element size in genArrayInit.\n"); + exit(1); + } + + iLoop = IC_ARRAYILIST(ic); + lastVal = 0xffff; + + while (iLoop) + { + bool firstpass = TRUE; + + emitcode(";", "store %d x 0x%x to DPTR (element size %d)", + iLoop->count, (int)iLoop->literalValue, elementSize); + + ix = iLoop->count; + + while (ix) + { + symbol *tlbl = NULL; + + count = ix > 256 ? 256 : ix; + + if (count > 1) + { + tlbl = newiTempLabel (NULL); + if (firstpass || (count & 0xff)) + { + emitcode("mov", "b, #0x%x", count & 0xff); + } + + emitcode ("", "%05d$:", tlbl->key + 100); + } + + firstpass = FALSE; + + for (eIndex = 0; eIndex < elementSize; eIndex++) + { + val = (((int)iLoop->literalValue) >> (eIndex * 8)) & 0xff; + if (val != lastVal) + { + emitcode("mov", "a, #0x%x", val); + lastVal = val; + } + + emitcode("movx", "@dptr, a"); + emitcode("inc", "dptr"); + } + + if (count > 1) + { + emitcode("djnz", "b, %05d$", tlbl->key + 100); + } + + ix -= count; + } + + iLoop = iLoop->next; + } + + freeAsmop (IC_LEFT(ic), NULL, ic, TRUE); +} + /*-----------------------------------------------------------------*/ /* genFarFarAssign - assignment when both are in far space */ /*-----------------------------------------------------------------*/ @@ -9256,7 +9482,7 @@ genFarFarAssign (operand * result, operand * right, iCode * ic) { /* We can use the '390 auto-toggle feature to good effect here. */ - D(emitcode(";","genFarFarAssign ('390 auto-toggle fun)");); + D(emitcode(";","genFarFarAssign (390 auto-toggle fun)");); emitcode("mov", "dps, #0x21"); /* Select DPTR2 & auto-toggle. */ emitcode ("mov", "dptr,#%s", rSym->rname); /* DP2 = result, DP1 = right, DP1 is current. */ @@ -9272,6 +9498,28 @@ genFarFarAssign (operand * result, operand * right, iCode * ic) } emitcode("mov", "dps, #0"); freeAsmop (right, NULL, ic, FALSE); +#if 0 +some alternative code for processors without auto-toggle +no time to test now, so later well put in...kpb + D(emitcode(";","genFarFarAssign (dual-dptr fun)");); + emitcode("mov", "dps, #0x01"); /* Select DPTR2. */ + emitcode ("mov", "dptr,#%s", rSym->rname); + /* DP2 = result, DP1 = right, DP1 is current. */ + while (size) + { + --size; + emitcode("movx", "a,@dptr"); + if (size) + emitcode("inc", "dptr"); + emitcode("inc", "dps"); + emitcode("movx", "@dptr,a"); + if (size) + emitcode("inc", "dptr"); + emitcode("inc", "dps"); + } + emitcode("mov", "dps, #0"); + freeAsmop (right, NULL, ic, FALSE); +#endif } else { @@ -9335,9 +9583,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) @@ -9468,7 +9715,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 */ @@ -9816,6 +10064,14 @@ gen390Code (iCode * lic) lineHead = lineCurr = NULL; + if (options.model == MODEL_FLAT24) { + fReturnSizeDS390 = 5; + fReturn = fReturn24; + } else { + fReturnSizeDS390 = 4; + fReturn = fReturn16; + options.stack10bit=0; + } #if 0 //REMOVE ME!!! /* print the allocation information */ @@ -10047,6 +10303,10 @@ gen390Code (iCode * lic) addSet (&_G.sendSet, ic); break; + case ARRAYINIT: + genArrayInit(ic); + break; + default: ic = ic; }