X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic%2Fpcode.c;h=03ab39ad954e8cf26cba52fd6380af9da7c960ac;hb=9adc1e115a66d97399e92f57a9298cdfbe68564a;hp=94e6fe0363912f1ba60d0729e5d5cd1044342695;hpb=4c3872ef27c1263faae7d9b85c1821381646ece8;p=fw%2Fsdcc diff --git a/src/pic/pcode.c b/src/pic/pcode.c index 94e6fe03..03ab39ad 100644 --- a/src/pic/pcode.c +++ b/src/pic/pcode.c @@ -26,42 +26,25 @@ #include "pcode.h" #include "ralloc.h" + +#if defined(__BORLANDC__) || defined(_MSC_VER) +#define STRCASECMP stricmp +#else +#define STRCASECMP strcasecmp +#endif + // Eventually this will go into device dependent files: pCodeOpReg pc_status = {{PO_STATUS, "STATUS"}, -1, NULL,NULL}; pCodeOpReg pc_indf = {{PO_INDF, "INDF"}, -1, NULL,NULL}; pCodeOpReg pc_fsr = {{PO_FSR, "FSR"}, -1, NULL,NULL}; +pCodeOpReg pc_pcl = {{PO_PCL, "PCL"}, -1, NULL,NULL}; +pCodeOpReg pc_pclath = {{PO_PCLATH, "PCLATH"}, -1, NULL,NULL}; + +static int mnemonics_initialized = 0; + + +static hTab *pic14MnemonicsHash = NULL; -//static char *PIC_mnemonics[] = { -static char *scpADDLW = "ADDLW"; -static char *scpADDWF = "ADDWF"; -static char *scpANDLW = "ANDLW"; -static char *scpANDWF = "ANDWF"; -static char *scpBCF = "BCF"; -static char *scpBSF = "BSF"; -static char *scpBTFSC = "BTFSC"; -static char *scpBTFSS = "BTFSS"; -static char *scpCALL = "CALL"; -static char *scpCOMF = "COMF"; -static char *scpCLRF = "CLRF"; -static char *scpCLRW = "CLRW"; -static char *scpDECF = "DECF"; -static char *scpDECFSZ = "DECFSZ"; -static char *scpGOTO = "GOTO"; -static char *scpINCF = "INCF"; -static char *scpINCFSZ = "INCFSZ"; -static char *scpIORLW = "IORLW"; -static char *scpIORWF = "IORWF"; -static char *scpMOVF = "MOVF"; -static char *scpMOVLW = "MOVLW"; -static char *scpMOVWF = "MOVWF"; -static char *scpNEGF = "NEGF"; -static char *scpRETLW = "RETLW"; -static char *scpRETURN = "RETURN"; -static char *scpSUBLW = "SUBLW"; -static char *scpSUBWF = "SUBWF"; -static char *scpTRIS = "TRIS"; -static char *scpXORLW = "XORLW"; -static char *scpXORWF = "XORWF"; static pFile *the_pFile = NULL; @@ -72,7 +55,7 @@ static int GpCodeSequenceNumber = 1; /* Forward declarations */ /****************************************************************/ -static void unlink(pCode *pc); +static void unlinkPC(pCode *pc); static void genericAnalyze(pCode *pc); static void AnalyzeGOTO(pCode *pc); static void AnalyzeSKIP(pCode *pc); @@ -87,23 +70,704 @@ static void pCodeOpPrint(FILE *of, pCodeOp *pcop); static char *get_op( pCodeInstruction *pcc); int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd); int pCodePeepMatchRule(pCode *pc); - - -char *Safe_strdup(char *str) +void pBlockStats(FILE *of, pBlock *pb); + + +pCodeInstruction pciADDWF = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_ADDWF, + "ADDWF", + NULL, // operand + 2, // num ops + 1,0, // dest, bit instruction + (PCC_W | PCC_REGISTER), // inCond + (PCC_REGISTER | PCC_Z) // outCond +}; + +pCodeInstruction pciADDFW = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_ADDWF, + "ADDWF", + NULL, // operand + 2, // num ops + 0,0, // dest, bit instruction + (PCC_W | PCC_REGISTER), // inCond + (PCC_W | PCC_Z) // outCond +}; + +pCodeInstruction pciADDLW = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_ADDLW, + "ADDLW", + NULL, // operand + 1, // num ops + 0,0, // dest, bit instruction + PCC_W, // inCond + (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond +}; + +pCodeInstruction pciANDLW = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_ANDLW, + "ANDLW", + NULL, // operand + 1, // num ops + 0,0, // dest, bit instruction + PCC_W, // inCond + (PCC_W | PCC_Z) // outCond +}; + +pCodeInstruction pciANDWF = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_ANDWF, + "ANDWF", + NULL, // operand + 2, // num ops + 1,0, // dest, bit instruction + (PCC_W | PCC_REGISTER), // inCond + (PCC_REGISTER | PCC_Z) // outCond +}; + +pCodeInstruction pciANDFW = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_ANDWF, + "ANDWF", + NULL, // operand + 2, // num ops + 0,0, // dest, bit instruction + (PCC_W | PCC_REGISTER), // inCond + (PCC_W | PCC_Z) // outCond +}; + +pCodeInstruction pciBCF = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_BCF, + "BCF", + NULL, // operand + 2, // num ops + 0,1, // dest, bit instruction + PCC_NONE, // inCond + PCC_EXAMINE_PCOP // outCond +}; + +pCodeInstruction pciBSF = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_BSF, + "BSF", + NULL, // operand + 2, // num ops + 0,1, // dest, bit instruction + PCC_NONE, // inCond + PCC_EXAMINE_PCOP // outCond +}; + +pCodeInstruction pciBTFSC = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + AnalyzeSKIP, + genericDestruct, + genericPrint}, + POC_BTFSC, + "BTFSC", + NULL, // operand + 2, // num ops + 0,1, // dest, bit instruction + PCC_EXAMINE_PCOP, // inCond + PCC_NONE // outCond +}; + +pCodeInstruction pciBTFSS = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + AnalyzeSKIP, + genericDestruct, + genericPrint}, + POC_BTFSS, + "BTFSS", + NULL, // operand + 2, // num ops + 0,1, // dest, bit instruction + PCC_EXAMINE_PCOP, // inCond + PCC_NONE // outCond +}; + +pCodeInstruction pciCALL = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_CALL, + "CALL", + NULL, // operand + 1, // num ops + 0,0, // dest, bit instruction + PCC_NONE, // inCond + PCC_NONE // outCond +}; + +pCodeInstruction pciCOMF = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_COMF, + "COMF", + NULL, // operand + 2, // num ops + 1,0, // dest, bit instruction + PCC_REGISTER, // inCond + PCC_REGISTER // outCond +}; + +pCodeInstruction pciCOMFW = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_COMFW, + "COMF", + NULL, // operand + 2, // num ops + 0,0, // dest, bit instruction + PCC_REGISTER, // inCond + PCC_W // outCond +}; + +pCodeInstruction pciCLRF = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_CLRF, + "CLRF", + NULL, // operand + 1, // num ops + 0,0, // dest, bit instruction + PCC_REGISTER, // inCond + PCC_REGISTER // outCond +}; + +pCodeInstruction pciCLRW = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_CLRW, + "CLRW", + NULL, // operand + 0, // num ops + 0,0, // dest, bit instruction + PCC_W, // inCond + PCC_W // outCond +}; + +pCodeInstruction pciDECF = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_DECF, + "DECF", + NULL, // operand + 2, // num ops + 1,0, // dest, bit instruction + PCC_REGISTER, // inCond + PCC_REGISTER // outCond +}; + +pCodeInstruction pciDECFW = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_DECFW, + "DECF", + NULL, // operand + 2, // num ops + 0,0, // dest, bit instruction + PCC_REGISTER, // inCond + PCC_W // outCond +}; + +pCodeInstruction pciDECFSZ = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + AnalyzeSKIP, + genericDestruct, + genericPrint}, + POC_DECFSZ, + "DECFSZ", + NULL, // operand + 2, // num ops + 1,0, // dest, bit instruction + PCC_REGISTER, // inCond + PCC_REGISTER // outCond +}; + +pCodeInstruction pciDECFSZW = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + AnalyzeSKIP, + genericDestruct, + genericPrint}, + POC_DECFSZW, + "DECFSZ", + NULL, // operand + 2, // num ops + 0,0, // dest, bit instruction + PCC_REGISTER, // inCond + PCC_W // outCond +}; + +pCodeInstruction pciGOTO = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + AnalyzeGOTO, + genericDestruct, + genericPrint}, + POC_GOTO, + "GOTO", + NULL, // operand + 1, // num ops + 0,0, // dest, bit instruction + PCC_NONE, // inCond + PCC_NONE // outCond +}; + + +pCodeInstruction pciINCF = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_INCF, + "INCF", + NULL, // operand + 2, // num ops + 1,0, // dest, bit instruction + PCC_REGISTER, // inCond + PCC_REGISTER // outCond +}; + +pCodeInstruction pciINCFW = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_INCFW, + "INCF", + NULL, // operand + 2, // num ops + 0,0, // dest, bit instruction + PCC_REGISTER, // inCond + PCC_W // outCond +}; + +pCodeInstruction pciINCFSZ = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + AnalyzeSKIP, + genericDestruct, + genericPrint}, + POC_INCFSZ, + "INCFSZ", + NULL, // operand + 2, // num ops + 1,0, // dest, bit instruction + PCC_REGISTER, // inCond + PCC_REGISTER // outCond +}; + +pCodeInstruction pciINCFSZW = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + AnalyzeSKIP, + genericDestruct, + genericPrint}, + POC_INCFSZW, + "INCFSZ", + NULL, // operand + 2, // num ops + 0,0, // dest, bit instruction + PCC_REGISTER, // inCond + PCC_W // outCond +}; + +pCodeInstruction pciIORWF = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_IORWF, + "IORWF", + NULL, // operand + 2, // num ops + 1,0, // dest, bit instruction + (PCC_W | PCC_REGISTER), // inCond + (PCC_REGISTER | PCC_Z) // outCond +}; + +pCodeInstruction pciIORFW = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_IORWF, + "IORWF", + NULL, // operand + 2, // num ops + 0,0, // dest, bit instruction + (PCC_W | PCC_REGISTER), // inCond + (PCC_W | PCC_Z) // outCond +}; + +pCodeInstruction pciIORLW = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_IORLW, + "IORLW", + NULL, // operand + 1, // num ops + 0,0, // dest, bit instruction + PCC_W, // inCond + (PCC_W | PCC_Z) // outCond +}; + +pCodeInstruction pciMOVF = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_MOVF, + "MOVF", + NULL, // operand + 2, // num ops + 1,0, // dest, bit instruction + PCC_REGISTER, // inCond + PCC_Z // outCond +}; + +pCodeInstruction pciMOVFW = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_MOVFW, + "MOVF", + NULL, // operand + 2, // num ops + 0,0, // dest, bit instruction + PCC_REGISTER, // inCond + (PCC_W | PCC_Z) // outCond +}; + +pCodeInstruction pciMOVWF = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_MOVWF, + "MOVWF", + NULL, // operand + 1, // num ops + 0,0, // dest, bit instruction + PCC_W, // inCond + 0 // outCond +}; + +pCodeInstruction pciMOVLW = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_MOVLW, + "MOVLW", + NULL, // operand + 1, // num ops + 0,0, // dest, bit instruction + PCC_NONE, // inCond + PCC_W // outCond +}; + +pCodeInstruction pciNEGF = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_NEGF, + "NEGF", + NULL, // operand + 1, // num ops + 0,0, // dest, bit instruction + PCC_REGISTER, // inCond + PCC_NONE // outCond +}; + + +pCodeInstruction pciRETLW = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + AnalyzeRETURN, + genericDestruct, + genericPrint}, + POC_RETLW, + "RETLW", + NULL, // operand + 1, // num ops + 0,0, // dest, bit instruction + PCC_NONE, // inCond + PCC_W // outCond +}; + +pCodeInstruction pciRETURN = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + AnalyzeRETURN, + genericDestruct, + genericPrint}, + POC_RETURN, + "RETURN", + NULL, // operand + 0, // num ops + 0,0, // dest, bit instruction + PCC_NONE, // inCond + PCC_W // outCond +}; + + +pCodeInstruction pciRLF = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_RLF, + "RLF", + NULL, // operand + 2, // num ops + 1,0, // dest, bit instruction + (PCC_C | PCC_REGISTER), // inCond + (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC) // outCond +}; + +pCodeInstruction pciRLFW = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_RLFW, + "RLF", + NULL, // operand + 2, // num ops + 0,0, // dest, bit instruction + (PCC_C | PCC_REGISTER), // inCond + (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond +}; + +pCodeInstruction pciRRF = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_RRF, + "RRF", + NULL, // operand + 2, // num ops + 1,0, // dest, bit instruction + (PCC_C | PCC_REGISTER), // inCond + (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC) // outCond +}; + +pCodeInstruction pciRRFW = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_RRFW, + "RRF", + NULL, // operand + 2, // num ops + 0,0, // dest, bit instruction + (PCC_C | PCC_REGISTER), // inCond + (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond +}; + +pCodeInstruction pciSUBWF = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_SUBWF, + "SUBWF", + NULL, // operand + 2, // num ops + 1,0, // dest, bit instruction + (PCC_W | PCC_REGISTER), // inCond + (PCC_REGISTER | PCC_Z) // outCond +}; + +pCodeInstruction pciSUBFW = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_SUBWF, + "SUBWF", + NULL, // operand + 2, // num ops + 0,0, // dest, bit instruction + (PCC_W | PCC_REGISTER), // inCond + (PCC_W | PCC_Z) // outCond +}; + +pCodeInstruction pciSUBLW = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_SUBLW, + "SUBLW", + NULL, // operand + 1, // num ops + 0,0, // dest, bit instruction + PCC_W, // inCond + (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond +}; + +pCodeInstruction pciSWAPF = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_SWAPF, + "SWAPF", + NULL, // operand + 2, // num ops + 1,0, // dest, bit instruction + (PCC_REGISTER), // inCond + (PCC_REGISTER) // outCond +}; + +pCodeInstruction pciSWAPFW = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_SWAPFW, + "SWAPF", + NULL, // operand + 2, // num ops + 0,0, // dest, bit instruction + (PCC_REGISTER), // inCond + (PCC_W) // outCond +}; +pCodeInstruction pciTRIS = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_TRIS, + "TRIS", + NULL, // operand + 1, // num ops + 0,0, // dest, bit instruction + PCC_NONE, // inCond + PCC_NONE +}; + + +pCodeInstruction pciXORWF = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_XORWF, + "XORWF", + NULL, // operand + 2, // num ops + 1,0, // dest, bit instruction + (PCC_W | PCC_REGISTER), // inCond + (PCC_REGISTER | PCC_Z) // outCond +}; + +pCodeInstruction pciXORFW = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_XORWF, + "XORWF", + NULL, // operand + 2, // num ops + 0,0, // dest, bit instruction + (PCC_W | PCC_REGISTER), // inCond + (PCC_W | PCC_Z) // outCond +}; + +pCodeInstruction pciXORLW = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_XORLW, + "XORLW", + NULL, // operand + 1, // num ops + 0,0, // dest, bit instruction + PCC_W, // inCond + (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond +}; + + +#define MAX_PIC14MNEMONICS 100 +pCodeInstruction *pic14Mnemonics[MAX_PIC14MNEMONICS]; + +/*-----------------------------------------------------------------*/ +/* SAFE_snprintf - like snprintf except the string pointer is */ +/* after the string has been printed to. This is */ +/* useful for printing to string as though if it */ +/* were a stream. */ +/*-----------------------------------------------------------------*/ +void SAFE_snprintf(char **str, size_t *size, const char *format, ...) { - char *copy; + va_list val; + int len; - if(!str) - return NULL; - - copy = strdup(str); - if(!copy) { - fprintf(stderr, "out of memory %s,%d\n",__FUNCTION__,__LINE__); - exit(1); - } + if(!str || !*str) + return; - return copy; + va_start(val, format); +#if 0 + // Alas, vsnprintf is not ANSI standard, and does not exist + // on Solaris (and probably other non-Gnu flavored Unixes). + vsnprintf(*str, *size, format, val); +#else + // This, of course, is *not* safe, despite the name. + vsprintf(*str, format, val); +#endif + va_end (val); + + len = strlen(*str); + *str += len; + *size -= len; + } void pCodeInitRegisters(void) @@ -114,6 +778,125 @@ void pCodeInitRegisters(void) } +/*-----------------------------------------------------------------*/ +/* mnem2key - convert a pic mnemonic into a hash key */ +/* (BTW - this spreads the mnemonics quite well) */ +/* */ +/*-----------------------------------------------------------------*/ + +int mnem2key(char const *mnem) +{ + int key = 0; + + if(!mnem) + return 0; + + while(*mnem) { + + key += toupper(*mnem++) +1; + + } + + return (key & 0x1f); + +} + +void pic14initMnemonics(void) +{ + int i = 0; + int key; + // char *str; + pCodeInstruction *pci; + + if(mnemonics_initialized) + return; + + pic14Mnemonics[POC_ADDLW] = &pciADDLW; + pic14Mnemonics[POC_ADDWF] = &pciADDWF; + pic14Mnemonics[POC_ADDFW] = &pciADDFW; + pic14Mnemonics[POC_ANDLW] = &pciANDLW; + pic14Mnemonics[POC_ANDWF] = &pciANDWF; + pic14Mnemonics[POC_ANDFW] = &pciANDFW; + pic14Mnemonics[POC_BCF] = &pciBCF; + pic14Mnemonics[POC_BSF] = &pciBSF; + pic14Mnemonics[POC_BTFSC] = &pciBTFSC; + pic14Mnemonics[POC_BTFSS] = &pciBTFSS; + pic14Mnemonics[POC_CALL] = &pciCALL; + pic14Mnemonics[POC_COMF] = &pciCOMF; + pic14Mnemonics[POC_COMFW] = &pciCOMFW; + pic14Mnemonics[POC_CLRF] = &pciCLRF; + pic14Mnemonics[POC_CLRW] = &pciCLRW; + pic14Mnemonics[POC_DECF] = &pciDECF; + pic14Mnemonics[POC_DECFW] = &pciDECFW; + pic14Mnemonics[POC_DECFSZ] = &pciDECFSZ; + pic14Mnemonics[POC_DECFSZW] = &pciDECFSZW; + pic14Mnemonics[POC_GOTO] = &pciGOTO; + pic14Mnemonics[POC_INCF] = &pciINCF; + pic14Mnemonics[POC_INCFW] = &pciINCFW; + pic14Mnemonics[POC_INCFSZ] = &pciINCFSZ; + pic14Mnemonics[POC_INCFSZW] = &pciINCFSZW; + pic14Mnemonics[POC_IORLW] = &pciIORLW; + pic14Mnemonics[POC_IORWF] = &pciIORWF; + pic14Mnemonics[POC_IORFW] = &pciIORFW; + pic14Mnemonics[POC_MOVF] = &pciMOVF; + pic14Mnemonics[POC_MOVFW] = &pciMOVFW; + pic14Mnemonics[POC_MOVLW] = &pciMOVLW; + pic14Mnemonics[POC_MOVWF] = &pciMOVWF; + pic14Mnemonics[POC_NEGF] = &pciNEGF; + pic14Mnemonics[POC_RETLW] = &pciRETLW; + pic14Mnemonics[POC_RETURN] = &pciRETURN; + pic14Mnemonics[POC_RLF] = &pciRLF; + pic14Mnemonics[POC_RLFW] = &pciRLFW; + pic14Mnemonics[POC_RRF] = &pciRRF; + pic14Mnemonics[POC_RRFW] = &pciRRFW; + pic14Mnemonics[POC_SUBLW] = &pciSUBLW; + pic14Mnemonics[POC_SUBWF] = &pciSUBWF; + pic14Mnemonics[POC_SUBFW] = &pciSUBFW; + pic14Mnemonics[POC_SWAPF] = &pciSWAPF; + pic14Mnemonics[POC_SWAPFW] = &pciSWAPFW; + pic14Mnemonics[POC_TRIS] = &pciTRIS; + pic14Mnemonics[POC_XORLW] = &pciXORLW; + pic14Mnemonics[POC_XORWF] = &pciXORWF; + pic14Mnemonics[POC_XORFW] = &pciXORFW; + + for(i=0; imnemonic), pic14Mnemonics[i]); + pci = hTabFirstItem(pic14MnemonicsHash, &key); + + while(pci) { + fprintf( stderr, "element %d key %d, mnem %s\n",i++,key,pci->mnemonic); + pci = hTabNextItem(pic14MnemonicsHash, &key); + } + + mnemonics_initialized = 1; +} + +int getpCode(char *mnem,unsigned dest) +{ + + pCodeInstruction *pci; + int key = mnem2key(mnem); + + if(!mnemonics_initialized) + pic14initMnemonics(); + + pci = hTabFirstItemWK(pic14MnemonicsHash, key); + + while(pci) { + + if(STRCASECMP(pci->mnemonic, mnem) == 0) { + if((pci->num_ops <= 1) || (pci->dest == dest)) + return(pci->op); + } + + pci = hTabNextItemWK (pic14MnemonicsHash); + + } + + return -1; +} + char getpBlock_dbName(pBlock *pb) { if(!pb) @@ -176,8 +959,10 @@ void copypCode(FILE *of, char dbName) return; for(pb = the_pFile->pbHead; pb; pb = pb->next) { - if(getpBlock_dbName(pb) == dbName) + if(getpBlock_dbName(pb) == dbName) { + pBlockStats(of,pb); printpBlock(of,pb); + } } } @@ -186,6 +971,8 @@ void pcode_test(void) printf("pcode is alive!\n"); + //initMnemonics(); + if(the_pFile) { pBlock *pb; @@ -215,6 +1002,13 @@ void pcode_test(void) } } } +/*-----------------------------------------------------------------*/ +/* int RegCond(pCodeOp *pcop) - if pcop points to the STATUS reg- */ +/* ister, RegCond will return the bit being referenced. */ +/* */ +/* fixme - why not just OR in the pcop bit field */ +/*-----------------------------------------------------------------*/ + static int RegCond(pCodeOp *pcop) { @@ -260,198 +1054,29 @@ static int RegCond(pCodeOp *pcop) pCode *newpCode (PIC_OPCODE op, pCodeOp *pcop) { pCodeInstruction *pci ; - + if(!mnemonics_initialized) + pic14initMnemonics(); + pci = Safe_calloc(1, sizeof(pCodeInstruction)); - pci->pc.analyze = genericAnalyze; // pointers to the generic functions, it - pci->pc.destruct = genericDestruct; // doesn't hurt to think about C++ virtual - pci->pc.print = genericPrint; // functions here. - pci->pc.type = PC_OPCODE; // - pci->op = op; // the "opcode" for the instruction. - pci->pc.prev = pci->pc.next = NULL; // The pCode gets linked in later - pci->pcop = pcop; // The operand of the instruction - pci->dest = 0; // e.g. W or F - pci->bit_inst = 0; // e.g. btfxx instructions - pci->num_ops = 2; // Most instructions have two ops... - pci->inCond = pci->outCond = PCC_NONE; /* input/output conditions. This is used during - * optimization to ascertain instruction dependencies. - * For example, if an instruction affects the Z bit, - * then the output condition for this instruction - * is "z bit is affected". The "conditions" are bit - * constants defined in pcode.h. */ - pci->pc.from = pci->pc.to = NULL; // Flow linkages are defined later - pci->pc.label = NULL; // Labels get merged into instructions here. - pci->pc.pb = NULL; // The pBlock to which this instruction belongs - - if(pcop && pcop->name) - printf("newpCode operand name %s\n",pcop->name); - - // The most pic dependent portion of the pCode logic: - switch(op) { - - case POC_ANDLW: - pci->inCond = PCC_W; - pci->outCond = PCC_W | PCC_Z; - pci->mnemonic = scpANDLW; - pci->num_ops = 1; - break; - case POC_ANDWF: - pci->dest = 1; - pci->inCond = PCC_W | PCC_REGISTER; - pci->outCond = PCC_REGISTER | PCC_Z; - pci->mnemonic = scpANDWF; - break; - case POC_ANDFW: - pci->inCond = PCC_W | PCC_REGISTER; - pci->outCond = PCC_W | PCC_Z; - pci->mnemonic = scpANDWF; - break; + if((op>=0) && (op < MAX_PIC14MNEMONICS) && pic14Mnemonics[op]) { + memcpy(pci, pic14Mnemonics[op], sizeof(pCodeInstruction)); + pci->pcop = pcop; - case POC_ADDLW: - pci->inCond = PCC_W; - pci->outCond = PCC_W | PCC_Z | PCC_C | PCC_DC; - pci->mnemonic = scpADDLW; - pci->num_ops = 1; - break; - case POC_ADDWF: - pci->dest = 1; - pci->inCond = PCC_W | PCC_REGISTER; - pci->outCond = PCC_REGISTER | PCC_Z | PCC_C | PCC_DC; - pci->mnemonic = scpADDWF; - break; - case POC_ADDFW: - pci->inCond = PCC_W | PCC_REGISTER; - pci->outCond = PCC_W | PCC_Z | PCC_C | PCC_DC; - pci->mnemonic = scpADDWF; - break; + if(pci->inCond == PCC_EXAMINE_PCOP) + pci->inCond = RegCond(pcop); - case POC_BCF: - pci->bit_inst = 1; - pci->mnemonic = scpBCF; - pci->outCond = RegCond(pcop); - break; - case POC_BSF: - pci->bit_inst = 1; - pci->mnemonic = scpBSF; - pci->outCond = RegCond(pcop); - break; - case POC_BTFSC: - pci->bit_inst = 1; - pci->mnemonic = scpBTFSC; - pci->pc.analyze = AnalyzeSKIP; - pci->inCond = RegCond(pcop); - break; - case POC_BTFSS: - pci->bit_inst = 1; - pci->mnemonic = scpBTFSS; - pci->pc.analyze = AnalyzeSKIP; - pci->inCond = RegCond(pcop); - break; - case POC_CALL: - pci->num_ops = 1; - pci->mnemonic = scpCALL; - break; - case POC_COMF: - pci->mnemonic = scpCOMF; - break; - case POC_CLRF: - pci->num_ops = 1; - pci->mnemonic = scpCLRF; - break; - case POC_CLRW: - pci->num_ops = 0; - pci->mnemonic = scpCLRW; - break; - case POC_DECF: - pci->dest = 1; - case POC_DECFW: - pci->mnemonic = scpDECF; - break; - case POC_DECFSZ: - pci->dest = 1; - case POC_DECFSZW: - pci->mnemonic = scpDECFSZ; - pci->pc.analyze = AnalyzeSKIP; - break; - case POC_GOTO: - pci->num_ops = 1; - pci->mnemonic = scpGOTO; - pci->pc.analyze = AnalyzeGOTO; - break; - case POC_INCF: - pci->dest = 1; - case POC_INCFW: - pci->mnemonic = scpINCF; - break; - case POC_INCFSZ: - pci->dest = 1; - case POC_INCFSZW: - pci->mnemonic = scpINCFSZ; - pci->pc.analyze = AnalyzeSKIP; - break; - case POC_IORLW: - pci->num_ops = 1; - pci->mnemonic = scpIORLW; - break; - case POC_IORWF: - pci->dest = 1; - case POC_IORFW: - pci->mnemonic = scpIORWF; - break; - case POC_MOVF: - pci->dest = 1; - case POC_MOVFW: - pci->mnemonic = scpMOVF; - break; - case POC_MOVLW: - pci->num_ops = 1; - pci->mnemonic = scpMOVLW; - break; - case POC_MOVWF: - pci->num_ops = 1; - pci->mnemonic = scpMOVWF; - break; - case POC_NEGF: - pci->mnemonic = scpNEGF; - break; - case POC_RETLW: - pci->num_ops = 1; - pci->mnemonic = scpRETLW; - pci->pc.analyze = AnalyzeRETURN; - break; - case POC_RETURN: - pci->num_ops = 0; - pci->mnemonic = scpRETURN; - pci->pc.analyze = AnalyzeRETURN; - break; - case POC_SUBLW: - pci->mnemonic = scpSUBLW; - pci->num_ops = 1; - break; - case POC_SUBWF: - pci->dest = 1; - case POC_SUBFW: - pci->mnemonic = scpSUBWF; - break; - case POC_TRIS: - pci->mnemonic = scpTRIS; - break; - case POC_XORLW: - pci->num_ops = 1; - pci->mnemonic = scpXORLW; - break; - case POC_XORWF: - pci->dest = 1; - case POC_XORFW: - pci->mnemonic = scpXORWF; - break; + if(pci->outCond == PCC_EXAMINE_PCOP) + pci->outCond = RegCond(pcop); - default: - pci->pc.print = genericPrint; + return (pCode *)pci; } - - return (pCode *)pci; + + fprintf(stderr, "pCode mnemonic error %s,%d\n",__FUNCTION__,__LINE__); + exit(1); + + return NULL; } /*-----------------------------------------------------------------*/ @@ -465,6 +1090,10 @@ pCode *newpCode (PIC_OPCODE op, pCodeOp *pcop) /* line (of assembly code) is declared matched. Note that the */ /* operand may be wild too. */ /* */ +/* Note, a wild instruction is specified just like a wild var: */ +/* %4 ; A wild instruction, */ +/* See the peeph.def file for additional examples */ +/* */ /*-----------------------------------------------------------------*/ pCode *newpCodeWild(int pCodeID, pCodeOp *optional_operand, pCodeOp *optional_label) @@ -483,7 +1112,7 @@ pCode *newpCodeWild(int pCodeID, pCodeOp *optional_operand, pCodeOp *optional_la pcw->pc.destruct = genericDestruct; pcw->pc.print = genericPrint; - pcw->id = pCodeID; + pcw->id = pCodeID; // this is the 'n' in %n pcw->operand = optional_operand; pcw->label = optional_label; @@ -511,7 +1140,10 @@ pCode *newpCodeCharP(char *cP) pcc->pc.destruct = genericDestruct; pcc->pc.print = genericPrint; - pcc->comment = Safe_strdup(cP); + if(cP) + pcc->comment = Safe_strdup(cP); + else + pcc->comment = NULL; return ( (pCode *)pcc); @@ -553,6 +1185,21 @@ pCode *newpCodeFunction(char *mod,char *f) } +/*-----------------------------------------------------------------*/ +/* pCodeLabelDestruct - free memory used by a label. */ +/*-----------------------------------------------------------------*/ +static void pCodeLabelDestruct(pCode *pc) +{ + + if(!pc) + return; + + if((pc->type == PC_LABEL) && PCL(pc)->label) + free(PCL(pc)->label); + + free(pc); + +} pCode *newpCodeLabel(int key) { @@ -568,16 +1215,18 @@ pCode *newpCodeLabel(int key) pcl->pc.pb = NULL; pcl->pc.analyze = genericAnalyze; - pcl->pc.destruct = genericDestruct; + pcl->pc.destruct = pCodeLabelDestruct; pcl->pc.print = pCodePrintLabel; pcl->key = key; + pcl->label = NULL; if(key>0) { sprintf(s,"_%05d_DS_",key); - pcl->label = Safe_strdup(s); - } else - pcl->label = NULL; + if(s) + pcl->label = Safe_strdup(s); + } + return ( (pCode *)pcl); @@ -586,7 +1235,10 @@ pCode *newpCodeLabelStr(char *str) { pCode *pc = newpCodeLabel(-1); - PCL(pc)->label = Safe_strdup(str); + if(str) + PCL(pc)->label = Safe_strdup(str); + else + PCL(pc)->label = NULL; return pc; } @@ -599,7 +1251,7 @@ pBlock *newpBlock(void) pBlock *PpB; - _ALLOC(PpB,sizeof(pBlock)); + PpB = Safe_calloc(1,sizeof(pBlock) ); PpB->next = PpB->prev = NULL; PpB->function_entries = PpB->function_exits = PpB->function_calls = NULL; @@ -631,20 +1283,6 @@ pBlock *newpCodeChain(memmap *cm,char c, pCode *pc) return pB; } -/*-----------------------------------------------------------------*/ -/*-----------------------------------------------------------------*/ - -pCodeOp *newpCodeOp(char *name, PIC_OPTYPE type) -{ - pCodeOp *pcop; - - pcop = Safe_calloc(1,sizeof(pCodeOp) ); - pcop->type = type; - pcop->name = Safe_strdup(name); - - return pcop; -} - /*-----------------------------------------------------------------*/ /* newpCodeOpLabel - Create a new label given the key */ /* Note, a negative key means that the label is part of wild card */ @@ -660,33 +1298,44 @@ pCodeOp *newpCodeOpLabel(int key) pcop = Safe_calloc(1,sizeof(pCodeOpLabel) ); pcop->type = PO_LABEL; + pcop->name = NULL; if(key>0) { sprintf(s,"_%05d_DS_",key); - pcop->name = Safe_strdup(s); - } else - pcop->name = NULL; + if(s) + pcop->name = Safe_strdup(s); + } + ((pCodeOpLabel *)pcop)->key = key; return pcop; } +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ pCodeOp *newpCodeOpLit(int lit) { char *s = buffer; pCodeOp *pcop; - _ALLOC(pcop,sizeof(pCodeOpLit) ); + pcop = Safe_calloc(1,sizeof(pCodeOpLit) ); pcop->type = PO_LITERAL; - sprintf(s,"0x%02x",lit); - _ALLOC_ATOMIC(pcop->name,strlen(s)+1); - strcpy(pcop->name,s); + pcop->name = NULL; + if(lit>=0) { + sprintf(s,"0x%02x",lit); + if(s) + pcop->name = Safe_strdup(s); + } + + ((pCodeOpLit *)pcop)->lit = lit; return pcop; } +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ pCodeOp *newpCodeOpWild(int id, pCodePeep *pcp, pCodeOp *subtype) { char *s = buffer; @@ -711,18 +1360,66 @@ pCodeOp *newpCodeOpWild(int id, pCodePeep *pcp, pCodeOp *subtype) return pcop; } -pCodeOp *newpCodeOpBit(char *s, int bit) +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ +pCodeOp *newpCodeOpBit(char *s, int bit, int inBitSpace) { pCodeOp *pcop; - _ALLOC(pcop,sizeof(pCodeOpBit) ); + pcop = Safe_calloc(1,sizeof(pCodeOpBit) ); pcop->type = PO_BIT; - pcop->name = Safe_strdup(s); - PCOB(pcop)->bit = bit; - if(bit>=0) - PCOB(pcop)->inBitSpace = 1; + if(s) + pcop->name = Safe_strdup(s); else - PCOB(pcop)->inBitSpace = 0; + pcop->name = NULL; + + PCOB(pcop)->bit = bit; + PCOB(pcop)->inBitSpace = inBitSpace; + + return pcop; +} + +pCodeOp *newpCodeOpReg(int rIdx) +{ + pCodeOp *pcop; + + pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); + + PCOR(pcop)->rIdx = rIdx; + PCOR(pcop)->r = pic14_regWithIdx(rIdx); + pcop->type = PCOR(pcop)->r->pc_type; + + return pcop; +} + +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ + +pCodeOp *newpCodeOp(char *name, PIC_OPTYPE type) +{ + pCodeOp *pcop; + + switch(type) { + case PO_BIT: + pcop = newpCodeOpBit(name, -1,0); + break; + + case PO_LITERAL: + pcop = newpCodeOpLit(-1); + break; + + case PO_LABEL: + pcop = newpCodeOpLabel(-1); + break; + + default: + pcop = Safe_calloc(1,sizeof(pCodeOp) ); + pcop->type = type; + if(name) + pcop->name = Safe_strdup(name); + else + pcop->name = NULL; + } return pcop; } @@ -732,12 +1429,18 @@ pCodeOp *newpCodeOpBit(char *s, int bit) /*-----------------------------------------------------------------*/ void addpCode2pBlock(pBlock *pb, pCode *pc) { - - pb->pcTail->next = pc; - pc->prev = pb->pcTail; - pc->next = NULL; - pc->pb = pb; - pb->pcTail = pc; + 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 { + pb->pcTail->next = pc; + pc->prev = pb->pcTail; + pc->next = NULL; + pc->pb = pb; + pb->pcTail = pc; + } } /*-----------------------------------------------------------------*/ @@ -748,7 +1451,7 @@ void addpBlock(pBlock *pb) if(!the_pFile) { /* First time called, we'll pass through here. */ - _ALLOC(the_pFile,sizeof(the_pFile)); + _ALLOC(the_pFile,sizeof(pFile)); the_pFile->pbHead = the_pFile->pbTail = pb; the_pFile->functions = NULL; return; @@ -803,23 +1506,33 @@ void printpBlock(FILE *of, pBlock *pb) /* */ /*-----------------------------------------------------------------*/ -static void unlink(pCode *pc) +static void unlinkPC(pCode *pc) { - if(pc && pc->prev && pc->next) { - pc->prev->next = pc->next; - pc->next->prev = pc->prev; + + if(pc) { + + if(pc->prev) + pc->prev->next = pc->next; + if(pc->next) + pc->next->prev = pc->prev; + + pc->prev = pc->next = NULL; } } static void genericDestruct(pCode *pc) { - unlink(pc); - fprintf(stderr,"warning, calling default pCode destructor\n"); + + unlinkPC(pc); + free(pc); + } +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ void pBlockRegs(FILE *of, pBlock *pb) { @@ -827,7 +1540,6 @@ void pBlockRegs(FILE *of, pBlock *pb) r = setFirstItem(pb->registers); while (r) { - fprintf(of," %s\n",r->name); r = setNextItem(pb->registers); } } @@ -843,9 +1555,13 @@ static char *get_op( pCodeInstruction *pcc) switch(pcc->pcop->type) { case PO_FSR: + r = pic14_regWithIdx(PCOR(pcc->pcop)->rIdx); + return r->name; + break; case PO_GPR_TEMP: + case PO_GPR_BIT: r = pic14_regWithIdx(PCOR(pcc->pcop)->r->rIdx); - fprintf(stderr,"getop: getting %s\nfrom:\n",r->name); //pcc->pcop->name); + //fprintf(stderr,"getop: getting %s\nfrom:\n",r->name); //pcc->pcop->name); pBlockRegs(stderr,pcc->pc.pb); return r->name; @@ -867,6 +1583,72 @@ static void pCodeOpPrint(FILE *of, pCodeOp *pcop) fprintf(of,"pcodeopprint\n"); } +char *pCode2str(char *str, int size, pCode *pc) +{ + char *s = str; + + switch(pc->type) { + + case PC_OPCODE: + + SAFE_snprintf(&s,&size, "\t%s\t", PCI(pc)->mnemonic); + + if( (PCI(pc)->num_ops >= 1) && (PCI(pc)->pcop)) { + + if(PCI(pc)->bit_inst) { + if(PCI(pc)->pcop->type == PO_BIT) { + if( (((pCodeOpBit *)(PCI(pc)->pcop))->inBitSpace) ) + SAFE_snprintf(&s,&size,"(%s >> 3), (%s & 7)", + PCI(pc)->pcop->name , + PCI(pc)->pcop->name ); + else + SAFE_snprintf(&s,&size,"%s,%d", get_op(PCI(pc)), + (((pCodeOpBit *)(PCI(pc)->pcop))->bit )); + } else if(PCI(pc)->pcop->type == PO_GPR_BIT) { + SAFE_snprintf(&s,&size,"%s,%d", get_op(PCI(pc)),PCORB(PCI(pc)->pcop)->bit); + }else + SAFE_snprintf(&s,&size,"%s,0 ; ?bug", get_op(PCI(pc))); + //PCI(pc)->pcop->t.bit ); + } else { + + if(PCI(pc)->pcop->type == PO_BIT) { + if( PCI(pc)->num_ops == 2) + SAFE_snprintf(&s,&size,"(%s >> 3),%c",get_op(PCI(pc)),((PCI(pc)->dest) ? 'F':'W')); + else + SAFE_snprintf(&s,&size,"(1 << (%s & 7))",get_op(PCI(pc))); + + }else { + SAFE_snprintf(&s,&size,"%s",get_op(PCI(pc))); + + if( PCI(pc)->num_ops == 2) + SAFE_snprintf(&s,&size,",%c", ( (PCI(pc)->dest) ? 'F':'W')); + } + } + + } + break; + + case PC_COMMENT: + /* assuming that comment ends with a \n */ + SAFE_snprintf(&s,&size,";%s", ((pCodeComment *)pc)->comment); + break; + + case PC_LABEL: + SAFE_snprintf(&s,&size,";label=%s, key=%d\n",PCL(pc)->label,PCL(pc)->key); + break; + case PC_FUNCTION: + SAFE_snprintf(&s,&size,";modname=%s,function=%s: id=%d\n",PCF(pc)->modname,PCF(pc)->fname); + break; + case PC_WILD: + SAFE_snprintf(&s,&size,";\tWild opcode: id=%d\n",PCW(pc)->id); + break; + + } + + return str; + +} + /*-----------------------------------------------------------------*/ /* genericPrint - the contents of a pCode to a file */ /*-----------------------------------------------------------------*/ @@ -885,48 +1667,20 @@ static void genericPrint(FILE *of, pCode *pc) // If the opcode has a label, print that first { pBranch *pbl = pc->label; - while(pbl) { + while(pbl && pbl->pc) { if(pbl->pc->type == PC_LABEL) pCodePrintLabel(of, pbl->pc); pbl = pbl->next; } } - fprintf(of, "\t%s\t", PCI(pc)->mnemonic); - if( (PCI(pc)->num_ops >= 1) && (PCI(pc)->pcop)) { - - if(PCI(pc)->bit_inst) { - if(PCI(pc)->pcop->type == PO_BIT) { - if( (((pCodeOpBit *)(PCI(pc)->pcop))->inBitSpace) ) - fprintf(of,"(%s >> 3), (%s & 7)", - PCI(pc)->pcop->name , - PCI(pc)->pcop->name ); - else - fprintf(of,"%s,%d", get_op(PCI(pc)), (((pCodeOpBit *)(PCI(pc)->pcop))->bit )); - } else - fprintf(of,"%s,0 ; ?bug", get_op(PCI(pc))); - //PCI(pc)->pcop->t.bit ); - } else { - - if(PCI(pc)->pcop->type == PO_BIT) { - if( PCI(pc)->num_ops == 2) - fprintf(of,"(%s >> 3),%c",get_op(PCI(pc)),((PCI(pc)->dest) ? 'F':'W')); - else - fprintf(of,"(1 << (%s & 7))",get_op(PCI(pc))); -/* - if( PCI(pc)->num_ops == 2) - fprintf(of,"(%s >> 3),%c",PCI(pc)->pcop->name,((PCI(pc)->dest) ? 'F':'W')); - else - fprintf(of,"(1 << (%s & 7))",PCI(pc)->pcop->name); -*/ - }else { - fprintf(of,"%s",get_op(PCI(pc))); + { + char str[256]; + + pCode2str(str, 256, pc); - if( PCI(pc)->num_ops == 2) - fprintf(of,",%c", ( (PCI(pc)->dest) ? 'F':'W')); - } - } + fprintf(of,"%s",str); } { @@ -955,6 +1709,9 @@ static void genericPrint(FILE *of, pCode *pc) case PC_WILD: fprintf(of,";\tWild opcode: id=%d\n",PCW(pc)->id); + if(pc->label) + pCodePrintLabel(of, pc->label->pc); + if(PCW(pc)->operand) { fprintf(of,";\toperand "); pCodeOpPrint(of,PCW(pc)->operand ); @@ -1016,11 +1773,41 @@ static void pCodePrintLabel(FILE *of, pCode *pc) else if (PCL(pc)->key >=0) fprintf(of,"_%05d_DS_:\n",PCL(pc)->key); else - fprintf(of,";wild card label\n"); + fprintf(of,";wild card label: id=%d\n",-PCL(pc)->key); } /*-----------------------------------------------------------------*/ +/* unlinkpCodeFromBranch - Search for a label in a pBranch and */ +/* remove it if it is found. */ +/*-----------------------------------------------------------------*/ +static void unlinkpCodeFromBranch(pCode *pcl , pCode *pc) +{ + pBranch *b, *bprev; + + 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; + } + +} +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ static pBranch * pBranchAppend(pBranch *h, pBranch *n) { pBranch *b; @@ -1151,8 +1938,33 @@ static void genericAnalyze(pCode *pc) } else npc = npc->next; } + /* reached the end of the pcode chain without finding + * an instruction we could link to. */ + } + } +} + +/*-----------------------------------------------------------------*/ +int compareLabel(pCode *pc, pCodeOpLabel *pcop_label) +{ + pBranch *pbr; + + if(pc->type == PC_LABEL) { + if( ((pCodeLabel *)pc)->key == pcop_label->key) + return TRUE; + } + if(pc->type == PC_OPCODE) { + pbr = pc->label; + while(pbr) { + if(pbr->pc->type == PC_LABEL) { + if( ((pCodeLabel *)(pbr->pc))->key == pcop_label->key) + return TRUE; + } + pbr = pbr->next; } } + + return FALSE; } /*-----------------------------------------------------------------*/ @@ -1162,29 +1974,15 @@ pCode * findLabel(pCodeOpLabel *pcop_label) { pBlock *pb; pCode *pc; - pBranch *pbr; if(!the_pFile) return NULL; for(pb = the_pFile->pbHead; pb; pb = pb->next) { - for(pc = pb->pcHead; pc; pc = pc->next) { - if(pc->type == PC_LABEL) { - if( ((pCodeLabel *)pc)->key == pcop_label->key) - return pc; - } - if(pc->type == PC_OPCODE) { - pbr = pc->label; - while(pbr) { - if(pbr->pc->type == PC_LABEL) { - if( ((pCodeLabel *)(pbr->pc))->key == pcop_label->key) - return pc; - } - pbr = pbr->next; - } - } - - } + for(pc = pb->pcHead; pc; pc = pc->next) + if(compareLabel(pc,pcop_label)) + return pc; + } fprintf(stderr,"Couldn't find label %s", pcop_label->pcop.name); @@ -1199,7 +1997,7 @@ pCode * findNextInstruction(pCode *pc) { while(pc) { - if(pc->type == PC_OPCODE) + if((pc->type == PC_OPCODE) || (pc->type == PC_WILD)) return pc; pc = pc->next; @@ -1262,6 +2060,8 @@ static void AnalyzeRETURN(pCode *pc) } +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ void AnalyzepBlock(pBlock *pb) { @@ -1276,7 +2076,7 @@ void AnalyzepBlock(pBlock *pb) if(PCI(pc)->pcop && PCI(pc)->pcop->type == PO_GPR_TEMP) { /* Loop through all of the registers declared so far in - this block and see if we find this new there */ + this block and see if we find this one there */ regs *r = setFirstItem(pb->registers); @@ -1302,6 +2102,8 @@ void AnalyzepBlock(pBlock *pb) } } +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ int OptimizepBlock(pBlock *pb) { pCode *pc; @@ -1310,14 +2112,79 @@ int OptimizepBlock(pBlock *pb) if(!pb || !peepOptimizing) return 0; - fprintf(stderr," Optimizing pBlock\n"); - + fprintf(stderr," Optimizing pBlock: %c\n",getpBlock_dbName(pb)); for(pc = pb->pcHead; pc; pc = pc->next) matches += pCodePeepMatchRule(pc); return matches; } + +/*-----------------------------------------------------------------*/ +/* pBlockRemoveUnusedLabels - remove the pCode labels from the */ +/*-----------------------------------------------------------------*/ +pCode * findInstructionUsingLabel(pCodeLabel *pcl, pCode *pcs) +{ + pCode *pc; + + for(pc = pcs; pc; pc = pc->next) { + + if((pc->type == PC_OPCODE) && + (PCI(pc)->pcop) && + (PCI(pc)->pcop->type == PO_LABEL) && + (PCOLAB(PCI(pc)->pcop)->key == pcl->key)) + return pc; + } + + + return NULL; +} + +/*-----------------------------------------------------------------*/ +/* pBlockRemoveUnusedLabels - remove the pCode labels from the */ +/* pCode chain if they're not used. */ +/*-----------------------------------------------------------------*/ +void pBlockRemoveUnusedLabels(pBlock *pb) +{ + pCode *pc; pCodeLabel *pcl; + + if(!pb) + return; + + for(pc = pb->pcHead; pc; pc = pc->next) { + + if(pc->type == PC_LABEL) + pcl = PCL(pc); + else if (pc->label) + pcl = PCL(pc->label->pc); + else continue; + + /* This pCode is a label, so search the pBlock to see if anyone + * refers to it */ + + if( (pcl->key>0) && (!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\n", pcl->key); + + if(pc->type == PC_LABEL) { + unlinkPC(pc); + pCodeLabelDestruct(pc); + } else { + unlinkpCodeFromBranch(pc, PCODE(pcl)); + /*if(pc->label->next == NULL && pc->label->pc == NULL) { + free(pc->label); + }*/ + } + + } + } + +} + + /*-----------------------------------------------------------------*/ /* pBlockMergeLabels - remove the pCode labels from the pCode */ /* chain and put them into pBranches that are */ @@ -1332,18 +2199,22 @@ void pBlockMergeLabels(pBlock *pb) if(!pb) return; + /* First, Try to remove any unused labels */ + //pBlockRemoveUnusedLabels(pb); + + /* Now loop through the pBlock and merge the labels with the opcodes */ + for(pc = pb->pcHead; pc; pc = pc->next) { if(pc->type == 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 - if(pc->prev) - pc->prev->next = pc->next; - if(pc->next) - pc->next->prev = pc->prev; + 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 @@ -1355,9 +2226,14 @@ void pBlockMergeLabels(pBlock *pb) pbr->next = NULL; pcnext->label = pBranchAppend(pcnext->label,pbr); + if(pcnext->prev) + pc = pcnext->prev; + else + pc = pcnext; } } + pBlockRemoveUnusedLabels(pb); } @@ -1400,23 +2276,32 @@ void AnalyzepCode(char dbName) pCode *pc; pBranch *pbr; + int i,changes; + if(!the_pFile) return; fprintf(stderr," Analyzing pCode"); - /* First, merge the labels with the instructions */ - for(pb = the_pFile->pbHead; pb; pb = pb->next) { - if('*' == dbName || getpBlock_dbName(pb) == dbName) { - pBlockMergeLabels(pb); - AnalyzepBlock(pb); + changes = 0; + i = 0; + do { + /* First, merge the labels with the instructions */ + for(pb = the_pFile->pbHead; pb; pb = pb->next) { + if('*' == dbName || getpBlock_dbName(pb) == dbName) { + + fprintf(stderr," analyze and merging block %c\n",dbName); + pBlockMergeLabels(pb); + AnalyzepBlock(pb); + } } - } - for(pb = the_pFile->pbHead; pb; pb = pb->next) { - if('*' == dbName || getpBlock_dbName(pb) == dbName) - OptimizepBlock(pb); - } + for(pb = the_pFile->pbHead; pb; pb = pb->next) { + if('*' == dbName || getpBlock_dbName(pb) == dbName) + changes += OptimizepBlock(pb); + } + + } while(changes && (i++ < MAX_PASSES)); /* Now build the call tree. First we examine all of the pCodes for functions. @@ -1539,26 +2424,28 @@ void pBlockStats(FILE *of, pBlock *pb) pCode *pc; regs *r; - fprintf(of,"***\n pBlock Stats\n***\n"); + fprintf(of,";***\n; pBlock Stats\n;***\n"); // for now just print the first element of each set pc = setFirstItem(pb->function_entries); if(pc) { - fprintf(of,"entry\n"); + fprintf(of,";entry: "); pc->print(of,pc); } pc = setFirstItem(pb->function_exits); if(pc) { - fprintf(of,"has an exit\n"); - pc->print(of,pc); + fprintf(of,";has an exit\n"); + //pc->print(of,pc); } pc = setFirstItem(pb->function_calls); if(pc) { - fprintf(of,"functions called\n"); + fprintf(of,";functions called:\n"); while(pc) { - pc->print(of,pc); + if(pc->type == PC_OPCODE && PCI(pc)->op == POC_CALL) { + fprintf(of,"; %s\n",get_op(PCI(pc))); + } pc = setNextItem(pb->function_calls); } } @@ -1567,10 +2454,10 @@ void pBlockStats(FILE *of, pBlock *pb) if(r) { int n = elementsInSet(pb->registers); - fprintf(of,"%d compiler assigned register%c:\n",n, ( (n!=1) ? 's' : ' ')); + fprintf(of,";%d compiler assigned register%c:\n",n, ( (n!=1) ? 's' : ' ')); while (r) { - fprintf(of," %s\n",r->name); + fprintf(of,"; %s\n",r->name); r = setNextItem(pb->registers); } } @@ -1630,6 +2517,10 @@ set *register_usage(pBlock *pb) pBlockStats(stderr,pb); // debug + + // Mark the registers in this block as used. + + MarkUsedRegisters(pb->registers); 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 */ @@ -1644,10 +2535,10 @@ set *register_usage(pBlock *pb) r2 = setFirstItem(pb->registers); - while(r2) { + while(r2 && (r1->type != REG_STK)) { if(r2->rIdx == r1->rIdx) { - newreg = pic14_findFreeReg(); + newreg = pic14_findFreeReg(REG_GPR); if(!newreg) { @@ -1659,7 +2550,10 @@ set *register_usage(pBlock *pb) r1->rIdx, newreg->rIdx); r2->rIdx = newreg->rIdx; //if(r2->name) free(r2->name); - r2->name = Safe_strdup(newreg->name); + if(newreg->name) + r2->name = Safe_strdup(newreg->name); + else + r2->name = NULL; newreg->isFree = 0; newreg->wasUsed = 1; } @@ -1672,13 +2566,15 @@ set *register_usage(pBlock *pb) /* 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; + if(r1->type != REG_STK) { + newreg = pic14_regWithIdx(r1->rIdx); + newreg->isFree = 1; + } r1 = setNextItem(registersInCallPath); } - } else - MarkUsedRegisters(pb->registers); + }// else + // MarkUsedRegisters(pb->registers); registers = unionSets(pb->registers, registersInCallPath, THROW_NONE); @@ -1775,7 +2671,10 @@ void pct2(FILE *of,pBlock *pb,int indent) r1->rIdx, newreg->rIdx); r2->rIdx = newreg->rIdx; //if(r2->name) free(r2->name); - r2->name = Safe_strdup(newreg->name); + if(newreg->name) + r2->name = Safe_strdup(newreg->name); + else + r2->name = NULL; newreg->isFree = 0; newreg->wasUsed = 1; }