X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fds390%2Fgen.c;h=b43549176e1b3040f3397fbdbd4a02007384c227;hb=9544ad10c9f8df77aa4d8c03b497a9a6fb6f20f9;hp=d865d7c8532aeb39b69dbb6e30feb5e8140551a3;hpb=84313567878de3a45d10797f1d6899d31c49d176;p=fw%2Fsdcc diff --git a/src/ds390/gen.c b/src/ds390/gen.c index d865d7c8..b4354917 100644 --- a/src/ds390/gen.c +++ b/src/ds390/gen.c @@ -482,7 +482,7 @@ endOfWorld: /*-----------------------------------------------------------------*/ /* genSetDPTR: generate code to select which DPTR is in use (zero */ /* selects standard DPTR (DPL/DPH/DPX), non-zero selects DS390 */ -/* alternate DPTR (DPL1/DPH1/DPX1). */ +/* alternate DPTR (DPL1/DPH1/DPX1). */ /*-----------------------------------------------------------------*/ static void genSetDPTR (int n) @@ -566,9 +566,9 @@ _flushLazyDPS (void) } /*-----------------------------------------------------------------*/ -/* _endLazyDPSEvaluation: end lazy DPS evaluation block. */ -/* */ -/* Forces us back to the safe state (standard DPTR selected). */ +/* _endLazyDPSEvaluation: end lazy DPS evaluation block. */ +/* */ +/* Forces us back to the safe state (standard DPTR selected). */ /*-----------------------------------------------------------------*/ static void _endLazyDPSEvaluation (void) @@ -729,8 +729,8 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool useDP2) if (sym->onStack) { signed char offset = ((sym->stack < 0) ? - ((char) (sym->stack - _G.nRegsSaved)) : - ((char) sym->stack)) & 0xff; + ((signed char) (sym->stack - _G.nRegsSaved)) : + ((signed char) sym->stack)) & 0xff; if ((abs(offset) <= 3) || (accuse && (abs(offset) <= 7))) @@ -774,14 +774,14 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool useDP2) if (sym->onStack && options.stack10bit) { - short stack_val = -((sym->stack < 0) ? - ((short) (sym->stack - _G.nRegsSaved)) : - ((short) sym->stack)) ; - if (_G.dptrInUse ) { - emitcode ("push",dpl); - emitcode ("push",dph); - emitcode ("push",dpx); - } + short stack_val = -((sym->stack < 0) ? + ((short) (sym->stack - _G.nRegsSaved)) : + ((short) sym->stack)) ; + if (_G.dptrInUse ) { + emitcode ("push",dpl); + emitcode ("push",dph); + emitcode ("push",dpx); + } /* It's on the 10 bit stack, which is located in * far data space. */ @@ -789,8 +789,8 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool useDP2) { /* between -5 & -1 */ if (options.model == MODEL_FLAT24) { - emitcode ("mov", "%s,#!constbyte", dpx, - (options.stack_loc >> 16) & 0xff); + emitcode ("mov", "%s,#!constbyte", dpx, + (options.stack_loc >> 16) & 0xff); } emitcode ("mov", "%s,_bpx+1", dph); emitcode ("mov", "%s,_bpx", dpl); @@ -1408,6 +1408,8 @@ aopGetUsesAcc (operand * oper, int offset) return TRUE; return FALSE; case AOP_DPTR: + case AOP_DPTR2: + case AOP_DPTRn: return TRUE; case AOP_IMMD: return FALSE; @@ -1544,32 +1546,32 @@ aopGet (operand * oper, genSetDPTR (0); } - if (saveAcc) + if (saveAcc) { - TR_AP("#2"); - emitcode ("xch", "a, %s", saveAcc); -// if (strcmp(saveAcc, "_ap")) -// { -// emitcode(";", "spiffy: non _ap return from aopGet."); -// } + TR_AP("#2"); + emitcode ("xch", "a, %s", saveAcc); +// if (strcmp(saveAcc, "_ap")) +// { +// emitcode(";", "spiffy: non _ap return from aopGet."); +// } - return saveAcc; + return saveAcc; } return (dname ? "acc" : "a"); case AOP_IMMD: if (aop->aopu.aop_immd.from_cast_remat && (offset == (aop->size-1))) - { + { SNPRINTF(buffer, sizeof(buffer), "%s",aop->aopu.aop_immd.aop_immd2); - } + } else if (bit16) - { - SNPRINTF(buffer, sizeof(buffer), - "#%s", aop->aopu.aop_immd.aop_immd1); - } + { + SNPRINTF(buffer, sizeof(buffer), + "#%s", aop->aopu.aop_immd.aop_immd1); + } else if (offset) - { + { switch (offset) { case 1: tsprintf(buffer, sizeof(buffer), @@ -1589,13 +1591,13 @@ aopGet (operand * oper, aop->aopu.aop_immd.aop_immd1, offset * 8); } - } + } else - { - SNPRINTF (buffer, sizeof(buffer), - "#%s", - aop->aopu.aop_immd.aop_immd1); - } + { + SNPRINTF (buffer, sizeof(buffer), + "#%s", + aop->aopu.aop_immd.aop_immd1); + } return Safe_strdup(buffer); case AOP_DIR: @@ -1658,51 +1660,6 @@ aopGet (operand * oper, return NULL; // not reached, but makes compiler happy. } -/*-----------------------------------------------------------------*/ -/* aopPutUsesAcc - indicates ahead of time whether aopPut() will */ -/* clobber the accumulator */ -/*-----------------------------------------------------------------*/ -#if 0 -static bool -aopPutUsesAcc (operand * oper, const char *s, int offset) -{ - asmop * aop = AOP (oper); - - if (offset > (aop->size - 1)) - return FALSE; - - switch (aop->type) - { - case AOP_DUMMY: - return TRUE; - case AOP_DIR: - return FALSE; - case AOP_REG: - wassert(strcmp(aop->aopu.aop_reg[offset]->name, "a")); - return FALSE; - case AOP_DPTR: - return TRUE; - case AOP_R0: - case AOP_R1: - return ((aop->paged) || (*s == '@')); - case AOP_STK: - return (*s == '@'); - case AOP_CRY: - return (!aop->aopu.aop_dir || strcmp(s, aop->aopu.aop_dir)); - case AOP_STR: - return FALSE; - case AOP_IMMD: - return FALSE; - case AOP_ACC: - return FALSE; - default: - /* Error case --- will have been caught already */ - wassert(0); - return FALSE; - } -} -#endif - /*-----------------------------------------------------------------*/ /* aopPut - puts a string for a aop and indicates if acc is in use */ /*-----------------------------------------------------------------*/ @@ -1905,12 +1862,12 @@ aopPut (operand * result, const char *s, int offset) emitcode ("mov", "%s,c", aop->aopu.aop_dir); else if (strcmp (s, aop->aopu.aop_dir)) { - MOVA (s); - /* set C, if a >= 1 */ - emitcode ("add", "a,#!constbyte",0xff); - emitcode ("mov", "%s,c", aop->aopu.aop_dir); - } + MOVA (s); + /* set C, if a >= 1 */ + emitcode ("add", "a,#!constbyte",0xff); + emitcode ("mov", "%s,c", aop->aopu.aop_dir); } + } break; case AOP_STR: @@ -2083,7 +2040,7 @@ toBoolean (operand * oper) emitcode("mov", "b,a"); while (--size) { - MOVA (aopGet (oper, offset++, FALSE, FALSE, NULL)); + MOVA (aopGet (oper, offset++, FALSE, FALSE, NULL)); emitcode ("orl", "b,a"); } MOVA (aopGet (oper, offset++, FALSE, FALSE, NULL)); @@ -2332,6 +2289,7 @@ release: static void savermask(bitVect *rs_mask) { int i; + if (options.useXstack) { if (bitVectBitValue (rs_mask, R0_IDX)) @@ -2390,7 +2348,7 @@ saveRegisters (iCode * lic) do nothing */ if (ic->regsSaved || (IS_SYMOP(IC_LEFT(ic)) && IFFUNC_ISNAKED(OP_SYM_TYPE(IC_LEFT(ic))) && !TARGET_IS_DS400) ) - return ; + return; /* special case if DPTR alive across a function call then must save it even though callee saves */ @@ -2421,9 +2379,11 @@ saveRegisters (iCode * lic) /*-----------------------------------------------------------------*/ static void unsavermask(bitVect *rs_mask) { - int i; - if (options.useXstack) { - emitcode ("mov", "r0,%s", spname); + int i; + + if (options.useXstack) + { + emitcode ("mov", "r0,%s", spname); for (i = ds390_nRegs; i >= 0; i--) { if (bitVectBitValue (rs_mask, i)) @@ -2452,7 +2412,7 @@ static void unsavermask(bitVect *rs_mask) bool bits_popped = FALSE; for (i = ds390_nRegs; i >= 0; i--) { - if (bitVectBitValue (rs_mask, i)) + if (bitVectBitValue (rs_mask, i)) { bits_popped = popReg (i, bits_popped); } @@ -2507,8 +2467,8 @@ pushSide (operand * oper, int size) } else { - emitcode ("push", "%s", l); - } + emitcode ("push", "%s", l); + } } _endLazyDPSEvaluation (); } @@ -2729,28 +2689,28 @@ saveRBank (int bank, iCode * ic, bool pushPsw) regs *r = NULL; if (options.useXstack) - { + { if (!ic) - { + { /* Assume r0 is available for use. */ r = REG_WITH_INDEX (R0_IDX);; - } + } else - { + { aop = newAsmop (0); r = getFreePtr (ic, &aop, FALSE); - } + } // allocate space first emitcode ("mov", "%s,_spx", r->name); MOVA (r->name); emitcode ("add", "a,#%d", count); emitcode ("mov", "_spx,a"); - } + } for (i = 0; i < 8; i++) /* only R0-R7 needs saving */ { if (options.useXstack) - { + { emitcode ("mov", "a,(%s+%d)", regs390[i].base, 8 * bank + regs390[i].offset); emitcode ("movx", "@%s,a", r->name); @@ -2788,15 +2748,15 @@ saveRBank (int bank, iCode * ic, bool pushPsw) else { emitcode ("push", "psw"); - } + } emitcode ("mov", "psw,#!constbyte", (bank << 3) & 0x00ff); } if (aop) - { + { freeAsmop (NULL, aop, ic, TRUE); - } + } if (ic) { @@ -2816,17 +2776,17 @@ unsaveRBank (int bank, iCode * ic, bool popPsw) if (options.useXstack) { - if (!ic) + if (!ic) { /* Assume r0 is available for use. */ r = REG_WITH_INDEX (R0_IDX);; } - else + else { aop = newAsmop (0); r = getFreePtr (ic, &aop, FALSE); } - emitcode ("mov", "%s,_spx", r->name); + emitcode ("mov", "%s,_spx", r->name); } if (popPsw) @@ -2869,7 +2829,7 @@ unsaveRBank (int bank, iCode * ic, bool popPsw) else { emitcode ("pop", "(%s+%d)", - regs390[i].base, 8 * bank + regs390[i].offset); + regs390[i].base, 8 * bank + regs390[i].offset); } } @@ -2879,9 +2839,9 @@ unsaveRBank (int bank, iCode * ic, bool popPsw) } if (aop) - { - freeAsmop (NULL, aop, ic, TRUE); - } + { + freeAsmop (NULL, aop, ic, TRUE); + } } /*-----------------------------------------------------------------*/ @@ -2889,13 +2849,13 @@ unsaveRBank (int bank, iCode * ic, bool popPsw) /*-----------------------------------------------------------------*/ static void genSend(set *sendSet) { - iCode *sic; + iCode *sic; int bit_count = 0; - int sendCount = 0 ; - static int rb1_count = 0; + int sendCount = 0 ; + static int rb1_count = 0; /* first we do all bit parameters */ - for (sic = setFirstItem (sendSet); sic; + for (sic = setFirstItem (sendSet); sic; sic = setNextItem (sendSet)) { if (sic->argreg > 12) @@ -2968,9 +2928,9 @@ static void genSend(set *sendSet) if (strcmp (l, fReturn[offset])) { emitcode ("mov", "%s,%s", fReturn[offset], l); - } + } offset++; - } + } _endLazyDPSEvaluation (); freeAsmop (IC_LEFT (sic), NULL, sic, TRUE); rb1_count =0; @@ -3055,8 +3015,8 @@ genCall (iCode * ic) swapBanks = TRUE; } - /* if caller saves & we have not saved then */ - if (!ic->regsSaved) + /* if caller saves & we have not saved then */ + if (!ic->regsSaved) saveRegisters (ic); /* if send set is not empty then assign */ @@ -3076,10 +3036,10 @@ genCall (iCode * ic) } if (swapBanks) - { - emitcode ("mov", "psw,#!constbyte", - ((FUNC_REGBANK(dtype)) << 3) & 0xff); - } + { + emitcode ("mov", "psw,#!constbyte", + ((FUNC_REGBANK(dtype)) << 3) & 0xff); + } /* make the call */ emitcode ("lcall", "%s", (OP_SYMBOL (IC_LEFT (ic))->rname[0] ? @@ -3170,13 +3130,13 @@ genCall (iCode * ic) emitcode ("push", "acc"); accPushed = TRUE; } - if (IS_BIT (OP_SYM_ETYPE (IC_LEFT (ic))) && - IS_BIT (OP_SYM_ETYPE (IC_RESULT (ic))) && - !assignResultGenerated) - { - emitcode ("mov", "F0,c"); - resultInF0 = TRUE; - } + if (IS_BIT (OP_SYM_ETYPE (IC_LEFT (ic))) && + IS_BIT (OP_SYM_ETYPE (IC_RESULT (ic))) && + !assignResultGenerated) + { + emitcode ("mov", "F0,c"); + resultInF0 = TRUE; + } emitcode ("mov", "a,%s", spname); emitcode ("add", "a,#!constbyte", (-ic->parmBytes) & 0xff); @@ -3345,7 +3305,7 @@ genPcall (iCode * ic) emitcode ("mov", "a,%s", spname); emitcode ("add", "a,#!constbyte", (-ic->parmBytes) & 0xff); emitcode ("mov", "%s,a", spname); - } + } else for (i = 0; i < ic->parmBytes; i++) emitcode ("dec", "%s", spname); @@ -3424,7 +3384,7 @@ genFunction (iCode * ic) { symbol *sym = OP_SYMBOL (IC_LEFT (ic)); sym_link *ftype; - bool switchedPSW = FALSE; + bool switchedPSW = FALSE; bool fReentrant = (IFFUNC_ISREENT (sym->type) || options.stackAuto); D (emitcode (";", "genFunction")); @@ -3832,7 +3792,7 @@ genEndFunction (iCode * ic) } if (IFFUNC_ISISR (sym->type)) - { /* is ISR */ + { /* is ISR */ /* now we need to restore the registers */ /* if this isr has no bank i.e. is going to @@ -3840,7 +3800,7 @@ genEndFunction (iCode * ic) registers :-) */ if (!FUNC_REGBANK (sym->type)) { - int i; + int i; /* if this function does not call any other function then we can be economical and save only those registers that are used */ @@ -3871,7 +3831,7 @@ genEndFunction (iCode * ic) unsaveRBank (0, ic, FALSE); } } - else + else { /* This ISR uses a non-zero bank. * @@ -5068,9 +5028,9 @@ addSign (operand * result, int offset, int sign) emitcode ("rlc", "a"); emitcode ("subb", "a,acc"); while (size--) - { - aopPut (result, "a", offset++); - } + { + aopPut (result, "a", offset++); + } } else { @@ -7314,9 +7274,9 @@ genAnd (iCode * ic, iCode * ifx) genIfxJump (ifx, buffer); } else - { - emitcode ("anl","a,#!constbyte",1 << (posbit & 0x07)); - } + { + emitcode ("anl","a,#!constbyte",1 << (posbit & 0x07)); + } goto release; } } @@ -7399,20 +7359,34 @@ genAnd (iCode * ic, iCode * ifx) else { if (AOP_TYPE (left) == AOP_ACC) - emitcode ("anl", "a,%s", - aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); + { + if (offset) + emitcode("mov", "a,b"); + emitcode ("anl", "a,%s", aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); + } + else if (aopGetUsesAcc (left, offset) && aopGetUsesAcc (right, offset)) + { + MOVB (aopGet (left, offset, FALSE, FALSE, NULL)); + MOVA (aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); + emitcode ("anl", "a,b"); + aopPut (result, "a", offset); + } + else if (aopGetUsesAcc (left, offset)) + { + MOVA (aopGet (left, offset, FALSE, FALSE, NULL)); + emitcode ("anl", "a,%s", aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); + aopPut (result, "a", offset); + } else { MOVA (aopGet (right, offset, FALSE, FALSE, NULL)); if (IS_AOP_PREG (result)) { - emitcode ("anl", "a,%s", - aopGet (left, offset, FALSE, TRUE, DP2_RESULT_REG)); + emitcode ("anl", "a,%s", aopGet (left, offset, FALSE, TRUE, DP2_RESULT_REG)); aopPut (result, "a", offset); } else - emitcode ("anl", "%s,a", - aopGet (left, offset, FALSE, TRUE, DP2_RESULT_REG)); + emitcode ("anl", "%s,a", aopGet (left, offset, FALSE, TRUE, DP2_RESULT_REG)); } } } @@ -7431,25 +7405,46 @@ genAnd (iCode * ic, iCode * ifx) emitcode ("setb", "c"); while (sizer--) { - if (AOP_TYPE(right)==AOP_REG && AOP_TYPE(left)==AOP_ACC) { - emitcode ("anl", "a,%s", - aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); - } else { - if (AOP_TYPE(left)==AOP_ACC) + if ((AOP_TYPE(right)==AOP_REG || IS_AOP_PREG(right) || AOP_TYPE(right)==AOP_DIR) + && AOP_TYPE(left)==AOP_ACC) { - bool pushedB = pushB (); - emitcode("mov", "b,a"); - MOVA (aopGet (right, offset, FALSE, FALSE, NULL)); - emitcode("anl", "a,b"); - popB (pushedB); + if (offset) + emitcode("mov", "a,b"); + emitcode ("anl", "a,%s", aopGet (right, offset, FALSE, FALSE, NULL)); } - else + else if (AOP_TYPE(left)==AOP_ACC) + { + if (!offset) + { + bool pushedB = pushB (); + emitcode("mov", "b,a"); + MOVA (aopGet (right, offset, FALSE, FALSE, NULL)); + emitcode("anl", "a,b"); + popB (pushedB); + } + else + { + MOVA (aopGet (right, offset, FALSE, FALSE, NULL)); + emitcode("anl", "a,b"); + } + } + else if (aopGetUsesAcc (left, offset) && aopGetUsesAcc (right, offset)) + { + emitcode ("mov", "b,%s", aopGet (left, offset, FALSE, FALSE, NULL)); + MOVA (aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); + emitcode ("anl", "a,b"); + } + else if (aopGetUsesAcc (left, offset)) + { + MOVA (aopGet (left, offset, FALSE, FALSE, NULL)); + emitcode ("anl", "a,%s", aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); + } + else { MOVA (aopGet (right, offset, FALSE, FALSE, NULL)); - emitcode ("anl", "a,%s", - aopGet (left, offset, FALSE, FALSE, DP2_RESULT_REG)); + emitcode ("anl", "a,%s", aopGet (left, offset, FALSE, FALSE, DP2_RESULT_REG)); } - } + emitcode ("jnz", "!tlabel", tlbl->key + 100); offset++; } @@ -7488,34 +7483,63 @@ genAnd (iCode * ic, iCode * ifx) aopPut (result, zero, offset); continue; } - D (emitcode (";", "better literal AND.")); - MOVA (aopGet (left, offset, FALSE, FALSE, NULL)); - emitcode ("anl", "a, %s", aopGet (right, offset, - FALSE, FALSE, DP2_RESULT_REG)); - + else if (AOP_TYPE (left) == AOP_ACC) + { + if (!offset) + { + emitcode ("anl", "a,%s", aopGet (right, offset, FALSE, FALSE, NULL)); + aopPut (result, "a", offset); + continue; + } + else + { + emitcode ("anl", "b,%s", aopGet (right, offset, FALSE, FALSE, NULL)); + aopPut (result, "b", offset); + continue; + } + } } - else + // faster than result <- left, anl result,right + // and better if result is SFR + if ((AOP_TYPE(right)==AOP_REG || IS_AOP_PREG(right) || AOP_TYPE(right)==AOP_DIR) + && AOP_TYPE(left)==AOP_ACC) { - // faster than result <- left, anl result,right - // and better if result is SFR - if (AOP_TYPE (left) == AOP_ACC) + if (offset) + emitcode("mov", "a,b"); + emitcode ("anl", "a,%s", aopGet (right, offset, FALSE, FALSE, NULL)); + } + else if (AOP_TYPE(left)==AOP_ACC) + { + if (!offset) { - emitcode ("anl", "a,%s", - aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); + bool pushedB = pushB (); + emitcode("mov", "b,a"); + MOVA (aopGet (right, offset, FALSE, FALSE, NULL)); + emitcode("anl", "a,b"); + popB (pushedB); } else { - char *rOp = aopGet (right, offset, FALSE, FALSE, NULL); - if (!strcmp(rOp, "a") || !strcmp(rOp, "acc")) - { - emitcode("mov", "b,a"); - rOp = "b"; - } - - MOVA (aopGet (left, offset, FALSE, FALSE, NULL)); - emitcode ("anl", "a,%s", rOp); + MOVA (aopGet (right, offset, FALSE, FALSE, NULL)); + emitcode("anl", "a,b"); } } + else if (aopGetUsesAcc (left, offset) && aopGetUsesAcc (right, offset)) + { + MOVB (aopGet (left, offset, FALSE, FALSE, NULL)); + MOVA (aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); + emitcode ("anl", "a,b"); + } + else if (aopGetUsesAcc (left, offset)) + { + MOVA (aopGet (left, offset, FALSE, FALSE, NULL)); + emitcode ("anl", "a,%s", aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); + } + else + { + MOVA (aopGet (right, offset, FALSE, FALSE, NULL)); + emitcode ("anl", "a,%s", aopGet (left, offset, FALSE, FALSE, DP2_RESULT_REG)); + } aopPut (result, "a", offset); } } @@ -7737,8 +7761,22 @@ genOr (iCode * ic, iCode * ifx) { if (AOP_TYPE (left) == AOP_ACC) { - emitcode ("orl", "a,%s", - aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); + if (offset) + emitcode("mov", "a,b"); + emitcode ("orl", "a,%s", aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); + } + else if (aopGetUsesAcc (left, offset) && aopGetUsesAcc (right, offset)) + { + emitcode ("mov", "b,%s", aopGet (left, offset, FALSE, FALSE, NULL)); + MOVA (aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); + emitcode ("orl", "a,b"); + aopPut (result, "a", offset); + } + else if (aopGetUsesAcc (left, offset)) + { + MOVA (aopGet (left, offset, FALSE, FALSE, NULL)); + emitcode ("orl", "a,%s", aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); + aopPut (result, "a", offset); } else { @@ -7772,14 +7810,46 @@ genOr (iCode * ic, iCode * ifx) emitcode ("setb", "c"); while (sizer--) { - if (AOP_TYPE(right)==AOP_REG && AOP_TYPE(left)==AOP_ACC) { - emitcode ("orl", "a,%s", - aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); - } else { - MOVA (aopGet (right, offset, FALSE, FALSE, NULL)); - emitcode ("orl", "a,%s", - aopGet (left, offset, FALSE, FALSE, DP2_RESULT_REG)); + if ((AOP_TYPE(right)==AOP_REG || IS_AOP_PREG(right) || AOP_TYPE(right)==AOP_DIR) + && AOP_TYPE(left)==AOP_ACC) + { + if (offset) + emitcode("mov", "a,b"); + emitcode ("orl", "a,%s", aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); + } + else if (AOP_TYPE(left)==AOP_ACC) + { + if (!offset) + { + bool pushedB = pushB (); + emitcode("mov", "b,a"); + MOVA (aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); + emitcode("orl", "a,b"); + popB (pushedB); + } + else + { + MOVA (aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); + emitcode("orl", "a,b"); + } + } + else if (aopGetUsesAcc (left, offset) && aopGetUsesAcc (right, offset)) + { + MOVB (aopGet (left, offset, FALSE, FALSE, NULL)); + MOVA (aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); + emitcode ("orl", "a,b"); + } + else if (aopGetUsesAcc (left, offset)) + { + MOVA (aopGet (left, offset, FALSE, FALSE, NULL)); + emitcode ("orl", "a,%s", aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); + } + else + { + MOVA (aopGet (right, offset, FALSE, FALSE, NULL)); + emitcode ("orl", "a,%s", aopGet (left, offset, FALSE, FALSE, DP2_RESULT_REG)); } + emitcode ("jnz", "!tlabel", tlbl->key + 100); offset++; } @@ -7819,37 +7889,48 @@ genOr (iCode * ic, iCode * ifx) aopPut (result, "#0xFF", offset); continue; } - D (emitcode (";", "better literal OR.")); - MOVA (aopGet (left, offset, FALSE, FALSE, NULL)); - emitcode ("orl", "a, %s", - aopGet (right, offset, - FALSE, FALSE, DP2_RESULT_REG)); - } - else + // faster than result <- left, orl result,right + // and better if result is SFR + if ((AOP_TYPE(right)==AOP_REG || IS_AOP_PREG(right) || AOP_TYPE(right)==AOP_DIR) + && AOP_TYPE(left)==AOP_ACC) { - // faster than result <- left, anl result,right - // and better if result is SFR - if (AOP_TYPE (left) == AOP_ACC) + if (offset) + emitcode("mov", "a,b"); + emitcode ("orl", "a,%s", aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); + } + else if (AOP_TYPE(left)==AOP_ACC) + { + if (!offset) { - emitcode ("orl", "a,%s", - aopGet (right, offset, - FALSE, FALSE, DP2_RESULT_REG)); + bool pushedB = pushB (); + emitcode("mov", "b,a"); + MOVA (aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); + emitcode("orl", "a,b"); + popB (pushedB); } else { - char *rOp = aopGet (right, offset, FALSE, FALSE, NULL); - - if (!strcmp(rOp, "a") || !strcmp(rOp, "acc")) - { - emitcode("mov", "b,a"); - rOp = "b"; - } - - MOVA (aopGet (left, offset, FALSE, FALSE, NULL)); - emitcode ("orl", "a,%s", rOp); + MOVA (aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); + emitcode("orl", "a,b"); } } + else if (aopGetUsesAcc (left, offset) && aopGetUsesAcc (right, offset)) + { + MOVB (aopGet (left, offset, FALSE, FALSE, NULL)); + MOVA (aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); + emitcode ("orl", "a,b"); + } + else if (aopGetUsesAcc (left, offset)) + { + MOVA (aopGet (left, offset, FALSE, FALSE, NULL)); + emitcode ("orl", "a,%s", aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); + } + else + { + MOVA (aopGet (right, offset, FALSE, FALSE, NULL)); + emitcode ("orl", "a,%s", aopGet (left, offset, FALSE, FALSE, DP2_RESULT_REG)); + } aopPut (result, "a", offset); } _endLazyDPSEvaluation(); @@ -7973,7 +8054,6 @@ genXor (iCode * ic, iCode * ifx) } } } - } else { @@ -8049,8 +8129,24 @@ genXor (iCode * ic, iCode * ifx) else { if (AOP_TYPE (left) == AOP_ACC) - emitcode ("xrl", "a,%s", - aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); + { + if (offset) + emitcode("mov", "a,b"); + emitcode ("xrl", "a,%s", aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); + } + else if (aopGetUsesAcc (left, offset) && aopGetUsesAcc (right, offset)) + { + MOVB (aopGet (left, offset, FALSE, FALSE, NULL)); + MOVA (aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); + emitcode ("xrl", "a,b"); + aopPut (result, "a", offset); + } + else if (aopGetUsesAcc (left, offset)) + { + MOVA (aopGet (left, offset, FALSE, FALSE, NULL)); + emitcode ("xrl", "a,%s", aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); + aopPut (result, "a", offset); + } else { MOVA (aopGet (right, offset, FALSE, FALSE, NULL)); @@ -8087,23 +8183,46 @@ genXor (iCode * ic, iCode * ifx) { MOVA (aopGet (left, offset, FALSE, FALSE, NULL)); } + else if ((AOP_TYPE(right)==AOP_REG || IS_AOP_PREG(right) || AOP_TYPE(right)==AOP_DIR) + && AOP_TYPE(left)==AOP_ACC) + { + if (offset) + emitcode("mov", "a,b"); + emitcode ("xrl", "a,%s", aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); + } + else if (AOP_TYPE(left)==AOP_ACC) + { + if (!offset) + { + bool pushedB = pushB (); + emitcode("mov", "b,a"); + MOVA (aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); + emitcode("xrl", "a,b"); + popB (pushedB); + } + else + { + MOVA (aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); + emitcode("xrl", "a,b"); + } + } + else if (aopGetUsesAcc (left, offset) && aopGetUsesAcc (right, offset)) + { + MOVB (aopGet (left, offset, FALSE, FALSE, NULL)); + MOVA (aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); + emitcode ("xrl", "a,b"); + } + else if (aopGetUsesAcc (left, offset)) + { + MOVA (aopGet (left, offset, FALSE, FALSE, NULL)); + emitcode ("xrl", "a,%s", aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); + } else { - if (AOP_TYPE(right)==AOP_REG && AOP_TYPE(left)==AOP_ACC) { - emitcode ("xrl", "a,%s", - aopGet (right, offset, FALSE, FALSE, DP2_RESULT_REG)); - } else { - char *rOp = aopGet (right, offset, FALSE, FALSE, NULL); - if (!strcmp(rOp, "a") || !strcmp(rOp, "acc")) - { - emitcode("mov", "b,a"); - rOp = "b"; - } - - MOVA (aopGet (left, offset, FALSE, FALSE, NULL)); - emitcode ("xrl", "a,%s", rOp); - } + MOVA (aopGet (right, offset, FALSE, FALSE, NULL)); + emitcode ("xrl", "a,%s", aopGet (left, offset, FALSE, TRUE, DP2_RESULT_REG)); } + emitcode ("jnz", "!tlabel", tlbl->key + 100); offset++; } @@ -8598,9 +8717,9 @@ movLeft2Result (operand * left, int offl, else { if (!sign) - { - aopPut (result, l, offr); - } + { + aopPut (result, l, offr); + } else { /* MSB sign in acc.7 ! */ @@ -9167,7 +9286,7 @@ genlshTwo (operand * result, operand * left, int shCount) shiftL1Left2Result (left, LSB, result, LSB, shCount); else shiftL2Left2Result (left, LSB, result, LSB, shCount); - } + } } #endif @@ -9626,12 +9745,13 @@ static void shiftRLong (operand * left, int offl, operand * result, int sign) { - int isSameRegs=sameRegs(AOP(left),AOP(result)); + bool overlapping = regsInCommon (left, result) || operandsEqu(left, result); - if (isSameRegs && offl>1) { - // we are in big trouble, but this shouldn't happen - werror(E_INTERNAL_ERROR, __FILE__, __LINE__); - } + if (overlapping && offl>1) + { + // we are in big trouble, but this shouldn't happen + werror(E_INTERNAL_ERROR, __FILE__, __LINE__); + } MOVA (aopGet (left, MSB32, FALSE, FALSE, NULL)); @@ -9662,28 +9782,44 @@ shiftRLong (operand * left, int offl, emitcode ("rrc", "a"); - if (isSameRegs && offl==MSB16) { - emitcode ("xch", - "a,%s",aopGet (left, MSB24, FALSE, FALSE, DP2_RESULT_REG)); - } else { - aopPut (result, "a", MSB32); - MOVA (aopGet (left, MSB24, FALSE, FALSE, NULL)); - } + if (overlapping && offl==MSB16) + { + emitcode ("xch", "a,%s", aopGet (left, MSB24, FALSE, FALSE, DP2_RESULT_REG)); + } + else + { + aopPut (result, "a", MSB32 - offl); + MOVA (aopGet (left, MSB24, FALSE, FALSE, NULL)); + } emitcode ("rrc", "a"); - if (isSameRegs && offl==1) { - emitcode ("xch", "a,%s", - aopGet (left, MSB16, FALSE, FALSE, DP2_RESULT_REG)); - } else { - aopPut (result, "a", MSB24); - MOVA (aopGet (left, MSB16, FALSE, FALSE, NULL)); - } - emitcode ("rrc", "a"); - aopPut (result, "a", MSB16 - offl); - if (offl == LSB) + if (overlapping && offl==MSB16) { - MOVA (aopGet (left, LSB, FALSE, FALSE, NULL)); + emitcode ("xch", "a,%s", aopGet (left, MSB16, FALSE, FALSE, DP2_RESULT_REG)); + } + else + { + aopPut (result, "a", MSB24 - offl); + MOVA (aopGet (left, MSB16, FALSE, FALSE, NULL)); + } + + emitcode ("rrc", "a"); + if (offl != LSB) + { + aopPut (result, "a", MSB16 - offl); + } + else + { + if (overlapping && offl==MSB16) + { + emitcode ("xch", "a,%s", aopGet (left, LSB, FALSE, FALSE, DP2_RESULT_REG)); + } + else + { + aopPut (result, "a", MSB16 - offl); + MOVA (aopGet (left, LSB, FALSE, FALSE, NULL)); + } emitcode ("rrc", "a"); aopPut (result, "a", LSB); } @@ -10415,9 +10551,9 @@ genNearPointerGet (operand * left, } offset++; if (size || pi) - emitcode ("inc", "%s", rname); - } + emitcode ("inc", "%s", rname); } + } /* now some housekeeping stuff */ if (aop) /* we had to allocate for this iCode */ @@ -10548,7 +10684,7 @@ static void genFarPointerGet (operand * left, operand * result, iCode * ic, iCode *pi) { - int size, offset, dopi=1; + int size, offset, dopi=1; sym_link *retype = getSpec (operandType (result)); sym_link *letype = getSpec (operandType (left)); D (emitcode (";", "genFarPointerGet");); @@ -10665,7 +10801,7 @@ genFarPointerGet (operand * left, } /*-----------------------------------------------------------------*/ -/* genCodePointerGet - get value from code space */ +/* genCodePointerGet - get value from code space */ /*-----------------------------------------------------------------*/ static void genCodePointerGet (operand * left, @@ -10768,7 +10904,8 @@ genCodePointerGet (operand * left, _endLazyDPSEvaluation (); } pi->generated = 1; - } else if ((OP_SYMBOL(left)->ruonly || AOP_INDPTRn(left)) && + } else if (IS_SYMOP(left) && + (OP_SYMBOL(left)->ruonly || AOP_INDPTRn(left)) && AOP_SIZE(result) > 1 && (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) { @@ -11666,11 +11803,11 @@ genIfx (iCode * ic, iCode * popIc) /* get the value into acc */ if (AOP_TYPE (cond) != AOP_CRY) { - toBoolean (cond); + toBoolean (cond); } else { - isbit = 1; + isbit = 1; if (AOP(cond)->aopu.aop_dir) dup = Safe_strdup(AOP(cond)->aopu.aop_dir); } @@ -11682,7 +11819,7 @@ genIfx (iCode * ic, iCode * popIc) if (popIc) genIpop (popIc); - /* if the condition is a bit variable */ + /* if the condition is a bit variable */ if (isbit && dup) genIfxJump (ic, dup); else if (isbit && IS_ITEMP (cond) && SPIL_LOC (cond)) @@ -11779,7 +11916,7 @@ genAddrOf (iCode * ic) while (size--) { aopPut (IC_RESULT (ic), zero, offset++); - } + } } goto release; } @@ -13299,9 +13436,9 @@ static void genMMDeref (iCode *ic,int nparms, operand **parms) if (AOP_TYPE(IC_RESULT(ic)) != AOP_STR) { _startLazyDPSEvaluation (); - aopPut(IC_RESULT(ic),"dpl",0); - aopPut(IC_RESULT(ic),"dph",1); - aopPut(IC_RESULT(ic),"dpx",2); + aopPut(IC_RESULT(ic),"dpl",0); + aopPut(IC_RESULT(ic),"dph",1); + aopPut(IC_RESULT(ic),"dpx",2); _endLazyDPSEvaluation ();