dattalo - Major commit! re-wrote register allocation and flow analysis.
authorsdattalo <sdattalo@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Thu, 14 Mar 2002 15:18:52 +0000 (15:18 +0000)
committersdattalo <sdattalo@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Thu, 14 Mar 2002 15:18:52 +0000 (15:18 +0000)
 * added support for individual pics.
 * interrupts are now supported
 * tons and tons of minor changes.

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

12 files changed:
src/pic/device.c [new file with mode: 0644]
src/pic/device.h [new file with mode: 0644]
src/pic/gen.c
src/pic/gen.h
src/pic/genarith.c
src/pic/glue.c
src/pic/main.c
src/pic/pcode.c
src/pic/pcode.h
src/pic/pcodepeep.c
src/pic/ralloc.c
src/pic/ralloc.h

diff --git a/src/pic/device.c b/src/pic/device.c
new file mode 100644 (file)
index 0000000..8700495
--- /dev/null
@@ -0,0 +1,555 @@
+/*-------------------------------------------------------------------------
+
+   device.c - Accomodates subtle variations in PIC devices
+   Written By -  Scott Dattalo scott@dattalo.com
+
+   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.
+-------------------------------------------------------------------------*/
+
+#include <stdio.h>
+
+#include "common.h"   // Include everything in the SDCC src directory
+#include "newalloc.h"
+
+
+#include "pcode.h"
+#include "ralloc.h"
+#include "device.h"
+
+#if defined(__BORLANDC__) || defined(_MSC_VER)
+#define STRCASECMP stricmp
+#else
+#define STRCASECMP strcasecmp
+#endif
+
+/* 16F627 */
+memRange p16f627_mem[] = {
+  {0x20,  0x6f,  0x00,  0},
+  {0xa0,  0xef,  0x00,  1},
+  {0x120, 0x14f, 0x00,  2},
+  {0x70,  0x7f,  0x180, 0},
+  {-1,    -1,    -1,   -1}     /* end indicator */
+};
+memRange p16f627_sfr[] = {
+  {0x00,  0x00,  0x180, 0},
+  {0x01,  0x01,  0x100, 0},
+  {0x02,  0x04,  0x180, 0},
+  {0x05,  0x05,  0x000, 0},
+  {0x06,  0x06,  0x100, 0},
+  {0x85,  0x85,  0x000, 1},
+  {0x86,  0x86,  0x100, 1},
+  {0x0a,  0x0b,  0x180, 0},
+  {0x0c,  0x0c,  0x000, 0},
+  {0x0e,  0x12,  0x000, 0},
+  {0x15,  0x1a,  0x000, 0},
+  {0x1f,  0x1f,  0x000, 0},
+  {0x8e,  0x8e,  0x000, 1},
+  {0x92,  0x92,  0x000, 1},
+  {0x98,  0x9d,  0x000, 1},
+  {0x9f,  0x9f,  0x000, 1},
+
+  {-1,    -1,    -1,   -1}     /* end indicator */
+};
+
+/* 16F84 */
+memRange p16f84_mem[] = {
+  {0x0c,  0x4f,  0x80,  0},
+  {-1,    -1,    -1,   -1}     /* end indicator */
+};
+memRange p16f84_sfr[] = {
+  {0x01,  0x01,  0x00, 0},
+  {0x02,  0x04,  0x80, 0},
+  {0x05,  0x06,  0x00, 0},
+  {0x85,  0x86,  0x80, 1},
+  {0x08,  0x09,  0x00, 0},
+  {0x88,  0x89,  0x00, 1},
+  {0x0a,  0x0b,  0x80, 0},
+  {-1,    -1,    -1,   -1}     /* end indicator */
+};
+
+/* 16F877 */
+memRange p16f877_mem[] = {
+  {0x20,  0x6f,  0x00,  0},
+  {0xa0,  0xef,  0x00,  1},
+  {0x110, 0x16f, 0x00,  2},
+  {0x190, 0x1ef, 0x00,  3},
+  {0x70,  0x7f,  0x180, 0},
+  {-1,    -1,    -1,   -1}     /* end indicator */
+};
+memRange p16f877_sfr[] = {
+  {0x00,  0x00,  0x180, 0},
+  {0x01,  0x01,  0x100, 0},
+  {0x02,  0x04,  0x180, 0},
+  {0x05,  0x05,  0x000, 0},
+  {0x85,  0x85,  0x000, 1},
+  {0x06,  0x06,  0x100, 0},
+  {0x86,  0x86,  0x100, 1},
+  {0x07,  0x09,  0x000, 0},
+  {0x87,  0x89,  0x000, 1},
+  {0x0a,  0x0b,  0x180, 0},
+  {0x0c,  0x1f,  0x000, 0},
+  {0x8c,  0x8e,  0x000, 1},
+  {0x91,  0x94,  0x000, 1},
+  {0x98,  0x99,  0x000, 1},
+  {0x9e,  0x9f,  0x000, 1},
+  {0x10c, 0x10f, 0x000, 2},
+  {0x18c, 0x18f, 0x000, 3},
+
+  {-1,    -1,    -1,   -1}     /* end indicator */
+};
+
+
+static PIC_device Pics[] = {
+  {
+    {"p16f627", "16f627", "pic16f627", "f627"}, /* processor name */
+    p16f627_mem,                     /* ram mem map */
+    p16f627_sfr,                     /* sfr mem map */
+    0,                               /* max ram address (calculated) */
+  },
+
+  {
+    {"p16f628", "16f628", "pic16f628", "f628"},
+    p16f627_mem,
+    p16f627_sfr,
+    0,
+  },
+
+  {
+    {"p16f84", "16f84", "pic16f84", "f84"},
+    p16f84_mem,
+    p16f84_sfr,
+    0,
+  },
+
+  {
+    {"p16f877", "16f877", "pic16f877", "f877"},
+    p16f877_mem,
+    p16f877_sfr,
+    0,
+  },
+
+};
+
+static int num_of_supported_PICS = sizeof(Pics)/sizeof(PIC_device);
+static int default_pic = 0;
+#define DEFAULT_PIC "f84"
+
+static PIC_device *pic=NULL;
+
+AssignedMemory *finalMapping=NULL;
+/*-----------------------------------------------------------------*
+ *
+ * void addMem(memRange *ranges,int type)
+ *
+ *
+ *-----------------------------------------------------------------*/
+
+static void addMem(memRange *ranges,int type)
+{
+  memRange *r = ranges;
+  int i;
+
+  do {
+
+    int alias = r->alias;
+
+    do {
+
+      for(i=r->start_address; i<= r->end_address; i++) {
+       if(i <= pic->max_address) {
+         finalMapping[i | alias].isValid = 1;
+         finalMapping[i | alias].alias = r->alias;
+         finalMapping[i | alias].bank  = r->bank;
+         if(type) {
+           /* hack for now */
+           finalMapping[i | alias].isSFR  = 1;
+         } else
+           finalMapping[i | alias].isSFR  = 0;
+       }
+      }
+
+      /* Decrement alias */
+      if(alias)
+       alias -= ((alias & (alias - 1)) ^ alias);
+       else
+         alias--;
+       
+    } while(alias >= 0);
+
+    r++;
+
+  } while (r->start_address >= 0);
+
+
+}
+
+static void addMaps(PIC_device *pPic)
+{
+  int i;
+  memRange *r;
+
+  if(!pPic)
+    return;
+
+
+  /* First, find the maximum address */
+
+  r = pPic->ram;
+  pPic->max_address = 0;
+
+  do {
+
+    if((r->end_address | r->alias) > pPic->max_address)
+      pPic->max_address = r->end_address | r->alias;
+
+    r++;
+
+  } while (r->start_address >= 0);
+
+
+
+  finalMapping = Safe_calloc(1+pPic->max_address, sizeof(AssignedMemory));
+
+  /* Now initialize the finalMapping array */
+
+  for(i=0; i<=pPic->max_address; i++) {
+    finalMapping[i].reg = NULL;
+    finalMapping[i].isValid = 0;
+  }
+
+  addMem(pPic->ram,0); /* add general purpose regs to the map */
+  addMem(pPic->sfr,1); /* Add SFR's to the memmap */
+
+}
+
+/*
+ *  dump_map -- debug stuff
+ */
+
+void dump_map(void)
+{
+  int i;
+
+  for(i=0; i<=pic->max_address; i++) {
+    //fprintf(stdout , "addr 0x%02x is %s\n", i, ((finalMapping[i].isValid) ? "valid":"invalid"));
+
+    if(finalMapping[i].isValid) {
+      fprintf(stderr,"addr: 0x%02x",i);
+      if(finalMapping[i].isSFR)
+       fprintf(stderr," isSFR");
+      if(finalMapping[i].reg) 
+       fprintf( stderr, "  reg %s", finalMapping[i].reg->name);
+      fprintf(stderr, "\n");
+    }
+  }
+
+}
+
+void dump_cblock(FILE *of)
+{
+  int start=-1;
+  int addr=0;
+
+  //dump_map();   /* display the register map */
+
+  do {
+
+    if(finalMapping[addr].reg && !finalMapping[addr].reg->isEmitted) {
+
+      if(start<0)
+       start = addr;
+    } else {
+      if(start>=0) {
+
+       /* 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 */
+       fprintf(of,"  cblock  0X%04X\t; Bank %d\n",start,finalMapping[start].bank);
+
+       for( ; start < addr; start++) {
+         if((finalMapping[start].reg) && !finalMapping[start].reg->isEmitted ) {
+           fprintf(of,"\t%s",finalMapping[start].reg->name);
+
+           /* If this register is aliased in multiple banks, then
+            * mangle the variable name with the alias address: */
+           if(finalMapping[start].alias & start)
+             fprintf(of,"_%x",finalMapping[start].alias);
+
+           if(finalMapping[start].instance)
+             fprintf(of,"_%d",finalMapping[start].instance);
+
+           
+           fputc('\n',of);
+
+           //finalMapping[start].reg->isEmitted = 1;
+         }
+       }
+
+       fprintf(of,"  endc\n");
+
+       start = -1;
+      }
+
+    }
+
+    addr++;
+
+  } while(addr <= pic->max_address);
+  
+
+}
+
+/*-----------------------------------------------------------------*
+ *  void list_valid_pics(int ncols, int list_alias)
+ *
+ * Print out a formatted list of valid PIC devices
+ *
+ * ncols - number of columns in the list.
+ *
+ * list_alias - if non-zero, print all of the supported aliases
+ *              for a device (e.g. F84, 16F84, etc...)
+ *-----------------------------------------------------------------*/
+void list_valid_pics(int ncols, int list_alias)
+{
+  int col,longest;
+  int i,j,k,l;
+
+  if(list_alias)
+    list_alias = sizeof(Pics[0].name) / sizeof(Pics[0].name[0]);
+
+  fprintf(stderr,"list_alias size = %d\n",list_alias);
+  /* decrement the column number if it's greater than zero */
+  ncols = (ncols > 1) ? ncols-1 : 4;
+
+  /* Find the device with the longest name */
+  for(i=0,longest=0; i<num_of_supported_PICS; i++) {
+    for(j=0; j<=list_alias; j++) {
+      k = strlen(Pics[i].name[j]);
+      if(k>longest)
+       longest = k;
+    }
+  }
+
+  col = 0;
+
+  for(i=0;  i < num_of_supported_PICS; i++) {
+    j = 0;
+    do {
+
+      fprintf(stderr,"%s", Pics[i].name[j]);
+      if(col<ncols) {
+       l = longest + 2 - strlen(Pics[i].name[j]);
+       for(k=0; k<l; k++)
+         fputc(' ',stderr);
+
+       col++;
+
+      } else {
+       fputc('\n',stderr);
+       col = 0;
+      }
+
+    } while(++j<list_alias);
+
+  }
+  if(col != ncols)
+    fputc('\n',stderr);
+
+}
+
+/*-----------------------------------------------------------------*
+ *  
+ *-----------------------------------------------------------------*/
+PIC_device *find_device(char *name)
+{
+
+  int i,j;
+
+  if(!name)
+    return NULL;
+
+  for(i = 0; i<num_of_supported_PICS; i++) {
+
+    for(j=0; j<PROCESSOR_NAMES; j++)
+      if(!STRCASECMP(Pics[i].name[j], name) )
+       return &Pics[i];
+  }
+
+  /* not found */
+  return NULL; 
+}
+
+/*-----------------------------------------------------------------*
+ *  
+ *-----------------------------------------------------------------*/
+void init_pic(void)
+{
+  pic = find_device(DEFAULT_PIC);
+
+  if(!pic) {
+    fprintf(stderr, "%s was not found.\nValid devices are:\n",DEFAULT_PIC);
+    list_valid_pics(4,0);
+    exit(1);
+  }
+
+  
+  addMaps(pic);
+
+
+}
+
+/*-----------------------------------------------------------------*
+ *  char *processor_base_name(void) - Include file is derived from this.
+ *-----------------------------------------------------------------*/
+char *processor_base_name(void)
+{
+
+  if(!pic)
+    return NULL;
+
+  return pic->name[0];
+}
+
+int isSFR(int address)
+{
+
+  if( (address > pic->max_address) || !finalMapping[address].isSFR)
+    return 0;
+
+  return 1;
+
+}
+
+int validAddress(int address, int reg_size)
+{
+  int i;
+
+  if(address > pic->max_address)
+    return 0;
+
+  for (i=0; i<reg_size; i++)
+    if(!finalMapping[address + i].isValid || 
+       finalMapping[address+i].reg ||
+       finalMapping[address+i].isSFR )
+      return 0;
+
+  return 1;
+}
+
+void mapRegister(regs *reg)
+{
+
+  int i;
+  int alias;
+
+
+
+  for(i=0; i<reg->size; i++) {
+
+    alias = finalMapping[reg->address].alias;
+    reg->alias = alias;
+
+    do {
+
+      fprintf(stdout,"mapping %s to address 0x%02x\n",reg->name, (reg->address+alias+i));
+
+      finalMapping[reg->address + alias + i].reg = reg;
+      finalMapping[reg->address + alias + i].instance = i;
+
+      /* Decrement alias */
+      if(alias)
+       alias -= ((alias & (alias - 1)) ^ alias);
+      else
+       alias--;
+
+    } while (alias>=0);
+  }
+
+  reg->isMapped = 1;
+
+}
+
+int assignRegister(regs *reg, int start_address)
+{
+  int i;
+
+  if(reg->isFixed) {
+
+    if (validAddress(reg->address,reg->size)) {
+
+      mapRegister(reg);
+      return reg->address;
+    }
+
+    if( isSFR(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->max_address; i++) {
+
+      if (validAddress(i,reg->size)) {
+       reg->address = i;
+       mapRegister(reg);
+       return i;
+      }
+    }
+
+    fprintf(stderr, "WARNING: No more RAM available\n");
+
+  }
+
+  return -1;
+}
+
+void assignFixedRegisters(set *regset)
+{
+  regs *reg;
+
+  for (reg = setFirstItem(regset) ; reg ; 
+       reg = setNextItem(regset)) {
+
+    if(reg->isFixed) 
+      assignRegister(reg,0);
+  }
+
+}
+
+void assignRelocatableRegisters(set *regset)
+{
+
+  regs *reg;
+  int address = 0;
+
+  for (reg = setFirstItem(regset) ; reg ; 
+       reg = setNextItem(regset)) {
+
+    //fprintf(stdout,"assigning %s\n",reg->name);
+
+    if(!reg->isFixed) 
+      address = assignRegister(reg,address);
+
+  }
+
+}
+
diff --git a/src/pic/device.h b/src/pic/device.h
new file mode 100644 (file)
index 0000000..1dc4c0c
--- /dev/null
@@ -0,0 +1,92 @@
+/*-------------------------------------------------------------------------
+
+   device.c - Accomodates subtle variations in PIC devices
+   Written By -  Scott Dattalo scott@dattalo.com
+
+   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.
+-------------------------------------------------------------------------*/
+
+/*
+  PIC device abstraction
+
+  There are dozens of variations of PIC microcontrollers. This include
+  file attempts to abstract those differences so that SDCC can easily
+  deal with them.
+*/
+
+#ifndef  __DEVICE_H__
+#define  __DEVICE_H__
+
+/* memRange - a structure to define a range of valid memory addresses 
+ * 
+ * The Memory of most PICs (and other micros) is a collection of
+ * disjoint chunks. The memRange structure will define the start
+ * and end address of one of these chunks. The memory map of a
+ * particular device is a collection of memRange struct's.
+ */
+
+typedef struct memRange {
+  int start_address;      /* first address in range */
+  int end_address;        /* last */
+  int alias;              /* bit mask defining how/if memory range is aliased 
+                          * e.g. alias = 0x80 means start_address is identical
+                          * to the memory location at (0x80 | start_address) */
+  int bank;               /* PIC memory bank this range occupies */
+
+} memRange;
+
+/* AssignedMemory - A structure to keep track of the memory that has been used.
+ *
+ * When a register gets assigned an address this struct is used to
+ * keep track of a few details about the register. There is one of
+ * these structures for each memory location in the device.
+ */
+
+typedef struct AssignedMemory {
+  regs *reg;        /* Pointer to the register (NULL if this is an invalid address) */
+  int  instance;    /* the i'th byte of a multibyte register */
+  int  alias;       /* Bit mapping of aliased addresses (see memRange) */
+  int  bank;        /* Memory bank of this register */
+  int  isValid:1;   /* True if the address is legal */
+  int  isSFR:1;     /* True if the address is that of a Special Function reg */
+  int  isEmitted:1; /* True if the register has been written to a cBlock */
+
+} AssignedMemory;
+
+
+/*
+ * finalMapping - Dynamically allocated array that records the register assignments
+ */
+
+extern AssignedMemory *finalMapping;
+#define PROCESSOR_NAMES    4
+/* Processor unique attributes */
+typedef struct PIC_device {
+  char *name[PROCESSOR_NAMES];/* aliases for the processor name */
+
+  memRange *ram;              /* RAM memory map */
+  memRange *sfr;              /* SFR memory map */
+
+  int max_address;            /* maximum value for a data address */
+  //  int hasAliasedRAM:1;        /* True if there are bank independent registers */
+
+} PIC_device;
+
+/* Given a pointer to a register, this macro returns the bank that it is in */
+#define REG_BANK(r)        (finalMapping[(r)->address].bank)
+#define REG_isALIASED(r)   (finalMapping[(r)->address].alias != 0)
+#define REG_isVALID(r)     (finalMapping[(r)->address].isValid)
+
+#endif  /* __DEVICE_H__ */
index 20fc81a2b790381d3062027774b56b58278794cc..0bf3c7b11155e7b40a1b492d25d820c5404a986e 100644 (file)
@@ -86,7 +86,7 @@ static char *zero = "#0x00";
 static char *one  = "#0x01";
 static char *spname = "sp";
 
-char *fReturnpic14[] = {"FSR","dph","b","a" };
+char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
 static char **fReturn = fReturnpic14;
@@ -207,7 +207,7 @@ void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
 
 static void emitpLabel(int key)
 {
-  addpCode2pBlock(pb,newpCodeLabel(key+100+labelOffset));
+  addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
 }
 
 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
@@ -305,8 +305,8 @@ static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
     if (!r0iu) {
         /* push it if not already pushed */
         if (!_G.r0Pushed) {
-            pic14_emitcode ("push","%s",
-                      pic14_regWithIdx(R0_IDX)->dname);
+         //pic14_emitcode ("push","%s",
+         //          pic14_regWithIdx(R0_IDX)->dname);
             _G.r0Pushed++ ;
         }
         
@@ -321,8 +321,8 @@ static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
     if (!r1iu) {
         /* push it if not already pushed */
         if (!_G.r1Pushed) {
-            pic14_emitcode ("push","%s",
-                      pic14_regWithIdx(R1_IDX)->dname);
+         //pic14_emitcode ("push","%s",
+         //          pic14_regWithIdx(R1_IDX)->dname);
             _G.r1Pushed++ ;
         }
         
@@ -520,6 +520,7 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
        aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
         strcpy(aop->aopu.aop_immd,sym->rname);
         aop->size = FPTRSIZE; 
+       DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
         return aop;
     }
 
@@ -569,6 +570,8 @@ static asmop *aopForRemat (symbol *sym)
     //DEBUGpic14_emitcode(";","%s",buffer);
     aop->aopu.aop_immd = Safe_calloc(1,strlen(buffer)+1);
     strcpy(aop->aopu.aop_immd,buffer);    
+    //aop->aopu.aop_alloc_reg = allocDirReg (IC_LEFT(ic));
+    allocDirReg (IC_LEFT(ic));
     return aop;        
 }
 
@@ -709,6 +712,12 @@ void aopOp (operand *op, iCode *ic, bool result)
         return;
     }
 
+    {
+      sym_link *type = operandType(op);
+      if(IS_PTR_CONST(type))
+       DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
+    }
+
     /* if already has a asmop then continue */
     if (op->aop)
         return ;
@@ -791,6 +800,12 @@ void aopOp (operand *op, iCode *ic, bool result)
         return;
     }
 
+    {
+      sym_link *type = operandType(op);
+      if(IS_PTR_CONST(type)) 
+       DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
+    }
+
     /* must be in a register */
     sym->aop = op->aop = aop = newAsmop(AOP_REG);
     aop->size = sym->nRegs;
@@ -980,7 +995,6 @@ char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
        
        
     case AOP_IMMD:
-      DEBUGpic14_emitcode(";","%d",__LINE__);
        if (bit16) 
            sprintf (s,"%s",aop->aopu.aop_immd);
        else
@@ -991,6 +1005,7 @@ char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
            else
                sprintf(s,"%s",
                        aop->aopu.aop_immd);
+       DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
        rs = Safe_calloc(1,strlen(s)+1);
        strcpy(rs,s);   
        return rs;
@@ -1007,9 +1022,9 @@ char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
        return rs;
        
     case AOP_REG:
-       if (dname) 
-           return aop->aopu.aop_reg[offset]->dname;
-       else
+      //if (dname) 
+      //    return aop->aopu.aop_reg[offset]->dname;
+      //else
            return aop->aopu.aop_reg[offset]->name;
        
     case AOP_CRY:
@@ -1053,7 +1068,7 @@ pCodeOp *popGetLabel(unsigned int key)
   if(key>max_key)
     max_key = key;
 
-  return newpCodeOpLabel(key+100+labelOffset);
+  return newpCodeOpLabel(NULL,key+100+labelOffset);
 }
 
 /*-----------------------------------------------------------------*/
@@ -1069,37 +1084,29 @@ pCodeOp *popCopyReg(pCodeOpReg *pc)
     fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
   pcor->r = pc->r;
   pcor->rIdx = pc->rIdx;
+  pcor->r->wasUsed=1;
 
   //DEBUGpic14_emitcode ("; ***","%s  , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
 
   return PCOP(pcor);
 }
-
 /*-----------------------------------------------------------------*/
-/* popCopy - copy a pcode operator                                 */
+/* popGet - asm operator to pcode operator conversion              */
 /*-----------------------------------------------------------------*/
-pCodeOp *popCopyGPR2Bit(pCodeOp *pc, int bitval)
+pCodeOp *popGetLit(unsigned int lit)
 {
-  pCodeOp *pcop;
-
-  pcop = Safe_calloc(1,sizeof(pCodeOpBit) );
-  pcop->type = PO_BIT;
-  if(!(pcop->name = Safe_strdup(pc->name)))
-    fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
-  ((pCodeOpBit *)pcop)->bit = bitval;
-
-  ((pCodeOpBit *)pcop)->inBitSpace = 0; //(pc->type == PO_BIT) ? 1 : 0;
 
-  return pcop;
+  return newpCodeOpLit(lit);
 }
 
+
 /*-----------------------------------------------------------------*/
-/* popGet - asm operator to pcode operator conversion              */
+/* popGetImmd - asm operator to pcode immediate conversion         */
 /*-----------------------------------------------------------------*/
-pCodeOp *popGetLit(unsigned int lit)
+pCodeOp *popGetImmd(char *name, unsigned int offset)
 {
 
-  return newpCodeOpLit(lit);
+  return newpCodeOpImmd(name, offset);
 }
 
 
@@ -1158,7 +1165,7 @@ pCodeOp *popRegFromIdx(int rIdx)
 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
 {
     char *s = buffer ;
-    char *rs;
+    //char *rs;
 
     pCodeOp *pcop;
 
@@ -1179,38 +1186,16 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
     case AOP_DPTR2:
     case AOP_ACC:
         DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
-       //pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
-       //pcop->type = PO_SFR_REGISTER;
-
-       //PCOR(pcop)->rIdx = -1;
-       //PCOR(pcop)->r = NULL;
-       // Really nasty hack to check for temporary registers
-
-       //pcop->name = Safe_strdup("BAD_REGISTER");
-
        return NULL;
        
     case AOP_IMMD:
       DEBUGpic14_emitcode(";","%d",__LINE__);
-       pcop = Safe_calloc(1,sizeof(pCodeOp) );
-       pcop->type = PO_IMMEDIATE;
-       //if (bit16) 
-       //    sprintf (s,"%s",aop->aopu.aop_immd);
-       //else
-       if (offset) 
-         sprintf(s,"(%s >> %d)",
-                 aop->aopu.aop_immd,
-                 offset*8);
-       else
-         sprintf(s,"%s",
-                 aop->aopu.aop_immd);
-       pcop->name = Safe_calloc(1,strlen(s)+1);
-       strcpy(pcop->name,s);   
-       return pcop;
-       
+      return popGetImmd(aop->aopu.aop_immd,offset);
+
     case AOP_DIR:
-       pcop = Safe_calloc(1,sizeof(pCodeOp) );
+       pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
        pcop->type = PO_DIR;
+
        if (offset)
            sprintf(s,"(%s + %d)",
                    aop->aopu.aop_dir,
@@ -1219,6 +1204,12 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
            sprintf(s,"%s",aop->aopu.aop_dir);
        pcop->name = Safe_calloc(1,strlen(s)+1);
        strcpy(pcop->name,s);   
+       PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
+       if(PCOR(pcop)->r == NULL)
+         fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
+       else
+         PCOR(pcop)->instance = offset;
+
        return pcop;
        
     case AOP_REG:
@@ -1228,14 +1219,18 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
        pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
        PCOR(pcop)->rIdx = rIdx;
        PCOR(pcop)->r = pic14_regWithIdx(rIdx);
+       PCOR(pcop)->instance = offset;
        pcop->type = PCOR(pcop)->r->pc_type;
-       rs = aop->aopu.aop_reg[offset]->name;
+       //rs = aop->aopu.aop_reg[offset]->name;
        //DEBUGpic14_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
        return pcop;
       }
 
     case AOP_CRY:
       pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
+      PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
+      if(PCOR(pcop)->r == NULL)
+       fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
       return pcop;
        
     case AOP_LIT:
@@ -1243,19 +1238,16 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
 
     case AOP_STR:
       DEBUGpic14_emitcode(";","%d",__LINE__);
+      return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
+      /*
+      pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
+      PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
+      PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
+      pcop->type = PCOR(pcop)->r->pc_type;
+      pcop->name = PCOR(pcop)->r->name;
 
-      pcop = Safe_calloc(1,sizeof(pCodeOp) );
-      pcop->type = PO_STR;
-
-      //aop->coff = offset ;
-      //if (strcmp(aop->aopu.aop_str[offset],"a") == 0 && dname)
-      //  sprintf(s,"%s","acc");
-      //else
-      sprintf(s,"%s",aop->aopu.aop_str[offset]);
-      pcop->name = Safe_calloc(1,strlen(s)+1);
-      strcpy(pcop->name,s);   
       return pcop;
-       
+      */
     }
 
     werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
@@ -1294,8 +1286,15 @@ void aopPut (asmop *aop, char *s, int offset)
            pic14_emitcode("movf","%s,w",s);
          pic14_emitcode("movwf","%s",d);
 
