--- /dev/null
+/*-------------------------------------------------------------------------
+
+ 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);
+
+ }
+
+}
+
--- /dev/null
+/*-------------------------------------------------------------------------
+
+ 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__ */
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;
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)
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++ ;
}
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++ ;
}
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;
}
//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;
}
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 ;
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;
case AOP_IMMD:
- DEBUGpic14_emitcode(";","%d",__LINE__);
if (bit16)
sprintf (s,"%s",aop->aopu.aop_immd);
else
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;
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:
if(key>max_key)
max_key = key;
- return newpCodeOpLabel(key+100+labelOffset);
+ return newpCodeOpLabel(NULL,key+100+labelOffset);
}
/*-----------------------------------------------------------------*/
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);
}
pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
{
char *s = buffer ;
- char *rs;
+ //char *rs;
pCodeOp *pcop;
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,
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:
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:
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__,
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));
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 ||
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));
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 &&
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);
+ //}
}
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
+
if(!GpsuedoStkPtr) {
/* The last byte in the assignment is in W */
size--;
/* 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"))
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);
}
}
saverbank(0,ic,FALSE);
}
}
+#endif
} else {
/* if callee-save to be used for this function
then save the registers being used in this function */
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++;
}
}
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);
}
}
unsaverbank(0,ic,FALSE);
}
}
-
+#if 0
if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
{
if (options.stack10bit)
if (IFFUNC_ISCRITICAL(sym->type))
pic14_emitcode("setb","ea");
+#endif
/* if debug then send end of function */
/* if (options.debug && currFunc) { */
}
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))
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);
}
}
// 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;
} 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 {
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 */
/*-----------------------------------------------------------------*/
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 ;
freeAsmop(result,NULL,ic,TRUE);
}
-
+#if 0
/*-----------------------------------------------------------------*/
/* genCodePointerGet - get value from code space */
/*-----------------------------------------------------------------*/
freeAsmop(result,NULL,ic,TRUE);
}
-
+#endif
/*-----------------------------------------------------------------*/
/* genGenPointerGet - gget value from generic pointer space */
/*-----------------------------------------------------------------*/
/* 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));
}
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);
}
+/*-----------------------------------------------------------------*/
+/* 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 */
/*-----------------------------------------------------------------*/
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);
/* 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 ; */
}
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;
}
}
} 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));
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),
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));
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;
}
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)) {
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;
"got unknown pointer type");
exit(1);
}
- aopPut(AOP(result),l, GPTRSIZE - 1);
+ //aopPut(AOP(result),l, GPTRSIZE - 1);
goto release ;
}
if(genMixedOperation(ic))
goto release;
+ DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
/* we move to result for the size of source */
size = AOP_SIZE(right);
/*-----------------------------------------------------------------*/
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);
}
/*-----------------------------------------------------------------*/
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;
}
DEBUGpic14_emitcode(";","adding lit to something. size %d",size);
genAddLit (ic, lit);
+ goto release;
} else if(AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) {
#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;
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 */
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 */
/* 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
}
-#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)
{
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)
{
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);
/* 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 */
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 */
/*-----------------------------------------------------------------*/
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;
/* 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 */
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 */
/* 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);
}
}
}
+
}
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");
}
}
-
/*-----------------------------------------------------------------*/
/* glue - the final glue that hold the whole thing together */
/*-----------------------------------------------------------------*/
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;
if(t->item)
DFPRINTF((stderr,"Set item %d\n",*(char *)t->item));
}
+#endif
addSetHead(&tmpfileSet,ovrFile);
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)));
/* 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);
pic14emitOverlay(ovrFile);
+ AnalyzepCode('*'); //code->dbName);
+
+ //#ifdef PCODE_DEBUG
+ printCallTree(stderr);
+ //#endif
+
pcode_test();
/* 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);
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");
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. */
#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;
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);
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
};
#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 */
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;
}
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;
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);
}
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 */
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:
if(pci->outCond == PCC_EXAMINE_PCOP)
pci->outCond = RegCond(pcop);
+ pci->pc.prev = pci->pc.next = NULL;
return (pCode *)pci;
}
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;
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;
}
/*-----------------------------------------------------------------*/
-/* newpCodeGLabel - create a new global label */
+/* newpCodeFunction - */
/*-----------------------------------------------------------------*/
{
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;
}
+/*-----------------------------------------------------------------*/
+/* 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. */
/*-----------------------------------------------------------------*/
}
-pCode *newpCodeLabel(int key)
+pCode *newpCodeLabel(char *name, int key)
{
char *s = buffer;
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;
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 */
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;
/* 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;
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)
{
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;
}
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;
+}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
switch(type) {
case PO_BIT:
+ case PO_GPR_BIT:
pcop = newpCodeOpBit(name, -1,0);
break;
break;
case PO_LABEL:
- pcop = newpCodeOpLabel(-1);
+ pcop = newpCodeOpLabel(NULL,-1);
break;
default:
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 */
/*-----------------------------------------------------------------*/
} else {
pb->pcTail->next = pc;
pc->prev = pb->pcTail;
- pc->next = NULL;
+ //pc->next = NULL;
pc->pb = pb;
pb->pcTail = 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;
if(pc) {
-
if(pc->prev)
pc->prev->next = pc->next;
if(pc->next)
regs *r;
- r = setFirstItem(pb->registers);
+ r = setFirstItem(pb->tregisters);
while (r) {
- r = setNextItem(pb->registers);
+ r = setNextItem(pb->tregisters);
}
}
static char *get_op( pCodeInstruction *pcc)
{
regs *r;
+ static char buffer[50];
+ char *s;
+ int size;
if(pcc && pcc->pcop) {
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;
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
//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)));
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'));
}
}
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;
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);
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) {
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 ");
}
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);
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) {
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");
}
{
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) {
bprev = b;
b = b->next;
}
-
+#endif
}
/*-----------------------------------------------------------------*/
/* 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);
#endif
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
+#if 0
static void genericAnalyze(pCode *pc)
{
switch(pc->type) {
/* 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)
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)
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 */
pc = pc->next;
}
- fprintf(stderr,"Couldn't find instruction\n");
+ //fprintf(stderr,"Couldn't find instruction\n");
return NULL;
}
}
#endif
+#if 0
static void AnalyzeGOTO(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) {
/* 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
}
}
+/*-----------------------------------------------------------------*/
+/* */
+/*-----------------------------------------------------------------*/
+#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)
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
// 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
}
/*-----------------------------------------------------------------*/
-/* 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.
*/
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();
}
/*-----------------------------------------------------------------*/
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);
}
}
- 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;
// 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 */
r1 = setFirstItem(registersInCallPath);
while(r1) {
- r2 = setFirstItem(pb->registers);
+ r2 = setFirstItem(pb->tregisters);
while(r2 && (r1->type != REG_STK)) {
newreg->isFree = 0;
newreg->wasUsed = 1;
}
- r2 = setNextItem(pb->registers);
+ r2 = setNextItem(pb->tregisters);
}
r1 = setNextItem(registersInCallPath);
}// 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"));
/* 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) {
#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
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
} 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
POC_MOVFW,
POC_MOVLW,
POC_MOVWF,
- POC_NEGF,
+ POC_NOP,
POC_RETLW,
POC_RETURN,
+ POC_RETFIE,
POC_RLF,
POC_RLFW,
POC_RRF,
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;
/************************************************/
char *name;
} pCodeOp;
-
+#if 0
typedef struct pCodeOpBit
{
pCodeOp pcop;
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;
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;
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;
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"
* 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);
} 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
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
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;
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
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 */
#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))
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
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);
*-----------------------------------------------------------------*/
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__
#include "pcode.h"
+#include "pcodeflow.h"
#include "ralloc.h"
#if defined(__BORLANDC__) || defined(_MSC_VER)
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);
}
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);
return NULL;
}
- if(pic14Mnemonics[opcode]->bit_inst)
+ if(pic14Mnemonics[opcode]->isBitInst)
pcosubtype = newpCodeOpBit(NULL,-1,0);
else
pcosubtype = newpCodeOp(NULL,PO_GPR_REGISTER);
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");
return NULL;
}
- if(pic14Mnemonics[opcode]->bit_inst)
+ if(pic14Mnemonics[opcode]->isBitInst)
pcosubtype = newpCodeOp(NULL,PO_BIT);
else
pcosubtype = newpCodeOp(NULL,PO_GPR_REGISTER);
/* 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;
}
} else {
// DFPRINTF((stderr,"destination doesn't have a label\n"));
- if(pcs->label)
+ if(PCI(pcs)->label)
return 0;
}
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;
case PO_STR:
case PO_NONE:
case PO_W:
+ case PO_INTCON:
case PO_STATUS:
case PO_PCL:
case PO_PCLATH:
#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 */
/* 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;
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 ®spic14[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 ®spic14[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 ®spic14[i];
+ if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
- //return ®spic14[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 ®spic14[i];
- }
- //return ®spic14[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 ®spic14[i];
- if (regspic14[i].isFree &&
- regspic14[i].type == type)
- return ®spic14[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 */
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;
if (regspic14[i].isFree && regspic14[i].type == type)
nfr++;
return nfr;
+#endif
}
/*-----------------------------------------------------------------*/
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 */
/*-----------------------------------------------------------------*/
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);
}
}
+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;
+*/
}
/*-----------------------------------------------------------------*/
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;
}
}
+*/
}
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__);
return;
accuse:
+ debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
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 */
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
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);
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[];
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