2004-01-06 Vangelis Rokas <vrokas@otenet.gr>
authorvrokas <vrokas@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Mon, 5 Jan 2004 19:45:14 +0000 (19:45 +0000)
committervrokas <vrokas@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Mon, 5 Jan 2004 19:45:14 +0000 (19:45 +0000)
PIC16 port related changes:
* device.c: removed pic16_finalMapping and pic16_finalMappingSize,
added variable stackPos,

* gen.c: genCall, assignResultValue: added support for
pushing/retrieving function parameters to/from stack,
genFunction,genEndFunction: setup stack frame for the
generated function,
genAddrOf: will be changed according to bug 863624

* added files genutils.c and genutils.h which contain gen*
debugged and optimised functions extracted from gen.c

* glue.c: added variable 'externs' which holds extern symbols,
pic16emitRegularMap: is modified to properly handle relocatable
 symbols under the new scheme,
pic16createInterruptVect: is modified
pic16printPublics: is modified to emit 'global' assembler directives,
added pic16_printExterns to print extern symbols,
pic16glue: initializes stack/frame pointer in the beginning of
the assembly output. Temporary hack, will be corrected later,
because gplink yet does not support stack and SDCC does not
yet support a type of crt0.o object to create the final binary.

* Removed many lines that contain 8051 legacy code.
* The code is finally placed under a 'code' directive.
* Added port specific options.

* _process_pragma: simplified since now we do not need *special*
include file to define SFR registers. But a separate header
will be needed. This will be developed later.
* _pic16_parseOptions: added, parses port specific options:
--pgen-banksel, --obanksel=, --pomit-config-words, --pomit-ivt,
--pleave-reset-vector, --penable-stack, --pstack-model, --debug-xtra
--preplace-udata-with=

* _pic16_setDefaultOptions: modified to initialize section names,
but hack is temporarly out of order since it needs improvement.
* _pic16_genAssemblerPreamble: configuration words are emitted by
their address instead of their name. This part is incomplete and
supports only the 18Fxx2 devices. Other devices will emit an error
during assembly since they do not contain the same set of config
registers
* _pic16_genIVT: is modified,

* pcode.c: added definitions for some hardware registers that are needed
for stack support
* added flag is2LitOp and variable pci_magic in pCodeInstruction.
All PCI entries are updated. Now LFSR is supported.
* Removed pic16_pciTRIS is mentioned by mdubuc in source
* added pic16_newpCodeOpLit2 to support instructions with
two literal arguments
* pic16_pCode2str: corrected code that emits assembler instructions
with two literal operands and those that have an access bit modifier
* genericPrint: now PC_ASMDIR pCodes, can emit a label if it exists,
this fixes a bug which caused some labels to be lost, when an
assembler directive was added, i.e. banksel,
* pic16_FixRegisterBanking: improved logic that causes the insertion
of bank switching,
* InlineFunction: functions that are called once, are not any more
inlined. This can be a port option in the future,

* pcode.h: added pCodeOpLit2 and added variable label in pCodeAsmDir

* ralloc.c: added pic16_rel_udata and pic16_fix_udata variables which
hold the corresponding uninitialized symbols,
* pic16_allocProcessorRegister: registers have explicit marked the
accessBank field,
* pic16_allocInternalRegister: registers are explicit marked as
not used,
* pic16_writeUsedRegs: pic16_dynDirectBitRegs was missing from the
processing list, so bit registers were lost,
*

* ralloc.h: added field 'accessBank' and original symbol operand
in register definition,
* removed the field isMapped from register definition,

** Several functions have been removed from various sources:
BanksUsedFlow2,BanksUsedFlow,FixBankFlow,InstructionRegBank,
pic16_addMemRange,pic16_isREGinBank,pic16_dump_map,pic16_dump_cblock
isSFR,validAddress,mapRegister,assignRegister,pic16_assignFixedRegisters
pic16_assignRelocatableRegisters

** others have been introduced:
pic16_areRegsSame,pic16_dump_section,checkAddReg,pic16_groupRegistersInSection
pic16_popGetLit2,pic16_popCombine2,pushw,pushaop

git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3080 4a8a32a2-be11-0410-ad9d-d568d2c75423

19 files changed:
ChangeLog
src/SDCCglobl.h
src/SDCCmain.c
src/pic16/device.c
src/pic16/device.h
src/pic16/gen.c
src/pic16/gen.h
src/pic16/genarith.c
src/pic16/genutils.c [new file with mode: 0644]
src/pic16/genutils.h [new file with mode: 0644]
src/pic16/glue.c
src/pic16/main.c
src/pic16/main.h
src/pic16/pcode.c
src/pic16/pcode.h
src/pic16/pcodepeep.c
src/pic16/pcoderegs.c
src/pic16/ralloc.c
src/pic16/ralloc.h

index 9c015e3584891ced62cda1f9144d5546b475181e..3636cc4b601cab111e4c5b8de75be4e7f83ba04b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,93 @@
+2004-01-06 Vangelis Rokas <vrokas@otenet.gr>
+
+       PIC16 port related changes:
+       * device.c: removed pic16_finalMapping and pic16_finalMappingSize,
+       added variable stackPos,
+
+       * gen.c: genCall, assignResultValue: added support for
+       pushing/retrieving function parameters to/from stack,
+       genFunction,genEndFunction: setup stack frame for the
+       generated function,
+       genAddrOf: will be changed according to bug 863624
+       
+       * added files genutils.c and genutils.h which contain gen*
+       debugged and optimised functions extracted from gen.c
+       
+       * glue.c: added variable 'externs' which holds extern symbols,
+       pic16emitRegularMap: is modified to properly handle relocatable
+        symbols under the new scheme,
+       pic16createInterruptVect: is modified
+       pic16printPublics: is modified to emit 'global' assembler directives,
+       added pic16_printExterns to print extern symbols,
+       pic16glue: initializes stack/frame pointer in the beginning of
+       the assembly output. Temporary hack, will be corrected later,
+       because gplink yet does not support stack and SDCC does not
+       yet support a type of crt0.o object to create the final binary.
+       
+       * Removed many lines that contain 8051 legacy code.
+       * The code is finally placed under a 'code' directive.
+       * Added port specific options.
+       
+       * _process_pragma: simplified since now we do not need *special*
+       include file to define SFR registers. But a separate header
+       will be needed. This will be developed later.
+       * _pic16_parseOptions: added, parses port specific options:
+       --pgen-banksel, --obanksel=, --pomit-config-words, --pomit-ivt,
+       --pleave-reset-vector, --penable-stack, --pstack-model, --debug-xtra
+       --preplace-udata-with=
+       
+       * _pic16_setDefaultOptions: modified to initialize section names,
+       but hack is temporarly out of order since it needs improvement.
+       * _pic16_genAssemblerPreamble: configuration words are emitted by
+       their address instead of their name. This part is incomplete and
+       supports only the 18Fxx2 devices. Other devices will emit an error
+       during assembly since they do not contain the same set of config
+       registers
+       * _pic16_genIVT: is modified,
+       
+       * pcode.c: added definitions for some hardware registers that are needed
+       for stack support
+       * added flag is2LitOp and variable pci_magic in pCodeInstruction.
+       All PCI entries are updated. Now LFSR is supported.
+       * Removed pic16_pciTRIS is mentioned by mdubuc in source
+       * added pic16_newpCodeOpLit2 to support instructions with
+       two literal arguments
+       * pic16_pCode2str: corrected code that emits assembler instructions
+       with two literal operands and those that have an access bit modifier
+       * genericPrint: now PC_ASMDIR pCodes, can emit a label if it exists,
+       this fixes a bug which caused some labels to be lost, when an
+       assembler directive was added, i.e. banksel,
+       * pic16_FixRegisterBanking: improved logic that causes the insertion
+       of bank switching,
+       * InlineFunction: functions that are called once, are not any more
+       inlined. This can be a port option in the future,
+       
+       * pcode.h: added pCodeOpLit2 and added variable label in pCodeAsmDir
+       
+       * ralloc.c: added pic16_rel_udata and pic16_fix_udata variables which
+       hold the corresponding uninitialized symbols,
+       * pic16_allocProcessorRegister: registers have explicit marked the
+       accessBank field,
+       * pic16_allocInternalRegister: registers are explicit marked as
+       not used,
+       * pic16_writeUsedRegs: pic16_dynDirectBitRegs was missing from the
+       processing list, so bit registers were lost,
+       * 
+
+       * ralloc.h: added field 'accessBank' and original symbol operand
+       in register definition,
+       * removed the field isMapped from register definition,
+
+       ** Several functions have been removed from various sources:
+       BanksUsedFlow2,BanksUsedFlow,FixBankFlow,InstructionRegBank,
+       pic16_addMemRange,pic16_isREGinBank,pic16_dump_map,pic16_dump_cblock
+       isSFR,validAddress,mapRegister,assignRegister,pic16_assignFixedRegisters
+       pic16_assignRelocatableRegisters
+       
+       ** others have been introduced:
+       pic16_areRegsSame,pic16_dump_section,checkAddReg,pic16_groupRegistersInSection
+       pic16_popGetLit2,pic16_popCombine2,pushw,pushaop
+       
 2004-01-05 Vangelis Rokas <vrokas@otenet.gr>
 
        * support/scripts/inc2h.pl: changed definition of BIT_AT
index 644d9923eb153f4f58c28a5ff9e7827b29745431..5ef744e0e711d34a311abd2ed8b7fb45a5f7a297 100644 (file)
@@ -242,7 +242,6 @@ struct options
     int noCcodeInAsm;           /* hide c-code from asm */
     int iCodeInAsm;             /* show i-code in asm */
     int printSearchDirs;        /* display the directories in the compiler's search path */
-    int gen_banksel;           /* enable the generation of the banksel assembler directive in pic16 port */
     int vc_err_style;           /* errors and warnings are compatible with Micro$oft visual studio */
     int use_stdout;             /* send errors to stdout instead of stderr */
     int no_std_crt0;            /*For the z80/gbz80 do not link default crt0.o*/
index 65e5a017541d8ed8c0d39e9f36f874569086bde0..8c58faf443805b6dde216e9b15e18a2ed4cbd9fe 100644 (file)
@@ -227,9 +227,6 @@ optionsTable[] = {
     { 0,    OPTION_USE_STDOUT, &options.use_stdout, "send errors to stdout instead of stderr"},
 #if !OPT_DISABLE_Z80 || !OPT_DISABLE_GBZ80
     { 0,    "--no-std-crt0", &options.no_std_crt0, "For the z80/gbz80 do not link default crt0.o"},
-#endif
-#if !OPT_DISABLE_PIC16
-    { 0,    "--gen-banksel",       &options.gen_banksel, "enable the generation of banksel assembler directives in PIC16 port"},
 #endif
     /* End of options */
     { 0,    NULL }
@@ -650,7 +647,7 @@ _setModel (int model, const char *sz)
 /** Gets the string argument to this option.  If the option is '--opt'
     then for input of '--optxyz' or '--opt xyz' returns xyz.
 */
-static char *
+char *
 getStringArg(const char *szStart, char **argv, int *pi, int argc)
 {
   if (argv[*pi][strlen(szStart)])
@@ -676,7 +673,7 @@ getStringArg(const char *szStart, char **argv, int *pi, int argc)
 /** Gets the integer argument to this option using the same rules as
     getStringArg.
 */
-static int
+int
 getIntArg(const char *szStart, char **argv, int *pi, int argc)
 {
     return (int)floatFromVal(constVal(getStringArg(szStart, argv, pi, argc)));
index 4dea1545d8328e8e718f5c79e456c780c27c4953..b7eb78657786f8251a8c1edf38396ff1051e0bb7 100644 (file)
@@ -208,8 +208,8 @@ static int num_of_supported_PICS = sizeof(Pics)/sizeof(PIC_device);
 
 static PIC_device *pic=NULL;
 
-AssignedMemory *pic16_finalMapping=NULL;
-int pic16_finalMappingSize=0;
+//AssignedMemory *pic16_finalMapping=NULL;
+//int pic16_finalMappingSize=0;
 
 #define DEFAULT_CONFIG_BYTE 0xff
 
@@ -258,51 +258,12 @@ static unsigned int config6h_word = DEFAULT_CONFIG6H_WORD;
 static unsigned int config7l_word = DEFAULT_CONFIG7L_WORD;
 static unsigned int config7h_word = DEFAULT_CONFIG7H_WORD;
 
-void pic16_addMemRange(memRange *r, int type)
-{
-  int i;
-  int alias = r->alias;
-
-  if (pic->maxRAMaddress < 0) {
-    fprintf(stderr, "missing \"#pragma maxram\" setting\n");
-    return;
-  }
-
-//     fprintf(stderr, "%s: adding memory range from 0x%x to 0x%x type= %d\n",
-//             __FUNCTION__, r->start_address, r->end_address, type);
-
-  do {
-    for (i=r->start_address; i<= r->end_address; i++) {
-      if ((i|alias) <= pic->maxRAMaddress) {
-       pic16_finalMapping[i | alias].isValid = 1;
-       pic16_finalMapping[i | alias].alias = r->alias;
-       pic16_finalMapping[i | alias].bank  = r->bank;
-       if(type) {
-         /* hack for now */
-         pic16_finalMapping[i | alias].isSFR  = 1;
-       } else {
-         pic16_finalMapping[i | alias].isSFR  = 0;
-       }
-      } else {
-       fprintf(stderr, "WARNING: %s:%s memory at 0x%x is beyond max ram = 0x%x\n",
-               __FILE__,__FUNCTION__,(i|alias), pic->maxRAMaddress);
-      }
-    }
-
-    /* Decrement alias */
-    if (alias) {
-      alias -= ((alias & (alias - 1)) ^ alias);
-    } else {
-      alias--;
-    }
-
-  } while (alias >= 0);
-}
+unsigned int stackPos = 0;
 
 void pic16_setMaxRAM(int size)
 {
-  int i;
   pic->maxRAMaddress = size;
+  stackPos = pic->RAMsize-1;
 
   if (pic->maxRAMaddress < 0) {
     fprintf(stderr, "invalid \"#pragma maxram 0x%x\" setting\n",
@@ -310,20 +271,20 @@ void pic16_setMaxRAM(int size)
     return;
   }
 
-  pic16_finalMapping = Safe_calloc(1+pic->maxRAMaddress,
-                            sizeof(AssignedMemory));
+//  pic16_finalMapping = Safe_calloc(1+pic->maxRAMaddress,
+//                          sizeof(AssignedMemory));
 
   /* Now initialize the pic16_finalMapping array */
 
-  for(i=0; i<=pic->maxRAMaddress; i++) {
-    pic16_finalMapping[i].reg = NULL;
-    pic16_finalMapping[i].isValid = 0;
-  }
+//  for(i=0; i<=pic->maxRAMaddress; i++) {
+//    pic16_finalMapping[i].reg = NULL;
+//    pic16_finalMapping[i].isValid = 0;
+//  }
 }
 
 /*-----------------------------------------------------------------*
  *-----------------------------------------------------------------*/
-
+#if 0
 int pic16_isREGinBank(regs *reg, int bank)
 {
 
@@ -335,7 +296,7 @@ int pic16_isREGinBank(regs *reg, int bank)
 
   return 0;
 }
-
+#endif
 /*-----------------------------------------------------------------*
  *-----------------------------------------------------------------*/
 int pic16_REGallBanks(regs *reg)
@@ -344,7 +305,7 @@ int pic16_REGallBanks(regs *reg)
   if(!reg || !pic)
     return 0;
 
-  if (reg->address > pic->maxRAMaddress)
+  if ((int)reg->address > pic->maxRAMaddress)
     return 0;
 
   return 1;
@@ -357,7 +318,7 @@ int pic16_REGallBanks(regs *reg)
 /*
  *  pic16_dump_map -- debug stuff
  */
-
+#if 0
 void pic16_dump_map(void)
 {
   int i;
@@ -376,80 +337,42 @@ void pic16_dump_map(void)
   }
 
 }
+#endif
 
-void pic16_dump_cblock(FILE *of)
-{
-  int start=-1;
-  int addr=0;
-  int bank_base;
-
-  //pic16_dump_map();   /* display the register map */
-
-  if (pic->maxRAMaddress < 0) {
-    fprintf(stderr, "missing \"#pragma maxram\" setting\n");
-    return;
-  }
-
-  do {
-
-    if(pic16_finalMapping[addr].reg && !pic16_finalMapping[addr].reg->isEmitted
-       && pic16_finalMapping[addr].reg->wasUsed) {
-
-      if(start<0)
-       start = addr;
-    } else {
-      if(start>=0) {
-
-       /* clear the lower 7-bits of the start address of the first
-        * variable declared in this bank. The upper bits for the mid
-        * range pics are the bank select bits.
-        */
-
-       bank_base = start & 0xfff8;
-
-       /* The bank number printed in the cblock comment tacitly
-        * assumes that the first register in the contiguous group
-        * of registers represents the bank for the whole group */
-
-        if ((pic16_finalMapping[start].bank == 0 && start <= 0x7f) ||
-            pic16_finalMapping[start].isSFR)
-         fprintf(of,"  cblock  0X%04X\t; Access Bank\n",start);
-        else
-         fprintf(of,"  cblock  0X%04X\t; Bank %d\n",start,pic16_finalMapping[start].bank);
-
-       for( ; start < addr; start++) {
-         if((pic16_finalMapping[start].reg) && !pic16_finalMapping[start].reg->isEmitted ) {
-           fprintf(of,"\t%s",pic16_finalMapping[start].reg->name);
-
-           /* If this register is aliased in multiple banks, then
-            * mangle the variable name with the alias address: */
-           if(pic16_finalMapping[start].alias & start)
-             fprintf(of,"_%x",bank_base);
-
-           if(pic16_finalMapping[start].instance)
-             fprintf(of,"_%d",pic16_finalMapping[start].instance);
-
-           
-           fputc('\n',of);
 
-//#warning why is the following line commented out?! (VR)
-//         pic16_finalMapping[start].reg->isEmitted = 1;
-         }
+void pic16_dump_section(FILE *of, char *sname, set *section, int fix)
+{
+  static int abs_section_no=0;
+  regs *r, *rprev;
+  int init_addr;
+
+       if(!fix) {
+               fprintf(of, "\n\n\tudata\n");
+               for(r = setFirstItem(section); r; r = setNextItem(section)) {
+                       fprintf(of, "%s\tres\t%d\n", r->name, r->size);
+               }
+       } else {
+               r = setFirstItem(section);
+               if(!r)return;
+               init_addr = r->address;
+               fprintf(of, "\n\nstatic_%s_%02d\tudata\t0X%04X\n", moduleName, abs_section_no++, init_addr);
+               
+               rprev = NULL;
+               for(; r; r = setNextItem(section)) {
+                       init_addr = r->address;
+
+                       if(rprev && (init_addr != (rprev->address + rprev->size))) {
+                               fprintf(of, "\nstatic_%s_%02d\tudata\t0X%04X\n", moduleName, abs_section_no++, init_addr);
+                       }
+
+                       fprintf(of, "%s\tres\t%d\n", r->name, r->size);
+                       rprev = r;
+               }
        }
+}
 
-       fprintf(of,"  endc\n");
-
-       start = -1;
-      }
-
-    }
-
-    addr++;
 
-  } while(addr <= pic->maxRAMaddress);
-  
 
-}
 
 /*-----------------------------------------------------------------*
  *  void pic16_list_valid_pics(int ncols, int list_alias)
@@ -535,21 +458,22 @@ PIC_device *pic16_find_device(char *name)
  *-----------------------------------------------------------------*/
 void pic16_init_pic(char *pic_type)
 {
-  pic = pic16_find_device(pic_type);
+       pic = pic16_find_device(pic_type);
 
-  if(!pic) {
-    if(pic_type)
-      fprintf(stderr, "'%s' was not found.\n", pic_type);
-    else
-      fprintf(stderr, "No processor has been specified (use -pPROCESSOR_NAME)\n");
+       if(!pic) {
+               if(pic_type)
+                       fprintf(stderr, "'%s' was not found.\n", pic_type);
+               else
+                       fprintf(stderr, "No processor has been specified (use -pPROCESSOR_NAME)\n");
 
-    fprintf(stderr,"Valid devices are:\n");
+               fprintf(stderr,"Valid devices are:\n");
 
-    pic16_list_valid_pics(4,0);
-    exit(1);
-  }
+               pic16_list_valid_pics(4,0);
+               exit(1);
+       }
 
-  pic->maxRAMaddress = -1;
+//     printf("PIC processor found and initialized: %s\n", pic_type);
+       pic16_setMaxRAM( 0xfff  );
 }
 
 /*-----------------------------------------------------------------*
@@ -576,22 +500,15 @@ char *pic16_processor_base_name(void)
   return pic->name[0];
 }
 
-static int isSFR(int address)
-{
-
-  if( (address > pic->maxRAMaddress) || !pic16_finalMapping[address].isSFR)
-    return 0;
-
-  return 1;
-
-}
 
+#if 0
 /*-----------------------------------------------------------------*
  *-----------------------------------------------------------------*/
 static int validAddress(int address, int reg_size)
 {
   int i;
 
+#if 0
   if (pic->maxRAMaddress < 0) {
     fprintf(stderr, "missing \"#pragma maxram\" setting\n");
     return 0;
@@ -605,136 +522,47 @@ static int validAddress(int address, int reg_size)
        pic16_finalMapping[address+i].reg ||
        pic16_finalMapping[address+i].isSFR )
       return 0;
+#endif
 
   return 1;
 }
+#endif
 
-/*-----------------------------------------------------------------*
- *-----------------------------------------------------------------*/
-static void mapRegister(regs *reg)
-{
-
-  int i;
-  int alias;
-
-  if(!reg || !reg->size) {
-    fprintf(stderr,"WARNING: %s:%s:%d Bad register\n",__FILE__,__FUNCTION__,__LINE__);
-    return;
-  }
-
-  if (pic->maxRAMaddress < 0) {
-    fprintf(stderr, "missing \"#pragma maxram\" setting\n");
-    return;
-  }
-
-  for(i=0; i<reg->size; i++) {
-
-    alias = pic16_finalMapping[reg->address].alias;
-    reg->alias = alias;
-
-    do {
-
-//     fprintf(stdout,"mapping %s to address 0x%02x, reg size = %d\n",reg->name, (reg->address+alias+i),reg->size);
-
-      pic16_finalMapping[reg->address + alias + i].reg = reg;
-      pic16_finalMapping[reg->address + alias + i].instance = i;
-
-      /* Decrement alias */
-      if(alias)
-       alias -= ((alias & (alias - 1)) ^ alias);
-      else
-       alias--;
-
-    } while (alias>=0);
-  }
-
-  //  fprintf(stderr,"%s - %s addr = 0x%03x, size %d\n",__FUNCTION__,reg->name, reg->address,reg->size);
-
-  reg->isMapped = 1;
-
-}
-
-/*-----------------------------------------------------------------*
- *-----------------------------------------------------------------*/
-static int assignRegister(regs *reg, int start_address)
+void checkAddReg(set **set, regs *reg)
 {
-  int i;
+  regs *tmp;
 
-//     fprintf(stderr,"%s -  %s start_address = 0x%03x\t(max=0x%03x)\n",__FUNCTION__,reg->name, start_address, pic->maxRAMaddress);
-  if(reg->isFixed) {
 
-    if (validAddress(reg->address,reg->size)) {
-//     fprintf(stderr,"fixed %s -  %s address = 0x%03x\n",__FUNCTION__,reg->name, reg->address);
-      mapRegister(reg);
-      return reg->address;
-    }
-
-    if( isSFR(reg->address)) {
-//     fprintf(stderr,"sfr %s -  %s address = 0x%03x\n",__FUNCTION__,reg->name, reg->address);
-      mapRegister(reg);
-      return reg->address;
-    }
-
-    //fprintf(stderr, "WARNING: Ignoring Out of Range register assignment at fixed address %d, %s\n",
-    //    reg->address, reg->name);
-
-  } else {
-
-    /* This register does not have a fixed address requirement
-     * so we'll search through all availble ram address and
-     * assign the first one */
-
-    for (i=start_address; i<=pic->maxRAMaddress; i++) {
-
-      if (validAddress(i,reg->size)) {
-//     fprintf(stderr, "found valid address = 0x%04x\n", i);
-       reg->address = i;
-       mapRegister(reg);
-       return i;
-      }
-    }
-
-    fprintf(stderr, "WARNING: No more RAM available for %s\n",reg->name);
-
-  }
-
-  return -1;
+       for(tmp = setFirstItem(*set); tmp; tmp = setNextItem(*set)) {
+               if(!strcmp(tmp->name, reg->name))break;
+       }
+       
+       if(!tmp)
+               addSet(set, reg);
 }
 
 /*-----------------------------------------------------------------*
+ * void pic16_groupRegistersInSection - add each register to its   *
+ *     corresponding section                                      *
  *-----------------------------------------------------------------*/
-void pic16_assignFixedRegisters(set *regset)
+void pic16_groupRegistersInSection(set *regset)
 {
   regs *reg;
 
-  for (reg = setFirstItem(regset) ; reg ; 
-       reg = setNextItem(regset)) {
-
-    if(reg->isFixed) 
-      assignRegister(reg,0);
-  }
-
+       for(reg=setFirstItem(regset); reg; reg = setNextItem(regset)) {
+               if(reg->wasUsed
+                       && !(reg->regop && SPEC_EXTR(OP_SYM_ETYPE(reg->regop)))) {
+                       if(reg->isFixed)
+                               checkAddReg(&pic16_fix_udata, reg);
+               
+                       if(!reg->isFixed)
+                               checkAddReg(&pic16_rel_udata, reg);
+               }
+       }
 }
 
-/*-----------------------------------------------------------------*
- *-----------------------------------------------------------------*/
-void pic16_assignRelocatableRegisters(set *regset, int used)
-{
 
-  regs *reg;
-  int address = 0;
 
-  for (reg = setFirstItem(regset) ; reg ; 
-       reg = setNextItem(regset)) {
-
-    //fprintf(stdout,"assigning %s isFixed=%d, wasUsed=%d\n",reg->name,reg->isFixed,reg->wasUsed);
-
-    if((!reg->isFixed) && (used || reg->wasUsed))
-      address = assignRegister(reg,address);
-
-  }
-
-}
 
 
 /*-----------------------------------------------------------------*
@@ -784,7 +612,7 @@ void pic16_assignConfigWordValue(int address, int value)
     break;
   }
 
-  //fprintf(stderr,"setting config word to 0x%x\n",value);
+       fprintf(stderr,"setting config word to 0x%x\n",value);
 
 }
 /*-----------------------------------------------------------------*
@@ -823,4 +651,3 @@ int pic16_getConfigWord(int address)
     return 0;
   }
 }
-
index ec12138bba0294993d903d4f75972bc45fff45dd..9e3d115136ddd996e557a3d1e9cbc0236e56e245 100644 (file)
@@ -71,13 +71,13 @@ typedef struct AssignedMemory {
  * pic16_finalMapping - Dynamically allocated array that records the register assignments
  */
 
-extern AssignedMemory *pic16_finalMapping;
+//extern AssignedMemory *pic16_finalMapping;
 
 /*
  * pic16_finalMappingSize - Size of register assignments that pic16_finalMapping can hold
  */
 
-extern int pic16_finalMappingSize;
+//extern int pic16_finalMappingSize;
 
 
 #define PROCESSOR_NAMES    4
@@ -96,9 +96,27 @@ typedef struct PIC_device {
 
 /* Given a pointer to a register, this macro returns the bank that it is in */
 #define REG_ADDR(r)        ((r)->isBitField ? (((r)->address)>>3) : (r)->address)
-#define REG_BANK(r)        (pic16_finalMapping[REG_ADDR(r)].bank)
-#define REG_isALIASED(r)   (pic16_finalMapping[REG_ADDR(r)].alias != 0)
-#define REG_isVALID(r)     (pic16_finalMapping[REG_ADDR(r)].isValid)
+//#define REG_BANK(r)        (pic16_finalMapping[REG_ADDR(r)].bank)
+//#define REG_isALIASED(r)   (pic16_finalMapping[REG_ADDR(r)].alias != 0)
+//#define REG_isVALID(r)     (pic16_finalMapping[REG_ADDR(r)].isValid)
+
+
+typedef struct {
+       int gen_banksel;
+       int opt_banksel;
+       int omit_configw;
+       int omit_ivt;
+       int leave_reset;
+       int enable_stack;
+       int stack_model;
+} pic16_options_t;
+
+#define USE_STACK      (pic16_options.enable_stack)
+#define STACK_MODEL_SMALL      (pic16_options.stack_model == 0)
+#define STACK_MODEL_LARGE      (pic16_options.stack_model == 1)
+
+
+extern pic16_options_t pic16_options;
 
 
 /****************************************/
@@ -109,4 +127,7 @@ int pic16_REGallBanks(regs *reg);
 void pic16_addMemRange(memRange *r, int type);
 void pic16_setMaxRAM(int size);
 
+void checkAddReg(set **set, regs *reg);
+
+
 #endif  /* __DEVICE_H__ */
index 174bca23be9111fdbda6990d0dffad7a96d726b6..7775b12c7b6220507ef30dc2947cbdfd27093804 100644 (file)
@@ -42,7 +42,8 @@
 #include "ralloc.h"
 #include "pcode.h"
 #include "gen.h"
-
+#include "genutils.h"
+#include "device.h"
 
 extern void pic16_genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
 extern void pic16_genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
@@ -273,8 +274,8 @@ void pic16_emitcode (char *inst,char *fmt, ...)
 
 // VR    fprintf(stderr, "lb = <%s>\n", lbp);
 
-    if(pic16_debug_verbose)
-      pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
+//    if(pic16_debug_verbose)
+//      pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
 
     va_end(ap);
 }
@@ -761,7 +762,8 @@ void pic16_aopOp (operand *op, iCode *ic, bool result)
     if (!op)
         return ;
 
-       DEBUGpic16_emitcode(";","%d",__LINE__);
+//     DEBUGpic16_emitcode(";","%d",__LINE__);
+
     /* if this a literal */
     if (IS_OP_LITERAL(op)) {
         op->aop = aop = newAsmop(AOP_LIT);
@@ -1225,18 +1227,26 @@ pCodeOp *pic16_popCopyReg(pCodeOpReg *pc)
 
   return PCOP(pcor);
 }
+
 /*-----------------------------------------------------------------*/
-/* pic16_popGet - asm operator to pcode operator conversion              */
+/* pic16_popGetLit - asm operator to pcode operator conversion     */
 /*-----------------------------------------------------------------*/
 pCodeOp *pic16_popGetLit(unsigned int lit)
 {
-
   return pic16_newpCodeOpLit(lit);
 }
 
+/*-----------------------------------------------------------------*/
+/* pic16_popGetLit2 - asm operator to pcode operator conversion    */
+/*-----------------------------------------------------------------*/
+pCodeOp *pic16_popGetLit2(unsigned int lit, unsigned int lit2)
+{
+  return pic16_newpCodeOpLit2(lit, lit2);
+}
+
 
 /*-----------------------------------------------------------------*/
-/* pic16_popGetImmd - asm operator to pcode immediate conversion         */
+/* pic16_popGetImmd - asm operator to pcode immediate conversion   */
 /*-----------------------------------------------------------------*/
 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index)
 {
@@ -1285,7 +1295,8 @@ static pCodeOp *pic16_popRegFromString(char *str, int size, int offset)
 
   PCOR(pcop)->r = pic16_dirregWithName(pcop->name);
   if(PCOR(pcop)->r == NULL) {
-    //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
+//     fprintf(stderr, "%s:%d - couldn't find %s in allocated regsters, size= %d ofs= %d\n",
+//             __FUNCTION__, __LINE__, str, size, offset);
     PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size);
 
        //fprintf(stderr, "allocating new register -> %s\n", str);
@@ -1335,6 +1346,15 @@ pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset)
   return PCOP(pcop2);
 }
 
+pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst)
+{
+  pCodeOpReg2 *pcop2;
+
+       pcop2 = (pCodeOpReg2 *)pic16_popCopyReg(src);
+       pcop2->pcop2 = pic16_popCopyReg(dst);
+
+  return PCOP(pcop2);
+}
 
 /*-----------------------------------------------------------------*/
 /* pic16_popGet - asm operator to pcode operator conversion              */
@@ -1366,45 +1386,18 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
        return NULL;
        
     case AOP_IMMD:
-      DEBUGpic16_emitcode(";","%d",__LINE__);
+      DEBUGpic16_emitcode(";","%d\tAOP_IMMD",__LINE__);
       return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
 
     case AOP_DIR:
+      DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__);
       return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset);
