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