-         if(strcmp(s,"W"))
-           pic14_emitcode(";BUG! should have this:movf","%s,w   %d",s,__LINE__);
+         if(strcmp(s,"W")) {
+           pic14_emitcode(";BUG!? should have this:movf","%s,w   %d",s,__LINE__);
+           if(offset >= aop->size) {
+             emitpcode(POC_CLRF,popGet(aop,offset));
+             break;
+           } else
+             emitpcode(POC_MOVLW,popGetImmd(s,offset));
+         }
+
          emitpcode(POC_MOVWF,popGet(aop,offset));
 
 
@@ -1303,8 +1302,8 @@ void aopPut (asmop *aop, char *s, int offset)
        break;
        
     case AOP_REG:
-       if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0 &&
-           strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
+      if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
+       //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
          /*
            if (*s == '@'           ||
                strcmp(s,"r0") == 0 ||
@@ -1679,7 +1678,7 @@ static void genNot (iCode *ic)
   DEBUGpic14_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) {
-    pic14_emitcode("movlw","1<<%s");
+    pic14_emitcode("movlw","1<<garbage");
     //pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); 
     //pic14_emitcode("cpl","c"); 
     //pic14_outBitC(IC_RESULT(ic));
@@ -1888,11 +1887,11 @@ static void saveRegisters(iCode *lic)
        pic14_emitcode("mov","%s,r0",spname);
        if (bitVectBitValue(rsave,R0_IDX))
            pic14_emitcode("mov","r0,b");           
-    } else
-       for (i = 0 ; i < pic14_nRegs ; i++) {
-           if (bitVectBitValue(rsave,i))
-               pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
-       }
+    }// else
+    //for (i = 0 ; i < pic14_nRegs ; i++) {
+    //    if (bitVectBitValue(rsave,i))
+    // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
+    //}
 
     dtype = operandType(IC_LEFT(ic));
     if (currFunc && dtype && 
@@ -1933,11 +1932,11 @@ static void unsaveRegisters (iCode *ic)
        pic14_emitcode("mov","%s,r0",spname);
        if (bitVectBitValue(rsave,R0_IDX))
            pic14_emitcode("mov","r0,b");
-    } else
-       for (i =  pic14_nRegs ; i >= 0 ; i--) {
-           if (bitVectBitValue(rsave,i))
-               pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
-       }
+    } //else
+    //for (i =  pic14_nRegs ; i >= 0 ; i--) {
+    //    if (bitVectBitValue(rsave,i))
+    // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
+    //}
 
 }  
 
@@ -1972,6 +1971,8 @@ static void assignResultValue(operand * oper)
 
   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
+  DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
+
   if(!GpsuedoStkPtr) {
     /* The last byte in the assignment is in W */
     size--;
@@ -2511,7 +2512,17 @@ static void genFunction (iCode *ic)
     /* if this is an interrupt service routine then
     save acc, b, dpl, dph  */
     if (IFFUNC_ISISR(sym->type)) {
-        
+      addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
+      emitpcodeNULLop(POC_NOP);
+      emitpcodeNULLop(POC_NOP);
+      emitpcodeNULLop(POC_NOP);
+      emitpcode(POC_MOVWF,  popCopyReg(&pc_wsave));
+      emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
+      emitpcode(POC_CLRF,   popCopyReg(&pc_status));
+      emitpcode(POC_MOVWF,  popCopyReg(&pc_ssave));
+
+      pBlockConvert2ISR(pb);
+#if 0  
        if (!inExcludeList("acc"))          
            pic14_emitcode ("push","acc");      
        if (!inExcludeList("b"))
@@ -2551,7 +2562,7 @@ static void genFunction (iCode *ic)
                    for ( i = 0 ; i < sym->regsUsed->size ; i++) {
                        if (bitVectBitValue(sym->regsUsed,i) ||
                           (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
-                           pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);                         
+                         pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);                         
                    }
                }
                
@@ -2562,6 +2573,7 @@ static void genFunction (iCode *ic)
                saverbank(0,ic,FALSE);
            }       
        }
+#endif
     } else {
        /* if callee-save to be used for this function
           then save the registers being used in this function */
@@ -2574,7 +2586,7 @@ static void genFunction (iCode *ic)
                for ( i = 0 ; i < sym->regsUsed->size ; i++) {
                    if (bitVectBitValue(sym->regsUsed,i) ||
                       (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
-                       pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
+                     //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
                        _G.nRegsSaved++;
                    }
                }
@@ -2693,7 +2705,7 @@ static void genEndFunction (iCode *ic)
                    for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
                        if (bitVectBitValue(sym->regsUsed,i) ||
                           (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
-                           pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
+                         pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
                    }
                }
                
@@ -2704,7 +2716,7 @@ static void genEndFunction (iCode *ic)
                unsaverbank(0,ic,FALSE);
            }       
        }
-
+#if 0
        if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
        {
            if (options.stack10bit)
@@ -2727,6 +2739,7 @@ static void genEndFunction (iCode *ic)
 
         if (IFFUNC_ISCRITICAL(sym->type))
             pic14_emitcode("setb","ea");
+#endif
 
        /* if debug then send end of function */
 /*     if (options.debug && currFunc) { */
@@ -2743,6 +2756,16 @@ static void genEndFunction (iCode *ic)
        }
        
         pic14_emitcode ("reti","");
+
+       emitpcode(POC_CLRF,   popCopyReg(&pc_status));
+       emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
+       emitpcode(POC_MOVWF,  popCopyReg(&pc_status));
+       emitpcode(POC_SWAPF,  popCopyReg(&pc_wsave));
+       emitpcode(POC_MOVFW,  popCopyReg(&pc_wsave));
+       addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
+
+       emitpcodeNULLop(POC_RETFIE);
+
     }
     else {
         if (IFFUNC_ISCRITICAL(sym->type))
@@ -2757,7 +2780,7 @@ static void genEndFunction (iCode *ic)
                for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
                    if (bitVectBitValue(sym->regsUsed,i) ||
                       (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
-                       pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
+                     pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
                }
            }
            
@@ -5486,7 +5509,8 @@ static void genXor (iCode *ic, iCode *ifx)
        // lit>>1  != 0 => result = 1
        if(AOP_TYPE(result) == AOP_CRY){
          if(size)
-           pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);
+           {emitpcode(POC_BSF,  popGet(AOP(result),offset));
+           pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
          else if(ifx)
            continueIfTrue(ifx);
          goto release;
@@ -5502,6 +5526,8 @@ static void genXor (iCode *ic, iCode *ifx)
        } else{
          // lit == 1, result = not(left)
          if(size && pic14_sameRegs(AOP(result),AOP(left))){
+           emitpcode(POC_MOVLW,  popGet(AOP(result),offset));
+           emitpcode(POC_XORWF,  popGet(AOP(result),offset));
            pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
            goto release;
          } else {
@@ -6693,6 +6719,34 @@ static void genLeftShiftLiteral (operand *left,
     freeAsmop(result,NULL,ic,TRUE);
 }
 
+/*-----------------------------------------------------------------*
+ * genMultiAsm - repeat assembly instruction for size of register.
+ * if endian == 1, then the high byte (i.e base address + size of 
+ * register) is used first else the low byte is used first;
+ *-----------------------------------------------------------------*/
+static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
+{
+
+  int offset = 0;
+
+  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+  if(!reg)
+    return;
+
+  if(!endian) {
+    endian = 1;
+  } else {
+    endian = -1;
+    offset = size-1;
+  }
+
+  while(size--) {
+    emitpcode(poc,    popGet(AOP(reg),offset));
+    offset += endian;
+  }
+
+}
 /*-----------------------------------------------------------------*/
 /* genLeftShift - generates code for left shifting                 */
 /*-----------------------------------------------------------------*/
@@ -6783,6 +6837,18 @@ static void genLeftShift (iCode *ic)
       goto release ;
     }
     
+    if (pic14_sameRegs(AOP(left),AOP(result))) {
+
+      tlbl = newiTempLabel(NULL);
+      emitpcode(POC_COMFW,  popGet(AOP(right),0));
+      genMultiAsm(POC_RRF, result, size,1);
+      emitpLabel(tlbl->key);
+      genMultiAsm(POC_RLF, result, size,0);
+      emitpcode(POC_ADDLW,  popGetLit(1));
+      emitSKPC;
+      emitpcode(POC_GOTO,popGetLabel(tlbl->key));
+      goto release;
+    }
 
     tlbl = newiTempLabel(NULL);
     offset = 0 ;   
@@ -7598,7 +7664,7 @@ static void genFarPointerGet (operand *left,
 
     freeAsmop(result,NULL,ic,TRUE);
 }
-
+#if 0
 /*-----------------------------------------------------------------*/
 /* genCodePointerGet - get value from code space                  */
 /*-----------------------------------------------------------------*/
@@ -7649,7 +7715,7 @@ static void genCodePointerGet (operand *left,
 
     freeAsmop(result,NULL,ic,TRUE);
 }
-
+#endif
 /*-----------------------------------------------------------------*/
 /* genGenPointerGet - gget value from generic pointer space        */
 /*-----------------------------------------------------------------*/
@@ -7668,7 +7734,7 @@ static void genGenPointerGet (operand *left,
 
   /* if the operand is already in dptr 
      then we do nothing else we move the value to dptr */
-  if (AOP_TYPE(left) != AOP_STR) {
+  //  if (AOP_TYPE(left) != AOP_STR) {
     /* if this is remateriazable */
     if (AOP_TYPE(left) == AOP_IMMD) {
       pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
@@ -7690,12 +7756,12 @@ static void genGenPointerGet (operand *left,
       }
       goto release;
     }
-  }
+    //}
   /* so dptr know contains the address */
 
   /* if bit then unpack */
-  if (IS_BITVAR(retype)) 
-    genUnpackBits(result,"dptr",GPOINTER);
+  //if (IS_BITVAR(retype)) 
+  //  genUnpackBits(result,"dptr",GPOINTER);
 
  release:
   freeAsmop(left,NULL,ic,TRUE);
@@ -7703,6 +7769,46 @@ static void genGenPointerGet (operand *left,
 
 }
 
+/*-----------------------------------------------------------------*/
+/* genConstPointerGet - get value from const generic pointer space */
+/*-----------------------------------------------------------------*/
+static void genConstPointerGet (operand *left,
+                               operand *result, iCode *ic)
+{
+  sym_link *retype = getSpec(operandType(result));
+  symbol *albl = newiTempLabel(NULL);
+  symbol *blbl = newiTempLabel(NULL);
+  PIC_OPCODE poc;
+
+  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+  aopOp(left,ic,FALSE);
+  aopOp(result,ic,FALSE);
+
+
+  DEBUGpic14_AopType(__LINE__,left,NULL,result);
+
+  DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
+
+  emitpcode(POC_CALL,popGetLabel(albl->key));
+  emitpcode(POC_GOTO,popGetLabel(blbl->key));
+  emitpLabel(albl->key);
+
+  poc = ( (AOP_TYPE(left) == AOP_IMMD) ? POC_MOVLW : POC_MOVFW);
+    
+  emitpcode(poc,popGet(AOP(left),1));
+  emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
+  emitpcode(poc,popGet(AOP(left),0));
+  emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
+
+  emitpLabel(blbl->key);
+
+  emitpcode(POC_MOVWF,popGet(AOP(result),0));
+
+
+  freeAsmop(left,NULL,ic,TRUE);
+  freeAsmop(result,NULL,ic,TRUE);
+
+}
 /*-----------------------------------------------------------------*/
 /* genPointerGet - generate code for pointer get                   */
 /*-----------------------------------------------------------------*/
@@ -7721,6 +7827,10 @@ static void genPointerGet (iCode *ic)
     move it to the correct pointer register */
     type = operandType(left);
     etype = getSpec(type);
+
+    if (IS_PTR_CONST(type))
+      DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
+
     /* if left is of type of pointer then it is simple */
     if (IS_PTR(type) && !IS_FUNC(type->next)) 
         p_type = DCL_TYPE(type);
@@ -7728,19 +7838,26 @@ static void genPointerGet (iCode *ic)
        /* we have to go by the storage class */
        p_type = PTR_TYPE(SPEC_OCLS(etype));
 
-/*     if (SPEC_OCLS(etype)->codesp ) { */
-/*         p_type = CPOINTER ;  */
-/*     } */
-/*     else */
-/*         if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
-/*             p_type = FPOINTER ; */
-/*         else */
-/*             if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
+       DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
+
+       if (SPEC_OCLS(etype)->codesp ) {
+         DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
+         //p_type = CPOINTER ; 
+       }
+       else
+           if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
+             DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
+              /*p_type = FPOINTER ;*/ 
+           else
+               if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
+                 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
 /*                 p_type = PPOINTER; */
-/*             else */
-/*                 if (SPEC_OCLS(etype) == idata ) */
+               else
+                   if (SPEC_OCLS(etype) == idata )
+                     DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
 /*                     p_type = IPOINTER; */
-/*                 else */
+                   else
+                     DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
 /*                     p_type = POINTER ; */
     }
 
@@ -7762,12 +7879,16 @@ static void genPointerGet (iCode *ic)
        break;
 
     case CPOINTER:
-       genCodePointerGet (left,result,ic);
+       genConstPointerGet (left,result,ic);
+       //pic14_emitcodePointerGet (left,result,ic);
        break;
 
     case GPOINTER:
+      if (IS_PTR_CONST(type))
+       genConstPointerGet (left,result,ic);
+      else
        genGenPointerGet (left,result,ic);
-       break;
+      break;
     }
 
 }
@@ -7963,7 +8084,8 @@ static void genDataPointerSet(operand *right,
 
          } else {
            pic14_emitcode("clrf","%s",buffer);
-           emitpcode(POC_CLRF, popRegFromString(buffer));
+           //emitpcode(POC_CLRF, popRegFromString(buffer));
+           emitpcode(POC_CLRF, popGet(AOP(result),offset));
          }
        }else {
          pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
@@ -8836,6 +8958,7 @@ static void genCast (iCode *ic)
     if (AOP_TYPE(result) == AOP_CRY) {
         /* if the right size is a literal then
         we know what the value is */
+      DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
         if (AOP_TYPE(right) == AOP_LIT) {
 
          emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
@@ -8882,6 +9005,8 @@ static void genCast (iCode *ic)
       int offset = 1;
       size = AOP_SIZE(result);
 
+      DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
+
       emitpcode(POC_CLRF,   popGet(AOP(result),0));
       emitpcode(POC_BTFSC,  popGet(AOP(right),0));
       emitpcode(POC_INCF,   popGet(AOP(result),0));
@@ -8896,17 +9021,30 @@ static void genCast (iCode *ic)
     if (AOP_SIZE(result) <= AOP_SIZE(right)) {
 
         /* if they are in the same place */
-        if (pic14_sameRegs(AOP(right),AOP(result)))
-            goto release;
+      if (pic14_sameRegs(AOP(right),AOP(result)))
+       goto release;
+
+      DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
+      if (IS_PTR_CONST(rtype))
+       DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
+      if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
+       DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
 
         /* if they in different places then copy */
         size = AOP_SIZE(result);
         offset = 0 ;
         while (size--) {
-            aopPut(AOP(result),
-                   aopGet(AOP(right),offset,FALSE,FALSE),
-                   offset);
-            offset++;
+         if(AOP_TYPE(right) == AOP_IMMD)
+           emitpcode(POC_MOVLW, popGetImmd(AOP(right)->aopu.aop_dir,offset));
+         else
+           emitpcode(POC_MOVFW,   popGet(AOP(right),offset));
+         emitpcode(POC_MOVWF,   popGet(AOP(result),offset));
+
+         //aopPut(AOP(result),
+         // aopGet(AOP(right),offset,FALSE,FALSE),
+         // offset);
+
+         offset++;
         }
         goto release;
     }
@@ -8918,6 +9056,7 @@ static void genCast (iCode *ic)
        int p_type;
        sym_link *type = operandType(right);
        sym_link *etype = getSpec(type);
+      DEBUGpic14_emitcode("; ***","%s  %d - pointer cast",__FUNCTION__,__LINE__);
 
        /* pointer to generic pointer */
        if (IS_GENPTR(ctype)) {
@@ -8948,24 +9087,30 @@ static void genCast (iCode *ic)
            size = GPTRSIZE - 1; 
            offset = 0 ;
            while (size--) {
+             if(offset < AOP_SIZE(right))
                aopPut(AOP(result),
                       aopGet(AOP(right),offset,FALSE,FALSE),
                       offset);
-               offset++;
+             else
+               emitpcode(POC_CLRF,popGet(AOP(result),offset));
+             offset++;
            }
            /* the last byte depending on type */
            switch (p_type) {
            case IPOINTER:
            case POINTER:
-               l = zero;
+               emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
                break;
            case FPOINTER:
+             pic14_emitcode(";BUG!? ","%d",__LINE__);
                l = one;
                break;
            case CPOINTER:
+             pic14_emitcode(";BUG!? ","%d",__LINE__);
                l = "#0x02";
                break;                          
            case PPOINTER:
+             pic14_emitcode(";BUG!? ","%d",__LINE__);
                l = "#0x03";
                break;
                
@@ -8975,7 +9120,7 @@ static void genCast (iCode *ic)
                       "got unknown pointer type");
                exit(1);
            }
-           aopPut(AOP(result),l, GPTRSIZE - 1);            
+           //aopPut(AOP(result),l, GPTRSIZE - 1);          
            goto release ;
        }
        
@@ -9001,6 +9146,7 @@ static void genCast (iCode *ic)
     if(genMixedOperation(ic))
       goto release;
 
+    DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
     
     /* we move to result for the size of source */
     size = AOP_SIZE(right);
@@ -9113,35 +9259,35 @@ static int genDjnz (iCode *ic, iCode *ifx)
 /*-----------------------------------------------------------------*/
 static void genReceive (iCode *ic)
 {    
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+  DEBUGpic14_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 =  fReturnSizePic - size;
-       while (size--) {
-           pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
+    int size = getSize(operandType(IC_RESULT(ic)));
+    int offset =  fReturnSizePic - size;
+    while (size--) {
+      pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
                                    fReturn[fReturnSizePic - offset - 1] : "acc"));
-           offset++;
-       }
-       aopOp(IC_RESULT(ic),ic,FALSE);  
-       size = AOP_SIZE(IC_RESULT(ic));
-       offset = 0;
-       while (size--) {
-           pic14_emitcode ("pop","acc");
-           aopPut (AOP(IC_RESULT(ic)),"a",offset++);
-       }
-       
-    } else {
-       _G.accInUse++;
-       aopOp(IC_RESULT(ic),ic,FALSE);  
-       _G.accInUse--;
-       assignResultValue(IC_RESULT(ic));       
+      offset++;
     }
+    aopOp(IC_RESULT(ic),ic,FALSE);  
+    size = AOP_SIZE(IC_RESULT(ic));
+    offset = 0;
+    while (size--) {
+      pic14_emitcode ("pop","acc");
+      aopPut (AOP(IC_RESULT(ic)),"a",offset++);
+    }
+       
+  } else {
+    _G.accInUse++;
+    aopOp(IC_RESULT(ic),ic,FALSE);  
+    _G.accInUse--;
+    assignResultValue(IC_RESULT(ic));  
+  }
 
-    freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
+  freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
 }
 
 /*-----------------------------------------------------------------*/
index f229cad6419e44132f38a971260136b6b454d6bd..f262de7a84e3e070fa076199809e0dc5adc5087a 100644 (file)
@@ -69,6 +69,7 @@ typedef struct asmop
        char *aop_immd;         /* if immediate others are implied */
        int aop_stk;            /* stack offset when AOP_STK */
        char *aop_str[4];       /* just a string array containing the location */
+/*     regs *aop_alloc_reg;     * points to a dynamically allocated register */
       }
     aopu;
   }
index a4e501bb7489af652e8d55a78d236be5c94a036c..832fa55f9ee86c092d00083a3514c1dedec43ae6 100644 (file)
@@ -786,6 +786,7 @@ void genPlus (iCode *ic)
     DEBUGpic14_emitcode(";","adding lit to something. size %d",size);
 
     genAddLit (ic,  lit);
+    goto release;
 
   } else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
 
index 1baf9327a39e6ab7b5b229445d2fec9494ff134d..c48be2671adbefb54b0537d6812b7ed8ead88d92 100644 (file)
 #include "newalloc.h"
 
 
+#ifdef _BIG_ENDIAN
+  #define _ENDIAN(x)  (3-x)
+#else
+  #define _ENDIAN(x)  (x)
+#endif
+
+#define BYTE_IN_LONG(x,b) ((x>>(8*_ENDIAN(b)))&0xff)
+
 extern symbol *interrupts[256];
-void printIval (symbol *, sym_link *, initList *, FILE *);
+static void printIval (symbol * sym, sym_link * type, initList * ilist, pBlock *pb);
 extern int noAlloc;
 extern set *publics;
 extern unsigned maxInterrupts;
@@ -47,50 +55,27 @@ extern char *iComments2;
 extern DEFSETFUNC (closeTmpFiles);
 extern DEFSETFUNC (rmTmpFiles);
 
+extern void AnalyzeBanking (void);
 extern void copyFile (FILE * dest, FILE * src);
 
+extern void writeUsedRegs(FILE *);
 
-//extern void emitMaps ();
-//extern void createInterruptVect (FILE * vFile);
 extern void initialComments (FILE * afile);
 extern void printPublics (FILE * afile);
 
 extern void printChar (FILE * ofile, char *s, int plen);
 
-#if 0
-char *
-aopLiteral (value * val, int offset)
-     static void emitRegularMap (memmap * map, bool addPublics, bool arFlag)
-     value *initPointer (initList * ilist)
-     void printIvalType (sym_link * type, initList * ilist, FILE * oFile)
-     void printIvalStruct (symbol * sym, sym_link * type,
-                          initList * ilist, FILE * oFile)
-     int printIvalChar (sym_link * type, initList * ilist, FILE * oFile, char *s)
-     void printIvalArray (symbol * sym, sym_link * type, initList * ilist,
-                         FILE * oFile)
-     void printIvalFuncPtr (sym_link * type, initList * ilist, FILE * oFile)
-     int printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile)
-     void printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
-#endif
 
 /*-----------------------------------------------------------------*/
-/* Allocation macros that replace those in SDCCalloc.h             */
-/*   Why? I dunno. I ran across a bug with those macros that       */
-/*   I couldn't fix, but I could work around...                    */
+/* aopLiteral - byte from a literal value                          */
 /*-----------------------------------------------------------------*/
+static int
+_aopLiteral (value * val, int offset)
+{
+  unsigned long ul = (unsigned long) floatFromVal (val);
 
-#define  _ALLOC(x,sz) if (!(x = calloc((sz),1) ))      \
-         {                                          \
-            werror(E_OUT_OF_MEM,__FILE__,(long) sz);\
-            exit (1);                               \
-         }
-
-#define _ALLOC_ATOMIC(x,y) if (!((x) = malloc(y)))   \
-         {                                               \
-            werror(E_OUT_OF_MEM,__FILE__,(long) y);     \
-            exit (1);                                    \
-         }
-
+  return  (ul >> (8*_ENDIAN(offset)) &0xff);
+}
 
 /*-----------------------------------------------------------------*/
 /* aopLiteral - string from a literal value                        */
@@ -107,11 +92,7 @@ int pic14aopLiteral (value *val, int offset)
   if (!IS_FLOAT(val->type)) {
     unsigned long v = (unsigned long) floatFromVal(val);
 
-    //v >>= (offset * 8);
     return ( (v >> (offset * 8)) & 0xff);
-    //sprintf(buffer,"0x%02x",((char) v) & 0xff);
-    //_ALLOC_ATOMIC(rs,strlen(buffer)+1);
-    //return strcpy (rs,buffer);
   }
 
   /* it is type float */
@@ -205,18 +186,6 @@ pic14emitRegularMap (memmap * map, bool addPublics, bool arFlag)
          /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
          if (IS_BITVAR (sym->etype))
            {
-             if ((bitvars % 8) == 0)
-               {
-                 fprintf (map->oFile, "  cblock\n");
-                 fprintf (map->oFile, "\tbitfield%d\n", bitvars);
-                 fprintf (map->oFile, "  endc\n");
-               }
-
-             fprintf (map->oFile, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
-                      sym->rname,
-                      bitvars & 0xfff8,
-                      bitvars & 0x0007);
-
              bitvars++;
            }
          else
@@ -250,196 +219,104 @@ pic14emitRegularMap (memmap * map, bool addPublics, bool arFlag)
 }
 
 
-#if 0
-/*-----------------------------------------------------------------*/
-/* initPointer - pointer initialization code massaging             */
-/*-----------------------------------------------------------------*/
-value *
-initPointer (initList * ilist)
-{
-  value *val;
-  ast *expr = list2expr (ilist);
-
-  if (!expr)
-    goto wrong;
-
-  /* try it the oldway first */
-  if ((val = constExprValue (expr, FALSE)))
-    return val;
-
-  /* no then we have to do these cludgy checks */
-  /* pointers can be initialized with address of
-     a variable or address of an array element */
-  if (IS_AST_OP (expr) && expr->opval.op == '&')
-    {
-      /* address of symbol */
-      if (IS_AST_SYM_VALUE (expr->left))
-       {
-         val = copyValue (AST_VALUE (expr->left));
-         val->type = newLink ();
-         if (SPEC_SCLS (expr->left->etype) == S_CODE)
-           {
-             DCL_TYPE (val->type) = CPOINTER;
-             DCL_PTR_CONST (val->type) = port->mem.code_ro;
-           }
-         else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
-           DCL_TYPE (val->type) = FPOINTER;
-         else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
-           DCL_TYPE (val->type) = PPOINTER;
-         else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
-           DCL_TYPE (val->type) = IPOINTER;
-         else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
-           DCL_TYPE (val->type) = EEPPOINTER;
-         else
-           DCL_TYPE (val->type) = POINTER;
-         val->type->next = expr->left->ftype;
-         val->etype = getSpec (val->type);
-         return val;
-       }
-
-      /* if address of indexed array */
-      if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
-       return valForArray (expr->left);
-
-      /* if address of structure element then
-         case 1. a.b ; */
-      if (IS_AST_OP (expr->left) &&
-         expr->left->opval.op == '.')
-       {
-         return valForStructElem (expr->left->left,
-                                  expr->left->right);
-       }
-
-      /* case 2. (&a)->b ;
-         (&some_struct)->element */
-      if (IS_AST_OP (expr->left) &&
-         expr->left->opval.op == PTR_OP &&
-         IS_ADDRESS_OF_OP (expr->left->left))
-       return valForStructElem (expr->left->left->left,
-                                expr->left->right);
-    }
-
-wrong:
-  werror (E_INIT_WRONG);
-  return NULL;
-
-}
-
-/*-----------------------------------------------------------------*/
-/* printChar - formats and prints a characater string with DB      */
-/*-----------------------------------------------------------------*/
-void
-printChar (FILE * ofile, char *s, int plen)
-{
-  int i;
-  int len = strlen (s);
-  int pplen = 0;
-
-  while (len && pplen < plen)
-    {
-
-      fprintf (ofile, "\t.ascii /");
-      i = 60;
-      while (i && *s && pplen < plen)
-       {
-         if (*s < ' ' || *s == '/')
-           {
-             fprintf (ofile, "/\n\t.byte 0x%02x\n\t.ascii /", *s++);
-           }
-         else
-           fprintf (ofile, "%c", *s++);
-         pplen++;
-         i--;
-       }
-      fprintf (ofile, "/\n");
-
-      if (len > 60)
-       len -= 60;
-      else
-       len = 0;
-    }
-  if (pplen < plen)
-    fprintf (ofile, "\t.byte\t0\n");
-}
-
 /*-----------------------------------------------------------------*/
 /* printIvalType - generates ival for int/char                     */
 /*-----------------------------------------------------------------*/