-
-#if 0
-       pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
-       pcop->type = PO_DIR;
-
-       /*
-       if (offset)
-           sprintf(s,"(%s + %d)",
-                   aop->aopu.aop_dir,
-                   offset);
-       else
-           sprintf(s,"%s",aop->aopu.aop_dir);
-       pcop->name = Safe_calloc(1,strlen(s)+1);
-       strcpy(pcop->name,s);   
-       */
-       pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
-       strcpy(pcop->name,aop->aopu.aop_dir);   
-       PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
-       if(PCOR(pcop)->r == NULL) {
-         //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
-         PCOR(pcop)->r = pic16_allocRegByName (aop->aopu.aop_dir,aop->size);
-         DEBUGpic16_emitcode(";","%d  %s   offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
-       } else {
-         DEBUGpic16_emitcode(";","%d  %s   offset=%d",__LINE__,pcop->name,offset);
-       }
-       PCOR(pcop)->instance = offset;
-
-       return pcop;
-#endif
        
     case AOP_REG:
       {
        int rIdx = aop->aopu.aop_reg[offset]->rIdx;
 
+       DEBUGpic16_emitcode(";","%d\tAOP_REG", __LINE__);
        pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
        PCOR(pcop)->rIdx = rIdx;
        PCOR(pcop)->r = pic16_regWithIdx(rIdx);
@@ -1419,6 +1412,8 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
       }
 
     case AOP_CRY:
+       DEBUGpic16_emitcode(";","%d\tAOP_CRY", __LINE__);
+
       pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1);
       PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
       //if(PCOR(pcop)->r == NULL)
@@ -1426,11 +1421,13 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
       return pcop;
        
     case AOP_LIT:
+       DEBUGpic16_emitcode(";","%d\tAOP_LIT", __LINE__);
       return pic16_newpCodeOpLit(pic16aopLiteral (aop->aopu.aop_lit,offset));
 
     case AOP_STR:
-      DEBUGpic16_emitcode(";","%d  %s",__LINE__,aop->aopu.aop_str[offset]);
+      DEBUGpic16_emitcode(";","%d AOP_STR %s",__LINE__,aop->aopu.aop_str[offset]);
       return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
+
       /*
       pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
       PCOR(pcop)->r = pic16_allocRegByName(aop->aopu.aop_str[offset]);
@@ -1704,6 +1701,48 @@ static void mov2w (asmop *aop, int offset)
 
 }
 
+
+/*-----------------------------------------------------------------*/
+/* pushw - pushes wreg to stack                                    */
+/*-----------------------------------------------------------------*/
+void pushw(void)
+{
+        DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+       pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postdec1));
+}
+
+                
+/*-----------------------------------------------------------------*/
+/* pushaop - pushes aop to stack                                   */
+/*-----------------------------------------------------------------*/
+void pushaop(asmop *aop, int offset)
+{
+        DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+        pic16_emitpcode(POC_MOVFF, pic16_popCombine2(PCOR(pic16_popGet(aop, offset)), &pic16_pc_postdec1));
+}
+
+#if 0
+/*-----------------------------------------------------------------*/
+/* popaop - pops aop from stack                                    */
+/*-----------------------------------------------------------------*/
+void popaop(asmop *aop, int offset)
+{
+       DEBUG
+}
+#endif
+
+void popaopidx(asmop *aop, int offset, int index)
+{
+  int ofs=1;
+
+        DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+       if(STACK_MODEL_LARGE)ofs++;
+
+       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(index + ofs));
+        pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_plusw2, PCOR(pic16_popGet(aop, offset))));
+}
+
 /*-----------------------------------------------------------------*/
 /* reAdjustPreg - points a register back to where it should        */
 /*-----------------------------------------------------------------*/
@@ -1851,10 +1890,11 @@ void pic16_toBoolean(operand *oper)
 }
 
 
+#if !defined(GEN_Not)
 /*-----------------------------------------------------------------*/
 /* genNot - generate code for ! operation                          */
 /*-----------------------------------------------------------------*/
-static void genNot (iCode *ic)
+static void pic16_genNot (iCode *ic)
 {
   symbol *tlbl;
   int size;
@@ -1897,12 +1937,14 @@ static void genNot (iCode *ic)
   pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
   pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
 }
+#endif
 
 
+#if !defined(GEN_Cpl)
 /*-----------------------------------------------------------------*/
 /* genCpl - generate code for complement                           */
 /*-----------------------------------------------------------------*/
-static void genCpl (iCode *ic)
+static void pic16_genCpl (iCode *ic)
 {
     int offset = 0;
     int size ;
@@ -1948,6 +1990,7 @@ release:
     pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
     pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
 }
+#endif
 
 /*-----------------------------------------------------------------*/
 /* genUminusFloat - unary minus for floating points                */
@@ -2166,22 +2209,41 @@ static void assignResultValue(operand * oper)
 {
   int size = AOP_SIZE(oper);
 
-  DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+       DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
+
+       if(!GpsuedoStkPtr) {
+//             DEBUGpic16_emitcode("; ", "pop %d", GpsuedoStkPtr);
+               /* The last byte in the assignment is in W */
+               size--;
+               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
+               GpsuedoStkPtr++;
+       }
 
-  DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
+       while (size--) {
+//             DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
+//             DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
+               
+#if STACK_SUPPORT
+               if(USE_STACK) {
+                       popaopidx(AOP(oper), size, GpsuedoStkPtr);
+               } else {
+                       pic16_emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
+               }
+#else
+               pic16_emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
+#endif /* STACK_SUPPORT */
+               GpsuedoStkPtr++;
 
-  if(!GpsuedoStkPtr) {
-    /* The last byte in the assignment is in W */
-    size--;
-    pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
-    GpsuedoStkPtr++;
-  }
+#if STACK_SUPPORT
+               if(!USE_STACK)
+                       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
+#else
+               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
+#endif
 
-  while (size--) {
-    pic16_emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
-    GpsuedoStkPtr++;
-    pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
-  }
+       }
+               
 }
 
 
@@ -2367,136 +2429,152 @@ static void saverbank (int bank, iCode *ic, bool pushPsw)
 #endif
 }
 
+
+
 /*-----------------------------------------------------------------*/
 /* genCall - generates a call statement                            */
 /*-----------------------------------------------------------------*/
 static void genCall (iCode *ic)
 {
   sym_link *dtype;   
+  int stackParms=0;
+  
+       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-  DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+       /* if caller saves & we have not saved then */
+       if (!ic->regsSaved)
+               saveRegisters(ic);
 
-  /* if caller saves & we have not saved then */
-  if (!ic->regsSaved)
-    saveRegisters(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 */
+       dtype = operandType(IC_LEFT(ic));
+       if (currFunc && dtype && 
+               (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
+               IFFUNC_ISISR(currFunc->type) &&
+               !ic->bankSaved) 
 
-  /* 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 */
-  dtype = operandType(IC_LEFT(ic));
-  if (currFunc && dtype && 
-      (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
-      IFFUNC_ISISR(currFunc->type) &&
-      !ic->bankSaved) 
+                       saverbank(FUNC_REGBANK(dtype),ic,TRUE);
 
-    saverbank(FUNC_REGBANK(dtype),ic,TRUE);
+       /* if send set is not empty the assign */
+       if (_G.sendSet) {
+         iCode *sic;
 
-  /* if send set is not empty the assign */
-  if (_G.sendSet) {
-    iCode *sic;
-    /* For the Pic port, there is no data stack.
-     * So parameters passed to functions are stored
-     * in registers. (The pCode optimizer will get
-     * rid of most of these :).
-     */
-    int psuedoStkPtr=-1; 
-    int firstTimeThruLoop = 1;
+               /* For the Pic port, there is no data stack.
+                * So parameters passed to functions are stored
+                * in registers. (The pCode optimizer will get
+                * rid of most of these :). */
 
-    _G.sendSet = reverseSet(_G.sendSet);
+         int psuedoStkPtr=-1; 
+         int firstTimeThruLoop = 1;
 
-    /* First figure how many parameters are getting passed */
-    for (sic = setFirstItem(_G.sendSet) ; sic ; 
-        sic = setNextItem(_G.sendSet)) {
+               _G.sendSet = reverseSet(_G.sendSet);
 
-      pic16_aopOp(IC_LEFT(sic),sic,FALSE);
-      psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
-      pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
-    }
+               /* First figure how many parameters are getting passed */
+               for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
+                       pic16_aopOp(IC_LEFT(sic),sic,FALSE);
+                       psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
+                       pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
+               }
 
-    for (sic = setFirstItem(_G.sendSet) ; sic ; 
-        sic = setNextItem(_G.sendSet)) {
-      int size, offset = 0;
+               stackParms = psuedoStkPtr;
 
-      pic16_aopOp(IC_LEFT(sic),sic,FALSE);
-      size = AOP_SIZE(IC_LEFT(sic));
+               for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
+                 int size, offset = 0;
 
-      while (size--) {
-       DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
-                            pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
+                       pic16_aopOp(IC_LEFT(sic),sic,FALSE);
+                       size = AOP_SIZE(IC_LEFT(sic));
+
+                       while (size--) {
+                               DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
+                                       pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
+                               DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
 
-       if(!firstTimeThruLoop) {
-         /* If this is not the first time we've been through the loop
-          * then we need to save the parameter in a temporary
-          * register. The last byte of the last parameter is
-          * passed in W. */
-         pic16_emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
+                               if(!firstTimeThruLoop) {
+                                       /* If this is not the first time we've been through the loop
+                                        * then we need to save the parameter in a temporary
+                                        * register. The last byte of the last parameter is
+                                        * passed in W. */
+
+#if STACK_SUPPORT
+                                       if(USE_STACK) {
+                                               pushw();
+                                               --psuedoStkPtr;         // sanity check
+                                       } else {
+                                               pic16_emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
+                                       }
+#else
+                                       pic16_emitpcode(POC_MOVWF, popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
+#endif /* STACK_SUPPORT */
+                               }
+                       
+                               firstTimeThruLoop=0;
 
+                               mov2w (AOP(IC_LEFT(sic)),  offset);
+                               offset++;
+                       }
+                       pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
+               }
+               _G.sendSet = NULL;
        }
-       firstTimeThruLoop=0;
 
-       //if (strcmp(l,fReturn[offset])) {
-       mov2w (AOP(IC_LEFT(sic)),  offset);
-/*
-       if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
-            ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
-         pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(sic)),offset));
-       else
-         pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_LEFT(sic)),offset));
-*/
-       //}
-       offset++;
-      }
-      pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
-    }
-    _G.sendSet = NULL;
-  }
-  /* make the call */
-  pic16_emitpcode(POC_CALL,pic16_popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
-                                     OP_SYMBOL(IC_LEFT(ic))->rname :
-                                     OP_SYMBOL(IC_LEFT(ic))->name));
-
-  GpsuedoStkPtr=0;
-  /* if we need assign a result value */
-  if ((IS_ITEMP(IC_RESULT(ic)) && 
-       (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
-       OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
-      IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
-
-    _G.accInUse++;
-    pic16_aopOp(IC_RESULT(ic),ic,FALSE);
-    _G.accInUse--;
+       /* make the call */
+       pic16_emitpcode(POC_CALL,pic16_popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
+                       OP_SYMBOL(IC_LEFT(ic))->rname :
+                       OP_SYMBOL(IC_LEFT(ic))->name));
+
+       GpsuedoStkPtr=0;
+       /* if we need assign a result value */
+       if ((IS_ITEMP(IC_RESULT(ic)) && 
+               (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
+               OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
+               IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
+
+               _G.accInUse++;
+               pic16_aopOp(IC_RESULT(ic),ic,FALSE);
+               _G.accInUse--;
 
-    assignResultValue(IC_RESULT(ic));
+               assignResultValue(IC_RESULT(ic));
 
-    DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
+               DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
                         pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
                
-    pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
-  }
+               pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
+       }
 
-  /* adjust the stack for parameters if 
-     required */
-  if (ic->parmBytes) {
-    int i;
-    if (ic->parmBytes > 3) {
-      pic16_emitcode("mov","a,%s",spname);
-      pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
-      pic16_emitcode("mov","%s,a",spname);
-    } else 
-      for ( i = 0 ; i <  ic->parmBytes ;i++)
-       pic16_emitcode("dec","%s",spname);
+#if STACK_SUPPORT
+       if(USE_STACK) {
+               pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
+               pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
+               if(STACK_MODEL_LARGE) {
+                       emitSKPNC;
+                       pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
+               }
+       }
+#endif
 
-  }
+       /* adjust the stack for parameters if required */
+       fprintf(stderr, "%s:%d: ic->parmBytes= %d\n", __FILE__, __LINE__, ic->parmBytes);
 
-  /* if register bank was saved then pop them */
-  if (ic->bankSaved)
-    unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
+       if (ic->parmBytes) {
+         int i;
 
-  /* if we hade saved some registers then unsave them */
-  if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
-    unsaveRegisters (ic);
+               if (ic->parmBytes > 3) {
+                       pic16_emitcode("mov","a,%s",spname);
+                       pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
+                       pic16_emitcode("mov","%s,a",spname);
+               } else 
+                       for ( i = 0 ; i <  ic->parmBytes ;i++)
+                               pic16_emitcode("dec","%s",spname);
+       }
 
+       /* if register bank was saved then pop them */
+       if (ic->bankSaved)
+               unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
 
+       /* if we hade saved some registers then unsave them */
+       if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
+               unsaveRegisters (ic);
 }
 
 /*-----------------------------------------------------------------*/
@@ -2795,6 +2873,21 @@ static void genFunction (iCode *ic)
                }
            }
        }
+       
+#if STACK_SUPPORT
+       /* emit code to setup stack frame if user enabled,
+        * and function is not main() */
+        
+       fprintf(stderr, "function name: %s\n", sym->name);
+       if(USE_STACK && strcmp(sym->name, "main")) {
+               /* setup the stack frame */
+               pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1));
+               pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1l, &pic16_pc_fsr2l));
+               if(STACK_MODEL_LARGE)
+                       pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h));
+       }
+#endif
+
     }
 
     /* set the register bank to the desired value */
@@ -2819,6 +2912,8 @@ static void genFunction (iCode *ic)
        pic16_emitcode ("mov","_bp,%s",spname);
     }
 
+       DEBUGpic16_emitcode("; ", "need to adjust stack = %d", sym->stack);
+
     /* adjust the stack for the function */
     if (sym->stack) {
 
@@ -2827,7 +2922,6 @@ static void genFunction (iCode *ic)
            werror(W_STACK_OVERFLOW,sym->name);
 
        if (i > 3 && sym->recvSize < 4) {              
-
            pic16_emitcode ("mov","a,sp");
            pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
            pic16_emitcode ("mov","sp,a");
@@ -2839,7 +2933,7 @@ static void genFunction (iCode *ic)
     }
 
      if (sym->xstack) {
-
+               DEBUGpic16_emitcode("; ", "%s", __FUNCTION__);
        pic16_emitcode ("mov","a,_spx");
        pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
        pic16_emitcode ("mov","_spx,a");
@@ -3005,6 +3099,28 @@ static void genEndFunction (iCode *ic)
            _G.debugLine = 0;
        }
 
+#if STACK_SUPPORT
+       /* insert code to restore stack frame, if user enabled it
+        * and function is not main() */
+        
+       if(USE_STACK && strcmp(sym->name, "main")) {
+               /* restore stack frame */
+               if(STACK_MODEL_LARGE)
+                       pic16_emitpcode(POC_MOVFF,
+                               pic16_popCombine2( &pic16_pc_postinc1, &pic16_pc_fsr2h ));
+               pic16_emitpcode(POC_MOVFF,
+                               pic16_popCombine2( &pic16_pc_postinc1, &pic16_pc_fsr2l ));
+
+/*
+       * I added this because of a mistake in the stack pointers design
+       * They should be removed though
+       
+                       pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_preinc2, &pic16_pc_fsr2h));
+               pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_preinc2, &pic16_pc_fsr2l));
+*/
+       }
+#endif
+
         pic16_emitcode ("return","");
        pic16_emitpcodeNULLop(POC_RETURN);
 
@@ -3041,8 +3157,10 @@ static void genRet (iCode *ic)
       pic16_emitcode("push","%s",l);
       pushed++;
     } else {
+       DEBUGpic16_emitcode(";", "%d", __LINE__);
       l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,
                 FALSE,FALSE);
+       DEBUGpic16_emitcode(";", "%d l= %s", __LINE__, l);       
       if (strcmp(fReturn[offset],l)) {
        if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
            ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
@@ -4953,15 +5071,25 @@ static void genCmpEq (iCode *ic, iCode *ifx)
              if ( IC_TRUE(ifx) ) {
                if(size) {
                  emitSKPZ;
+               
+                       DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPZ");
+
                  pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
                  pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
                } else {
                  emitSKPNZ;
+
+                       DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPNZ");
+
+
                  pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
                  pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
                }
              } else {
                emitSKPZ;
+
+                       DEBUGpic16_emitcode (";","\tnot IC_TRUE emitSKPZ");
+
                pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
                pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
              }
@@ -9000,6 +9128,7 @@ static void genGenPointerSet (operand *right,
       /* hack hack! see if this the FSR. If so don't load W */
       if(AOP_TYPE(right) != AOP_ACC) {
 
+//     pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(result), pic16_popCopyReg(&pic16_pc_fsr0), 0));
 
        pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),0));
        pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
@@ -9186,6 +9315,7 @@ static void genIfx (iCode *ic, iCode *popIc)
 /*-----------------------------------------------------------------*/
 /* genAddrOf - generates code for address of                       */
 /*-----------------------------------------------------------------*/
+#if 0
 static void genAddrOf (iCode *ic)
 {
   operand *right, *result, *left;
@@ -9218,6 +9348,54 @@ static void genAddrOf (iCode *ic)
 
 }
 
+#else  /* new genAddrOf */
+
+static void genAddrOf (iCode *ic)
+{
+  operand *result, *left;
+  int size;
+  symbol *sym; // = OP_SYMBOL(IC_LEFT(ic));
+  pCodeOp *pcop0, *pcop1;
+
+       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+       pic16_aopOp((left=IC_LEFT(ic)), ic, FALSE);
+       pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
+
+       sym = OP_SYMBOL( left );
+
+       size = AOP_SIZE(IC_RESULT(ic));
+
+       /* Assume that what we want the address of is in direct addressing space
+        * since there is no stack on the PIC, yet! -- VR */
+
+       pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, 0));
+       pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, 0));
+#if 0
+       pcop0 = pic16_newpCodeOp(sym->rname, PO_IMMEDIATE);
+       PCOI(pcop0)->offset = 0;
+       PCOI(pcop0)->index = 0;
+       pcop1 = pic16_newpCodeOp(sym->rname, PO_IMMEDIATE);
+       PCOI(pcop1)->offset = 1;
+       PCOI(pcop1)->index = 0;
+#endif
+
+       if (size == 2) {
+               pic16_emitpcode(POC_MOVLW, pcop0);
+               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
+               pic16_emitpcode(POC_MOVLW, pcop1);
+               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
+       } else {
+               pic16_emitpcode(POC_MOVLW, pcop0);
+               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
+       }
+
+       pic16_freeAsmop(result,NULL,ic,TRUE);
+       pic16_freeAsmop(left, NULL, ic, FALSE);
+}
+
+#endif /* new genAddrOf */
+
 #if 0
 /*-----------------------------------------------------------------*/
 /* genFarFarAssign - assignment when both are in far space         */
@@ -9365,7 +9543,7 @@ static void genAssign (iCode *ic)
 
 #if 1
        /* This is a hack to turn MOVFW/MOVWF pairs to MOVFF command. It
-          normally should work, but mind that thw W register live range
+          normally should work, but mind that the W register live range
           is not checked, so if the code generator assumes that the W
           is already loaded after such a pair, wrong code will be generated.
           
@@ -9374,7 +9552,6 @@ static void genAssign (iCode *ic)
           USE WITH CARE. Revert to old code by setting 0 to the condition above.
           Vangelis Rokas 030603 (vrokas@otenet.gr) */
           
-       
        pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
 #else  
        /* This is the old code, which is assumed(?!) that works fine(!?) */
@@ -9916,35 +10093,40 @@ static int genDjnz (iCode *ic, iCode *ifx)
 /*-----------------------------------------------------------------*/
 static void genReceive (iCode *ic)
 {    
-  DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-  if (isOperandInFarSpace(IC_RESULT(ic)) && 
-      ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
-       IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
+       if (isOperandInFarSpace(IC_RESULT(ic)) && 
+               ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
+               IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
 
-    int size = getSize(operandType(IC_RESULT(ic)));
-    int offset =  pic16_fReturnSizePic - size;
-    while (size--) {
-      pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
-                                   fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
-      offset++;
-    }
-    pic16_aopOp(IC_RESULT(ic),ic,FALSE);  
-    size = AOP_SIZE(IC_RESULT(ic));
-    offset = 0;
-    while (size--) {
-      pic16_emitcode ("pop","acc");
-      pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
-    }
-       
-  } else {
-    _G.accInUse++;
-    pic16_aopOp(IC_RESULT(ic),ic,FALSE);  
-    _G.accInUse--;
-    assignResultValue(IC_RESULT(ic));  
-  }
+         int size = getSize(operandType(IC_RESULT(ic)));
+         int offset =  pic16_fReturnSizePic - size;
 
-  pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
+               while (size--) {
+                       pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
+                                       fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
+                       offset++;
+               }
+
+               DEBUGpic16_emitcode ("; ***","1 %s  %d",__FUNCTION__,__LINE__);
+
+               pic16_aopOp(IC_RESULT(ic),ic,FALSE);  
+               size = AOP_SIZE(IC_RESULT(ic));
+               offset = 0;
+               while (size--) {
+                       pic16_emitcode ("pop","acc");
+                       pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
+               }
+       } else {
+               DEBUGpic16_emitcode ("; ***","2 %s  %d",__FUNCTION__,__LINE__);
+
+               _G.accInUse++;
+               pic16_aopOp(IC_RESULT(ic),ic,FALSE);  
+               _G.accInUse--;
+               assignResultValue(IC_RESULT(ic));       
+       }
+
+       pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
 }
 
 /*-----------------------------------------------------------------*/
