X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic%2Fpcode.c;h=3b2b7d91b14917ef41dd58cb28fe7291a35297f3;hb=256bce22d6b6abdc49735eef9b87f4685ca20bcc;hp=2c0c54268b950e732c0bf4738d823b3a50140ea9;hpb=fdae13dc9bca4bdd2284a7437c0c50fe615228a2;p=fw%2Fsdcc diff --git a/src/pic/pcode.c b/src/pic/pcode.c index 2c0c5426..3b2b7d91 100644 --- a/src/pic/pcode.c +++ b/src/pic/pcode.c @@ -70,24 +70,27 @@ static hTab *pic14pCodePeepCommandsHash = NULL; static pFile *the_pFile = NULL; -static int peepOptimizing = 1; -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 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 isCALL(x) ((isPCI(x)) && (PCI(x)->op == POC_CALL)) -#define isSTATUS_REG(r) ((r)->pc_type == PO_STATUS) +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 = 0; /* Set true to inundate .asm file */ + +// static int GpCodeSequenceNumber = 1; +int GpcFlowSeq = 1; + +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); @@ -102,11 +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 *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, @@ -120,9 +132,11 @@ pCodeInstruction pciADDWF = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 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 @@ -140,9 +154,11 @@ pCodeInstruction pciADDFW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 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 @@ -160,11 +176,13 @@ pCodeInstruction pciADDLW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 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 }; @@ -180,11 +198,13 @@ pCodeInstruction pciANDLW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 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 }; @@ -200,9 +220,11 @@ pCodeInstruction pciANDWF = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 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 @@ -220,9 +242,11 @@ pCodeInstruction pciANDFW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 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 @@ -240,11 +264,13 @@ pCodeInstruction pciBCF = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 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 }; @@ -260,12 +286,14 @@ pCodeInstruction pciBSF = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 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 = { @@ -280,12 +308,14 @@ pCodeInstruction pciBTFSC = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 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 = { @@ -300,12 +330,14 @@ pCodeInstruction pciBTFSS = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 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 = { @@ -320,9 +352,11 @@ pCodeInstruction pciCALL = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 1, // num ops 0,0, // dest, bit instruction 1,0, // branch, skip + 0, // literal operand POC_NOP, PCC_NONE, // inCond PCC_NONE // outCond @@ -340,9 +374,11 @@ pCodeInstruction pciCOMF = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, PCC_REGISTER, // inCond PCC_REGISTER // outCond @@ -360,9 +396,11 @@ pCodeInstruction pciCOMFW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, PCC_REGISTER, // inCond PCC_W // outCond @@ -380,11 +418,13 @@ pCodeInstruction pciCLRF = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 1, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, - PCC_REGISTER, // inCond + PCC_NONE, // inCond PCC_REGISTER // outCond }; @@ -400,14 +440,38 @@ pCodeInstruction pciCLRW = { 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_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, @@ -420,9 +484,11 @@ pCodeInstruction pciDECF = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, PCC_REGISTER, // inCond PCC_REGISTER // outCond @@ -440,9 +506,11 @@ pCodeInstruction pciDECFW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, PCC_REGISTER, // inCond PCC_W // outCond @@ -460,9 +528,11 @@ pCodeInstruction pciDECFSZ = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 1,0, // dest, bit instruction 1,1, // branch, skip + 0, // literal operand POC_NOP, PCC_REGISTER, // inCond PCC_REGISTER // outCond @@ -480,9 +550,11 @@ pCodeInstruction pciDECFSZW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 0,0, // dest, bit instruction 1,1, // branch, skip + 0, // literal operand POC_NOP, PCC_REGISTER, // inCond PCC_W // outCond @@ -500,9 +572,11 @@ pCodeInstruction pciGOTO = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 1, // num ops 0,0, // dest, bit instruction 1,0, // branch, skip + 0, // literal operand POC_NOP, PCC_NONE, // inCond PCC_NONE // outCond @@ -520,9 +594,11 @@ pCodeInstruction pciINCF = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, PCC_REGISTER, // inCond PCC_REGISTER // outCond @@ -540,9 +616,11 @@ pCodeInstruction pciINCFW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, PCC_REGISTER, // inCond PCC_W // outCond @@ -560,9 +638,11 @@ pCodeInstruction pciINCFSZ = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 1,0, // dest, bit instruction 1,1, // branch, skip + 0, // literal operand POC_NOP, PCC_REGISTER, // inCond PCC_REGISTER // outCond @@ -580,9 +660,11 @@ pCodeInstruction pciINCFSZW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 0,0, // dest, bit instruction 1,1, // branch, skip + 0, // literal operand POC_NOP, PCC_REGISTER, // inCond PCC_W // outCond @@ -600,9 +682,11 @@ pCodeInstruction pciIORWF = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 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 @@ -620,9 +704,11 @@ pCodeInstruction pciIORFW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 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 @@ -640,11 +726,13 @@ pCodeInstruction pciIORLW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 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 }; @@ -660,9 +748,11 @@ pCodeInstruction pciMOVF = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, PCC_REGISTER, // inCond PCC_Z // outCond @@ -680,9 +770,11 @@ pCodeInstruction pciMOVFW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 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 @@ -700,9 +792,11 @@ pCodeInstruction pciMOVWF = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 1, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, PCC_W, // inCond PCC_REGISTER // outCond @@ -710,7 +804,6 @@ pCodeInstruction pciMOVWF = { pCodeInstruction pciMOVLW = { {PC_OPCODE, NULL, NULL, 0, NULL, - // genericAnalyze, genericDestruct, genericPrint}, POC_MOVLW, @@ -720,11 +813,13 @@ pCodeInstruction pciMOVLW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 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 }; @@ -739,9 +834,11 @@ pCodeInstruction pciNOP = { 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 @@ -759,9 +856,11 @@ pCodeInstruction pciRETFIE = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 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) @@ -779,11 +878,13 @@ pCodeInstruction pciRETLW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 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 }; @@ -799,9 +900,11 @@ pCodeInstruction pciRETURN = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 0, // num ops 0,0, // dest, bit instruction 1,0, // branch, skip + 0, // literal operand POC_NOP, PCC_NONE, // inCond PCC_NONE // outCond @@ -819,9 +922,11 @@ pCodeInstruction pciRLF = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 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 @@ -839,9 +944,11 @@ pCodeInstruction pciRLFW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 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 @@ -859,9 +966,11 @@ pCodeInstruction pciRRF = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 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 @@ -879,9 +988,11 @@ pCodeInstruction pciRRFW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 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 @@ -899,9 +1010,11 @@ pCodeInstruction pciSUBWF = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 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 @@ -919,9 +1032,11 @@ pCodeInstruction pciSUBFW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 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 @@ -939,11 +1054,13 @@ pCodeInstruction pciSUBLW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 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 }; @@ -959,9 +1076,11 @@ pCodeInstruction pciSWAPF = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, (PCC_REGISTER), // inCond (PCC_REGISTER) // outCond @@ -979,9 +1098,11 @@ pCodeInstruction pciSWAPFW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, (PCC_REGISTER), // inCond (PCC_W) // outCond @@ -999,9 +1120,11 @@ pCodeInstruction pciTRIS = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 1, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + 0, // literal operand POC_NOP, PCC_NONE, // inCond PCC_REGISTER // outCond @@ -1019,9 +1142,11 @@ pCodeInstruction pciXORWF = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 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 @@ -1039,9 +1164,11 @@ pCodeInstruction pciXORFW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 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 @@ -1059,11 +1186,13 @@ pCodeInstruction pciXORLW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 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 }; @@ -1071,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). @@ -1101,6 +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,(int)*size); } *str += len; @@ -1108,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. @@ -1129,6 +1257,7 @@ void SAFE_snprintf(char **str, size_t *size, const char *format, ...) len = strlen(buffer); 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); } strcpy(*str, buffer); @@ -1137,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); @@ -1147,8 +1276,13 @@ extern void init_pic(char *); void pCodeInitRegisters(void) { + static int initialized=0; + + if(initialized) + return; + initialized = 1; - initStack(0x38, 8); + initStack(0xfff, 8); init_pic(port->processor); pc_status.r = allocProcessorRegister(IDX_STATUS,"STATUS", PO_STATUS, 0x80); @@ -1173,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(); + } /*-----------------------------------------------------------------*/ @@ -1226,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; @@ -1289,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); } @@ -1429,6 +1567,7 @@ void copypCode(FILE *of, char dbName) if(getpBlock_dbName(pb) == dbName) { pBlockStats(of,pb); printpBlock(of,pb); + fprintf (of, "\n"); } } @@ -1447,7 +1586,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" ))) { @@ -1531,11 +1670,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; @@ -1672,6 +1811,8 @@ pCode *newpCodeFunction(char *mod,char *f) pcf->pc.destruct = genericDestruct; pcf->pc.print = pCodePrintFunction; + pcf->ncalled = 0; + if(mod) { //_ALLOC_ATOMIC(pcf->modname,strlen(mod)+1); pcf->modname = Safe_calloc(1,strlen(mod)+1); @@ -1693,7 +1834,23 @@ pCode *newpCodeFunction(char *mod,char *f) /*-----------------------------------------------------------------*/ /* newpCodeFlow */ /*-----------------------------------------------------------------*/ +void destructpCodeFlow(pCode *pc) +{ + if(!pc || !isPCFL(pc)) + return; + +/* + 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 ) { @@ -1704,28 +1861,79 @@ 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; - pcflow->pc.destruct = genericDestruct; + pcflow->pc.destruct = destructpCodeFlow; 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->firstBank = -1; + pcflow->lastBank = -1; + + pcflow->FromConflicts = 0; + pcflow->ToConflicts = 0; + pcflow->end = NULL; + + pcflow->registers = newSet(); + return ( (pCode *)pcflow); } +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ +pCodeFlowLink *newpCodeFlowLink(pCodeFlow *pcflow) +{ + pCodeFlowLink *pcflowLink; + + pcflowLink = Safe_calloc(1,sizeof(pCodeFlowLink)); + + pcflowLink->pcflow = pcflow; + pcflowLink->bank_conflict = 0; + + return pcflowLink; +} + +/*-----------------------------------------------------------------*/ +/* newpCodeCSource - create a new pCode Source Symbol */ +/*-----------------------------------------------------------------*/ + +pCode *newpCodeCSource(int ln, char *f, char *l) +{ + + pCodeCSource *pccs; + + pccs = Safe_calloc(1,sizeof(pCodeCSource)); + + pccs->pc.type = PC_CSOURCE; + pccs->pc.prev = pccs->pc.next = NULL; + pccs->pc.pb = NULL; + + pccs->pc.destruct = genericDestruct; + pccs->pc.print = genericPrint; + + pccs->line_number = ln; + if(l) + pccs->line = Safe_strdup(l); + else + pccs->line = NULL; + + if(f) + pccs->file_name = Safe_strdup(f); + else + pccs->file_name = NULL; + + return ( (pCode *)pccs); + +} /*-----------------------------------------------------------------*/ /* pCodeLabelDestruct - free memory used by a label. */ /*-----------------------------------------------------------------*/ @@ -1770,7 +1978,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); } @@ -1790,6 +1998,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; @@ -1845,6 +2054,7 @@ pCodeOp *newpCodeOpLabel(char *name, int key) ((pCodeOpLabel *)pcop)->key = key; + //fprintf(stderr,"newpCodeOpLabel: key=%d, name=%s\n",key,((s)?s:"")); return pcop; } @@ -1873,23 +2083,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; } @@ -1936,6 +2159,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; } @@ -1963,7 +2189,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; @@ -2008,6 +2233,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; @@ -2077,16 +2310,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; } } @@ -2113,6 +2352,43 @@ void addpBlock(pBlock *pb) the_pFile->pbTail = pb; } +/*-----------------------------------------------------------------*/ +/* removepBlock - remove a pBlock from the pFile */ +/*-----------------------------------------------------------------*/ +void removepBlock(pBlock *pb) +{ + pBlock *pbs; + + if(!the_pFile) + return; + + + //fprintf(stderr," Removing pBlock: dbName =%c\n",getpBlock_dbName(pb)); + + for(pbs = the_pFile->pbHead; pbs; pbs = pbs->next) { + if(pbs == pb) { + + if(pbs == the_pFile->pbHead) + the_pFile->pbHead = pbs->next; + + if (pbs == the_pFile->pbTail) + the_pFile->pbTail = pbs->prev; + + if(pbs->next) + pbs->next->prev = pbs->prev; + + if(pbs->prev) + pbs->prev->next = pbs->next; + + return; + + } + } + + fprintf(stderr, "Warning: call to %s:%s didn't find pBlock\n",__FILE__,__FUNCTION__); + +} + /*-----------------------------------------------------------------*/ /* printpCode - write the contents of a pCode to a file */ /*-----------------------------------------------------------------*/ @@ -2156,11 +2432,15 @@ void printpBlock(FILE *of, pBlock *pb) /* */ /*-----------------------------------------------------------------*/ -static void unlinkPC(pCode *pc) +void unlinkpCode(pCode *pc) { if(pc) { +#ifdef PCODE_DEBUG + fprintf(stderr,"Unlinking: "); + printpCode(stderr, pc); +#endif if(pc->prev) pc->prev->next = pc->next; if(pc->next) @@ -2169,13 +2449,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); } @@ -2196,41 +2497,60 @@ void pBlockRegs(FILE *of, pBlock *pb) /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ -char *get_op(pCodeOp *pcop) +char *get_op(pCodeOp *pcop,char *buffer, size_t size) { regs *r; - static char buffer[50]; + 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) { - SAFE_snprintf(&s,&size,"(((%s+%d) >> %d)&0xff)", - pcop->name, - PCOI(pcop)->index, - 8 * PCOI(pcop)->offset ); + switch(PCOI(pcop)->offset) { + case 0: + SAFE_snprintf(&s,&size,"low %s",pcop->name); + break; + case 1: + SAFE_snprintf(&s,&size,"high %s",pcop->name); + break; + default: + SAFE_snprintf(&s,&size,"(((%s+%d) >> %d)&0xff)", + pcop->name, + PCOI(pcop)->index, + 8 * PCOI(pcop)->offset ); + } } else SAFE_snprintf(&s,&size,"LOW(%s+%d)",pcop->name,PCOI(pcop)->index); } else { @@ -2239,15 +2559,25 @@ char *get_op(pCodeOp *pcop) SAFE_snprintf(&s,&size,"(%s + %d)", pcop->name, PCOI(pcop)->index ); - } else - SAFE_snprintf(&s,&size,"%s",pcop->name); + } else { + switch(PCOI(pcop)->offset) { + case 0: + SAFE_snprintf(&s,&size,"%s",pcop->name); + break; + case 1: + SAFE_snprintf(&s,&size,"high %s",pcop->name); + break; + default: + SAFE_snprintf(&s,&size,"(%s >> %d)&0xff",pcop->name, 8*PCOI(pcop)->offset); + } + } } return buffer; case PO_DIR: s = buffer; - size = sizeof(buffer); + //size = sizeof(buffer); if( PCOR(pcop)->instance) { SAFE_snprintf(&s,&size,"(%s + %d)", pcop->name, @@ -2258,8 +2588,13 @@ char *get_op(pCodeOp *pcop) return buffer; default: - if (pcop->name) + if (pcop->name) { + if(use_buffer) { + SAFE_snprintf(&buffer,&size,"%s",pcop->name); + return buffer; + } return pcop->name; + } } } @@ -2274,9 +2609,12 @@ static char *get_op_from_instruction( pCodeInstruction *pcc) { if(pcc ) - return get_op(pcc->pcop); - + 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"); } @@ -2285,10 +2623,12 @@ static char *get_op_from_instruction( pCodeInstruction *pcc) static void pCodeOpPrint(FILE *of, pCodeOp *pcop) { - fprintf(of,"pcodeopprint\n"); + fprintf(of,"pcodeopprint- not implemented\n"); } -char *pCode2str(char *str, int size, pCode *pc) +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ +char *pCode2str(char *str, size_t size, pCode *pc) { char *s = str; @@ -2355,6 +2695,12 @@ char *pCode2str(char *str, int size, pCode *pc) case PC_FLOW: 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); + break; + + case PC_BAD: + SAFE_snprintf(&s,&size,";A bad pCode is being used\n"); } return str; @@ -2390,6 +2736,8 @@ static void genericPrint(FILE *of, pCode *pc) } } + if(PCI(pc)->cline) + genericPrint(of,PCODE(PCI(pc)->cline)); { char str[256]; @@ -2399,9 +2747,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 { @@ -2443,9 +2793,18 @@ 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: + fprintf(of,";#CSRC\t%s %d\n; %s\n", PCCS(pc)->file_name, PCCS(pc)->line_number, PCCS(pc)->line); + break; case PC_LABEL: default: fprintf(of,"unknown pCode type %d\n",pc->type); @@ -2523,8 +2882,12 @@ static void unlinkpCodeFromBranch(pCode *pcl , pCode *pc) } + //fprintf (stderr, "%s \n",__FUNCTION__); + //pcl->print(stderr,pcl); + //pc->print(stderr,pc); while(b) { if(b->pc == pc) { + //fprintf (stderr, "found label\n"); /* Found a label */ if(bprev) { @@ -2541,41 +2904,20 @@ static void unlinkpCodeFromBranch(pCode *pcl , pCode *pc) b = b->next; } -#if 0 - - original stuff: - - bprev = NULL; - b = pcl->label; - 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); - pcl->label = b->next; /* First pCode in chain */ - free(b); - } - return; /* A label can't occur more than once */ - } - bprev = b; - b = b->next; - } -#endif } /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ -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; @@ -2710,10 +3052,14 @@ 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 +/*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ int compareLabel(pCode *pc, pCodeOpLabel *pcop_label) { @@ -2737,6 +3083,42 @@ int compareLabel(pCode *pc, pCodeOpLabel *pcop_label) return FALSE; } +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ +int checkLabel(pCode *pc) +{ + pBranch *pbr; + + if(pc && isPCI(pc)) { + pbr = PCI(pc)->label; + while(pbr) { + if(isPCL(pbr->pc) && (PCL(pbr->pc)->key >= 0)) + return TRUE; + + pbr = pbr->next; + } + } + + return FALSE; +} + +/*-----------------------------------------------------------------*/ +/* findLabelinpBlock - Search the pCode for a particular label */ +/*-----------------------------------------------------------------*/ +pCode * findLabelinpBlock(pBlock *pb,pCodeOpLabel *pcop_label) +{ + pCode *pc; + + if(!pb) + return NULL; + + for(pc = pb->pcHead; pc; pc = pc->next) + if(compareLabel(pc,pcop_label)) + return pc; + + return NULL; +} + /*-----------------------------------------------------------------*/ /* findLabel - Search the pCode for a particular label */ /*-----------------------------------------------------------------*/ @@ -2749,10 +3131,8 @@ pCode * findLabel(pCodeOpLabel *pcop_label) return NULL; for(pb = the_pFile->pbHead; pb; pb = pb->next) { - for(pc = pb->pcHead; pc; pc = pc->next) - if(compareLabel(pc,pcop_label)) - return pc; - + if( (pc = findLabelinpBlock(pb,pcop_label)) != NULL) + return pc; } fprintf(stderr,"Couldn't find label %s", pcop_label->pcop.name); @@ -2796,12 +3176,14 @@ pCode * findPrevpCode(pCode *pc, PC_TYPE pct) /* findNextInstruction - given a pCode, find the next instruction */ /* in the linked list */ /*-----------------------------------------------------------------*/ -pCode * findNextInstruction(pCode *pc) +pCode * findNextInstruction(pCode *pci) { + pCode *pc = pci; while(pc) { if((pc->type == PC_OPCODE) || (pc->type == PC_WILD)) return pc; + #ifdef PCODE_DEBUG fprintf(stderr,"findNextInstruction: "); printpCode(stderr, pc); @@ -2813,9 +3195,18 @@ pCode * findNextInstruction(pCode *pc) return NULL; } +/*-----------------------------------------------------------------*/ +/* findNextInstruction - given a pCode, find the next instruction */ +/* in the linked list */ +/*-----------------------------------------------------------------*/ +pCode * findPrevInstruction(pCode *pci) +{ + return findPrevpCode(pci, PC_OPCODE); +} + /*-----------------------------------------------------------------*/ /* findFunctionEnd - given a pCode find the end of the function */ -/* that contains it t */ +/* that contains it */ /*-----------------------------------------------------------------*/ pCode * findFunctionEnd(pCode *pc) { @@ -2873,6 +3264,7 @@ static void AnalyzeRETURN(pCode *pc) /*-----------------------------------------------------------------*/ regs * getRegFromInstruction(pCode *pc) { + if(!pc || !isPCI(pc) || !PCI(pc)->pcop || @@ -2882,7 +3274,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: @@ -2890,8 +3284,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; @@ -2949,10 +3347,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); @@ -2982,7 +3381,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; @@ -3003,7 +3403,7 @@ void BuildFlow(pBlock *pb) { pCode *pc; pCode *last_pci=NULL; - pCode *pflow; + pCode *pflow=NULL; int seq = 0; if(!pb) @@ -3012,34 +3412,69 @@ 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=findNextInstruction(pc)) != NULL; ) { + for( pc = findNextInstruction(pb->pcHead); + pc != NULL; + pc=findNextInstruction(pc)) { pc->seq = seq++; PCI(pc)->pcflow = PCFL(pflow); - if(PCI(pc)->isSkip || PCI(pc)->isBranch) { + //fprintf(stderr," build: "); + //pflow->print(stderr,pflow); + + if( PCI(pc)->isSkip) { + + /* The two instructions immediately following this one + * mark the beginning of a new flow segment */ + + while(pc && PCI(pc)->isSkip) { + + PCI(pc)->pcflow = PCFL(pflow); + pc->seq = seq-1; + seq = 1; + + InsertpFlow(pc, &pflow); + pc=findNextInstruction(pc->next); + } + + seq = 0; + + if(!pc) + break; + + PCI(pc)->pcflow = PCFL(pflow); + pc->seq = 0; + InsertpFlow(pc, &pflow); - /* The instruction immediately following this one - * marks the beginning of a new flow segment */ + } else if ( PCI(pc)->isBranch && !checkLabel(findNextInstruction(pc->next))) { InsertpFlow(pc, &pflow); seq = 0; - - } else if (PCI_HAS_LABEL(pc)) { + + } else if (checkLabel(pc)) { /* This instruction marks the beginning of a * new flow segment */ pc->seq = 0; - seq = 1; - InsertpFlow(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); @@ -3049,21 +3484,58 @@ void BuildFlow(pBlock *pb) } //fprintf (stderr,",end seq %d",GpcFlowSeq); - PCFL(pflow)->end = pb->pcTail; + if(pflow) + PCFL(pflow)->end = pb->pcTail; } +/*-------------------------------------------------------------------*/ +/* unBuildFlow(pBlock *pb) - examine the code in a pBlock and build */ +/* the flow blocks. */ +/* + * unBuildFlow removes pCodeFlow objects from a pCode chain + */ /*-----------------------------------------------------------------*/ -/*-----------------------------------------------------------------*/ -void dumpCond(int cond) +void unBuildFlow(pBlock *pb) { + pCode *pc,*pcnext; - static char *pcc_str[] = { - //"PCC_NONE", - "PCC_REGISTER", - "PCC_C", - "PCC_Z", - "PCC_DC", - "PCC_W", + if(!pb) + return; + + pc = pb->pcHead; + + while(pc) { + pcnext = pc->next; + + if(isPCI(pc)) { + + pc->seq = 0; + if(PCI(pc)->pcflow) { + //free(PCI(pc)->pcflow); + PCI(pc)->pcflow = NULL; + } + + } else if(isPCFL(pc) ) + pc->destruct(pc); + + pc = pcnext; + } + + +} + +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ +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", @@ -3084,119 +3556,185 @@ void dumpCond(int cond) /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ -void FillFlow(pCodeFlow *pcflow) +void FlowStats(pCodeFlow *pcflow) { pCode *pc; - int cur_bank; if(!isPCFL(pcflow)) return; - // fprintf(stderr, " FillFlow - flow block (seq=%d)\n", pcflow->pc.seq); + fprintf(stderr, " FlowStats - flow block (seq=%d)\n", pcflow->pc.seq); pc = findNextpCode(PCODE(pcflow), PC_OPCODE); + if(!pc) { - // fprintf(stderr, " FillFlow - empty flow (seq=%d)\n", pcflow->pc.seq); + fprintf(stderr, " FlowStats - empty flow (seq=%d)\n", pcflow->pc.seq); return; } - cur_bank = -1; - do { - //regs *reg; + fprintf(stderr, " FlowStats inCond: "); + dumpCond(pcflow->inCond); + fprintf(stderr, " FlowStats outCond: "); + dumpCond(pcflow->outCond); - 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; +/*-----------------------------------------------------------------* + * int isBankInstruction(pCode *pc) - examine the pCode *pc to determine + * if it affects the banking bits. + * + * return: -1 == Banking bits are unaffected by this pCode. + * + * return: > 0 == Banking bits are affected. + * + * If the banking bits are affected, then the returned value describes + * which bits are affected and how they're affected. The lower half + * of the integer maps to the bits that are affected, the upper half + * to whether they're set or cleared. + * + *-----------------------------------------------------------------*/ +#define SET_BANK_BIT (1 << 16) +#define CLR_BANK_BIT 0 - default: - fprintf(stderr, " FillFlow - Status register is getting Modified by:\n"); - genericPrint(stderr, pc); - } +int isBankInstruction(pCode *pc) +{ + regs *reg; + int bank = -1; + + if(!isPCI(pc)) + return -1; + + if( ( (reg = getRegFromInstruction(pc)) != NULL) && isSTATUS_REG(reg)) { + + /* 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, " isBankInstruction - Set RP0\n"); + return SET_BANK_BIT | PIC_RP0_BIT; } - } else - inCond |= PCC_REG_BANK0 << (REG_BANK(reg) & 3); + if(PCORB(pcop)->bit == PIC_RP1_BIT) { + //fprintf(stderr, " isBankInstruction - Set RP1\n"); + return CLR_BANK_BIT | PIC_RP0_BIT; + } + break; + + case POC_BCF: + if(PCORB(pcop)->bit == PIC_RP0_BIT) { + //fprintf(stderr, " isBankInstruction - Clr RP0\n"); + return CLR_BANK_BIT | PIC_RP1_BIT; + } + if(PCORB(pcop)->bit == PIC_RP1_BIT) { + //fprintf(stderr, " isBankInstruction - Clr RP1\n"); + return CLR_BANK_BIT | PIC_RP1_BIT; + } + break; + default: + //fprintf(stderr, " isBankInstruction - Status register is getting Modified by:\n"); + //genericPrint(stderr, pc); + ; + } } -#endif - pcflow->inCond |= (inCond & ~pcflow->outCond); - pcflow->outCond |= outCond; + } - + return bank; +} - pc = findNextpCode(pc->next, PC_OPCODE); - } while (pc && (pc != pcflow->end)); +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ +void FillFlow(pCodeFlow *pcflow) +{ -#if 0 - if(!pc) - fprintf(stderr, " FillFlow - Bad end of flow\n"); + pCode *pc; + int cur_bank; + if(!isPCFL(pcflow)) + return; + + // fprintf(stderr, " FillFlow - flow block (seq=%d)\n", pcflow->pc.seq); + + pc = findNextpCode(PCODE(pcflow), PC_OPCODE); + + if(!pc) { + //fprintf(stderr, " FillFlow - empty flow (seq=%d)\n", pcflow->pc.seq); + return; + } + + cur_bank = -1; + + do { + isBankInstruction(pc); + pc = pc->next; + } while (pc && (pc != pcflow->end) && !isPCFL(pc)); + +/* + if(!pc ) { + fprintf(stderr, " FillFlow - Bad end of flow\n"); + } else { + fprintf(stderr, " FillFlow - Ending flow with\n "); + pc->print(stderr,pc); + } fprintf(stderr, " FillFlow inCond: "); dumpCond(pcflow->inCond); fprintf(stderr, " FillFlow outCond: "); dumpCond(pcflow->outCond); -#endif +*/ } + /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ void LinkFlow_pCode(pCodeInstruction *from, pCodeInstruction *to) { + pCodeFlowLink *fromLink, *toLink; if(!from || !to || !to->pcflow || !from->pcflow) return; - addSet(&(from->pcflow->to), to->pcflow); - addSet(&(to->pcflow->from), from->pcflow); + fromLink = newpCodeFlowLink(from->pcflow); + toLink = newpCodeFlowLink(to->pcflow); + + addSetIfnotP(&(from->pcflow->to), toLink); //to->pcflow); + addSetIfnotP(&(to->pcflow->from), fromLink); //from->pcflow); } -/*-----------------------------------------------------------------*/ -/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------* + * 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; pCode *pcflow; pCode *pct; - + //fprintf(stderr,"linkflow \n"); + for( pcflow = findNextpCode(pb->pcHead, PC_FLOW); - (pcflow = findNextpCode(pcflow, PC_FLOW)) != NULL; - pcflow = pcflow->next) { + pcflow != NULL; + pcflow = findNextpCode(pcflow->next, PC_FLOW) ) { if(!isPCFL(pcflow)) fprintf(stderr, "LinkFlow - pcflow is not a flow object "); + //fprintf(stderr," link: "); + //pcflow->print(stderr,pcflow); + //FillFlow(PCFL(pcflow)); pc = PCFL(pcflow)->end; @@ -3204,6 +3742,7 @@ void LinkFlow(pBlock *pb) //fprintf(stderr, "LinkFlow - flow block (seq=%d) ", pcflow->seq); if(isPCI_SKIP(pc)) { //fprintf(stderr, "ends with skip\n"); + //pc->print(stderr,pc); pct=findNextInstruction(pc->next); LinkFlow_pCode(PCI(pc),PCI(pct)); pct=findNextInstruction(pct->next); @@ -3212,34 +3751,567 @@ void LinkFlow(pBlock *pb) } if(isPCI_BRANCH(pc)) { - //fprintf(stderr, "ends with branch\n"); + pCodeOpLabel *pcol = PCOLAB(PCI(pc)->pcop); + + //fprintf(stderr, "ends with branch\n "); + //pc->print(stderr,pc); + + if(!(pcol && isPCOLAB(pcol))) { + 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__); + } + continue; + } + + if( (pct = findLabelinpBlock(pb,pcol)) != NULL) + LinkFlow_pCode(PCI(pc),PCI(pct)); + else + 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; } -#if 0 + + if(isPCI(pc)) { + //fprintf(stderr, "ends with non-branching instruction:\n"); + //pc->print(stderr,pc); + + LinkFlow_pCode(PCI(pc),PCI(findNextInstruction(pc->next))); + + continue; + } + if(pc) { - fprintf(stderr, "has an unrecognized ending:\n"); - pc->print(stderr,pc); + //fprintf(stderr, "ends with unknown\n"); + //pc->print(stderr,pc); + continue; } - else - fprintf(stderr, "has no end pcode\n"); -#endif + + //fprintf(stderr, "ends with nothing: ERROR\n"); } } +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ + +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ +int isPCinFlow(pCode *pc, pCode *pcflow) +{ + + if(!pc || !pcflow) + return 0; + + if(!isPCI(pc) || !PCI(pc)->pcflow || !isPCFL(pcflow) ) + return 0; + + if( PCI(pc)->pcflow->pc.seq == pcflow->seq) + return 1; + + return 0; +} + +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ +void BanksUsedFlow2(pCode *pcflow) +{ + pCode *pc=NULL; + + int bank = -1; + bool RegUsed = 0; + + regs *reg; + + if(!isPCFL(pcflow)) { + fprintf(stderr, "BanksUsed - pcflow is not a flow object "); + return; + } + + pc = findNextInstruction(pcflow->next); + + PCFL(pcflow)->lastBank = -1; + + while(isPCinFlow(pc,pcflow)) { + + int bank_selected = isBankInstruction(pc); + + //if(PCI(pc)->pcflow) + //fprintf(stderr,"BanksUsedFlow2, looking at seq %d\n",PCI(pc)->pcflow->pc.seq); + + if(bank_selected > 0) { + //fprintf(stderr,"BanksUsed - mucking with bank %d\n",bank_selected); + + /* This instruction is modifying banking bits before accessing registers */ + if(!RegUsed) + PCFL(pcflow)->firstBank = -1; + + if(PCFL(pcflow)->lastBank == -1) + PCFL(pcflow)->lastBank = 0; + + bank = (1 << (bank_selected & (PIC_RP0_BIT | PIC_RP1_BIT))); + if(bank_selected & SET_BANK_BIT) + PCFL(pcflow)->lastBank |= bank; + + + } else { + reg = getRegFromInstruction(pc); + + if(reg && !isREGinBank(reg, bank)) { + int allbanks = REGallBanks(reg); + if(bank == -1) + PCFL(pcflow)->firstBank = allbanks; + + PCFL(pcflow)->lastBank = allbanks; + + bank = allbanks; + } + RegUsed = 1; + } + + pc = findNextInstruction(pc->next); + } + +// fprintf(stderr,"BanksUsedFlow2 flow seq=%3d, first bank = 0x%03x, Last bank 0x%03x\n", +// pcflow->seq,PCFL(pcflow)->firstBank,PCFL(pcflow)->lastBank); + + + +} +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ +void BanksUsedFlow(pBlock *pb) +{ + pCode *pcflow; + + + //pb->pcHead->print(stderr, pb->pcHead); + + pcflow = findNextpCode(pb->pcHead, PC_FLOW); + //pcflow->print(stderr,pcflow); + + for( pcflow = findNextpCode(pb->pcHead, PC_FLOW); + pcflow != NULL; + pcflow = findNextpCode(pcflow->next, PC_FLOW) ) { + + BanksUsedFlow2(pcflow); + } + +} + + +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ +void insertBankSwitch(int position, pCode *pc, int Set_Clear, int RP_BankBit) +{ + pCode *new_pc; + + if(!pc) + return; + + if(RP_BankBit < 0) + new_pc = newpCode(POC_CLRF, popCopyReg(&pc_status)); + else + new_pc = newpCode((Set_Clear ? POC_BSF : POC_BCF), + popCopyGPR2Bit(PCOP(&pc_status),RP_BankBit)); + + 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 */ + + if(PCI(pc)->label) { + PCI(new_pc)->label = PCI(pc)->label; + PCI(pc)->label = NULL; + } + + /* The new instruction has the same pcflow block */ + PCI(new_pc)->pcflow = PCI(pc)->pcflow; + +} +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ +void FixRegisterBankingInFlow(pCodeFlow *pcfl, int cur_bank) +{ + pCode *pc=NULL; + pCode *pcprev=NULL; + pCode *new_pc; + + regs *reg; + + if(!pcfl) + return; + + pc = findNextInstruction(pcfl->pc.next); + + while(isPCinFlow(pc,PCODE(pcfl))) { + + 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) || + ((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; + 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; + 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 { + //fprintf(stderr, "Bummer can't switch banks\n"); + ; + } + } + + pcprev = pc; + pc = findNextInstruction(pc->next); + + } + + if(pcprev && cur_bank) { + /* Brute force - make sure that we point to bank 0 at the + * end of each flow block */ + new_pc = newpCode(POC_BCF, + popCopyGPR2Bit(PCOP(&pc_status),PIC_RP0_BIT)); + pCodeInsertAfter(pcprev, new_pc); + cur_bank = 0; + } + +} + +/*-----------------------------------------------------------------*/ +/*int compareBankFlow - compare the banking requirements between */ +/* flow objects. */ +/*-----------------------------------------------------------------*/ +int compareBankFlow(pCodeFlow *pcflow, pCodeFlowLink *pcflowLink, int toORfrom) +{ + + if(!pcflow || !pcflowLink || !pcflowLink->pcflow) + return 0; + + if(!isPCFL(pcflow) || !isPCFL(pcflowLink->pcflow)) + return 0; + + if(pcflow->firstBank == -1) + return 0; + + + if(pcflowLink->pcflow->firstBank == -1) { + pCodeFlowLink *pctl = setFirstItem( toORfrom ? + pcflowLink->pcflow->to : + pcflowLink->pcflow->from); + return compareBankFlow(pcflow, pctl, toORfrom); + } + + if(toORfrom) { + if(pcflow->lastBank == pcflowLink->pcflow->firstBank) + return 0; + + pcflowLink->bank_conflict++; + pcflowLink->pcflow->FromConflicts++; + pcflow->ToConflicts++; + } else { + + if(pcflow->firstBank == pcflowLink->pcflow->lastBank) + return 0; + + pcflowLink->bank_conflict++; + pcflowLink->pcflow->ToConflicts++; + pcflow->FromConflicts++; + + } + /* + fprintf(stderr,"compare flow found conflict: seq %d from conflicts %d, to conflicts %d\n", + pcflowLink->pcflow->pc.seq, + pcflowLink->pcflow->FromConflicts, + pcflowLink->pcflow->ToConflicts); + */ + return 1; + +} +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ +void FixBankFlow(pBlock *pb) +{ + pCode *pc=NULL; + pCode *pcflow; + pCodeFlowLink *pcfl; + + pCode *pcflow_max_To=NULL; + pCode *pcflow_max_From=NULL; + int max_ToConflicts=0; + int max_FromConflicts=0; + + //fprintf(stderr,"Fix Bank flow \n"); + pcflow = findNextpCode(pb->pcHead, PC_FLOW); + + + /* + First loop through all of the flow objects in this pcode block + and fix the ones that have banking conflicts between the + entry and exit. + */ + + //fprintf(stderr, "FixBankFlow - Phase 1\n"); + + for( pcflow = findNextpCode(pb->pcHead, PC_FLOW); + pcflow != NULL; + pcflow = findNextpCode(pcflow->next, PC_FLOW) ) { + + if(!isPCFL(pcflow)) { + fprintf(stderr, "FixBankFlow - pcflow is not a flow object "); + continue; + } + + if(PCFL(pcflow)->firstBank != PCFL(pcflow)->lastBank && + PCFL(pcflow)->firstBank >= 0 && + PCFL(pcflow)->lastBank >= 0 ) { + + int cur_bank = (PCFL(pcflow)->firstBank < PCFL(pcflow)->lastBank) ? + PCFL(pcflow)->firstBank : PCFL(pcflow)->lastBank; + + FixRegisterBankingInFlow(PCFL(pcflow),cur_bank); + BanksUsedFlow2(pcflow); + + } + } + + //fprintf(stderr, "FixBankFlow - Phase 2\n"); + + for( pcflow = findNextpCode(pb->pcHead, PC_FLOW); + pcflow != NULL; + pcflow = findNextpCode(pcflow->next, PC_FLOW) ) { + + int nFlows; + int nConflicts; + + if(!isPCFL(pcflow)) { + fprintf(stderr, "FixBankFlow - pcflow is not a flow object "); + continue; + } + + PCFL(pcflow)->FromConflicts = 0; + PCFL(pcflow)->ToConflicts = 0; + + nFlows = 0; + nConflicts = 0; + + //fprintf(stderr, " FixBankFlow flow seq %d\n",pcflow->seq); + pcfl = setFirstItem(PCFL(pcflow)->from); + while (pcfl) { + + pc = PCODE(pcfl->pcflow); + + if(!isPCFL(pc)) { + fprintf(stderr,"oops dumpflow - to is not a pcflow\n"); + pc->print(stderr,pc); + } + + nConflicts += compareBankFlow(PCFL(pcflow), pcfl, 0); + nFlows++; + + pcfl=setNextItem(PCFL(pcflow)->from); + } + + if((nFlows >= 2) && nConflicts && (PCFL(pcflow)->firstBank>0)) { + //fprintf(stderr, " From conflicts flow seq %d, nflows %d ,nconflicts %d\n",pcflow->seq,nFlows, nConflicts); + + FixRegisterBankingInFlow(PCFL(pcflow),0); + BanksUsedFlow2(pcflow); + + continue; /* Don't need to check the flow from here - it's already been fixed */ + + } + + nFlows = 0; + nConflicts = 0; + + pcfl = setFirstItem(PCFL(pcflow)->to); + while (pcfl) { + + pc = PCODE(pcfl->pcflow); + if(!isPCFL(pc)) { + fprintf(stderr,"oops dumpflow - to is not a pcflow\n"); + pc->print(stderr,pc); + } + + nConflicts += compareBankFlow(PCFL(pcflow), pcfl, 1); + nFlows++; + + pcfl=setNextItem(PCFL(pcflow)->to); + } + + if((nFlows >= 2) && nConflicts &&(nConflicts != nFlows) && (PCFL(pcflow)->lastBank>0)) { + //fprintf(stderr, " To conflicts flow seq %d, nflows %d ,nconflicts %d\n",pcflow->seq,nFlows, nConflicts); + + FixRegisterBankingInFlow(PCFL(pcflow),0); + BanksUsedFlow2(pcflow); + } + } + + /* + Loop through the flow objects again and find the ones with the + maximum conflicts + */ + + for( pcflow = findNextpCode(pb->pcHead, PC_FLOW); + pcflow != NULL; + pcflow = findNextpCode(pcflow->next, PC_FLOW) ) { + + if(PCFL(pcflow)->ToConflicts > max_ToConflicts) + pcflow_max_To = pcflow; + + if(PCFL(pcflow)->FromConflicts > max_FromConflicts) + pcflow_max_From = pcflow; + } +/* + if(pcflow_max_To) + fprintf(stderr,"compare flow Max To conflicts: seq %d conflicts %d\n", + PCFL(pcflow_max_To)->pc.seq, + PCFL(pcflow_max_To)->ToConflicts); + + if(pcflow_max_From) + fprintf(stderr,"compare flow Max From conflicts: seq %d conflicts %d\n", + PCFL(pcflow_max_From)->pc.seq, + PCFL(pcflow_max_From)->FromConflicts); +*/ +} + +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ +void DumpFlow(pBlock *pb) +{ + pCode *pc=NULL; + pCode *pcflow; + pCodeFlowLink *pcfl; + + + fprintf(stderr,"Dump flow \n"); + pb->pcHead->print(stderr, pb->pcHead); + + pcflow = findNextpCode(pb->pcHead, PC_FLOW); + pcflow->print(stderr,pcflow); + + for( pcflow = findNextpCode(pb->pcHead, PC_FLOW); + pcflow != NULL; + pcflow = findNextpCode(pcflow->next, PC_FLOW) ) { + + if(!isPCFL(pcflow)) { + fprintf(stderr, "DumpFlow - pcflow is not a flow object "); + continue; + } + fprintf(stderr,"dumping: "); + pcflow->print(stderr,pcflow); + FlowStats(PCFL(pcflow)); + + for(pcfl = setFirstItem(PCFL(pcflow)->to); pcfl; pcfl=setNextItem(PCFL(pcflow)->to)) { + + pc = PCODE(pcfl->pcflow); + + fprintf(stderr, " from seq %d:\n",pc->seq); + if(!isPCFL(pc)) { + fprintf(stderr,"oops dumpflow - from is not a pcflow\n"); + pc->print(stderr,pc); + } + + } + + for(pcfl = setFirstItem(PCFL(pcflow)->to); pcfl; pcfl=setNextItem(PCFL(pcflow)->to)) { + + pc = PCODE(pcfl->pcflow); + + fprintf(stderr, " to seq %d:\n",pc->seq); + if(!isPCFL(pc)) { + fprintf(stderr,"oops dumpflow - to is not a pcflow\n"); + pc->print(stderr,pc); + } + + } + + } + +} + /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ int OptimizepBlock(pBlock *pb) { - pCode *pc; + pCode *pc, *pcprev; int matches =0; if(!pb || !peepOptimizing) return 0; DFPRINTF((stderr," Optimizing pBlock: %c\n",getpBlock_dbName(pb))); +/* for(pc = pb->pcHead; pc; pc = pc->next) matches += pCodePeepMatchRule(pc); +*/ + + pc = findNextInstruction(pb->pcHead); + if(!pc) + return 0; + + pcprev = pc->prev; + do { + + + if(pCodePeepMatchRule(pc)) { + + matches++; + + if(pcprev) + pc = findNextInstruction(pcprev->next); + else + pc = findNextInstruction(pb->pcHead); + } else + pc = findNextInstruction(pc->next); + } while(pc); + if(matches) DFPRINTF((stderr," Optimizing pBlock: %c - matches=%d\n",getpBlock_dbName(pb),matches)); return matches; @@ -3266,6 +4338,44 @@ pCode * findInstructionUsingLabel(pCodeLabel *pcl, pCode *pcs) return NULL; } +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ +void exchangeLabels(pCodeLabel *pcl, pCode *pc) +{ + + char *s=NULL; + + if(isPCI(pc) && + (PCI(pc)->pcop) && + (PCI(pc)->pcop->type == PO_LABEL)) { + + pCodeOpLabel *pcol = PCOLAB(PCI(pc)->pcop); + + //fprintf(stderr,"changing label key from %d to %d\n",pcol->key, pcl->key); + if(pcol->pcop.name) + free(pcol->pcop.name); + + /* 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); + + } + + +} + /*-----------------------------------------------------------------*/ /* pBlockRemoveUnusedLabels - remove the pCode labels from the */ /* pCode chain if they're not used. */ @@ -3277,26 +4387,54 @@ void pBlockRemoveUnusedLabels(pBlock *pb) if(!pb) return; + for(pc = pb->pcHead; (pc=findNextInstruction(pc->next)) != NULL; ) { + + pBranch *pbr = PCI(pc)->label; + if(pbr && pbr->next) { + pCode *pcd = pb->pcHead; + + //fprintf(stderr, "multiple labels\n"); + //pc->print(stderr,pc); + + pbr = pbr->next; + while(pbr) { + + while ( (pcd = findInstructionUsingLabel(PCL(PCI(pc)->label->pc), pcd)) != NULL) { + //fprintf(stderr,"Used by:\n"); + //pcd->print(stderr,pcd); + + exchangeLabels(PCL(pbr->pc),pcd); + + pcd = pcd->next; + } + pbr = pbr->next; + } + } + } + for(pc = pb->pcHead; pc; pc = pc->next) { - if(pc->type == PC_LABEL) + if(isPCL(pc)) // pc->type == PC_LABEL) pcl = PCL(pc); - else if ((pc->type == PC_OPCODE) && PCI(pc)->label) + else if (isPCI(pc) && PCI(pc)->label) //((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 - * refers to it */ + //fprintf(stderr," found A LABEL !!! key = %d, %s\n", pcl->key,pcl->label); + + /* This pCode is a label, so search the pBlock to see if anyone + * refers to it */ if( (pcl->key>0) && (!findInstructionUsingLabel(pcl, pb->pcHead))) { + //if( !findInstructionUsingLabel(pcl, pb->pcHead)) { /* Couldn't find an instruction that refers to this label * So, unlink the pCode label from it's pCode chain * and destroy the label */ + //fprintf(stderr," removed A LABEL !!! key = %d, %s\n", pcl->key,pcl->label); - DFPRINTF((stderr," !!! REMOVED A LABEL !!! key = %d\n", pcl->key)); - + 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)); @@ -3330,35 +4468,52 @@ 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) { + + //fprintf(stderr," checking merging label %s\n",PCL(pc)->label); //fprintf(stderr,"Checking label key = %d\n",PCL(pc)->key); - if( !(pcnext = findNextInstruction(pc)) ) - return; // Couldn't find an instruction associated with this label - - // Unlink the pCode label from it's pCode chain - unlinkPC(pc); - - //fprintf(stderr,"Merged label key = %d\n",PCL(pc)->key); - // And link it into the instruction's pBranch labels. (Note, since - // it's possible to have multiple labels associated with one instruction - // we must provide a means to accomodate the additional labels. Thus - // the labels are placed into the singly-linked list "label" as - // opposed to being a single member of the pCodeInstruction.) - - //_ALLOC(pbr,sizeof(pBranch)); - pbr = Safe_calloc(1,sizeof(pBranch)); - pbr->pc = pc; - pbr->next = NULL; - - PCI(pcnext)->label = pBranchAppend(PCI(pcnext)->label,pbr); - if(pcnext->prev) - pc = pcnext->prev; - else - pc = pcnext; - } + if((pcnext = findNextInstruction(pc) )) { + + // Unlink the pCode label from it's pCode chain + unlinkpCode(pc); + + //fprintf(stderr,"Merged label key = %d\n",PCL(pc)->key); + // And link it into the instruction's pBranch labels. (Note, since + // it's possible to have multiple labels associated with one instruction + // we must provide a means to accomodate the additional labels. Thus + // the labels are placed into the singly-linked list "label" as + // opposed to being a single member of the pCodeInstruction.) + //_ALLOC(pbr,sizeof(pBranch)); + pbr = Safe_calloc(1,sizeof(pBranch)); + pbr->pc = pc; + pbr->next = NULL; + + PCI(pcnext)->label = pBranchAppend(PCI(pcnext)->label,pbr); + + } else { + fprintf(stderr, "WARNING: couldn't associate label %s with an instruction\n",PCL(pc)->label); + } + } else if(pc->type == PC_CSOURCE) { + + /* merge the source line symbolic info into the next instruction */ + if((pcnext = findNextInstruction(pc) )) { + + // Unlink the pCode label from it's pCode chain + unlinkpCode(pc); + PCI(pcnext)->cline = PCCS(pc); + //fprintf(stderr, "merging CSRC\n"); + //genericPrint(stderr,pcnext); + } + + } + pc = pcn; } pBlockRemoveUnusedLabels(pb); @@ -3366,7 +4521,7 @@ void pBlockMergeLabels(pBlock *pb) /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ -void OptimizepCode(char dbName) +int OptimizepCode(char dbName) { #define MAX_PASSES 4 @@ -3375,11 +4530,12 @@ void OptimizepCode(char dbName) pBlock *pb; if(!the_pFile) - return; + return 0; DFPRINTF((stderr," Optimizing pCode\n")); do { + matches = 0; for(pb = the_pFile->pbHead; pb; pb = pb->next) { if('*' == dbName || getpBlock_dbName(pb) == dbName) matches += OptimizepBlock(pb); @@ -3387,6 +4543,7 @@ void OptimizepCode(char dbName) } while(matches && ++passes < MAX_PASSES); + return matches; } /*-----------------------------------------------------------------*/ @@ -3430,88 +4587,177 @@ 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 */ + //pc = findNextpCode(pb->pcHead, PC_FLOW); + pc = findNextpCode(pb->pcHead, PC_OPCODE); + if(!pc) + return; + /* loop through all of the flow blocks with in one pblock */ + + //fprintf(stderr,"Register banking\n"); + cur_bank = 0; + do { + /* at this point, pc should point to a PC_FLOW object */ + + + /* for each flow block, determine the register banking + requirements */ + + // do { + if(isPCI(pc)) { + //genericPrint(stderr, pc); + + reg = getRegFromInstruction(pc); +#if 0 + if(reg) { + fprintf(stderr, " %s ",reg->name); + 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) || + ((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; + 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 { + //fprintf(stderr, "Bummer can't switch banks\n"); + ; + } + } + + pcprev = pc; + + } + + pc = pc->next; + // } while(pc && !(isPCFL(pc))); + + + }while (pc); + + 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; - //fprintf(stderr,"Register banking\n"); - cur_bank = 0; - do { - /* at this point, pc should point to a PC_FLOW object */ + } +/* + 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"); + } +} - /* for each flow block, determine the register banking - requirements */ - 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 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); - //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); - */ - } + 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 { - //fprintf(stderr, "Bummer can't switch banks\n"); - ; - } - } - } + } +#endif - 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; - } - }while (pc); -} void pBlockDestruct(pBlock *pb) { @@ -3567,12 +4813,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; @@ -3580,6 +4832,27 @@ 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 + * and register banking is fixed. + */ + + //for(pb = the_pFile->pbHead; pb; pb = pb->next) + //FixRegisterBanking(pb); + /* Phase 2 - Flow Analysis * * In this phase, the pCode is partition into pCodeFlow @@ -3591,6 +4864,7 @@ void AnalyzeBanking(void) 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 @@ -3600,9 +4874,41 @@ void AnalyzeBanking(void) for(pb = the_pFile->pbHead; pb; pb = pb->next) LinkFlow(pb); + /* Phase 3 - Flow Analysis - Flow Tree + * + * In this phase, the individual flow blocks are examined + * to determine their order of excution. + */ + for(pb = the_pFile->pbHead; pb; pb = pb->next) - FixRegisterBanking(pb); + BuildFlowTree(pb); + + + /* Phase x - Flow Analysis - Used Banks + * + * In this phase, the individual flow blocks are examined + * to determine the Register Banks they use + */ + + for(pb = the_pFile->pbHead; pb; pb = pb->next) + 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); +*/ /* debug stuff */ for(pb = the_pFile->pbHead; pb; pb = pb->next) { pCode *pcflow; @@ -3614,6 +4920,51 @@ void AnalyzeBanking(void) } } +/* + 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) { + + FlowStats(PCFL(pcflow)); + } + } +*/ +} + +/*-----------------------------------------------------------------*/ +/* 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); } @@ -3663,7 +5014,7 @@ void buildCallTree(void ) for(pb = the_pFile->pbHead; pb; pb = pb->next) { pCode *pc_fstart=NULL; for(pc = pb->pcHead; pc; pc = pc->next) { - if(isPCF(pc)) { //pc->type == PC_FUNCTION) { + if(isPCF(pc)) { if (PCF(pc)->fname) { if(STRCASECMP(PCF(pc)->fname, "_main") == 0) { @@ -3672,7 +5023,6 @@ void buildCallTree(void ) pb->dbName = 'M'; } - //_ALLOC(pbr,sizeof(pBranch)); pbr = Safe_calloc(1,sizeof(pBranch)); pbr->pc = pc_fstart = pc; pbr->next = NULL; @@ -3690,7 +5040,7 @@ void buildCallTree(void ) addSet(&pb->function_exits, pc); } - } else if(isCALL(pc)) {// if(pc->type == PC_OPCODE && PCI(pc)->op == POC_CALL) { + } else if(isCALL(pc)) { addSet(&pb->function_calls,pc); } } @@ -3699,7 +5049,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) @@ -3742,25 +5093,23 @@ void AnalyzepCode(char dbName) do { DFPRINTF((stderr," Analyzing pCode: PASS #%d\n",i+1)); + //fprintf(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)); + //fprintf(stderr," analyze and merging block %c\n",dbName); pBlockMergeLabels(pb); AnalyzepBlock(pb); + } else { + DFPRINTF((stderr," skipping block analysis dbName=%c blockname=%c\n",dbName,getpBlock_dbName)); } } - changes = 0; + changes = OptimizepCode(dbName); - for(pb = the_pFile->pbHead; pb; pb = pb->next) { - if('*' == dbName || getpBlock_dbName(pb) == dbName) - changes += OptimizepBlock(pb); - } - } while(changes && (i++ < MAX_PASSES)); buildCallTree(); @@ -3869,6 +5218,7 @@ void pBlockStats(FILE *of, pBlock *pb) /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ +#if 0 static void sequencepCode(void) { pBlock *pb; @@ -3884,6 +5234,7 @@ static void sequencepCode(void) } } +#endif /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ @@ -4006,10 +5357,10 @@ void pct2(FILE *of,pBlock *pb,int indent) // set *registersInCallPath = NULL; if(!of) - return;// registers; + return; if(indent > 10) - return; // registers; //recursion ? + return; //recursion ? pc = setFirstItem(pb->function_entries); @@ -4044,77 +5395,6 @@ void pct2(FILE *of,pBlock *pb,int indent) } -#if 0 - fprintf(stderr,"pBlock before register optim.\n"); - pBlockStats(stderr,pb); // debug - - 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 using here */ - - regs *r1,*r2, *newreg; - - fprintf(stderr,"comparing registers\n"); - - r1 = setFirstItem(registersInCallPath); - while(r1) { - - r2 = setFirstItem(pb->registers); - - while(r2) { - - if(r2->rIdx == r1->rIdx) { - newreg = pic14_findFreeReg(); - - - if(!newreg) { - fprintf(stderr,"Bummer, no more registers.\n"); - exit(1); - } - - fprintf(stderr,"Cool found register collision nIdx=%d moving to %d\n", - r1->rIdx, newreg->rIdx); - r2->rIdx = newreg->rIdx; - //if(r2->name) free(r2->name); - if(newreg->name) - r2->name = Safe_strdup(newreg->name); - else - r2->name = NULL; - newreg->isFree = 0; - newreg->wasUsed = 1; - } - r2 = setNextItem(pb->registers); - } - - r1 = setNextItem(registersInCallPath); - } - - /* Collisions have been resolved. Now free the registers in the call path */ - r1 = setFirstItem(registersInCallPath); - while(r1) { - newreg = pic14_regWithIdx(r1->rIdx); - newreg->isFree = 1; - r1 = setNextItem(registersInCallPath); - } - - } else - MarkUsedRegisters(pb->registers); - - registers = unionSets(pb->registers, registersInCallPath, THROW_NONE); - - if(registers) - fprintf(stderr,"returning regs\n"); - else - fprintf(stderr,"not returning regs\n"); - - fprintf(stderr,"pBlock after register optim.\n"); - pBlockStats(stderr,pb); // debug - - - return registers; - -#endif - /*-----------------------------------------------------------------*/ /* printCallTree - writes the call tree to a file */ @@ -4161,17 +5441,6 @@ 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) { if(pb->visited) @@ -4182,3 +5451,156 @@ void printCallTree(FILE *of) fprintf(of,"block dbname: %c\n", getpBlock_dbName(pb)); } } + + + +/*-----------------------------------------------------------------*/ +/* */ +/*-----------------------------------------------------------------*/ + +void InlineFunction(pBlock *pb) +{ + pCode *pc; + pCode *pc_call; + + if(!pb) + return; + + pc = setFirstItem(pb->function_calls); + + for( ; pc; pc = setNextItem(pb->function_calls)) { + + if(isCALL(pc)) { + pCode *pcn = findFunction(get_op_from_instruction(PCI(pc))); + pCode *pct; + pCode *pce; + + pBranch *pbr; + + if(pcn && isPCF(pcn) && (PCF(pcn)->ncalled == 1)) { + + //fprintf(stderr,"Cool can inline:\n"); + //pcn->print(stderr,pcn); + + //fprintf(stderr,"recursive call Inline\n"); + InlineFunction(pcn->pb); + //fprintf(stderr,"return from recursive call Inline\n"); + + /* + At this point, *pc points to a CALL mnemonic, and + *pcn points to the function that is being called. + + To in-line this call, we need to remove the CALL + and RETURN(s), and link the function pCode in with + the CALLee pCode. + + */ + + + /* Remove the CALL */ + pc_call = pc; + pc = pc->prev; + + /* remove callee pBlock from the pBlock linked list */ + removepBlock(pcn->pb); + + pce = pcn; + while(pce) { + pce->pb = pb; + pce = pce->next; + } + + /* Remove the Function pCode */ + pct = findNextInstruction(pcn->next); + + /* Link the function with the callee */ + pc->next = pcn->next; + pcn->next->prev = pc; + + /* Convert the function name into a label */ + + pbr = Safe_calloc(1,sizeof(pBranch)); + pbr->pc = newpCodeLabel(PCF(pcn)->fname, -1); + pbr->next = NULL; + PCI(pct)->label = pBranchAppend(PCI(pct)->label,pbr); + PCI(pct)->label = pBranchAppend(PCI(pct)->label,PCI(pc_call)->label); + + /* turn all of the return's except the last into goto's */ + /* check case for 2 instruction pBlocks */ + pce = findNextInstruction(pcn->next); + while(pce) { + pCode *pce_next = findNextInstruction(pce->next); + + if(pce_next == NULL) { + /* found the last return */ + pCode *pc_call_next = findNextInstruction(pc_call->next); + + //fprintf(stderr,"found last return\n"); + //pce->print(stderr,pce); + pce->prev->next = pc_call->next; + pc_call->next->prev = pce->prev; + PCI(pc_call_next)->label = pBranchAppend(PCI(pc_call_next)->label, + PCI(pce)->label); + } + + pce = pce_next; + } + + + } + } else + fprintf(stderr,"BUG? pCode isn't a POC_CALL %d\n",__LINE__); + + } + +} + +/*-----------------------------------------------------------------*/ +/* */ +/*-----------------------------------------------------------------*/ + +void InlinepCode(void) +{ + + pBlock *pb; + pCode *pc; + + if(!the_pFile) + return; + + if(!functionInlining) + return; + + /* Loop through all of the function definitions and count the + * number of times each one is called */ + //fprintf(stderr,"inlining %d\n",__LINE__); + + for(pb = the_pFile->pbHead; pb; pb = pb->next) { + + pc = setFirstItem(pb->function_calls); + + for( ; pc; pc = setNextItem(pb->function_calls)) { + + if(isCALL(pc)) { + pCode *pcn = findFunction(get_op_from_instruction(PCI(pc))); + if(pcn && isPCF(pcn)) { + PCF(pcn)->ncalled++; + } + } else + fprintf(stderr,"BUG? pCode isn't a POC_CALL %d\n",__LINE__); + + } + } + + //fprintf(stderr,"inlining %d\n",__LINE__); + + /* Now, Loop through the function definitions again, but this + * time inline those functions that have only been called once. */ + + InlineFunction(the_pFile->pbHead); + //fprintf(stderr,"inlining %d\n",__LINE__); + + for(pb = the_pFile->pbHead; pb; pb = pb->next) + unBuildFlow(pb); + +}