-void
-printIvalType (sym_link * type, initList * ilist, FILE * oFile)
+static void 
+printIvalType (symbol *sym, sym_link * type, initList * ilist, pBlock *pb)
 {
   value *val;
+  unsigned long ulval;
+
+  //fprintf(stderr, "%s\n",__FUNCTION__);
 
   /* if initList is deep */
   if (ilist->type == INIT_DEEP)
     ilist = ilist->init.deep;
 
-  val = list2val (ilist);
-  switch (getSize (type))
-    {
-    case 1:
-      if (!val)
-       fprintf (oFile, "\t.byte 0\n");
-      else
-       fprintf (oFile, "\t.byte %s\n",
-                aopLiteral (val, 0));
-      break;
-
-    case 2:
-      if (!val)
-       fprintf (oFile, "\t.word 0\n");
-      else
-       fprintf (oFile, "\t.byte %s,%s\n",
-                aopLiteral (val, 0), aopLiteral (val, 1));
-      break;
-
-    case 4:
-      if (!val)
-       fprintf (oFile, "\t.word 0,0\n");
-      else
-       fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
-                aopLiteral (val, 0), aopLiteral (val, 1),
-                aopLiteral (val, 2), aopLiteral (val, 3));
-      break;
-    }
+  if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
+    werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
+  }
 
-  return;
-}
+  if (!(val = list2val (ilist))) {
+    // assuming a warning has been thrown
+    val=constVal("0");
+  }
 
-/*-----------------------------------------------------------------*/
-/* printIvalStruct - generates initial value for structures        */
-/*-----------------------------------------------------------------*/
-void
-printIvalStruct (symbol * sym, sym_link * type,
-                initList * ilist, FILE * oFile)
-{
-  symbol *sflds;
-  initList *iloop;
+  if (val->type != type) {
+    val = valCastLiteral(type, floatFromVal(val));
+  }
 
-  sflds = SPEC_STRUCT (type)->fields;
-  if (ilist->type != INIT_DEEP)
-    {
-      werror (E_INIT_STRUCT, sym->name);
-      return;
+  if(val) 
+    ulval = (unsigned long) floatFromVal (val);
+  else
+    ulval =0;
+
+  switch (getSize (type)) {
+  case 1:
+    //tfprintf (oFile, "\t!dbs\n",aopLiteral (val, 0));
+    addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
+    //fprintf(stderr,"0x%02x\n",_aopLiteral(val,0));
+
+    break;
+
+  case 2:
+    // if (port->use_dw_for_init) {
+    //tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2));
+    //  fprintf(stderr,"%s:%d  aopLiteralLong\n",__FILE__,__LINE__);
+    //}else
+    //fprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
+    //fprintf(stderr,"0x%02x  0x%02x\n",_aopLiteral(val,0),_aopLiteral(val,1));
+    addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
+    addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
+    break;
+  case 4:
+    /*
+    if (!val) {
+      tfprintf (oFile, "\t!dw !constword\n", 0);
+      tfprintf (oFile, "\t!dw !constword\n", 0);
     }
-
-  iloop = ilist->init.deep;
-
-  for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
-    printIval (sflds, sflds->type, iloop, oFile);
-
-  return;
+    else {
+      fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
+              aopLiteral (val, 0), aopLiteral (val, 1),
+              aopLiteral (val, 2), aopLiteral (val, 3));
+      fprintf(stderr,"0x%02x  0x%02x 0x%02x  0x%02x\n",
+             _aopLiteral(val,0),_aopLiteral(val,1),
+             _aopLiteral(val,2),_aopLiteral(val,3));
+    }
+    */
+    addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
+    addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
+    addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,2))));
+    addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,3))));
+    break;
+  }
+#if 0
+  {
+    int size = getSize(type);
+
+    fprintf(stderr," size=%d, val =",size);
+    if(val)
+      fprintf(stderr,"0x%02x\n",_aopLiteral(val,0));
+    else
+      fprintf(stderr,"none\n");
+  }
+#endif
 }
 
 /*-----------------------------------------------------------------*/
 /* printIvalChar - generates initital value for character array    */
 /*-----------------------------------------------------------------*/
-int
-printIvalChar (sym_link * type, initList * ilist, FILE * oFile, char *s)
+static int 
+printIvalChar (sym_link * type, initList * ilist, pBlock *pb, char *s)
 {
   value *val;
   int remain;
 
+  if(!pb)
+    return 0;
+
+  //fprintf(stderr, "%s\n",__FUNCTION__);
   if (!s)
     {
 
@@ -450,45 +327,58 @@ printIvalChar (sym_link * type, initList * ilist, FILE * oFile, char *s)
          if (!DCL_ELEM (type))
            DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
 
-         /* if size mismatch  */
-/*      if (DCL_ELEM (type) < ((int) strlen (SPEC_CVAL (val->etype).v_char) + 1)) */
-/*    werror (E_ARRAY_BOUND); */
-
-         printChar (oFile, SPEC_CVAL (val->etype).v_char, DCL_ELEM (type));
+         //printChar (oFile, SPEC_CVAL (val->etype).v_char, DCL_ELEM (type));
+         //fprintf(stderr, "%s omitting call to printChar\n",__FUNCTION__);
+         addpCode2pBlock(pb,newpCodeCharP(";omitting call to printChar"));
 
          if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0)
            while (remain--)
-             fprintf (oFile, "\t.byte 0\n");
-
+             //tfprintf (oFile, "\t!db !constbyte\n", 0);
+             addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(0)));
          return 1;
        }
       else
        return 0;
     }
-  else
-    printChar (oFile, s, strlen (s) + 1);
+  else {
+    //printChar (oFile, s, strlen (s) + 1);
+
+    for(remain=0; remain<strlen(s); remain++) {
+      addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(s[remain])));
+      //fprintf(stderr,"0x%02x ",s[remain]);
+    }
+    //fprintf(stderr,"\n");
+  }
   return 1;
 }
 
 /*-----------------------------------------------------------------*/
 /* printIvalArray - generates code for array initialization        */
 /*-----------------------------------------------------------------*/
-void
+static void 
 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
-               FILE * oFile)
+               pBlock *pb)
 {
   initList *iloop;
   int lcnt = 0, size = 0;
 
+  if(!pb)
+    return;
+
   /* take care of the special   case  */
   /* array of characters can be init  */
   /* by a string                      */
-  if (IS_CHAR (type->next))
+  if (IS_CHAR (type->next)) {
+    //fprintf(stderr,"%s:%d - is_char\n",__FUNCTION__,__LINE__);
+    if (!IS_LITERAL(list2val(ilist)->etype)) {
+      werror (W_INIT_WRONG);
+      return;
+    }
     if (printIvalChar (type,
                       (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
-                      oFile, SPEC_CVAL (sym->etype).v_char))
+                      pb, SPEC_CVAL (sym->etype).v_char))
       return;
-
+  }
   /* not the special case             */
   if (ilist->type != INIT_DEEP)
     {
@@ -501,8 +391,9 @@ printIvalArray (symbol * sym, sym_link * type, initList * ilist,
 
   for (;;)
     {
+      //fprintf(stderr,"%s:%d - is_char\n",__FUNCTION__,__LINE__);
       size++;
-      printIval (sym, type->next, iloop, oFile);
+      printIval (sym, type->next, iloop, pb);
       iloop = (iloop ? iloop->next : NULL);
 
 
@@ -513,8 +404,13 @@ printIvalArray (symbol * sym, sym_link * type, initList * ilist,
 
       /* no of elements given and we    */
       /* have generated for all of them */
-      if (!--lcnt)
+      if (!--lcnt) {
+       /* if initializers left */
+       if (iloop) {
+         werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
+       }
        break;
+      }
     }
 
   /* if we have not been given a size  */
@@ -524,177 +420,49 @@ printIvalArray (symbol * sym, sym_link * type, initList * ilist,
   return;
 }
 
-/*-----------------------------------------------------------------*/
-/* printIvalFuncPtr - generate initial value for function pointers */
-/*-----------------------------------------------------------------*/
-void
-printIvalFuncPtr (sym_link * type, initList * ilist, FILE * oFile)
-{
-  value *val;
-  int dLvl = 0;
-
-  val = list2val (ilist);
-  /* check the types   */
-  if ((dLvl = checkType (val->type, type->next)) <= 0)
-    {
-
-      fprintf (oFile, "\t.word 0\n");
-      return;
-    }
-
-  /* now generate the name */
-  if (!val->sym)
-    {
-      if (IS_LITERAL (val->etype))
-       fprintf (oFile, "\t.byte %s,%s\n",
-                aopLiteral (val, 0), aopLiteral (val, 1));
-      else
-       fprintf (oFile, "\t.byte %s,(%s >> 8)\n",
-                val->name, val->name);
-    }
-  else
-    fprintf (oFile, "\t.byte %s,(%s >> 8)\n",
-            val->sym->rname, val->sym->rname);
-
-  return;
-}
-
-/*-----------------------------------------------------------------*/
-/* printIvalCharPtr - generates initial values for character pointers */
-/*-----------------------------------------------------------------*/
-int
-printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile)
-{
-  int size = 0;
-
-  size = getSize (type);
-
-  if (size == 1)
-    fprintf (oFile,
-            "\t.byte %s", val->name);
-  else
-    fprintf (oFile,
-            "\t.byte %s,(%s >> 8)",
-            val->name, val->name);
-
-  if (size > 2)
-    fprintf (oFile, ",#0x02\n");
-  else
-    fprintf (oFile, "\n");
-
-  if (val->sym && val->sym->isstrlit)
-    addSet (&statsg->syms, val->sym);
-
-  return 1;
-}
-
-/*-----------------------------------------------------------------*/
-/* printIvalPtr - generates initial value for pointers             */
-/*-----------------------------------------------------------------*/
-void
-printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
-{
-  value *val;
-
-  /* if deep then   */
-  if (ilist->type == INIT_DEEP)
-    ilist = ilist->init.deep;
-
-  /* function pointer     */
-  if (IS_FUNC (type->next))
-    {
-      printIvalFuncPtr (type, ilist, oFile);
-      return;
-    }
-
-  if (!(val = initPointer (ilist)))
-    return;
-
-  /* if character pointer */
-  if (IS_CHAR (type->next))
-    if (printIvalCharPtr (sym, type, val, oFile))
-      return;
-
-  /* check the type      */
-  if (checkType (type, val->type) != 1)
-    werror (E_INIT_WRONG);
-
-  /* if val is literal */
-  if (IS_LITERAL (val->etype))
-    {
-      switch (getSize (type))
-       {
-       case 1:
-         fprintf (oFile, "\t.byte 0x%02x\n", ((char) floatFromVal (val)) & 0xff);
-         break;
-       case 2:
-         fprintf (oFile, "\t.byte %s,%s\n",
-                  aopLiteral (val, 0), aopLiteral (val, 1));
-
-         break;
-       case 3:
-         fprintf (oFile, "\t.byte %s,%s,0x%02x\n",
-                  aopLiteral (val, 0), aopLiteral (val, 1), CPOINTER);
-       }
-      return;
-    }
-
-
-  switch (getSize (type))
-    {
-    case 1:
-      fprintf (oFile, "\t.byte %s\n", val->name);
-      break;
-    case 2:
-      fprintf (oFile, "\t.byte %s,(%s >> 8)\n", val->name, val->name);
-      break;
-
-    case 3:
-      fprintf (oFile, "\t.byte %s,(%s >> 8),0x%02x\n",
-              val->name, val->name, DCL_TYPE (val->type));
-    }
-  return;
-}
-
 /*-----------------------------------------------------------------*/
 /* printIval - generates code for initial value                    */
 /*-----------------------------------------------------------------*/
-void
-printIval (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
+static void 
+printIval (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
 {
-  if (!ilist)
+  if (!ilist || !pb)
     return;
 
   /* if structure then    */
   if (IS_STRUCT (type))
     {
-      printIvalStruct (sym, type, ilist, oFile);
+      //fprintf(stderr,"%s struct\n",__FUNCTION__);
+      //printIvalStruct (sym, type, ilist, oFile);
       return;
     }
 
   /* if this is a pointer */
   if (IS_PTR (type))
     {
-      printIvalPtr (sym, type, ilist, oFile);
+      //fprintf(stderr,"%s pointer\n",__FUNCTION__);
+      //printIvalPtr (sym, type, ilist, oFile);
       return;
     }
 
   /* if this is an array   */
   if (IS_ARRAY (type))
     {
-      printIvalArray (sym, type, ilist, oFile);
+      //fprintf(stderr,"%s array\n",__FUNCTION__);
+      printIvalArray (sym, type, ilist, pb);
       return;
     }
 
   /* if type is SPECIFIER */
   if (IS_SPEC (type))
     {
-      printIvalType (type, ilist, oFile);
+      //fprintf(stderr,"%s spec\n",__FUNCTION__);
+      printIvalType (sym, type, ilist, pb);
       return;
     }
 }
 
-#endif
+extern void pCodeConstString(char *name, char *value);
 /*-----------------------------------------------------------------*/
 /* emitStaticSeg - emitcode for the static segment                 */
 /*-----------------------------------------------------------------*/
@@ -705,12 +473,12 @@ pic14emitStaticSeg (memmap * map)
 
   fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
 
+  //fprintf(stderr, "%s\n",__FUNCTION__);
 
   /* for all variables in this segment do */
   for (sym = setFirstItem (map->syms); sym;
        sym = setNextItem (map->syms))
     {
-
       /* if it is "extern" then do nothing */
       if (IS_EXTERN (sym->etype))
        continue;
@@ -723,8 +491,10 @@ pic14emitStaticSeg (memmap * map)
       /* print extra debug info if required */
       if (options.debug || sym->level == 0)
        {
-
-         cdbSymbol (sym, cdbFile, FALSE, FALSE);
+         /* NOTE to me - cdbFile may be null in which case,
+          * the sym name will be printed to stdout. oh well */
+         if(cdbFile)
+           cdbSymbol (sym, cdbFile, FALSE, FALSE);
 
          if (!sym->level)
            {                   /* global */
@@ -738,6 +508,7 @@ pic14emitStaticSeg (memmap * map)
            fprintf (code->oFile, "L%s_",
                     (sym->localof ? sym->localof->name : "-null-"));
          fprintf (code->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
+
        }
 
       /* if it has an absolute address */
@@ -758,27 +529,37 @@ pic14emitStaticSeg (memmap * map)
          /* if it has an initial value */
          if (sym->ival)
            {
+             pBlock *pb;
+
              fprintf (code->oFile, "%s:\n", sym->rname);
              noAlloc++;
              resolveIvalSym (sym->ival);
-             printIval (sym, sym->type, sym->ival, code->oFile);
+             //printIval (sym, sym->type, sym->ival, code->oFile);
+             pb = newpCodeChain(NULL, 'P',newpCodeCharP("; Starting pCode block for Ival"));
+             addpBlock(pb);
+             addpCode2pBlock(pb,newpCodeLabel(sym->rname,-1));
+
+             printIval (sym, sym->type, sym->ival, pb);
              noAlloc--;
            }
          else
            {
+
              /* allocate space */
              fprintf (code->oFile, "%s:\n", sym->rname);
              /* special case for character strings */
              if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
                  SPEC_CVAL (sym->etype).v_char)
-               printChar (code->oFile,
+               pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
+               /*printChar (code->oFile,
                           SPEC_CVAL (sym->etype).v_char,
-                          strlen (SPEC_CVAL (sym->etype).v_char) + 1);
+                          strlen (SPEC_CVAL (sym->etype).v_char) + 1);*/
              else
                fprintf (code->oFile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
            }
        }
     }
+
 }
 
 
@@ -845,7 +626,7 @@ pic14createInterruptVect (FILE * vFile)
       for (; i < maxInterrupts; i++)
        {
          if (interrupts[i])
-           fprintf (vFile, ";\tljmp\t%s\n\t.ds\t5\n", interrupts[i]->rname);
+           fprintf (vFile, ";\tljmp\t%s\n;\t.ds\t5\n", interrupts[i]->rname);
          else
            fprintf (vFile, ";\treti\n;\t.ds\t7\n");
        }
@@ -987,7 +768,6 @@ pic14emitOverlay (FILE * afile)
 }
 
 
-
 /*-----------------------------------------------------------------*/
 /* glue - the final glue that hold the whole thing together        */
 /*-----------------------------------------------------------------*/
@@ -998,7 +778,8 @@ picglue ()
   FILE *vFile;
   FILE *asmFile;
   FILE *ovrFile = tempfile();
-  int i;
+  //  int i;
+#if 0
   set *s=NULL,*t=NULL;
   char a=1,b=2,c=3;
 
@@ -1018,6 +799,7 @@ picglue ()
     if(t->item) 
       DFPRINTF((stderr,"Set item %d\n",*(char *)t->item));
   }
+#endif
 
   addSetHead(&tmpfileSet,ovrFile);
 
@@ -1028,7 +810,7 @@ picglue ()
     addpBlock(pb);
 
     /* entry point @ start of CSEG */
-    addpCode2pBlock(pb,newpCodeLabelStr("__sdcc_program_startup"));
+    addpCode2pBlock(pb,newpCodeLabel("__sdcc_program_startup",-1));
     /* put in the call to main */
     addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp("_main",PO_STR)));
 
@@ -1050,16 +832,12 @@ picglue ()
   /* Now it needs to be rearranged into the order it should be placed in the */
   /* code space */
 
-  movepBlock2Head(code->dbName);     // Last
+  movepBlock2Head('P');              // Last
+  movepBlock2Head(code->dbName);
   movepBlock2Head('X');
   movepBlock2Head(statsg->dbName);   // First
 
 
-  AnalyzepCode('*'); //code->dbName);
-#ifdef PCODE_DEBUG
-  printCallTree(stderr);
-#endif
-
   /* print the global struct definitions */
   if (options.debug)
     cdbStructBlock (0,cdbFile);
@@ -1079,6 +857,12 @@ picglue ()
   pic14emitOverlay(ovrFile);
 
 
+  AnalyzepCode('*'); //code->dbName);
+
+  //#ifdef PCODE_DEBUG
+  printCallTree(stderr);
+  //#endif
+
   pcode_test();
 
 
@@ -1122,36 +906,8 @@ picglue ()
     
 
   /* Put all variables into a cblock */
-  fprintf (asmFile, "\n\n\tcblock  0x20\n\n");
-
-  for(i=0; i<pic14_nRegs; i++) {
-    if(regspic14[i].wasUsed && (regspic14[i].offset>=0x0c) )
-      fprintf (asmFile, "\t%s\n",regspic14[i].name);
-  }
-
-
-  /* For now, create a "dpl" and a "dph" in the register space */
-  /* of the pic so that we can use the same calling mechanism */
-  /* as the 8051 port */
-  fprintf (asmFile, "%s", iComments2);
-  fprintf (asmFile, "; dpl and dph to emulate the 8051 calling mechanism \n");
-  fprintf (asmFile, "%s", iComments2);
-
-
-  /* copy the sbit segment */
-  fprintf (asmFile, "%s", iComments2);
-  fprintf (asmFile, "; special function bits \n");
-  fprintf (asmFile, "%s", iComments2);
-  copyFile (asmFile, sfrbit->oFile);
-    
-  /* copy the data segment */
-  fprintf (asmFile, "%s", iComments2);
-  fprintf (asmFile, "; internal ram data\n");
-  fprintf (asmFile, "%s", iComments2);
-  copyFile (asmFile, data->oFile);
-
-  fprintf (asmFile, "\tendc\n");
-
+  writeUsedRegs(asmFile);
+  AnalyzeBanking();
 
   /* create the overlay segments */
   fprintf (asmFile, "%s", iComments2);
@@ -1254,11 +1010,14 @@ picglue ()
   fprintf (asmFile, "%s", iComments2);
   fprintf (asmFile, ";\t.area %s\n", port->mem.code_name);
 
-  //copyFile (asmFile, code->oFile);
+  //copyFile (stderr, code->oFile);
 
+  copypCode(asmFile, 'I');
   copypCode(asmFile, statsg->dbName);
   copypCode(asmFile, 'X');
+  copypCode(asmFile, 'M');
   copypCode(asmFile, code->dbName);
+  copypCode(asmFile, 'P');
 
 
   fprintf (asmFile,"\tend\n");
index 8669abd9a161cbc974da7a7f74179c2b4812d1db..96ae3b39c83261f62220f279c2b27ada7fb9e2bb 100644 (file)
@@ -159,12 +159,22 @@ _pic14_getRegName (struct regs *reg)
   return "err";
 }
 
+extern char *processor_base_name(void);
+
 static void
 _pic14_genAssemblerPreamble (FILE * of)
 {
-  fprintf (of, "\tlist\tp=16f877\n");
+  char * name = processor_base_name();
+
+  if(!name) {
+
+    name = "p16f877";
+    fprintf(stderr,"WARNING: No Pic has been selected, defaulting to %s\n",name);
+  }
+
+  fprintf (of, "\tlist\tp=%s\n",&name[1]);
   fprintf (of, "\t__config _wdt_off\n");
-  fprintf (of, "\ninclude \"p16f877.inc\"\n");
+  fprintf (of, "\ninclude \"%s.inc\"\n",name);
 }
 
 /* Generate interrupt vector table. */
index 14522f8afc07daa5909b9d09952e98be8a53afc2..f2177942d87b22a6137d0572d0835d63bbbfcfad 100644 (file)
@@ -25,7 +25,9 @@
 
 
 #include "pcode.h"
+#include "pcodeflow.h"
 #include "ralloc.h"
+#include "device.h"
 
 #if defined(__BORLANDC__) || defined(_MSC_VER)
 #define STRCASECMP stricmp
 #define STRCASECMP strcasecmp
 #endif
 
+
 // Eventually this will go into device dependent files:
-pCodeOpReg pc_status    = {{PO_STATUS,  "STATUS"}, -1, NULL,NULL};
-pCodeOpReg pc_indf      = {{PO_INDF,    "INDF"}, -1, NULL,NULL};
-pCodeOpReg pc_fsr       = {{PO_FSR,     "FSR"}, -1, NULL,NULL};
-pCodeOpReg pc_pcl       = {{PO_PCL,     "PCL"}, -1, NULL,NULL};
-pCodeOpReg pc_pclath    = {{PO_PCLATH,  "PCLATH"}, -1, NULL,NULL};
+pCodeOpReg pc_status    = {{PO_STATUS,  "STATUS"}, -1, NULL,0,NULL};
+pCodeOpReg pc_indf      = {{PO_INDF,    "INDF"}, -1, NULL,0,NULL};
+pCodeOpReg pc_fsr       = {{PO_FSR,     "FSR"}, -1, NULL,0,NULL};
+pCodeOpReg pc_intcon    = {{PO_INTCON,  ""}, -1, NULL,0,NULL};
+pCodeOpReg pc_pcl       = {{PO_PCL,     "PCL"}, -1, NULL,0,NULL};
+pCodeOpReg pc_pclath    = {{PO_PCLATH,  "PCLATH"}, -1, NULL,0,NULL};
 
-pCodeOpReg pc_kzero     = {{PO_GPR_REGISTER,  "KZ"}, -1, NULL,NULL};
+pCodeOpReg pc_kzero     = {{PO_GPR_REGISTER,  "KZ"}, -1, NULL,0,NULL};
+pCodeOpReg pc_wsave     = {{PO_GPR_REGISTER,  "W_SAVE"}, -1, NULL,0,NULL};
+pCodeOpReg pc_ssave     = {{PO_GPR_REGISTER,  "STATUS_SAVE"}, -1, NULL,0,NULL};
 
 static int mnemonics_initialized = 0;
 
@@ -52,16 +58,27 @@ static hTab *pic14MnemonicsHash = NULL;
 static pFile *the_pFile = NULL;
 static int peepOptimizing = 0;
 static int GpCodeSequenceNumber = 1;
+static int GpcFlowSeq = 1;
+
+#define isPCI(x)        ((PCODE(x)->type == PC_OPCODE))
+#define isPCI_BRANCH(x) ((PCODE(x)->type == PC_OPCODE) &&  PCI(x)->isBranch)
+#define isPCI_SKIP(x)   ((PCODE(x)->type == PC_OPCODE) &&  PCI(x)->isSkip)
+#define isPCFL(x)       ((PCODE(x)->type == PC_FLOW))
+#define isPCF(x)        ((PCODE(x)->type == PC_FUNCTION))
+#define isCALL(x)       ((isPCI(x)) && (PCI(x)->op == POC_CALL))
+#define isSTATUS_REG(r) ((r)->pc_type == PO_STATUS)
 
 /****************************************************************/
 /*                      Forward declarations                    */
 /****************************************************************/
 
 static void unlinkPC(pCode *pc);
+#if 0
 static void genericAnalyze(pCode *pc);
 static void AnalyzeGOTO(pCode *pc);
 static void AnalyzeSKIP(pCode *pc);
 static void AnalyzeRETURN(pCode *pc);
+#endif
 
 static void genericDestruct(pCode *pc);
 static void genericPrint(FILE *of,pCode *pc);
@@ -73,665 +90,916 @@ static char *get_op( pCodeInstruction *pcc);
 int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd);
 int pCodePeepMatchRule(pCode *pc);
 void pBlockStats(FILE *of, pBlock *pb);
-
+extern void pCodeInsertAfter(pCode *pc1, pCode *pc2);
 
 pCodeInstruction pciADDWF = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_ADDWF,
   "ADDWF",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   2,    // num ops
   1,0,  // dest, bit instruction
+  0,0,  // branch, skip
   (PCC_W | PCC_REGISTER),   // inCond
   (PCC_REGISTER | PCC_Z) // outCond
 };
 
 pCodeInstruction pciADDFW = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_ADDWF,
   "ADDWF",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   2,    // num ops
   0,0,  // dest, bit instruction
+  0,0,  // branch, skip
   (PCC_W | PCC_REGISTER),   // inCond
   (PCC_W | PCC_Z) // outCond
 };
 
 pCodeInstruction pciADDLW = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_ADDLW,
   "ADDLW",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   1,    // num ops
   0,0,  // dest, bit instruction
+  0,0,  // branch, skip
   PCC_W,   // inCond
   (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
 };
 
 pCodeInstruction pciANDLW = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_ANDLW,
   "ANDLW",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   1,    // num ops
   0,0,  // dest, bit instruction
+  0,0,  // branch, skip
   PCC_W,   // inCond
   (PCC_W | PCC_Z) // outCond
 };
 
 pCodeInstruction pciANDWF = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_ANDWF,
   "ANDWF",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   2,    // num ops
   1,0,  // dest, bit instruction
+  0,0,  // branch, skip
   (PCC_W | PCC_REGISTER),   // inCond
   (PCC_REGISTER | PCC_Z) // outCond
 };
 
 pCodeInstruction pciANDFW = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_ANDWF,
   "ANDWF",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   2,    // num ops
   0,0,  // dest, bit instruction
+  0,0,  // branch, skip
   (PCC_W | PCC_REGISTER),   // inCond
   (PCC_W | PCC_Z) // outCond
 };
 
 pCodeInstruction pciBCF = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_BCF,
   "BCF",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   2,    // num ops
-  0,1,  // dest, bit instruction
-  PCC_NONE,   // inCond
-  PCC_EXAMINE_PCOP // outCond
+  1,1,  // dest, bit instruction
+  0,0,  // branch, skip
+  PCC_REGISTER,   // inCond
+  PCC_REGISTER // outCond
 };
 
 pCodeInstruction pciBSF = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_BSF,
   "BSF",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   2,    // num ops
-  0,1,  // dest, bit instruction
-  PCC_NONE,   // inCond
-  PCC_EXAMINE_PCOP // outCond
+  1,1,  // dest, bit instruction
+  0,0,  // branch, skip
+  PCC_REGISTER,   // inCond
+  PCC_REGISTER // outCond
 };
 
 pCodeInstruction pciBTFSC = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   AnalyzeSKIP,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   AnalyzeSKIP,
    genericDestruct,
    genericPrint},
   POC_BTFSC,
   "BTFSC",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   2,    // num ops
   0,1,  // dest, bit instruction
-  PCC_EXAMINE_PCOP,   // inCond
+  1,1,  // branch, skip
+  PCC_REGISTER,   // inCond
   PCC_NONE // outCond
 };
 
 pCodeInstruction pciBTFSS = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   AnalyzeSKIP,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   AnalyzeSKIP,
    genericDestruct,
    genericPrint},
   POC_BTFSS,
   "BTFSS",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   2,    // num ops
   0,1,  // dest, bit instruction