@@ -10014,11 +10196,6 @@ void genpic16Code (iCode *lic)
                         ic->level,ic->block);
                _G.debugLine = 0;
            }
-           /*
-             pic16_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
-             pic16_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, 
-             printCLine(ic->filename, ic->lineno));
-           */
            pic16_addpCode2pBlock(pb,
                            pic16_newpCodeCSource(ic->lineno, 
                                            ic->filename, 
@@ -10036,11 +10213,11 @@ void genpic16Code (iCode *lic)
        /* depending on the operation */
        switch (ic->op) {
        case '!' :
-           genNot(ic);
+           pic16_genNot(ic);
            break;
            
        case '~' :
-           genCpl(ic);
+           pic16_genCpl(ic);
            break;
            
        case UNARYMINUS:
@@ -10213,6 +10390,8 @@ void genpic16Code (iCode *lic)
            break;
            
        case SEND:
+             DEBUGpic16_emitcode(";ic ", "\t%c 0x%x\tSEND",ic->op, ic->op);
+
            addSet(&_G.sendSet,ic);
            break;
 
index 90294755b4a379bb409a7d0d5a3be744d6da9ba2..c37eebd69d8b8d1ba5ddf73915059a848fa1268a 100644 (file)
@@ -163,6 +163,7 @@ pCodeOp *pic16_popGetLabel(unsigned int key);
 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc);
 pCodeOp *pic16_popCopyGPR2Bit(pCodeOp *pc, int bitval);
 pCodeOp *pic16_popGetLit(unsigned int lit);
+pCodeOp *pic16_popGetLit2(unsigned int lit, unsigned int lit2);
 pCodeOp *popGetWithString(char *str);
 pCodeOp *pic16_popGet (asmop *aop, int offset);//, bool bit16, bool dname);
 pCodeOp *pic16_popGetTempReg(void);
index 9f6a859579a900255da5c32ce4df61ccb51700a4..79574276420fb8a15097a899948d5d5fc29bf2a7 100644 (file)
@@ -180,8 +180,8 @@ bool pic16_genPlusIncr (iCode *ic)
     
     DEBUGpic16_emitcode ("; ","%s  %d",__FUNCTION__,__LINE__);
     /* if the literal value of the right hand side
-       is greater than 1 then it is faster to add */
-    if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 1)          // this was > 2 why? VR
+       is greater than 2 then it is faster to add */
+    if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 2)
         return FALSE ;
     
     /* if increment 16 bits in register */
@@ -228,7 +228,6 @@ bool pic16_genPlusIncr (iCode *ic)
     }
 
 
-
     /* if the sizes are greater than 1 then we cannot */
     if (AOP_SIZE(IC_RESULT(ic)) > 1 ||
         AOP_SIZE(IC_LEFT(ic)) > 1   )
diff --git a/src/pic16/genutils.c b/src/pic16/genutils.c
new file mode 100644 (file)
index 0000000..3439a07
--- /dev/null
@@ -0,0 +1,161 @@
+/*-------------------------------------------------------------------------
+ genutils.c - source file for code generation for pic16
+       code generation utility functions
+
+       Created by Vangelis Rokas (vrokas@otenet.gr) [Nov-2003]
+
+       Based on :
+
+  Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
+         and -  Jean-Louis VERN.jlvern@writeme.com (1999)
+  Bug Fixes  -  Wojciech Stryjewski  wstryj1@tiger.lsu.edu (1999 v2.1.9a)
+  PIC port   -  Scott Dattalo scott@dattalo.com (2000)
+  PIC16 port -  Martin Dubuc m.dubuc@rogers.com (2002)
+  
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published by the
+  Free Software Foundation; either version 2, or (at your option) any
+  later version.
+  
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+  
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+  
+  In other words, you are welcome to use, share and improve this program.
+  You are forbidden to forbid anyone else to use, share and improve
+  what you give them.   Help stamp out software-hoarding!
+  
+  Notes:
+  000123 mlh   Moved aopLiteral to SDCCglue.c to help the split
+               Made everything static
+-------------------------------------------------------------------------*/
+
+/**********************************************************
+ * Here is a list with completed genXXXXX functions
+ *
+ * genNot
+ *
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "SDCCglobl.h"
+#include "newalloc.h"
+
+#include "common.h"
+#include "SDCCpeeph.h"
+#include "ralloc.h"
+#include "pcode.h"
+#include "gen.h"
+
+#include "genutils.h"
+
+
+#if defined(GEN_Not)
+/*-----------------------------------------------------------------*/
+/* pic16_genNot - generate code for ! operation                    */
+/*-----------------------------------------------------------------*/
+void pic16_genNot (iCode *ic)
+{
+  int size;
+
+/*
+ * result[AOP_CRY,AOP_REG]  = ! left[AOP_CRY, AOP_REG]
+ */
+
+       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+       /* assign asmOps to operand & result */
+       pic16_aopOp (IC_LEFT(ic),ic,FALSE);
+       pic16_aopOp (IC_RESULT(ic),ic,TRUE);
+       DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
+
+       /* if in bit space then a special case */
+       if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
+               if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
+                       pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
+                       pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
+               } else {
+                       pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
+                       pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
+                       pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
+               }
+               goto release;
+       }
+
+       size = AOP_SIZE(IC_LEFT(ic));
+       if(size == 1) {
+               pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
+               pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
+               pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
+               goto release;
+       }
+
+release:    
+       /* release the aops */
+       pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
+       pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
+}
+
+#endif /* defined(GEN_Not) */
+
+
+
+#if defined(GEN_Cpl)
+/*-----------------------------------------------------------------*/
+/* pic16_genCpl - generate code for complement                     */
+/*-----------------------------------------------------------------*/
+void pic16_genCpl (iCode *ic)
+{
+  int offset = 0;
+  int size ;
+
+/*
+ * result[CRY,REG] = ~left[CRY,REG]
+ */
+
+       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+       /* assign asmOps to operand & result */
+       pic16_aopOp (IC_LEFT(ic),ic,FALSE);
+       pic16_aopOp (IC_RESULT(ic),ic,TRUE);
+       DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
+
+       /* if both are in bit space then 
+          a special case */
+       if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
+               AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
+
+               /* FIXME */
+               pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); 
+               pic16_emitcode("cpl","c"); 
+               pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir); 
+               goto release; 
+       } 
+
+       size = AOP_SIZE(IC_RESULT(ic));
+       while (size--) {
+
+               if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
+                       pic16_emitpcode(POC_COMF,  pic16_popGet(AOP(IC_LEFT(ic)), offset));
+               } else {
+                       pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
+                       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
+               }
+               offset++;
+       }
+
+release:
+    /* release the aops */
+    pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
+    pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
+}
+#endif /* defined(GEN_Cpl) */
+
diff --git a/src/pic16/genutils.h b/src/pic16/genutils.h
new file mode 100644 (file)
index 0000000..f6dc45c
--- /dev/null
@@ -0,0 +1,33 @@
+
+/*
+** $Id$
+*/
+
+#ifndef __GENUTILS_H__
+#define __GENUTILS_H__
+
+
+#include "common.h"
+
+
+/*
+ * The various GEN_xxxxx macros handle which functions
+ * should be included in the gen.c source. We are going to use
+ * our own functions here so, they must be commentted out from
+ * gen.c
+ */
+
+#define GEN_Not
+void pic16_genNot(iCode *ic);
+
+#define GEN_Cpl
+void pic16_genCpl(iCode *ic);
+
+
+/*
+ * global function definitions
+ */
+void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result);
+
+
+#endif /* __GENUTILS_H__ */
index 0c3c7f3d919c304803fecc3d64481736f5aadb82..0d0407d06896c9e19ade81b9e012c463345050c0 100644 (file)
@@ -27,6 +27,8 @@
 #include "ralloc.h"
 #include "pcode.h"
 #include "newalloc.h"
+#include "device.h"
+#include "main.h"
 
 
 #ifdef WORDS_BIGENDIAN
@@ -41,6 +43,7 @@ extern symbol *interrupts[256];
 static void printIval (symbol * sym, sym_link * type, initList * ilist, pBlock *pb);
 extern int noAlloc;
 extern set *publics;
+extern set *externs;
 extern unsigned maxInterrupts;
 extern int maxRegBank;
 extern symbol *mainf;
@@ -65,6 +68,10 @@ extern void printPublics (FILE * afile);
 
 extern void printChar (FILE * ofile, char *s, int plen);
 void  pic16_pCodeInitRegisters(void);
+pCodeOp *pic16_popGetLit(unsigned int lit);
+pCodeOp *pic16_popGetLit2(unsigned int lit, unsigned int lit2);
+pCodeOp *pic16_popCopyReg(pCodeOpReg *pc);
+pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst);
 
 /*-----------------------------------------------------------------*/
 /* aopLiteral - string from a literal value                        */
@@ -94,7 +101,6 @@ int pic16aopLiteral (value *val, int offset)
 
 }
 
-
 /*-----------------------------------------------------------------*/
 /* emitRegularMap - emit code for maps with no special cases       */
 /*-----------------------------------------------------------------*/
@@ -104,7 +110,10 @@ pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
   symbol *sym;
   int i, size, bitvars = 0;;
 
+//     fprintf(stderr, "%s:%d map name= %s\n", __FUNCTION__, __LINE__, map->sname);
+       
   if (addPublics)
+
     fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
 
   /* print the area name */
@@ -112,9 +121,17 @@ pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
        sym = setNextItem (map->syms))
     {
 
-      /* if extern then do nothing */
-      if (IS_EXTERN (sym->etype))
+#if 0
+       fprintf(stderr, "\t%s: sym: %s\tused: %d\n", map->sname, sym->name, sym->used);
+       printTypeChain( sym->type, stderr );
+       printf("\n");
+#endif
+
+      /* if extern then add to externs */
+      if (IS_EXTERN (sym->etype)) {
+       addSetHead(&externs, sym);
        continue;
+      }
 
       /* if allocation required check is needed
          then check if the symbol really requires
@@ -126,7 +143,7 @@ pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
 
       /* if global variable & not static or extern
          and addPublics allowed then add it to the public set */
-      if ((sym->level == 0 ||
+      if ((sym->used) && (sym->level == 0 ||
           (sym->_isparm && !IS_REGPARM (sym->etype))) &&
          addPublics &&
          !IS_STATIC (sym->etype))
@@ -136,12 +153,13 @@ pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
          then do nothing */
       if (IS_FUNC (sym->type))
        continue;
+
 #if 0
       /* print extra debug info if required */
       if (options.debug || sym->level == 0)
        {
 
-         cdbSymbol (sym, cdbFile, FALSE, FALSE);
+         cdbWriteSymbol (sym); //, cdbFile, FALSE, FALSE);
 
          if (!sym->level)      /* global */
            if (IS_STATIC (sym->etype))
@@ -155,16 +173,40 @@ pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
        }
 #endif
 
+       /* FIXME -- VR
+        * The equates are nice, but do not allow relocatable objects to
+        * be created in the form that I (VR) want to make SDCC to work */
+
       /* if is has an absolute address then generate
          an equate for this no need to allocate space */
       if (SPEC_ABSA (sym->etype))
        {
          //if (options.debug || sym->level == 0)
-         //fprintf (map->oFile,"; == 0x%04x\n",SPEC_ADDR (sym->etype));
+//       fprintf (stderr,"; %s == 0x%04x\t\treqv= %p nRegs= %d\n",
+//             sym->name, SPEC_ADDR (sym->etype), sym->reqv, sym->regType);
 
          fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
                   sym->rname,
                   SPEC_ADDR (sym->etype));
+
+#if 1
+         /* emit only if it is global */
+         if(sym->level == 0) {
+           regs *reg;
+           operand *op;
+
+//             fprintf(stderr, "%s: implicit add of symbol = %s\n", __FUNCTION__, sym->name);
+               op = operandFromSymbol( sym );
+               reg = pic16_allocDirReg( op );
+               if(reg) {
+                       //continue;
+
+                       checkAddReg(&pic16_fix_udata, reg);
+                       /* and add to globals list */
+                       addSetHead(&publics, sym);
+               }
+         }
+#endif
        }
       else
        {
@@ -189,11 +231,25 @@ pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
          //fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
        }
        
-       /* if it has a initial value then do it only if
+
+       /* FIXME -- VR Fix the following, so that syms to be placed
+        * in the idata section and let linker decide about their fate */
+
+       /* if it has an initial value then do it only if
           it is a global variable */
+//     if(sym->ival && sym->level == 0) 
+               
+
+#if 1
        if (sym->ival && sym->level == 0) {
            ast *ival = NULL;
-           
+
+//             if(SPEC_OCLS(sym->etype)==data) {
+//                     fprintf(stderr, "%s: sym %s placed in data\n", map->sname, sym->name);
+//             }
+
+//             fprintf(stderr, "'%s': sym '%s' has initial value\n", map->sname, sym->name);
+
            if (IS_AGGREGATE (sym->type))
                ival = initAggregates (sym, sym->ival, NULL);
            else
@@ -204,6 +260,7 @@ pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
            eBBlockFromiCode (iCodeFromAst (ival));
            sym->ival = NULL;
        }
+#endif
     }
 }
 
@@ -435,6 +492,14 @@ pic16emitStaticSeg (memmap * map)
   for (sym = setFirstItem (map->syms); sym;
        sym = setNextItem (map->syms))
     {
+
+#if 1
+       fprintf(stderr, "\t%s: sym: %s\tused: %d\n", map->sname, sym->name, sym->used);
+       printTypeChain( sym->type, stderr );
+       printf("\n");
+#endif
+
+
       /* if it is "extern" then do nothing */
       if (IS_EXTERN (sym->etype))
        continue;
@@ -545,7 +610,6 @@ pic16emitMaps ()
 static void
 pic16createInterruptVect (FILE * vFile)
 {
-  unsigned i = 0;
   mainf = newSymbol ("main", 0);
   mainf->block = 0;
 
@@ -566,35 +630,18 @@ pic16createInterruptVect (FILE * vFile)
       return;
     }
 
-/*
- * update started by Vangelis Rokas on 19-Jun-2003
- * all fprintf() calls are prefixed with ';' so they seem
- * as comments to the assembler. I (VR) removed them */
-
-//  fprintf (vFile, "\t.area\t%s\n", CODE_NAME);
-       fprintf(vFile, "\tcode\t0x0000\n");
-  fprintf (vFile, "__interrupt_vect:\n");
-
-
-  if (!port->genIVT || !(port->genIVT (vFile, interrupts, maxInterrupts)))
-    {
-      /* "generic" interrupt table header (if port doesn't specify one).
+       if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
+               fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
+               fprintf(vFile, ".intvecs\tcode\t0x0000\n");
+               fprintf (vFile, "__interrupt_vect:\n");
 
-       * Look suspiciously like 8051 code to me...
-       */
-
-      fprintf (vFile, ";\tljmp\t__sdcc_gsinit_startup\n");
-
-
-      /* now for the other interrupts */
-      for (; i < maxInterrupts; i++)
-       {
-         if (interrupts[i])
-           fprintf (vFile, ";\tljmp\t%s\n;\t.ds\t5\n", interrupts[i]->rname);
-         else
-           fprintf (vFile, ";\treti\n;\t.ds\t7\n");
+               /* this is an overkill since WE are the port,
+                * and we know if we have a genIVT function! */
+               if(port->genIVT) {
+                       port->genIVT(vFile, interrupts, maxInterrupts);
+               }
        }
-    }
+       
 }
 
 
@@ -611,23 +658,36 @@ pic16initialComments (FILE * afile)
 }
 
 /*-----------------------------------------------------------------*/
-/* printPublics - generates .global for publics                    */
+/* printPublics - generates global declarations for publics        */
 /*-----------------------------------------------------------------*/
 static void
 pic16printPublics (FILE * afile)
 {
   symbol *sym;
 
-  fprintf (afile, "%s", iComments2);
-  fprintf (afile, "; publics variables in this module\n");
-  fprintf (afile, "%s", iComments2);
+       fprintf (afile, "%s", iComments2);
+       fprintf (afile, "; publics variables in this module\n");
+       fprintf (afile, "%s", iComments2);
 
-  for (sym = setFirstItem (publics); sym;
-       sym = setNextItem (publics))
-    fprintf (afile, ";\t.globl %s\n", sym->rname);
+       for (sym = setFirstItem (publics); sym; sym = setNextItem (publics))
+               fprintf(afile, "\tglobal %s\n", sym->rname);
 }
 
+/*-----------------------------------------------------------------*/
+/* printExterns - generates extern declarations for externs        */
+/*-----------------------------------------------------------------*/
+static void
+pic16_printExterns(FILE *afile)
+{
+  symbol *sym;
 
+       fprintf(afile, "%s", iComments2);
+       fprintf(afile, "; extern variables to this module\n");
+       fprintf(afile, "%s", iComments2);
+       
+       for(sym = setFirstItem(externs); sym; sym = setNextItem(externs))
+               fprintf(afile, "\textern %s\n", sym->rname);
+}
 
 /*-----------------------------------------------------------------*/
 /* emitOverlay - will emit code for the overlay stuff              */
@@ -771,6 +831,17 @@ pic16glue ()
     }
   }
 
+#if STACK_SUPPORT
+       if(USE_STACK) {
+         pBlock *pb = pic16_newpCodeChain(NULL, 'X', pic16_newpCodeCharP("; Setup stack & frame register"));
+
+               pic16_addpBlock(pb);
+               pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR, pic16_popGetLit2(1, stackPos)));
+               pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR, pic16_popGetLit2(2, stackPos)));
+
+       }
+#endif
+
 
   /* At this point we've got all the code in the form of pCode structures */
   /* Now it needs to be rearranged into the order it should be placed in the */
@@ -790,7 +861,8 @@ pic16glue ()
   /* PENDING: this isnt the best place but it will do */
   if (port->general.glue_up_main) {
     /* create the interrupt vector table */
-    pic16createInterruptVect (vFile);
+
+       pic16createInterruptVect (vFile);
   }
 
   addSetHead(&tmpfileSet,vFile);
@@ -803,17 +875,21 @@ pic16glue ()
 
        pic16_AnalyzepCode('*');
 
-  //#ifdef PCODE_DEBUG
-  //pic16_printCallTree(stderr);
-  //#endif
+#if 0
+       {
+         FILE *cFile;
+               sprintf(buffer, dstFileName);
+               strcat(buffer, ".calltree");
+               cFile = fopen(buffer, "w");
+               pic16_printCallTree( cFile );
+               fclose(cFile);
+       }
+#endif
 
   pic16_InlinepCode();
-
   pic16_AnalyzepCode('*');
-
   pic16_pcode_test();
 
-
   /* now put it all together into the assembler file */
   /* create the assembler file name */
     
@@ -844,15 +920,19 @@ pic16glue ()
       port->genAssemblerPreamble(asmFile);
     }
     
+  /* print the extern variables to this module */
+  pic16_printExterns(asmFile);
+  
   /* print the global variables in this module */
   pic16printPublics (asmFile);
-    
 
+#if 0
   /* copy the sfr segment */
   fprintf (asmFile, "%s", iComments2);
   fprintf (asmFile, "; special function registers\n");
   fprintf (asmFile, "%s", iComments2);
   copyFile (asmFile, sfr->oFile);
+#endif
     
 
   /* Put all variables into a cblock */
@@ -871,15 +951,21 @@ pic16glue ()
     fprintf (asmFile, "; Stack segment in internal ram \n");
     fprintf (asmFile, "%s", iComments2);    
     fprintf (asmFile, ";\t.area\tSSEG\t(DATA)\n"
-            ";__start__stack:\n;\t.ds\t1\n\n");
+       ";__start__stack:\n;\t.ds\t1\n\n");
   }
 
+#if 0
+       /* no indirect data in pic */
   /* create the idata segment */
   fprintf (asmFile, "%s", iComments2);
   fprintf (asmFile, "; indirectly addressable internal ram data\n");
   fprintf (asmFile, "%s", iComments2);
   copyFile (asmFile, idata->oFile);
-    
+#endif
+
+
+#if 0
+       /* no xdata in pic */
   /* if external stack then reserve space of it */
   if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
     fprintf (asmFile, "%s", iComments2);
@@ -888,14 +974,16 @@ pic16glue ()
     fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
     fprintf (asmFile,";\t.ds 256\n");
   }
-       
-       
+#endif
+
+#if 0  
+       /* no xdata in pic */
   /* copy xtern ram data */
   fprintf (asmFile, "%s", iComments2);
   fprintf (asmFile, "; external ram data\n");
   fprintf (asmFile, "%s", iComments2);
   copyFile (asmFile, xdata->oFile);
-    
+#endif
 
   /* copy the bit segment */
   fprintf (asmFile, "%s", iComments2);
@@ -906,7 +994,6 @@ pic16glue ()
 
 /* the following is commented out. the CODE directive will be
    used instead before code */
-   
 //  fprintf (asmFile, "\tORG 0\n");
 
   /* copy the interrupt vector table */
@@ -922,6 +1009,8 @@ pic16glue ()
   fprintf (asmFile, "; global & static initialisations\n");
   fprintf (asmFile, "%s", iComments2);
     
+#if 0
+  /* FIXME 8051 Legacy -- VR */
   /* Everywhere we generate a reference to the static_name area, 
    * (which is currently only here), we immediately follow it with a 
    * definition of the post_static_name area. This guarantees that
@@ -931,12 +1020,13 @@ pic16glue ()
   fprintf (asmFile, ";\t.area %s\n", port->mem.static_name); /* MOF */
   fprintf (asmFile, ";\t.area %s\n", port->mem.post_static_name);
   fprintf (asmFile, ";\t.area %s\n", port->mem.static_name);
+#endif
 
   if (mainf && IFFUNC_HASBODY(mainf->type)) {
     fprintf (asmFile,"__sdcc_gsinit_startup:\n");
 
 #if 0
-       /* 8051 legacy (?!) - VR 20-Jun-2003 */
+       /* FIXME 8051 legacy (?!) - VR 20-Jun-2003 */
     /* if external stack is specified then the
        higher order byte of the xdatalocation is
        going into P2 and the lower order going into
@@ -951,25 +1041,26 @@ pic16glue ()
 
   }
 
+  /* copy over code */
+  fprintf (asmFile, "%s", iComments2);
+  fprintf (asmFile, "\tcode\n");
+  fprintf (asmFile, "%s", iComments2);
+  fprintf (asmFile, ";\t.area %s\n", port->mem.code_name);
+
   if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type))
     {
       /* This code is generated in the post-static area.
        * This area is guaranteed to follow the static area
        * by the ugly shucking and jiving about 20 lines ago.
        */
-      fprintf(asmFile, ";\t.area %s\n", port->mem.post_static_name);
+//      fprintf(asmFile, ";\t.area %s\n", port->mem.post_static_name);
       fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
     }
        
-  /* copy over code */
-  fprintf (asmFile, "%s", iComments2);
-  fprintf (asmFile, "; code\n");
-  fprintf (asmFile, "%s", iComments2);
-  fprintf (asmFile, ";\t.area %s\n", port->mem.code_name);
 
   //copyFile (stderr, code->oFile);
 
-//             fprintf(asmFile, "; I code from now on!\n");
+               fprintf(asmFile, "; I code from now on!\n");
        pic16_copypCode(asmFile, 'I');
 
        
@@ -979,9 +1070,12 @@ pic16glue ()
 
                fprintf(asmFile, "; X code from now on!\n");
        pic16_copypCode(asmFile, 'X');
+
                fprintf(asmFile, "; M code from now on!\n");
        pic16_copypCode(asmFile, 'M');
+
        pic16_copypCode(asmFile, code->dbName);
+
        pic16_copypCode(asmFile, 'P');
 
        fprintf (asmFile,"\tend\n");
index 772b6d411d1d4caf9317f73a5fb757d678170395..71cf8b2b07292b92ec095259b3a614c289eb2083 100644 (file)
@@ -67,6 +67,9 @@ static char *_pic16_keywords[] =
 };
 
 
+pic16_sectioninfo_t pic16_sectioninfo;
+
+
 extern char *pic16_processor_base_name(void);
 
 void  pic16_pCodeInitRegisters(void);
@@ -75,12 +78,24 @@ void pic16_assignRegisters (eBBlock ** ebbs, int count);
 
 static int regParmFlg = 0;     /* determine if we can register a parameter */
 
+pic16_options_t pic16_options;
+
 static void
 _pic16_init (void)
 {
-  asm_addTree (&asm_asxxxx_mapping);
-  pic16_pCodeInitRegisters();
-  maxInterrupts = 2;
+       asm_addTree (&asm_asxxxx_mapping);
+       pic16_pCodeInitRegisters();
+       maxInterrupts = 2;
+       
+
+       /* set pic16 port options to defaults */
+       pic16_options.gen_banksel = 0;
+       pic16_options.opt_banksel = 0;
+       pic16_options.omit_configw = 0;
+       pic16_options.omit_ivt = 0;
+       pic16_options.leave_reset = 0;
+       pic16_options.enable_stack = 0;
+       pic16_options.stack_model = 0;                  /* 0 for 'small', 1 for 'large' */
 }
 
 static void
@@ -101,76 +116,256 @@ _pic16_regparm (sym_link * l)
   return 1;
 }
 
