+ else
+ {
+ /* This ISR uses a non-zero bank.
+ *
+ * We assume that the bank is available for our
+ * exclusive use.
+ *
+ * However, if this ISR calls a function which uses some
+ * other bank, we must save that bank entirely.
+ */
+ unsigned long banksToSave = 0;
+
+ if (sym->hasFcall)
+ {
+
+#define MAX_REGISTER_BANKS 4
+
+ iCode *i;
+ int ix;
+
+ for (i = ic; i; i = i->next)
+ {
+ if (i->op == ENDFUNCTION)
+ {
+ /* we got to the end OK. */
+ break;
+ }
+
+ if (i->op == CALL)
+ {
+ sym_link *detype;
+
+ detype = getSpec(operandType (IC_LEFT(i)));
+ if (detype
+ && SPEC_BANK(detype) != SPEC_BANK(sym->etype))
+ {
+ /* Mark this bank for saving. */
+ if (SPEC_BANK(detype) >= MAX_REGISTER_BANKS)
+ {
+ werror(E_NO_SUCH_BANK, SPEC_BANK(detype));
+ }
+ else
+ {
+ banksToSave |= (1 << SPEC_BANK(detype));
+ }
+
+ /* And note that we don't need to do it in
+ * genCall.
+ */
+ i->bankSaved = 1;
+ }
+ }
+ if (i->op == PCALL)
+ {
+ /* This is a mess; we have no idea what
+ * register bank the called function might
+ * use.
+ *
+ * The only thing I can think of to do is
+ * throw a warning and hope.
+ */
+ werror(W_FUNCPTR_IN_USING_ISR);
+ }
+ }
+
+ for (ix = 0; ix < MAX_REGISTER_BANKS; ix++)
+ {
+ if (banksToSave & (1 << ix))
+ {
+ saveRBank(ix, NULL, FALSE);
+ }
+ }
+ }
+ SPEC_ISR_SAVED_BANKS(currFunc->etype) = banksToSave;
+ }