-  PCC_EXAMINE_PCOP,   // inCond
+  1,1,  // branch, skip
+  PCC_REGISTER,   // inCond
   PCC_NONE // outCond
 };
 
 pCodeInstruction pciCALL = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_CALL,
   "CALL",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   1,    // num ops
   0,0,  // dest, bit instruction
+  1,0,  // branch, skip
   PCC_NONE, // inCond
   PCC_NONE  // outCond
 };
 
 pCodeInstruction pciCOMF = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_COMF,
   "COMF",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   2,    // num ops
   1,0,  // dest, bit instruction
+  0,0,  // branch, skip
   PCC_REGISTER,  // inCond
   PCC_REGISTER   // outCond
 };
 
 pCodeInstruction pciCOMFW = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_COMFW,
   "COMF",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   2,    // num ops
   0,0,  // dest, bit instruction
+  0,0,  // branch, skip
   PCC_REGISTER,  // inCond
   PCC_W   // outCond
 };
 
 pCodeInstruction pciCLRF = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_CLRF,
   "CLRF",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   1,    // num ops
   0,0,  // dest, bit instruction
+  0,0,  // branch, skip
   PCC_REGISTER, // inCond
   PCC_REGISTER  // outCond
 };
 
 pCodeInstruction pciCLRW = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_CLRW,
   "CLRW",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   0,    // num ops
   0,0,  // dest, bit instruction
+  0,0,  // branch, skip
   PCC_W, // inCond
   PCC_W  // outCond
 };
 
 pCodeInstruction pciDECF = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_DECF,
   "DECF",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   2,    // num ops
   1,0,  // dest, bit instruction
+  0,0,  // branch, skip
   PCC_REGISTER,   // inCond
   PCC_REGISTER    // outCond
 };
 
 pCodeInstruction pciDECFW = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_DECFW,
   "DECF",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   2,    // num ops
   0,0,  // dest, bit instruction
+  0,0,  // branch, skip
   PCC_REGISTER,   // inCond
   PCC_W    // outCond
 };
 
 pCodeInstruction pciDECFSZ = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   AnalyzeSKIP,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   AnalyzeSKIP,
    genericDestruct,
    genericPrint},
   POC_DECFSZ,
   "DECFSZ",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   2,    // num ops
   1,0,  // dest, bit instruction
+  1,1,  // branch, skip
   PCC_REGISTER,   // inCond
   PCC_REGISTER    // outCond
 };
 
 pCodeInstruction pciDECFSZW = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   AnalyzeSKIP,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   AnalyzeSKIP,
    genericDestruct,
    genericPrint},
   POC_DECFSZW,
   "DECFSZ",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   2,    // num ops
   0,0,  // dest, bit instruction
+  1,1,  // branch, skip
   PCC_REGISTER,   // inCond
   PCC_W           // outCond
 };
 
 pCodeInstruction pciGOTO = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   AnalyzeGOTO,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   AnalyzeGOTO,
    genericDestruct,
    genericPrint},
   POC_GOTO,
   "GOTO",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   1,    // num ops
   0,0,  // dest, bit instruction
+  1,0,  // branch, skip
   PCC_NONE,   // inCond
   PCC_NONE    // outCond
 };
 
 
 pCodeInstruction pciINCF = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_INCF,
   "INCF",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   2,    // num ops
   1,0,  // dest, bit instruction
+  0,0,  // branch, skip
   PCC_REGISTER,   // inCond
   PCC_REGISTER    // outCond
 };
 
 pCodeInstruction pciINCFW = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_INCFW,
   "INCF",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   2,    // num ops
   0,0,  // dest, bit instruction
+  0,0,  // branch, skip
   PCC_REGISTER,   // inCond
   PCC_W    // outCond
 };
 
 pCodeInstruction pciINCFSZ = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   AnalyzeSKIP,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   AnalyzeSKIP,
    genericDestruct,
    genericPrint},
   POC_INCFSZ,
   "INCFSZ",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   2,    // num ops
   1,0,  // dest, bit instruction
+  1,1,  // branch, skip
   PCC_REGISTER,   // inCond
   PCC_REGISTER    // outCond
 };
 
 pCodeInstruction pciINCFSZW = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   AnalyzeSKIP,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   AnalyzeSKIP,
    genericDestruct,
    genericPrint},
   POC_INCFSZW,
   "INCFSZ",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   2,    // num ops
   0,0,  // dest, bit instruction
+  1,1,  // branch, skip
   PCC_REGISTER,   // inCond
   PCC_W           // outCond
 };
 
 pCodeInstruction pciIORWF = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_IORWF,
   "IORWF",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   2,    // num ops
   1,0,  // dest, bit instruction
+  0,0,  // branch, skip
   (PCC_W | PCC_REGISTER),   // inCond
   (PCC_REGISTER | PCC_Z) // outCond
 };
 
 pCodeInstruction pciIORFW = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_IORWF,
   "IORWF",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   2,    // num ops
   0,0,  // dest, bit instruction
+  0,0,  // branch, skip
   (PCC_W | PCC_REGISTER),   // inCond
   (PCC_W | PCC_Z) // outCond
 };
 
 pCodeInstruction pciIORLW = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_IORLW,
   "IORLW",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   1,    // num ops
   0,0,  // dest, bit instruction
+  0,0,  // branch, skip
   PCC_W,   // inCond
   (PCC_W | PCC_Z) // outCond
 };
 
 pCodeInstruction pciMOVF = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_MOVF,
   "MOVF",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   2,    // num ops
   1,0,  // dest, bit instruction
+  0,0,  // branch, skip
   PCC_REGISTER,   // inCond
   PCC_Z // outCond
 };
 
 pCodeInstruction pciMOVFW = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_MOVFW,
   "MOVF",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   2,    // num ops
   0,0,  // dest, bit instruction
+  0,0,  // branch, skip
   PCC_REGISTER,   // inCond
   (PCC_W | PCC_Z) // outCond
 };
 
 pCodeInstruction pciMOVWF = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_MOVWF,
   "MOVWF",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   1,    // num ops
   0,0,  // dest, bit instruction
+  0,0,  // branch, skip
   PCC_W,   // inCond
-  0 // outCond
+  PCC_REGISTER // outCond
 };
 
 pCodeInstruction pciMOVLW = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_MOVLW,
   "MOVLW",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   1,    // num ops
   0,0,  // dest, bit instruction
+  0,0,  // branch, skip
   PCC_NONE,   // inCond
   PCC_W // outCond
 };
 
-pCodeInstruction pciNEGF = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+pCodeInstruction pciNOP = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
    genericDestruct,
    genericPrint},
-  POC_NEGF,
-  "NEGF",
+  POC_NOP,
+  "NOP",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
-  1,    // num ops
+  NULL, // flow block
+  0,    // num ops
   0,0,  // dest, bit instruction
-  PCC_REGISTER,   // inCond
+  0,0,  // branch, skip
+  PCC_NONE,   // inCond
   PCC_NONE // outCond
 };
 
+pCodeInstruction pciRETFIE = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   AnalyzeRETURN,
+   genericDestruct,
+   genericPrint},
+  POC_RETFIE,
+  "RETFIE",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
+  NULL, // operand
+  NULL, // flow block
+  0,    // num ops
+  0,0,  // dest, bit instruction
+  1,0,  // branch, skip
+  PCC_NONE,   // inCond
+  PCC_NONE // outCond (not true... affects the GIE bit too)
+};
 
 pCodeInstruction pciRETLW = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   AnalyzeRETURN,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   AnalyzeRETURN,
    genericDestruct,
    genericPrint},
   POC_RETLW,
   "RETLW",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   1,    // num ops
   0,0,  // dest, bit instruction
+  1,0,  // branch, skip
   PCC_NONE,   // inCond
   PCC_W // outCond
 };
 
 pCodeInstruction pciRETURN = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   AnalyzeRETURN,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   AnalyzeRETURN,
    genericDestruct,
    genericPrint},
   POC_RETURN,
   "RETURN",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   0,    // num ops
   0,0,  // dest, bit instruction
+  1,0,  // branch, skip
   PCC_NONE,   // inCond
-  PCC_W // outCond
+  PCC_NONE // outCond
 };
 
-
 pCodeInstruction pciRLF = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_RLF,
   "RLF",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   2,    // num ops
   1,0,  // dest, bit instruction
+  0,0,  // branch, skip
   (PCC_C | PCC_REGISTER),   // inCond
   (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC) // outCond
 };
 
 pCodeInstruction pciRLFW = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_RLFW,
   "RLF",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   2,    // num ops
   0,0,  // dest, bit instruction
+  0,0,  // branch, skip
   (PCC_C | PCC_REGISTER),   // inCond
   (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
 };
 
 pCodeInstruction pciRRF = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_RRF,
   "RRF",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   2,    // num ops
   1,0,  // dest, bit instruction
+  0,0,  // branch, skip
   (PCC_C | PCC_REGISTER),   // inCond
   (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC) // outCond
 };
 
 pCodeInstruction pciRRFW = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_RRFW,
   "RRF",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   2,    // num ops
   0,0,  // dest, bit instruction
+  0,0,  // branch, skip
   (PCC_C | PCC_REGISTER),   // inCond
   (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
 };
 
 pCodeInstruction pciSUBWF = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_SUBWF,
   "SUBWF",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   2,    // num ops
   1,0,  // dest, bit instruction
+  0,0,  // branch, skip
   (PCC_W | PCC_REGISTER),   // inCond
   (PCC_REGISTER | PCC_Z) // outCond
 };
 
 pCodeInstruction pciSUBFW = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_SUBWF,
   "SUBWF",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   2,    // num ops
   0,0,  // dest, bit instruction
+  0,0,  // branch, skip
   (PCC_W | PCC_REGISTER),   // inCond
   (PCC_W | PCC_Z) // outCond
 };
 
 pCodeInstruction pciSUBLW = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_SUBLW,
   "SUBLW",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   1,    // num ops
   0,0,  // dest, bit instruction
+  0,0,  // branch, skip
   PCC_W,   // inCond
   (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
 };
 
 pCodeInstruction pciSWAPF = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_SWAPF,
   "SWAPF",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   2,    // num ops
   1,0,  // dest, bit instruction
+  0,0,  // branch, skip
   (PCC_REGISTER),   // inCond
   (PCC_REGISTER) // outCond
 };
 
 pCodeInstruction pciSWAPFW = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_SWAPFW,
   "SWAPF",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   2,    // num ops
   0,0,  // dest, bit instruction
+  0,0,  // branch, skip
   (PCC_REGISTER),   // inCond
   (PCC_W) // outCond
 };
+
 pCodeInstruction pciTRIS = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {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
   1,    // num ops
   0,0,  // dest, bit instruction
+  0,0,  // branch, skip
   PCC_NONE,   // inCond
-  PCC_NONE
+  PCC_REGISTER // outCond
 };
 
-
 pCodeInstruction pciXORWF = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_XORWF,
   "XORWF",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   2,    // num ops
   1,0,  // dest, bit instruction
+  0,0,  // branch, skip
   (PCC_W | PCC_REGISTER),   // inCond
   (PCC_REGISTER | PCC_Z) // outCond
 };
 
 pCodeInstruction pciXORFW = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_XORWF,
   "XORWF",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   2,    // num ops
   0,0,  // dest, bit instruction
+  0,0,  // branch, skip
   (PCC_W | PCC_REGISTER),   // inCond
   (PCC_W | PCC_Z) // outCond
 };
 
 pCodeInstruction pciXORLW = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
-   genericAnalyze,
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_XORLW,
   "XORLW",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
   NULL, // operand
+  NULL, // flow block
   1,    // num ops
   0,0,  // dest, bit instruction
+  0,0,  // branch, skip
   PCC_W,   // inCond
   (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
 };
@@ -740,6 +1008,13 @@ pCodeInstruction pciXORLW = {
 #define MAX_PIC14MNEMONICS 100
 pCodeInstruction *pic14Mnemonics[MAX_PIC14MNEMONICS];
 
+/* This definition needs to be part of configure.in */
+// #define USE_VSNPRINTF
+
+#ifdef USE_VSNPRINTF
+  // Alas, vsnprintf is not ANSI standard, and does not exist
+  // on Solaris (and probably other non-Gnu flavored Unixes).
+
 /*-----------------------------------------------------------------*/
 /* SAFE_snprintf - like snprintf except the string pointer is      */
 /*                 after the string has been printed to. This is   */
@@ -755,34 +1030,85 @@ void SAFE_snprintf(char **str, size_t *size, const  char  *format, ...)
     return;
 
   va_start(val, format);
-#if 0
-  // Alas, vsnprintf is not ANSI standard, and does not exist
-  // on Solaris (and probably other non-Gnu flavored Unixes).
+
   vsnprintf(*str, *size, format, val);
-#else
-  // This, of course, is *not* safe, despite the name.
-  vsprintf(*str, format, val);
-#endif
-    
+
   va_end (val);
 
   len = strlen(*str);
+  if(len > *size) {
+    fprintf(stderr,"WARNING, it looks like %s has overflowed\n",__FUNCTION__);
+  }
+
+  *str += len;
+  *size -= len;
+
+}
+
+#else  //  USE_VSNPRINTF
+
+// This version is *not* safe, despite the name.
+
+void SAFE_snprintf(char **str, size_t *size, const  char  *format, ...)
+{
+  va_list val;
+  int len;
+  static char buffer[1024]; /* grossly conservative, but still not inherently safe */
+
+  if(!str || !*str)
+    return;
+
+  va_start(val, format);
+
+  vsprintf(buffer, format, val);
+  va_end (val);
+
+  len = strlen(buffer);
+  if(len > *size) {
+    fprintf(stderr,"WARNING, it looks like %s has overflowed\n",__FUNCTION__);
+  }
+
+  strcpy(*str, buffer);
   *str += len;
   *size -= len;
 
 }
 
+#endif    //  USE_VSNPRINTF
+    
+
+extern  void initStack(int base_address, int size);
+extern regs *allocProcessorRegister(int rIdx, char * name, short po_type, int alias);
+extern regs *allocInternalRegister(int rIdx, char * name, short po_type, int alias);
+extern void init_pic(void);
+
 void  pCodeInitRegisters(void)
 {
 
-  pc_fsr.rIdx = IDX_FSR;
-  pc_fsr.r = pic14_regWithIdx(IDX_FSR);
+  initStack(0x38, 8);
+  init_pic();
 
+  pc_status.r = allocProcessorRegister(IDX_STATUS,"STATUS", PO_STATUS, 0x80);
+  pc_pcl.r = allocProcessorRegister(IDX_PCL,"PCL", PO_PCL, 0x80);
+  pc_pclath.r = allocProcessorRegister(IDX_PCLATH,"PCLATH", PO_PCLATH, 0x80);
+  pc_fsr.r = allocProcessorRegister(IDX_FSR,"FSR", PO_FSR, 0x80);
+  pc_indf.r = allocProcessorRegister(IDX_INDF,"INDF", PO_INDF, 0x80);
+  pc_intcon.r = allocProcessorRegister(IDX_INTCON,"INTCON", PO_INTCON, 0x80);
+
+  pc_status.rIdx = IDX_STATUS;
+  pc_fsr.rIdx = IDX_FSR;
   pc_indf.rIdx = IDX_INDF;
-  pc_indf.r = pic14_regWithIdx(IDX_INDF);
+  pc_intcon.rIdx = IDX_INTCON;
+  pc_pcl.rIdx = IDX_PCL;
+  pc_pclath.rIdx = IDX_PCLATH;
+
+  pc_kzero.r = allocInternalRegister(IDX_KZ,"KZ",PO_GPR_REGISTER,0);
+  pc_ssave.r = allocInternalRegister(IDX_SSAVE,"SSAVE", PO_GPR_REGISTER, 0x80);
+  pc_wsave.r = allocInternalRegister(IDX_WSAVE,"WSAVE", PO_GPR_REGISTER, 0);
 
   pc_kzero.rIdx = IDX_KZ;
-  pc_kzero.r = pic14_regWithIdx(IDX_KZ);
+  pc_wsave.rIdx = IDX_WSAVE;
+  pc_ssave.rIdx = IDX_SSAVE;
 
 }
 
@@ -850,7 +1176,8 @@ void pic14initMnemonics(void)
   pic14Mnemonics[POC_MOVFW] = &pciMOVFW;
   pic14Mnemonics[POC_MOVLW] = &pciMOVLW;
   pic14Mnemonics[POC_MOVWF] = &pciMOVWF;
-  pic14Mnemonics[POC_NEGF] = &pciNEGF;
+  pic14Mnemonics[POC_NOP] = &pciNOP;
+  pic14Mnemonics[POC_RETFIE] = &pciRETFIE;
   pic14Mnemonics[POC_RETLW] = &pciRETLW;
   pic14Mnemonics[POC_RETURN] = &pciRETURN;
   pic14Mnemonics[POC_RLF] = &pciRLF;
@@ -894,7 +1221,7 @@ int getpCode(char *mnem,unsigned dest)
   while(pci) {
 
     if(STRCASECMP(pci->mnemonic, mnem) == 0) {
-      if((pci->num_ops <= 1) || (pci->dest == dest))
+      if((pci->num_ops <= 1) || (pci->isModReg == dest))
        return(pci->op);
     }
 
@@ -915,6 +1242,17 @@ char getpBlock_dbName(pBlock *pb)
 
   return pb->dbName;
 }
+void pBlockConvert2ISR(pBlock *pb)
+{
+  if(!pb)
+    return;
+
+  if(pb->cmemmap)
+    pb->cmemmap = NULL;
+
+  pb->dbName = 'I';
+}
+
 /*-----------------------------------------------------------------*/
 /* movepBlock2Head - given the dbname of a pBlock, move all        */
 /*                   instances to the front of the doubly linked   */
@@ -1023,8 +1361,8 @@ static int RegCond(pCodeOp *pcop)
   if(!pcop)
     return 0;
 
-  if(pcop->type == PO_BIT  && !strcmp(pcop->name, pc_status.pcop.name)) {
-    switch(PCOB(pcop)->bit) {
+  if(pcop->type == PO_GPR_BIT  && !strcmp(pcop->name, pc_status.pcop.name)) {
+    switch(PCORB(pcop)->bit) {
     case PIC_C_BIT:
       return PCC_C;
     case PIC_DC_BIT:
@@ -1078,6 +1416,7 @@ pCode *newpCode (PIC_OPCODE op, pCodeOp *pcop)
     if(pci->outCond == PCC_EXAMINE_PCOP)
       pci->outCond   = RegCond(pcop);
 
+    pci->pc.prev = pci->pc.next = NULL;
     return (pCode *)pci;
   }
 
@@ -1111,14 +1450,14 @@ pCode *newpCodeWild(int pCodeID, pCodeOp *optional_operand, pCodeOp *optional_la
     
   pcw = Safe_calloc(1,sizeof(pCodeWild));
 
-  pcw->pc.type = PC_WILD;
-  pcw->pc.prev = pcw->pc.next = NULL;
-  pcw->pc.from = pcw->pc.to = pcw->pc.label = NULL;
-  pcw->pc.pb = NULL;
+  pcw->pci.pc.type = PC_WILD;
+  pcw->pci.pc.prev = pcw->pci.pc.next = NULL;
+  pcw->pci.from = pcw->pci.to = pcw->pci.label = NULL;
+  pcw->pci.pc.pb = NULL;
 
-  pcw->pc.analyze = genericAnalyze;
-  pcw->pc.destruct = genericDestruct;
-  pcw->pc.print = genericPrint;
+  //  pcw->pci.pc.analyze = genericAnalyze;
+  pcw->pci.pc.destruct = genericDestruct;
+  pcw->pci.pc.print = genericPrint;
 
   pcw->id = pCodeID;              // this is the 'n' in %n
   pcw->operand = optional_operand;
@@ -1141,10 +1480,10 @@ pCode *newpCodeCharP(char *cP)
 
   pcc->pc.type = PC_COMMENT;
   pcc->pc.prev = pcc->pc.next = NULL;
-  pcc->pc.from = pcc->pc.to = pcc->pc.label = NULL;
+  //pcc->pc.from = pcc->pc.to = pcc->pc.label = NULL;
   pcc->pc.pb = NULL;
 
-  pcc->pc.analyze = genericAnalyze;
+  //  pcc->pc.analyze = genericAnalyze;
   pcc->pc.destruct = genericDestruct;
   pcc->pc.print = genericPrint;
 
@@ -1158,7 +1497,7 @@ pCode *newpCodeCharP(char *cP)
 }
 
 /*-----------------------------------------------------------------*/
-/* newpCodeGLabel - create a new global label                      */
+/* newpCodeFunction -                                              */
 /*-----------------------------------------------------------------*/
 
 
@@ -1166,25 +1505,28 @@ pCode *newpCodeFunction(char *mod,char *f)
 {
   pCodeFunction *pcf;
 
-  _ALLOC(pcf,sizeof(pCodeFunction));
+  pcf = Safe_calloc(1,sizeof(pCodeFunction));
+  //_ALLOC(pcf,sizeof(pCodeFunction));
 
   pcf->pc.type = PC_FUNCTION;
   pcf->pc.prev = pcf->pc.next = NULL;
-  pcf->pc.from = pcf->pc.to = pcf->pc.label = NULL;
+  //pcf->pc.from = pcf->pc.to = pcf->pc.label = NULL;
   pcf->pc.pb = NULL;
 
-  pcf->pc.analyze = genericAnalyze;
+  //  pcf->pc.analyze = genericAnalyze;
   pcf->pc.destruct = genericDestruct;
   pcf->pc.print = pCodePrintFunction;
 
   if(mod) {
-    _ALLOC_ATOMIC(pcf->modname,strlen(mod)+1);
+    //_ALLOC_ATOMIC(pcf->modname,strlen(mod)+1);
+    pcf->modname = Safe_calloc(1,strlen(mod)+1);
     strcpy(pcf->modname,mod);
   } else
     pcf->modname = NULL;
 
   if(f) {
-    _ALLOC_ATOMIC(pcf->fname,strlen(f)+1);
+    //_ALLOC_ATOMIC(pcf->fname,strlen(f)+1);
+    pcf->fname = Safe_calloc(1,strlen(f)+1);
     strcpy(pcf->fname,f);
   } else
     pcf->fname = NULL;
@@ -1193,6 +1535,42 @@ pCode *newpCodeFunction(char *mod,char *f)
 
 }
 
+/*-----------------------------------------------------------------*/
+/* newpCodeFlow                                                    */
+/*-----------------------------------------------------------------*/
+
+
+pCode *newpCodeFlow(void )
+{
+  pCodeFlow *pcflow;
+
+  //_ALLOC(pcflow,sizeof(pCodeFlow));
+  pcflow = Safe_calloc(1,sizeof(pCodeFlow));
+
+  pcflow->pc.type = PC_FLOW;
+  pcflow->pc.prev = pcflow->pc.next = NULL;
+  //pcflow->pc.from = pcflow->pc.to = pcflow->pc.label = NULL;
+  pcflow->pc.pb = NULL;
+
+  //  pcflow->pc.analyze = genericAnalyze;
+  pcflow->pc.destruct = genericDestruct;
+  pcflow->pc.print = genericPrint;
+
+  pcflow->pc.seq = GpcFlowSeq++;
+
+  pcflow->nuses = 7;
+  pcflow->uses = Safe_calloc(pcflow->nuses, sizeof(set *));
+
+  pcflow->from = pcflow->to = NULL;
+
+  pcflow->inCond = PCC_NONE;
+  pcflow->outCond = PCC_NONE;
+
+  pcflow->end = NULL;
+  return ( (pCode *)pcflow);
+
+}
+
 /*-----------------------------------------------------------------*/
 /* pCodeLabelDestruct - free memory used by a label.               */
 /*-----------------------------------------------------------------*/
@@ -1209,7 +1587,7 @@ static void pCodeLabelDestruct(pCode *pc)
 
 }
 
-pCode *newpCodeLabel(int key)
+pCode *newpCodeLabel(char *name, int key)
 {
 
   char *s = buffer;
@@ -1219,10 +1597,10 @@ pCode *newpCodeLabel(int key)
 
   pcl->pc.type = PC_LABEL;
   pcl->pc.prev = pcl->pc.next = NULL;
-  pcl->pc.from = pcl->pc.to = pcl->pc.label = NULL;
+  //pcl->pc.from = pcl->pc.to = pcl->pc.label = NULL;
   pcl->pc.pb = NULL;
 
-  pcl->pc.analyze = genericAnalyze;
+  //  pcl->pc.analyze = genericAnalyze;
   pcl->pc.destruct = pCodeLabelDestruct;
   pcl->pc.print = pCodePrintLabel;
 
@@ -1231,25 +1609,17 @@ pCode *newpCodeLabel(int key)
   pcl->label = NULL;
   if(key>0) {
     sprintf(s,"_%05d_DS_",key);
-    if(s)
-      pcl->label = Safe_strdup(s);
-  }
+  } else
+    s = name;
+
+  if(s)
+    pcl->label = Safe_strdup(s);
 
 
   return ( (pCode *)pcl);
 
 }
-pCode *newpCodeLabelStr(char *str)
-{
-  pCode *pc = newpCodeLabel(-1);
-
-  if(str)
-    PCL(pc)->label = Safe_strdup(str);
-  else
-    PCL(pc)->label = NULL;
 
-  return pc;
-}
 
 /*-----------------------------------------------------------------*/
 /* newpBlock - create and return a pointer to a new pBlock         */
@@ -1263,7 +1633,7 @@ pBlock *newpBlock(void)
   PpB->next = PpB->prev = NULL;
 
   PpB->function_entries = PpB->function_exits = PpB->function_calls = NULL;
-  PpB->registers = NULL;
+  PpB->tregisters = NULL;
   PpB->visited = 0;
 
   return PpB;
@@ -1298,21 +1668,25 @@ pBlock *newpCodeChain(memmap *cm,char c, pCode *pc)
 /*   optimizations).                                               */
 /*-----------------------------------------------------------------*/
 
-pCodeOp *newpCodeOpLabel(int key)
+pCodeOp *newpCodeOpLabel(char *name, int key)
 {
-  char *s = buffer;
+  char *s=NULL;
+  static int label_key=-1;
+
   pCodeOp *pcop;
 
   pcop = Safe_calloc(1,sizeof(pCodeOpLabel) );
   pcop->type = PO_LABEL;
 
   pcop->name = NULL;
-  if(key>0) {
-    sprintf(s,"_%05d_DS_",key);
-    if(s)
-      pcop->name = Safe_strdup(s);
-  } 
 
+  if(key>0)
+    sprintf(s=buffer,"_%05d_DS_",key);
+  else 
+    s = name, key = label_key--;
+
+  if(s)
+    pcop->name = Safe_strdup(s);
 
   ((pCodeOpLabel *)pcop)->key = key;
 
@@ -1329,19 +1703,40 @@ pCodeOp *newpCodeOpLit(int lit)
 
   pcop = Safe_calloc(1,sizeof(pCodeOpLit) );
   pcop->type = PO_LITERAL;
+
   pcop->name = NULL;
   if(lit>=0) {
     sprintf(s,"0x%02x",lit);
     if(s)
       pcop->name = Safe_strdup(s);
-  } 
-
+  }
 
   ((pCodeOpLit *)pcop)->lit = lit;
 
   return pcop;
 }
 
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+pCodeOp *newpCodeOpImmd(char *name, int offset)
+{
+  pCodeOp *pcop;
+
+
+  pcop = Safe_calloc(1,sizeof(pCodeOpImmd) );
+  pcop->type = PO_IMMEDIATE;
+  if(name) {
+    pcop->name = Safe_strdup(name);
+  } else {
+    pcop->name = NULL;
+  }
+
+
+  PCOI(pcop)->offset = offset;
+
+  return pcop;
+}
+
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 pCodeOp *newpCodeOpWild(int id, pCodePeep *pcp, pCodeOp *subtype)
@@ -1374,15 +1769,15 @@ pCodeOp *newpCodeOpBit(char *s, int bit, int inBitSpace)
 {
   pCodeOp *pcop;
 
-  pcop = Safe_calloc(1,sizeof(pCodeOpBit) );
-  pcop->type = PO_BIT;
+  pcop = Safe_calloc(1,sizeof(pCodeOpRegBit) );
+  pcop->type = PO_GPR_BIT;
   if(s)
     pcop->name = Safe_strdup(s);   
   else
     pcop->name = NULL;
 
-  PCOB(pcop)->bit = bit;
-  PCOB(pcop)->inBitSpace = inBitSpace;
+  PCORB(pcop)->bit = bit;
+  PCORB(pcop)->inBitSpace = inBitSpace;
 
   return pcop;
 }
