-/*-----------------------------------------------------------------*/
-/* Check for bank selection pcodes instructions and modify */
-/* cur_bank to match. */
-/*-----------------------------------------------------------------*/
-static int IsBankChange(pCode *pc, regs *reg, int *cur_bank) {
-
- if (isSTATUS_REG(reg)) {
-
- if (PCI(pc)->op == POC_BCF) {
- int old_bank = *cur_bank;
- if (PCORB(PCI(pc)->pcop)->bit == PIC_RP0_BIT) {
- /* If current bank is unknown or linker assigned then set to 0 else just change the bit */
- if (*cur_bank & ~(0x3))
- *cur_bank = 0;
- else
- *cur_bank = *cur_bank&0x2;
- LastRegIdx = reg->rIdx;
- } else if (PCORB(PCI(pc)->pcop)->bit == PIC_RP1_BIT) {
- /* If current bank is unknown or linker assigned then set to 0 else just change the bit */
- if (*cur_bank & ~(0x3))
- *cur_bank = 0;
- else
- *cur_bank = *cur_bank&0x1;
- LastRegIdx = reg->rIdx;
- }
- return old_bank != *cur_bank;
- }
-
- if (PCI(pc)->op == POC_BSF) {
- int old_bank = *cur_bank;
- if (PCORB(PCI(pc)->pcop)->bit == PIC_RP0_BIT) {
- /* If current bank is unknown or linker assigned then set to bit else just change the bit */
- if (*cur_bank & ~(0x3))
- *cur_bank = 0x1;
- else
- *cur_bank = (*cur_bank&0x2) | 0x1;
- LastRegIdx = reg->rIdx;
- } else if (PCORB(PCI(pc)->pcop)->bit == PIC_RP1_BIT) {
- /* If current bank is unknown or linker assigned then set to bit else just change the bit */
- if (*cur_bank & ~(0x3))
- *cur_bank = 0x2;
- else
- *cur_bank = (*cur_bank&0x1) | 0x2;
- LastRegIdx = reg->rIdx;
- }
- return old_bank != *cur_bank;
- }
-
- } else if (PCI(pc)->op == POC_BANKSEL) {
- int old_bank = *cur_bank;
- *cur_bank = (PCOR(PCI(pc)->pcop)->r->isExtern) ? 'E' : 'L';
- LastRegIdx = reg->rIdx;
- return old_bank != *cur_bank;
- }
-
- return 0;
-}
-
-/*-----------------------------------------------------------------*/
-/* Set bank selection if necessary */
-/*-----------------------------------------------------------------*/
-static int DoBankSelect(pCode *pc, int cur_bank) {
- pCode *pcprev;
- regs *reg;
-
- if(!isPCI(pc))
- return cur_bank;
-
- if (isCALL(pc)) {
- pCode *pcf = findFunction(get_op_from_instruction(PCI(pc)));
- if (pcf && isPCF(pcf)) {
- pCode *pcfr;
- int rbank = 'U'; // Undetermined
- FixRegisterBanking(pcf->pb,cur_bank); // Ensure this block has had its banks selection done
- // Check all the returns to work out what bank is selected
- for (pcfr=pcf->pb->pcHead; pcfr; pcfr=pcfr->next) {
- if (isPCI(pcfr)) {
- if ((PCI(pcfr)->op==POC_RETURN) || (PCI(pcfr)->op==POC_RETLW)) {
- if (rbank == 'U')
- rbank = PCFL(pcfr)->lastBank;
- else
- if (rbank != PCFL(pcfr)->lastBank)
- return -1; // Unknown bank - multiple returns with different banks
- }
- }
- }
- if (rbank == 'U')
- return -1; // Unknown bank
- return rbank;
- } else if (isPCOS(PCI(pc)->pcop) && PCOS(PCI(pc)->pcop)->isPublic) {
- /* Extern functions may use registers in different bank - must call banksel */
- return -1; /* Unknown bank */
- }
- }
-
- if ((isPCI(pc)) && (PCI(pc)->op == POC_BANKSEL)) {
- return -1; /* New bank unknown - linkers choice. */
- }
-
- reg = getRegFromInstruction(pc);
- if (reg) {
-
- if (IsBankChange(pc,reg,&cur_bank))
- return cur_bank;
-
- if (!isPCI_LIT(pc)) {
-
- /* Examine the instruction before this one to make sure it is
- * not a skip type instruction */
- pcprev = findPrevpCode(pc->prev, PC_OPCODE);
-
- if(!pcprev || (pcprev && !isPCI_SKIP(pcprev))) {
- cur_bank = BankSelect(PCI(pc),cur_bank,reg);
- } else {
- cur_bank = BankSelect(PCI(pcprev),cur_bank,reg);
- }
- if (!PCI(pc)->pcflow)
- fprintf(stderr,"PCI ID=%d missing flow pointer ???\n",pc->id);
- else
- PCI(pc)->pcflow->lastBank = cur_bank; /* Maintain pCodeFlow lastBank state */
+ /* Arrrrg: is pci's previous instruction is a skip, we need to
+ * change that into a jump (over pci and the new instruction) ... */
+ if (pcprev && isPCI_SKIP(pcprev))
+ {
+ symbol *lbl = newiTempLabel (NULL);
+ pCode *label = newpCodeLabel (NULL, lbl->key);
+ pCode *jump = newpCode(POC_GOTO, newpCodeOpLabel(NULL, lbl->key));
+
+ pCodeInsertAfter (pcprev, jump);
+
+ // Yuck: Cannot simply replace INCFSZ/INCFSZW/DECFSZ/DECFSZW
+ // We replace them with INCF/INCFW/DECF/DECFW followed by 'BTFSS STATUS, Z'
+ switch (PCI(pcprev)->op) {
+ case POC_INCFSZ:
+ case POC_INCFSZW:
+ case POC_DECFSZ:
+ case POC_DECFSZW:
+ // These are turned into non-skipping instructions, so
+ // insert 'BTFSC STATUS, Z' after pcprev
+ pCodeInsertAfter (jump->prev, newpCode(POC_BTFSC, popCopyGPR2Bit(PCOP(&pc_status), PIC_Z_BIT)));
+ break;
+ default:
+ // no special actions required
+ break;