+
 static int
 _process_pragma(const char *sz)
 {
   static const char *WHITE = " \t";
   char *ptr = strtok((char *)sz, WHITE);
 
-  if (startsWith (ptr, "memmap"))
-    {
-      char     *start;
-      char     *end;
-      char     *type;
-      char     *alias;
-
-      start = strtok((char *)NULL, WHITE);
-      end = strtok((char *)NULL, WHITE);
-      type = strtok((char *)NULL, WHITE);
-      alias = strtok((char *)NULL, WHITE);
-
-      if (start != (char *)NULL
-         && end != (char *)NULL
-         && type != (char *)NULL) {
-       value           *startVal = constVal(start);
-       value           *endVal = constVal(end);
-       value           *aliasVal;
-       memRange        r;
-
-       if (alias == (char *)NULL) {
-         aliasVal = constVal(0);
-       } else {
-         aliasVal = constVal(alias);
+       if (startsWith (ptr, "maxram")) {
+         char *maxRAM = strtok((char *)NULL, WHITE);
+
+               if (maxRAM != (char *)NULL) {
+                 int maxRAMaddress;
+                 value *maxRAMVal;
+
+                       maxRAMVal = constVal(maxRAM);
+                       maxRAMaddress = (int)floatFromVal(maxRAMVal);
+                       pic16_setMaxRAM(maxRAMaddress);
+               }
        }
+       
+       if(startsWith(ptr, "stack")) {
+         char *stackPosS = strtok((char *)NULL, WHITE);
+         value *stackPosVal;
 
-       r.start_address = (int)floatFromVal(startVal);
-       r.end_address = (int)floatFromVal(endVal);
-       r.alias = (int)floatFromVal(aliasVal);
-       r.bank = (r.start_address >> 7) & 0xf;
-
-       if (strcmp(type, "RAM") == 0) {
-         pic16_addMemRange(&r, 0);
-       } else if (strcmp(type, "SFR") == 0) {
-         pic16_addMemRange(&r, 1);
-       } else {
-         return 1;
+//             fprintf(stderr, "Initializing stack pointer to 0x%x\n", (int)floatFromVal(constVal(stackPos)));
+               stackPosVal = constVal( stackPosS );
+               stackPos = (unsigned int)floatFromVal( stackPosVal );
        }
-      }
 
-      return 0;
-    } else if (startsWith (ptr, "maxram")) {
-      char *maxRAM = strtok((char *)NULL, WHITE);
+  return 0;
+}
+
+#define REP_UDATA      "--preplace-udata-with="
+#define REP_UDATAACS   "--preplace-udata-acs-with="
+#define REP_UDATAOVR   "--preplace-udata-ovr-with="
+#define REP_UDATASHR   "--preplace-udata-sht-with="
+
+#define NAME_CODE      "--psection-code-name="
+#define NAME_IDATA     "--psection-idata-name="
+#define NAME_UDATA     "--psection-udata-name="
+#define NAME_UDATAACS  "--psection-udata-acs-name="
+#define NAME_UDATAOVR  "--psection-udata-ovr-name="
+#define NAME_UDATASHR  "--psection-udata-shr-name="
 
-      if (maxRAM != (char *)NULL) {
-       int     maxRAMaddress;
-       value   *maxRAMVal;
+#define ADDR_CODE      "--psection-code-addr="
+#define ADDR_IDATA     "--psection-idata-addr="
+#define ADDR_UDATA     "--psection-udata-addr="
+#define ADDR_UDATAACS  "--psection-udata-acs-addr="
+#define ADDR_UDATAOVR  "--psection-udata-ovr-addr="
+#define ADDR_UDATASHR  "--psection-udata-shr-addr="
 
-       maxRAMVal = constVal(maxRAM);
-       maxRAMaddress = (int)floatFromVal(maxRAMVal);
-       pic16_setMaxRAM(maxRAMaddress);
-      }
+#define STACK_MODEL    "--pstack-model="
+#define OPT_BANKSEL    "--obanksel="
+
+
+extern int pic16_debug_verbose;
+
+OPTION pic16_optionsTable[]= {
+       { 0,    "--pgen-banksel",       &pic16_options.gen_banksel,     "generate BANKSEL assembler directives"},
+       { 0,    OPT_BANKSEL,            NULL,                           "set banksel optimization level (default=0 no)"},
+       { 0,    "--pomit-config-words", &pic16_options.omit_configw,    "omit the generation of configuration words"},
+       { 0,    "--pomit-ivt",          &pic16_options.omit_ivt,        "omit the generation of the Interrupt Vector Table"},
+       { 0,    "--pleave-reset-vector",&pic16_options.leave_reset,     "when omitting IVT leave RESET vector"},
+       { 0,    "--penable-stack",      &pic16_options.enable_stack,    "enable the use of stack"},
+       { 0,    STACK_MODEL,    NULL,   "use stack model 'small' (default) or 'large'"},
+
+       { 0,    "--debug-xtra",         &pic16_debug_verbose,   "show more debug info in assembly output"},
+       { 0,    REP_UDATA,      NULL,   "Place udata variables at another section: udata_acs, udata_ovr, udata_shr"},
+
+#if 0
+       /* these may not be in any use -- VR */
+       { 0,    AT_UDATAACS,    NULL,   "Emit udata_acs variables at another section"},
+       { 0,    AT_UDATAOVR,    NULL,   "Emit udata_ovr variables at another section"},
+       { 0,    AT_UDATASHR,    NULL,   "Emit udata_shr variables at another section"},
+#endif
+
+#if 0
+       /* commented out for the time being -- VR */
+       { 0,    NAME_CODE,      NULL,   "Set code section name[,address]"},
+       { 0,    NAME_IDATA,     NULL,   "Set idata section name[,address]"},
+       { 0,    NAME_UDATA,     NULL,   "Set udata section name[,address]"},
+       { 0,    NAME_UDATAACS,  NULL,   "Set udata_acs section name[,address]"},
+       { 0,    NAME_UDATAOVR,  NULL,   "Set udata_ovr section name[,address]"},
+       { 0,    NAME_UDATASHR,  NULL,   "Set udata_shr section name[,address]"},
        
-      return 0;
-    }
-  return 1;
-}
+       { 0,    ADDR_CODE,      NULL,   "Set code section address"},
+       { 0,    ADDR_IDATA,     NULL,   "Set idata section address"},
+       { 0,    ADDR_UDATA,     NULL,   "Set udata section address"},
+       { 0,    ADDR_UDATAACS,  NULL,   "Set udata_acs section address"},
+       { 0,    ADDR_UDATAOVR,  NULL,   "Set udata_ovr section address"},
+       { 0,    ADDR_UDATASHR,  NULL,   "Set udata_shr section address"},
+#endif
+
+       { 0,    NULL,           NULL,   NULL}
+       };
+
+
+#define ISOPT(str)     !strncmp(argv[ *i ], str, strlen(str) )
+
+extern char *getStringArg(const char *,  char **, int *, int);
+extern int getIntArg(const char *, char **, int *, int);
 
 static bool
 _pic16_parseOptions (int *pargc, char **argv, int *i)
 {
+  int j=0;
+//  set *tset;
+
   /* TODO: allow port-specific command line options to specify
    * segment names here.
    */
+       /* check for arguments that have associated an integer variable */
+       while(pic16_optionsTable[j].pparameter) {
+               if(ISOPT( pic16_optionsTable[j].longOpt )) {
+                       (*pic16_optionsTable[j].pparameter)++;
+                       return TRUE;
+               }
+               j++;
+       }
+
+
+       if(ISOPT(STACK_MODEL)) {
+               switch(*getStringArg(STACK_MODEL, argv, i, *pargc)) {
+                       case 's': pic16_options.stack_model = 0; break;
+                       case 'l': pic16_options.stack_model = 1; break;
+                       
+                       default:
+                               fprintf(stderr, "Unknown stack model");
+                               exit(-1);
+               }
+               return TRUE;
+       }
+
+       if(ISOPT(OPT_BANKSEL)) {
+               pic16_options.opt_banksel = getIntArg(OPT_BANKSEL, argv, i, *pargc);
+               return TRUE;
+       }
+
+       if(ISOPT(REP_UDATA)) {
+               pic16_sectioninfo.at_udata = Safe_strdup(getStringArg(REP_UDATA, argv, i, *pargc));
+               return TRUE;
+       }
+       
+/*
+       if(ISOPT(AT_UDATAACS)) {
+               pic16_sectioninfo.at_udataacs = Safe_strdup( getStringArg(AT_UDATAACS, argv, i, *pargc));
+               return TRUE;
+       }
+
+       if(ISOPT(AT_UDATAOVR)) {
+               pic16_sectioninfo.at_udataovr = Safe_strdup( getStringArg(AT_UDATAOVR, argv, i, *pargc));
+               return TRUE;
+       }
+       
+       if(ISOPT(AT_UDATASHR)) {
+               pic16_sectioninfo.at_udatashr = Safe_strdup( getStringArg(AT_UDATASHR, argv, i, *pargc));
+               return TRUE;
+       }
+*/
+
+#if 0
+       if(ISOPT(ADDR_CODE)) {
+               pic16_sectioninfo.addr_code = getIntArg(ADDR_CODE, argv, i, *pargc);
+               return TRUE;
+       }
+       
+       if(ISOPT(ADDR_IDATA)) {
+               pic16_sectioninfo.addr_idata = getIntArg(ADDR_IDATA, argv, i, *pargc);
+               return TRUE;
+       }
+       
+       if(ISOPT(ADDR_UDATA)) {
+               pic16_sectioninfo.addr_udata = getIntArg(ADDR_UDATA, argv, i, *pargc);
+               return TRUE;
+       }
+       
+       if(ISOPT(ADDR_UDATAACS)) {
+               pic16_sectioninfo.addr_udataacs = getIntArg(ADDR_UDATAACS, argv, i, *pargc);
+               return TRUE;
+       }
+       
+       if(ISOPT(ADDR_UDATAOVR)) {
+               pic16_sectioninfo.addr_udataovr = getIntArg(ADDR_UDATAOVR, argv, i, *pargc);
+               return TRUE;
+       }
+       
+       if(ISOPT(ADDR_UDATASHR)) {
+               pic16_sectioninfo.addr_udatashr = getIntArg(ADDR_UDATASHR, argv, i, *pargc);
+               return TRUE;
+       }
+
+       tset = newSet();
+       
+       if(ISOPT(NAME_CODE)) {
+               setParseWithComma(&tset, getStringArg(NAME_CODE, argv, i, *pargc));
+               if(elementsInSet(tset) > 0)
+                       pic16_sectioninfo.name_code = Safe_strdup( (char *)indexSet(tset, 0));
+               if(elementsInSet(tset) > 1)
+                       pic16_sectioninfo.addr_code = atoi( (char *)indexSet(tset, 1));
+               return TRUE;
+       }
+
+       if(ISOPT(NAME_IDATA)) {
+               setParseWithComma(&tset, getStringArg(NAME_IDATA, argv, i, *pargc));
+               if(elementsInSet(tset) > 0)
+                       pic16_sectioninfo.name_idata = Safe_strdup( (char *)indexSet(tset, 0));
+               if(elementsInSet(tset) > 1)
+                       pic16_sectioninfo.addr_idata = atoi( (char *)indexSet(tset, 1));
+               return TRUE;
+       }
+
+       if(ISOPT(NAME_UDATA)) {
+               setParseWithComma(&tset, getStringArg(NAME_UDATA, argv, i, *pargc));
+               if(elementsInSet(tset) > 0)
+                       pic16_sectioninfo.name_udata = Safe_strdup( (char *)indexSet(tset, 0));
+               if(elementsInSet(tset) > 1)
+                       pic16_sectioninfo.addr_udata = atoi( (char *)indexSet(tset, 1));
+               return TRUE;
+       }
+
+       if(ISOPT(NAME_UDATAACS)) {
+               setParseWithComma(&tset, getStringArg(NAME_UDATAACS, argv, i, *pargc));
+               if(elementsInSet(tset) > 0)
+                       pic16_sectioninfo.name_udataacs = Safe_strdup( (char *)indexSet(tset, 0));
+               if(elementsInSet(tset) > 1)
+                       pic16_sectioninfo.addr_udataacs = atoi( (char *)indexSet(tset, 1));
+               return TRUE;
+       }
+
+       if(ISOPT(NAME_UDATAOVR)) {
+               setParseWithComma(&tset, getStringArg(NAME_UDATAOVR, argv, i, *pargc));
+               if(elementsInSet(tset) > 0)
+                       pic16_sectioninfo.name_udataovr = Safe_strdup( (char *)indexSet(tset, 0));
+               if(elementsInSet(tset) > 1)
+                       pic16_sectioninfo.addr_udataovr = atoi( (char *)indexSet(tset, 1));
+               return TRUE;
+       }
+
+       if(ISOPT(NAME_UDATASHR)) {
+               setParseWithComma(&tset, getStringArg(NAME_UDATASHR, argv, i, *pargc));
+               if(elementsInSet(tset) > 0)
+                       pic16_sectioninfo.name_udatashr = Safe_strdup( (char *)indexSet(tset, 0));
+               if(elementsInSet(tset) > 1)
+                       pic16_sectioninfo.addr_udatashr = atoi( (char *)indexSet(tset, 1));
+               return TRUE;
+       }
+
+       deleteSet( &tset );
+#endif
+
   return FALSE;
 }
 
@@ -246,6 +441,27 @@ _pic16_finaliseOptions (void)
 static void
 _pic16_setDefaultOptions (void)
 {
+       /* initialize to defaults section locations, names and addresses */
+       pic16_sectioninfo.at_udata      = "udata";
+       pic16_sectioninfo.at_udataacs   = "udata_acs";
+       pic16_sectioninfo.at_udataovr   = "udata_ovr";
+       pic16_sectioninfo.at_udatashr   = "udata_shr";
+
+       /* initialize to nothing, so let linker decide about their names */
+       pic16_sectioninfo.name_code     =
+       pic16_sectioninfo.name_idata    =
+       pic16_sectioninfo.name_udata    =
+       pic16_sectioninfo.name_udataacs =
+       pic16_sectioninfo.name_udataovr =
+       pic16_sectioninfo.name_udatashr = "";
+
+       /* initialize to -1, so let linker decide about their address */
+       pic16_sectioninfo.addr_code     =
+       pic16_sectioninfo.addr_idata    =
+       pic16_sectioninfo.addr_udata    =
+       pic16_sectioninfo.addr_udataacs =
+       pic16_sectioninfo.addr_udataovr =
+       pic16_sectioninfo.addr_udatashr = -1;
 }
 
 static const char *
@@ -257,32 +473,42 @@ _pic16_getRegName (struct regs *reg)
 }
 
 
-static void
-_pic16_genAssemblerPreamble (FILE * of)
+#if 0
+static  char *_pic16_mangleFunctionName(char *sz)
 {
-  char * name = pic16_processor_base_name();
+       fprintf(stderr, "mangled function name: %s\n", sz);
 
-  if(!name) {
+  return sz;
+}
+#endif
 
-    name = "p18f452";
-    fprintf(stderr,"WARNING: No Pic has been selected, defaulting to %s\n",name);
-  }
 
-  fprintf (of, "\tlist\tp=%s\n",&name[1]);
-  fprintf (of, "\tinclude \"%s.inc\"\n",name);
+static void
+_pic16_genAssemblerPreamble (FILE * of)
+{
+  char *name = pic16_processor_base_name();
 
-  fprintf (of, "\t__config _CONFIG1H,0x%x\n",pic16_getConfigWord(0x300001));
-  fprintf (of, "\t__config _CONFIG2L,0x%x\n",pic16_getConfigWord(0x300002));
-  fprintf (of, "\t__config _CONFIG2H,0x%x\n",pic16_getConfigWord(0x300003));
-  fprintf (of, "\t__config _CONFIG3H,0x%x\n",pic16_getConfigWord(0x300005));
-  fprintf (of, "\t__config _CONFIG4L,0x%x\n",pic16_getConfigWord(0x300006));
-  fprintf (of, "\t__config _CONFIG5L,0x%x\n",pic16_getConfigWord(0x300008));
-  fprintf (of, "\t__config _CONFIG5H,0x%x\n",pic16_getConfigWord(0x300009));
-  fprintf (of, "\t__config _CONFIG6L,0x%x\n",pic16_getConfigWord(0x30000a));
-  fprintf (of, "\t__config _CONFIG6H,0x%x\n",pic16_getConfigWord(0x30000b));
-  fprintf (of, "\t__config _CONFIG7L,0x%x\n",pic16_getConfigWord(0x30000c));
-  fprintf (of, "\t__config _CONFIG7H,0x%x\n",pic16_getConfigWord(0x30000d));
+       if(!name) {
+               name = "p18f452";
+               fprintf(stderr,"WARNING: No Pic has been selected, defaulting to %s\n",name);
+       }
 
+       fprintf (of, "\tlist\tp=%s\n",&name[1]);
+
+       if(!pic16_options.omit_configw) {
+               fprintf (of, "\t__config 0x%x,0x%x\n", 0x300001, pic16_getConfigWord(0x300001));
+               fprintf (of, "\t__config 0x%x,0x%x\n", 0x300002, pic16_getConfigWord(0x300002));
+               fprintf (of, "\t__config 0x%x,0x%x\n", 0x300003, pic16_getConfigWord(0x300003));
+               fprintf (of, "\t__config 0x%x,0x%x\n", 0x300005, pic16_getConfigWord(0x300005));
+               fprintf (of, "\t__config 0x%x,0x%x\n", 0x300006, pic16_getConfigWord(0x300006));
+               fprintf (of, "\t__config 0x%x,0x%x\n", 0x300008, pic16_getConfigWord(0x300008));
+               fprintf (of, "\t__config 0x%x,0x%x\n", 0x300009, pic16_getConfigWord(0x300009));
+               fprintf (of, "\t__config 0x%x,0x%x\n", 0x30000a, pic16_getConfigWord(0x30000a));
+               fprintf (of, "\t__config 0x%x,0x%x\n", 0x30000b, pic16_getConfigWord(0x30000b));
+               fprintf (of, "\t__config 0x%x,0x%x\n", 0x30000c, pic16_getConfigWord(0x30000c));
+               fprintf (of, "\t__config 0x%x,0x%x\n", 0x30000d, pic16_getConfigWord(0x30000d));
+       }
+       
   fprintf (of, "\tradix dec\n");
 }
 