@@ -1393,12 +1788,25 @@ pCodeOp *newpCodeOpReg(int rIdx)
 
   pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
 
+  pcop->name = NULL;
   PCOR(pcop)->rIdx = rIdx;
   PCOR(pcop)->r = pic14_regWithIdx(rIdx);
   pcop->type = PCOR(pcop)->r->pc_type;
 
   return pcop;
 }
+pCodeOp *newpCodeOpRegFromStr(char *name)
+{
+  pCodeOp *pcop;
+
+  pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
+  PCOR(pcop)->r = allocRegByName(name);
+  PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
+  pcop->type = PCOR(pcop)->r->pc_type;
+  pcop->name = PCOR(pcop)->r->name;
+
+  return pcop;
+}
 
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
@@ -1409,6 +1817,7 @@ pCodeOp *newpCodeOp(char *name, PIC_OPTYPE type)
 
   switch(type) {
   case PO_BIT:
+  case PO_GPR_BIT:
     pcop = newpCodeOpBit(name, -1,0);
     break;
 
@@ -1417,7 +1826,7 @@ pCodeOp *newpCodeOp(char *name, PIC_OPTYPE type)
     break;
 
   case PO_LABEL:
-    pcop = newpCodeOpLabel(-1);
+    pcop = newpCodeOpLabel(NULL,-1);
     break;
 
   default:
@@ -1432,6 +1841,58 @@ pCodeOp *newpCodeOp(char *name, PIC_OPTYPE type)
   return pcop;
 }
 
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+void pCodeConstString(char *name, char *value)
+{
+  pBlock *pb;
+
+  //  fprintf(stderr, " %s  %s  %s\n",__FUNCTION__,name,value);
+
+  if(!name || !value)
+    return;
+
+  pb = newpCodeChain(NULL, 'P',newpCodeCharP("; Starting pCode block"));
+
+  addpBlock(pb);
+
+  sprintf(buffer,"; %s = %s",name,value);
+  
+  addpCode2pBlock(pb,newpCodeCharP(buffer));
+  addpCode2pBlock(pb,newpCodeLabel(name,-1));
+
+  do {
+    addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(*value)));
+  }while (*value++);
+
+
+}
+
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+void pCodeReadCodeTable(void)
+{
+  pBlock *pb;
+
+  fprintf(stderr, " %s\n",__FUNCTION__);
+
+  pb = newpCodeChain(NULL, 'P',newpCodeCharP("; Starting pCode block"));
+
+  addpBlock(pb);
+
+  addpCode2pBlock(pb,newpCodeCharP("; ReadCodeTable - built in function"));
+  addpCode2pBlock(pb,newpCodeCharP("; Inputs: temp1,temp2 = code pointer"));
+  addpCode2pBlock(pb,newpCodeCharP("; Outpus: W (from RETLW at temp2:temp1)"));
+  addpCode2pBlock(pb,newpCodeLabel("ReadCodeTable:",-1));
+
+  addpCode2pBlock(pb,newpCode(POC_MOVFW,newpCodeOpRegFromStr("temp2")));
+  addpCode2pBlock(pb,newpCode(POC_MOVWF,newpCodeOpRegFromStr("PCLATH")));
+  addpCode2pBlock(pb,newpCode(POC_MOVFW,newpCodeOpRegFromStr("temp1")));
+  addpCode2pBlock(pb,newpCode(POC_MOVWF,newpCodeOpRegFromStr("PCL")));
+
+
+}
+
 /*-----------------------------------------------------------------*/
 /* addpCode2pBlock - place the pCode into the pBlock linked list   */
 /*-----------------------------------------------------------------*/
@@ -1445,7 +1906,7 @@ void addpCode2pBlock(pBlock *pb, pCode *pc)
   } else {
     pb->pcTail->next = pc;
     pc->prev = pb->pcTail;
-    pc->next = NULL;
+    //pc->next = NULL;
     pc->pb = pb;
     pb->pcTail = pc;
   }
