-/* If the register is a fixed known addess then we can assign the */
-/* bank selection bits. Otherwise the linker is going to assign */
-/* the register location and thus has to set bank selection bits */
-/* through the banksel directive. */
-/* One critical assumption here is that within this C module all */
-/* the locally allocated registers are in the same udata sector. */
-/* Therefore banksel is only called for external registers or the */
-/* first time a local register is encountered. */
-/*-----------------------------------------------------------------*/
-static int LastRegIdx = -1; /* If the previous register is the same one again then no need to change bank. */
-static int BankSelect(pCodeInstruction *pci, int cur_bank, regs *reg)
-{
-#if 1
- /* Always insert BANKSELs rather than try to be clever:
- * Too many bugs in optimized banksels... */
- static PIC_device *pic;
- if (!pic) pic = pic14_getPIC();
-
- // possible optimizations:
- // * do not emit BANKSELs for SFRs that are present in all banks (bankmsk == regmap for this register)
- if (reg && pic && ((reg->alias & pic->bankMask) == pic->bankMask)) return 'L';
-
- insertBankSel(pci, reg->name); // Let linker choose the bank selection
- return 'L';
-#else
- int bank;
- int a = reg->alias>>7;
- if ((a&3) == 3) {
- return cur_bank; // This register is available in all banks
- } else if ((a&1)&&((cur_bank==0)||(cur_bank==1))) {
- return cur_bank; // This register is available in banks 0 & 1
- } else if (a&2) {
- if (reg->address&0x80) {
- if ((cur_bank==1)||(cur_bank==3)) {
- return cur_bank; // This register is available in banks 1 & 3
- }
- } else {
- if ((cur_bank==0)||(cur_bank==1)) {
- return cur_bank; // This register is available in banks 0 & 2
- }
- }
- }
-
-#if 1
- if (LastRegIdx == reg->rIdx) // If this is the same register as last time then it is in same bank
- return cur_bank;
- LastRegIdx = reg->rIdx;
-#endif
-
- /* Optimized code---unfortunately this turns out to be buggy
- * (at least on devices with more than two banks). */
- if (reg->isFixed) {
- bank = REG_BANK(reg);
- } else if (reg->isExtern) {
- bank = 'E'; // Unfixed extern registers are allocated by the linker therefore its bank is unknown
- } else {
- bank = 'L'; // Unfixed local registers are allocated by the linker therefore its bank is unknown
- }
- if (bank == 'E' || bank == 'L') { // Reg is now extern and linker to assign bank
- insertBankSel(pci, reg->name); // Let linker choose the bank selection
- } else if ((cur_bank == -1)||(cur_bank == 'L')||(cur_bank == 'E')) { // Current bank unknown and new register bank is known then can set bank bits
- insertBankSwitch(pci, bank&1, PIC_RP0_BIT);
- if (pic14_getMaxRam()&0x100)
- insertBankSwitch(pci, bank&2, PIC_RP1_BIT);
- } else { // Current bank and new register banks known - can set bank bits
- switch((cur_bank^bank) & 3) {
- case 0:
- break;
- case 1:
- insertBankSwitch(pci, bank&1, PIC_RP0_BIT);
- break;
- case 2:
- insertBankSwitch(pci, bank&2, PIC_RP1_BIT);
- break;
- case 3:
- insertBankSwitch(pci, bank&1, PIC_RP0_BIT);
- if (pic14_getMaxRam()&0x100)
- insertBankSwitch(pci, bank&2, PIC_RP1_BIT);
- break;
- }
- }
-
- return bank;
-#endif
-}
-
-/*-----------------------------------------------------------------*/
-/* Check for bank selection pcodes instructions and modify */
-/* cur_bank to match. */