@@ -290,55 +516,34 @@ _pic16_genAssemblerPreamble (FILE * of)
 static int
 _pic16_genIVT (FILE * of, symbol ** interrupts, int maxInterrupts)
 {
-#if 0
-  int i;
-#endif
-
-#if 0
-       if (options.model != MODEL_FLAT24) {
-       /* Let the default code handle it. */
-         return FALSE;
-       }
-#endif
-
        /* PIC18F family has only two interrupts, the high and the low
         * priority interrupts, which reside at 0x0008 and 0x0018 respectively - VR */
 
-       fprintf(of, "; RESET vector\n");
-       fprintf(of, "\tgoto\t__sdcc_gsinit_startup\n");
-       fprintf(of, "\tres 4\n");
-
-
-       fprintf(of, "; High priority interrupt vector 0x0008\n");
-       if(interrupts[1]) {
-               fprintf(of, "\tgoto\t%s\n", interrupts[1]->rname);
-               fprintf(of, "\tres\t12\n"); 
-       } else {
-               fprintf(of, "\tretfie\n");
-               fprintf(of, "\tres\t14\n");
+       if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
+               fprintf(of, "; RESET vector\n");
+               fprintf(of, "\tgoto\t__sdcc_gsinit_startup\n");
        }
-
-       fprintf(of, "; Low priority interrupt vector 0x0018\n");
-       if(interrupts[2]) {
-               fprintf(of, "\tgoto\t%s\n", interrupts[2]->rname);
-       } else {
-               fprintf(of, "\tretfie\n");
-       }
-#if 0
-  /* now for the other interrupts */
-  for (i = 0; i < maxInterrupts; i++)
-    {
-       fprintf(of, "; %s priority interrupt vector 0x%s\n", (i==0)?"high":"low", (i==0)?"0008":"0018");
-      if (interrupts[i])
-       {
-         fprintf (of, "\tgoto\t%s\n\tres\t4\n", interrupts[i]->rname);
-       }
-      else
-       {
-         fprintf (of, "\tretfie\n\tres\t7\n");
+       
+       if(!pic16_options.omit_ivt) {
+               fprintf(of, "\tres 4\n");
+
+
+               fprintf(of, "; High priority interrupt vector 0x0008\n");
+               if(interrupts[1]) {
+                       fprintf(of, "\tgoto\t%s\n", interrupts[1]->rname);
+                       fprintf(of, "\tres\t12\n"); 
+               } else {
+                       fprintf(of, "\tretfie\n");
+                       fprintf(of, "\tres\t14\n");
+               }
+
+               fprintf(of, "; Low priority interrupt vector 0x0018\n");
+               if(interrupts[2]) {
+                       fprintf(of, "\tgoto\t%s\n", interrupts[2]->rname);
+               } else {
+                       fprintf(of, "\tretfie\n");
+               }
        }
-    }
-#endif
 
   return TRUE;
 }
@@ -440,7 +645,7 @@ PORT pic16_port =
   TARGET_ID_PIC16,
   "pic16",
   "MCU PIC16",                 /* Target name */
-  "p18f442",                    /* Processor */
+  "p18f452",                    /* Processor */
   {
     pic16glue,
     TRUE,                      /* Emit glue around main */
@@ -448,32 +653,35 @@ PORT pic16_port =
     MODEL_SMALL
   },
   {
-    _asmCmd,
-    NULL,
-    NULL,
-    NULL,
-       //"-plosgffc",          /* Options with debug */
-       //"-plosgff",           /* Options without debug */
-    0,
-    ".asm",
+    _asmCmd,                   /* assembler command and arguments */
+    NULL,                      /* alternate macro based form */
+    NULL,                      /* arguments for debug mode */
+    NULL,                      /* arguments for normal mode */
+    0,                         /* print externs as global */
+    ".asm",                    /* assembler file extension */
     NULL                       /* no do_assemble function */
   },
   {
-    _linkCmd,
-    NULL,
-    NULL,
-    ".rel"
+    _linkCmd,                  /* linker command and arguments */
+    NULL,                      /* alternate macro based form */
+    NULL,                      /* no do_link function */
+    ".rel"                     /* extension for object files */
   },
   {
     _defaultRules
   },
   {
-       /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
-    1, 2, 2, 4, 2, 2, 2, 1, 4, 4
-       /* TSD - I changed the size of gptr from 3 to 1. However, it should be
-          2 so that we can accomodate the PIC's with 4 register banks (like the
-          16f877)
-        */
+       /* Sizes */
+    1,         /* char */
+    2,         /* short */
+    2,         /* int */
+    4,         /* long */
+    2,         /* ptr */
+    2,         /* fptr, this should be changed to 3 for far pointers (see Microchip) */
+    2,         /* gptr */
+    1,         /* bit */
+    4,         /* float */
+    4          /* max */
   },
   {
     "XSEG    (XDATA)",         // xstack
@@ -492,11 +700,20 @@ PORT pic16_port =
     NULL,                      // xinit
     NULL,                      // default location for auto vars
     NULL,                      // default location for global vars
-    1                          // code is read only
+    1                          // code is read only 1=yes
+  },
+  {
+    NULL,              /* genExtraAreaDeclaration */
+    NULL               /* genExatrAreaLinkOptions */
   },
-  { NULL, NULL },
   {
-    +1, 1, 4, 1, 1, 0
+       /* stack related information */
+    -1,                        /* -1 stack grows downwards, +1 upwards */
+    1,                 /* extra overhead when calling between banks */
+    4,                 /* extra overhead when the function is an ISR */
+    1,                 /* extra overhead for a function call */
+    1,                 /* re-entrant space */
+    0                  /* 'banked' call overhead, mild overlap with bank_overhead */
   },
     /* pic16 has an 8 bit mul */
   {
@@ -505,7 +722,7 @@ PORT pic16_port =
   "_",
   _pic16_init,
   _pic16_parseOptions,
-  NULL,
+  pic16_optionsTable,
   _pic16_finaliseOptions,
   _pic16_setDefaultOptions,
   pic16_assignRegisters,
@@ -518,11 +735,11 @@ PORT pic16_port =
   _pic16_reset_regparm,
   _pic16_regparm,
   _process_pragma,                             /* process a pragma */
-  NULL,
+  NULL,                                //_pic16_mangleFunctionName,                            /* mangles function name */
   _hasNativeMulFor,
   hasExtBitOp,                 /* hasExtBitOp */
   oclsExpense,                 /* oclsExpense */
-  FALSE,
+  FALSE,                       
   TRUE,                                /* little endian */
   0,                           /* leave lt */
   0,                           /* leave gt */
index 65552254cc7bc707cfc07401e6f6bbb02e4e58d9..b58617272225a2fec123ac399522b2d0f3e9507e 100644 (file)
@@ -5,4 +5,26 @@ bool x_parseOptions (char **argv, int *pargc);
 void x_setDefaultOptions (void);
 void x_finaliseOptions (void);
 
+
+typedef struct {
+       char *at_udata;
+       char *at_udataacs;
+       char *at_udataovr;
+       char *at_udatashr;
+       
+       char *name_code;
+       char *name_idata;
+       char *name_udata;
+       char *name_udataacs;
+       char *name_udataovr;
+       char *name_udatashr;
+       
+       unsigned int addr_code;
+       unsigned int addr_idata;
+       unsigned int addr_udata;
+       unsigned int addr_udataacs;
+       unsigned int addr_udataovr;
+       unsigned int addr_udatashr;
+} pic16_sectioninfo_t;
+
 #endif
index 9c6e07f1b542efbcca0bc7cb0fbbd1837b012ccb..1623b998ee4d3545b30175c5f8973a01a2772710 100644 (file)
@@ -53,13 +53,23 @@ static peepCommand peepCommands[] = {
 
 // Eventually this will go into device dependent files:
 pCodeOpReg pic16_pc_status    = {{PO_STATUS,  "_STATUS"}, -1, NULL,0,NULL};
-pCodeOpReg pic16_pc_indf0     = {{PO_INDF0,   "_INDF0"}, -1, NULL,0,NULL};
-pCodeOpReg pic16_pc_fsr0      = {{PO_FSR0,    "_FSR0"}, -1, NULL,0,NULL};
-pCodeOpReg pic16_pc_intcon    = {{PO_INTCON,  ""}, -1, NULL,0,NULL};
-pCodeOpReg pic16_pc_pcl       = {{PO_PCL,     "_PCL"}, -1, NULL,0,NULL};
+pCodeOpReg pic16_pc_indf0     = {{PO_INDF0,   "INDF0"}, -1, NULL,0,NULL};
+pCodeOpReg pic16_pc_fsr0      = {{PO_FSR0,    "FSR0"}, -1, NULL,0,NULL};
+pCodeOpReg pic16_pc_intcon    = {{PO_INTCON,  "_INTCON"}, -1, NULL,0,NULL};
+pCodeOpReg pic16_pc_pcl       = {{PO_PCL,     "PCL"}, -1, NULL,0,NULL};
 pCodeOpReg pic16_pc_pclath    = {{PO_PCLATH,  "_PCLATH"}, -1, NULL,0,NULL};
-pCodeOpReg pic16_pc_wreg      = {{PO_WREG,    "_WREG"}, -1, NULL,0,NULL};
-pCodeOpReg pic16_pc_bsr       = {{PO_BSR,     "_BSR"}, -1, NULL,0,NULL};
+pCodeOpReg pic16_pc_wreg      = {{PO_WREG,    "WREG"}, -1, NULL,0,NULL};
+pCodeOpReg pic16_pc_bsr       = {{PO_BSR,     "BSR"}, -1, NULL,0,NULL};
+
+pCodeOpReg pic16_pc_fsr1l      = {{PO_FSR0,    "FSR1L"}, -1, NULL, 0, NULL};
+pCodeOpReg pic16_pc_fsr1h      = {{PO_FSR0,    "FSR1H"}, -1, NULL, 0, NULL};
+pCodeOpReg pic16_pc_fsr2l      = {{PO_FSR0,    "FSR2L"}, -1, NULL, 0, NULL};
+pCodeOpReg pic16_pc_fsr2h      = {{PO_FSR0,    "FSR2H"}, -1, NULL, 0, NULL};
+pCodeOpReg pic16_pc_postinc1   = {{PO_FSR0,    "POSTINC1"}, -1, NULL, 0, NULL};
+
+pCodeOpReg pic16_pc_plusw2     = {{PO_FSR0,    "PLUSW2"}, -1, NULL, 0, NULL};
+pCodeOpReg pic16_pc_preinc2    = {{PO_FSR0,    "PREINC1"}, -1, NULL, 0, NULL};
+pCodeOpReg pic16_pc_postdec1   = {{PO_FSR0,    "POSTDEV1"}, -1, NULL, 0, NULL};
 
 pCodeOpReg pic16_pc_kzero     = {{PO_GPR_REGISTER,  "KZ"}, -1, NULL,0,NULL};
 pCodeOpReg pic16_pc_wsave     = {{PO_GPR_REGISTER,  "WSAVE"}, -1, NULL,0,NULL};
@@ -77,7 +87,7 @@ static pBlock *pb_dead_pcodes = NULL;
 /* Hardcoded flags to change the behavior of the PIC port */
 static int peepOptimizing = 1;        /* run the peephole optimizer if nonzero */
 static int functionInlining = 1;      /* inline functions if nonzero */
-int pic16_debug_verbose = 1;                /* Set true to inundate .asm file */
+int pic16_debug_verbose = 0;                /* Set true to inundate .asm file */
 
 //static int GpCodeSequenceNumber = 1;
 static int GpcFlowSeq = 1;
@@ -147,9 +157,11 @@ pCodeInstruction pic16_pciADDWF = {
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
-  (PCC_REGISTER | PCC_Z) // outCond
+  (PCC_REGISTER | PCC_Z), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciADDFW = {
@@ -172,9 +184,11 @@ pCodeInstruction pic16_pciADDFW = {
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
-  (PCC_W | PCC_Z) // outCond
+  (PCC_W | PCC_Z), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciADDWFC = { // mdubuc - New
@@ -197,9 +211,11 @@ pCodeInstruction pic16_pciADDWFC = { // mdubuc - New
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER | PCC_C),   // inCond
-  (PCC_REGISTER | PCC_Z) // outCond
+  (PCC_REGISTER | PCC_Z), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciADDFWC = {
@@ -222,9 +238,11 @@ pCodeInstruction pic16_pciADDFWC = {
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER | PCC_C),   // inCond
-  (PCC_W | PCC_Z) // outCond
+  (PCC_W | PCC_Z), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciADDLW = {
@@ -247,9 +265,11 @@ pCodeInstruction pic16_pciADDLW = {
   0,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_LITERAL),   // inCond
-  (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N) // outCond
+  (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciANDLW = {
@@ -272,9 +292,11 @@ pCodeInstruction pic16_pciANDLW = {
   0,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_LITERAL),   // inCond
-  (PCC_W | PCC_Z | PCC_N) // outCond
+  (PCC_W | PCC_Z | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciANDWF = {
@@ -297,9 +319,11 @@ pCodeInstruction pic16_pciANDWF = {
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
-  (PCC_REGISTER | PCC_Z | PCC_N) // outCond
+  (PCC_REGISTER | PCC_Z | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciANDFW = {
@@ -322,6 +346,7 @@ pCodeInstruction pic16_pciANDFW = {
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
   (PCC_W | PCC_Z) // outCond
@@ -347,9 +372,11 @@ pCodeInstruction pic16_pciBC = { // mdubuc - New
   0,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_REL_ADDR | PCC_C),   // inCond
-  PCC_NONE    // outCond
+  PCC_NONE,    // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciBCF = {
@@ -372,9 +399,11 @@ pCodeInstruction pic16_pciBCF = {
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,    // second literal operand
   POC_BSF,
   (PCC_REGISTER | PCC_EXAMINE_PCOP),   // inCond
-  PCC_REGISTER // outCond
+  PCC_REGISTER, // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciBN = { // mdubuc - New
@@ -397,9 +426,11 @@ pCodeInstruction pic16_pciBN = { // mdubuc - New
   0,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_REL_ADDR | PCC_N),   // inCond
-  PCC_NONE    // outCond
+  PCC_NONE   , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciBNC = { // mdubuc - New
@@ -422,9 +453,11 @@ pCodeInstruction pic16_pciBNC = { // mdubuc - New
   0,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_REL_ADDR | PCC_C),   // inCond
-  PCC_NONE    // outCond
+  PCC_NONE   , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciBNN = { // mdubuc - New
@@ -447,9 +480,11 @@ pCodeInstruction pic16_pciBNN = { // mdubuc - New
   0,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_REL_ADDR | PCC_N),   // inCond
-  PCC_NONE    // outCond
+  PCC_NONE   , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciBNOV = { // mdubuc - New
@@ -472,9 +507,11 @@ pCodeInstruction pic16_pciBNOV = { // mdubuc - New
   0,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_REL_ADDR | PCC_OV),   // inCond
-  PCC_NONE    // outCond
+  PCC_NONE   , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciBNZ = { // mdubuc - New
@@ -497,9 +534,11 @@ pCodeInstruction pic16_pciBNZ = { // mdubuc - New
   0,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_REL_ADDR | PCC_Z),   // inCond
-  PCC_NONE    // outCond
+  PCC_NONE   , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciBOV = { // mdubuc - New
@@ -522,9 +561,11 @@ pCodeInstruction pic16_pciBOV = { // mdubuc - New
   0,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_REL_ADDR | PCC_OV),   // inCond
-  PCC_NONE  // outCond
+  PCC_NONE , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciBRA = { // mdubuc - New
@@ -547,9 +588,11 @@ pCodeInstruction pic16_pciBRA = { // mdubuc - New
   0,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REL_ADDR,   // inCond
-  PCC_NONE    // outCond
+  PCC_NONE   , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciBSF = {
@@ -572,9 +615,11 @@ pCodeInstruction pic16_pciBSF = {
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,    // second literal operand
   POC_BCF,
   (PCC_REGISTER | PCC_EXAMINE_PCOP),   // inCond
-  (PCC_REGISTER | PCC_EXAMINE_PCOP) // outCond
+  (PCC_REGISTER | PCC_EXAMINE_PCOP), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciBTFSC = {
@@ -597,9 +642,11 @@ pCodeInstruction pic16_pciBTFSC = {
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,    // second literal operand
   POC_BTFSS,
   (PCC_REGISTER | PCC_EXAMINE_PCOP),   // inCond
-  PCC_EXAMINE_PCOP // outCond
+  PCC_EXAMINE_PCOP, // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciBTFSS = {
@@ -622,9 +669,11 @@ pCodeInstruction pic16_pciBTFSS = {
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,    // second literal operand
   POC_BTFSC,
   (PCC_REGISTER | PCC_EXAMINE_PCOP),   // inCond
-  PCC_EXAMINE_PCOP // outCond
+  PCC_EXAMINE_PCOP, // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciBTG = { // mdubuc - New
@@ -647,9 +696,11 @@ pCodeInstruction pic16_pciBTG = { // mdubuc - New
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_REGISTER | PCC_EXAMINE_PCOP),   // inCond
-  (PCC_REGISTER | PCC_EXAMINE_PCOP) // outCond
+  (PCC_REGISTER | PCC_EXAMINE_PCOP), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciBZ = { // mdubuc - New
@@ -672,9 +723,11 @@ pCodeInstruction pic16_pciBZ = { // mdubuc - New
   0,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_Z,   // inCond
-  PCC_NONE // outCond
+  PCC_NONE, // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciCALL = {
@@ -697,9 +750,11 @@ pCodeInstruction pic16_pciCALL = {
   0,    // RAM access bit
   1,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_NONE, // inCond
-  PCC_NONE  // outCond
+  PCC_NONE , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciCOMF = {
@@ -722,9 +777,11 @@ pCodeInstruction pic16_pciCOMF = {
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,  // inCond
-  PCC_REGISTER   // outCond
+  PCC_REGISTER  , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciCOMFW = {
@@ -747,9 +804,11 @@ pCodeInstruction pic16_pciCOMFW = {
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,  // inCond
-  PCC_W   // outCond
+  PCC_W  , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciCLRF = {
@@ -772,9 +831,11 @@ pCodeInstruction pic16_pciCLRF = {
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER, // inCond
-  PCC_REGISTER  // outCond
+  PCC_REGISTER , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciCLRWDT = {
@@ -797,9 +858,11 @@ pCodeInstruction pic16_pciCLRWDT = {
   0,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_NONE, // inCond
-  PCC_NONE  // outCond
+  PCC_NONE , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciCPFSEQ = { // mdubuc - New
@@ -822,9 +885,11 @@ pCodeInstruction pic16_pciCPFSEQ = { // mdubuc - New
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER), // inCond
-  PCC_NONE  // outCond
+  PCC_NONE , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciCPFSGT = { // mdubuc - New
@@ -847,9 +912,11 @@ pCodeInstruction pic16_pciCPFSGT = { // mdubuc - New
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER), // inCond
-  PCC_NONE  // outCond
+  PCC_NONE , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciCPFSLT = { // mdubuc - New
@@ -872,9 +939,11 @@ pCodeInstruction pic16_pciCPFSLT = { // mdubuc - New
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER), // inCond
-  PCC_NONE  // outCond
+  PCC_NONE , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciDAW = {
@@ -897,9 +966,11 @@ pCodeInstruction pic16_pciDAW = {
   0,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_W, // inCond
-  (PCC_W | PCC_C) // outCond
+  (PCC_W | PCC_C), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciDCFSNZ = { // mdubuc - New
@@ -922,9 +993,11 @@ pCodeInstruction pic16_pciDCFSNZ = { // mdubuc - New
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER, // inCond
-  PCC_REGISTER  // outCond
+  PCC_REGISTER , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciDCFSNZW = { // mdubuc - New
@@ -947,9 +1020,11 @@ pCodeInstruction pic16_pciDCFSNZW = { // mdubuc - New
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER, // inCond
-  PCC_W  // outCond
+  PCC_W , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciDECF = {
@@ -972,9 +1047,11 @@ pCodeInstruction pic16_pciDECF = {
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  PCC_REGISTER    // outCond
+  PCC_REGISTER   , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciDECFW = {
@@ -997,9 +1074,11 @@ pCodeInstruction pic16_pciDECFW = {
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  PCC_W    // outCond
+  PCC_W   , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciDECFSZ = {
@@ -1022,9 +1101,11 @@ pCodeInstruction pic16_pciDECFSZ = {
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  PCC_REGISTER    // outCond
+  PCC_REGISTER   , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciDECFSZW = {
@@ -1047,9 +1128,11 @@ pCodeInstruction pic16_pciDECFSZW = {
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  PCC_W           // outCond
+  PCC_W          , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciGOTO = {
@@ -1072,9 +1155,11 @@ pCodeInstruction pic16_pciGOTO = {
   0,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REL_ADDR,   // inCond
-  PCC_NONE    // outCond
+  PCC_NONE   , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciINCF = {
@@ -1097,9 +1182,11 @@ pCodeInstruction pic16_pciINCF = {
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  (PCC_REGISTER | PCC_C | PCC_DC | PCC_Z | PCC_OV | PCC_N) // outCond
+  (PCC_REGISTER | PCC_C | PCC_DC | PCC_Z | PCC_OV | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciINCFW = {
@@ -1122,9 +1209,11 @@ pCodeInstruction pic16_pciINCFW = {
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  PCC_W    // outCond
+  PCC_W   , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciINCFSZ = {
@@ -1147,9 +1236,11 @@ pCodeInstruction pic16_pciINCFSZ = {
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  PCC_REGISTER    // outCond
+  PCC_REGISTER   , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciINCFSZW = {
@@ -1172,9 +1263,11 @@ pCodeInstruction pic16_pciINCFSZW = {
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  PCC_W           // outCond
+  PCC_W          , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciINFSNZ = { // mdubuc - New
@@ -1197,9 +1290,11 @@ pCodeInstruction pic16_pciINFSNZ = { // mdubuc - New
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  PCC_REGISTER    // outCond
+  PCC_REGISTER   , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciIORWF = {
@@ -1222,9 +1317,11 @@ pCodeInstruction pic16_pciIORWF = {
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
-  (PCC_REGISTER | PCC_Z | PCC_N) // outCond
+  (PCC_REGISTER | PCC_Z | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciIORFW = {
@@ -1247,9 +1344,11 @@ pCodeInstruction pic16_pciIORFW = {
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
-  (PCC_W | PCC_Z | PCC_N) // outCond
+  (PCC_W | PCC_Z | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciIORLW = {
@@ -1272,9 +1371,11 @@ pCodeInstruction pic16_pciIORLW = {
   0,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_LITERAL),   // inCond
-  (PCC_W | PCC_Z | PCC_N) // outCond
+  (PCC_W | PCC_Z | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciLFSR = { // mdubuc - New
@@ -1297,10 +1398,11 @@ pCodeInstruction pic16_pciLFSR = { // mdubuc - New
   0,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  1,   // second literal operand
   POC_NOP,
-  (PCC_REGISTER | PCC_LITERAL), // mdubuc - Should we use a special syntax for
-                                // f (identifies FSRx)?
-  PCC_REGISTER // outCond
+  (PCC_REGISTER | PCC_LITERAL),
+  PCC_REGISTER, // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciMOVF = {
@@ -1323,9 +1425,11 @@ pCodeInstruction pic16_pciMOVF = {
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  (PCC_Z | PCC_N) // outCond
+  (PCC_Z | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciMOVFW = {
@@ -1348,9 +1452,11 @@ pCodeInstruction pic16_pciMOVFW = {
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  (PCC_W | PCC_Z) // outCond
+  (PCC_W | PCC_Z), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciMOVFF = { // mdubuc - New
@@ -1373,9 +1479,11 @@ pCodeInstruction pic16_pciMOVFF = { // mdubuc - New
   0,    // RAM access bit
   0,    // fast call/return mode select bit
   1,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  PCC_REGISTER2 // outCond
+  PCC_REGISTER2, // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciMOVLB = { // mdubuc - New
@@ -1397,9 +1505,11 @@ pCodeInstruction pic16_pciMOVLB = { // mdubuc - New
   0,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_NONE | PCC_LITERAL),   // inCond
-  PCC_REGISTER // outCond - BSR
+  PCC_REGISTER, // outCond - BSR
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciMOVLW = {
@@ -1421,9 +1531,11 @@ pCodeInstruction pic16_pciMOVLW = {
   0,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_NONE | PCC_LITERAL),   // inCond
-  PCC_W // outCond
+  PCC_W, // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciMOVWF = {
@@ -1446,9 +1558,11 @@ pCodeInstruction pic16_pciMOVWF = {
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  PCC_W // outCond
+  PCC_W, // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciMULLW = { // mdubuc - New
@@ -1470,9 +1584,11 @@ pCodeInstruction pic16_pciMULLW = { // mdubuc - New
   0,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_LITERAL),   // inCond
-  PCC_REGISTER // outCond - PROD
+  PCC_REGISTER, // outCond - PROD
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciMULWF = { // mdubuc - New
@@ -1494,9 +1610,11 @@ pCodeInstruction pic16_pciMULWF = { // mdubuc - New
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
-  PCC_REGISTER // outCond - PROD
+  PCC_REGISTER, // outCond - PROD
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciNEGF = { // mdubuc - New
@@ -1518,9 +1636,11 @@ pCodeInstruction pic16_pciNEGF = { // mdubuc - New
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER, // inCond
-  (PCC_REGISTER | PCC_C | PCC_DC | PCC_OV | PCC_N) // outCond
+  (PCC_REGISTER | PCC_C | PCC_DC | PCC_OV | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciNOP = {
@@ -1542,9 +1662,11 @@ pCodeInstruction pic16_pciNOP = {
   0,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_NONE,   // inCond
-  PCC_NONE // outCond
+  PCC_NONE, // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciPOP = { // mdubuc - New
@@ -1566,9 +1688,11 @@ pCodeInstruction pic16_pciPOP = { // mdubuc - New
   0,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_NONE,  // inCond
-  PCC_NONE   // outCond
+  PCC_NONE  , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciPUSH = {
@@ -1590,9 +1714,11 @@ pCodeInstruction pic16_pciPUSH = {
   0,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_NONE,  // inCond
-  PCC_NONE   // outCond
+  PCC_NONE  , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciRCALL = { // mdubuc - New
@@ -1614,9 +1740,11 @@ pCodeInstruction pic16_pciRCALL = { // mdubuc - New
   0,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REL_ADDR,  // inCond
-  PCC_NONE   // outCond
+  PCC_NONE  , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciRETFIE = {
@@ -1639,9 +1767,11 @@ pCodeInstruction pic16_pciRETFIE = {
   0,    // RAM access bit
   1,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_NONE,   // inCond
-  PCC_NONE    // outCond (not true... affects the GIE bit too)
+  PCC_NONE,    // outCond (not true... affects the GIE bit too)
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciRETLW = {
@@ -1664,9 +1794,11 @@ pCodeInstruction pic16_pciRETLW = {
   0,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_LITERAL,   // inCond
-  PCC_W // outCond
+  PCC_W, // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciRETURN = {
@@ -1689,9 +1821,11 @@ pCodeInstruction pic16_pciRETURN = {
   0,    // RAM access bit
   1,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_NONE,   // inCond
-  PCC_NONE // outCond
+  PCC_NONE, // outCond
+  PCI_MAGIC
 };
 pCodeInstruction pic16_pciRLCF = { // mdubuc - New
   {PC_OPCODE, NULL, NULL, 0, NULL, 
@@ -1713,9 +1847,11 @@ pCodeInstruction pic16_pciRLCF = { // mdubuc - New
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_C | PCC_REGISTER),   // inCond
-  (PCC_REGISTER | PCC_C | PCC_Z | PCC_N) // outCond
+  (PCC_REGISTER | PCC_C | PCC_Z | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciRLCFW = { // mdubuc - New
@@ -1738,9 +1874,11 @@ pCodeInstruction pic16_pciRLCFW = { // mdubuc - New
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_C | PCC_REGISTER),   // inCond
-  (PCC_W | PCC_C | PCC_Z | PCC_N) // outCond
+  (PCC_W | PCC_C | PCC_Z | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciRLNCF = { // mdubuc - New
@@ -1763,9 +1901,11 @@ pCodeInstruction pic16_pciRLNCF = { // mdubuc - New
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  (PCC_REGISTER | PCC_Z | PCC_N) // outCond
+  (PCC_REGISTER | PCC_Z | PCC_N), // outCond
+  PCI_MAGIC
 };
 pCodeInstruction pic16_pciRLNCFW = { // mdubuc - New
   {PC_OPCODE, NULL, NULL, 0, NULL, 
@@ -1787,9 +1927,11 @@ pCodeInstruction pic16_pciRLNCFW = { // mdubuc - New
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  (PCC_W | PCC_Z | PCC_N) // outCond
+  (PCC_W | PCC_Z | PCC_N), // outCond
+  PCI_MAGIC
 };
 pCodeInstruction pic16_pciRRCF = { // mdubuc - New
   {PC_OPCODE, NULL, NULL, 0, NULL, 
@@ -1811,9 +1953,11 @@ pCodeInstruction pic16_pciRRCF = { // mdubuc - New
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_C | PCC_REGISTER),   // inCond
-  (PCC_REGISTER | PCC_C | PCC_Z | PCC_N) // outCond
+  (PCC_REGISTER | PCC_C | PCC_Z | PCC_N), // outCond
+  PCI_MAGIC
 };
 pCodeInstruction pic16_pciRRCFW = { // mdubuc - New
   {PC_OPCODE, NULL, NULL, 0, NULL, 
@@ -1835,9 +1979,11 @@ pCodeInstruction pic16_pciRRCFW = { // mdubuc - New
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_C | PCC_REGISTER),   // inCond
-  (PCC_W | PCC_C | PCC_Z | PCC_N) // outCond
+  (PCC_W | PCC_C | PCC_Z | PCC_N), // outCond
+  PCI_MAGIC
 };
 pCodeInstruction pic16_pciRRNCF = { // mdubuc - New
   {PC_OPCODE, NULL, NULL, 0, NULL, 
@@ -1859,9 +2005,11 @@ pCodeInstruction pic16_pciRRNCF = { // mdubuc - New
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  (PCC_REGISTER | PCC_Z | PCC_N) // outCond
+  (PCC_REGISTER | PCC_Z | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciRRNCFW = { // mdubuc - New
@@ -1884,9 +2032,11 @@ pCodeInstruction pic16_pciRRNCFW = { // mdubuc - New
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  (PCC_W | PCC_Z | PCC_N) // outCond
+  (PCC_W | PCC_Z | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciSETF = { // mdubuc - New
@@ -1909,9 +2059,11 @@ pCodeInstruction pic16_pciSETF = { // mdubuc - New
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,  // inCond
-  PCC_REGISTER   // outCond
+  PCC_REGISTER  , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciSUBLW = {
@@ -1934,9 +2086,11 @@ pCodeInstruction pic16_pciSUBLW = {
   0,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_LITERAL),   // inCond
-  (PCC_W | PCC_C | PCC_DC | PCC_Z | PCC_OV | PCC_N) // outCond
+  (PCC_W | PCC_C | PCC_DC | PCC_Z | PCC_OV | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciSUBFWB = {
@@ -1959,9 +2113,11 @@ pCodeInstruction pic16_pciSUBFWB = {
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER | PCC_C),   // inCond
-  (PCC_W | PCC_C | PCC_DC | PCC_Z | PCC_OV | PCC_N) // outCond
+  (PCC_W | PCC_C | PCC_DC | PCC_Z | PCC_OV | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciSUBWF = {
@@ -1984,9 +2140,11 @@ pCodeInstruction pic16_pciSUBWF = {
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
-  (PCC_REGISTER | PCC_Z) // outCond
+  (PCC_REGISTER | PCC_Z), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciSUBFW = {
@@ -2009,9 +2167,11 @@ pCodeInstruction pic16_pciSUBFW = {
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
-  (PCC_W | PCC_Z | PCC_OV | PCC_N) // outCond
+  (PCC_W | PCC_Z | PCC_OV | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciSUBFWB_D1 = { // mdubuc - New
@@ -2034,9 +2194,11 @@ pCodeInstruction pic16_pciSUBFWB_D1 = { // mdubuc - New
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER | PCC_C),   // inCond
-  (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N) // outCond
+  (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciSUBFWB_D0 = { // mdubuc - New
@@ -2059,9 +2221,11 @@ pCodeInstruction pic16_pciSUBFWB_D0 = { // mdubuc - New
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER | PCC_C),   // inCond
-  (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N) // outCond
+  (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciSUBWFB_D1 = { // mdubuc - New
@@ -2084,9 +2248,11 @@ pCodeInstruction pic16_pciSUBWFB_D1 = { // mdubuc - New
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER | PCC_C),   // inCond
-  (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N) // outCond
+  (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciSUBWFB_D0 = { // mdubuc - New
@@ -2109,9 +2275,11 @@ pCodeInstruction pic16_pciSUBWFB_D0 = { // mdubuc - New
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER | PCC_C),   // inCond
-  (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N) // outCond
+  (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciSWAPF = {
@@ -2134,9 +2302,11 @@ pCodeInstruction pic16_pciSWAPF = {
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_REGISTER),   // inCond
-  (PCC_REGISTER) // outCond
+  (PCC_REGISTER), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciSWAPFW = {
@@ -2159,38 +2329,12 @@ pCodeInstruction pic16_pciSWAPFW = {
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_REGISTER),   // inCond
-  (PCC_W) // outCond
-};
-
-
-#if 0
-// mdubuc - Remove TRIS
-
-pCodeInstruction pic16_pciTRIS = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, 
-   //   genericAnalyze,
-   genericDestruct,
-   genericPrint},
-  POC_TRIS,
-  "TRIS",
-  NULL, // from branch
-  NULL, // to branch
-  NULL, // label
-  NULL, // operand
-  NULL, // flow block
-  NULL, // C source 
-  1,    // num ops
-  0,0,  // dest, bit instruction
-  0,0,  // branch, skip
-  0,    // literal operand
-  0,   // second memory operand
-  POC_NOP,
-  PCC_NONE,   // inCond
-  PCC_REGISTER // outCond
+  (PCC_W), // outCond
+  PCI_MAGIC
 };
-#endif
 
 pCodeInstruction pic16_pciTSTFSZ = { // mdubuc - New
   {PC_OPCODE, NULL, NULL, 0, NULL, 
@@ -2212,9 +2356,11 @@ pCodeInstruction pic16_pciTSTFSZ = { // mdubuc - New
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  PCC_NONE // outCond
+  PCC_NONE, // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciXORWF = {
@@ -2237,9 +2383,11 @@ pCodeInstruction pic16_pciXORWF = {
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
-  (PCC_REGISTER | PCC_Z | PCC_N) // outCond
+  (PCC_REGISTER | PCC_Z | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciXORFW = {
@@ -2262,9 +2410,11 @@ pCodeInstruction pic16_pciXORFW = {
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
-  (PCC_W | PCC_Z | PCC_N) // outCond
+  (PCC_W | PCC_Z | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciXORLW = {
@@ -2287,9 +2437,11 @@ pCodeInstruction pic16_pciXORLW = {
   1,    // RAM access bit
   0,    // fast call/return mode select bit
   0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_LITERAL),   // inCond
-  (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_N) // outCond
+  (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 
@@ -2379,39 +2531,57 @@ void  pic16_pCodeInitRegisters(void)
 {
   static int initialized=0;
 
-  if(initialized)
-    return;
-  initialized = 1;
-
-  pic16_initStack(0xfff, 8);
-  pic16_init_pic(port->processor);
-
-  pic16_pc_status.r = pic16_allocProcessorRegister(IDX_STATUS,"_STATUS", PO_STATUS, 0x80);
-  pic16_pc_pcl.r = pic16_allocProcessorRegister(IDX_PCL,"PCL", PO_PCL, 0x80);
-  pic16_pc_pclath.r = pic16_allocProcessorRegister(IDX_PCLATH,"_PCLATH", PO_PCLATH, 0x80);
-  pic16_pc_fsr0.r = pic16_allocProcessorRegister(IDX_FSR0,"FSR0", PO_FSR0, 0x80);
-  pic16_pc_indf0.r = pic16_allocProcessorRegister(IDX_INDF0,"INDF0", PO_INDF0, 0x80);
-  pic16_pc_intcon.r = pic16_allocProcessorRegister(IDX_INTCON,"INTCON", PO_INTCON, 0x80);
-  pic16_pc_wreg.r = pic16_allocProcessorRegister(IDX_WREG,"WREG", PO_WREG, 0x80);
-
-  pic16_pc_status.rIdx = IDX_STATUS;
-  pic16_pc_fsr0.rIdx = IDX_FSR0;
-  pic16_pc_indf0.rIdx = IDX_INDF0;
-  pic16_pc_intcon.rIdx = IDX_INTCON;
-  pic16_pc_pcl.rIdx = IDX_PCL;
-  pic16_pc_pclath.rIdx = IDX_PCLATH;
-  pic16_pc_wreg.rIdx = IDX_WREG;
-
-  pic16_pc_kzero.r = pic16_allocInternalRegister(IDX_KZ,"KZ",PO_GPR_REGISTER,0);
-  pic16_pc_ssave.r = pic16_allocInternalRegister(IDX_SSAVE,"SSAVE", PO_GPR_REGISTER, 0x80);
-  pic16_pc_wsave.r = pic16_allocInternalRegister(IDX_WSAVE,"WSAVE", PO_GPR_REGISTER, 0);
-
-  pic16_pc_kzero.rIdx = IDX_KZ;
-  pic16_pc_wsave.rIdx = IDX_WSAVE;
-  pic16_pc_ssave.rIdx = IDX_SSAVE;
-
-  /* probably should put this in a separate initialization routine */
-  pb_dead_pcodes = newpBlock();
+       if(initialized)
+               return;
+       
+       initialized = 1;
+
+       pic16_initStack(0xfff, 8);
+       pic16_init_pic(port->processor);
+
+       pic16_pc_status.r = pic16_allocProcessorRegister(IDX_STATUS,"_STATUS", PO_STATUS, 0x00);
+       pic16_pc_pcl.r = pic16_allocProcessorRegister(IDX_PCL,"_PCL", PO_PCL, 0x80);
+       pic16_pc_pclath.r = pic16_allocProcessorRegister(IDX_PCLATH,"_PCLATH", PO_PCLATH, 0x80);
+       pic16_pc_fsr0.r = pic16_allocProcessorRegister(IDX_FSR0,"_FSR0", PO_FSR0, 0x80);
+       pic16_pc_indf0.r = pic16_allocProcessorRegister(IDX_INDF0,"_INDF0", PO_INDF0, 0x80);
+       pic16_pc_intcon.r = pic16_allocProcessorRegister(IDX_INTCON,"_INTCON", PO_INTCON, 0x80);
+       pic16_pc_wreg.r = pic16_allocProcessorRegister(IDX_WREG,"_WREG", PO_WREG, 0x80);
+
+       pic16_pc_fsr1l.r = pic16_allocProcessorRegister(IDX_FSR1L, "_FSR1L", PO_FSR0, 0x80);
+       pic16_pc_fsr1h.r = pic16_allocProcessorRegister(IDX_FSR1H, "_FSR1H", PO_FSR0, 0x80);
+       pic16_pc_fsr2l.r = pic16_allocProcessorRegister(IDX_FSR2L, "_FSR2L", PO_FSR0, 0x80);
+       pic16_pc_fsr2h.r = pic16_allocProcessorRegister(IDX_FSR2H, "_FSR2H", PO_FSR0, 0x80);
+       pic16_pc_postinc1.r = pic16_allocProcessorRegister(IDX_POSTINC1, "_POSTINC1", PO_FSR0, 0x80);
+       pic16_pc_postdec1.r = pic16_allocProcessorRegister(IDX_POSTDEC1, "_POSTDEC1", PO_FSR0, 0x80);
+       pic16_pc_preinc2.r = pic16_allocProcessorRegister(IDX_PREINC2, "_PREINC2", PO_FSR0, 0x80);
+       pic16_pc_plusw2.r = pic16_allocProcessorRegister(IDX_PLUSW2, "_PLUSW2", PO_FSR0, 0x80);
+       
+       pic16_pc_status.rIdx = IDX_STATUS;
+       pic16_pc_fsr0.rIdx = IDX_FSR0;
+       pic16_pc_indf0.rIdx = IDX_INDF0;
+       pic16_pc_intcon.rIdx = IDX_INTCON;
+       pic16_pc_pcl.rIdx = IDX_PCL;
+       pic16_pc_pclath.rIdx = IDX_PCLATH;
+       pic16_pc_wreg.rIdx = IDX_WREG;
+       pic16_pc_fsr1l.rIdx = IDX_FSR1L;
+       pic16_pc_fsr1h.rIdx = IDX_FSR1H;
+       pic16_pc_fsr2l.rIdx = IDX_FSR2L;
+       pic16_pc_fsr2h.rIdx = IDX_FSR2H;
+       pic16_pc_postinc1.rIdx = IDX_POSTINC1;
+       pic16_pc_postdec1.rIdx = IDX_POSTDEC1;
+       pic16_pc_preinc2.rIdx = IDX_PREINC2;
+       pic16_pc_plusw2.rIdx = IDX_PLUSW2;
+       
+       pic16_pc_kzero.r = pic16_allocInternalRegister(IDX_KZ,"KZ",PO_GPR_REGISTER,0);
+       pic16_pc_ssave.r = pic16_allocInternalRegister(IDX_SSAVE,"SSAVE", PO_GPR_REGISTER, 0x80);
+       pic16_pc_wsave.r = pic16_allocInternalRegister(IDX_WSAVE,"WSAVE", PO_GPR_REGISTER, 0);
+       
+       pic16_pc_kzero.rIdx = IDX_KZ;
+       pic16_pc_wsave.rIdx = IDX_WSAVE;
+       pic16_pc_ssave.rIdx = IDX_SSAVE;
+
+       /* probably should put this in a separate initialization routine */
+       pb_dead_pcodes = newpBlock();
 
 }
 
@@ -2537,7 +2707,6 @@ void pic16initMnemonics(void)
   pic16Mnemonics[POC_SUBFWB_D1] = &pic16_pciSUBFWB_D1;
   pic16Mnemonics[POC_SWAPF] = &pic16_pciSWAPF;
   pic16Mnemonics[POC_SWAPFW] = &pic16_pciSWAPFW;
-//  pic16Mnemonics[POC_TRIS] = &pic16_pciTRIS;
   pic16Mnemonics[POC_TSTFSZ] = &pic16_pciTSTFSZ;
   pic16Mnemonics[POC_XORLW] = &pic16_pciXORLW;
   pic16Mnemonics[POC_XORWF] = &pic16_pciXORWF;
@@ -2669,6 +2838,11 @@ void pic16_movepBlock2Head(char dbName)
 {
   pBlock *pb;
 
+
+  /* this can happen in sources without code,
+   * only variable definitions */
+  if(!the_pFile)return;
+
   pb = the_pFile->pbHead;
 
   while(pb) {
@@ -2707,15 +2881,16 @@ void pic16_copypCode(FILE *of, char dbName)
 {
   pBlock *pb;
 
-  if(!of || !the_pFile)
-    return;
+       if(!of || !the_pFile)
+               return;
 
-  for(pb = the_pFile->pbHead; pb; pb = pb->next) {
-    if(getpBlock_dbName(pb) == dbName) {
-      pBlockStats(of,pb);
-      pic16_printpBlock(of,pb);
-    }
-  }
+       for(pb = the_pFile->pbHead; pb; pb = pb->next) {
+               if(getpBlock_dbName(pb) == dbName) {
+//                     fprintf(stderr, "%s:%d: output of pb= 0x%p\n", __FILE__, __LINE__, pb);
+                       pBlockStats(of,pb);
+                       pic16_printpBlock(of,pb);
+               }
+       }
 
 }
 void pic16_pcode_test(void)
@@ -3094,8 +3269,7 @@ pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...)
   char buffer[256];            // how long can a directive be?!
   char *lbp=buffer;
   
-
-       pcad = Safe_calloc(1, sizeof(pCodeAsmDir));
+       pcad = Safe_alloc(/*1, */sizeof(pCodeAsmDir));
        pcad->pc.type = PC_ASMDIR;
        pcad->pc.prev = pcad->pc.next = NULL;
        pcad->pc.pb = NULL;
@@ -3166,7 +3340,6 @@ pCode *pic16_newpCodeLabel(char *name, int key)
   if(s)
     pcl->label = Safe_strdup(s);
 
-  //fprintf(stderr,"pic16_newpCodeLabel: key=%d, name=%s\n",key, ((s)?s:""));
   return ( (pCode *)pcl);
 
 }
@@ -3271,31 +3444,56 @@ pCodeOp *pic16_newpCodeOpLit(int lit)
 
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
-pCodeOp *pic16_newpCodeOpImmd(char *name, int offset, int index, int code_space)
+pCodeOp *pic16_newpCodeOpLit2(int lit, int lit2)
 {
+  char *s = buffer;
   pCodeOp *pcop;
 
-  pcop = Safe_calloc(1,sizeof(pCodeOpImmd) );
-  pcop->type = PO_IMMEDIATE;
-  if(name) {
-    regs *r = pic16_dirregWithName(name);
-    pcop->name = Safe_strdup(name);
-    PCOI(pcop)->r = r;
-    if(r) {
-      //fprintf(stderr, " pic16_newpCodeOpImmd reg %s exists\n",name);
-      PCOI(pcop)->rIdx = r->rIdx;
-    } else {
-      //fprintf(stderr, " pic16_newpCodeOpImmd reg %s doesn't exist\n",name);
-      PCOI(pcop)->rIdx = -1;
-    }
-    //fprintf(stderr,"%s %s %d\n",__FUNCTION__,name,offset);
-  } else {
-    pcop->name = NULL;
+
+  pcop = Safe_calloc(1,sizeof(pCodeOpLit2) );
+  pcop->type = PO_LITERAL;
+
+  pcop->name = NULL;
+  if(lit>=0 && lit2>=0) {
+    sprintf(s,"0x%02x,0x%02x",lit, lit2);
+    if(s)
+      pcop->name = Safe_strdup(s);
   }
 
-  PCOI(pcop)->index = index;
-  PCOI(pcop)->offset = offset;
-  PCOI(pcop)->_const = code_space;
+  ((pCodeOpLit2 *)pcop)->lit = lit;
+  ((pCodeOpLit2 *)pcop)->lit2 = lit2;
+
+  return pcop;
+}
+
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+pCodeOp *pic16_newpCodeOpImmd(char *name, int offset, int index, int code_space)
+{
+  pCodeOp *pcop;
+
+       pcop = Safe_calloc(1,sizeof(pCodeOpImmd) );
+       pcop->type = PO_IMMEDIATE;
+       if(name) {
+               regs *r = pic16_dirregWithName(name);
+               pcop->name = Safe_strdup(name);
+               PCOI(pcop)->r = r;
+               
+               if(r) {
+//                     fprintf(stderr, " pic16_newpCodeOpImmd reg %s exists\n",name);
+                       PCOI(pcop)->rIdx = r->rIdx;
+               } else {
+                       fprintf(stderr, " pic16_newpCodeOpImmd reg %s doesn't exist\n",name);
+                       PCOI(pcop)->rIdx = -1;
+               }
+//                     fprintf(stderr,"%s %s %d\n",__FUNCTION__,name,offset);
+       } else {
+               pcop->name = NULL;
+       }
+
+       PCOI(pcop)->index = index;
+       PCOI(pcop)->offset = offset;
+       PCOI(pcop)->_const = code_space;
 
   return pcop;
 }
@@ -3372,6 +3570,11 @@ pCodeOp *pic16_newpCodeOpReg(int rIdx)
 
     if(PCOR(pcop)->r)
       PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
+    else {
+       fprintf(stderr, "%s:%d Could not find a free GPR register\n",
+               __FUNCTION__, __LINE__);
+       exit(-1);
+    }
   }
 
   pcop->type = PCOR(pcop)->r->pc_type;
@@ -3671,21 +3874,6 @@ static void genericDestruct(pCode *pc)
 
 
 
-#if 0
-/*-----------------------------------------------------------------*/
-/*-----------------------------------------------------------------*/
-static void pBlockRegs(FILE *of, pBlock *pb)
-{
-
-  regs  *r;
-
-  r = setFirstItem(pb->tregisters);
-  while (r) {
-    r = setNextItem(pb->tregisters);
-  }
-}
-#endif
-
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 char *pic16_get_op(pCodeOp *pcop,char *buffer, size_t size)
@@ -3909,10 +4097,18 @@ static void pCodeOpPrint(FILE *of, pCodeOp *pcop)
 }
 
 /*-----------------------------------------------------------------*/
+/* pic16_pCode2str - convert a pCode instruction to string               */
 /*-----------------------------------------------------------------*/
-static char *pCode2str(char *str, size_t size, pCode *pc)
+static char *pic16_pCode2str(char *str, size_t size, pCode *pc)
 {
   char *s = str;
+  regs *r;
+
+       if(PCI(pc)->pci_magic != PCI_MAGIC) {
+               fprintf(stderr, "%s:%d: pCodeInstruction initialization error in instruction %s\n",
+                       __FILE__, __LINE__, PCI(pc)->mnemonic);
+               exit(-1);
+       }
 
   switch(pc->type) {
 
@@ -3928,6 +4124,11 @@ static char *pCode2str(char *str, size_t size, pCode *pc)
                break;
        }
 
+       if(PCI(pc)->is2LitOp) {
+               SAFE_snprintf(&s,&size, "%s", PCOP(PCI(pc)->pcop)->name);
+               break;
+       }
+
       if(PCI(pc)->isBitInst) {
        if(PCI(pc)->pcop->type == PO_GPR_BIT) {
          if( (((pCodeOpRegBit *)(PCI(pc)->pcop))->inBitSpace) )
@@ -3953,8 +4154,16 @@ static char *pCode2str(char *str, size_t size, pCode *pc)
        }else {
          SAFE_snprintf(&s,&size,"%s",pic16_get_op_from_instruction(PCI(pc)));
 
-         if( PCI(pc)->num_ops == 3)
-           SAFE_snprintf(&s,&size,",%c", ( (PCI(pc)->isModReg) ? 'F':'W'));
+               if( PCI(pc)->num_ops == 3 || ((PCI(pc)->num_ops == 2) && (PCI(pc)->isAccess))) {
+                       if(PCI(pc)->num_ops == 3)
+                               SAFE_snprintf(&s,&size,", %c", ( (PCI(pc)->isModReg) ? 'F':'W'));
+
+                       r = pic16_getRegFromInstruction(pc);
+//                     fprintf(stderr, "%s:%d reg = %p\tname= %s, accessBank= %d\n",
+//                                     __FUNCTION__, __LINE__, r, (r)?r->name:"<null>", (r)?r->accessBank:-1);
+
+                       if(r && !r->accessBank)SAFE_snprintf(&s,&size,", %s", "B");
+         }
        }
       }
 
@@ -4033,48 +4242,20 @@ static void genericPrint(FILE *of, pCode *pc)
     {
       char str[256];
       
-      pCode2str(str, 256, pc);
+      pic16_pCode2str(str, 256, pc);
 
       fprintf(of,"%s",str);
 
       /* Debug */
       if(pic16_debug_verbose) {
-       fprintf(of, "\t;key=%03x %d",pc->seq, __LINE__);
+       fprintf(of, "\t;key=%03x",pc->seq);
        if(PCI(pc)->pcflow)
-         fprintf(of,",flow seq=%03x",PCI(pc)->pcflow->pc.seq);
+         fprintf(of,", flow seq=%03x",PCI(pc)->pcflow->pc.seq);
       }
     }
     fprintf(of, "\n");
     break;
       
-#if 0
-    {
-      pBranch *dpb = pc->to;   // debug
-      while(dpb) {
-       switch ( dpb->pc->type) {
-       case PC_OPCODE:
-         fprintf(of, "\t;%s", PCI(dpb->pc)->mnemonic);
-         break;
-       case PC_LABEL:
-         fprintf(of, "\t;label %d", PCL(dpb->pc)->key);
-         break;
-       case PC_FUNCTION:
-         fprintf(of, "\t;function %s", ( (PCF(dpb->pc)->fname) ? (PCF(dpb->pc)->fname) : "[END]"));
-         break;
-       case PC_FLOW:
-         fprintf(of, "\t;flow");
-         break;
-       case PC_COMMENT:
-       case PC_WILD:
-         break;
-       }
-       dpb = dpb->next;
-      }
-    }
-#endif
-//    fprintf(of,"\n");                // these are moved prior to #if 0
-//    break;
-
   case PC_WILD:
     fprintf(of,";\tWild opcode: id=%d\n",PCW(pc)->id);
     if(PCW(pc)->pci.label)
@@ -4100,7 +4281,15 @@ static void genericPrint(FILE *of, pCode *pc)
     fprintf(of,";#CSRC\t%s %d\n;  %s\n", PCCS(pc)->file_name, PCCS(pc)->line_number, PCCS(pc)->line);
     break;
   case PC_ASMDIR:
-       fprintf(of, "\t%s\t%s\n", PCAD(pc)->directive, PCAD(pc)->arg?PCAD(pc)->arg:"");
+       {
+         pBranch *pbl = PCAD(pc)->label;
+               while(pbl && pbl->pc) {
+                       if(pbl->pc->type == PC_LABEL)
+                               pCodePrintLabel(of, pbl->pc);
+                       pbl = pbl->next;
+               }
+       }
+       fprintf(of, "\t%s\t%s\n", PCAD(pc)->directive, PCAD(pc)->arg?PCAD(pc)->arg:"");
        break;
        
   case PC_LABEL:
@@ -4154,7 +4343,7 @@ static void pCodePrintLabel(FILE *of, pCode *pc)
     return;
 
   if(PCL(pc)->label) 
-    fprintf(of,"%s\n",PCL(pc)->label);
+    fprintf(of,"%s:\n",PCL(pc)->label);
   else if (PCL(pc)->key >=0) 
     fprintf(of,"_%05d_DS_:\n",PCL(pc)->key);
   else
@@ -4579,7 +4768,7 @@ regs * pic16_getRegFromInstruction(pCode *pc)
 
   case PO_BIT:
   case PO_GPR_TEMP:
-    //fprintf(stderr, "pic16_getRegFromInstruction - bit or temp\n");
+//     fprintf(stderr, "pic16_getRegFromInstruction - bit or temp\n");
     return PCOR(PCI(pc)->pcop)->r;
 
   case PO_IMMEDIATE:
@@ -4594,7 +4783,7 @@ regs * pic16_getRegFromInstruction(pCode *pc)
     return PCOR(PCI(pc)->pcop)->r;
 
   case PO_DIR:
-    //fprintf(stderr, "pic16_getRegFromInstruction - dir\n");
+//     fprintf(stderr, "pic16_getRegFromInstruction - dir\n");
     return PCOR(PCI(pc)->pcop)->r;
   case PO_LITERAL:
     //fprintf(stderr, "pic16_getRegFromInstruction - literal\n");
@@ -5146,92 +5335,8 @@ int pic16_isPCinFlow(pCode *pc, pCode *pcflow)
   return 0;
 }
 
-/*-----------------------------------------------------------------*/
-/* BanksUsedFlow - Identify which banks are used in flow 2.        */
-/*-----------------------------------------------------------------*/
-static void BanksUsedFlow2(pCode *pcflow)
-{
-  pCode *pc=NULL;
-
-  int bank = -1;
-  bool RegUsed = 0;
-
-  regs *reg;
-
-  if(!isPCFL(pcflow)) {
-    fprintf(stderr, "BanksUsed - pcflow is not a flow object ");
-    return;
-  }
-
-  pc = pic16_findNextInstruction(pcflow->next);
-
-  PCFL(pcflow)->lastBank = -1;
-
-  while(pic16_isPCinFlow(pc,pcflow)) {
-
-    int bank_selected = isBankInstruction(pc);
-
-    //if(PCI(pc)->pcflow) 
-    //fprintf(stderr,"BanksUsedFlow2, looking at seq %d\n",PCI(pc)->pcflow->pc.seq);
-
-    if(bank_selected >= 0) {
-      //fprintf(stderr,"BanksUsed - mucking with bank %d\n",bank_selected);
-
-      /* This instruction is modifying banking bits before accessing registers */
-      if(!RegUsed)
-       PCFL(pcflow)->firstBank = -1;
-
-      if(PCFL(pcflow)->lastBank == -1)
-       PCFL(pcflow)->lastBank = 0;
-
-      bank = 1 << bank_selected;
-      PCFL(pcflow)->lastBank |= bank;
-                                
-
-    } else { 
-      reg = pic16_getRegFromInstruction(pc);
-
-      if(reg && !pic16_isREGinBank(reg, bank)) {
-       int allbanks = pic16_REGallBanks(reg);
-       if(bank == -1)
-         PCFL(pcflow)->firstBank = allbanks;
-
-       PCFL(pcflow)->lastBank = allbanks;
-
-       bank = allbanks;
-      }
-      RegUsed = 1;
-    }
-
-    pc = pic16_findNextInstruction(pc->next);
-  }
-
-//  fprintf(stderr,"BanksUsedFlow2 flow seq=%3d, first bank = 0x%03x, Last bank 0x%03x\n",
-//       pcflow->seq,PCFL(pcflow)->firstBank,PCFL(pcflow)->lastBank);
-
-
-
-}
-/*-----------------------------------------------------------------*/
-/*-----------------------------------------------------------------*/
-static void BanksUsedFlow(pBlock *pb)
-{
-  pCode *pcflow;
-
-
-  //pb->pcHead->print(stderr, pb->pcHead);
-
-  pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW);
-  //pcflow->print(stderr,pcflow);
-
-  for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); 
-       pcflow != NULL;
-       pcflow = pic16_findNextpCode(pcflow->next, PC_FLOW) ) {
 
-    BanksUsedFlow2(pcflow);
-  }
 
-}
 
 
 /*-----------------------------------------------------------------*/
@@ -5252,12 +5357,13 @@ static void insertBankSwitch(int position, pCode *pc, int bsr)
  * bank at linking time
  */
 
-       if(!options.gen_banksel || bsr != -1) {
+       if(!pic16_options.gen_banksel || bsr != -1) {
 //             new_pc = pic16_newpCode(POC_MOVLB, pic16_newpCodeOpLit(bsr));
                return;
        } else {
                /* emit the BANKSEL [symbol] */
 
+               /* FIXME */
                /* IMPORTANT: The following code does not check if a symbol is
                 * split in multiple banks. This should be corrected. - VR 6/6/2003 */
 
@@ -5273,96 +5379,29 @@ static void insertBankSwitch(int position, pCode *pc, int bsr)
        pc->print(stderr, pc);
 #endif
 
-  if(position) {
-    /* insert the bank switch after this pc instruction */
-    pCode *pcnext = pic16_findNextInstruction(pc);
-    pic16_pCodeInsertAfter(pc, new_pc);
-    if(pcnext)
-      pc = pcnext;
+       if(position) {
+               /* insert the bank switch after this pc instruction */
+               pCode *pcnext = pic16_findNextInstruction(pc);
+               pic16_pCodeInsertAfter(pc, new_pc);
+               if(pcnext)
+                       pc = pcnext;
 
-  } else
-    pic16_pCodeInsertAfter(pc->prev, new_pc);
+       } else
+               pic16_pCodeInsertAfter(pc->prev, new_pc);
 
   /* Move the label, if there is one */
 
-  if(PCI(pc)->label) {
-    PCI(new_pc)->label = PCI(pc)->label;
-    PCI(pc)->label = NULL;
-  }
-
-  /* The new instruction has the same pcflow block */
-  PCI(new_pc)->pcflow = PCI(pc)->pcflow;
-
-}
-/*-----------------------------------------------------------------*/
-/*-----------------------------------------------------------------*/
-static void FixRegisterBankingInFlow(pCodeFlow *pcfl, int cur_bank)
-{
-  pCode *pc=NULL;
-  pCode *pcprev=NULL;
-  pCode *new_pc;
-
-  regs *reg;
-
-  if(!pcfl)
-    return;
-
-  pc = pic16_findNextInstruction(pcfl->pc.next);
-
-  while(pic16_isPCinFlow(pc,PCODE(pcfl))) {
-
-    reg = pic16_getRegFromInstruction(pc);
-
-#if 1
-    if(reg) {
-      fprintf(stderr, "%s:%d  %s  ",__FUNCTION__, __LINE__, reg->name);
-      fprintf(stderr, "addr = 0x%03x, bank = %d\n",reg->address,REG_BANK(reg));
-
-    }
-#endif
-
-    if( ( (reg && !isACCESS_BANK(reg) && REG_BANK(reg)!=cur_bank) || 
-         ((PCI(pc)->op == POC_CALL) && (cur_bank != 0) ) ) &&
-       (!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) /* && !isBankInstruction(pcprev)*/)) {
-       int reg_bank;
-
-       reg_bank =  (reg) ? REG_BANK(reg) : 0;
-
-       
-        if (cur_bank != reg_bank) {
-         //fprintf(stderr, "Cool! can switch banks\n");
-         cur_bank = reg_bank;
-         insertBankSwitch(0, pc, cur_bank);
+       if(PCI(pc)->label) {
+//             fprintf(stderr, "%s:%d: moving label due to bank switch directive src= 0x%p dst= 0x%p\n",
+//                     __FILE__, __LINE__, pc, new_pc);
+               PCAD(new_pc)->label = PCI(pc)->label;
+               PCI(pc)->label = NULL;
        }
 
-      } else {
-       //fprintf(stderr, "Bummer can't switch banks\n");
-       ;
-      }
-    }
-
-    pcprev = pc;
-    pc = pic16_findNextInstruction(pc->next);
-
-  }
-
-  if(pcprev && cur_bank) {
-    /* Brute force - make sure that we point to bank 0 at the
-     * end of each flow block */
-    new_pc = pic16_newpCode(POC_MOVLB, pic16_newpCodeOpLit(0));
-    pic16_pCodeInsertAfter(pcprev, new_pc);
-      cur_bank = 0;
-    //fprintf(stderr, "Brute force switch\n");
-  }
-
+//  fprintf(stderr, "BankSwitch has been inserted\n");
 }
 
+
 /*-----------------------------------------------------------------*/
 /*int compareBankFlow - compare the banking requirements between   */
 /*  flow objects. */
@@ -5413,153 +5452,7 @@ static int compareBankFlow(pCodeFlow *pcflow, pCodeFlowLink *pcflowLink, int toO
   return 1;
 
 }
-/*-----------------------------------------------------------------*/
-/*-----------------------------------------------------------------*/
-static void FixBankFlow(pBlock *pb)
-{
-  pCode *pc=NULL;
-  pCode *pcflow;
-  pCodeFlowLink *pcfl;
-
-  pCode *pcflow_max_To=NULL;
-  pCode *pcflow_max_From=NULL;
-  int max_ToConflicts=0;
-  int max_FromConflicts=0;
-
-  //fprintf(stderr,"Fix Bank flow \n");
-  pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW);
-
-
-  /*
-    First loop through all of the flow objects in this pcode block
-    and fix the ones that have banking conflicts between the 
-    entry and exit.
-  */
-
-//     fprintf(stderr, "FixBankFlow - Phase 1\n");
-
-  for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); 
-       pcflow != NULL;
-       pcflow = pic16_findNextpCode(pcflow->next, PC_FLOW) ) {
-
-    if(!isPCFL(pcflow)) {
-      fprintf(stderr, "FixBankFlow - pcflow is not a flow object ");
-      continue;
-    }
-
-    if(PCFL(pcflow)->firstBank != PCFL(pcflow)->lastBank  &&
-       PCFL(pcflow)->firstBank >= 0 &&
-       PCFL(pcflow)->lastBank >= 0 ) {
-
-      int cur_bank = (PCFL(pcflow)->firstBank < PCFL(pcflow)->lastBank) ?
-       PCFL(pcflow)->firstBank : PCFL(pcflow)->lastBank;
-
-      FixRegisterBankingInFlow(PCFL(pcflow),cur_bank);
-      BanksUsedFlow2(pcflow);
-
-    }
-  }
-
-//     fprintf(stderr, "FixBankFlow - Phase 2\n");
-
-  for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); 
-       pcflow != NULL;
-       pcflow = pic16_findNextpCode(pcflow->next, PC_FLOW) ) {
-
-    int nFlows;
-    int nConflicts;
-
-    if(!isPCFL(pcflow)) {
-      fprintf(stderr, "FixBankFlow - pcflow is not a flow object ");
-      continue;
-    }
-
-    PCFL(pcflow)->FromConflicts = 0;
-    PCFL(pcflow)->ToConflicts = 0;
-
-    nFlows = 0;
-    nConflicts = 0;
-
-    //fprintf(stderr, " FixBankFlow flow seq %d\n",pcflow->seq);
-    pcfl = setFirstItem(PCFL(pcflow)->from);
-    while (pcfl) {
-
-      pc = PCODE(pcfl->pcflow);
-
-      if(!isPCFL(pc)) {
-       fprintf(stderr,"oops dumpflow - to is not a pcflow\n");
-       pc->print(stderr,pc);
-      }
-
-      nConflicts += compareBankFlow(PCFL(pcflow), pcfl, 0);
-      nFlows++;
-
-      pcfl=setNextItem(PCFL(pcflow)->from);
-    }
-
-    if((nFlows >= 2) && nConflicts && (PCFL(pcflow)->firstBank>0)) {
-      //fprintf(stderr, " From conflicts flow seq %d, nflows %d ,nconflicts %d\n",pcflow->seq,nFlows, nConflicts);
-
-      FixRegisterBankingInFlow(PCFL(pcflow),0);
-      BanksUsedFlow2(pcflow);
-
-      continue;  /* Don't need to check the flow from here - it's already been fixed */
 
-    }
-
-    nFlows = 0;
-    nConflicts = 0;
-
-    pcfl = setFirstItem(PCFL(pcflow)->to);
-    while (pcfl) {
-
-      pc = PCODE(pcfl->pcflow);
-      if(!isPCFL(pc)) {
-       fprintf(stderr,"oops dumpflow - to is not a pcflow\n");
-       pc->print(stderr,pc);
-      }
-
-      nConflicts += compareBankFlow(PCFL(pcflow), pcfl, 1);
-      nFlows++;
-
-      pcfl=setNextItem(PCFL(pcflow)->to);
-    }
-
-    if((nFlows >= 2) && nConflicts &&(nConflicts != nFlows) && (PCFL(pcflow)->lastBank>0)) {
-      //fprintf(stderr, " To conflicts flow seq %d, nflows %d ,nconflicts %d\n",pcflow->seq,nFlows, nConflicts);
-
-      FixRegisterBankingInFlow(PCFL(pcflow),0);
-      BanksUsedFlow2(pcflow);
-    }
-  }
-
-  /*
-    Loop through the flow objects again and find the ones with the 
-    maximum conflicts
-  */
-
-  for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); 
-       pcflow != NULL;
-       pcflow = pic16_findNextpCode(pcflow->next, PC_FLOW) ) {
-
-    if(PCFL(pcflow)->ToConflicts > max_ToConflicts)
-      pcflow_max_To = pcflow;
-
-    if(PCFL(pcflow)->FromConflicts > max_FromConflicts)
-      pcflow_max_From = pcflow;
-  }
-/*
-  if(pcflow_max_To)
-    fprintf(stderr,"compare flow Max To conflicts: seq %d conflicts %d\n",
-           PCFL(pcflow_max_To)->pc.seq,
-           PCFL(pcflow_max_To)->ToConflicts);
-
-  if(pcflow_max_From)
-    fprintf(stderr,"compare flow Max From conflicts: seq %d conflicts %d\n",
-           PCFL(pcflow_max_From)->pc.seq,
-           PCFL(pcflow_max_From)->FromConflicts);
-*/
-}
 #if 0
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
@@ -5815,14 +5708,15 @@ void pic16_pBlockMergeLabels(pBlock *pb)
 
     if(pc->type == PC_LABEL) {
 
-      //fprintf(stderr," checking merging label %s\n",PCL(pc)->label);
-      //fprintf(stderr,"Checking label key = %d\n",PCL(pc)->key);
+//     fprintf(stderr," checking merging label %s\n",PCL(pc)->label);
+//     fprintf(stderr,"Checking label key = %d\n",PCL(pc)->key);
+
       if((pcnext = pic16_findNextInstruction(pc) )) {
 
        // Unlink the pCode label from it's pCode chain
        pic16_unlinkpCode(pc);
        
-       //fprintf(stderr,"Merged label key = %d\n",PCL(pc)->key);
+//     fprintf(stderr,"Merged label key = %d\n",PCL(pc)->key);
        // And link it into the instruction's pBranch labels. (Note, since
        // it's possible to have multiple labels associated with one instruction
        // we must provide a means to accomodate the additional labels. Thus
@@ -5830,12 +5724,13 @@ void pic16_pBlockMergeLabels(pBlock *pb)
        // opposed to being a single member of the pCodeInstruction.)
 
        //_ALLOC(pbr,sizeof(pBranch));
+#if 1
        pbr = Safe_calloc(1,sizeof(pBranch));
        pbr->pc = pc;
        pbr->next = NULL;
 
        PCI(pcnext)->label = pic16_pBranchAppend(PCI(pcnext)->label,pbr);
-
+#endif
       } else {
        fprintf(stderr, "WARNING: couldn't associate label %s with an instruction\n",PCL(pc)->label);
       }
@@ -5899,26 +5794,22 @@ pCodeOp *pic16_popCopyGPR2Bit(pCodeOp *pc, int bitval)
         (pcop->type == PO_LITERAL) ||
         (pcop->type == PO_STR) ))
     PCOR(pcop)->r = PCOR(pc)->r;  /* This is dangerous... */
-    PCOR(pcop)->r->wasUsed = 1;                // mark register as used
+    PCOR(pcop)->r->wasUsed = 1;
+
   return pcop;
 }
 
 
-
-#if 0
-/*-----------------------------------------------------------------*/
-/*-----------------------------------------------------------------*/
-int InstructionRegBank(pCode *pc)
+/*----------------------------------------------------------------------*
+ * pic16_areRegsSame - check to see if the names of two registers match *
+ *----------------------------------------------------------------------*/
+int pic16_areRegsSame(regs *r1, regs *r2)
 {
-  regs *reg;
-
-  if( (reg = pic16_getRegFromInstruction(pc)) == NULL)
-    return -1;
-
-  return REG_BANK(reg);
+       if(!strcmp(r1->name, r2->name))return 1;
 
+  return 0;
 }
-#endif
+
 
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
@@ -5926,93 +5817,71 @@ static void pic16_FixRegisterBanking(pBlock *pb)
 {
   pCode *pc=NULL;
   pCode *pcprev=NULL;
+  regs *reg, *prevreg;
 
-  int cur_bank;
-  regs *reg;
+       if(!pb)
+               return;
 
-  if(!pb)
-    return;
+       pc = pic16_findNextpCode(pb->pcHead, PC_OPCODE);
+       if(!pc)
+               return;
 
-  //pc = pic16_findNextpCode(pb->pcHead, PC_FLOW);
-  pc = pic16_findNextpCode(pb->pcHead, PC_OPCODE);
-  if(!pc)
-    return;
-  /* loop through all of the flow blocks with in one pblock */
+       /* loop through all of the flow blocks with in one pblock */
 
 //     fprintf(stderr,"%s:%d: Register banking\n", __FUNCTION__, __LINE__);
 
-  cur_bank = 0;
+  prevreg = NULL;
   do {
     /* at this point, pc should point to a PC_FLOW object */
-
-
     /* for each flow block, determine the register banking 
        requirements */
 
-    //    do {
       if(isPCI(pc) && !PCI(pc)->is2MemOp) {
-//             genericPrint(stderr, pc);
-
-       reg = pic16_getRegFromInstruction(pc);
-#if 0
-       if(reg) {
-         fprintf(stderr, "%s:%d:  %s  %d\n",__FUNCTION__, __LINE__, reg->name, reg->rIdx);
-         fprintf(stderr, "addr = 0x%03x, bank = %d, bit=%d\tmapped = %d sfr=%d fix=%d\n",
-                 reg->address,REG_BANK(reg),reg->isBitField, reg->isMapped,
-                       pic16_finalMapping[ reg->rIdx ].isSFR, reg->isFixed);
-
-       }
-#endif
-
-/*
-#if !defined(__BORLANDC__) && !defined(_MSC_VER)
-   #warning Fix this if-conditional
-#else
-    #pragma message( "warning Fix this if-conditional" )
-#endif
-*/
-
-       /* the !(reg->rIdx==-1) is a temporary hack. It should be changed - VR 6-Jun-2003 */
-       if( ( (reg /*&& !(reg->rIdx==-1)*/ && !isACCESS_BANK(reg) && (isBankInstruction(pc)==-1) && !(reg->alias == 0x80) )
-                /*|| (PCI(pc)->op != POC_CALL)*/ )
-             && (!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) /*&& !isBankInstruction(pcprev)*/)) {
-           int reg_bank;
-
-               reg_bank =  (reg) ? REG_BANK(reg) : 0;
+               reg = pic16_getRegFromInstruction(pc);
 
 #if 0
-               fprintf(stderr, "%s:%d add bank = %d\n", __FUNCTION__, __LINE__, reg_bank);
-               pc->print(stderr, pc);
+               fprintf(stderr, "reg = %p\n", reg);
+               if(reg) {
+                       fprintf(stderr, "%s:%d:  %s  %d\n",__FUNCTION__, __LINE__, reg->name, reg->rIdx);
+                       fprintf(stderr, "addr = 0x%03x, bank = %d, bit=%d\tmapped = %d sfr=%d fix=%d\n",
+                               reg->address,REG_BANK(reg),reg->isBitField, reg->isMapped,
+                               pic16_finalMapping[ reg->address ].isSFR, reg->isFixed);
+               }
 #endif
 
-//             if (cur_bank != reg_bank) {
-                       cur_bank = reg_bank;
-                       insertBankSwitch(0, pc, (options.gen_banksel)?-1:cur_bank);     //cur_bank);
-//             }
-
-         }else {
-           //fprintf(stderr, "Bummer can't switch banks\n");
-           ;
-         }
-       }
+               /* we can be 99% that within a pBlock, between two consequtive
+                * refernces to the same register, the extra banksel is needless */
+
+               if((reg && !isACCESS_BANK(reg) && (isBankInstruction(pc) == -1))
+                       && (!isPCI_LIT(pc))
+                       && (PCI(pc)->op != POC_CALL)
+
+                       && ( ((pic16_options.opt_banksel>0)
+                               && (!prevreg || (prevreg && !pic16_areRegsSame(reg, prevreg))))
+                           || (!pic16_options.opt_banksel)
+                          )
+                                  )
+                          {
+                 /* Examine the instruction before this one to make sure it is
+                  * not a skip type instruction */
+                       pcprev = findPrevpCode(pc->prev, PC_OPCODE);
+
+                       /* FIXME: if previous is SKIP pCode, we should move the BANKSEL
+                        * before SKIP, but we have to check if the SKIP uses BANKSEL, etc... */
+                       if(!pcprev || (pcprev && !isPCI_SKIP(pcprev))) {
+                               prevreg = reg;
+                               insertBankSwitch(0, pc, (pic16_options.gen_banksel)?-1:0);
+                       }
+               }
 
        pcprev = pc;
 
       }
 
       pc = pc->next;
-      // } while(pc && !(isPCFL(pc))); 
-
-
   }while (pc);
 
+#if 0
   if(pcprev && cur_bank) {
 
     int pos = 1;  /* Assume that the bank switch instruction(s)
@@ -6031,7 +5900,7 @@ static void pic16_FixRegisterBanking(pBlock *pb)
     /* Brute force - make sure that we point to bank 0 at the
      * end of each flow block */
 
-    insertBankSwitch(pos, pcprev, 0);
+//    insertBankSwitch(pos, pcprev, 0);
 /*
     new_pc = pic16_newpCode(POC_MOVLB, pic16_newpCodeOpLit(0));
     pic16_pCodeInsertAfter(pcprev, new_pc);
@@ -6039,45 +5908,9 @@ static void pic16_FixRegisterBanking(pBlock *pb)
     cur_bank = 0;
     //fprintf(stderr, "Brute force switch\n");
   }
-
-}
-
-
-
-
-#if 0
-       if(reg && REG_BANK(reg)!=cur_bank) {
-         //fprintf(stderr,"need to switch banks\n");
-         /* 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))) {
-           int b = cur_bank ^ REG_BANK(reg);
-
-           cur_bank = REG_BANK(reg);
-
-           switch(b & 3) {
-           case 0:
-             break;
-           case 1:
-             insertBankSwitch(0, pc, cur_bank&1, PIC_RP0_BIT);
-             break;
-           case 2:
-             insertBankSwitch(0, pc, cur_bank&2, PIC_RP1_BIT);
-             insertBankSwitch(0, pc, cur_bank&2, PIC_RP1_BIT);
-             break;
-           case 3:
-             if(cur_bank & 3) {
-               insertBankSwitch(0, pc, cur_bank&1, PIC_RP0_BIT);
-               insertBankSwitch(0, pc, cur_bank&2, PIC_RP1_BIT);
-             } else
-               insertBankSwitch(0, pc, -1, -1);
-             break;
-
-           }
 #endif
 
-
+}
 
 
 static void pBlockDestruct(pBlock *pb)
@@ -6146,24 +5979,27 @@ static void mergepBlocks(char dbName)
 static void AnalyzeFlow(int level)
 {
   static int times_called=0;
-
   pBlock *pb;
 
-  if(!the_pFile)
-    return;
+       if(!the_pFile) {
+
+               /* remove unused allocated registers before exiting */
+               pic16_RemoveUnusedRegisters();
+       
+         return;
+       }
 
 
   /* if this is not the first time this function has been called,
      then clean up old flow information */
-  if(times_called++) {
-    for(pb = the_pFile->pbHead; pb; pb = pb->next)
-      unBuildFlow(pb);
-
-    pic16_RegsUnMapLiveRanges();
+       if(times_called++) {
+               for(pb = the_pFile->pbHead; pb; pb = pb->next)
+                       unBuildFlow(pb);
 
-  }
+               pic16_RegsUnMapLiveRanges();
+       }
 
-  GpcFlowSeq = 1;
+       GpcFlowSeq = 1;
 
   /* Phase 2 - Flow Analysis - Register Banking
    *
@@ -6184,8 +6020,8 @@ static void AnalyzeFlow(int level)
    * a call or goto or whatever).
    */
 
-  for(pb = the_pFile->pbHead; pb; pb = pb->next)
-    pic16_BuildFlow(pb);
+       for(pb = the_pFile->pbHead; pb; pb = pb->next)
+               pic16_BuildFlow(pb);
 
 
   /* Phase 2 - Flow Analysis - linking flow blocks
@@ -6194,17 +6030,17 @@ static void AnalyzeFlow(int level)
    * to determine their order of excution.
    */
 
-  for(pb = the_pFile->pbHead; pb; pb = pb->next)
-    LinkFlow(pb);
+       for(pb = the_pFile->pbHead; pb; pb = pb->next)
+               LinkFlow(pb);
 
   /* Phase 3 - Flow Analysis - Flow Tree
    *
    * In this phase, the individual flow blocks are examined
-   * to determine their order of excution.
+   * to determine their order of execution.
    */
 
-  for(pb = the_pFile->pbHead; pb; pb = pb->next)
-    pic16_BuildFlowTree(pb);
+       for(pb = the_pFile->pbHead; pb; pb = pb->next)
+               pic16_BuildFlowTree(pb);
 
 
   /* Phase x - Flow Analysis - Used Banks
@@ -6213,51 +6049,62 @@ static void AnalyzeFlow(int level)
    * to determine the Register Banks they use
    */
 
-  for(pb = the_pFile->pbHead; pb; pb = pb->next)
-    FixBankFlow(pb);
+#if 0
+       for(pb = the_pFile->pbHead; pb; pb = pb->next)
+               FixBankFlow(pb);
+#endif
 
 
-  for(pb = the_pFile->pbHead; pb; pb = pb->next)
-    pic16_pCodeRegMapLiveRanges(pb);
+       for(pb = the_pFile->pbHead; pb; pb = pb->next)
+               pic16_pCodeRegMapLiveRanges(pb);
 
-  pic16_RemoveUnusedRegisters();
+       pic16_RemoveUnusedRegisters();
 
   //  for(pb = the_pFile->pbHead; pb; pb = pb->next)
-  pic16_pCodeRegOptimizeRegUsage(level);
+       pic16_pCodeRegOptimizeRegUsage(level);
 
 
        if(!options.nopeep)
                OptimizepCode('*');
 
 
-/*
-  for(pb = the_pFile->pbHead; pb; pb = pb->next)
-    DumpFlow(pb);
-*/
+#if 0
+       for(pb = the_pFile->pbHead; pb; pb = pb->next)
+               DumpFlow(pb);
+#endif
+
   /* debug stuff */ 
-  for(pb = the_pFile->pbHead; pb; pb = pb->next) {
-    pCode *pcflow;
-    for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); 
-        (pcflow = pic16_findNextpCode(pcflow, PC_FLOW)) != NULL;
-        pcflow = pcflow->next) {
+       for(pb = the_pFile->pbHead; pb; pb = pb->next) {
+         pCode *pcflow;
+               for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); 
+                       (pcflow = pic16_findNextpCode(pcflow, PC_FLOW)) != NULL;
+                       pcflow = pcflow->next) {
+
+                       FillFlow(PCFL(pcflow));
+               }
+       }
 
-      FillFlow(PCFL(pcflow));
-    }
-  }
+#if 0
+       for(pb = the_pFile->pbHead; pb; pb = pb->next) {
+         pCode *pcflow;
 
-/*
-  for(pb = the_pFile->pbHead; pb; pb = pb->next) {
-    pCode *pcflow;
-    for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); 
-        (pcflow = pic16_findNextpCode(pcflow, PC_FLOW)) != NULL;
-        pcflow = pcflow->next) {
+               for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); 
+                       (pcflow = pic16_findNextpCode(pcflow, PC_FLOW)) != NULL;
+                       pcflow = pcflow->next) {
 
-      FlowStats(PCFL(pcflow));
-    }
-  }
-*/
+                       FlowStats(PCFL(pcflow));
+               }
+       }
+#endif
 }
 
+/* VR -- no need to analyze banking in flow, but left here :
+ *     1. because it may be used in the future for other purposes
+ *     2. because if omitted we'll miss some optimization done here
+ *
+ * Perhaps I should rename it to something else
+ */
+
 /*-----------------------------------------------------------------*/
 /* pic16_AnalyzeBanking - Called after the memory addresses have been    */
 /*                  assigned to the registers.                     */
@@ -6268,31 +6115,38 @@ void pic16_AnalyzeBanking(void)
 {
   pBlock  *pb;
 
-  if(!pic16_picIsInitialized()) {
-    fprintf(stderr,"Temporary ERROR: at the moment you have to use\n");
-    fprintf(stderr,"an include file create by inc2h.pl. See SDCC source:\n");
-    fprintf(stderr,"support/scripts/inc2h.pl\n");
-    fprintf(stderr,"this is a nuisance bug that will be fixed shortly\n");
+       if(!pic16_picIsInitialized()) {
+               fprintf(stderr,"Temporary ERROR: at the moment you have to use\n");
+               fprintf(stderr,"an include file create by inc2h.pl. See SDCC source:\n");
+               fprintf(stderr,"support/scripts/inc2h.pl\n");
+               fprintf(stderr,"this is a nuisance bug that will be fixed shortly\n");
 
-    exit(1);
-  }
+               /* I think it took a long long time to fix this bug! ;-) -- VR */
 
-  /* Phase x - Flow Analysis - Used Banks
-   *
-   * In this phase, the individual flow blocks are examined
-   * to determine the Register Banks they use
-   */
+               exit(1);
+       }
 
-  AnalyzeFlow(0);
-  AnalyzeFlow(1);
 
-  for(pb = the_pFile->pbHead; pb; pb = pb->next)
-    BanksUsedFlow(pb);
+       /* Phase x - Flow Analysis - Used Banks
+        *
+        * In this phase, the individual flow blocks are examined
+        * to determine the Register Banks they use
+        */
 
-  for(pb = the_pFile->pbHead; pb; pb = pb->next)
-    pic16_FixRegisterBanking(pb);
-}
+       AnalyzeFlow(0);
+       AnalyzeFlow(1);
 
+//     for(pb = the_pFile->pbHead; pb; pb = pb->next)
+//             BanksUsedFlow(pb);
+
+       if(!the_pFile)return;
+
+       for(pb = the_pFile->pbHead; pb; pb = pb->next) {
+//             fprintf(stderr, "%s:%d: Fix register banking in pb= 0x%p\n", __FILE__, __LINE__, pb);
+               pic16_FixRegisterBanking(pb);
+       }
+
+}
 
 /*-----------------------------------------------------------------*/
 /* buildCallTree - Look at the flow and extract all of the calls.  */
@@ -6806,7 +6660,7 @@ static void InlineFunction(pBlock *pb)
 
       pBranch *pbr;
 
-      if(pcn && isPCF(pcn) && (PCF(pcn)->ncalled == 1)) {
+      if(pcn && isPCF(pcn) && (PCF(pcn)->ncalled == 0)) {              /* change 0 to 1 to enable inlining */
        
        //fprintf(stderr,"Cool can inline:\n");
        //pcn->print(stderr,pcn);
index 3ffbd3c7ba2a6ae5cf9d3647979c44c91f109586..2b57ef5d2f36fd181ee4541a5157847df5961d90 100644 (file)
@@ -360,6 +360,14 @@ typedef struct pCodeOpLit
   int lit;
 } pCodeOpLit;
 
+typedef struct pCodeOpLit2
+{
+  pCodeOp pcop;
+  int lit;
+  int lit2;
+} pCodeOpLit2;
+
+
 typedef struct pCodeOpImmd
 {
   pCodeOp pcop;
@@ -396,11 +404,6 @@ typedef struct pCodeOpReg2
   struct pBlock *pb;
 
   pCodeOp *pcop2;      // second memory operand
-/*
-  int rIdx1;
-  struct regs *r1;
-*/
-  
 } pCodeOpReg2;
 
 typedef struct pCodeOpRegBit
@@ -501,6 +504,8 @@ typedef struct pCodeAsmDir
   
   char *directive;
   char *arg;
+
+  pBranch *label;
 } pCodeAsmDir;
 
 
@@ -604,11 +609,14 @@ typedef struct pCodeInstruction
   unsigned int isAccess:   1;   /* True if this instruction has an access RAM operand */
   unsigned int isFastCall: 1;   /* True if this instruction has a fast call/return mode select operand */
   unsigned int is2MemOp: 1;    /* True is second operand is a memory operand VR - support for MOVFF */
+  unsigned int is2LitOp: 1;    /* True if instruction takes 2 literal operands VR - support for LFSR */
 
   PIC_OPCODE inverted_op;      /* Opcode of instruction that's the opposite of this one */
   unsigned int inCond;   // Input conditions for this instruction
   unsigned int outCond;  // Output conditions for this instruction
 
+#define PCI_MAGIC      0x6e12
+  unsigned int pci_magic;      // sanity check for pci initialization
 } pCodeInstruction;
 
 
@@ -859,15 +867,24 @@ typedef struct peepCommand {
 #define isSTATUS_REG(r) ((r)->pc_type == PO_STATUS)
 #define isBSR_REG(r)    ((r)->pc_type == PO_BSR)
 
+#if 0
+/* these are deprecated since when creating relocatable code, the register
+   address is not known (except of course of the SFRs and the Fixed registers)
+*/
+
+
 #define isACCESS_LOW(r) ((pic16_finalMapping[REG_ADDR(r)].bank == \
                           PIC_BANK_FIRST) && (REG_ADDR(r) < 0x80))
 #define isACCESS_HI(r)  (pic16_finalMapping[REG_ADDR(r)].bank == PIC_BANK_LAST)
+#define isACCESS_BANK(r)       (isACCESS_LOW(r) || isACCESS_HI(r))
+
+#endif
+
+//#define isACCESS_BANK(r)     (REG_ADDR(r)!= 0)
+#define isACCESS_BANK(r)       (r->accessBank)
+// && pic16_finalMapping[REG_ADDR(r)].isSFR)
+//                             || (pic16_finalMapping[(r)->rIdx].reg && pic16_finalMapping[(r)->rIdx].reg->isFixed))
 
-/*
-#define isACCESS_BANK(r)(isACCESS_LOW(r) || isACCESS_HI(r))
-*/
-#define isACCESS_BANK(r)       (pic16_finalMapping[(r)->rIdx].isSFR \
-                               || (pic16_finalMapping[(r)->rIdx].reg && pic16_finalMapping[(r)->rIdx].reg->isFixed))
 
 
 #define isPCOLAB(x)     ((PCOP(x)->type) == PO_LABEL)
@@ -889,6 +906,7 @@ void pic16_addpBlock(pBlock *pb);                  // Add a pBlock to a pFile
 void pic16_copypCode(FILE *of, char dbName);       // Write all pBlocks with dbName to *of
 void pic16_movepBlock2Head(char dbName);           // move pBlocks around
 void pic16_AnalyzepCode(char dbName);
+void pic16_AssignRegBanks(void);
 void pic16_printCallTree(FILE *of);
 void pCodePeepInit(void);
 void pic16_pBlockConvert2ISR(pBlock *pb);
@@ -896,6 +914,7 @@ void pic16_pBlockConvert2ISR(pBlock *pb);
 pCodeOp *pic16_newpCodeOpLabel(char *name, int key);
 pCodeOp *pic16_newpCodeOpImmd(char *name, int offset, int index, int code_space);
 pCodeOp *pic16_newpCodeOpLit(int lit);
+pCodeOp *pic16_newpCodeOpLit2(int lit, int lit2);
 pCodeOp *pic16_newpCodeOpBit(char *name, int bit,int inBitSpace);
 pCodeOp *pic16_newpCodeOpRegFromStr(char *name);
 pCodeOp *pic16_newpCodeOp(char *name, PIC_OPTYPE p);
@@ -920,6 +939,15 @@ extern pCodeOpReg pic16_pc_fsr0;
 extern pCodeOpReg pic16_pc_pcl;
 extern pCodeOpReg pic16_pc_pclath;
 extern pCodeOpReg pic16_pc_wreg;
+extern pCodeOpReg pic16_pc_fsr1l;
+extern pCodeOpReg pic16_pc_fsr1h;
+extern pCodeOpReg pic16_pc_fsr2l;
+extern pCodeOpReg pic16_pc_fsr2h;
+extern pCodeOpReg pic16_pc_postinc1;
+extern pCodeOpReg pic16_pc_postdec1;
+extern pCodeOpReg pic16_pc_preinc2;
+extern pCodeOpReg pic16_pc_plusw2;
+
 extern pCodeOpReg pic16_pc_kzero;
 extern pCodeOpReg pic16_pc_wsave;     /* wsave and ssave are used to save W and the Status */
 extern pCodeOpReg pic16_pc_ssave;     /* registers during an interrupt */
index 5be20126fa03f2893f67edf3df3b714820abe5da..69ce8a42651e1aeec1b5e352922cfcde9ef7a9e3 100644 (file)
@@ -1517,7 +1517,7 @@ static int pCodeOpCompare(pCodeOp *pcops, pCodeOp *pcopd)
   if(!pcops || !pcopd)
     return 0;
 
-#if 1
+#if 0
   fprintf(stderr," Comparing operands %s",
          pic16_get_op( pcops,NULL,0));
 
index 525a1bae5fa00cd125653d32f5ec708507779c77..8ea1e52cd6cb08c3624233fee59329a6f186300b 100644 (file)
@@ -321,7 +321,7 @@ static void  RemoveRegsFromSet(set *regset)
        pc = setFirstItem(reg->reglives.usedpCodes);
 
        if(reg->type == REG_SFR) {
-         //fprintf(stderr, "not removing SFR reg %s even though used only once\n",reg->name);
+               fprintf(stderr, "not removing SFR reg %s even though used only once\n",reg->name);
          continue;
        }
 
@@ -660,10 +660,10 @@ static void OptimizeRegUsage(set *fregs, int optimize_multi_uses, int optimize_l
     reg = fregs->item;
     fregs = fregs->next;
 
-    if(reg->type == REG_SFR) {
-      //fprintf(stderr,"skipping SFR: %s\n",reg->name);
-      continue;
-    }
+       if(reg->type == REG_SFR) {
+//             fprintf(stderr,"skipping SFR: %s\n",reg->name);
+               continue;
+       }
 
     pcfl_used = setFirstItem(reg->reglives.usedpFlows);
     pcfl_assigned = setFirstItem(reg->reglives.assignedpFlows);
@@ -723,7 +723,7 @@ static void OptimizeRegUsage(set *fregs, int optimize_multi_uses, int optimize_l
       if(used && !pcfl_used && pcfl_assigned) {
        pCode *pc;
 
-       //fprintf(stderr,"WARNING %s: reg %s assigned without being used\n",__FUNCTION__,reg->name);
+//             fprintf(stderr,"WARNING %s: reg %s assigned without being used\n",__FUNCTION__,reg->name);
 
        pc = setFirstItem(reg->reglives.usedpCodes);
        while(pc) {
index 1c883364bc45778518dc7466d540785117315096..cb96f41e1b37f5943dfb359fcab2dd69cbbd45d9 100644 (file)
@@ -77,6 +77,10 @@ set *pic16_dynInternalRegs=NULL;
 static hTab  *dynDirectRegNames= NULL;
 //static hTab  *regHash = NULL;    /* a hash table containing ALL registers */
 
+set *pic16_rel_udata=NULL;
+set *pic16_fix_udata=NULL;
+
+
 static int dynrIdx=0x20;
 static int rDirectIdx=0;
 
@@ -436,43 +440,48 @@ static int regname2key(char const *name)
 /*-----------------------------------------------------------------*/
 /* newReg - allocate and init memory for a new register            */
 /*-----------------------------------------------------------------*/
-static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias)
+static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias, operand *refop)
 {
 
   regs *dReg;
 
-  dReg = Safe_calloc(1,sizeof(regs));
-  dReg->type = type;
-  dReg->pc_type = pc_type;
-  dReg->rIdx = rIdx;
-  if(name) 
-    dReg->name = Safe_strdup(name);
-  else {
-    sprintf(buffer,"r0x%02X", dReg->rIdx);
-    if(type == REG_STK)
-      *buffer = 's';
-    dReg->name = Safe_strdup(buffer);
-  }
-  //fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx);
-  dReg->isFree = 0;
-  dReg->wasUsed = 1;
-  if(type == REG_SFR) {
-    dReg->isFixed = 1;
-    dReg->address = rIdx;
-  } else {
-    dReg->isFixed = 0;
-    dReg->address = 0;
-  }
+       dReg = Safe_calloc(1,sizeof(regs));
+       dReg->type = type;
+       dReg->pc_type = pc_type;
+       dReg->rIdx = rIdx;
+       if(name) 
+               dReg->name = Safe_strdup(name);
+       else {
+               sprintf(buffer,"r0x%02X", dReg->rIdx);
+               if(type == REG_STK)
+                       *buffer = 's';
+                       dReg->name = Safe_strdup(buffer);
+       }
 
-  dReg->isMapped = 0;
-  dReg->isEmitted = 0;
-  dReg->size = size;
-  dReg->alias = alias;
-  dReg->reg_alias = NULL;
-  dReg->reglives.usedpFlows = newSet();
-  dReg->reglives.assignedpFlows = newSet();
+//     fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx);
+       dReg->isFree = 0;
+       dReg->wasUsed = 1;
 
-  hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
+//     dReg->isMapped = 0;
+       dReg->isEmitted = 0;
+       dReg->accessBank = 0;
+
+       if(type == REG_SFR) {
+               dReg->isFixed = 1;
+               dReg->address = rIdx;
+       } else {
+               dReg->isFixed = 0;
+               dReg->address = 0;
+       }
+       
+       dReg->size = size;
+       dReg->alias = alias;
+       dReg->reg_alias = NULL;
+       dReg->reglives.usedpFlows = newSet();
+       dReg->reglives.assignedpFlows = newSet();
+       dReg->regop = refop;
+  
+       hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
 
   return dReg;
 }
@@ -525,7 +534,7 @@ void pic16_initStack(int base_address, int size)
   //fprintf(stderr,"initStack");
 
   for(i = 0; i<size; i++)
-    addSet(&pic16_dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0));
+    addSet(&pic16_dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0, NULL));
 }
 
 /*-----------------------------------------------------------------*
@@ -533,11 +542,13 @@ void pic16_initStack(int base_address, int size)
 regs *
 pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
 {
-  regs * reg = newReg(REG_SFR, po_type, rIdx, name, 1, alias);
+  regs *reg = newReg(REG_SFR, po_type, rIdx, name, 1, alias, NULL);
+
+//     fprintf(stderr,"%s: %s addr =0x%x\n",__FUNCTION__, name,rIdx);
+
+       reg->wasUsed = 0;               // we do not know if they are going to be used at all
+       reg->accessBank = 1;            // implicit add access Bank
 
-       if(reg)reg->wasUsed = 0;
-       
-  //fprintf(stderr,"pic16_allocProcessorRegister %s addr =0x%x\n",name,rIdx);
   return addSet(&pic16_dynProcessorRegs, reg);
 }
 
@@ -547,9 +558,10 @@ pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
 regs *
 pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias)
 {
-  regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias);
+  regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias, NULL);
+
+//  fprintf(stderr,"pic16_allocInternalRegister %s addr =0x%x\n",name,rIdx);
 
-  //fprintf(stderr,"pic16_allocInternalRegister %s addr =0x%x\n",name,rIdx);
   if(reg) {
     reg->wasUsed = 0;
     return addSet(&pic16_dynInternalRegs,reg);
@@ -568,7 +580,7 @@ allocReg (short type)
   //fprintf(stderr,"allocReg\n");
 
 
-  return addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
+  return addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
 
 }
 
@@ -636,11 +648,17 @@ pic16_allocDirReg (operand *op )
   //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
   //name++;
 
+  /* The above hack is not necessery anymore, since .asm include files are not
+   * used by current implementation of the port -- VR 03-Jan-04 */
+
   debugLog ("%s symbol name %s\n", __FUNCTION__,name);
+//  fprintf(stderr, "%s symbol name %s\n", __FUNCTION__,name);
   {
     if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
       debugLog(" %d  const char\n",__LINE__);
       debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
+//      fprintf(stderr, " %d  const char\n",__LINE__);
+//      fprintf(stderr, " value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
     }
 
     debugLog("  %d  storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
@@ -690,12 +708,12 @@ pic16_allocDirReg (operand *op )
      * a new one and put it in the hash table AND in the 
      * dynDirectRegNames set */
     if(!IS_CONFIG_ADDRESS(address)) {
-      //fprintf(stderr,"allocating new reg %s\n",name);
+      //fprintf(stderr,"%s:allocating new reg %s\n",__FUNCTION__, name);
 
-      reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
-      debugLog ("  -- added %s to hash, size = %d\n", name,reg->size);
+      reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op);
+      debugLog ("%d  -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
 
-      //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
+      //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);       /* commented out */
 
       if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
 
@@ -711,7 +729,18 @@ pic16_allocDirReg (operand *op )
 
     } else {
       debugLog ("  -- %s is declared at address 0x30000x\n",name);
+      fprintf(stderr, "  -- %s is declared at address 0x30000x\n",name);
+
+/*
+       fprintf(stderr, "  setting config word to %x\n", 
+                 (int) floatFromVal (op->operand.valOperand)); //IC_RIGHT(ic)->operand.valOperand));
+
+       pic16_assignConfigWordValue(  SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
+                               (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
+*/
 
+
+      return NULL;
     }
   }
 
@@ -747,11 +776,12 @@ pic16_allocRegByName (char *name, int size)
      * a new one and put it in the hash table AND in the 
      * dynDirectRegNames set */
     //fprintf (stderr,"%s symbol name %s\n", __FUNCTION__,name);
-    reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0 );
+    reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, NULL);
 
-    debugLog ("  -- added %s to hash, size = %d\n", name,reg->size);
+    debugLog ("%d  -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
+    //fprintf(stderr, "  -- added %s to hash, size = %d\n", name,reg->size);
 
-    //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
+    //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* initially commented out */
     addSet(&pic16_dynDirectRegs, reg);
   }
 
@@ -843,6 +873,7 @@ pic16_allocWithIdx (int idx)
     debugLog ("Found a Stack Register!\n");
   } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,0)) != NULL ) {
     debugLog ("Found a Processor Register!\n");
+    fprintf(stderr, "Found a processor register! %s\n", dReg->name);
   } else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
     debugLog ("Found an Internal Register!\n");
   } else {
@@ -874,7 +905,7 @@ pic16_findFreeReg(short type)
   case REG_GPR:
     if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
       return dReg;
-    return addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
+    return addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
 
   case REG_STK:
 
@@ -896,8 +927,8 @@ pic16_findFreeReg(short type)
 static void
 freeReg (regs * reg)
 {
-  debugLog ("%s\n", __FUNCTION__);
-  reg->isFree = 1;
+       debugLog ("%s\n", __FUNCTION__);
+       reg->isFree = 1;
 }
 
 
@@ -955,10 +986,10 @@ static void writeSetUsedRegs(FILE *of, set *dRegs)
 }
 #endif
 
-extern void pic16_assignFixedRegisters(set *regset);
-extern void pic16_assignRelocatableRegisters(set *regset,int used);
+extern void pic16_groupRegistersInSection(set *regset);
+
 extern void pic16_dump_map(void);
-extern void pic16_dump_cblock(FILE *of);
+extern void pic16_dump_section(FILE *of, char *sname, set *section, int fix);
 
 
 static void packBits(set *bregs)
@@ -989,7 +1020,7 @@ static void packBits(set *bregs)
       if(!bitfield) {
        sprintf (buffer, "fbitfield%02x", breg->address);
        //fprintf(stderr,"new bit field\n");
-       bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0);
+       bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0, NULL);
        bitfield->isBitField = 1;
        bitfield->isFixed = 1;
        bitfield->address = breg->address;
@@ -1008,7 +1039,7 @@ static void packBits(set *bregs)
        bit_no=0;
        sprintf (buffer, "bitfield%d", byte_no);
        //fprintf(stderr,"new relocatable bit field\n");
-       relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
+       relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0, NULL);
        relocbitfield->isBitField = 1;
        addSet(&pic16_dynDirectRegs,relocbitfield);
        //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
@@ -1085,29 +1116,41 @@ static void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
 
 void pic16_writeUsedRegs(FILE *of) 
 {
-  packBits(pic16_dynDirectBitRegs);
-
+       packBits(pic16_dynDirectBitRegs);
 
-  pic16_assignFixedRegisters(pic16_dynAllocRegs);
-  pic16_assignFixedRegisters(pic16_dynStackRegs);
-  pic16_assignFixedRegisters(pic16_dynDirectRegs);
-  pic16_assignFixedRegisters(pic16_dynProcessorRegs);
-
-  pic16_assignRelocatableRegisters(pic16_dynInternalRegs,0);
-  pic16_assignRelocatableRegisters(pic16_dynAllocRegs,0);
-  pic16_assignRelocatableRegisters(pic16_dynStackRegs,0);
-  pic16_assignRelocatableRegisters(pic16_dynDirectRegs,0);
+       pic16_groupRegistersInSection(pic16_dynAllocRegs);
+       pic16_groupRegistersInSection(pic16_dynInternalRegs);
+       pic16_groupRegistersInSection(pic16_dynStackRegs);
+       pic16_groupRegistersInSection(pic16_dynDirectRegs);
+       pic16_groupRegistersInSection(pic16_dynDirectBitRegs);
+       pic16_groupRegistersInSection(pic16_dynProcessorRegs);
+       
+       
+#if 0
+       pic16_assignFixedRegisters(pic16_dynAllocRegs);
+       pic16_assignFixedRegisters(pic16_dynStackRegs);
+       pic16_assignFixedRegisters(pic16_dynDirectRegs);
+       pic16_assignFixedRegisters(pic16_dynProcessorRegs);
+
+       pic16_assignRelocatableRegisters(pic16_dynDirectBitRegs, 0);
+       pic16_assignRelocatableRegisters(pic16_dynInternalRegs,0);
+       pic16_assignRelocatableRegisters(pic16_dynAllocRegs,0);
+       pic16_assignRelocatableRegisters(pic16_dynStackRegs,0);
+       pic16_assignRelocatableRegisters(pic16_dynDirectRegs,0);
+#endif
 
-       //pic16_dump_map();
+//     pic16_dump_map();
+//     pic16_dump_cblock(of);
 
-  pic16_dump_cblock(of);
+       pic16_dump_section(of, "ud1", pic16_rel_udata, 0);
+       pic16_dump_section(of, "ud2", pic16_fix_udata, 1);
 
 #if 0
-  bitEQUs(of,pic16_dynDirectBitRegs);
-  aliasEQUs(of,pic16_dynAllocRegs,0);
-  aliasEQUs(of,pic16_dynDirectRegs,0);
-  aliasEQUs(of,pic16_dynStackRegs,0);
-  aliasEQUs(of,pic16_dynProcessorRegs,1);
+       bitEQUs(of,pic16_dynDirectBitRegs);
+       aliasEQUs(of,pic16_dynAllocRegs,0);
+       aliasEQUs(of,pic16_dynDirectRegs,0);
+       aliasEQUs(of,pic16_dynStackRegs,0);
+       aliasEQUs(of,pic16_dynProcessorRegs,1);
 #endif
 
 }
@@ -2441,6 +2484,7 @@ regTypeNum ()
        sym = hTabNextItem (liveRanges, &k)) {
 
     debugLog ("  %d - %s\n", __LINE__, sym->rname);
+    //fprintf(stderr,"  %d - %s\n", __LINE__, sym->rname);
 
     /* if used zero times then no registers needed */
     if ((sym->liveTo - sym->liveFrom) == 0)
@@ -2688,8 +2732,8 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
 
   iCode *dic, *sic;
 
-  debugLog ("%s\n", __FUNCTION__);
-
+  debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
+  debugLog ("ic->op = %s\n", decodeOp( ic->op ) );
   debugAopGet ("  result:", IC_RESULT (ic));
   debugAopGet ("  left:", IC_LEFT (ic));
   debugAopGet ("  right:", IC_RIGHT (ic));
@@ -2701,10 +2745,15 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
       if(IS_VALOP(IC_RIGHT(ic))) {
        debugLog ("  setting config word to %x\n", 
                  (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
+       fprintf(stderr, "  setting config word to %x\n", 
+                 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
        pic16_assignConfigWordValue(  SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
                                (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
       }
 
+
+       debugLog(" %d\n", __LINE__);
+
       /* remove the assignment from the iCode chain. */
 
       remiCodeFromeBBlock (ebp, ic);
@@ -2715,23 +2764,28 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
 
     }
   }
+       debugLog(" %d - actuall processing\n", __LINE__ );
 
   if (!IS_ITEMP (IC_RESULT (ic))) {
     pic16_allocDirReg(IC_RESULT (ic));
     debugLog ("  %d - result is not temp\n", __LINE__);
   }
-/*
+
+#if 0
   if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
     debugLog ("  %d - left is not temp, allocating\n", __LINE__);
     pic16_allocDirReg(IC_LEFT (ic));
   }
-*/
+#endif
 
+/* See BUGLOG0001 - VR */
+#if 1
   if (!IS_ITEMP (IC_RIGHT (ic))) {
     debugLog ("  %d - not packing - right is not temp\n", __LINE__);
     pic16_allocDirReg(IC_RIGHT (ic));
     return 0;
   }
+#endif
 
   if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
       OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
@@ -2770,6 +2824,23 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
       if (SKIP_IC2 (dic))
        continue;
 
+       debugLog("%d\tSearching for iTempNN\n", __LINE__);
+
+#if 0
+       if(IS_TRUE_SYMOP( IC_RESULT(dic))) {
+               debugLog("%d - dic result is a TRUE_SYMOP\n", __LINE__);
+               debugAopGet(" result is ", IC_RESULT(dic));
+       }
+       if(IS_TRUE_SYMOP( IC_LEFT(dic))) {
+               debugLog("%d - dic left is a SYMOP\n", __LINE__);
+               debugAopGet("   left is ", IC_LEFT(dic));
+       }
+       if(IS_TRUE_SYMOP( IC_RIGHT(dic))) {
+               debugLog("%d - dic right is a SYMOP\n", __LINE__);
+               debugAopGet("  right is ", IC_RIGHT(dic));
+       }
+#endif
+
       if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
          IS_OP_VOLATILE (IC_RESULT (dic)))
        {
@@ -2778,6 +2849,26 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
          break;
        }
 
+#if 0
+      if (IS_TRUE_SYMOP( IC_RIGHT (dic)) &&
+               IS_OP_VOLATILE (IC_RIGHT(dic)))
+       {
+         debugLog ("  %d - dic right is VOLATILE\n", __LINE__);
+         dic = NULL;
+         break;
+       }
+#endif
+
+#if 0
+      if (IS_TRUE_SYMOP( IC_LEFT (dic)) &&
+               IS_OP_VOLATILE (IC_LEFT(dic)))
+       {
+         debugLog ("  %d - dic left is VOLATILE\n", __LINE__);
+         dic = NULL;
+         break;
+       }
+#endif
+
       if (IS_SYMOP (IC_RESULT (dic)) &&
          IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
        {
@@ -2864,6 +2955,8 @@ pack:
 
   remiCodeFromeBBlock (ebp, ic);
   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
+
+       debugLog("  %d\n", __LINE__ );
   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
   OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
   return 1;
@@ -3218,24 +3311,29 @@ packRegsForAccUse (iCode * ic)
        getSize (operandType (IC_RESULT (ic))) > 1))
     return;
 
+  debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
   if (ic->op == LEFT_OP &&
       (isOperandLiteral (IC_RIGHT (ic)) ||
        getSize (operandType (IC_RESULT (ic))) > 1))
     return;
 
+  debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
   if (IS_BITWISE_OP (ic) &&
       getSize (operandType (IC_RESULT (ic))) > 1)
     return;
 
 
+  debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
   /* has only one definition */
   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
     return;
 
+  debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
   /* has only one use */
   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
     return;
 
+  debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
   /* and the usage immediately follows this iCode */
   if (!(uic = hTabItemWithKey (iCodehTab,
                               bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
@@ -3457,6 +3555,7 @@ static void isData(sym_link *sl)
   }
     
 }
+
 /*--------------------------------------------------------------------*/
 /* pic16_packRegisters - does some transformations to reduce          */
 /*                   register pressure                                */
@@ -3480,7 +3579,7 @@ pic16_packRegisters (eBBlock * ebp)
     /* TrueSym := iTempNN:1             */
     for (ic = ebp->sch; ic; ic = ic->next)
       {
-
+//             debugLog("%d\n", __LINE__);
        /* find assignment of the form TrueSym := iTempNN:1 */
        /* see BUGLOG0001 for workaround with the CAST - VR */
        if ((ic->op == '=' || ic->op == CAST) && !POINTER_SET (ic))
@@ -3506,20 +3605,28 @@ pic16_packRegisters (eBBlock * ebp)
     if(IS_SYMOP ( IC_LEFT(ic))) {
       sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
 
-      debugAopGet ("  left:", IC_LEFT (ic));
-#if 0
+      debugAopGet ("x  left:", IC_LEFT (ic));
+#if 1
       if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
 #else
       if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
 #endif
        debugLog ("    is a pointer\n");
 
+      if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
+        debugLog ("    is a ptr\n");
+
       if(IS_OP_VOLATILE(IC_LEFT(ic)))
        debugLog ("    is volatile\n");
 
       isData(etype);
 
-      printSymType("   ", OP_SYMBOL(IC_LEFT(ic))->type);
+       if(IS_OP_VOLATILE(IC_LEFT(ic))) {
+           debugLog ("  %d - left is not temp, allocating\n", __LINE__);
+           pic16_allocDirReg(IC_LEFT (ic));
+       }
+
+      printSymType("c  ", OP_SYMBOL(IC_LEFT(ic))->type);
     }
 
     if(IS_SYMOP ( IC_RIGHT(ic))) {
@@ -3600,8 +3707,11 @@ pic16_packRegisters (eBBlock * ebp)
        debugAopGet ("  left:", IC_LEFT (ic));
       }
 
+       //debugLog("  %d   %s\n", __LINE__, __FUNCTION__);
+
     if (!SKIP_IC2 (ic))
       {
+       //debugLog("  %d   %s\n", __LINE__, __FUNCTION__ );
        /* if we are using a symbol on the stack
           then we should say pic16_ptrRegReq */
        if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
@@ -3612,6 +3722,8 @@ pic16_packRegisters (eBBlock * ebp)
                               OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
        else
          {
+
+               //debugLog("   %d   %s\n", __LINE__, __FUNCTION__ );
            if (IS_SYMOP (IC_LEFT (ic)))
              pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
                                   OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
@@ -3645,6 +3757,8 @@ pic16_packRegisters (eBBlock * ebp)
        continue;
       }
 
+       debugLog(" %d\n", __LINE__);
+
     /* reduce for support function calls */
     if (ic->supportRtn || ic->op == '+' || ic->op == '-')
       packRegsForSupport (ic, ebp);
@@ -3679,7 +3793,7 @@ pic16_packRegisters (eBBlock * ebp)
        getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
 
       packRegsForOneuse (ic, IC_LEFT (ic), ebp);
-
+      debugLog("%d - return from packRegsForOneuse\n", __LINE__);
 
     /* if this is cast for intergral promotion then
        check if only use of  the definition of the 
@@ -3701,6 +3815,7 @@ pic16_packRegisters (eBBlock * ebp)
        if (dic) {
                
          if (IS_ARITHMETIC_OP (dic)) {
+                   debugLog("   %d   %s\n", __LINE__, __FUNCTION__ );
                    
            bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
            IC_RESULT (dic) = IC_RESULT (ic);
@@ -3722,7 +3837,9 @@ pic16_packRegisters (eBBlock * ebp)
                
          iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
          if (dic) {
-                   
+
+                  debugLog(" %d\n", __LINE__);
+
            bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
            IC_RESULT (dic) = IC_RESULT (ic);
            bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
@@ -3845,6 +3962,7 @@ pic16_assignRegisters (eBBlock ** ebbs, int count)
 
     while(reg) {
       debugLog("  -- #%d reg = %s  key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
+//      fprintf(stderr, "  -- #%d reg = %s  key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
       reg = hTabNextItem(dynDirectRegNames, &hkey);
     }
 
index cce622800bd0114b903aac71133daf2c75db8dee..547ce9302bf5bce6872c8283da709fd3a3dc731a 100644 (file)
@@ -31,6 +31,9 @@
 
 #include "pcoderegs.h"
 
+/* set STACK_SUPPORT to 1 to compile code for stack */
+#define STACK_SUPPORT 1
+extern unsigned int stackPos;
 
 enum
   {
@@ -70,14 +73,16 @@ typedef struct regs
     unsigned isFree:1;         /* is currently unassigned  */
     unsigned wasUsed:1;                /* becomes true if register has been used */
     unsigned isFixed:1;         /* True if address can't change */
-    unsigned isMapped:1;        /* The Register's address has been mapped to physical RAM */
+//    unsigned isMapped:1;        /* The Register's address has been mapped to physical RAM */
     unsigned isBitField:1;      /* True if reg is type bit OR is holder for several bits */
     unsigned isEmitted:1;       /* True if the reg has been written to a .asm file */
+    unsigned accessBank:1;     /* True if the reg is explicit placed in access bank */
     unsigned address;           /* reg's address if isFixed | isMapped is true */
     unsigned size;              /* 0 for byte, 1 for int, 4 for long */
     unsigned alias;             /* Alias mask if register appears in multiple banks */
     struct regs *reg_alias;     /* If more than one register share the same address 
                                 * then they'll point to each other. (primarily for bits)*/
+    operand *regop;            /* reference to the operand used to create the register */
     pCodeRegLives reglives; /* live range mapping */
   }
 regs;
@@ -97,6 +102,8 @@ extern set *pic16_dynDirectRegs;
 extern set *pic16_dynDirectBitRegs;
 extern set *pic16_dynInternalRegs;
 
+extern set *pic16_rel_udata;
+extern set *pic16_fix_udata;
 
 regs *pic16_regWithIdx (int);
 regs *pic16_dirregWithName (char *name );
@@ -120,6 +127,15 @@ regs *pic16_allocRegByName (char *name, int size );
 #define IDX_INTCON  0xff2
 #define IDX_WREG    0xfe8
 
+#define IDX_FSR1L      0xfe1
+#define IDX_FSR1H      0xfe2
+#define IDX_FSR2L      0xfd9
+#define IDX_FSR2H      0xfda
+#define IDX_POSTINC1   0xfe6
+#define IDX_POSTDEC1   0xfe5
+#define IDX_PREINC2    0xfdc
+#define IDX_PLUSW2     0xfdb
+
 #define IDX_KZ      0x7fff   /* Known zero - actually just a general purpose reg. */
 #define IDX_WSAVE   0x7ffe
 #define IDX_SSAVE   0x7ffd