@@ -1456,10 +1917,12 @@ void addpCode2pBlock(pBlock *pb, pCode *pc)
 /*-----------------------------------------------------------------*/
 void addpBlock(pBlock *pb)
 {
+  // fprintf(stderr," Adding pBlock: dbName =%c\n",getpBlock_dbName(pb));
 
   if(!the_pFile) {
     /* First time called, we'll pass through here. */
-    _ALLOC(the_pFile,sizeof(pFile));
+    //_ALLOC(the_pFile,sizeof(pFile));
+    the_pFile = Safe_calloc(1,sizeof(pFile));
     the_pFile->pbHead = the_pFile->pbTail = pb;
     the_pFile->functions = NULL;
     return;
@@ -1519,7 +1982,6 @@ static void unlinkPC(pCode *pc)
 
 
   if(pc) {
-
     if(pc->prev) 
       pc->prev->next = pc->next;
     if(pc->next)
@@ -1546,9 +2008,9 @@ void pBlockRegs(FILE *of, pBlock *pb)
 
   regs  *r;
 
-  r = setFirstItem(pb->registers);
+  r = setFirstItem(pb->tregisters);
   while (r) {
-    r = setNextItem(pb->registers);
+    r = setNextItem(pb->tregisters);
   }
 }
 
@@ -1556,6 +2018,9 @@ void pBlockRegs(FILE *of, pBlock *pb)
 static char *get_op( pCodeInstruction *pcc)
 {
   regs *r;
+  static char buffer[50];
+  char *s;
+  int size;
 
   if(pcc && pcc->pcop) {
 
@@ -1564,16 +2029,31 @@ static char *get_op( pCodeInstruction *pcc)
     case PO_INDF:
     case PO_FSR:
       //fprintf(stderr,"get_op getting register name rIdx=%d\n",PCOR(pcc->pcop)->rIdx);
-      r = pic14_regWithIdx(PCOR(pcc->pcop)->rIdx);
-      return r->name;
+      //r = pic14_regWithIdx(PCOR(pcc->pcop)->rIdx);
+      //return r->name;
+      return PCOR(pcc->pcop)->r->name;
       break;
     case PO_GPR_TEMP:
-    case PO_GPR_BIT:
       r = pic14_regWithIdx(PCOR(pcc->pcop)->r->rIdx);
       //fprintf(stderr,"getop: getting %s\nfrom:\n",r->name); //pcc->pcop->name);
       pBlockRegs(stderr,pcc->pc.pb);
       return r->name;
 
+      //    case PO_GPR_BIT:
+      //      return PCOR(pcc->pcop)->r)->name;
+    case PO_IMMEDIATE:
+      s = buffer;
+      size = sizeof(buffer);
+      if( PCOI(pcc->pcop)->offset && PCOI(pcc->pcop)->offset<4) {
+       SAFE_snprintf(&s,&size,"((%s >> %d)&0xff)",
+                     pcc->pcop->name,
+                     8 * PCOI(pcc->pcop)->offset );
+      } else
+       SAFE_snprintf(&s,&size,"LOW(%s)",pcc->pcop->name);
+
+      
+      return buffer;
+
     default:
       if  (pcc->pcop->name)
        return pcc->pcop->name;
@@ -1604,15 +2084,15 @@ char *pCode2str(char *str, int size, pCode *pc)
 
     if( (PCI(pc)->num_ops >= 1) && (PCI(pc)->pcop)) {
 
-      if(PCI(pc)->bit_inst) {
-       if(PCI(pc)->pcop->type == PO_BIT) {
-         if( (((pCodeOpBit *)(PCI(pc)->pcop))->inBitSpace) )
+      if(PCI(pc)->isBitInst) {
+       if(PCI(pc)->pcop->type == PO_GPR_BIT) {
+         if( (((pCodeOpRegBit *)(PCI(pc)->pcop))->inBitSpace) )
            SAFE_snprintf(&s,&size,"(%s >> 3), (%s & 7)", 
                          PCI(pc)->pcop->name ,
                          PCI(pc)->pcop->name );
          else
            SAFE_snprintf(&s,&size,"%s,%d", get_op(PCI(pc)), 
-                         (((pCodeOpBit *)(PCI(pc)->pcop))->bit ));
+                         (((pCodeOpRegBit *)(PCI(pc)->pcop))->bit ));
        } else if(PCI(pc)->pcop->type == PO_GPR_BIT) {
          SAFE_snprintf(&s,&size,"%s,%d", get_op(PCI(pc)),PCORB(PCI(pc)->pcop)->bit);
        }else
@@ -1620,9 +2100,9 @@ char *pCode2str(char *str, int size, pCode *pc)
        //PCI(pc)->pcop->t.bit );
       } else {
 
-       if(PCI(pc)->pcop->type == PO_BIT) {
+       if(PCI(pc)->pcop->type == PO_GPR_BIT) {
          if( PCI(pc)->num_ops == 2)
-           SAFE_snprintf(&s,&size,"(%s >> 3),%c",get_op(PCI(pc)),((PCI(pc)->dest) ? 'F':'W'));
+           SAFE_snprintf(&s,&size,"(%s >> 3),%c",get_op(PCI(pc)),((PCI(pc)->isModReg) ? 'F':'W'));
          else
            SAFE_snprintf(&s,&size,"(1 << (%s & 7))",get_op(PCI(pc)));
 
@@ -1630,7 +2110,7 @@ char *pCode2str(char *str, int size, pCode *pc)
          SAFE_snprintf(&s,&size,"%s",get_op(PCI(pc)));
 
          if( PCI(pc)->num_ops == 2)
-           SAFE_snprintf(&s,&size,",%c", ( (PCI(pc)->dest) ? 'F':'W'));
+           SAFE_snprintf(&s,&size,",%c", ( (PCI(pc)->isModReg) ? 'F':'W'));
        }
       }
 
@@ -1651,7 +2131,9 @@ char *pCode2str(char *str, int size, pCode *pc)
   case PC_WILD:
     SAFE_snprintf(&s,&size,";\tWild opcode: id=%d\n",PCW(pc)->id);
     break;
-
+  case PC_FLOW:
+    SAFE_snprintf(&s,&size,";\t--FLOW change\n");
+    break;
   }
 
   return str;
@@ -1675,7 +2157,7 @@ static void genericPrint(FILE *of, pCode *pc)
   case PC_OPCODE:
     // If the opcode has a label, print that first
     {
-      pBranch *pbl = pc->label;
+      pBranch *pbl = PCI(pc)->label;
       while(pbl && pbl->pc) {
        if(pbl->pc->type == PC_LABEL)
          pCodePrintLabel(of, pbl->pc);
@@ -1690,8 +2172,13 @@ static void genericPrint(FILE *of, pCode *pc)
       pCode2str(str, 256, pc);
 
       fprintf(of,"%s",str);
-    }
 
+      /* Debug */
+      fprintf(of, "\t;key=%03x",pc->seq);
+      if(PCI(pc)->pcflow)
+       fprintf(of,",flow seq=%03x",PCI(pc)->pcflow->pc.seq);
+    }
+#if 0
     {
       pBranch *dpb = pc->to;   // debug
       while(dpb) {
@@ -1705,21 +2192,24 @@ static void genericPrint(FILE *of, pCode *pc)
        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;
       }
-      fprintf(of,"\n");
     }
-
+#endif
+    fprintf(of,"\n");
     break;
 
   case PC_WILD:
     fprintf(of,";\tWild opcode: id=%d\n",PCW(pc)->id);
-    if(pc->label)
-      pCodePrintLabel(of, pc->label->pc);
+    if(PCW(pc)->pci.label)
+      pCodePrintLabel(of, PCW(pc)->pci.label->pc);
 
     if(PCW(pc)->operand) {
       fprintf(of,";\toperand  ");
@@ -1727,6 +2217,10 @@ static void genericPrint(FILE *of, pCode *pc)
     }
     break;
 
+  case PC_FLOW:
+    fprintf(of,";Start of new flow, seq=%d\n",pc->seq);
+    break;
+
   case PC_LABEL:
   default:
     fprintf(of,"unknown pCode type %d\n",pc->type);
@@ -1748,7 +2242,7 @@ static void pCodePrintFunction(FILE *of, pCode *pc)
     fprintf(of,"F_%s",((pCodeFunction *)pc)->modname);
 
   if(PCF(pc)->fname) {
-    pBranch *exits = pc->to;
+    pBranch *exits = PCF(pc)->to;
     int i=0;
     fprintf(of,"%s\t;Function start\n",PCF(pc)->fname);
     while(exits) {
@@ -1759,10 +2253,10 @@ static void pCodePrintFunction(FILE *of, pCode *pc)
     fprintf(of,"; %d exit point%c\n",i, ((i==1) ? ' ':'s'));
     
   }else {
-    if(pc->from && 
-       pc->from->pc->type == PC_FUNCTION &&
-       PCF(pc->from->pc)->fname) 
-      fprintf(of,"; exit point of %s\n",PCF(pc->from->pc)->fname);
+    if((PCF(pc)->from && 
+       PCF(pc)->from->pc->type == PC_FUNCTION &&
+       PCF(PCF(pc)->from->pc)->fname) )
+      fprintf(of,"; exit point of %s\n",PCF(PCF(pc)->from->pc)->fname);
     else
       fprintf(of,"; exit point [can't find entry point]\n");
   }
@@ -1793,6 +2287,39 @@ static void unlinkpCodeFromBranch(pCode *pcl , pCode *pc)
 {
   pBranch *b, *bprev;
 
+
+  bprev = NULL;
+
+  if(pcl->type == PC_OPCODE)
+    b = PCI(pcl)->label;
+  else {
+    fprintf(stderr, "LINE %d. can't unlink from non opcode\n",__LINE__);
+    exit(1);
+
+  }
+
+  while(b) {
+    if(b->pc == pc) {
+
+      /* Found a label */
+      if(bprev) {
+       bprev->next = b->next;  /* Not first pCode in chain */
+       free(b);
+      } else {
+       pc->destruct(pc);
+       PCI(pcl)->label = b->next;   /* First pCode in chain */
+       free(b);
+      }
+      return;  /* A label can't occur more than once */
+    }
+    bprev = b;
+    b = b->next;
+  }
+
+#if 0
+
+  original stuff:
+
   bprev = NULL;
   b = pcl->label;
   while(b) {
@@ -1812,7 +2339,7 @@ static void unlinkpCodeFromBranch(pCode *pcl , pCode *pc)
     bprev = b;
     b = b->next;
   }
-
+#endif
 }
 
 /*-----------------------------------------------------------------*/
@@ -1837,22 +2364,24 @@ static pBranch * pBranchAppend(pBranch *h, pBranch *n)
 /* pBranchLink - given two pcodes, this function will link them    */
 /*               together through their pBranches                  */
 /*-----------------------------------------------------------------*/
-static void pBranchLink(pCode *f, pCode *t)
+static void pBranchLink(pCodeFunction *f, pCodeFunction *t)
 {
   pBranch *b;
 
   // Declare a new branch object for the 'from' pCode.
 
-  _ALLOC(b,sizeof(pBranch));
-  b->pc = t;                    // The link to the 'to' pCode.
+  //_ALLOC(b,sizeof(pBranch));
+  b = Safe_calloc(1,sizeof(pBranch));
+  b->pc = PCODE(t);             // The link to the 'to' pCode.
   b->next = NULL;
 
   f->to = pBranchAppend(f->to,b);
 
   // Now do the same for the 'to' pCode.
 
-  _ALLOC(b,sizeof(pBranch));
-  b->pc = f;
+  //_ALLOC(b,sizeof(pBranch));
+  b = Safe_calloc(1,sizeof(pBranch));
+  b->pc = PCODE(f);
   b->next = NULL;
 
   t->from = pBranchAppend(t->from,b);
@@ -1923,6 +2452,7 @@ static void pCodeUnlink(pCode *pc)
 #endif
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
+#if 0
 static void genericAnalyze(pCode *pc)
 {
   switch(pc->type) {
@@ -1950,8 +2480,14 @@ static void genericAnalyze(pCode *pc)
       /* reached the end of the pcode chain without finding
        * an instruction we could link to. */
     }
+    break;
+  case PC_FLOW:
+    fprintf(stderr,"analyze PC_FLOW\n");
+
+    return;
   }
 }
+#endif
 
 /*-----------------------------------------------------------------*/
 int compareLabel(pCode *pc, pCodeOpLabel *pcop_label)
@@ -1963,7 +2499,7 @@ int compareLabel(pCode *pc, pCodeOpLabel *pcop_label)
       return TRUE;
   }
   if(pc->type == PC_OPCODE) {
-    pbr = pc->label;
+    pbr = PCI(pc)->label;
     while(pbr) {
       if(pbr->pc->type == PC_LABEL) {
        if( ((pCodeLabel *)(pbr->pc))->key ==  pcop_label->key)
@@ -1998,6 +2534,39 @@ pCode * findLabel(pCodeOpLabel *pcop_label)
   return NULL;
 }
 
+/*-----------------------------------------------------------------*/
+/* findNextpCode - given a pCode, find the next of type 'pct'      */
+/*                 in the linked list                              */
+/*-----------------------------------------------------------------*/
+pCode * findNextpCode(pCode *pc, PC_TYPE pct)
+{
+
+  while(pc) {
+    if(pc->type == pct)
+      return pc;
+
+    pc = pc->next;
+  }
+
+  return NULL;
+}
+
+/*-----------------------------------------------------------------*/
+/* findPrevpCode - given a pCode, find the previous of type 'pct'  */
+/*                 in the linked list                              */
+/*-----------------------------------------------------------------*/
+pCode * findPrevpCode(pCode *pc, PC_TYPE pct)
+{
+
+  while(pc) {
+    if(pc->type == pct)
+      return pc;
+
+    pc = pc->prev;
+  }
+
+  return NULL;
+}
 /*-----------------------------------------------------------------*/
 /* findNextInstruction - given a pCode, find the next instruction  */
 /*                       in the linked list                        */
@@ -2012,7 +2581,7 @@ pCode * findNextInstruction(pCode *pc)
     pc = pc->next;
   }
 
-  fprintf(stderr,"Couldn't find instruction\n");
+  //fprintf(stderr,"Couldn't find instruction\n");
   return NULL;
 }
 
@@ -2047,6 +2616,7 @@ static void AnalyzeLabel(pCode *pc)
 }
 #endif
 
+#if 0
 static void AnalyzeGOTO(pCode *pc)
 {
 
@@ -2069,21 +2639,68 @@ static void AnalyzeRETURN(pCode *pc)
 
 }
 
+#endif
+
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
-
-void AnalyzepBlock(pBlock *pb)
+regs * getRegFromInstruction(pCode *pc)
 {
-  pCode *pc;
+  if(!pc                   || 
+     !isPCI(pc)            ||
+     !PCI(pc)->pcop        ||
+     PCI(pc)->num_ops == 0 )
+    return NULL;
 
-  if(!pb)
-    return;
+  switch(PCI(pc)->pcop->type) {
+  case PO_INDF:
+  case PO_FSR:
+    return pic14_regWithIdx(PCOR(PCI(pc)->pcop)->rIdx);
 
-  /* Find all of the registers used in this pBlock 
-   * by looking at each instruction and examining it's
-   * operands
-   */
-  for(pc = pb->pcHead; pc; pc = pc->next) {
+  case PO_BIT:
+  case PO_GPR_TEMP:
+    fprintf(stderr, "getRegFromInstruction - bit or temp\n");
+    return PCOR(PCI(pc)->pcop)->r;
+
+  case PO_IMMEDIATE:
+    fprintf(stderr, "getRegFromInstruction - immediate\n");
+    return NULL; // PCOR(PCI(pc)->pcop)->r;
+
+  case PO_GPR_BIT:
+    return PCOR(PCI(pc)->pcop)->r;
+
+  case PO_DIR:
+    fprintf(stderr, "getRegFromInstruction - dir\n");
+    //return NULL; PCOR(PCI(pc)->pcop)->r;
+    return PCOR(PCI(pc)->pcop)->r;
+  case PO_LITERAL:
+    fprintf(stderr, "getRegFromInstruction - literal\n");
+    break;
+
+  default:
+    fprintf(stderr, "getRegFromInstruction - unknown reg type %d\n",PCI(pc)->pcop->type);
+    genericPrint(stderr, pc);
+    break;
+  }
+
+  return NULL;
+
+}
+
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+
+void AnalyzepBlock(pBlock *pb)
+{
+  pCode *pc;
+
+  if(!pb)
+    return;
+
+  /* Find all of the registers used in this pBlock 
+   * by looking at each instruction and examining it's
+   * operands
+   */
+  for(pc = pb->pcHead; pc; pc = pc->next) {
 
     /* Is this an instruction with operands? */
     if(pc->type == PC_OPCODE && PCI(pc)->pcop) {
@@ -2093,21 +2710,21 @@ void AnalyzepBlock(pBlock *pb)
        /* Loop through all of the registers declared so far in
           this block and see if we find this one there */
 
-       regs *r = setFirstItem(pb->registers);
+       regs *r = setFirstItem(pb->tregisters);
 
        while(r) {
          if(r->rIdx == PCOR(PCI(pc)->pcop)->r->rIdx) {
            PCOR(PCI(pc)->pcop)->r = r;
            break;
          }
-         r = setNextItem(pb->registers);
+         r = setNextItem(pb->tregisters);
        }
 
        if(!r) {
          /* register wasn't found */
          r = Safe_calloc(1, sizeof(regs));
          memcpy(r,PCOR(PCI(pc)->pcop)->r, sizeof(regs));
-         addSet(&pb->registers, r);
+         addSet(&pb->tregisters, r);
          PCOR(PCI(pc)->pcop)->r = r;
          //fprintf(stderr,"added register to pblock: reg %d\n",r->rIdx);
        }/* else 
@@ -2131,6 +2748,258 @@ void AnalyzepBlock(pBlock *pb)
   }
 }
 
+/*-----------------------------------------------------------------*/
+/* */
+/*-----------------------------------------------------------------*/
+#define PCI_HAS_LABEL(x) ((x) && (PCI(x)->label != NULL))
+
+void InsertpFlow(pCode *pc, pCode **pflow)
+{
+  PCFL(*pflow)->end = pc;
+
+  if(!pc || !pc->next)
+    return;
+
+  *pflow = newpCodeFlow();
+  pCodeInsertAfter(pc, *pflow);
+}
+
+/*-----------------------------------------------------------------*/
+/* BuildFlow(pBlock *pb) - examine the code in a pBlock and build  */
+/*                         the flow blocks.                        */
+/*
+ * BuildFlow inserts pCodeFlow objects into the pCode chain at each
+ * point the instruction flow changes. 
+ */
+/*-----------------------------------------------------------------*/
+void BuildFlow(pBlock *pb)
+{
+  pCode *pc;
+  pCode *last_pci=NULL;
+  pCode *pflow;
+  int seq = 0;
+
+  if(!pb)
+    return;
+
+  //fprintf (stderr,"build flow start seq %d  ",GpcFlowSeq);
+  /* Insert a pCodeFlow object at the beginning of a pBlock */
+
+  pflow = newpCodeFlow();    /* Create a new Flow object */
+  pflow->next = pb->pcHead;  /* Make the current head the next object */
+  pb->pcHead->prev = pflow;  /* let the current head point back to the flow object */
+  pb->pcHead = pflow;        /* Make the Flow object the head */
+  pflow->pb = pb;
+
+  for( pc = findNextInstruction(pb->pcHead); 
+      (pc=findNextInstruction(pc)) != NULL; ) { 
+
+    pc->seq = seq++;
+    PCI(pc)->pcflow = PCFL(pflow);
+
+    if(PCI(pc)->isSkip || PCI(pc)->isBranch)  {
+
+      /* The instruction immediately following this one 
+       * marks the beginning of a new flow segment */
+
+      InsertpFlow(pc, &pflow);
+      seq = 0;
+         
+    } else if (PCI_HAS_LABEL(pc)) {
+
+      /* This instruction marks the beginning of a
+       * new flow segment */
+
+      pc->seq = 0;
+      seq = 1; 
+      InsertpFlow(pc->prev, &pflow);
+
+      PCI(pc)->pcflow = PCFL(pflow);
+      
+    }
+    last_pci = pc;
+    pc = pc->next;
+  }
+
+  //fprintf (stderr,",end seq %d",GpcFlowSeq);
+  PCFL(pflow)->end = pb->pcTail;
+}
+
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+void dumpCond(int cond)
+{
+
+  static char *pcc_str[] = {
+    //"PCC_NONE",
+    "PCC_REGISTER",
+    "PCC_C",
+    "PCC_Z",
+    "PCC_DC",
+    "PCC_W",
+    "PCC_EXAMINE_PCOP",
+    "PCC_REG_BANK0",
+    "PCC_REG_BANK1",
+    "PCC_REG_BANK2",
+    "PCC_REG_BANK3"
+  };
+
+  int ncond = sizeof(pcc_str) / sizeof(char *);
+  int i,j;
+
+  fprintf(stderr, "0x%04X\n",cond);
+
+  for(i=0,j=1; i<ncond; i++, j<<=1)
+    if(cond & j)
+      fprintf(stderr, "  %s\n",pcc_str[i]);
+
+}
+
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+void FillFlow(pCodeFlow *pcflow)
+{
+
+  pCode *pc;
+  int cur_bank;
+
+  if(!isPCFL(pcflow))
+    return;
+
+  //  fprintf(stderr, " FillFlow - flow block (seq=%d)\n", pcflow->pc.seq);
+
+  pc = findNextpCode(PCODE(pcflow), PC_OPCODE); 
+  if(!pc) {
+    //    fprintf(stderr, " FillFlow - empty flow (seq=%d)\n", pcflow->pc.seq);
+    return;
+  }
+
+  cur_bank = -1;
+
+  do {
+    //regs *reg;
+
+    int inCond = PCI(pc)->inCond;
+    int outCond = PCI(pc)->outCond;
+#if 0
+    if( (reg = getRegFromInstruction(pc)) != NULL) {
+      if(isSTATUS_REG(reg)) {
+
+       //fprintf(stderr, "  FillFlow - Status register\n");
+
+       /* Check to see if the register banks are changing */
+       if(PCI(pc)->isModReg) {
+
+         pCodeOp *pcop = PCI(pc)->pcop;
+         switch(PCI(pc)->op) {
+           case POC_BSF:
+             if(PCORB(pcop)->bit == PIC_RP0_BIT)
+               fprintf(stderr, "  FillFlow - Set RP0\n");
+             //outCond |= PCC_REG_BANK1;
+             if(PCORB(pcop)->bit == PIC_RP1_BIT) 
+               fprintf(stderr, "  FillFlow - Set RP1\n");
+             //outCond |= PCC_REG_BANK3;
+             break;
+
+           case POC_BCF:
+             if(PCORB(pcop)->bit == PIC_RP0_BIT)
+               fprintf(stderr, "  FillFlow - Clr RP0\n");
+             //outCond |= PCC_REG_BANK1;
+             if(PCORB(pcop)->bit == PIC_RP1_BIT) 
+               fprintf(stderr, "  FillFlow - Clr RP1\n");
+             //outCond |= PCC_REG_BANK3;
+             break;
+
+         default:
+           fprintf(stderr, "  FillFlow - Status register is getting Modified by:\n");
+           genericPrint(stderr, pc);
+         }
+       }
+
+      } else
+       inCond |= PCC_REG_BANK0 << (REG_BANK(reg) & 3);
+    }
+#endif
+
+    pcflow->inCond |= (inCond &  ~pcflow->outCond);
+    pcflow->outCond |= outCond;
+
+    
+
+
+    pc = findNextpCode(pc->next, PC_OPCODE);
+  } while (pc && (pc != pcflow->end));
+
+#if 0
+  if(!pc)
+    fprintf(stderr, "  FillFlow - Bad end of flow\n");
+
+
+  fprintf(stderr, "  FillFlow inCond: ");
+  dumpCond(pcflow->inCond);
+  fprintf(stderr, "  FillFlow outCond: ");
+  dumpCond(pcflow->outCond);
+#endif
+}
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+void LinkFlow_pCode(pCodeInstruction *from, pCodeInstruction *to)
+{
+
+  if(!from || !to || !to->pcflow || !from->pcflow)
+    return;
+
+  addSet(&(from->pcflow->to), to->pcflow);
+  addSet(&(to->pcflow->from), from->pcflow);
+
+}
+
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+void LinkFlow(pBlock *pb)
+{
+  pCode *pc=NULL;
+  pCode *pcflow;
+  pCode *pct;
+
+  
+  for( pcflow = findNextpCode(pb->pcHead, PC_FLOW); 
+      (pcflow = findNextpCode(pcflow, PC_FLOW)) != NULL;
+      pcflow = pcflow->next) {
+
+    if(!isPCFL(pcflow))
+      fprintf(stderr, "LinkFlow - pcflow is not a flow object ");
+
+    //FillFlow(PCFL(pcflow));
+
+    pc = PCFL(pcflow)->end;
+
+    //fprintf(stderr, "LinkFlow - flow block (seq=%d) ", pcflow->seq);
+    if(isPCI_SKIP(pc)) {
+      //fprintf(stderr, "ends with skip\n");
+      pct=findNextInstruction(pc->next);
+      LinkFlow_pCode(PCI(pc),PCI(pct));
+      pct=findNextInstruction(pct->next);
+      LinkFlow_pCode(PCI(pc),PCI(pct));
+      continue;
+    }
+
+    if(isPCI_BRANCH(pc)) {
+      //fprintf(stderr, "ends with branch\n");
+
+      continue;
+    }
+#if 0
+    if(pc) {
+      fprintf(stderr, "has an unrecognized ending:\n");
+      pc->print(stderr,pc);
+    }
+    else 
+      fprintf(stderr, "has no end pcode\n");
+#endif 
+    
+  }
+}
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 int OptimizepBlock(pBlock *pb)
@@ -2185,8 +3054,8 @@ void pBlockRemoveUnusedLabels(pBlock *pb)
 
     if(pc->type == PC_LABEL)
       pcl = PCL(pc);
-    else if (pc->label)
-      pcl = PCL(pc->label->pc);
+    else if ((pc->type == PC_OPCODE) && PCI(pc)->label)
+      pcl = PCL(PCI(pc)->label->pc);
     else continue;
 
       /* This pCode is a label, so search the pBlock to see if anyone
@@ -2251,11 +3120,12 @@ void pBlockMergeLabels(pBlock *pb)
       // the labels are placed into the singly-linked list "label" as 
       // opposed to being a single member of the pCodeInstruction.)
 
-      _ALLOC(pbr,sizeof(pBranch));
+      //_ALLOC(pbr,sizeof(pBranch));
+      pbr = Safe_calloc(1,sizeof(pBranch));
       pbr->pc = pc;
       pbr->next = NULL;
 
-      pcnext->label = pBranchAppend(pcnext->label,pbr);
+      PCI(pcnext)->label = pBranchAppend(PCI(pcnext)->label,pbr);
       if(pcnext->prev) 
        pc = pcnext->prev;
       else
@@ -2293,48 +3163,246 @@ void OptimizepCode(char dbName)
 }
 
 /*-----------------------------------------------------------------*/
-/* AnalyzepCode - parse the pCode that has been generated and form */
-/*                all of the logical connections.                  */
-/*                                                                 */
-/* Essentially what's done here is that the pCode flow is          */
-/* determined.                                                     */
+/* popCopy - copy a pcode operator                                 */
 /*-----------------------------------------------------------------*/
+pCodeOp *popCopyGPR2Bit(pCodeOp *pc, int bitval)
+{
+  pCodeOp *pcop;
 
-void AnalyzepCode(char dbName)
+  pcop = newpCodeOpBit(pc->name, bitval, 0);
+
+  if( !( (pcop->type == PO_LABEL) ||
+        (pcop->type == PO_LITERAL) ||
+        (pcop->type == PO_STR) ))
+    PCOR(pcop)->r = PCOR(pc)->r;  /* This is dangerous... */
+
+  return pcop;
+}
+
+
+
+#if 0
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+int InstructionRegBank(pCode *pc)
 {
-  pBlock *pb;
-  pCode *pc;
-  pBranch *pbr;
+  regs *reg;
 
-  int i,changes;
+  if( (reg = getRegFromInstruction(pc)) == NULL)
+    return -1;
 
-  if(!the_pFile)
+  return REG_BANK(reg);
+
+}
+#endif
+
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+void FixRegisterBanking(pBlock *pb)
+{
+  pCode *pc=NULL;
+  pCode *pcprev=NULL;
+  pCode *new_pc;
+
+  int cur_bank;
+  regs *reg;
+  return;
+  if(!pb)
     return;
 
+  pc = findNextpCode(pb->pcHead, PC_FLOW);
+  if(!pc)
+    return;
+  /* loop through all of the flow blocks with in one pblock */
 
-  i = 0;
+  //  fprintf(stderr,"Register banking\n");
+  cur_bank = 0;
   do {
+    /* at this point, pc should point to a PC_FLOW object */
 
-    DFPRINTF((stderr," Analyzing pCode: PASS #%d\n",i+1));
 
-    /* First, merge the labels with the instructions */
-    for(pb = the_pFile->pbHead; pb; pb = pb->next) {
-      if('*' == dbName || getpBlock_dbName(pb) == dbName) {
+    /* for each flow block, determine the register banking 
+       requirements */
 
-       DFPRINTF((stderr," analyze and merging block %c\n",dbName));
-       pBlockMergeLabels(pb);
-       AnalyzepBlock(pb);
+    do {
+      if(isPCI(pc)) {
+    genericPrint(stderr, pc);
+
+       reg = getRegFromInstruction(pc);
+       //#if 0
+       if(reg) {
+         fprintf(stderr, "  %s  ",reg->name);
+         fprintf(stderr, "addr = 0x%03x, bank = %d\n",reg->address,REG_BANK(reg));
+
+       }
+       //#endif
+       if(reg && REG_BANK(reg)!=cur_bank) {
+         /* Examine the instruction before this one to make sure it is
+          * not a skip type instruction */
+         pcprev = findPrevpCode(pc->prev, PC_OPCODE);
+         if(pcprev && !isPCI_SKIP(pcprev)) {
+           int b = cur_bank ^ REG_BANK(reg);
+
+           //fprintf(stderr, "Cool! can switch banks\n");
+           cur_bank = REG_BANK(reg);
+           if(b & 1) {
+             new_pc = newpCode(((cur_bank&1) ? POC_BSF : POC_BCF),
+                               popCopyGPR2Bit(PCOP(&pc_status),PIC_RP0_BIT));
+             pCodeInsertAfter(pc->prev, new_pc);
+             if(PCI(pc)->label) { 
+               PCI(new_pc)->label = PCI(pc)->label;
+               PCI(pc)->label = NULL;
+             }
+             /*
+               new_pc = newpCode(((cur_bank&1) ? POC_BCF : POC_BSF),
+               popCopyGPR2Bit(PCOP(&pc_status),PIC_RP0_BIT));
+               pCodeInsertAfter(pc, new_pc);
+             */
+
+           }
+
+         } else
+           fprintf(stderr, "Bummer can't switch banks\n");
+       }
       }
+
+      pcprev = pc;
+      pc = pc->next;
+    } while(pc && !(isPCFL(pc))); 
+
+    if(pcprev && cur_bank) {
+      /* Brute force - make sure that we point to bank 0 at the
+       * end of each flow block */
+      new_pc = newpCode(POC_BCF,
+                       popCopyGPR2Bit(PCOP(&pc_status),PIC_RP0_BIT));
+      pCodeInsertAfter(pcprev, new_pc);
+      cur_bank = 0;
     }
 
-    changes = 0;
+  }while (pc);
 
-    for(pb = the_pFile->pbHead; pb; pb = pb->next) {
-      if('*' == dbName || getpBlock_dbName(pb) == dbName)
-       changes += OptimizepBlock(pb);
+}
+
+void pBlockDestruct(pBlock *pb)
+{
+
+  if(!pb)
+    return;
+
+
+  free(pb);
+
+}
+
+/*-----------------------------------------------------------------*/
+/* void mergepBlocks(char dbName) - Search for all pBlocks with the*/
+/*                                  name dbName and combine them   */
+/*                                  into one block                 */
+/*-----------------------------------------------------------------*/
+void mergepBlocks(char dbName)
+{
+
+  pBlock *pb, *pbmerged = NULL,*pbn;
+
+  pb = the_pFile->pbHead;
+
+  //fprintf(stderr," merging blocks named %c\n",dbName);
+  while(pb) {
+
+    pbn = pb->next;
+    //fprintf(stderr,"looking at %c\n",getpBlock_dbName(pb));
+    if( getpBlock_dbName(pb) == dbName) {
+
+      //fprintf(stderr," merged block %c\n",dbName);
+
+      if(!pbmerged) {
+       pbmerged = pb;
+      } else {
+       addpCode2pBlock(pbmerged, pb->pcHead);
+       /* addpCode2pBlock doesn't handle the tail: */
+       pbmerged->pcTail = pb->pcTail;
+
+       pb->prev->next = pbn;
+       if(pbn) 
+         pbn->prev = pb->prev;
+
+
+       pBlockDestruct(pb);
+      }
+      //printpBlock(stderr, pbmerged);
+    } 
+    pb = pbn;
+  }
+
+}
+
+/*-----------------------------------------------------------------*/
+/* AnalyzeBanking - Called after the memory addresses have been    */
+/*                  assigned to the registers.                     */
+/*                                                                 */
+/*-----------------------------------------------------------------*/
+void AnalyzeBanking(void)
+{
+
+  pBlock *pb;
+
+  if(!the_pFile)
+    return;
+
+
+  /* Phase 2 - Flow Analysis
+   *
+   * In this phase, the pCode is partition into pCodeFlow 
+   * blocks. The flow blocks mark the points where a continuous
+   * stream of instructions changes flow (e.g. because of
+   * a call or goto or whatever).
+   */
+
+  for(pb = the_pFile->pbHead; pb; pb = pb->next)
+    BuildFlow(pb);
+
+  /* Phase 2 - Flow Analysis - linking flow blocks
+   *
+   * In this phase, the individual flow blocks are examined
+   * 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)
+    FixRegisterBanking(pb);
+
+  /* debug stuff */ 
+  for(pb = the_pFile->pbHead; pb; pb = pb->next) {
+    pCode *pcflow;
+    for( pcflow = findNextpCode(pb->pcHead, PC_FLOW); 
+        (pcflow = findNextpCode(pcflow, PC_FLOW)) != NULL;
+        pcflow = pcflow->next) {
+
+      FillFlow(PCFL(pcflow));
     }
-      
-  } while(changes && (i++ < MAX_PASSES));
+  }
+
+
+}
+
+/*-----------------------------------------------------------------*/
+/* buildCallTree - look at the flow and extract all of the calls   */
+/*                                                                 */
+/*-----------------------------------------------------------------*/
+set *register_usage(pBlock *pb);
+
+void buildCallTree(void    )
+{
+  pBranch *pbr;
+  pBlock  *pb;
+  pCode   *pc;
+
+  if(!the_pFile)
+    return;
+
+
 
   /* Now build the call tree.
      First we examine all of the pCodes for functions.
@@ -2363,36 +3431,109 @@ void AnalyzepCode(char dbName)
 
    */
   for(pb = the_pFile->pbHead; pb; pb = pb->next) {
-    if('*' == dbName || getpBlock_dbName(pb) == dbName) {
-      pCode *pc_fstart=NULL;
-      for(pc = pb->pcHead; pc; pc = pc->next) {
-       if(pc->type == PC_FUNCTION) {
-         if (PCF(pc)->fname) {
-           // I'm not liking this....
-           // Found the beginning of a function.
-           _ALLOC(pbr,sizeof(pBranch));
-           pbr->pc = pc_fstart = pc;
-           pbr->next = NULL;
-
-           the_pFile->functions = pBranchAppend(the_pFile->functions,pbr);
-
-           // Here's a better way of doing the same:
-           addSet(&pb->function_entries, pc);
-
-         } else {
-           // Found an exit point in a function, e.g. return
-           // (Note, there may be more than one return per function)
-           if(pc_fstart)
-             pBranchLink(pc_fstart, pc);
-
-           addSet(&pb->function_exits, pc);
+    pCode *pc_fstart=NULL;
+    for(pc = pb->pcHead; pc; pc = pc->next) {
+      if(isPCF(pc)) {  //pc->type == PC_FUNCTION) {
+       if (PCF(pc)->fname) {
+
+         if(STRCASECMP(PCF(pc)->fname, "_main") == 0) {
+           fprintf(stderr," found main \n");
+           pb->cmemmap = NULL;  /* FIXME do we need to free ? */
+           pb->dbName = 'M';
          }
-       } else  if(pc->type == PC_OPCODE && PCI(pc)->op == POC_CALL) {
-         addSet(&pb->function_calls,pc);
+
+         //_ALLOC(pbr,sizeof(pBranch));
+         pbr = Safe_calloc(1,sizeof(pBranch));
+         pbr->pc = pc_fstart = pc;
+         pbr->next = NULL;
+
+         the_pFile->functions = pBranchAppend(the_pFile->functions,pbr);
+
+         // Here's a better way of doing the same:
+         addSet(&pb->function_entries, pc);
+
+       } else {
+         // Found an exit point in a function, e.g. return
+         // (Note, there may be more than one return per function)
+         if(pc_fstart)
+           pBranchLink(PCF(pc_fstart), PCF(pc));
+
+         addSet(&pb->function_exits, pc);
        }
+      } else if(isCALL(pc)) {// if(pc->type == PC_OPCODE && PCI(pc)->op == POC_CALL) {
+       addSet(&pb->function_calls,pc);
       }
     }
   }
+
+  /* Re-allocate the registers so that there are no collisions
+   * between local variables when one function call another */
+
+  pic14_deallocateAllRegs();
+
+  for(pb = the_pFile->pbHead; pb; pb = pb->next) {
+    if(!pb->visited)
+      register_usage(pb);
+  }
+
+}
+
+/*-----------------------------------------------------------------*/
+/* AnalyzepCode - parse the pCode that has been generated and form */
+/*                all of the logical connections.                  */
+/*                                                                 */
+/* Essentially what's done here is that the pCode flow is          */
+/* determined.                                                     */
+/*-----------------------------------------------------------------*/
+
+void AnalyzepCode(char dbName)
+{
+  pBlock *pb;
+  int i,changes;
+
+  if(!the_pFile)
+    return;
+
+  mergepBlocks('D');
+
+
+  /* Phase 1 - Register allocation and peep hole optimization
+   *
+   * The first part of the analysis is to determine the registers
+   * that are used in the pCode. Once that is done, the peep rules
+   * are applied to the code. We continue to loop until no more
+   * peep rule optimizations are found (or until we exceed the
+   * MAX_PASSES threshold). 
+   *
+   * When done, the required registers will be determined.
+   *
+   */
+  i = 0;
+  do {
+
+    DFPRINTF((stderr," Analyzing pCode: PASS #%d\n",i+1));
+
+    /* First, merge the labels with the instructions */
+    for(pb = the_pFile->pbHead; pb; pb = pb->next) {
+      if('*' == dbName || getpBlock_dbName(pb) == dbName) {
+
+       DFPRINTF((stderr," analyze and merging block %c\n",dbName));
+       //fprintf(stderr," analyze and merging block %c\n",getpBlock_dbName(pb));
+       pBlockMergeLabels(pb);
+       AnalyzepBlock(pb);
+      }
+    }
+
+    changes = 0;
+
+    for(pb = the_pFile->pbHead; pb; pb = pb->next) {
+      if('*' == dbName || getpBlock_dbName(pb) == dbName)
+       changes += OptimizepBlock(pb);
+    }
+      
+  } while(changes && (i++ < MAX_PASSES));
+
+  buildCallTree();
 }
 
 /*-----------------------------------------------------------------*/
@@ -2457,7 +3598,7 @@ void pBlockStats(FILE *of, pBlock *pb)
   pCode *pc;
   regs  *r;
 
-  fprintf(of,";***\n;  pBlock Stats\n;***\n");
+  fprintf(of,";***\n;  pBlock Stats: dbName = %c\n;***\n",getpBlock_dbName(pb));
 
   // for now just print the first element of each set
   pc = setFirstItem(pb->function_entries);
@@ -2483,22 +3624,22 @@ void pBlockStats(FILE *of, pBlock *pb)
     }
   }
 
-  r = setFirstItem(pb->registers);
+  r = setFirstItem(pb->tregisters);
   if(r) {
-    int n = elementsInSet(pb->registers);
+    int n = elementsInSet(pb->tregisters);
 
     fprintf(of,";%d compiler assigned register%c:\n",n, ( (n!=1) ? 's' : ' '));
 
     while (r) {
       fprintf(of,";   %s\n",r->name);
-      r = setNextItem(pb->registers);
+      r = setNextItem(pb->tregisters);
     }
   }
 }
 
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
-void sequencepCode(void)
+static void sequencepCode(void)
 {
   pBlock *pb;
   pCode *pc;
@@ -2554,7 +3695,7 @@ set *register_usage(pBlock *pb)
 
   // Mark the registers in this block as used.
 
-  MarkUsedRegisters(pb->registers);
+  MarkUsedRegisters(pb->tregisters);
   if(registersInCallPath) {
     /* registers were used in the functions this pBlock has called */
     /* so now, we need to see if these collide with the ones we are */
@@ -2567,7 +3708,7 @@ set *register_usage(pBlock *pb)
     r1 = setFirstItem(registersInCallPath);
     while(r1) {
 
-      r2 = setFirstItem(pb->registers);
+      r2 = setFirstItem(pb->tregisters);
 
       while(r2 && (r1->type != REG_STK)) {
 
@@ -2591,7 +3732,7 @@ set *register_usage(pBlock *pb)
          newreg->isFree = 0;
          newreg->wasUsed = 1;
        }
-       r2 = setNextItem(pb->registers);
+       r2 = setNextItem(pb->tregisters);
       }
 
       r1 = setNextItem(registersInCallPath);
@@ -2610,7 +3751,7 @@ set *register_usage(pBlock *pb)
   }// else
   //    MarkUsedRegisters(pb->registers);
 
-  registers = unionSets(pb->registers, registersInCallPath, THROW_NONE);
+  registers = unionSets(pb->tregisters, registersInCallPath, THROW_NONE);
 #ifdef PCODE_DEBUG
   if(registers) 
     DFPRINTF((stderr,"returning regs\n"));
@@ -2792,13 +3933,14 @@ void printCallTree(FILE *of)
 
   /* Re-allocate the registers so that there are no collisions
    * between local variables when one function call another */
-
+#if 0
   pic14_deallocateAllRegs();
 
   for(pb = the_pFile->pbHead; pb; pb = pb->next) {
     if(!pb->visited)
       register_usage(pb);
   }
+#endif
 
   fprintf(of,"\n**************\n\na better call tree\n");
   for(pb = the_pFile->pbHead; pb; pb = pb->next) {
index 39a637d006885bd0334910d432bf1b2956745873..c0a8bee399914a06996926f88bb28f1a164cdb73 100644 (file)
@@ -91,6 +91,21 @@ struct regs;
 #define PIC_C_BIT    0
 #define PIC_DC_BIT   1
 #define PIC_Z_BIT    2
+#define PIC_RP0_BIT  5   /* Register Bank select bits RP1:0 : */
+#define PIC_RP1_BIT  6   /* 00 - bank 0, 01 - bank 1, 10 - bank 2, 11 - bank 3 */
+#define PIC_IRP_BIT  7   /* Indirect register page select */
+
+/***********************************************************************
+ *  PIC INTCON bits - this will move into device dependent headers
+ ***********************************************************************/
+#define PIC_RBIF_BIT 0   /* Port B level has changed flag */
+#define PIC_INTF_BIT 1   /* Port B bit 0 interrupt on edge flag */
+#define PIC_T0IF_BIT 2   /* TMR0 has overflowed flag */
+#define PIC_RBIE_BIT 3   /* Port B level has changed - Interrupt Enable */
+#define PIC_INTE_BIT 4   /* Port B bit 0 interrupt on edge - Int Enable */
+#define PIC_T0IE_BIT 5   /* TMR0 overflow Interrupt Enable */
+#define PIC_PIE_BIT  6   /* Peripheral Interrupt Enable */
+#define PIC_GIE_BIT  7   /* Global Interrupt Enable */
 
 /***********************************************************************
  *  Operand types 
@@ -124,6 +139,7 @@ typedef enum
   PO_STATUS,         // The 'STATUS' register
   PO_FSR,            // The "file select register" (in 18c it's one of three)
   PO_INDF,           // The Indirect register
+  PO_INTCON,         // Interrupt Control register
   PO_GPR_REGISTER,   // A general purpose register
   PO_GPR_BIT,        // A bit of a general purpose register
   PO_GPR_TEMP,       // A general purpose temporary register
@@ -141,37 +157,6 @@ typedef enum
 } PIC_OPTYPE;
 
 
-/*************************************************
- * pCode conditions:
- *
- * The "conditions" are bit-mapped flags that describe
- * input and/or output conditions that are affected by
- * the instructions. For example:
- *
- *    MOVF   SOME_REG,W
- *
- * This instruction depends upon 'SOME_REG'. Consequently
- * it has the input condition PCC_REGISTER set to true.
- *
- * In addition, this instruction affects the Z bit in the
- * status register and affects W. Thus the output conditions
- * are the logical or:
- *  PCC_ZERO_BIT | PCC_W
- *
- * The conditions are intialized when the pCode for an
- * instruction is created. They're subsequently used
- * by the pCode optimizer determine state information
- * in the program flow.
- *************************************************/
-
-#define  PCC_NONE          0
-#define  PCC_REGISTER      (1<<0)
-#define  PCC_C             (1<<1)
-#define  PCC_Z             (1<<2)
-#define  PCC_DC            (1<<3)
-#define  PCC_W             (1<<4)
-#define  PCC_EXAMINE_PCOP  (1<<5)
-
 /***********************************************************************
  *
  *  PIC_OPCODE
@@ -216,9 +201,10 @@ typedef enum
   POC_MOVFW,
   POC_MOVLW,
   POC_MOVWF,
-  POC_NEGF,
+  POC_NOP,
   POC_RETLW,
   POC_RETURN,
+  POC_RETFIE,
   POC_RLF,
   POC_RLFW,
   POC_RRF,
@@ -241,11 +227,13 @@ typedef enum
 
 typedef enum
 {
-  PC_COMMENT=0,   // pCode is a comment
-  PC_OPCODE,      // PORT dependent opcode
-  PC_LABEL,       // assembly label
-  PC_FUNCTION,    // Function start or end
-  PC_WILD         // wildcard - an opcode place holder
+  PC_COMMENT=0,   /* pCode is a comment     */
+  PC_OPCODE,      /* PORT dependent opcode  */
+  PC_LABEL,       /* assembly label         */
+  PC_FLOW,        /* flow analysis          */
+  PC_FUNCTION,    /* Function start or end  */
+  PC_WILD         /* wildcard - an opcode place holder used 
+                  * in the pCode peep hole optimizer */
 } PC_TYPE;
 
 /************************************************/
@@ -297,7 +285,7 @@ typedef struct pCodeOp
   char *name;
   
 } pCodeOp;
-
+#if 0
 typedef struct pCodeOpBit
 {
   pCodeOp pcop;
@@ -305,13 +293,19 @@ typedef struct pCodeOpBit
   unsigned int inBitSpace: 1; /* True if in bit space, else
                                 just a bit of a register */
 } pCodeOpBit;
-
+#endif
 typedef struct pCodeOpLit
 {
   pCodeOp pcop;
   int lit;
 } pCodeOpLit;
 
+typedef struct pCodeOpImmd
+{
+  pCodeOp pcop;
+  int offset;
+} pCodeOpImmd;
+
 typedef struct pCodeOpLabel
 {
   pCodeOp pcop;
@@ -323,6 +317,7 @@ typedef struct pCodeOpReg
   pCodeOp pcop;    // Can be either GPR or SFR
   int rIdx;        // Index into the register table
   struct regs *r;
+  int instance;    // byte # of Multi-byte registers
   struct pBlock *pb;
 } pCodeOpReg;
 
@@ -331,6 +326,8 @@ typedef struct pCodeOpRegBit
   pCodeOpReg  pcor;       // The Register containing this bit
   int bit;                // 0-7 bit number.
   PIC_OPTYPE subtype;     // The type of this register.
+  unsigned int inBitSpace: 1; /* True if in bit space, else
+                                just a bit of a register */
 } pCodeOpRegBit;
 
 
@@ -352,10 +349,6 @@ typedef struct pCode
 
   int seq;             // sequence number
 
-  pBranch *from;       // pCodes that execute before this one
-  pBranch *to;         // pCodes that execute after
-  pBranch *label;      // pCode instructions that have labels
-
   struct pBlock *pb;   // The pBlock that contains this pCode.
 
   /* "virtual functions"
@@ -363,7 +356,7 @@ typedef struct pCode
    * in C++. The subsequent structures that "inherit"
    * the pCode structure will initialize these function
    * pointers to something useful */
-  void (*analyze) (struct pCode *_this);
+  //  void (*analyze) (struct pCode *_this);
   void (*destruct)(struct pCode *_this);
   void (*print)  (FILE *of,struct pCode *_this);
 
@@ -383,6 +376,39 @@ typedef struct pCodeComment
 
 } pCodeComment;
 
+/*************************************************
+    pCodeFlow
+
+  The Flow object is used as marker to separate 
+ the assembly code into contiguous chunks. In other
+ words, everytime an instruction cause or potentially
+ causes a branch, a Flow object will be inserted into
+ the pCode chain to mark the beginning of the next
+ contiguous chunk.
+**************************************************/
+
+typedef struct pCodeFlow
+{
+
+  pCode  pc;
+
+  pCode *end;   /* Last pCode in this flow. Note that
+                  the first pCode is pc.next */
+
+  set **uses;   /* map the pCode instruction inCond and outCond conditions 
+                * in this array of set's. The reason we allocate an 
+                * array of pointers instead of declaring each type of 
+                * usage is because there are port dependent usage definitions */
+  int nuses;    /* number of uses sets */
+
+  set *from;    /* flow blocks that can send control to this flow block */
+  set *to;      /* flow blocks to which this one can send control */
+
+  int inCond;   /* Input conditions - stuff assumed defined at entry */
+  int outCond;  /* Output conditions - stuff modified by flow block */
+
+} pCodeFlow;
+
 /*************************************************
     pCodeInstruction
 
@@ -400,11 +426,19 @@ typedef struct pCodeInstruction
 
   char const * const mnemonic;       // Pointer to mnemonic string
 
-  pCodeOp *pcop;        // Operand
+  pBranch *from;       // pCodes that execute before this one
+  pBranch *to;         // pCodes that execute after
+  pBranch *label;      // pCode instructions that have labels
 
-  unsigned int num_ops;
-  unsigned int dest:     1;       // If destination is W or F, then 1==F
-  unsigned int bit_inst: 1;
+  pCodeOp *pcop;              /* Operand, if this instruction has one */
+
+  pCodeFlow *pcflow;   /* flow block to which this instruction belongs */
+
+  unsigned int num_ops;        /* Number of operands (0,1,2 for mid range pics) */
+  unsigned int isModReg:  1;   /* If destination is W or F, then 1==F */
+  unsigned int isBitInst: 1;   /* e.g. BCF */
+  unsigned int isBranch:  1;   /* True if this is a branching instruction */
+  unsigned int isSkip:    1;   /* True if this is a skip instruction */
 
   unsigned int inCond;   // Input conditions for this instruction
   unsigned int outCond;  // Output conditions for this instruction
@@ -441,6 +475,10 @@ typedef struct pCodeFunction
                      start and the name is contained
                      here */
 
+  pBranch *from;       // pCodes that execute before this one
+  pBranch *to;         // pCodes that execute after
+  pBranch *label;      // pCode instructions that have labels
+
 } pCodeFunction;
 
 
@@ -451,7 +489,7 @@ typedef struct pCodeFunction
 typedef struct pCodeWild
 {
 
-  pCode  pc;
+  pCodeInstruction  pci;
 
   int    id;     /* Index into the wild card array of a peepBlock 
                  * - this wild card will get expanded into that pCode
@@ -487,7 +525,7 @@ typedef struct pBlock
   set *function_entries;    /* dll of functions in this pblock */
   set *function_exits;
   set *function_calls;
-  set *registers;
+  set *tregisters;
 
   unsigned visited:1;       /* set true if traversed in call tree */
 
@@ -579,11 +617,13 @@ typedef struct pCodeOpWild
 #define PCI(x)    ((pCodeInstruction *)(x))
 #define PCL(x)    ((pCodeLabel *)(x))
 #define PCF(x)    ((pCodeFunction *)(x))
+#define PCFL(x)    ((pCodeFlow *)(x))
 #define PCW(x)    ((pCodeWild *)(x))
 
 #define PCOP(x)   ((pCodeOp *)(x))
-#define PCOB(x)   ((pCodeOpBit *)(x))
+//#define PCOB(x)   ((pCodeOpBit *)(x))
 #define PCOL(x)   ((pCodeOpLit *)(x))
+#define PCOI(x)   ((pCodeOpImmd *)(x))
 #define PCOLAB(x) ((pCodeOpLabel *)(x))
 #define PCOR(x)   ((pCodeOpReg *)(x))
 #define PCORB(x)  ((pCodeOpRegBit *)(x))
@@ -598,8 +638,7 @@ typedef struct pCodeOpWild
 pCode *newpCode (PIC_OPCODE op, pCodeOp *pcop); // Create a new pCode given an operand
 pCode *newpCodeCharP(char *cP);              // Create a new pCode given a char *
 pCode *newpCodeFunction(char *g, char *f);   // Create a new function
-pCode *newpCodeLabel(int key);               // Create a new label given a key
-pCode *newpCodeLabelStr(char *str);          // Create a new label given a string
+pCode *newpCodeLabel(char *name,int key);    // Create a new label given a key
 pBlock *newpCodeChain(memmap *cm,char c, pCode *pc); // Create a new pBlock
 void printpBlock(FILE *of, pBlock *pb);      // Write a pBlock to a file
 void printpCode(FILE *of, pCode *pc);        // Write a pCode to a file
@@ -611,10 +650,13 @@ void AnalyzepCode(char dbName);
 void OptimizepCode(char dbName);
 void printCallTree(FILE *of);
 void pCodePeepInit(void);
+void pBlockConvert2ISR(pBlock *pb);
 
-pCodeOp *newpCodeOpLabel(int key);
+pCodeOp *newpCodeOpLabel(char *name, int key);
+pCodeOp *newpCodeOpImmd(char *name, int offset);
 pCodeOp *newpCodeOpLit(int lit);
 pCodeOp *newpCodeOpBit(char *name, int bit,int inBitSpace);
+pCodeOp *newpCodeOpRegFromStr(char *name);
 pCodeOp *newpCodeOp(char *name, PIC_OPTYPE p);
 extern void pcode_test(void);
 
@@ -623,31 +665,14 @@ extern void pcode_test(void);
  *-----------------------------------------------------------------*/
 
 extern pCodeOpReg pc_status;
+extern pCodeOpReg pc_intcon;
 extern pCodeOpReg pc_indf;
 extern pCodeOpReg pc_fsr;
 extern pCodeOpReg pc_pcl;
 extern pCodeOpReg pc_pclath;
 extern pCodeOpReg pc_kzero;
+extern pCodeOpReg pc_wsave;     /* wsave and ssave are used to save W and the Status */
+extern pCodeOpReg pc_ssave;     /* registers during an interrupt */
 
 
-////////////////////   DELETE THIS ///////////////////
-/*-----------------------------------------------------------------*/
-/* Allocation macros that replace those in SDCCalloc.h             */
-/*   Why? I dunno. I ran across a bug with those macros that       */
-/*   I couldn't fix, but I could work around...                    */
-/*-----------------------------------------------------------------*/
-# define GC_malloc(x) calloc((x), 1)
-
-#define  _ALLOC(x,sz) if (!(x = calloc((sz),1) ))      \
-         {                                          \
-            werror(E_OUT_OF_MEM,__FILE__,(long) sz);\
-            exit (1);                               \
-         }
-
-#define _ALLOC_ATOMIC(x,y) if (!((x) = malloc(y)))   \
-         {                                               \
-            werror(E_OUT_OF_MEM,__FILE__,(long) y);     \
-            exit (1);                                    \
-         }
-
 #endif // __PCODE_H__
index b21f7cea501377ebd4889f5bdd0676f7ac8c70d8..fe125973d1dcba26e20eceaac6d6495496d8b91b 100644 (file)
@@ -26,6 +26,7 @@
 
 
 #include "pcode.h"
+#include "pcodeflow.h"
 #include "ralloc.h"
 
 #if defined(__BORLANDC__) || defined(_MSC_VER)
@@ -308,7 +309,7 @@ static void * cvt_altpat_label(void *pp)
   parsedPattern *p = pp;
 
   DFPRINTF((stderr,"altpat_label with ID = %d\n",p->pct[1].tok.n));
-  return newpCodeLabel(-p->pct[1].tok.n);
+  return newpCodeLabel(NULL,-p->pct[1].tok.n);
 
 }
 
@@ -402,7 +403,7 @@ static void * cvt_altpat_mnem1(void *pp)
     return NULL;
   }
 
-  if(pic14Mnemonics[opcode]->bit_inst)
+  if(pic14Mnemonics[opcode]->isBitInst)
     pcosubtype = newpCodeOp(p[1].pct[0].tok.s,PO_BIT);
   else
     pcosubtype = newpCodeOp(p[1].pct[0].tok.s,PO_GPR_REGISTER);
@@ -441,7 +442,7 @@ static void * cvt_altpat_mnem1a(void *pp)
     return NULL;
   }
 
-  if(pic14Mnemonics[opcode]->bit_inst)
+  if(pic14Mnemonics[opcode]->isBitInst)
     pcosubtype = newpCodeOpBit(NULL,-1,0);
   else
     pcosubtype = newpCodeOp(NULL,PO_GPR_REGISTER);
@@ -513,7 +514,7 @@ static void * cvt_altpat_mnem2(void *pp)
     return NULL;
   }
 
-  if(pic14Mnemonics[opcode]->bit_inst) {
+  if(pic14Mnemonics[opcode]->isBitInst) {
     pcosubtype = cvt_extract_status(p[1].pct[0].tok.s, p[3].pct[0].tok.s);
     if(pcosubtype == NULL) {
       fprintf(stderr, "bad operand?\n");
@@ -568,7 +569,7 @@ static void * cvt_altpat_mnem2a(void *pp)
     return NULL;
   }
 
-  if(pic14Mnemonics[opcode]->bit_inst)
+  if(pic14Mnemonics[opcode]->isBitInst)
     pcosubtype = newpCodeOp(NULL,PO_BIT);
   else
     pcosubtype = newpCodeOp(NULL,PO_GPR_REGISTER);
@@ -1263,22 +1264,22 @@ int pCodePeepMatchLabels(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
 
   /* Check for a label associated with this wild pCode */
   // If the wild card has a label, make sure the source code does too.
-  if(pcd->label) {
+  if(PCI(pcd)->label) {
     pCode *pcl;
 
-    if(!pcs->label)
+    if(!PCI(pcs)->label)
       return 0;
 
-    pcl = pcd->label->pc;
+    pcl = PCI(pcd)->label->pc;
 
     labindex = -PCL(pcl)->key;
     //DFPRINTF((stderr,"label id = %d (labindex = %d)\n",PCL(pcl)->key,labindex));
     if(peepBlock->vars[labindex] == NULL) {
       // First time to encounter this label
-      peepBlock->vars[labindex] = PCL(pcs->label->pc)->label;
+      peepBlock->vars[labindex] = PCL(PCI(pcs)->label->pc)->label;
       //DFPRINTF((stderr,"first time for a label: %d %s\n",labindex, peepBlock->vars[labindex]));
     } else {
-      if(strcmp(peepBlock->vars[labindex],PCL(pcs->label->pc)->label) != 0) {
+      if(strcmp(peepBlock->vars[labindex],PCL(PCI(pcs)->label->pc)->label) != 0) {
        // DFPRINTF((stderr,"labels don't match\n"));
        return 0;
       }
@@ -1287,7 +1288,7 @@ int pCodePeepMatchLabels(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
   } else {
     // DFPRINTF((stderr,"destination doesn't have a label\n"));
 
-    if(pcs->label)
+    if(PCI(pcs)->label)
       return 0;
   }
 
@@ -1493,9 +1494,9 @@ static pCodeOp *pCodeOpCopy(pCodeOp *pcop)
   case PO_CRY:
   case PO_BIT:
     //DFPRINTF((stderr,"pCodeOpCopy bit\n"));
-    pcopnew = Safe_calloc(1,sizeof(pCodeOpBit) );
-    PCOB(pcopnew)->bit = PCOB(pcop)->bit;
-    PCOB(pcopnew)->inBitSpace = PCOB(pcop)->inBitSpace;
+    pcopnew = Safe_calloc(1,sizeof(pCodeOpRegBit) );
+    PCORB(pcopnew)->bit = PCORB(pcop)->bit;
+    PCORB(pcopnew)->inBitSpace = PCORB(pcop)->inBitSpace;
 
     break;
 
@@ -1546,6 +1547,7 @@ static pCodeOp *pCodeOpCopy(pCodeOp *pcop)
   case PO_STR:
   case PO_NONE:
   case PO_W:
+  case PO_INTCON:
   case PO_STATUS:
   case PO_PCL:
   case PO_PCLATH:
index d5ab8566417d142f99a87858425c822a38a73eb0..7b7f125b14b2545c692498869aebde04d0c1b889 100644 (file)
 #include "pcode.h"
 #include "gen.h"
 
+#if defined(__BORLANDC__) || defined(_MSC_VER)
+#define STRCASECMP stricmp
+#else
+#define STRCASECMP strcasecmp
+#endif
+
 /*-----------------------------------------------------------------*/
 /* At this point we start getting processor specific although      */
 /* some routines are non-processor specific & can be reused when   */
@@ -57,95 +63,27 @@ _G;
 /* Shared with gen.c */
 int pic14_ptrRegReq;           /* one byte pointer register required */
 
-/* pic14 registers */
-/* A nasty, awful, disgusting hack for register declarations */
-#ifdef p16c84
-
-regs regspic14[] =
-{
-
-  {REG_GPR, PO_GPR_TEMP, 0x0C, "r0x0C", "r0x0C", 0x0C, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x0D, "r0x0D", "r0x0C", 0x0D, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x0E, "r0x0E", "r0x0C", 0x0E, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x0F, "r0x0F", "r0x0C", 0x0F, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x10, "r0x10", "r0x10", 0x10, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x11, "r0x11", "r0x11", 0x11, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x12, "r0x12", "r0x12", 0x12, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x13, "r0x13", "r0x13", 0x13, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x14, "r0x14", "r0x14", 0x14, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x15, "r0x15", "r0x15", 0x15, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x16, "r0x16", "r0x16", 0x16, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x17, "r0x17", "r0x17", 0x17, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x18, "r0x18", "r0x18", 0x18, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x19, "r0x19", "r0x19", 0x19, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x1A, "r0x1A", "r0x1A", 0x1A, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x1B, "r0x1B", "r0x1B", 0x1B, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x1C, "r0x1C", "r0x1C", 0x1C, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x1D, "r0x1D", "r0x1D", 0x1D, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x1E, "r0x1E", "r0x1E", 0x1E, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x1F, "r0x1F", "r0x1F", 0x1F, 1, 0},
-  {REG_PTR, PO_FSR, 4, "FSR", "FSR", 4, 1, 0},
-
-};
-#else
 
-int Gstack_base_addr=0x38; /* The starting address of registers that
-                           * are used to pass and return parameters */
-regs regspic14[] =
-{
-  {REG_GPR, PO_GPR_TEMP, 0x20, "r0x20", "r0x20", 0x20, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x21, "r0x21", "r0x21", 0x21, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x22, "r0x22", "r0x22", 0x22, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x23, "r0x23", "r0x23", 0x23, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x24, "r0x24", "r0x24", 0x24, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x25, "r0x25", "r0x25", 0x25, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x26, "r0x26", "r0x26", 0x26, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x27, "r0x27", "r0x27", 0x27, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x28, "r0x28", "r0x28", 0x28, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x29, "r0x29", "r0x29", 0x29, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x2A, "r0x2A", "r0x2A", 0x2A, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x2B, "r0x2B", "r0x2B", 0x2B, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x2C, "r0x2C", "r0x2C", 0x2C, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x2D, "r0x2D", "r0x2D", 0x2D, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x2E, "r0x2E", "r0x2E", 0x2E, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x2F, "r0x2F", "r0x2F", 0x2F, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x30, "r0x30", "r0x30", 0x30, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x31, "r0x31", "r0x31", 0x31, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x32, "r0x32", "r0x32", 0x32, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x33, "r0x33", "r0x33", 0x33, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x34, "r0x34", "r0x34", 0x34, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x35, "r0x35", "r0x35", 0x35, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x36, "r0x36", "r0x36", 0x36, 1, 0},
-  {REG_GPR, PO_GPR_TEMP, 0x37, "r0x37", "r0x37", 0x37, 1, 0},
-  {REG_STK, PO_GPR_TEMP, 0x38, "r0x38", "r0x38", 0x38, 1, 0},
-  {REG_STK, PO_GPR_TEMP, 0x39, "r0x39", "r0x39", 0x39, 1, 0},
-  {REG_STK, PO_GPR_TEMP, 0x3A, "r0x3A", "r0x3A", 0x3A, 1, 0},
-  {REG_STK, PO_GPR_TEMP, 0x3B, "r0x3B", "r0x3B", 0x3B, 1, 0},
-  {REG_STK, PO_GPR_TEMP, 0x3C, "r0x3C", "r0x3C", 0x3C, 1, 0},
-  {REG_STK, PO_GPR_TEMP, 0x3D, "r0x3D", "r0x3D", 0x3D, 1, 0},
-  {REG_STK, PO_GPR_TEMP, 0x3E, "r0x3E", "r0x3E", 0x3E, 1, 0},
-  {REG_STK, PO_GPR_TEMP, 0x3F, "r0x3F", "r0x3F", 0x3F, 1, 0},
-  {REG_STK, PO_GPR_TEMP, 0x40, "r0x40", "r0x40", 0x40, 1, 0},
-  {REG_STK, PO_GPR_TEMP, 0x41, "r0x41", "r0x41", 0x41, 1, 0},
-  {REG_STK, PO_GPR_TEMP, 0x42, "r0x42", "r0x42", 0x42, 1, 0},
-  {REG_STK, PO_GPR_TEMP, 0x43, "r0x43", "r0x43", 0x43, 1, 0},
-  {REG_STK, PO_GPR_TEMP, 0x44, "r0x44", "r0x44", 0x44, 1, 0},
-  {REG_STK, PO_GPR_TEMP, 0x45, "r0x45", "r0x45", 0x45, 1, 0},
-  {REG_STK, PO_GPR_TEMP, 0x46, "r0x46", "r0x46", 0x46, 1, 0},
-  {REG_STK, PO_GPR_TEMP, 0x47, "r0x47", "r0x47", 0x47, 1, 0},
-
-  {REG_SFR, PO_GPR_REGISTER, IDX_KZ,    "KZ",  "KZ",   IDX_KZ,   1, 0}, /* Known zero */
-
-
-  {REG_STK, PO_FSR,      IDX_FSR,  "FSR",  "FSR",  IDX_FSR,  1, 0},
-  {REG_STK, PO_INDF,     IDX_INDF, "INDF", "INDF", IDX_INDF, 1, 0},
-
-
-};
+static set *dynAllocRegs=NULL;
+static set *dynStackRegs=NULL;
+static set *dynProcessorRegs=NULL;
+static set *dynDirectRegs=NULL;
+static set *dynDirectBitRegs=NULL;
+static set *dynInternalRegs=NULL;
+
+static hTab  *dynDirectRegNames= NULL;
+
+static int dynrIdx=0x20;
+static int rDirectIdx=0;
+
+int pic14_nRegs = 128;   // = sizeof (regspic14) / sizeof (regs);
+
+int Gstack_base_addr=0; /* The starting address of registers that
+                        * are used to pass and return parameters */
+
+
 
-#endif
 
-int pic14_nRegs = sizeof (regspic14) / sizeof (regs);
 static void spillThis (symbol *);
 static int debug = 1;
 static FILE *debugF = NULL;
@@ -472,108 +410,401 @@ debugLogRegType (short type)
   return buffer;
 }
 
+/*-----------------------------------------------------------------*/
+/* 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)
+{
+
+  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\n",dReg->name);
+  dReg->isFree = 0;
+  dReg->wasUsed = 1;
+  dReg->isFixed = 0;
+  dReg->isMapped = 0;
+  dReg->isEmitted = 0;
+  dReg->address = 0;
+  dReg->size = size;
+  dReg->alias = alias;
+  dReg->reg_alias = NULL;
+
+  return dReg;
+}
+
+/*-----------------------------------------------------------------*/
+/* regWithIdx - Search through a set of registers that matches idx */
+/*-----------------------------------------------------------------*/
+static regs *
+regWithIdx (set *dRegs, int idx, int fixed)
+{
+  regs *dReg;
+
+  for (dReg = setFirstItem(dRegs) ; dReg ; 
+       dReg = setNextItem(dRegs)) {
+
+    if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
+      return dReg;
+    }
+  }
+
+  return NULL;
+}
+
+/*-----------------------------------------------------------------*/
+/* regFindFree - Search for a free register in a set of registers  */
+/*-----------------------------------------------------------------*/
+static regs *
+regFindFree (set *dRegs)
+{
+  regs *dReg;
+
+  for (dReg = setFirstItem(dRegs) ; dReg ; 
+       dReg = setNextItem(dRegs)) {
+
+    if(dReg->isFree)
+      return dReg;
+  }
+
+  return NULL;
+}
+/*-----------------------------------------------------------------*/
+/* initStack - allocate registers for a psuedo stack               */
+/*-----------------------------------------------------------------*/
+void initStack(int base_address, int size)
+{
+
+  int i;
+
+  Gstack_base_addr = base_address;
+  for(i = 0; i<size; i++)
+    addSet(&dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0));
+}
+
+regs *
+allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
+{
+  return addSet(&dynProcessorRegs,newReg(REG_SFR, po_type, rIdx, name,1,alias));
+}
+
+regs *
+allocInternalRegister(int rIdx, char * name, short po_type, int alias)
+{
+  regs * reg = newReg(REG_SFR, po_type, rIdx, name,1,alias);
+
+  if(reg) {
+    reg->wasUsed = 0;
+    return addSet(&dynInternalRegs,reg);
+  }
+
+  return NULL;
+}
 /*-----------------------------------------------------------------*/
 /* allocReg - allocates register of given type                     */
 /*-----------------------------------------------------------------*/
 static regs *
 allocReg (short type)
 {
-  int i;
 
   debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
 
-  for (i = 0; i < pic14_nRegs; i++)
-    {
 
-      /* if type is given as 0 then any
-         free register will do */
-      if (!type &&
-         regspic14[i].isFree)
-       {
-         regspic14[i].isFree = 0;
-         regspic14[i].wasUsed = 1;
-         if (currFunc)
-           currFunc->regsUsed =
-             bitVectSetBit (currFunc->regsUsed, i);
-         debugLog ("  returning %s\n", regspic14[i].name);
-         return &regspic14[i];
-       }
-      /* other wise look for specific type
-         of register */
-      if (regspic14[i].isFree &&
-         regspic14[i].type == type)
-       {
-         regspic14[i].isFree = 0;
-         regspic14[i].wasUsed = 1;
-         if (currFunc)
-           currFunc->regsUsed =
-             bitVectSetBit (currFunc->regsUsed, i);
-         debugLog ("  returning %s\n", regspic14[i].name);
-         return &regspic14[i];
-       }
+  return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
+
+}
+
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+static int regname2key(char const *name)
+{
+  int key = 0;
+
+  if(!name)
+    return 0;
+
+  while(*name) {
+
+    key += (*name++) + 1;
+
+  }
+
+  return ( (key + (key >> 4) + (key>>8)) & 0x3f);
+
+}
+
+/*-----------------------------------------------------------------*/
+/* dirregWithName - search for register by name                    */
+/*-----------------------------------------------------------------*/
+regs *
+dirregWithName (char *name )
+{
+  int hkey;
+  regs *reg;
+
+  if(!name)
+    return NULL;
+
+  /* hash the name to get a key */
+
+  hkey = regname2key(name);
+
+  reg = hTabFirstItemWK(dynDirectRegNames, hkey);
+
+  while(reg) {
+
+    if(STRCASECMP(reg->name, name) == 0) {
+      return(reg);
     }
-  return NULL;
+
+    reg = hTabNextItemWK (dynDirectRegNames);
+  
+  }
+
+  return NULL; // name wasn't found in the hash table
 }
 
 /*-----------------------------------------------------------------*/
-/* pic14_regWithIdx - returns pointer to register wit index number       */
+/* allocDirReg - allocates register of given type                  */
 /*-----------------------------------------------------------------*/
 regs *
-pic14_regWithIdx (int idx)
+allocDirReg (operand *op )
 {
-  int i;
+
+  regs *reg;
+  char *name;
+
+  if(!IS_SYMOP(op)) {
+    debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
+    return NULL;
+  }
+
+  name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
+
+  /* If the symbol is at a fixed address, then remove the leading underscore
+   * from the name. This is hack to allow the .asm include file named registers
+   * to match the .c declared register names */
+
+  //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
+  //name++;
+
+  debugLog ("%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)));
+    }
+
+    debugLog("  %d  storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
+    if (IS_CODE ( OP_SYM_ETYPE(op)) )
+      debugLog(" %d  code space\n",__LINE__);
+
+    if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
+      debugLog(" %d  integral\n",__LINE__);
+    if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
+      debugLog(" %d  literal\n",__LINE__);
+    if (IS_SPEC ( OP_SYM_ETYPE(op)) )
+      debugLog(" %d  specifier\n",__LINE__);
+    debugAopGet(NULL, op);
+  }
+
+  if (IS_CODE ( OP_SYM_ETYPE(op)) )
+    return NULL;
+
+  /* First, search the hash table to see if there is a register with this name */
+  reg = dirregWithName(name);
+
+  if(!reg) {
+
+    /* Register wasn't found in hash, so let's create
+     * a new one and put it in the hash table AND in the 
+     * dynDirectRegNames set */
+
+    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);
+
+    if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
+      reg->isFixed = 1;
+      reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
+      debugLog ("  -- and it is at a fixed address 0x%02x\n",reg->address);
+    }
+
+    hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
+    if (IS_BITVAR (OP_SYM_ETYPE(op)))
+      addSet(&dynDirectBitRegs, reg);
+    else
+      addSet(&dynDirectRegs, reg);
+  }
+
+  return reg;
+}
+
+/*-----------------------------------------------------------------*/
+/* allocDirReg - allocates register of given type                  */
+/*-----------------------------------------------------------------*/
+regs *
+allocRegByName (char *name )
+{
+
+  regs *reg;
+
+  if(!name) {
+    fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
+    exit(1);
+  }
+
+  debugLog ("%s symbol name %s\n", __FUNCTION__,name);
+
+  /* First, search the hash table to see if there is a register with this name */
+  reg = dirregWithName(name);
+
+  if(!reg) {
+
+    /* Register wasn't found in hash, so let's create
+     * a new one and put it in the hash table AND in the 
+     * dynDirectRegNames set */
+
+    reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,1,0 );
+
+    debugLog ("  -- added %s to hash, size = %d\n", name,reg->size);
+
+    hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
+    addSet(&dynDirectRegs, reg);
+  }
+
+  return reg;
+}
+
+/*-----------------------------------------------------------------*/
+/* RegWithIdx - returns pointer to register with index number       */
+/*-----------------------------------------------------------------*/
+static regs *
+typeRegWithIdx (int idx, int type, int fixed)
+{
+
+  regs *dReg;
 
   debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
 
-  for (i = 0; i < pic14_nRegs; i++)
-    if (regspic14[i].rIdx == idx)
-      return &regspic14[i];
+  if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
 
-  //return &regspic14[0];
+    debugLog ("Found a Dynamic Register!\n");
+    return dReg;
+  }
+
+  if( (dReg = regWithIdx ( dynStackRegs, idx, fixed)) != NULL ) {
+    debugLog ("Found a Stack Register!\n");
+    return dReg;
+  }
+
+  if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) {
+    debugLog ("Found a Direct Register!\n");
+    return dReg;
+  }
+
+  if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
+    debugLog ("Found a Processor Register!\n");
+    return dReg;
+  }
+/*
+  if( (dReg = regWithIdx ( dynDirectBitRegs, idx, fixed)) != NULL ) {
+    debugLog ("Found a bit Register!\n");
+    return dReg;
+  }
+*/
+/*
   fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
          "regWithIdx not found");
   exit (1);
+*/
+  return NULL;
 }
 
 /*-----------------------------------------------------------------*/
-/* pic14_regWithIdx - returns pointer to register wit index number       */
+/* pic14_regWithIdx - returns pointer to register with index number*/
+/*-----------------------------------------------------------------*/
+regs *
+pic14_regWithIdx (int idx)
+{
+
+  return typeRegWithIdx(idx,-1,0);
+}
+
+/*-----------------------------------------------------------------*/
+/* pic14_regWithIdx - returns pointer to register with index number       */
 /*-----------------------------------------------------------------*/
 regs *
 pic14_allocWithIdx (int idx)
 {
-  int i;
+
+  regs *dReg;
 
   debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
 
-  for (i = 0; i < pic14_nRegs; i++)
-    if (regspic14[i].rIdx == idx){
-      debugLog ("%s - alloc fount index = 0x%x\n", __FUNCTION__,idx);
-      regspic14[i].wasUsed = 1;
-      regspic14[i].isFree = 0;
-      return &regspic14[i];
-    }
-  //return &regspic14[0];
-  fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
-  werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
-         "regWithIdx not found");
-  exit (1);
+  if( (dReg = regWithIdx ( dynAllocRegs, idx,0)) != NULL) {
+
+    debugLog ("Found a Dynamic Register!\n");
+  } else if( (dReg = regWithIdx ( dynStackRegs, idx,0)) != NULL ) {
+    debugLog ("Found a Stack Register!\n");
+  } else if( (dReg = regWithIdx ( dynProcessorRegs, idx,0)) != NULL ) {
+    debugLog ("Found a Processor Register!\n");
+  } else {
+    
+    debugLog ("Dynamic Register not found\n");
+
+
+    fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
+    werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+           "regWithIdx not found");
+    exit (1);
+
+  }
+
+  dReg->wasUsed = 1;
+  dReg->isFree = 0;
+
+  return dReg;
 }
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 regs *
 pic14_findFreeReg(short type)
 {
-  int i;
+  //  int i;
+  regs* dReg;
 
-  for (i = 0; i < pic14_nRegs; i++) {
-    if (!type && regspic14[i].isFree)
-      return &regspic14[i];
-    if (regspic14[i].isFree &&
-       regspic14[i].type == type)
-      return &regspic14[i];
+  switch (type) {
+  case REG_GPR:
+    if((dReg = regFindFree(dynAllocRegs)) != NULL)
+      return dReg;
+
+    return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,0,0));
+
+  case REG_STK:
+
+    if((dReg = regFindFree(dynStackRegs)) != NULL)
+      return dReg;
+
+    return NULL;
+
+  case REG_PTR:
+  case REG_CND:
+  case REG_SFR:
+  default:
+    return NULL;
   }
-  return NULL;
 }
 /*-----------------------------------------------------------------*/
 /* freeReg - frees a register                                      */
@@ -592,6 +823,11 @@ freeReg (regs * reg)
 static int
 nFreeRegs (int type)
 {
+  /* dynamically allocate as many as we need and worry about
+   * fitting them into a PIC later */
+
+  return 100;
+#if 0
   int i;
   int nfr = 0;
 
@@ -600,6 +836,7 @@ nFreeRegs (int type)
     if (regspic14[i].isFree && regspic14[i].type == type)
       nfr++;
   return nfr;
+#endif
 }
 
 /*-----------------------------------------------------------------*/
@@ -619,6 +856,186 @@ nfreeRegsType (int type)
   return nFreeRegs (type);
 }
 
+//<<<<<<< ralloc.c
+void writeSetUsedRegs(FILE *of, set *dRegs)
+{
+
+  regs *dReg;
+
+  for (dReg = setFirstItem(dRegs) ; dReg ; 
+       dReg = setNextItem(dRegs)) {
+
+    if(dReg->wasUsed)
+      fprintf (of, "\t%s\n",dReg->name);
+  }
+
+}
+extern void assignFixedRegisters(set *regset);
+extern void assignRelocatableRegisters(set *regset);
+extern void dump_map(void);
+extern void dump_cblock(FILE *of);
+
+
+void packBits(set *bregs)
+{
+  set *regset;
+  regs *breg;
+  regs *bitfield=NULL;
+  regs *relocbitfield=NULL;
+  int bit_no=0;
+  int byte_no=-1;
+  char buffer[20];
+
+  for (regset = bregs ; regset ;
+       regset = regset->next) {
+
+    breg = regset->item;
+    breg->isBitField = 1;
+    //fprintf(stderr,"bit reg: %s\n",breg->name);
+
+    if(breg->isFixed) {
+      //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
+
+      bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
+      breg->rIdx = breg->address & 7;
+      breg->address >>= 3;
+
+      if(!bitfield) {
+       sprintf (buffer, "fbitfield%02x", breg->address);
+       //fprintf(stderr,"new bit field\n");
+       bitfield = newReg(REG_GPR, PO_GPR_BIT,breg->address,buffer,1,0);
+       bitfield->isBitField = 1;
+       bitfield->isFixed = 1;
+       bitfield->address = breg->address;
+       addSet(&dynDirectRegs,bitfield);
+       hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
+      } else {
+       //fprintf(stderr,"  which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
+       ;
+      }
+      breg->reg_alias = bitfield;
+      bitfield = NULL;
+
+    } else {
+      if(!relocbitfield || bit_no >7) {
+       byte_no++;
+       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->isBitField = 1;
+       addSet(&dynDirectRegs,relocbitfield);
+       hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
+
+      }
+
+      breg->reg_alias = relocbitfield;
+      breg->address = rDirectIdx;   /* byte_no; */
+      breg->rIdx = bit_no++;
+    }
+  }
+      
+}
+
+
+
+void bitEQUs(FILE *of, set *bregs)
+{
+  regs *breg,*bytereg;
+  int bit_no=0;
+
+  //fprintf(stderr," %s\n",__FUNCTION__);
+  for (breg = setFirstItem(bregs) ; breg ;
+       breg = setNextItem(bregs)) {
+
+    //fprintf(stderr,"bit reg: %s\n",breg->name);
+
+    bytereg = breg->reg_alias;
+    if(bytereg)
+      fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
+              breg->name,
+              bytereg->name,
+              breg->rIdx & 0x0007);
+
+    else {
+      fprintf(stderr, "bit field is not assigned to a register\n");
+      fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
+              breg->name,
+              bit_no>>3,
+              bit_no & 0x0007);
+
+      bit_no++;
+    }
+  }
+      
+}
+void aliasEQUs(FILE *of, set *fregs)
+{
+  regs *reg;
+
+
+  for (reg = setFirstItem(fregs) ; reg ;
+       reg = setNextItem(fregs)) {
+
+    if(!reg->isEmitted)
+      fprintf (of, "%s\tEQU\t0x%03x\n",
+              reg->name,
+              reg->address);
+  }
+      
+}
+
+void writeUsedRegs(FILE *of) 
+{
+  packBits(dynDirectBitRegs);
+
+  assignFixedRegisters(dynAllocRegs);
+  assignFixedRegisters(dynStackRegs);
+  assignFixedRegisters(dynDirectRegs);
+
+  assignRelocatableRegisters(dynAllocRegs);
+  assignRelocatableRegisters(dynStackRegs);
+  assignRelocatableRegisters(dynDirectRegs);
+
+  //dump_map();
+
+  dump_cblock(of);
+  bitEQUs(of,dynDirectBitRegs);
+  aliasEQUs(of,dynAllocRegs);
+  aliasEQUs(of,dynDirectRegs);
+  aliasEQUs(of,dynStackRegs);
+
+}
+#if 0
+/*-----------------------------------------------------------------*/
+/* allDefsOutOfRange - all definitions are out of a range          */
+/*-----------------------------------------------------------------*/
+static bool
+allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
+{
+  int i;
+
+  debugLog ("%s\n", __FUNCTION__);
+  if (!defs)
+    return TRUE;
+
+  for (i = 0; i < defs->size; i++)
+    {
+      iCode *ic;
+
+      if (bitVectBitValue (defs, i) &&
+         (ic = hTabItemWithKey (iCodehTab, i)) &&
+         (ic->seq >= fseq && ic->seq <= toseq))
+
+       return FALSE;
+
+    }
+
+  return TRUE;
+}
+#endif
+//=======
+//>>>>>>> 1.28
 /*-----------------------------------------------------------------*/
 /* computeSpillable - given a point find the spillable live ranges */
 /*-----------------------------------------------------------------*/
