X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic%2Fpcode.c;h=f99510028e5701f78eb612ef2b9ce7e648635da8;hb=552a5c9d683b153343d17cc7ea0b05dd478314b3;hp=dce141969717b17f71135c06e06505a114a44b91;hpb=a11adc08c61607bc23d54c29b090c159e4b9c994;p=fw%2Fsdcc diff --git a/src/pic/pcode.c b/src/pic/pcode.c index dce14196..f9951002 100644 --- a/src/pic/pcode.c +++ b/src/pic/pcode.c @@ -50,12 +50,12 @@ peepCommand peepCommands[] = { // Eventually this will go into device dependent files: -pCodeOpReg pc_status = {{PO_STATUS, "STATUS"}, -1, NULL,0,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_pclath = {{PO_PCLATH, "_PCLATH"}, -1, NULL,0,NULL}; pCodeOpReg pc_kzero = {{PO_GPR_REGISTER, "KZ"}, -1, NULL,0,NULL}; pCodeOpReg pc_wsave = {{PO_GPR_REGISTER, "WSAVE"}, -1, NULL,0,NULL}; @@ -70,34 +70,27 @@ static hTab *pic14pCodePeepCommandsHash = NULL; static pFile *the_pFile = NULL; +static pBlock *pb_dead_pcodes = NULL; /* Hardcoded flags to change the behavior of the PIC port */ static int peepOptimizing = 1; /* run the peephole optimizer if nonzero */ static int functionInlining = 1; /* inline functions if nonzero */ +int debug_verbose = 1; /* Set true to inundate .asm file */ -static int GpCodeSequenceNumber = 1; -static int GpcFlowSeq = 1; +// static int GpCodeSequenceNumber = 1; +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 isPCI_BITSKIP(x)((PCODE(x)->type == PC_OPCODE) && PCI(x)->isSkip && PCI(x)->isBitInst) -#define isPCFL(x) ((PCODE(x)->type == PC_FLOW)) -#define isPCF(x) ((PCODE(x)->type == PC_FUNCTION)) -#define isPCL(x) ((PCODE(x)->type == PC_LABEL)) -#define isPCW(x) ((PCODE(x)->type == PC_WILD)) -#define isPCCS(x) ((PCODE(x)->type == PC_CSOURCE)) - -#define isCALL(x) ((isPCI(x)) && (PCI(x)->op == POC_CALL)) -#define isSTATUS_REG(r) ((r)->pc_type == PO_STATUS) - -#define isPCOLAB(x) ((PCOP(x)->type) == PO_LABEL) +extern void RemoveUnusedRegisters(void); +extern void RegsUnMapLiveRanges(void); +extern void BuildFlowTree(pBlock *pb); +extern void pCodeRegOptimizeRegUsage(int level); +extern int picIsInitialized(void); /****************************************************************/ /* Forward declarations */ /****************************************************************/ -static void unlinkPC(pCode *pc); +void unlinkpCode(pCode *pc); #if 0 static void genericAnalyze(pCode *pc); static void AnalyzeGOTO(pCode *pc); @@ -112,13 +105,20 @@ static void pCodePrintLabel(FILE *of, pCode *pc); static void pCodePrintFunction(FILE *of, pCode *pc); static void pCodeOpPrint(FILE *of, pCodeOp *pcop); static char *get_op_from_instruction( pCodeInstruction *pcc); -char *get_op( pCodeOp *pcop,char *buff,int buf_size); +char *get_op( pCodeOp *pcop,char *buff,size_t buf_size); int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd); int pCodePeepMatchRule(pCode *pc); void pBlockStats(FILE *of, pBlock *pb); +pBlock *newpBlock(void); extern void pCodeInsertAfter(pCode *pc1, pCode *pc2); extern pCodeOp *popCopyReg(pCodeOpReg *pc); pCodeOp *popCopyGPR2Bit(pCodeOp *pc, int bitval); +void pCodeRegMapLiveRanges(pBlock *pb); + + +/****************************************************************/ +/* PIC Instructions */ +/****************************************************************/ pCodeInstruction pciADDWF = { {PC_OPCODE, NULL, NULL, 0, NULL, @@ -136,6 +136,7 @@ pCodeInstruction pciADDWF = { 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, (PCC_W | PCC_REGISTER), // inCond (PCC_REGISTER | PCC_Z) // outCond @@ -157,6 +158,7 @@ pCodeInstruction pciADDFW = { 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, (PCC_W | PCC_REGISTER), // inCond (PCC_W | PCC_Z) // outCond @@ -178,8 +180,9 @@ pCodeInstruction pciADDLW = { 1, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + 1, // literal operand POC_NOP, - PCC_W, // inCond + (PCC_W | PCC_LITERAL), // inCond (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond }; @@ -199,8 +202,9 @@ pCodeInstruction pciANDLW = { 1, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + 1, // literal operand POC_NOP, - PCC_W, // inCond + (PCC_W | PCC_LITERAL), // inCond (PCC_W | PCC_Z) // outCond }; @@ -220,6 +224,7 @@ pCodeInstruction pciANDWF = { 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, (PCC_W | PCC_REGISTER), // inCond (PCC_REGISTER | PCC_Z) // outCond @@ -241,6 +246,7 @@ pCodeInstruction pciANDFW = { 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, (PCC_W | PCC_REGISTER), // inCond (PCC_W | PCC_Z) // outCond @@ -262,8 +268,9 @@ pCodeInstruction pciBCF = { 2, // num ops 1,1, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_BSF, - PCC_REGISTER, // inCond + (PCC_REGISTER | PCC_EXAMINE_PCOP), // inCond PCC_REGISTER // outCond }; @@ -283,9 +290,10 @@ pCodeInstruction pciBSF = { 2, // num ops 1,1, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_BCF, - PCC_REGISTER, // inCond - PCC_REGISTER // outCond + (PCC_REGISTER | PCC_EXAMINE_PCOP), // inCond + (PCC_REGISTER | PCC_EXAMINE_PCOP) // outCond }; pCodeInstruction pciBTFSC = { @@ -304,9 +312,10 @@ pCodeInstruction pciBTFSC = { 2, // num ops 0,1, // dest, bit instruction 1,1, // branch, skip + 0, // literal operand POC_BTFSS, - PCC_REGISTER, // inCond - PCC_NONE // outCond + (PCC_REGISTER | PCC_EXAMINE_PCOP), // inCond + PCC_EXAMINE_PCOP // outCond }; pCodeInstruction pciBTFSS = { @@ -325,9 +334,10 @@ pCodeInstruction pciBTFSS = { 2, // num ops 0,1, // dest, bit instruction 1,1, // branch, skip + 0, // literal operand POC_BTFSC, - PCC_REGISTER, // inCond - PCC_NONE // outCond + (PCC_REGISTER | PCC_EXAMINE_PCOP), // inCond + PCC_EXAMINE_PCOP // outCond }; pCodeInstruction pciCALL = { @@ -346,6 +356,7 @@ pCodeInstruction pciCALL = { 1, // num ops 0,0, // dest, bit instruction 1,0, // branch, skip + 0, // literal operand POC_NOP, PCC_NONE, // inCond PCC_NONE // outCond @@ -367,6 +378,7 @@ pCodeInstruction pciCOMF = { 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, PCC_REGISTER, // inCond PCC_REGISTER // outCond @@ -388,6 +400,7 @@ pCodeInstruction pciCOMFW = { 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, PCC_REGISTER, // inCond PCC_W // outCond @@ -409,8 +422,9 @@ pCodeInstruction pciCLRF = { 1, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, - PCC_REGISTER, // inCond + PCC_NONE, // inCond PCC_REGISTER // outCond }; @@ -430,11 +444,34 @@ pCodeInstruction pciCLRW = { 0, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, - PCC_W, // inCond + PCC_NONE, // inCond PCC_W // outCond }; +pCodeInstruction pciCLRWDT = { + {PC_OPCODE, NULL, NULL, 0, NULL, + // genericAnalyze, + genericDestruct, + genericPrint}, + POC_CLRWDT, + "CLRWDT", + NULL, // from branch + NULL, // to branch + NULL, // label + NULL, // operand + NULL, // flow block + NULL, // C source + 0, // num ops + 0,0, // dest, bit instruction + 0,0, // branch, skip + 0, // literal operand + POC_NOP, + PCC_NONE, // inCond + PCC_NONE // outCond +}; + pCodeInstruction pciDECF = { {PC_OPCODE, NULL, NULL, 0, NULL, // genericAnalyze, @@ -451,6 +488,7 @@ pCodeInstruction pciDECF = { 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, PCC_REGISTER, // inCond PCC_REGISTER // outCond @@ -472,6 +510,7 @@ pCodeInstruction pciDECFW = { 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, PCC_REGISTER, // inCond PCC_W // outCond @@ -493,6 +532,7 @@ pCodeInstruction pciDECFSZ = { 2, // num ops 1,0, // dest, bit instruction 1,1, // branch, skip + 0, // literal operand POC_NOP, PCC_REGISTER, // inCond PCC_REGISTER // outCond @@ -514,6 +554,7 @@ pCodeInstruction pciDECFSZW = { 2, // num ops 0,0, // dest, bit instruction 1,1, // branch, skip + 0, // literal operand POC_NOP, PCC_REGISTER, // inCond PCC_W // outCond @@ -535,6 +576,7 @@ pCodeInstruction pciGOTO = { 1, // num ops 0,0, // dest, bit instruction 1,0, // branch, skip + 0, // literal operand POC_NOP, PCC_NONE, // inCond PCC_NONE // outCond @@ -556,6 +598,7 @@ pCodeInstruction pciINCF = { 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, PCC_REGISTER, // inCond PCC_REGISTER // outCond @@ -577,6 +620,7 @@ pCodeInstruction pciINCFW = { 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, PCC_REGISTER, // inCond PCC_W // outCond @@ -598,6 +642,7 @@ pCodeInstruction pciINCFSZ = { 2, // num ops 1,0, // dest, bit instruction 1,1, // branch, skip + 0, // literal operand POC_NOP, PCC_REGISTER, // inCond PCC_REGISTER // outCond @@ -619,6 +664,7 @@ pCodeInstruction pciINCFSZW = { 2, // num ops 0,0, // dest, bit instruction 1,1, // branch, skip + 0, // literal operand POC_NOP, PCC_REGISTER, // inCond PCC_W // outCond @@ -640,6 +686,7 @@ pCodeInstruction pciIORWF = { 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, (PCC_W | PCC_REGISTER), // inCond (PCC_REGISTER | PCC_Z) // outCond @@ -661,6 +708,7 @@ pCodeInstruction pciIORFW = { 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, (PCC_W | PCC_REGISTER), // inCond (PCC_W | PCC_Z) // outCond @@ -682,8 +730,9 @@ pCodeInstruction pciIORLW = { 1, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + 1, // literal operand POC_NOP, - PCC_W, // inCond + (PCC_W | PCC_LITERAL), // inCond (PCC_W | PCC_Z) // outCond }; @@ -703,6 +752,7 @@ pCodeInstruction pciMOVF = { 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, PCC_REGISTER, // inCond PCC_Z // outCond @@ -724,6 +774,7 @@ pCodeInstruction pciMOVFW = { 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, PCC_REGISTER, // inCond (PCC_W | PCC_Z) // outCond @@ -745,6 +796,7 @@ pCodeInstruction pciMOVWF = { 1, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, PCC_W, // inCond PCC_REGISTER // outCond @@ -752,7 +804,6 @@ pCodeInstruction pciMOVWF = { pCodeInstruction pciMOVLW = { {PC_OPCODE, NULL, NULL, 0, NULL, - // genericAnalyze, genericDestruct, genericPrint}, POC_MOVLW, @@ -766,8 +817,9 @@ pCodeInstruction pciMOVLW = { 1, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + 1, // literal operand POC_NOP, - PCC_NONE, // inCond + (PCC_NONE | PCC_LITERAL), // inCond PCC_W // outCond }; @@ -786,6 +838,7 @@ pCodeInstruction pciNOP = { 0, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, PCC_NONE, // inCond PCC_NONE // outCond @@ -807,6 +860,7 @@ pCodeInstruction pciRETFIE = { 0, // num ops 0,0, // dest, bit instruction 1,0, // branch, skip + 0, // literal operand POC_NOP, PCC_NONE, // inCond PCC_NONE // outCond (not true... affects the GIE bit too) @@ -828,8 +882,9 @@ pCodeInstruction pciRETLW = { 1, // num ops 0,0, // dest, bit instruction 1,0, // branch, skip + 1, // literal operand POC_NOP, - PCC_NONE, // inCond + PCC_LITERAL, // inCond PCC_W // outCond }; @@ -849,6 +904,7 @@ pCodeInstruction pciRETURN = { 0, // num ops 0,0, // dest, bit instruction 1,0, // branch, skip + 0, // literal operand POC_NOP, PCC_NONE, // inCond PCC_NONE // outCond @@ -870,6 +926,7 @@ pCodeInstruction pciRLF = { 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, (PCC_C | PCC_REGISTER), // inCond (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC) // outCond @@ -891,6 +948,7 @@ pCodeInstruction pciRLFW = { 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, (PCC_C | PCC_REGISTER), // inCond (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond @@ -912,6 +970,7 @@ pCodeInstruction pciRRF = { 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, (PCC_C | PCC_REGISTER), // inCond (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC) // outCond @@ -933,6 +992,7 @@ pCodeInstruction pciRRFW = { 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, (PCC_C | PCC_REGISTER), // inCond (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond @@ -954,6 +1014,7 @@ pCodeInstruction pciSUBWF = { 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, (PCC_W | PCC_REGISTER), // inCond (PCC_REGISTER | PCC_Z) // outCond @@ -975,6 +1036,7 @@ pCodeInstruction pciSUBFW = { 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, (PCC_W | PCC_REGISTER), // inCond (PCC_W | PCC_Z) // outCond @@ -996,8 +1058,9 @@ pCodeInstruction pciSUBLW = { 1, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + 1, // literal operand POC_NOP, - PCC_W, // inCond + (PCC_W | PCC_LITERAL), // inCond (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond }; @@ -1017,6 +1080,7 @@ pCodeInstruction pciSWAPF = { 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, (PCC_REGISTER), // inCond (PCC_REGISTER) // outCond @@ -1038,6 +1102,7 @@ pCodeInstruction pciSWAPFW = { 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, (PCC_REGISTER), // inCond (PCC_W) // outCond @@ -1059,6 +1124,7 @@ pCodeInstruction pciTRIS = { 1, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, PCC_NONE, // inCond PCC_REGISTER // outCond @@ -1080,6 +1146,7 @@ pCodeInstruction pciXORWF = { 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, (PCC_W | PCC_REGISTER), // inCond (PCC_REGISTER | PCC_Z) // outCond @@ -1101,6 +1168,7 @@ pCodeInstruction pciXORFW = { 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, (PCC_W | PCC_REGISTER), // inCond (PCC_W | PCC_Z) // outCond @@ -1122,8 +1190,9 @@ pCodeInstruction pciXORLW = { 1, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + 1, // literal operand POC_NOP, - PCC_W, // inCond + (PCC_W | PCC_LITERAL), // inCond (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond }; @@ -1131,10 +1200,8 @@ 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 +#ifdef HAVE_VSNPRINTF // Alas, vsnprintf is not ANSI standard, and does not exist // on Solaris (and probably other non-Gnu flavored Unixes). @@ -1161,7 +1228,7 @@ void SAFE_snprintf(char **str, size_t *size, const char *format, ...) len = strlen(*str); if(len > *size) { fprintf(stderr,"WARNING, it looks like %s has overflowed\n",__FUNCTION__); - fprintf(stderr,"len = %d is > str size %d\n",len,*size); + fprintf(stderr,"len = %d is > str size %d\n",len,(int)*size); } *str += len; @@ -1169,7 +1236,7 @@ void SAFE_snprintf(char **str, size_t *size, const char *format, ...) } -#else // USE_VSNPRINTF +#else // HAVE_VSNPRINTF // This version is *not* safe, despite the name. @@ -1199,7 +1266,7 @@ void SAFE_snprintf(char **str, size_t *size, const char *format, ...) } -#endif // USE_VSNPRINTF +#endif // HAVE_VSNPRINTF extern void initStack(int base_address, int size); @@ -1209,13 +1276,18 @@ extern void init_pic(char *); void pCodeInitRegisters(void) { + static int initialized=0; + + if(initialized) + return; + initialized = 1; initStack(0xfff, 8); init_pic(port->processor); - pc_status.r = allocProcessorRegister(IDX_STATUS,"STATUS", PO_STATUS, 0x80); + 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_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); @@ -1235,6 +1307,9 @@ void pCodeInitRegisters(void) pc_wsave.rIdx = IDX_WSAVE; pc_ssave.rIdx = IDX_SSAVE; + /* probably should put this in a separate initialization routine */ + pb_dead_pcodes = newpBlock(); + } /*-----------------------------------------------------------------*/ @@ -1288,6 +1363,7 @@ void pic14initMnemonics(void) pic14Mnemonics[POC_COMFW] = &pciCOMFW; pic14Mnemonics[POC_CLRF] = &pciCLRF; pic14Mnemonics[POC_CLRW] = &pciCLRW; + pic14Mnemonics[POC_CLRWDT] = &pciCLRWDT; pic14Mnemonics[POC_DECF] = &pciDECF; pic14Mnemonics[POC_DECFW] = &pciDECFW; pic14Mnemonics[POC_DECFSZ] = &pciDECFSZ; @@ -1351,7 +1427,7 @@ int getpCode(char *mnem,unsigned dest) while(pci) { if(STRCASECMP(pci->mnemonic, mnem) == 0) { - if((pci->num_ops <= 1) || (pci->isModReg == dest)) + if((pci->num_ops <= 1) || (pci->isModReg == dest) || (pci->isBitInst)) return(pci->op); } @@ -1509,7 +1585,7 @@ void pcode_test(void) char buffer[100]; /* create the file name */ - strcpy(buffer,srcFileName); + strcpy(buffer,dstFileName); strcat(buffer,".p"); if( !(pFile = fopen(buffer, "w" ))) { @@ -1593,11 +1669,11 @@ pCode *newpCode (PIC_OPCODE op, pCodeOp *pcop) memcpy(pci, pic14Mnemonics[op], sizeof(pCodeInstruction)); pci->pcop = pcop; - if(pci->inCond == PCC_EXAMINE_PCOP) - pci->inCond = RegCond(pcop); + if(pci->inCond & PCC_EXAMINE_PCOP) + pci->inCond |= RegCond(pcop); - if(pci->outCond == PCC_EXAMINE_PCOP) - pci->outCond = RegCond(pcop); + if(pci->outCond & PCC_EXAMINE_PCOP) + pci->outCond |= RegCond(pcop); pci->pc.prev = pci->pc.next = NULL; return (pCode *)pci; @@ -1757,19 +1833,22 @@ pCode *newpCodeFunction(char *mod,char *f) /*-----------------------------------------------------------------*/ /* newpCodeFlow */ /*-----------------------------------------------------------------*/ - void destructpCodeFlow(pCode *pc) { if(!pc || !isPCFL(pc)) return; - if(PCFL(pc)->uses) - free(PCFL(pc)->uses); /* if(PCFL(pc)->from) if(PCFL(pc)->to) */ + unlinkpCode(pc); + + deleteSet(&PCFL(pc)->registers); + deleteSet(&PCFL(pc)->from); + deleteSet(&PCFL(pc)->to); free(pc); + } pCode *newpCodeFlow(void ) @@ -1781,7 +1860,6 @@ pCode *newpCodeFlow(void ) 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; @@ -1790,9 +1868,6 @@ pCode *newpCodeFlow(void ) pcflow->pc.seq = GpcFlowSeq++; - pcflow->nuses = 7; - pcflow->uses = Safe_calloc(pcflow->nuses, sizeof(set *)); - pcflow->from = pcflow->to = NULL; pcflow->inCond = PCC_NONE; @@ -1805,6 +1880,9 @@ pCode *newpCodeFlow(void ) pcflow->ToConflicts = 0; pcflow->end = NULL; + + pcflow->registers = newSet(); + return ( (pCode *)pcflow); } @@ -1899,7 +1977,7 @@ pCode *newpCodeLabel(char *name, int key) if(s) pcl->label = Safe_strdup(s); - + //fprintf(stderr,"newpCodeLabel: key=%d, name=%s\n",key, ((s)?s:"")); return ( (pCode *)pcl); } @@ -1919,6 +1997,7 @@ pBlock *newpBlock(void) PpB->function_entries = PpB->function_exits = PpB->function_calls = NULL; PpB->tregisters = NULL; PpB->visited = 0; + PpB->FlowTree = NULL; return PpB; @@ -1974,6 +2053,7 @@ pCodeOp *newpCodeOpLabel(char *name, int key) ((pCodeOpLabel *)pcop)->key = key; + //fprintf(stderr,"newpCodeOpLabel: key=%d, name=%s\n",key,((s)?s:"")); return pcop; } @@ -2002,23 +2082,36 @@ pCodeOp *newpCodeOpLit(int lit) /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ -pCodeOp *newpCodeOpImmd(char *name, int offset, int index, int code_space) +pCodeOp *newpCodeOpImmd(char *name, int offset, int index, int code_space, int is_func) { pCodeOp *pcop; pcop = Safe_calloc(1,sizeof(pCodeOpImmd) ); pcop->type = PO_IMMEDIATE; if(name) { + regs *r = NULL; pcop->name = Safe_strdup(name); + + if(!is_func) + r = dirregWithName(name); + + PCOI(pcop)->r = r; + if(r) { + //fprintf(stderr, " newpCodeOpImmd reg %s exists\n",name); + PCOI(pcop)->rIdx = r->rIdx; + } else { + //fprintf(stderr, " newpCodeOpImmd reg %s doesn't exist\n",name); + PCOI(pcop)->rIdx = -1; + } //fprintf(stderr,"%s %s %d\n",__FUNCTION__,name,offset); } else { pcop->name = NULL; } - PCOI(pcop)->index = index; PCOI(pcop)->offset = offset; PCOI(pcop)->_const = code_space; + PCOI(pcop)->_function = is_func; return pcop; } @@ -2065,6 +2158,9 @@ pCodeOp *newpCodeOpBit(char *s, int bit, int inBitSpace) PCORB(pcop)->bit = bit; PCORB(pcop)->inBitSpace = inBitSpace; + /* pCodeOpBit is derived from pCodeOpReg. We need to init this too */ + PCOR(pcop)->r = NULL; + PCOR(pcop)->rIdx = 0; return pcop; } @@ -2092,7 +2188,6 @@ pCodeOp *newpCodeOpReg(int rIdx) if(PCOR(pcop)->r) PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx; - //fprintf(stderr, "newpcodeOpReg - rIdx = %d\n", PCOR(pcop)->r->rIdx); } pcop->type = PCOR(pcop)->r->pc_type; @@ -2137,6 +2232,14 @@ pCodeOp *newpCodeOp(char *name, PIC_OPTYPE type) pcop = newpCodeOpReg(-1); break; + case PO_GPR_POINTER: + case PO_GPR_REGISTER: + if(name) + pcop = newpCodeOpRegFromStr(name); + else + pcop = newpCodeOpReg(-1); + break; + default: pcop = Safe_calloc(1,sizeof(pCodeOp) ); pcop->type = type; @@ -2206,16 +2309,22 @@ void pCodeReadCodeTable(void) /*-----------------------------------------------------------------*/ void addpCode2pBlock(pBlock *pb, pCode *pc) { + + if(!pc) + return; + if(!pb->pcHead) { /* If this is the first pcode to be added to a block that * was initialized with a NULL pcode, then go ahead and * make this pcode the head and tail */ pb->pcHead = pb->pcTail = pc; } else { + // if(pb->pcTail) pb->pcTail->next = pc; + pc->prev = pb->pcTail; - //pc->next = NULL; pc->pb = pb; + pb->pcTail = pc; } } @@ -2322,7 +2431,7 @@ void printpBlock(FILE *of, pBlock *pb) /* */ /*-----------------------------------------------------------------*/ -static void unlinkPC(pCode *pc) +void unlinkpCode(pCode *pc) { @@ -2339,13 +2448,34 @@ static void unlinkPC(pCode *pc) pc->prev = pc->next = NULL; } } + +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ + static void genericDestruct(pCode *pc) { - //fprintf(stderr,"warning, calling default pCode destructor\n"); - unlinkPC(pc); + unlinkpCode(pc); - free(pc); + if(isPCI(pc)) { + /* For instructions, tell the register (if there's one used) + * that it's no longer needed */ + regs *reg = getRegFromInstruction(pc); + if(reg) + deleteSetItem (&(reg->reglives.usedpCodes),pc); + } + + /* Instead of deleting the memory used by this pCode, mark + * the object as bad so that if there's a pointer to this pCode + * dangling around somewhere then (hopefully) when the type is + * checked we'll catch it. + */ + + pc->type = PC_BAD; + + addpCode2pBlock(pb_dead_pcodes, pc); + + //free(pc); } @@ -2366,38 +2496,44 @@ void pBlockRegs(FILE *of, pBlock *pb) /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ -char *get_op(pCodeOp *pcop,char *buffer, int size) +char *get_op(pCodeOp *pcop,char *buffer, size_t size) { regs *r; static char b[50]; char *s; - // int size; + int use_buffer = 1; // copy the string to the passed buffer pointer if(!buffer) { buffer = b; size = sizeof(b); + use_buffer = 0; // Don't bother copying the string to the buffer. } if(pcop) { switch(pcop->type) { 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; - return PCOR(pcop)->r->name; + if(use_buffer) { + SAFE_snprintf(&buffer,&size,"%s",PCOR(pcop)->r->name); + return buffer; + } + //return PCOR(pcop)->r->name; + return pcop->name; break; case PO_GPR_TEMP: r = pic14_regWithIdx(PCOR(pcop)->r->rIdx); - //fprintf(stderr,"getop: getting %s\nfrom:\n",r->name); //pcc->pcop->name); + + if(use_buffer) { + SAFE_snprintf(&buffer,&size,"%s",r->name); + return buffer; + } + return r->name; - // case PO_GPR_BIT: - // return PCOR(pcc->pcop)->r)->name; + case PO_IMMEDIATE: s = buffer; - //size = sizeof(buffer); - //fprintf(stderr,"PO_IMMEDIATE name = %s offset = %d\n",pcc->pcop->name,PCOI(pcc->pcop)->offset); + if(PCOI(pcop)->_const) { if( PCOI(pcop)->offset && PCOI(pcop)->offset<4) { @@ -2413,8 +2549,12 @@ char *get_op(pCodeOp *pcop,char *buffer, int size) SAFE_snprintf(&s,&size,"(%s + %d)", pcop->name, PCOI(pcop)->index ); - } else - SAFE_snprintf(&s,&size,"%s",pcop->name); + } else { + if(PCOI(pcop)->offset) + SAFE_snprintf(&s,&size,"(%s >> %d)&0xff",pcop->name, 8*PCOI(pcop)->offset); + else + SAFE_snprintf(&s,&size,"%s",pcop->name); + } } return buffer; @@ -2432,8 +2572,13 @@ char *get_op(pCodeOp *pcop,char *buffer, int size) return buffer; default: - if (pcop->name) + if (pcop->name) { + if(use_buffer) { + SAFE_snprintf(&buffer,&size,"%s",pcop->name); + return buffer; + } return pcop->name; + } } } @@ -2449,8 +2594,11 @@ static char *get_op_from_instruction( pCodeInstruction *pcc) if(pcc ) return get_op(pcc->pcop,NULL,0); - + + /* gcc 3.2: warning: concatenation of string literals with __FUNCTION__ is deprecated return ("ERROR Null: "__FUNCTION__); + */ + return ("ERROR Null: get_op_from_instruction"); } @@ -2464,7 +2612,7 @@ static void pCodeOpPrint(FILE *of, pCodeOp *pcop) /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ -char *pCode2str(char *str, int size, pCode *pc) +char *pCode2str(char *str, size_t size, pCode *pc) { char *s = str; @@ -2532,9 +2680,11 @@ char *pCode2str(char *str, int size, pCode *pc) SAFE_snprintf(&s,&size,";\t--FLOW change\n"); break; case PC_CSOURCE: - SAFE_snprintf(&s,&size,";#CSRC\t%s %d\n; %s\n", PCCS(pc)->file_name, PCCS(pc)->line_number, PCCS(pc)->line); + SAFE_snprintf(&s,&size,";#CSRC\t%s %d\n; %s\n", PCCS(pc)->file_name, PCCS(pc)->line_number, PCCS(pc)->line); break; + case PC_BAD: + SAFE_snprintf(&s,&size,";A bad pCode is being used\n"); } return str; @@ -2581,9 +2731,11 @@ static void genericPrint(FILE *of, pCode *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(debug_verbose) { + fprintf(of, "\t;key=%03x",pc->seq); + if(PCI(pc)->pcflow) + fprintf(of,",flow seq=%03x",PCI(pc)->pcflow->pc.seq); + } } #if 0 { @@ -2625,7 +2777,13 @@ static void genericPrint(FILE *of, pCode *pc) break; case PC_FLOW: - fprintf(of,";<>Start of new flow, seq=%d\n",pc->seq); + if(debug_verbose) { + fprintf(of,";<>Start of new flow, seq=0x%x",pc->seq); + if(PCFL(pc)->ancestor) + fprintf(of," ancestor = 0x%x", PCODE(PCFL(pc)->ancestor)->seq); + fprintf(of,"\n"); + + } break; case PC_CSOURCE: @@ -2734,13 +2892,16 @@ static void unlinkpCodeFromBranch(pCode *pcl , pCode *pc) /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ -static pBranch * pBranchAppend(pBranch *h, pBranch *n) +pBranch * pBranchAppend(pBranch *h, pBranch *n) { pBranch *b; if(!h) return n; + if(h == n) + return n; + b = h; while(b->next) b = b->next; @@ -2875,6 +3036,9 @@ static void genericAnalyze(pCode *pc) fprintf(stderr,"analyze PC_FLOW\n"); return; + case PC_BAD: + fprintf(stderr,,";A bad pCode is being used\n"); + } } #endif @@ -3084,6 +3248,7 @@ static void AnalyzeRETURN(pCode *pc) /*-----------------------------------------------------------------*/ regs * getRegFromInstruction(pCode *pc) { + if(!pc || !isPCI(pc) || !PCI(pc)->pcop || @@ -3093,7 +3258,9 @@ regs * getRegFromInstruction(pCode *pc) switch(PCI(pc)->pcop->type) { case PO_INDF: case PO_FSR: - return pic14_regWithIdx(PCOR(PCI(pc)->pcop)->rIdx); + return PCOR(PCI(pc)->pcop)->r; + + // return typeRegWithIdx (PCOR(PCI(pc)->pcop)->rIdx, REG_SFR, 0); case PO_BIT: case PO_GPR_TEMP: @@ -3101,8 +3268,12 @@ regs * getRegFromInstruction(pCode *pc) return PCOR(PCI(pc)->pcop)->r; case PO_IMMEDIATE: + if(PCOI(PCI(pc)->pcop)->r) + return (PCOI(PCI(pc)->pcop)->r); + //fprintf(stderr, "getRegFromInstruction - immediate\n"); - return NULL; // PCOR(PCI(pc)->pcop)->r; + return dirregWithName(PCI(pc)->pcop->name); + //return NULL; // PCOR(PCI(pc)->pcop)->r; case PO_GPR_BIT: return PCOR(PCI(pc)->pcop)->r; @@ -3160,10 +3331,11 @@ void AnalyzepBlock(pBlock *pb) if(!r) { /* register wasn't found */ - r = Safe_calloc(1, sizeof(regs)); - memcpy(r,PCOR(PCI(pc)->pcop)->r, sizeof(regs)); - addSet(&pb->tregisters, r); - PCOR(PCI(pc)->pcop)->r = r; + //r = Safe_calloc(1, sizeof(regs)); + //memcpy(r,PCOR(PCI(pc)->pcop)->r, sizeof(regs)); + //addSet(&pb->tregisters, r); + addSet(&pb->tregisters, PCOR(PCI(pc)->pcop)->r); + //PCOR(PCI(pc)->pcop)->r = r; //fprintf(stderr,"added register to pblock: reg %d\n",r->rIdx); }/* else fprintf(stderr,"found register in pblock: reg %d\n",r->rIdx); @@ -3193,7 +3365,8 @@ void AnalyzepBlock(pBlock *pb) void InsertpFlow(pCode *pc, pCode **pflow) { - PCFL(*pflow)->end = pc; + if(*pflow) + PCFL(*pflow)->end = pc; if(!pc || !pc->next) return; @@ -3214,7 +3387,7 @@ void BuildFlow(pBlock *pb) { pCode *pc; pCode *last_pci=NULL; - pCode *pflow; + pCode *pflow=NULL; int seq = 0; if(!pb) @@ -3223,11 +3396,13 @@ void BuildFlow(pBlock *pb) //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; + InsertpFlow(pb->pcHead, &pflow); + + //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 != NULL; @@ -3268,14 +3443,22 @@ void BuildFlow(pBlock *pb) InsertpFlow(pc, &pflow); seq = 0; - } else if (checkLabel(pc)) { //(PCI_HAS_LABEL(pc)) { + } else if (checkLabel(pc)) { /* This instruction marks the beginning of a * new flow segment */ pc->seq = 0; - seq = 1; - InsertpFlow(findPrevInstruction(pc->prev), &pflow); + seq = 1; + + /* If the previous pCode is not a flow object, then + * insert a new flow object. (This check prevents + * two consecutive flow objects from being insert in + * the case where a skip instruction preceeds an + * instruction containing a label.) */ + + if(last_pci && (PCI(last_pci)->pcflow == PCFL(pflow))) + InsertpFlow(findPrevInstruction(pc->prev), &pflow); PCI(pc)->pcflow = PCFL(pflow); @@ -3285,7 +3468,8 @@ void BuildFlow(pBlock *pb) } //fprintf (stderr,",end seq %d",GpcFlowSeq); - PCFL(pflow)->end = pb->pcTail; + if(pflow) + PCFL(pflow)->end = pb->pcTail; } /*-------------------------------------------------------------------*/ @@ -3297,27 +3481,31 @@ void BuildFlow(pBlock *pb) /*-----------------------------------------------------------------*/ void unBuildFlow(pBlock *pb) { - pCode *pc; + pCode *pc,*pcnext; if(!pb) return; pc = pb->pcHead; + while(pc) { - pCode *pcn = pc->next; + pcnext = pc->next; if(isPCI(pc)) { + pc->seq = 0; - PCI(pc)->pcflow = NULL; - pc = pcn; - } else if(isPCFL(pc)) { - unlinkPC(pc); + if(PCI(pc)->pcflow) { + //free(PCI(pc)->pcflow); + PCI(pc)->pcflow = NULL; + } + + } else if(isPCFL(pc) ) pc->destruct(pc); - } else - pc = pcn; + pc = pcnext; } + } /*-----------------------------------------------------------------*/ @@ -3504,8 +3692,15 @@ void LinkFlow_pCode(pCodeInstruction *from, pCodeInstruction *to) } -/*-----------------------------------------------------------------*/ -/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------* + * void LinkFlow(pBlock *pb) + * + * In BuildFlow, the PIC code has been partitioned into contiguous + * non-branching segments. In LinkFlow, we determine the execution + * order of these segments. For example, if one of the segments ends + * with a skip, then we know that there are two possible flow segments + * to which control may be passed. + *-----------------------------------------------------------------*/ void LinkFlow(pBlock *pb) { pCode *pc=NULL; @@ -3546,7 +3741,7 @@ void LinkFlow(pBlock *pb) //pc->print(stderr,pc); if(!(pcol && isPCOLAB(pcol))) { - if((PCI(pc)->op != POC_RETURN) && (PCI(pc)->op != POC_CALL)) { + if((PCI(pc)->op != POC_RETLW) && (PCI(pc)->op != POC_RETURN) && (PCI(pc)->op != POC_CALL) && (PCI(pc)->op != POC_RETFIE) ) { pc->print(stderr,pc); fprintf(stderr, "ERROR: %s, branch instruction doesn't have label\n",__FUNCTION__); } @@ -3556,7 +3751,9 @@ void LinkFlow(pBlock *pb) if( (pct = findLabelinpBlock(pb,pcol)) != NULL) LinkFlow_pCode(PCI(pc),PCI(pct)); else - fprintf(stderr, "ERROR: %s, couldn't find label\n",__FUNCTION__); + fprintf(stderr, "ERROR: %s, couldn't find label. key=%d,lab=%s\n", + __FUNCTION__,pcol->key,((PCOP(pcol)->name)?PCOP(pcol)->name:"-")); + //fprintf(stderr,"newpCodeOpLabel: key=%d, name=%s\n",key,((s)?s:"")); continue; } @@ -3580,6 +3777,8 @@ void LinkFlow(pBlock *pb) } } +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ @@ -3688,7 +3887,7 @@ void BanksUsedFlow(pBlock *pb) /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ -void insertBankSwitch(pCode *pc, int Set_Clear, int RP_BankBit) +void insertBankSwitch(int position, pCode *pc, int Set_Clear, int RP_BankBit) { pCode *new_pc; @@ -3701,7 +3900,15 @@ void insertBankSwitch(pCode *pc, int Set_Clear, int RP_BankBit) new_pc = newpCode((Set_Clear ? POC_BSF : POC_BCF), popCopyGPR2Bit(PCOP(&pc_status),RP_BankBit)); - pCodeInsertAfter(pc->prev, new_pc); + if(position) { + /* insert the bank switch after this pc instruction */ + pCode *pcnext = findNextInstruction(pc); + pCodeInsertAfter(pc, new_pc); + if(pcnext) + pc = pcnext; + + } else + pCodeInsertAfter(pc->prev, new_pc); /* Move the label, if there is one */ @@ -3731,7 +3938,6 @@ void FixRegisterBankingInFlow(pCodeFlow *pcfl, int cur_bank) while(isPCinFlow(pc,PCODE(pcfl))) { - reg = getRegFromInstruction(pc); #if 0 if(reg) { @@ -3741,46 +3947,41 @@ void FixRegisterBankingInFlow(pCodeFlow *pcfl, int cur_bank) } #endif - if(reg && REG_BANK(reg)!=cur_bank) { + if( ( (reg && REG_BANK(reg)!=cur_bank) || + ((PCI(pc)->op == POC_CALL) && (cur_bank != 0) ) ) && + (!isPCI_LIT(pc)) ){ + /* Examine the instruction before this one to make sure it is * not a skip type instruction */ pcprev = findPrevpCode(pc->prev, PC_OPCODE); + if(!pcprev || (pcprev && !isPCI_SKIP(pcprev))) { - int b = cur_bank ^ REG_BANK(reg); + int b; + int reg_bank; + + reg_bank = (reg) ? REG_BANK(reg) : 0; + + b = cur_bank ^ reg_bank; //fprintf(stderr, "Cool! can switch banks\n"); - cur_bank = REG_BANK(reg); + cur_bank = reg_bank; switch(b & 3) { case 0: break; case 1: - insertBankSwitch(pc, cur_bank&1, PIC_RP0_BIT); + insertBankSwitch(0, pc, cur_bank&1, PIC_RP0_BIT); break; case 2: - insertBankSwitch(pc, cur_bank&2, PIC_RP1_BIT); - insertBankSwitch(pc, cur_bank&2, PIC_RP1_BIT); + insertBankSwitch(0, pc, cur_bank&2, PIC_RP1_BIT); + insertBankSwitch(0, pc, cur_bank&2, PIC_RP1_BIT); break; case 3: if(cur_bank & 3) { - insertBankSwitch(pc, cur_bank&1, PIC_RP0_BIT); - insertBankSwitch(pc, cur_bank&2, PIC_RP1_BIT); + insertBankSwitch(0, pc, cur_bank&1, PIC_RP0_BIT); + insertBankSwitch(0, pc, cur_bank&2, PIC_RP1_BIT); } else - insertBankSwitch(pc, -1, -1); + insertBankSwitch(0, pc, -1, -1); break; - /* - 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); - */ } @@ -4076,6 +4277,9 @@ int OptimizepBlock(pBlock *pb) */ pc = findNextInstruction(pb->pcHead); + if(!pc) + return 0; + pcprev = pc->prev; do { @@ -4123,6 +4327,8 @@ pCode * findInstructionUsingLabel(pCodeLabel *pcl, pCode *pcs) void exchangeLabels(pCodeLabel *pcl, pCode *pc) { + char *s=NULL; + if(isPCI(pc) && (PCI(pc)->pcop) && (PCI(pc)->pcop->type == PO_LABEL)) { @@ -4133,9 +4339,19 @@ void exchangeLabels(pCodeLabel *pcl, pCode *pc) if(pcol->pcop.name) free(pcol->pcop.name); - sprintf(buffer,"_%05d_DS_",pcl->key); - - pcol->pcop.name = Safe_strdup(buffer); + /* If the key is negative, then we (probably) have a label to + * a function and the name is already defined */ + + if(pcl->key>0) + sprintf(s=buffer,"_%05d_DS_",pcl->key); + else + s = pcl->label; + + //sprintf(buffer,"_%05d_DS_",pcl->key); + if(!s) { + fprintf(stderr, "ERROR %s:%d function label is null\n",__FUNCTION__,__LINE__); + } + pcol->pcop.name = Safe_strdup(s); pcol->key = pcl->key; //pc->print(stderr,pc); @@ -4202,7 +4418,7 @@ void pBlockRemoveUnusedLabels(pBlock *pb) DFPRINTF((stderr," !!! REMOVED A LABEL !!! key = %d, %s\n", pcl->key,pcl->label)); if(pc->type == PC_LABEL) { - unlinkPC(pc); + unlinkpCode(pc); pCodeLabelDestruct(pc); } else { unlinkpCodeFromBranch(pc, PCODE(pcl)); @@ -4236,7 +4452,11 @@ void pBlockMergeLabels(pBlock *pb) /* Now loop through the pBlock and merge the labels with the opcodes */ - for(pc = pb->pcHead; pc; pc = pc->next) { + pc = pb->pcHead; + // for(pc = pb->pcHead; pc; pc = pc->next) { + + while(pc) { + pCode *pcn = pc->next; if(pc->type == PC_LABEL) { @@ -4244,10 +4464,8 @@ void pBlockMergeLabels(pBlock *pb) //fprintf(stderr,"Checking label key = %d\n",PCL(pc)->key); if((pcnext = findNextInstruction(pc) )) { - pCode *pcn = pc->next; - // Unlink the pCode label from it's pCode chain - unlinkPC(pc); + unlinkpCode(pc); //fprintf(stderr,"Merged label key = %d\n",PCL(pc)->key); // And link it into the instruction's pBranch labels. (Note, since @@ -4261,10 +4479,7 @@ void pBlockMergeLabels(pBlock *pb) pbr->pc = pc; pbr->next = NULL; - PCI(pcnext)->label = pBranchAppend(PCI(pcnext)->label,pbr); - - pc = pcn; } else { fprintf(stderr, "WARNING: couldn't associate label %s with an instruction\n",PCL(pc)->label); @@ -4274,18 +4489,15 @@ void pBlockMergeLabels(pBlock *pb) /* merge the source line symbolic info into the next instruction */ if((pcnext = findNextInstruction(pc) )) { - pCode *pcn = pc->next; - // Unlink the pCode label from it's pCode chain - unlinkPC(pc); + unlinkpCode(pc); PCI(pcnext)->cline = PCCS(pc); //fprintf(stderr, "merging CSRC\n"); //genericPrint(stderr,pcnext); - pc = pcn; } } - + pc = pcn; } pBlockRemoveUnusedLabels(pb); @@ -4359,11 +4571,10 @@ void FixRegisterBanking(pBlock *pb) { pCode *pc=NULL; pCode *pcprev=NULL; - pCode *new_pc; int cur_bank; regs *reg; - // return; + if(!pb) return; @@ -4387,63 +4598,151 @@ void FixRegisterBanking(pBlock *pb) //genericPrint(stderr, pc); reg = getRegFromInstruction(pc); - #if 0 +#if 0 if(reg) { fprintf(stderr, " %s ",reg->name); - fprintf(stderr, "addr = 0x%03x, bank = %d\n",reg->address,REG_BANK(reg)); + fprintf(stderr, "addr = 0x%03x, bank = %d, bit=%d\n", + reg->address,REG_BANK(reg),reg->isBitField); } - #endif - if(reg && REG_BANK(reg)!=cur_bank) { +#endif + + if( ( (reg && REG_BANK(reg)!=cur_bank) || + ((PCI(pc)->op == POC_CALL) && (cur_bank != 0) ) ) && + (!isPCI_LIT(pc)) ){ + + /* Examine the instruction before this one to make sure it is * not a skip type instruction */ pcprev = findPrevpCode(pc->prev, PC_OPCODE); - if(!pcprev || (pcprev && !isPCI_SKIP(pcprev))) { - 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); - */ + if(!pcprev || (pcprev && !isPCI_SKIP(pcprev))) { + int b; + int reg_bank; + + reg_bank = (reg) ? REG_BANK(reg) : 0; + + b = cur_bank ^ reg_bank; + + cur_bank = reg_bank; + switch(b & 3) { + case 0: + break; + case 1: + insertBankSwitch(0, pc, cur_bank&1, PIC_RP0_BIT); + break; + case 2: + insertBankSwitch(0, pc, cur_bank&2, PIC_RP1_BIT); + insertBankSwitch(0, pc, cur_bank&2, PIC_RP1_BIT); + break; + case 3: + if(cur_bank & 3) { + insertBankSwitch(0, pc, cur_bank&1, PIC_RP0_BIT); + insertBankSwitch(0, pc, cur_bank&2, PIC_RP1_BIT); + } else + insertBankSwitch(0, pc, -1, -1); + break; } - } else { + }else { //fprintf(stderr, "Bummer can't switch banks\n"); ; } } + + pcprev = pc; + } - pcprev = pc; pc = pc->next; // } while(pc && !(isPCFL(pc))); }while (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; + if(pcprev && cur_bank) { + + int pos = 1; /* Assume that the bank swithc instruction(s) + * are inserted after this instruction */ + + if((PCI(pcprev)->op == POC_RETLW) || + (PCI(pcprev)->op == POC_RETURN) || + (PCI(pcprev)->op == POC_RETFIE)) { + + /* oops, a RETURN - we need to switch banks *before* the RETURN */ + + pos = 0; + + } + + /* Brute force - make sure that we point to bank 0 at the + * end of each flow block */ + + switch(cur_bank & 3) { + case 0: + break; + case 1: + insertBankSwitch(pos, pcprev, 0, PIC_RP0_BIT); + break; + case 2: + insertBankSwitch(pos, pcprev, 0, PIC_RP1_BIT); + insertBankSwitch(pos, pcprev, 0, PIC_RP1_BIT); + break; + case 3: + insertBankSwitch(pos, pcprev, -1, -1); + break; + } +/* + new_pc = newpCode(POC_BCF, + popCopyGPR2Bit(PCOP(&pc_status),PIC_RP0_BIT)); + pCodeInsertAfter(pcprev, new_pc); +*/ + cur_bank = 0; + //fprintf(stderr, "Brute force switch\n"); + } } + + + +#if 0 + if(reg && REG_BANK(reg)!=cur_bank) { + //fprintf(stderr,"need to switch banks\n"); + /* Examine the instruction before this one to make sure it is + * not a skip type instruction */ + pcprev = findPrevpCode(pc->prev, PC_OPCODE); + if(!pcprev || (pcprev && !isPCI_SKIP(pcprev))) { + int b = cur_bank ^ REG_BANK(reg); + + cur_bank = REG_BANK(reg); + + switch(b & 3) { + case 0: + break; + case 1: + insertBankSwitch(0, pc, cur_bank&1, PIC_RP0_BIT); + break; + case 2: + insertBankSwitch(0, pc, cur_bank&2, PIC_RP1_BIT); + insertBankSwitch(0, pc, cur_bank&2, PIC_RP1_BIT); + break; + case 3: + if(cur_bank & 3) { + insertBankSwitch(0, pc, cur_bank&1, PIC_RP0_BIT); + insertBankSwitch(0, pc, cur_bank&2, PIC_RP1_BIT); + } else + insertBankSwitch(0, pc, -1, -1); + break; + + } +#endif + + + + void pBlockDestruct(pBlock *pb) { @@ -4498,12 +4797,18 @@ void mergepBlocks(char dbName) } /*-----------------------------------------------------------------*/ -/* AnalyzeBanking - Called after the memory addresses have been */ -/* assigned to the registers. */ +/* AnalyzeFlow - Examine the flow of the code and optimize */ /* */ +/* level 0 == minimal optimization */ +/* optimize registers that are used only by two instructions */ +/* level 1 == maximal optimization */ +/* optimize by looking at pairs of instructions that use the */ +/* register. */ /*-----------------------------------------------------------------*/ -void AnalyzeBanking(void) + +void AnalyzeFlow(int level) { + static int times_called=0; pBlock *pb; @@ -4511,6 +4816,18 @@ void AnalyzeBanking(void) return; + /* if this is not the first time this function has been called, + then clean up old flow information */ + if(times_called++) { + for(pb = the_pFile->pbHead; pb; pb = pb->next) + unBuildFlow(pb); + + RegsUnMapLiveRanges(); + + } + + GpcFlowSeq = 1; + /* Phase 2 - Flow Analysis - Register Banking * * In this phase, the individual flow blocks are examined @@ -4541,15 +4858,15 @@ void AnalyzeBanking(void) for(pb = the_pFile->pbHead; pb; pb = pb->next) LinkFlow(pb); - - /* Phase x - Flow Analysis - Used Banks + /* Phase 3 - Flow Analysis - Flow Tree * * In this phase, the individual flow blocks are examined - * to determine the Register Banks they use + * to determine their order of excution. */ for(pb = the_pFile->pbHead; pb; pb = pb->next) - BanksUsedFlow(pb); + BuildFlowTree(pb); + /* Phase x - Flow Analysis - Used Banks * @@ -4560,6 +4877,18 @@ void AnalyzeBanking(void) for(pb = the_pFile->pbHead; pb; pb = pb->next) FixBankFlow(pb); + + for(pb = the_pFile->pbHead; pb; pb = pb->next) + pCodeRegMapLiveRanges(pb); + + RemoveUnusedRegisters(); + + // for(pb = the_pFile->pbHead; pb; pb = pb->next) + pCodeRegOptimizeRegUsage(level); + + OptimizepCode('*'); + + /* for(pb = the_pFile->pbHead; pb; pb = pb->next) DumpFlow(pb); @@ -4574,6 +4903,7 @@ void AnalyzeBanking(void) FillFlow(PCFL(pcflow)); } } + /* for(pb = the_pFile->pbHead; pb; pb = pb->next) { pCode *pcflow; @@ -4587,6 +4917,41 @@ void AnalyzeBanking(void) */ } +/*-----------------------------------------------------------------*/ +/* AnalyzeBanking - Called after the memory addresses have been */ +/* assigned to the registers. */ +/* */ +/*-----------------------------------------------------------------*/ + +void AnalyzeBanking(void) +{ + pBlock *pb; + + if(!picIsInitialized()) { + fprintf(stderr,"Temporary ERROR: at the moment you have to use\n"); + fprintf(stderr,"an include file create by inc2h.pl. See SDCC source:\n"); + fprintf(stderr,"support/scripts/inc2h.pl\n"); + fprintf(stderr,"this is a nuisance bug that will be fixed shortly\n"); + + exit(1); + } + + /* Phase x - Flow Analysis - Used Banks + * + * In this phase, the individual flow blocks are examined + * to determine the Register Banks they use + */ + + AnalyzeFlow(0); + AnalyzeFlow(1); + + for(pb = the_pFile->pbHead; pb; pb = pb->next) + BanksUsedFlow(pb); + for(pb = the_pFile->pbHead; pb; pb = pb->next) + FixRegisterBanking(pb); + +} + /*-----------------------------------------------------------------*/ /* buildCallTree - look at the flow and extract all of the calls */ /* */ @@ -4668,7 +5033,8 @@ void buildCallTree(void ) /* Re-allocate the registers so that there are no collisions * between local variables when one function call another */ - pic14_deallocateAllRegs(); + // this is weird... + // pic14_deallocateAllRegs(); for(pb = the_pFile->pbHead; pb; pb = pb->next) { if(!pb->visited)