@@ -1939,6 +2356,12 @@ regTypeNum ()
                    getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
                    getSize (sym->type));
 
+
+    if(IS_PTR_CONST (sym->type)) {
+      debugLog ("  %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
+      sym->nRegs = 2;
+    }
+
       if (sym->nRegs > 4) {
        fprintf (stderr, "allocated more than 4 or 0 registers for type ");
        printTypeChain (sym->type, stderr);
@@ -1965,18 +2388,37 @@ regTypeNum ()
   }
 
 }
+DEFSETFUNC (markRegFree)
+{
+  ((regs *)item)->isFree = 1;
+
+  return 0;
+}
 
+DEFSETFUNC (deallocReg)
+{
+  ((regs *)item)->isFree = 1;
+  ((regs *)item)->wasUsed = 0;
+
+  return 0;
+}
 /*-----------------------------------------------------------------*/
 /* freeAllRegs - mark all registers as free                        */
 /*-----------------------------------------------------------------*/
 void
 pic14_freeAllRegs ()
 {
-  int i;
+  //  int i;
 
   debugLog ("%s\n", __FUNCTION__);
+
+  applyToSet(dynAllocRegs,markRegFree);
+  applyToSet(dynStackRegs,markRegFree);
+
+/*
   for (i = 0; i < pic14_nRegs; i++)
     regspic14[i].isFree = 1;
+*/
 }
 
 /*-----------------------------------------------------------------*/
@@ -1984,15 +2426,20 @@ pic14_freeAllRegs ()
 void
 pic14_deallocateAllRegs ()
 {
-  int i;
+  //  int i;
 
   debugLog ("%s\n", __FUNCTION__);
+
+  applyToSet(dynAllocRegs,deallocReg);
+
+/*
   for (i = 0; i < pic14_nRegs; i++) {
     if(regspic14[i].pc_type == PO_GPR_TEMP) {
       regspic14[i].isFree = 1;
       regspic14[i].wasUsed = 0;
     }
   }
+*/
 }
 
 
@@ -2092,8 +2539,24 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
   debugAopGet ("  left:", IC_LEFT (ic));
   debugAopGet ("  right:", IC_RIGHT (ic));
 
-  if (!IS_ITEMP (IC_RIGHT (ic)) ||
-      OP_SYMBOL (IC_RIGHT (ic))->isind ||
+  if (!IS_ITEMP (IC_RESULT (ic))) {
+    allocDirReg(IC_RESULT (ic));
+    debugLog ("  %d - result is not temp\n", __LINE__);
+  }
+/*
+  if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
+    debugLog ("  %d - left is not temp, allocating\n", __LINE__);
+    allocDirReg(IC_LEFT (ic));
+  }
+*/
+
+  if (!IS_ITEMP (IC_RIGHT (ic))) {
+    debugLog ("  %d - not packing - right is not temp\n", __LINE__);
+    allocDirReg(IC_RIGHT (ic));
+    return 0;
+  }
+
+  if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
       OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
     {
       debugLog ("  %d - not packing - right side fails \n", __LINE__);
@@ -2686,6 +3149,7 @@ packRegsForAccUse (iCode * ic)
   return;
 
 accuse:
+  debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
   OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
 
 
@@ -2761,6 +3225,14 @@ packForPush (iCode * ic, eBBlock * ebp)
   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
 }
 
+void printSymType(char * str, sym_link *sl)
+{
+  debugLog ("    %s Symbol type: ",str);
+  printTypeChain( sl, debugF);
+  debugLog ("\n");
+
+}
+
 /*-----------------------------------------------------------------*/
 /* packRegisters - does some transformations to reduce register    */
 /*                   pressure                                      */
@@ -2773,268 +3245,294 @@ packRegisters (eBBlock * ebp)
 
   debugLog ("%s\n", __FUNCTION__);
 
-  while (1)
-    {
+  while (1) {
 
-      change = 0;
+    change = 0;
 
-      /* look for assignments of the form */
-      /* iTempNN = TRueSym (someoperation) SomeOperand */
-      /*       ....                       */
-      /* TrueSym := iTempNN:1             */
-      for (ic = ebp->sch; ic; ic = ic->next)
-       {
+    /* look for assignments of the form */
+    /* iTempNN = TRueSym (someoperation) SomeOperand */
+    /*       ....                       */
+    /* TrueSym := iTempNN:1             */
+    for (ic = ebp->sch; ic; ic = ic->next)
+      {
 
-         /* find assignment of the form TrueSym := iTempNN:1 */
-         if (ic->op == '=' && !POINTER_SET (ic))
-           change += packRegsForAssign (ic, ebp);
-         /* debug stuff */
-         if (ic->op == '=')
-           {
-             if (POINTER_SET (ic))
-               debugLog ("pointer is set\n");
-             debugAopGet ("  result:", IC_RESULT (ic));
-             debugAopGet ("  left:", IC_LEFT (ic));
-             debugAopGet ("  right:", IC_RIGHT (ic));
-           }
+       /* find assignment of the form TrueSym := iTempNN:1 */
+       if (ic->op == '=' && !POINTER_SET (ic))
+         change += packRegsForAssign (ic, ebp);
+       /* debug stuff */
+       if (ic->op == '=')
+         {
+           if (POINTER_SET (ic))
+             debugLog ("pointer is set\n");
+           debugAopGet ("  result:", IC_RESULT (ic));
+           debugAopGet ("  left:", IC_LEFT (ic));
+           debugAopGet ("  right:", IC_RIGHT (ic));
+         }
 
-       }
+      }
+
+    if (!change)
+      break;
+  }
+
+  for (ic = ebp->sch; ic; ic = ic->next) {
+
+    if(IS_SYMOP ( IC_LEFT(ic))) {
+      //sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
 
-      if (!change)
-       break;
+      debugAopGet ("  left:", IC_LEFT (ic));
+      if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
+       debugLog ("    is a pointer");
+
+      printSymType("   ", OP_SYMBOL(IC_LEFT(ic))->type);
     }
 
-  for (ic = ebp->sch; ic; ic = ic->next)
-    {
+    if(IS_SYMOP ( IC_RIGHT(ic))) {
+      debugAopGet ("  right:", IC_RIGHT (ic));
+      printSymType("    ", OP_SYMBOL(IC_RIGHT(ic))->type);
+    }
 
-      /* if this is an itemp & result of a address of a true sym 
-         then mark this as rematerialisable   */
-      if (ic->op == ADDRESS_OF &&
-         IS_ITEMP (IC_RESULT (ic)) &&
-         IS_TRUE_SYMOP (IC_LEFT (ic)) &&
-         bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
-         !OP_SYMBOL (IC_LEFT (ic))->onStack)
-       {
+    if(IS_SYMOP ( IC_RESULT(ic))) {
+      debugAopGet ("  result:", IC_RESULT (ic));
+      printSymType("     ", OP_SYMBOL(IC_RESULT(ic))->type);
+    }
 
-         debugLog ("  %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
+    if (POINTER_SET (ic))
+       debugLog ("  %d - Pointer set\n", __LINE__);
 
-         OP_SYMBOL (IC_RESULT (ic))->remat = 1;
-         OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
-         OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
 
-       }
+    /* if this is an itemp & result of a address of a true sym 
+       then mark this as rematerialisable   */
+    if (ic->op == ADDRESS_OF &&
+       IS_ITEMP (IC_RESULT (ic)) &&
+       IS_TRUE_SYMOP (IC_LEFT (ic)) &&
+       bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
+       !OP_SYMBOL (IC_LEFT (ic))->onStack)
+      {
 
-      /* if straight assignment then carry remat flag if
-         this is the only definition */
-      if (ic->op == '=' &&
-         !POINTER_SET (ic) &&
-         IS_SYMOP (IC_RIGHT (ic)) &&
-         OP_SYMBOL (IC_RIGHT (ic))->remat &&
-         bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
-       {
-         debugLog ("  %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
+       debugLog ("  %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
 
-         OP_SYMBOL (IC_RESULT (ic))->remat =
-           OP_SYMBOL (IC_RIGHT (ic))->remat;
-         OP_SYMBOL (IC_RESULT (ic))->rematiCode =
-           OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
-       }
+       OP_SYMBOL (IC_RESULT (ic))->remat = 1;
+       OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
+       OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
 
-      /* if this is a +/- operation with a rematerizable 
-         then mark this as rematerializable as well */
-      if ((ic->op == '+' || ic->op == '-') &&
-         (IS_SYMOP (IC_LEFT (ic)) &&
-          IS_ITEMP (IC_RESULT (ic)) &&
-          OP_SYMBOL (IC_LEFT (ic))->remat &&
-          bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
-          IS_OP_LITERAL (IC_RIGHT (ic))))
-       {
-         debugLog ("  %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
-         //int i = 
-         operandLitValue (IC_RIGHT (ic));
-         OP_SYMBOL (IC_RESULT (ic))->remat = 1;
-         OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
-         OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
-       }
+      }
 
-      /* mark the pointer usages */
-      if (POINTER_SET (ic))
-       {
-         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
-         debugLog ("  marking as a pointer (set) =>");
-         debugAopGet ("  result:", IC_RESULT (ic));
-       }
-      if (POINTER_GET (ic))
-       {
-         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
-         debugLog ("  marking as a pointer (get) =>");
-         debugAopGet ("  left:", IC_LEFT (ic));
-       }
+    /* if straight assignment then carry remat flag if
+       this is the only definition */
+    if (ic->op == '=' &&
+       !POINTER_SET (ic) &&
+       IS_SYMOP (IC_RIGHT (ic)) &&
+       OP_SYMBOL (IC_RIGHT (ic))->remat &&
+       bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
+      {
+       debugLog ("  %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
 
-      if (!SKIP_IC2 (ic))
-       {
-         /* if we are using a symbol on the stack
-            then we should say pic14_ptrRegReq */
-         if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
-           pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
-                                OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
-         else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
-           pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
-                             OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
-         else
-           {
-             if (IS_SYMOP (IC_LEFT (ic)))
-               pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
-                               OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
-             if (IS_SYMOP (IC_RIGHT (ic)))
-               pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
-                              OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
-             if (IS_SYMOP (IC_RESULT (ic)))
-               pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
-                             OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
-           }
-       }
+       OP_SYMBOL (IC_RESULT (ic))->remat =
+         OP_SYMBOL (IC_RIGHT (ic))->remat;
+       OP_SYMBOL (IC_RESULT (ic))->rematiCode =
+         OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
+      }
 
-      /* if the condition of an if instruction
-         is defined in the previous instruction then
-         mark the itemp as a conditional */
-      if ((IS_CONDITIONAL (ic) ||
-          ((ic->op == BITWISEAND ||
-            ic->op == '|' ||
-            ic->op == '^') &&
-           isBitwiseOptimizable (ic))) &&
-         ic->next && ic->next->op == IFX &&
-         isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
-         OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
-       {
+    /* if this is a +/- operation with a rematerizable 
+       then mark this as rematerializable as well */
+    if ((ic->op == '+' || ic->op == '-') &&
+       (IS_SYMOP (IC_LEFT (ic)) &&
+        IS_ITEMP (IC_RESULT (ic)) &&
+        OP_SYMBOL (IC_LEFT (ic))->remat &&
+        bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
+        IS_OP_LITERAL (IC_RIGHT (ic))))
+      {
+       debugLog ("  %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
+       //int i = 
+       operandLitValue (IC_RIGHT (ic));
+       OP_SYMBOL (IC_RESULT (ic))->remat = 1;
+       OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
+       OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
+      }
 
-         OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
-         continue;
-       }
+    /* mark the pointer usages */
+    if (POINTER_SET (ic))
+      {
+       OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
+       debugLog ("  marking as a pointer (set) =>");
+       debugAopGet ("  result:", IC_RESULT (ic));
+      }
+    if (POINTER_GET (ic))
+      {
+       OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
+       debugLog ("  marking as a pointer (get) =>");
+       debugAopGet ("  left:", IC_LEFT (ic));
+      }
 
-      /* reduce for support function calls */
-      if (ic->supportRtn || ic->op == '+' || ic->op == '-')
-       packRegsForSupport (ic, ebp);
-
-      /* if a parameter is passed, it's in W, so we may not
-         need to place a copy in a register */
-      if (ic->op == RECEIVE)
-       packForReceive (ic, ebp);
-
-      /* some cases the redundant moves can
-         can be eliminated for return statements */
-      if ((ic->op == RETURN || ic->op == SEND) &&
-         !isOperandInFarSpace (IC_LEFT (ic)) &&
-         !options.model)
-       packRegsForOneuse (ic, IC_LEFT (ic), ebp);
-
-      /* if pointer set & left has a size more than
-         one and right is not in far space */
-      if (POINTER_SET (ic) &&
-         !isOperandInFarSpace (IC_RIGHT (ic)) &&
-         !OP_SYMBOL (IC_RESULT (ic))->remat &&
-         !IS_OP_RUONLY (IC_RIGHT (ic)) &&
-         getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
-
-       packRegsForOneuse (ic, IC_RESULT (ic), ebp);
-
-      /* if pointer get */
-      if (POINTER_GET (ic) &&
-         !isOperandInFarSpace (IC_RESULT (ic)) &&
-         !OP_SYMBOL (IC_LEFT (ic))->remat &&
-         !IS_OP_RUONLY (IC_RESULT (ic)) &&
-         getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
-
-       packRegsForOneuse (ic, IC_LEFT (ic), ebp);
-
-
-      /* if this is cast for intergral promotion then
-         check if only use of  the definition of the 
-         operand being casted/ if yes then replace
-         the result of that arithmetic operation with 
-         this result and get rid of the cast */
-      if (ic->op == CAST)
-       {
-         sym_link *fromType = operandType (IC_RIGHT (ic));
-         sym_link *toType = operandType (IC_LEFT (ic));
+    if (!SKIP_IC2 (ic))
+      {
+       /* if we are using a symbol on the stack
+          then we should say pic14_ptrRegReq */
+       if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
+         pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
+                              OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
+       else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
+         pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
+                              OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
+       else
+         {
+           if (IS_SYMOP (IC_LEFT (ic)))
+             pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
+                                  OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
+           if (IS_SYMOP (IC_RIGHT (ic)))
+             pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
+                                  OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
+           if (IS_SYMOP (IC_RESULT (ic)))
+             pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
+                                  OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
+         }
 
-         if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
-             getSize (fromType) != getSize (toType))
-           {
+       debugLog ("  %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
 
-             iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
-             if (dic)
-               {
-                 if (IS_ARITHMETIC_OP (dic))
-                   {
-                     bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
-                     IC_RESULT (dic) = IC_RESULT (ic);
-                     remiCodeFromeBBlock (ebp, ic);
-                     bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
-                     hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
-                     OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
-                     ic = ic->prev;
-                   }
-                 else
-                   OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
-               }
-           }
-         else
-           {
+      }
 
-             /* if the type from and type to are the same
-                then if this is the only use then packit */
-             if (compareType (operandType (IC_RIGHT (ic)),
-                            operandType (IC_LEFT (ic))) == 1)
-               {
-                 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
-                 if (dic)
-                   {
-                     bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
-                     IC_RESULT (dic) = IC_RESULT (ic);
-                     bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
-                     remiCodeFromeBBlock (ebp, ic);
-                     hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
-                     OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
-                     ic = ic->prev;
-                   }
-               }
-           }
-       }
+    /* if the condition of an if instruction
+       is defined in the previous instruction then
+       mark the itemp as a conditional */
+    if ((IS_CONDITIONAL (ic) ||
+        ((ic->op == BITWISEAND ||
+          ic->op == '|' ||
+          ic->op == '^') &&
+         isBitwiseOptimizable (ic))) &&
+       ic->next && ic->next->op == IFX &&
+       isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
+       OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
+      {
 
-      /* pack for PUSH 
-         iTempNN := (some variable in farspace) V1
-         push iTempNN ;
-         -------------
-         push V1
-       */
-      if (ic->op == IPUSH)
-       {
-         packForPush (ic, ebp);
+       debugLog ("  %d\n", __LINE__);
+       OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
+       continue;
+      }
+
+    /* reduce for support function calls */
+    if (ic->supportRtn || ic->op == '+' || ic->op == '-')
+      packRegsForSupport (ic, ebp);
+
+    /* if a parameter is passed, it's in W, so we may not
+       need to place a copy in a register */
+    if (ic->op == RECEIVE)
+      packForReceive (ic, ebp);
+
+    /* some cases the redundant moves can
+       can be eliminated for return statements */
+    if ((ic->op == RETURN || ic->op == SEND) &&
+       !isOperandInFarSpace (IC_LEFT (ic)) &&
+       !options.model)
+      packRegsForOneuse (ic, IC_LEFT (ic), ebp);
+
+    /* if pointer set & left has a size more than
+       one and right is not in far space */
+    if (POINTER_SET (ic) &&
+       !isOperandInFarSpace (IC_RIGHT (ic)) &&
+       !OP_SYMBOL (IC_RESULT (ic))->remat &&
+       !IS_OP_RUONLY (IC_RIGHT (ic)) &&
+       getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
+
+      packRegsForOneuse (ic, IC_RESULT (ic), ebp);
+
+    /* if pointer get */
+    if (POINTER_GET (ic) &&
+       !isOperandInFarSpace (IC_RESULT (ic)) &&
+       !OP_SYMBOL (IC_LEFT (ic))->remat &&
+       !IS_OP_RUONLY (IC_RESULT (ic)) &&
+       getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
+
+      packRegsForOneuse (ic, IC_LEFT (ic), ebp);
+
+
+    /* if this is cast for intergral promotion then
+       check if only use of  the definition of the 
+       operand being casted/ if yes then replace
+       the result of that arithmetic operation with 
+       this result and get rid of the cast */
+    if (ic->op == CAST) {
+       
+      sym_link *fromType = operandType (IC_RIGHT (ic));
+      sym_link *toType = operandType (IC_LEFT (ic));
+
+      debugLog ("  %d - casting\n", __LINE__);
+
+      if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
+         getSize (fromType) != getSize (toType)) {
+           
+
+       iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
+       if (dic) {
+               
+         if (IS_ARITHMETIC_OP (dic)) {
+                   
+           bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
+           IC_RESULT (dic) = IC_RESULT (ic);
+           remiCodeFromeBBlock (ebp, ic);
+           bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
+           hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
+           OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
+           ic = ic->prev;
+         }  else
+               
+           OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
+       }
+      } else {
+
+       /* if the type from and type to are the same
+          then if this is the only use then packit */
+       if (compareType (operandType (IC_RIGHT (ic)),
+                        operandType (IC_LEFT (ic))) == 1) {
+               
+         iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
+         if (dic) {
+                   
+           bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
+           IC_RESULT (dic) = IC_RESULT (ic);
+           bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
+           remiCodeFromeBBlock (ebp, ic);
+           hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
+           OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
+           ic = ic->prev;
+         }
        }
+      }
+    }
 
+    /* pack for PUSH 
+       iTempNN := (some variable in farspace) V1
+       push iTempNN ;
+       -------------
+       push V1
+    */
+    if (ic->op == IPUSH)
+      {
+       packForPush (ic, ebp);
+      }
 
-      /* pack registers for accumulator use, when the
-         result of an arithmetic or bit wise operation
-         has only one use, that use is immediately following
-         the defintion and the using iCode has only one
-         operand or has two operands but one is literal &
-         the result of that operation is not on stack then
-         we can leave the result of this operation in acc:b
-         combination */
-      if ((IS_ARITHMETIC_OP (ic)
 
-          || IS_BITWISE_OP (ic)
+    /* pack registers for accumulator use, when the
+       result of an arithmetic or bit wise operation
+       has only one use, that use is immediately following
+       the defintion and the using iCode has only one
+       operand or has two operands but one is literal &
+       the result of that operation is not on stack then
+       we can leave the result of this operation in acc:b
+       combination */
+    if ((IS_ARITHMETIC_OP (ic)
 
-          || ic->op == LEFT_OP || ic->op == RIGHT_OP
+        || IS_BITWISE_OP (ic)
 
-         ) &&
-         IS_ITEMP (IC_RESULT (ic)) &&
-         getSize (operandType (IC_RESULT (ic))) <= 2)
+        || ic->op == LEFT_OP || ic->op == RIGHT_OP
 
-       packRegsForAccUse (ic);
+        ) &&
+       IS_ITEMP (IC_RESULT (ic)) &&
+       getSize (operandType (IC_RESULT (ic))) <= 2)
 
-    }
+      packRegsForAccUse (ic);
+
+  }
 }
 
 static void
@@ -3102,6 +3600,21 @@ pic14_assignRegisters (eBBlock ** ebbs, int count)
   for (i = 0; i < count; i++)
     packRegisters (ebbs[i]);
 
+  {
+    regs *reg;
+    int hkey;
+    int i=0;
+
+    debugLog("dir registers allocated so far:\n");
+    reg = hTabFirstItem(dynDirectRegNames, &hkey);
+
+    while(reg) {
+      debugLog("  -- #%d reg = %s  key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
+      reg = hTabNextItem(dynDirectRegNames, &hkey);
+    }
+
+  }
+
   if (options.dump_pack)
     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
 
index b99341b8504e18b7c0ffcf4d96dfdd70905e1cd1..ee2ee7149142356c586e622ea31064696533a303 100644 (file)
@@ -56,11 +56,18 @@ typedef struct regs
     short rIdx;                        /* index into register table */
     //    short otype;        
     char *name;                        /* name */
-    char *dname;               /* name when direct access needed */
-    //  char *base ;         /* base address */
-    short offset;              /* offset from the base */
+
     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 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 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)*/
   }
 regs;
 extern regs regspic14[];
@@ -68,14 +75,27 @@ extern int pic14_nRegs;
 extern int Gstack_base_addr;
 
 regs *pic14_regWithIdx (int);
+regs *dirregWithName (char *name );
 void  pic14_freeAllRegs ();
 void  pic14_deallocateAllRegs ();
 regs *pic14_findFreeReg(short type);
 regs *pic14_allocWithIdx (int idx);
+regs *allocDirReg (operand *op );
+regs *allocRegByName (char *name );
 
 /* Define register address that are constant across PIC family */
 #define IDX_INDF    0
+#define IDX_TMR0    1
+#define IDX_PCL     2
+#define IDX_STATUS  3
 #define IDX_FSR     4
+#define IDX_PORTA   5
+#define IDX_PORTB   6
+#define IDX_PCLATH  0x0a
+#define IDX_INTCON  0x0b
+
 #define IDX_KZ      0x7fff   /* Known zero - actually just a general purpose reg. */
+#define IDX_WSAVE   0x7ffe
+#define IDX_SSAVE   0x7ffd
 
 #endif