X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic16%2Fpcode.c;h=7d04d89db199f6267cd9d55ffd2f295da412791b;hb=d10151253d907646b1040f76f9b152f2f9d25835;hp=b1823026ce047c0ff3368ac7871a14caa255c909;hpb=0f23774d2f5a0e5eb43c67b8694793ba13d91a41;p=fw%2Fsdcc diff --git a/src/pic16/pcode.c b/src/pic16/pcode.c index b1823026..7d04d89d 100644 --- a/src/pic16/pcode.c +++ b/src/pic16/pcode.c @@ -1,6 +1,7 @@ /*------------------------------------------------------------------------- - pcode.c - post code generation + pcode.c - post code generation + Written By - Scott Dattalo scott@dattalo.com Ported to PIC16 By - Martin Dubuc m.dubuc@rogers.com @@ -25,6 +26,7 @@ #include "newalloc.h" +#include "main.h" #include "pcode.h" #include "pcodeflow.h" #include "ralloc.h" @@ -51,19 +53,84 @@ static peepCommand peepCommands[] = { // Eventually this will go into device dependent files: -pCodeOpReg pic16_pc_status = {{PO_STATUS, "_STATUS"}, -1, NULL,0,NULL}; -pCodeOpReg pic16_pc_indf0 = {{PO_INDF0, "INDF0"}, -1, NULL,0,NULL}; -pCodeOpReg pic16_pc_fsr0 = {{PO_FSR0, "FSR0"}, -1, NULL,0,NULL}; -pCodeOpReg pic16_pc_intcon = {{PO_INTCON, ""}, -1, NULL,0,NULL}; +pCodeOpReg pic16_pc_status = {{PO_STATUS, "STATUS"}, -1, NULL,0,NULL}; +pCodeOpReg pic16_pc_intcon = {{PO_INTCON, "INTCON"}, -1, NULL,0,NULL}; pCodeOpReg pic16_pc_pcl = {{PO_PCL, "PCL"}, -1, NULL,0,NULL}; -pCodeOpReg pic16_pc_pclath = {{PO_PCLATH, "_PCLATH"}, -1, NULL,0,NULL}; +pCodeOpReg pic16_pc_pclath = {{PO_PCLATH, "PCLATH"}, -1, NULL,0,NULL}; +pCodeOpReg pic16_pc_pclatu = {{PO_PCLATU, "PCLATU"}, -1, NULL,0,NULL}; // patch 14 pCodeOpReg pic16_pc_wreg = {{PO_WREG, "WREG"}, -1, NULL,0,NULL}; pCodeOpReg pic16_pc_bsr = {{PO_BSR, "BSR"}, -1, NULL,0,NULL}; +pCodeOpReg pic16_pc_tosl = {{PO_SFR_REGISTER, "TOSL"}, -1, NULL,0,NULL}; // patch 14 +pCodeOpReg pic16_pc_tosh = {{PO_SFR_REGISTER, "TOSH"}, -1, NULL,0,NULL}; // +pCodeOpReg pic16_pc_tosu = {{PO_SFR_REGISTER, "TOSU"}, -1, NULL,0,NULL}; // patch 14 + +pCodeOpReg pic16_pc_tblptrl = {{PO_SFR_REGISTER, "TBLPTRL"}, -1, NULL,0,NULL}; // patch 15 +pCodeOpReg pic16_pc_tblptrh = {{PO_SFR_REGISTER, "TBLPTRH"}, -1, NULL,0,NULL}; // +pCodeOpReg pic16_pc_tblptru = {{PO_SFR_REGISTER, "TBLPTRU"}, -1, NULL,0,NULL}; // +pCodeOpReg pic16_pc_tablat = {{PO_SFR_REGISTER, "TABLAT"}, -1, NULL,0,NULL}; // patch 15 + +//pCodeOpReg pic16_pc_fsr0 = {{PO_FSR0, "FSR0"}, -1, NULL,0,NULL}; //deprecated ! + +pCodeOpReg pic16_pc_fsr0l = {{PO_FSR0, "FSR0L"}, -1, NULL, 0, NULL}; +pCodeOpReg pic16_pc_fsr0h = {{PO_FSR0, "FSR0H"}, -1, NULL, 0, NULL}; +pCodeOpReg pic16_pc_fsr1l = {{PO_FSR0, "FSR1L"}, -1, NULL, 0, NULL}; +pCodeOpReg pic16_pc_fsr1h = {{PO_FSR0, "FSR1H"}, -1, NULL, 0, NULL}; +pCodeOpReg pic16_pc_fsr2l = {{PO_FSR0, "FSR2L"}, -1, NULL, 0, NULL}; +pCodeOpReg pic16_pc_fsr2h = {{PO_FSR0, "FSR2H"}, -1, NULL, 0, NULL}; + +pCodeOpReg pic16_pc_indf0 = {{PO_INDF0, "INDF0"}, -1, NULL,0,NULL}; +pCodeOpReg pic16_pc_postinc0 = {{PO_INDF0, "POSTINC0"}, -1, NULL, 0, NULL}; +pCodeOpReg pic16_pc_postdec0 = {{PO_INDF0, "POSTDEC0"}, -1, NULL, 0, NULL}; +pCodeOpReg pic16_pc_preinc0 = {{PO_INDF0, "PREINC0"}, -1, NULL, 0, NULL}; +pCodeOpReg pic16_pc_plusw0 = {{PO_INDF0, "PLUSW0"}, -1, NULL, 0, NULL}; + +pCodeOpReg pic16_pc_indf1 = {{PO_INDF0, "INDF1"}, -1, NULL,0,NULL}; +pCodeOpReg pic16_pc_postinc1 = {{PO_INDF0, "POSTINC1"}, -1, NULL, 0, NULL}; +pCodeOpReg pic16_pc_postdec1 = {{PO_INDF0, "POSTDEC1"}, -1, NULL, 0, NULL}; +pCodeOpReg pic16_pc_preinc1 = {{PO_INDF0, "PREINC1"}, -1, NULL, 0, NULL}; +pCodeOpReg pic16_pc_plusw1 = {{PO_INDF0, "PLUSW1"}, -1, NULL, 0, NULL}; + +pCodeOpReg pic16_pc_indf2 = {{PO_INDF0, "INDF2"}, -1, NULL,0,NULL}; +pCodeOpReg pic16_pc_postinc2 = {{PO_INDF0, "POSTINC2"}, -1, NULL, 0, NULL}; +pCodeOpReg pic16_pc_postdec2 = {{PO_INDF0, "POSTDEC2"}, -1, NULL, 0, NULL}; +pCodeOpReg pic16_pc_preinc2 = {{PO_INDF0, "PREINC2"}, -1, NULL, 0, NULL}; +pCodeOpReg pic16_pc_plusw2 = {{PO_INDF0, "PLUSW2"}, -1, NULL, 0, NULL}; + +pCodeOpReg pic16_pc_prodl = {{PO_PRODL, "PRODL"}, -1, NULL, 0, NULL}; +pCodeOpReg pic16_pc_prodh = {{PO_PRODH, "PRODH"}, -1, NULL, 0, NULL}; + +/* EEPROM registers */ +pCodeOpReg pic16_pc_eecon1 = {{PO_SFR_REGISTER, "EECON1"}, -1, NULL, 0, NULL}; +pCodeOpReg pic16_pc_eecon2 = {{PO_SFR_REGISTER, "EECON2"}, -1, NULL, 0, NULL}; +pCodeOpReg pic16_pc_eedata = {{PO_SFR_REGISTER, "EEDATA"}, -1, NULL, 0, NULL}; +pCodeOpReg pic16_pc_eeadr = {{PO_SFR_REGISTER, "EEADR"}, -1, NULL, 0, NULL}; + pCodeOpReg pic16_pc_kzero = {{PO_GPR_REGISTER, "KZ"}, -1, NULL,0,NULL}; pCodeOpReg pic16_pc_wsave = {{PO_GPR_REGISTER, "WSAVE"}, -1, NULL,0,NULL}; pCodeOpReg pic16_pc_ssave = {{PO_GPR_REGISTER, "SSAVE"}, -1, NULL,0,NULL}; +pCodeOpReg *pic16_stackpnt_lo; +pCodeOpReg *pic16_stackpnt_hi; +pCodeOpReg *pic16_stack_postinc; +pCodeOpReg *pic16_stack_postdec; +pCodeOpReg *pic16_stack_preinc; +pCodeOpReg *pic16_stack_plusw; + +pCodeOpReg *pic16_framepnt_lo; +pCodeOpReg *pic16_framepnt_hi; +pCodeOpReg *pic16_frame_postinc; +pCodeOpReg *pic16_frame_postdec; +pCodeOpReg *pic16_frame_preinc; +pCodeOpReg *pic16_frame_plusw; + +pCodeOpReg pic16_pc_gpsimio = {{PO_GPR_REGISTER, "GPSIMIO"}, -1, NULL, 0, NULL}; +pCodeOpReg pic16_pc_gpsimio2 = {{PO_GPR_REGISTER, "GPSIMIO2"}, -1, NULL, 0, NULL}; + +char *OPT_TYPE_STR[] = { "begin", "end" }; +char *LR_TYPE_STR[] = { "entry begin", "entry end", "exit begin", "exit end" }; + + static int mnemonics_initialized = 0; @@ -76,7 +143,9 @@ 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 pic16_debug_verbose = 1; /* Set true to inundate .asm file */ +int pic16_debug_verbose = 0; /* Set true to inundate .asm file */ + +int pic16_pcode_verbose = 0; //static int GpCodeSequenceNumber = 1; static int GpcFlowSeq = 1; @@ -86,11 +155,8 @@ extern void pic16_RegsUnMapLiveRanges(void); extern void pic16_BuildFlowTree(pBlock *pb); extern void pic16_pCodeRegOptimizeRegUsage(int level); extern int pic16_picIsInitialized(void); -#if !OPT_DISABLE_PIC || !OPT_DISABLE_PIC16 -// From pic/pcode.c: extern void SAFE_snprintf(char **str, size_t *size, const char *format, ...); extern int mnem2key(char const *mnem); -#endif // OPT_DISABLE_PIC || !OPT_DISABLE_PIC16 /****************************************************************/ /* Forward declarations */ @@ -120,6 +186,15 @@ extern void pic16_pCodeInsertAfter(pCode *pc1, pCode *pc2); extern pCodeOp *pic16_popCopyReg(pCodeOpReg *pc); pCodeOp *pic16_popCopyGPR2Bit(pCodeOp *pc, int bitval); void pic16_pCodeRegMapLiveRanges(pBlock *pb); +void OptimizeLocalRegs(void); +pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst); + +char *dumpPicOptype(PIC_OPTYPE type); + +pCodeOp *pic16_popGetLit2(int, pCodeOp *); +pCodeOp *pic16_popGetLit(int); +pCodeOp *pic16_popGetWithString(char *); +extern int inWparamList(char *s); /****************************************************************/ @@ -133,6 +208,7 @@ pCodeInstruction pic16_pciADDWF = { genericPrint}, POC_ADDWF, "ADDWF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -146,9 +222,11 @@ pCodeInstruction pic16_pciADDWF = { 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_W | PCC_REGISTER), // inCond - (PCC_REGISTER | PCC_Z) // outCond + (PCC_REGISTER | PCC_Z), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciADDFW = { @@ -158,6 +236,7 @@ pCodeInstruction pic16_pciADDFW = { genericPrint}, POC_ADDFW, "ADDWF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -171,9 +250,11 @@ pCodeInstruction pic16_pciADDFW = { 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_W | PCC_REGISTER), // inCond - (PCC_W | PCC_Z) // outCond + (PCC_W | PCC_Z), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciADDWFC = { // mdubuc - New @@ -183,6 +264,7 @@ pCodeInstruction pic16_pciADDWFC = { // mdubuc - New genericPrint}, POC_ADDWFC, "ADDWFC", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -196,9 +278,11 @@ pCodeInstruction pic16_pciADDWFC = { // mdubuc - New 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_W | PCC_REGISTER | PCC_C), // inCond - (PCC_REGISTER | PCC_Z) // outCond + (PCC_REGISTER | PCC_Z), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciADDFWC = { @@ -208,6 +292,7 @@ pCodeInstruction pic16_pciADDFWC = { genericPrint}, POC_ADDFWC, "ADDWFC", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -221,9 +306,11 @@ pCodeInstruction pic16_pciADDFWC = { 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_W | PCC_REGISTER | PCC_C), // inCond - (PCC_W | PCC_Z) // outCond + (PCC_W | PCC_Z), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciADDLW = { @@ -233,6 +320,7 @@ pCodeInstruction pic16_pciADDLW = { genericPrint}, POC_ADDLW, "ADDLW", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -246,9 +334,11 @@ pCodeInstruction pic16_pciADDLW = { 0, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_W | PCC_LITERAL), // inCond - (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N) // outCond + (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciANDLW = { @@ -258,6 +348,7 @@ pCodeInstruction pic16_pciANDLW = { genericPrint}, POC_ANDLW, "ANDLW", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -271,9 +362,11 @@ pCodeInstruction pic16_pciANDLW = { 0, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_W | PCC_LITERAL), // inCond - (PCC_W | PCC_Z | PCC_N) // outCond + (PCC_W | PCC_Z | PCC_N), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciANDWF = { @@ -283,6 +376,7 @@ pCodeInstruction pic16_pciANDWF = { genericPrint}, POC_ANDWF, "ANDWF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -296,9 +390,11 @@ pCodeInstruction pic16_pciANDWF = { 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_W | PCC_REGISTER), // inCond - (PCC_REGISTER | PCC_Z | PCC_N) // outCond + (PCC_REGISTER | PCC_Z | PCC_N), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciANDFW = { @@ -308,6 +404,7 @@ pCodeInstruction pic16_pciANDFW = { genericPrint}, POC_ANDFW, "ANDWF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -321,6 +418,7 @@ pCodeInstruction pic16_pciANDFW = { 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_W | PCC_REGISTER), // inCond (PCC_W | PCC_Z) // outCond @@ -333,6 +431,7 @@ pCodeInstruction pic16_pciBC = { // mdubuc - New genericPrint}, POC_BC, "BC", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -346,9 +445,11 @@ pCodeInstruction pic16_pciBC = { // mdubuc - New 0, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_REL_ADDR | PCC_C), // inCond - PCC_NONE // outCond + PCC_NONE, // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciBCF = { @@ -358,6 +459,7 @@ pCodeInstruction pic16_pciBCF = { genericPrint}, POC_BCF, "BCF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -371,9 +473,11 @@ pCodeInstruction pic16_pciBCF = { 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_BSF, (PCC_REGISTER | PCC_EXAMINE_PCOP), // inCond - PCC_REGISTER // outCond + PCC_REGISTER, // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciBN = { // mdubuc - New @@ -383,6 +487,7 @@ pCodeInstruction pic16_pciBN = { // mdubuc - New genericPrint}, POC_BN, "BN", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -396,9 +501,11 @@ pCodeInstruction pic16_pciBN = { // mdubuc - New 0, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_REL_ADDR | PCC_N), // inCond - PCC_NONE // outCond + PCC_NONE , // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciBNC = { // mdubuc - New @@ -408,6 +515,7 @@ pCodeInstruction pic16_pciBNC = { // mdubuc - New genericPrint}, POC_BNC, "BNC", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -421,9 +529,11 @@ pCodeInstruction pic16_pciBNC = { // mdubuc - New 0, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_REL_ADDR | PCC_C), // inCond - PCC_NONE // outCond + PCC_NONE , // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciBNN = { // mdubuc - New @@ -433,6 +543,7 @@ pCodeInstruction pic16_pciBNN = { // mdubuc - New genericPrint}, POC_BNN, "BNN", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -446,9 +557,11 @@ pCodeInstruction pic16_pciBNN = { // mdubuc - New 0, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_REL_ADDR | PCC_N), // inCond - PCC_NONE // outCond + PCC_NONE , // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciBNOV = { // mdubuc - New @@ -458,6 +571,7 @@ pCodeInstruction pic16_pciBNOV = { // mdubuc - New genericPrint}, POC_BNOV, "BNOV", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -471,9 +585,11 @@ pCodeInstruction pic16_pciBNOV = { // mdubuc - New 0, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_REL_ADDR | PCC_OV), // inCond - PCC_NONE // outCond + PCC_NONE , // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciBNZ = { // mdubuc - New @@ -483,6 +599,7 @@ pCodeInstruction pic16_pciBNZ = { // mdubuc - New genericPrint}, POC_BNZ, "BNZ", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -496,9 +613,11 @@ pCodeInstruction pic16_pciBNZ = { // mdubuc - New 0, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_REL_ADDR | PCC_Z), // inCond - PCC_NONE // outCond + PCC_NONE , // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciBOV = { // mdubuc - New @@ -508,6 +627,7 @@ pCodeInstruction pic16_pciBOV = { // mdubuc - New genericPrint}, POC_BOV, "BOV", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -521,9 +641,11 @@ pCodeInstruction pic16_pciBOV = { // mdubuc - New 0, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_REL_ADDR | PCC_OV), // inCond - PCC_NONE // outCond + PCC_NONE , // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciBRA = { // mdubuc - New @@ -533,6 +655,7 @@ pCodeInstruction pic16_pciBRA = { // mdubuc - New genericPrint}, POC_BRA, "BRA", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -546,9 +669,11 @@ pCodeInstruction pic16_pciBRA = { // mdubuc - New 0, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_REL_ADDR, // inCond - PCC_NONE // outCond + PCC_NONE , // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciBSF = { @@ -558,6 +683,7 @@ pCodeInstruction pic16_pciBSF = { genericPrint}, POC_BSF, "BSF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -571,9 +697,11 @@ pCodeInstruction pic16_pciBSF = { 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_BCF, (PCC_REGISTER | PCC_EXAMINE_PCOP), // inCond - (PCC_REGISTER | PCC_EXAMINE_PCOP) // outCond + (PCC_REGISTER | PCC_EXAMINE_PCOP), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciBTFSC = { @@ -583,6 +711,7 @@ pCodeInstruction pic16_pciBTFSC = { genericPrint}, POC_BTFSC, "BTFSC", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -596,9 +725,11 @@ pCodeInstruction pic16_pciBTFSC = { 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_BTFSS, (PCC_REGISTER | PCC_EXAMINE_PCOP), // inCond - PCC_EXAMINE_PCOP // outCond + PCC_EXAMINE_PCOP, // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciBTFSS = { @@ -608,6 +739,7 @@ pCodeInstruction pic16_pciBTFSS = { genericPrint}, POC_BTFSS, "BTFSS", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -621,9 +753,11 @@ pCodeInstruction pic16_pciBTFSS = { 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_BTFSC, (PCC_REGISTER | PCC_EXAMINE_PCOP), // inCond - PCC_EXAMINE_PCOP // outCond + PCC_EXAMINE_PCOP, // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciBTG = { // mdubuc - New @@ -633,6 +767,7 @@ pCodeInstruction pic16_pciBTG = { // mdubuc - New genericPrint}, POC_BTG, "BTG", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -646,9 +781,11 @@ pCodeInstruction pic16_pciBTG = { // mdubuc - New 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_REGISTER | PCC_EXAMINE_PCOP), // inCond - (PCC_REGISTER | PCC_EXAMINE_PCOP) // outCond + (PCC_REGISTER | PCC_EXAMINE_PCOP), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciBZ = { // mdubuc - New @@ -658,6 +795,7 @@ pCodeInstruction pic16_pciBZ = { // mdubuc - New genericPrint}, POC_BZ, "BZ", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -671,9 +809,11 @@ pCodeInstruction pic16_pciBZ = { // mdubuc - New 0, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_Z, // inCond - PCC_NONE // outCond + PCC_NONE, // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciCALL = { @@ -683,6 +823,7 @@ pCodeInstruction pic16_pciCALL = { genericPrint}, POC_CALL, "CALL", + 4, NULL, // from branch NULL, // to branch NULL, // label @@ -696,9 +837,11 @@ pCodeInstruction pic16_pciCALL = { 0, // RAM access bit 1, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_NONE, // inCond - PCC_NONE // outCond + PCC_NONE, // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciCOMF = { @@ -708,6 +851,7 @@ pCodeInstruction pic16_pciCOMF = { genericPrint}, POC_COMF, "COMF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -721,9 +865,11 @@ pCodeInstruction pic16_pciCOMF = { 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_REGISTER, // inCond - PCC_REGISTER // outCond + PCC_REGISTER , // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciCOMFW = { @@ -733,6 +879,7 @@ pCodeInstruction pic16_pciCOMFW = { genericPrint}, POC_COMFW, "COMF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -746,9 +893,11 @@ pCodeInstruction pic16_pciCOMFW = { 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_REGISTER, // inCond - PCC_W // outCond + PCC_W , // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciCLRF = { @@ -758,6 +907,7 @@ pCodeInstruction pic16_pciCLRF = { genericPrint}, POC_CLRF, "CLRF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -771,9 +921,11 @@ pCodeInstruction pic16_pciCLRF = { 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_REGISTER, // inCond - PCC_REGISTER // outCond + PCC_REGISTER , // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciCLRWDT = { @@ -783,6 +935,7 @@ pCodeInstruction pic16_pciCLRWDT = { genericPrint}, POC_CLRWDT, "CLRWDT", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -796,9 +949,11 @@ pCodeInstruction pic16_pciCLRWDT = { 0, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_NONE, // inCond - PCC_NONE // outCond + PCC_NONE , // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciCPFSEQ = { // mdubuc - New @@ -808,6 +963,7 @@ pCodeInstruction pic16_pciCPFSEQ = { // mdubuc - New genericPrint}, POC_CPFSEQ, "CPFSEQ", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -821,9 +977,11 @@ pCodeInstruction pic16_pciCPFSEQ = { // mdubuc - New 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_W | PCC_REGISTER), // inCond - PCC_NONE // outCond + PCC_NONE , // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciCPFSGT = { // mdubuc - New @@ -833,6 +991,7 @@ pCodeInstruction pic16_pciCPFSGT = { // mdubuc - New genericPrint}, POC_CPFSGT, "CPFSGT", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -846,9 +1005,11 @@ pCodeInstruction pic16_pciCPFSGT = { // mdubuc - New 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_W | PCC_REGISTER), // inCond - PCC_NONE // outCond + PCC_NONE , // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciCPFSLT = { // mdubuc - New @@ -858,6 +1019,7 @@ pCodeInstruction pic16_pciCPFSLT = { // mdubuc - New genericPrint}, POC_CPFSLT, "CPFSLT", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -871,9 +1033,11 @@ pCodeInstruction pic16_pciCPFSLT = { // mdubuc - New 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_W | PCC_REGISTER), // inCond - PCC_NONE // outCond + PCC_NONE , // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciDAW = { @@ -883,6 +1047,7 @@ pCodeInstruction pic16_pciDAW = { genericPrint}, POC_DAW, "DAW", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -896,9 +1061,11 @@ pCodeInstruction pic16_pciDAW = { 0, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_W, // inCond - (PCC_W | PCC_C) // outCond + (PCC_W | PCC_C), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciDCFSNZ = { // mdubuc - New @@ -908,6 +1075,7 @@ pCodeInstruction pic16_pciDCFSNZ = { // mdubuc - New genericPrint}, POC_DCFSNZ, "DCFSNZ", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -921,9 +1089,11 @@ pCodeInstruction pic16_pciDCFSNZ = { // mdubuc - New 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_REGISTER, // inCond - PCC_REGISTER // outCond + PCC_REGISTER , // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciDCFSNZW = { // mdubuc - New @@ -933,6 +1103,7 @@ pCodeInstruction pic16_pciDCFSNZW = { // mdubuc - New genericPrint}, POC_DCFSNZW, "DCFSNZ", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -946,9 +1117,11 @@ pCodeInstruction pic16_pciDCFSNZW = { // mdubuc - New 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_REGISTER, // inCond - PCC_W // outCond + PCC_W , // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciDECF = { @@ -958,6 +1131,7 @@ pCodeInstruction pic16_pciDECF = { genericPrint}, POC_DECF, "DECF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -971,9 +1145,11 @@ pCodeInstruction pic16_pciDECF = { 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_REGISTER, // inCond - PCC_REGISTER // outCond + PCC_REGISTER , // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciDECFW = { @@ -983,6 +1159,7 @@ pCodeInstruction pic16_pciDECFW = { genericPrint}, POC_DECFW, "DECF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -996,9 +1173,11 @@ pCodeInstruction pic16_pciDECFW = { 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_REGISTER, // inCond - PCC_W // outCond + PCC_W , // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciDECFSZ = { @@ -1008,6 +1187,7 @@ pCodeInstruction pic16_pciDECFSZ = { genericPrint}, POC_DECFSZ, "DECFSZ", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1021,9 +1201,11 @@ pCodeInstruction pic16_pciDECFSZ = { 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_REGISTER, // inCond - PCC_REGISTER // outCond + PCC_REGISTER , // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciDECFSZW = { @@ -1033,6 +1215,7 @@ pCodeInstruction pic16_pciDECFSZW = { genericPrint}, POC_DECFSZW, "DECFSZ", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1046,9 +1229,11 @@ pCodeInstruction pic16_pciDECFSZW = { 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_REGISTER, // inCond - PCC_W // outCond + PCC_W , // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciGOTO = { @@ -1058,6 +1243,7 @@ pCodeInstruction pic16_pciGOTO = { genericPrint}, POC_GOTO, "GOTO", + 4, NULL, // from branch NULL, // to branch NULL, // label @@ -1071,9 +1257,11 @@ pCodeInstruction pic16_pciGOTO = { 0, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_REL_ADDR, // inCond - PCC_NONE // outCond + PCC_NONE , // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciINCF = { @@ -1083,6 +1271,7 @@ pCodeInstruction pic16_pciINCF = { genericPrint}, POC_INCF, "INCF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1096,9 +1285,11 @@ pCodeInstruction pic16_pciINCF = { 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_REGISTER, // inCond - (PCC_REGISTER | PCC_C | PCC_DC | PCC_Z | PCC_OV | PCC_N) // outCond + (PCC_REGISTER | PCC_C | PCC_DC | PCC_Z | PCC_OV | PCC_N), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciINCFW = { @@ -1108,6 +1299,7 @@ pCodeInstruction pic16_pciINCFW = { genericPrint}, POC_INCFW, "INCF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1121,9 +1313,11 @@ pCodeInstruction pic16_pciINCFW = { 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_REGISTER, // inCond - PCC_W // outCond + PCC_W , // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciINCFSZ = { @@ -1133,6 +1327,7 @@ pCodeInstruction pic16_pciINCFSZ = { genericPrint}, POC_INCFSZ, "INCFSZ", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1146,9 +1341,11 @@ pCodeInstruction pic16_pciINCFSZ = { 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand - POC_NOP, + 0, // second literal operand + POC_INFSNZ, PCC_REGISTER, // inCond - PCC_REGISTER // outCond + PCC_REGISTER , // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciINCFSZW = { @@ -1158,6 +1355,7 @@ pCodeInstruction pic16_pciINCFSZW = { genericPrint}, POC_INCFSZW, "INCFSZ", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1171,9 +1369,11 @@ pCodeInstruction pic16_pciINCFSZW = { 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand - POC_NOP, + 0, // second literal operand + POC_INFSNZW, PCC_REGISTER, // inCond - PCC_W // outCond + PCC_W , // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciINFSNZ = { // mdubuc - New @@ -1182,7 +1382,8 @@ pCodeInstruction pic16_pciINFSNZ = { // mdubuc - New genericDestruct, genericPrint}, POC_INFSNZ, - "INCFSNZ", + "INFSNZ", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1196,9 +1397,39 @@ pCodeInstruction pic16_pciINFSNZ = { // mdubuc - New 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand - POC_NOP, + 0, // second literal operand + POC_INCFSZ, + PCC_REGISTER, // inCond + PCC_REGISTER , // outCond + PCI_MAGIC +}; + +pCodeInstruction pic16_pciINFSNZW = { // vrokas - New + {PC_OPCODE, NULL, NULL, 0, NULL, + // AnalyzeSKIP, + genericDestruct, + genericPrint}, + POC_INFSNZW, + "INFSNZ", + 2, + NULL, // from branch + NULL, // to branch + NULL, // label + NULL, // operand + NULL, // flow block + NULL, // C source + 3, // num ops + 0,0, // dest, bit instruction + 1,1, // branch, skip + 0, // literal operand + 1, // RAM access bit + 0, // fast call/return mode select bit + 0, // second memory operand + 0, // second literal operand + POC_INCFSZW, PCC_REGISTER, // inCond - PCC_REGISTER // outCond + PCC_W , // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciIORWF = { @@ -1208,6 +1439,7 @@ pCodeInstruction pic16_pciIORWF = { genericPrint}, POC_IORWF, "IORWF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1221,9 +1453,11 @@ pCodeInstruction pic16_pciIORWF = { 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_W | PCC_REGISTER), // inCond - (PCC_REGISTER | PCC_Z | PCC_N) // outCond + (PCC_REGISTER | PCC_Z | PCC_N), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciIORFW = { @@ -1233,6 +1467,7 @@ pCodeInstruction pic16_pciIORFW = { genericPrint}, POC_IORFW, "IORWF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1246,9 +1481,11 @@ pCodeInstruction pic16_pciIORFW = { 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_W | PCC_REGISTER), // inCond - (PCC_W | PCC_Z | PCC_N) // outCond + (PCC_W | PCC_Z | PCC_N), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciIORLW = { @@ -1258,6 +1495,7 @@ pCodeInstruction pic16_pciIORLW = { genericPrint}, POC_IORLW, "IORLW", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1271,9 +1509,11 @@ pCodeInstruction pic16_pciIORLW = { 0, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_W | PCC_LITERAL), // inCond - (PCC_W | PCC_Z | PCC_N) // outCond + (PCC_W | PCC_Z | PCC_N), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciLFSR = { // mdubuc - New @@ -1283,6 +1523,7 @@ pCodeInstruction pic16_pciLFSR = { // mdubuc - New genericPrint}, POC_LFSR, "LFSR", + 4, NULL, // from branch NULL, // to branch NULL, // label @@ -1296,10 +1537,11 @@ pCodeInstruction pic16_pciLFSR = { // mdubuc - New 0, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 1, // second literal operand POC_NOP, - (PCC_REGISTER | PCC_LITERAL), // mdubuc - Should we use a special syntax for - // f (identifies FSRx)? - PCC_REGISTER // outCond + (PCC_REGISTER | PCC_LITERAL), + PCC_REGISTER, // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciMOVF = { @@ -1309,6 +1551,7 @@ pCodeInstruction pic16_pciMOVF = { genericPrint}, POC_MOVF, "MOVF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1322,9 +1565,11 @@ pCodeInstruction pic16_pciMOVF = { 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_REGISTER, // inCond - (PCC_Z | PCC_N) // outCond + (PCC_Z | PCC_N), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciMOVFW = { @@ -1334,6 +1579,7 @@ pCodeInstruction pic16_pciMOVFW = { genericPrint}, POC_MOVFW, "MOVF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1347,9 +1593,11 @@ pCodeInstruction pic16_pciMOVFW = { 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_REGISTER, // inCond - (PCC_W | PCC_Z) // outCond + (PCC_W | PCC_Z), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciMOVFF = { // mdubuc - New @@ -1359,6 +1607,7 @@ pCodeInstruction pic16_pciMOVFF = { // mdubuc - New genericPrint}, POC_MOVFF, "MOVFF", + 4, NULL, // from branch NULL, // to branch NULL, // label @@ -1372,9 +1621,11 @@ pCodeInstruction pic16_pciMOVFF = { // mdubuc - New 0, // RAM access bit 0, // fast call/return mode select bit 1, // second memory operand + 0, // second literal operand POC_NOP, PCC_REGISTER, // inCond - PCC_REGISTER2 // outCond + PCC_REGISTER, // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciMOVLB = { // mdubuc - New @@ -1383,6 +1634,7 @@ pCodeInstruction pic16_pciMOVLB = { // mdubuc - New genericPrint}, POC_MOVLB, "MOVLB", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1396,9 +1648,11 @@ pCodeInstruction pic16_pciMOVLB = { // mdubuc - New 0, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_NONE | PCC_LITERAL), // inCond - PCC_REGISTER // outCond - BSR + PCC_REGISTER, // outCond - BSR + PCI_MAGIC }; pCodeInstruction pic16_pciMOVLW = { @@ -1407,6 +1661,7 @@ pCodeInstruction pic16_pciMOVLW = { genericPrint}, POC_MOVLW, "MOVLW", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1420,9 +1675,11 @@ pCodeInstruction pic16_pciMOVLW = { 0, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_NONE | PCC_LITERAL), // inCond - PCC_W // outCond + PCC_W, // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciMOVWF = { @@ -1432,6 +1689,7 @@ pCodeInstruction pic16_pciMOVWF = { genericPrint}, POC_MOVWF, "MOVWF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1445,9 +1703,11 @@ pCodeInstruction pic16_pciMOVWF = { 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_REGISTER, // inCond - PCC_W // outCond + PCC_W, // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciMULLW = { // mdubuc - New @@ -1456,6 +1716,7 @@ pCodeInstruction pic16_pciMULLW = { // mdubuc - New genericPrint}, POC_MULLW, "MULLW", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1469,9 +1730,11 @@ pCodeInstruction pic16_pciMULLW = { // mdubuc - New 0, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_W | PCC_LITERAL), // inCond - PCC_REGISTER // outCond - PROD + PCC_REGISTER, // outCond - PROD + PCI_MAGIC }; pCodeInstruction pic16_pciMULWF = { // mdubuc - New @@ -1480,6 +1743,7 @@ pCodeInstruction pic16_pciMULWF = { // mdubuc - New genericPrint}, POC_MULWF, "MULWF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1493,9 +1757,11 @@ pCodeInstruction pic16_pciMULWF = { // mdubuc - New 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_W | PCC_REGISTER), // inCond - PCC_REGISTER // outCond - PROD + PCC_REGISTER, // outCond - PROD + PCI_MAGIC }; pCodeInstruction pic16_pciNEGF = { // mdubuc - New @@ -1504,6 +1770,7 @@ pCodeInstruction pic16_pciNEGF = { // mdubuc - New genericPrint}, POC_NEGF, "NEGF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1517,9 +1784,11 @@ pCodeInstruction pic16_pciNEGF = { // mdubuc - New 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_REGISTER, // inCond - (PCC_REGISTER | PCC_C | PCC_DC | PCC_OV | PCC_N) // outCond + (PCC_REGISTER | PCC_C | PCC_DC | PCC_OV | PCC_N), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciNOP = { @@ -1528,6 +1797,7 @@ pCodeInstruction pic16_pciNOP = { genericPrint}, POC_NOP, "NOP", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1541,9 +1811,11 @@ pCodeInstruction pic16_pciNOP = { 0, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_NONE, // inCond - PCC_NONE // outCond + PCC_NONE, // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciPOP = { // mdubuc - New @@ -1552,6 +1824,7 @@ pCodeInstruction pic16_pciPOP = { // mdubuc - New genericPrint}, POC_POP, "POP", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1565,9 +1838,11 @@ pCodeInstruction pic16_pciPOP = { // mdubuc - New 0, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_NONE, // inCond - PCC_NONE // outCond + PCC_NONE , // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciPUSH = { @@ -1576,6 +1851,7 @@ pCodeInstruction pic16_pciPUSH = { genericPrint}, POC_PUSH, "PUSH", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1589,9 +1865,11 @@ pCodeInstruction pic16_pciPUSH = { 0, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_NONE, // inCond - PCC_NONE // outCond + PCC_NONE , // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciRCALL = { // mdubuc - New @@ -1600,6 +1878,7 @@ pCodeInstruction pic16_pciRCALL = { // mdubuc - New genericPrint}, POC_RCALL, "RCALL", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1613,9 +1892,11 @@ pCodeInstruction pic16_pciRCALL = { // mdubuc - New 0, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_REL_ADDR, // inCond - PCC_NONE // outCond + PCC_NONE , // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciRETFIE = { @@ -1625,6 +1906,7 @@ pCodeInstruction pic16_pciRETFIE = { genericPrint}, POC_RETFIE, "RETFIE", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1638,9 +1920,11 @@ pCodeInstruction pic16_pciRETFIE = { 0, // RAM access bit 1, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_NONE, // inCond - PCC_NONE // outCond (not true... affects the GIE bit too) + PCC_NONE, // outCond (not true... affects the GIE bit too) + PCI_MAGIC }; pCodeInstruction pic16_pciRETLW = { @@ -1650,6 +1934,7 @@ pCodeInstruction pic16_pciRETLW = { genericPrint}, POC_RETLW, "RETLW", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1663,9 +1948,11 @@ pCodeInstruction pic16_pciRETLW = { 0, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_LITERAL, // inCond - PCC_W // outCond + PCC_W, // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciRETURN = { @@ -1675,6 +1962,7 @@ pCodeInstruction pic16_pciRETURN = { genericPrint}, POC_RETURN, "RETURN", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1688,9 +1976,11 @@ pCodeInstruction pic16_pciRETURN = { 0, // RAM access bit 1, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_NONE, // inCond - PCC_NONE // outCond + PCC_NONE, // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciRLCF = { // mdubuc - New {PC_OPCODE, NULL, NULL, 0, NULL, @@ -1699,6 +1989,7 @@ pCodeInstruction pic16_pciRLCF = { // mdubuc - New genericPrint}, POC_RLCF, "RLCF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1712,9 +2003,11 @@ pCodeInstruction pic16_pciRLCF = { // mdubuc - New 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_C | PCC_REGISTER), // inCond - (PCC_REGISTER | PCC_C | PCC_Z | PCC_N) // outCond + (PCC_REGISTER | PCC_C | PCC_Z | PCC_N), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciRLCFW = { // mdubuc - New @@ -1724,6 +2017,7 @@ pCodeInstruction pic16_pciRLCFW = { // mdubuc - New genericPrint}, POC_RLCFW, "RLCF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1737,9 +2031,11 @@ pCodeInstruction pic16_pciRLCFW = { // mdubuc - New 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_C | PCC_REGISTER), // inCond - (PCC_W | PCC_C | PCC_Z | PCC_N) // outCond + (PCC_W | PCC_C | PCC_Z | PCC_N), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciRLNCF = { // mdubuc - New @@ -1749,6 +2045,7 @@ pCodeInstruction pic16_pciRLNCF = { // mdubuc - New genericPrint}, POC_RLNCF, "RLNCF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1762,9 +2059,11 @@ pCodeInstruction pic16_pciRLNCF = { // mdubuc - New 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_REGISTER, // inCond - (PCC_REGISTER | PCC_Z | PCC_N) // outCond + (PCC_REGISTER | PCC_Z | PCC_N), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciRLNCFW = { // mdubuc - New {PC_OPCODE, NULL, NULL, 0, NULL, @@ -1773,6 +2072,7 @@ pCodeInstruction pic16_pciRLNCFW = { // mdubuc - New genericPrint}, POC_RLNCFW, "RLNCF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1786,9 +2086,11 @@ pCodeInstruction pic16_pciRLNCFW = { // mdubuc - New 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_REGISTER, // inCond - (PCC_W | PCC_Z | PCC_N) // outCond + (PCC_W | PCC_Z | PCC_N), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciRRCF = { // mdubuc - New {PC_OPCODE, NULL, NULL, 0, NULL, @@ -1797,6 +2099,7 @@ pCodeInstruction pic16_pciRRCF = { // mdubuc - New genericPrint}, POC_RRCF, "RRCF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1810,9 +2113,11 @@ pCodeInstruction pic16_pciRRCF = { // mdubuc - New 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_C | PCC_REGISTER), // inCond - (PCC_REGISTER | PCC_C | PCC_Z | PCC_N) // outCond + (PCC_REGISTER | PCC_C | PCC_Z | PCC_N), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciRRCFW = { // mdubuc - New {PC_OPCODE, NULL, NULL, 0, NULL, @@ -1821,6 +2126,7 @@ pCodeInstruction pic16_pciRRCFW = { // mdubuc - New genericPrint}, POC_RRCFW, "RRCF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1834,9 +2140,11 @@ pCodeInstruction pic16_pciRRCFW = { // mdubuc - New 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_C | PCC_REGISTER), // inCond - (PCC_W | PCC_C | PCC_Z | PCC_N) // outCond + (PCC_W | PCC_C | PCC_Z | PCC_N), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciRRNCF = { // mdubuc - New {PC_OPCODE, NULL, NULL, 0, NULL, @@ -1845,6 +2153,7 @@ pCodeInstruction pic16_pciRRNCF = { // mdubuc - New genericPrint}, POC_RRNCF, "RRNCF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1858,9 +2167,11 @@ pCodeInstruction pic16_pciRRNCF = { // mdubuc - New 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_REGISTER, // inCond - (PCC_REGISTER | PCC_Z | PCC_N) // outCond + (PCC_REGISTER | PCC_Z | PCC_N), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciRRNCFW = { // mdubuc - New @@ -1870,6 +2181,7 @@ pCodeInstruction pic16_pciRRNCFW = { // mdubuc - New genericPrint}, POC_RRNCFW, "RRNCF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1883,9 +2195,11 @@ pCodeInstruction pic16_pciRRNCFW = { // mdubuc - New 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_REGISTER, // inCond - (PCC_W | PCC_Z | PCC_N) // outCond + (PCC_W | PCC_Z | PCC_N), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciSETF = { // mdubuc - New @@ -1895,6 +2209,7 @@ pCodeInstruction pic16_pciSETF = { // mdubuc - New genericPrint}, POC_SETF, "SETF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1908,9 +2223,11 @@ pCodeInstruction pic16_pciSETF = { // mdubuc - New 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_REGISTER, // inCond - PCC_REGISTER // outCond + PCC_REGISTER , // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciSUBLW = { @@ -1920,6 +2237,7 @@ pCodeInstruction pic16_pciSUBLW = { genericPrint}, POC_SUBLW, "SUBLW", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1933,9 +2251,11 @@ pCodeInstruction pic16_pciSUBLW = { 0, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_W | PCC_LITERAL), // inCond - (PCC_W | PCC_C | PCC_DC | PCC_Z | PCC_OV | PCC_N) // outCond + (PCC_W | PCC_C | PCC_DC | PCC_Z | PCC_OV | PCC_N), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciSUBFWB = { @@ -1945,6 +2265,7 @@ pCodeInstruction pic16_pciSUBFWB = { genericPrint}, POC_SUBFWB, "SUBFWB", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1958,9 +2279,11 @@ pCodeInstruction pic16_pciSUBFWB = { 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_W | PCC_REGISTER | PCC_C), // inCond - (PCC_W | PCC_C | PCC_DC | PCC_Z | PCC_OV | PCC_N) // outCond + (PCC_W | PCC_C | PCC_DC | PCC_Z | PCC_OV | PCC_N), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciSUBWF = { @@ -1970,6 +2293,7 @@ pCodeInstruction pic16_pciSUBWF = { genericPrint}, POC_SUBWF, "SUBWF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -1983,9 +2307,11 @@ pCodeInstruction pic16_pciSUBWF = { 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_W | PCC_REGISTER), // inCond - (PCC_REGISTER | PCC_Z) // outCond + (PCC_REGISTER | PCC_Z), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciSUBFW = { @@ -1995,6 +2321,7 @@ pCodeInstruction pic16_pciSUBFW = { genericPrint}, POC_SUBFW, "SUBWF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -2008,9 +2335,11 @@ pCodeInstruction pic16_pciSUBFW = { 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_W | PCC_REGISTER), // inCond - (PCC_W | PCC_Z | PCC_OV | PCC_N) // outCond + (PCC_W | PCC_Z | PCC_OV | PCC_N), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciSUBFWB_D1 = { // mdubuc - New @@ -2020,6 +2349,7 @@ pCodeInstruction pic16_pciSUBFWB_D1 = { // mdubuc - New genericPrint}, POC_SUBFWB_D1, "SUBFWB", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -2033,9 +2363,11 @@ pCodeInstruction pic16_pciSUBFWB_D1 = { // mdubuc - New 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_W | PCC_REGISTER | PCC_C), // inCond - (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N) // outCond + (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciSUBFWB_D0 = { // mdubuc - New @@ -2045,6 +2377,7 @@ pCodeInstruction pic16_pciSUBFWB_D0 = { // mdubuc - New genericPrint}, POC_SUBFWB_D0, "SUBFWB", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -2058,9 +2391,11 @@ pCodeInstruction pic16_pciSUBFWB_D0 = { // mdubuc - New 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_W | PCC_REGISTER | PCC_C), // inCond - (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N) // outCond + (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciSUBWFB_D1 = { // mdubuc - New @@ -2070,6 +2405,7 @@ pCodeInstruction pic16_pciSUBWFB_D1 = { // mdubuc - New genericPrint}, POC_SUBWFB_D1, "SUBWFB", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -2083,9 +2419,11 @@ pCodeInstruction pic16_pciSUBWFB_D1 = { // mdubuc - New 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_W | PCC_REGISTER | PCC_C), // inCond - (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N) // outCond + (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciSUBWFB_D0 = { // mdubuc - New @@ -2095,6 +2433,7 @@ pCodeInstruction pic16_pciSUBWFB_D0 = { // mdubuc - New genericPrint}, POC_SUBWFB_D0, "SUBWFB", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -2108,9 +2447,11 @@ pCodeInstruction pic16_pciSUBWFB_D0 = { // mdubuc - New 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_W | PCC_REGISTER | PCC_C), // inCond - (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N) // outCond + (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciSWAPF = { @@ -2120,6 +2461,7 @@ pCodeInstruction pic16_pciSWAPF = { genericPrint}, POC_SWAPF, "SWAPF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -2133,9 +2475,11 @@ pCodeInstruction pic16_pciSWAPF = { 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_REGISTER), // inCond - (PCC_REGISTER) // outCond + (PCC_REGISTER), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciSWAPFW = { @@ -2145,6 +2489,7 @@ pCodeInstruction pic16_pciSWAPFW = { genericPrint}, POC_SWAPFW, "SWAPF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -2158,38 +2503,228 @@ pCodeInstruction pic16_pciSWAPFW = { 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_REGISTER), // inCond - (PCC_W) // outCond + (PCC_W), // outCond + PCI_MAGIC }; +pCodeInstruction pic16_pciTBLRD = { // patch 15 + {PC_OPCODE, NULL, NULL, 0, NULL, + genericDestruct, + genericPrint}, + POC_TBLRD, + "TBLRD*", + 2, + 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 + 0, // RAM access bit + 0, // fast call/return mode select bit + 0, // second memory operand + 0, // second literal operand + POC_NOP, + PCC_NONE, // inCond + PCC_NONE , // outCond + PCI_MAGIC +}; -#if 0 -// mdubuc - Remove TRIS +pCodeInstruction pic16_pciTBLRD_POSTINC = { // patch 15 + {PC_OPCODE, NULL, NULL, 0, NULL, + genericDestruct, + genericPrint}, + POC_TBLRD_POSTINC, + "TBLRD*+", + 2, + 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 + 0, // RAM access bit + 0, // fast call/return mode select bit + 0, // second memory operand + 0, // second literal operand + POC_NOP, + PCC_NONE, // inCond + PCC_NONE , // outCond + PCI_MAGIC +}; -pCodeInstruction pic16_pciTRIS = { +pCodeInstruction pic16_pciTBLRD_POSTDEC = { // patch 15 {PC_OPCODE, NULL, NULL, 0, NULL, - // genericAnalyze, genericDestruct, genericPrint}, - POC_TRIS, - "TRIS", + POC_TBLRD_POSTDEC, + "TBLRD*-", + 2, NULL, // from branch NULL, // to branch NULL, // label NULL, // operand NULL, // flow block NULL, // C source - 1, // num ops + 0, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip 0, // literal operand + 0, // RAM access bit + 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, - PCC_NONE, // inCond - PCC_REGISTER // outCond + PCC_NONE, // inCond + PCC_NONE , // outCond + PCI_MAGIC +}; + +pCodeInstruction pic16_pciTBLRD_PREINC = { // patch 15 + {PC_OPCODE, NULL, NULL, 0, NULL, + genericDestruct, + genericPrint}, + POC_TBLRD_PREINC, + "TBLRD+*", + 2, + 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 + 0, // RAM access bit + 0, // fast call/return mode select bit + 0, // second memory operand + 0, // second literal operand + POC_NOP, + PCC_NONE, // inCond + PCC_NONE , // outCond + PCI_MAGIC +}; + +pCodeInstruction pic16_pciTBLWT = { // patch 15 + {PC_OPCODE, NULL, NULL, 0, NULL, + genericDestruct, + genericPrint}, + POC_TBLWT, + "TBLWT*", + 2, + 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 + 0, // RAM access bit + 0, // fast call/return mode select bit + 0, // second memory operand + 0, // second literal operand + POC_NOP, + PCC_NONE, // inCond + PCC_NONE , // outCond + PCI_MAGIC +}; + +pCodeInstruction pic16_pciTBLWT_POSTINC = { // patch 15 + {PC_OPCODE, NULL, NULL, 0, NULL, + genericDestruct, + genericPrint}, + POC_TBLWT_POSTINC, + "TBLWT*+", + 2, + 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 + 0, // RAM access bit + 0, // fast call/return mode select bit + 0, // second memory operand + 0, // second literal operand + POC_NOP, + PCC_NONE, // inCond + PCC_NONE , // outCond + PCI_MAGIC +}; + +pCodeInstruction pic16_pciTBLWT_POSTDEC = { // patch 15 + {PC_OPCODE, NULL, NULL, 0, NULL, + genericDestruct, + genericPrint}, + POC_TBLWT_POSTDEC, + "TBLWT*-", + 2, + 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 + 0, // RAM access bit + 0, // fast call/return mode select bit + 0, // second memory operand + 0, // second literal operand + POC_NOP, + PCC_NONE, // inCond + PCC_NONE , // outCond + PCI_MAGIC +}; + +pCodeInstruction pic16_pciTBLWT_PREINC = { // patch 15 + {PC_OPCODE, NULL, NULL, 0, NULL, + genericDestruct, + genericPrint}, + POC_TBLWT_PREINC, + "TBLWT+*", + 2, + 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 + 0, // RAM access bit + 0, // fast call/return mode select bit + 0, // second memory operand + 0, // second literal operand + POC_NOP, + PCC_NONE, // inCond + PCC_NONE , // outCond + PCI_MAGIC }; -#endif pCodeInstruction pic16_pciTSTFSZ = { // mdubuc - New {PC_OPCODE, NULL, NULL, 0, NULL, @@ -2198,6 +2733,7 @@ pCodeInstruction pic16_pciTSTFSZ = { // mdubuc - New genericPrint}, POC_TSTFSZ, "TSTFSZ", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -2211,9 +2747,11 @@ pCodeInstruction pic16_pciTSTFSZ = { // mdubuc - New 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, PCC_REGISTER, // inCond - PCC_NONE // outCond + PCC_NONE, // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciXORWF = { @@ -2223,6 +2761,7 @@ pCodeInstruction pic16_pciXORWF = { genericPrint}, POC_XORWF, "XORWF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -2236,9 +2775,11 @@ pCodeInstruction pic16_pciXORWF = { 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_W | PCC_REGISTER), // inCond - (PCC_REGISTER | PCC_Z | PCC_N) // outCond + (PCC_REGISTER | PCC_Z | PCC_N), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciXORFW = { @@ -2248,6 +2789,7 @@ pCodeInstruction pic16_pciXORFW = { genericPrint}, POC_XORFW, "XORWF", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -2261,9 +2803,11 @@ pCodeInstruction pic16_pciXORFW = { 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_W | PCC_REGISTER), // inCond - (PCC_W | PCC_Z | PCC_N) // outCond + (PCC_W | PCC_Z | PCC_N), // outCond + PCI_MAGIC }; pCodeInstruction pic16_pciXORLW = { @@ -2273,6 +2817,7 @@ pCodeInstruction pic16_pciXORLW = { genericPrint}, POC_XORLW, "XORLW", + 2, NULL, // from branch NULL, // to branch NULL, // label @@ -2286,18 +2831,47 @@ pCodeInstruction pic16_pciXORLW = { 1, // RAM access bit 0, // fast call/return mode select bit 0, // second memory operand + 0, // second literal operand POC_NOP, (PCC_W | PCC_LITERAL), // inCond - (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_N) // outCond + (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_N), // outCond + PCI_MAGIC +}; + + +pCodeInstruction pic16_pciBANKSEL = { + {PC_OPCODE, NULL, NULL, 0, NULL, + genericDestruct, + genericPrint}, + POC_BANKSEL, + "BANKSEL", + 2, + 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 + 0, // RAM access bit + 0, // fast call/return mode select bit + 0, // second memory operand + 0, // second literal operand + POC_NOP, + PCC_NONE, // inCond + PCC_NONE, // outCond + PCI_MAGIC }; #define MAX_PIC16MNEMONICS 100 pCodeInstruction *pic16Mnemonics[MAX_PIC16MNEMONICS]; +//#define USE_VSNPRINTF #if OPT_DISABLE_PIC -/* This definition needs to be part of configure.in */ -// #define USE_VSNPRINTF #ifdef USE_VSNPRINTF // Alas, vsnprintf is not ANSI standard, and does not exist @@ -2334,8 +2908,7 @@ void SAFE_snprintf(char **str, size_t *size, const char *format, ...) } -#else // USE_VSNPRINTF - +#else // This version is *not* safe, despite the name. void SAFE_snprintf(char **str, size_t *size, const char *format, ...) @@ -2365,10 +2938,9 @@ void SAFE_snprintf(char **str, size_t *size, const char *format, ...) } #endif // USE_VSNPRINTF - -#endif // OPT_DISABLE_PIC - +#endif +extern set *externs; extern void pic16_initStack(int base_address, int size); extern regs *pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias); extern regs *pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias); @@ -2378,39 +2950,143 @@ void pic16_pCodeInitRegisters(void) { static int initialized=0; - if(initialized) - return; - initialized = 1; - - pic16_initStack(0xfff, 8); - pic16_init_pic(port->processor); + if(initialized) + return; + + initialized = 1; + +// pic16_initStack(0xfff, 8); + pic16_init_pic(port->processor); + + pic16_pc_status.r = pic16_allocProcessorRegister(IDX_STATUS,"STATUS", PO_STATUS, 0x80); + pic16_pc_pcl.r = pic16_allocProcessorRegister(IDX_PCL,"PCL", PO_PCL, 0x80); + pic16_pc_pclath.r = pic16_allocProcessorRegister(IDX_PCLATH,"PCLATH", PO_PCLATH, 0x80); + pic16_pc_pclatu.r = pic16_allocProcessorRegister(IDX_PCLATU,"PCLATU", PO_PCLATU, 0x80); + pic16_pc_intcon.r = pic16_allocProcessorRegister(IDX_INTCON,"INTCON", PO_INTCON, 0x80); + pic16_pc_wreg.r = pic16_allocProcessorRegister(IDX_WREG,"WREG", PO_WREG, 0x80); + pic16_pc_bsr.r = pic16_allocProcessorRegister(IDX_BSR,"BSR", PO_BSR, 0x80); + + pic16_pc_tosl.r = pic16_allocProcessorRegister(IDX_TOSL,"TOSL", PO_SFR_REGISTER, 0x80); + pic16_pc_tosh.r = pic16_allocProcessorRegister(IDX_TOSH,"TOSH", PO_SFR_REGISTER, 0x80); + pic16_pc_tosu.r = pic16_allocProcessorRegister(IDX_TOSU,"TOSU", PO_SFR_REGISTER, 0x80); + + pic16_pc_tblptrl.r = pic16_allocProcessorRegister(IDX_TBLPTRL,"TBLPTRL", PO_SFR_REGISTER, 0x80); + pic16_pc_tblptrh.r = pic16_allocProcessorRegister(IDX_TBLPTRH,"TBLPTRH", PO_SFR_REGISTER, 0x80); + pic16_pc_tblptru.r = pic16_allocProcessorRegister(IDX_TBLPTRU,"TBLPTRU", PO_SFR_REGISTER, 0x80); + pic16_pc_tablat.r = pic16_allocProcessorRegister(IDX_TABLAT,"TABLAT", PO_SFR_REGISTER, 0x80); + + pic16_pc_fsr0l.r = pic16_allocProcessorRegister(IDX_FSR0L, "FSR0L", PO_FSR0, 0x80); + pic16_pc_fsr0h.r = pic16_allocProcessorRegister(IDX_FSR0H, "FSR0H", PO_FSR0, 0x80); + pic16_pc_fsr1l.r = pic16_allocProcessorRegister(IDX_FSR1L, "FSR1L", PO_FSR0, 0x80); + pic16_pc_fsr1h.r = pic16_allocProcessorRegister(IDX_FSR1H, "FSR1H", PO_FSR0, 0x80); + pic16_pc_fsr2l.r = pic16_allocProcessorRegister(IDX_FSR2L, "FSR2L", PO_FSR0, 0x80); + pic16_pc_fsr2h.r = pic16_allocProcessorRegister(IDX_FSR2H, "FSR2H", PO_FSR0, 0x80); + + pic16_stackpnt_lo = &pic16_pc_fsr1l; + pic16_stackpnt_hi = &pic16_pc_fsr1h; + pic16_stack_postdec = &pic16_pc_postdec1; + pic16_stack_postinc = &pic16_pc_postinc1; + pic16_stack_preinc = &pic16_pc_preinc1; + pic16_stack_plusw = &pic16_pc_plusw1; + + pic16_framepnt_lo = &pic16_pc_fsr2l; + pic16_framepnt_hi = &pic16_pc_fsr2h; + pic16_frame_postdec = &pic16_pc_postdec2; + pic16_frame_postinc = &pic16_pc_postinc2; + pic16_frame_preinc = &pic16_pc_preinc2; + pic16_frame_plusw = &pic16_pc_plusw2; + + pic16_pc_indf0.r = pic16_allocProcessorRegister(IDX_INDF0,"INDF0", PO_INDF0, 0x80); + pic16_pc_postinc0.r = pic16_allocProcessorRegister(IDX_POSTINC0, "POSTINC0", PO_INDF0, 0x80); + pic16_pc_postdec0.r = pic16_allocProcessorRegister(IDX_POSTDEC0, "POSTDEC0", PO_INDF0, 0x80); + pic16_pc_preinc0.r = pic16_allocProcessorRegister(IDX_PREINC0, "PREINC0", PO_INDF0, 0x80); + pic16_pc_plusw0.r = pic16_allocProcessorRegister(IDX_PLUSW0, "PLUSW0", PO_INDF0, 0x80); + + pic16_pc_indf1.r = pic16_allocProcessorRegister(IDX_INDF1,"INDF1", PO_INDF0, 0x80); + pic16_pc_postinc1.r = pic16_allocProcessorRegister(IDX_POSTINC1, "POSTINC1", PO_INDF0, 0x80); + pic16_pc_postdec1.r = pic16_allocProcessorRegister(IDX_POSTDEC1, "POSTDEC1", PO_INDF0, 0x80); + pic16_pc_preinc1.r = pic16_allocProcessorRegister(IDX_PREINC1, "PREINC1", PO_INDF0, 0x80); + pic16_pc_plusw1.r = pic16_allocProcessorRegister(IDX_PLUSW1, "PLUSW1", PO_INDF0, 0x80); + + pic16_pc_indf2.r = pic16_allocProcessorRegister(IDX_INDF2,"INDF2", PO_INDF0, 0x80); + pic16_pc_postinc2.r = pic16_allocProcessorRegister(IDX_POSTINC2, "POSTINC2", PO_INDF0, 0x80); + pic16_pc_postdec2.r = pic16_allocProcessorRegister(IDX_POSTDEC2, "POSTDEC2", PO_INDF0, 0x80); + pic16_pc_preinc2.r = pic16_allocProcessorRegister(IDX_PREINC2, "PREINC2", PO_INDF0, 0x80); + pic16_pc_plusw2.r = pic16_allocProcessorRegister(IDX_PLUSW2, "PLUSW2", PO_INDF0, 0x80); + + pic16_pc_prodl.r = pic16_allocProcessorRegister(IDX_PRODL, "PRODL", PO_PRODL, 0x80); + pic16_pc_prodh.r = pic16_allocProcessorRegister(IDX_PRODH, "PRODH", PO_PRODH, 0x80); - pic16_pc_status.r = pic16_allocProcessorRegister(IDX_STATUS,"_STATUS", PO_STATUS, 0x80); - pic16_pc_pcl.r = pic16_allocProcessorRegister(IDX_PCL,"PCL", PO_PCL, 0x80); - pic16_pc_pclath.r = pic16_allocProcessorRegister(IDX_PCLATH,"_PCLATH", PO_PCLATH, 0x80); - pic16_pc_fsr0.r = pic16_allocProcessorRegister(IDX_FSR0,"FSR0", PO_FSR0, 0x80); - pic16_pc_indf0.r = pic16_allocProcessorRegister(IDX_INDF0,"INDF0", PO_INDF0, 0x80); - pic16_pc_intcon.r = pic16_allocProcessorRegister(IDX_INTCON,"INTCON", PO_INTCON, 0x80); - pic16_pc_wreg.r = pic16_allocProcessorRegister(IDX_WREG,"WREG", PO_WREG, 0x80); - pic16_pc_status.rIdx = IDX_STATUS; - pic16_pc_fsr0.rIdx = IDX_FSR0; - pic16_pc_indf0.rIdx = IDX_INDF0; - pic16_pc_intcon.rIdx = IDX_INTCON; - pic16_pc_pcl.rIdx = IDX_PCL; - pic16_pc_pclath.rIdx = IDX_PCLATH; - pic16_pc_wreg.rIdx = IDX_WREG; + pic16_pc_eecon1.r = pic16_allocProcessorRegister(IDX_EECON1, "EECON1", PO_SFR_REGISTER, 0x80); + pic16_pc_eecon2.r = pic16_allocProcessorRegister(IDX_EECON2, "EECON2", PO_SFR_REGISTER, 0x80); + pic16_pc_eedata.r = pic16_allocProcessorRegister(IDX_EEDATA, "EEDATA", PO_SFR_REGISTER, 0x80); + pic16_pc_eeadr.r = pic16_allocProcessorRegister(IDX_EEADR, "EEADR", PO_SFR_REGISTER, 0x80); - pic16_pc_kzero.r = pic16_allocInternalRegister(IDX_KZ,"KZ",PO_GPR_REGISTER,0); - pic16_pc_ssave.r = pic16_allocInternalRegister(IDX_SSAVE,"SSAVE", PO_GPR_REGISTER, 0x80); - pic16_pc_wsave.r = pic16_allocInternalRegister(IDX_WSAVE,"WSAVE", PO_GPR_REGISTER, 0); + + pic16_pc_status.rIdx = IDX_STATUS; + pic16_pc_intcon.rIdx = IDX_INTCON; + pic16_pc_pcl.rIdx = IDX_PCL; + pic16_pc_pclath.rIdx = IDX_PCLATH; + pic16_pc_pclatu.rIdx = IDX_PCLATU; + pic16_pc_wreg.rIdx = IDX_WREG; + pic16_pc_bsr.rIdx = IDX_BSR; + + pic16_pc_tosl.rIdx = IDX_TOSL; + pic16_pc_tosh.rIdx = IDX_TOSH; + pic16_pc_tosu.rIdx = IDX_TOSU; + + pic16_pc_tblptrl.rIdx = IDX_TBLPTRL; + pic16_pc_tblptrh.rIdx = IDX_TBLPTRH; + pic16_pc_tblptru.rIdx = IDX_TBLPTRU; + pic16_pc_tablat.rIdx = IDX_TABLAT; + + pic16_pc_fsr0l.rIdx = IDX_FSR0L; + pic16_pc_fsr0h.rIdx = IDX_FSR0H; + pic16_pc_fsr1l.rIdx = IDX_FSR1L; + pic16_pc_fsr1h.rIdx = IDX_FSR1H; + pic16_pc_fsr2l.rIdx = IDX_FSR2L; + pic16_pc_fsr2h.rIdx = IDX_FSR2H; + pic16_pc_indf0.rIdx = IDX_INDF0; + pic16_pc_postinc0.rIdx = IDX_POSTINC0; + pic16_pc_postdec0.rIdx = IDX_POSTDEC0; + pic16_pc_preinc0.rIdx = IDX_PREINC0; + pic16_pc_plusw0.rIdx = IDX_PLUSW0; + pic16_pc_indf1.rIdx = IDX_INDF1; + pic16_pc_postinc1.rIdx = IDX_POSTINC1; + pic16_pc_postdec1.rIdx = IDX_POSTDEC1; + pic16_pc_preinc1.rIdx = IDX_PREINC1; + pic16_pc_plusw1.rIdx = IDX_PLUSW1; + pic16_pc_indf2.rIdx = IDX_INDF2; + pic16_pc_postinc2.rIdx = IDX_POSTINC2; + pic16_pc_postdec2.rIdx = IDX_POSTDEC2; + pic16_pc_preinc2.rIdx = IDX_PREINC2; + pic16_pc_plusw2.rIdx = IDX_PLUSW2; + pic16_pc_prodl.rIdx = IDX_PRODL; + pic16_pc_prodh.rIdx = IDX_PRODH; + + pic16_pc_kzero.r = pic16_allocInternalRegister(IDX_KZ,"KZ",PO_GPR_REGISTER,0); + pic16_pc_ssave.r = pic16_allocInternalRegister(IDX_SSAVE,"SSAVE", PO_GPR_REGISTER, 0); + pic16_pc_wsave.r = pic16_allocInternalRegister(IDX_WSAVE,"WSAVE", PO_GPR_REGISTER, 0); + + pic16_pc_kzero.rIdx = IDX_KZ; + pic16_pc_wsave.rIdx = IDX_WSAVE; + pic16_pc_ssave.rIdx = IDX_SSAVE; + + pic16_pc_eecon1.rIdx = IDX_EECON1; + pic16_pc_eecon2.rIdx = IDX_EECON2; + pic16_pc_eedata.rIdx = IDX_EEDATA; + pic16_pc_eeadr.rIdx = IDX_EEADR; + + + pic16_pc_gpsimio.r = pic16_allocProcessorRegister(IDX_GPSIMIO, "GPSIMIO", PO_GPR_REGISTER, 0x80); + pic16_pc_gpsimio2.r = pic16_allocProcessorRegister(IDX_GPSIMIO2, "GPSIMIO2", PO_GPR_REGISTER, 0x80); - pic16_pc_kzero.rIdx = IDX_KZ; - pic16_pc_wsave.rIdx = IDX_WSAVE; - pic16_pc_ssave.rIdx = IDX_SSAVE; + pic16_pc_gpsimio.rIdx = IDX_GPSIMIO; + pic16_pc_gpsimio2.rIdx = IDX_GPSIMIO2; - /* probably should put this in a separate initialization routine */ - pb_dead_pcodes = newpBlock(); + /* probably should put this in a separate initialization routine */ + pb_dead_pcodes = newpBlock(); } @@ -2437,7 +3113,7 @@ int mnem2key(char const *mnem) return (key & 0x1f); } -#endif // OPT_DISABLE_PIC +#endif void pic16initMnemonics(void) { @@ -2498,6 +3174,7 @@ void pic16initMnemonics(void) pic16Mnemonics[POC_INCFSZ] = &pic16_pciINCFSZ; pic16Mnemonics[POC_INCFSZW] = &pic16_pciINCFSZW; pic16Mnemonics[POC_INFSNZ] = &pic16_pciINFSNZ; + pic16Mnemonics[POC_INFSNZW] = &pic16_pciINFSNZW; pic16Mnemonics[POC_IORWF] = &pic16_pciIORWF; pic16Mnemonics[POC_IORFW] = &pic16_pciIORFW; pic16Mnemonics[POC_IORLW] = &pic16_pciIORLW; @@ -2520,7 +3197,7 @@ void pic16initMnemonics(void) pic16Mnemonics[POC_RETURN] = &pic16_pciRETURN; pic16Mnemonics[POC_RLCF] = &pic16_pciRLCF; pic16Mnemonics[POC_RLCFW] = &pic16_pciRLCFW; - pic16Mnemonics[POC_RLCF] = &pic16_pciRLNCF; + pic16Mnemonics[POC_RLNCF] = &pic16_pciRLNCF; pic16Mnemonics[POC_RLNCFW] = &pic16_pciRLNCFW; pic16Mnemonics[POC_RRCF] = &pic16_pciRRCF; pic16Mnemonics[POC_RRCFW] = &pic16_pciRRCFW; @@ -2536,11 +3213,19 @@ void pic16initMnemonics(void) pic16Mnemonics[POC_SUBFWB_D1] = &pic16_pciSUBFWB_D1; pic16Mnemonics[POC_SWAPF] = &pic16_pciSWAPF; pic16Mnemonics[POC_SWAPFW] = &pic16_pciSWAPFW; -// pic16Mnemonics[POC_TRIS] = &pic16_pciTRIS; + pic16Mnemonics[POC_TBLRD] = &pic16_pciTBLRD; + pic16Mnemonics[POC_TBLRD_POSTINC] = &pic16_pciTBLRD_POSTINC; + pic16Mnemonics[POC_TBLRD_POSTDEC] = &pic16_pciTBLRD_POSTDEC; + pic16Mnemonics[POC_TBLRD_PREINC] = &pic16_pciTBLRD_PREINC; + pic16Mnemonics[POC_TBLWT] = &pic16_pciTBLWT; + pic16Mnemonics[POC_TBLWT_POSTINC] = &pic16_pciTBLWT_POSTINC; + pic16Mnemonics[POC_TBLWT_POSTDEC] = &pic16_pciTBLWT_POSTDEC; + pic16Mnemonics[POC_TBLWT_PREINC] = &pic16_pciTBLWT_PREINC; pic16Mnemonics[POC_TSTFSZ] = &pic16_pciTSTFSZ; pic16Mnemonics[POC_XORLW] = &pic16_pciXORLW; pic16Mnemonics[POC_XORWF] = &pic16_pciXORWF; pic16Mnemonics[POC_XORFW] = &pic16_pciXORFW; + pic16Mnemonics[POC_BANKSEL] = &pic16_pciBANKSEL; for(i=0; imnemonic, mnem) == 0) { - if((pci->num_ops <= 1) || (pci->isModReg == dest) || (pci->isBitInst) || - (pci->num_ops <= 2 && pci->isAccess) || - (pci->num_ops <= 2 && pci->isFastCall)) + if((pci->num_ops <= 1) + || (pci->isModReg == dest) + || (pci->isBitInst) + || (pci->num_ops <= 2 && pci->isAccess) + || (pci->num_ops <= 2 && pci->isFastCall) + || (pci->num_ops <= 2 && pci->is2MemOp) + || (pci->num_ops <= 2 && pci->is2LitOp) ) return(pci->op); } @@ -2649,15 +3338,27 @@ static char getpBlock_dbName(pBlock *pb) } void pic16_pBlockConvert2ISR(pBlock *pb) { - if(!pb) - return; + if(!pb)return; - if(pb->cmemmap) - pb->cmemmap = NULL; + if(pb->cmemmap)pb->cmemmap = NULL; - pb->dbName = 'I'; + pb->dbName = 'I'; + + if(pic16_pcode_verbose) + fprintf(stderr, "%s:%d converting to 'I'interrupt pBlock\n", __FILE__, __LINE__); } +void pic16_pBlockConvert2Absolute(pBlock *pb) +{ + if(!pb)return; + if(pb->cmemmap)pb->cmemmap = NULL; + + pb->dbName = 'A'; + + if(pic16_pcode_verbose) + fprintf(stderr, "%s:%d converting to 'A'bsolute pBlock\n", __FILE__, __LINE__); +} + /*-----------------------------------------------------------------*/ /* pic16_movepBlock2Head - given the dbname of a pBlock, move all */ /* instances to the front of the doubly linked */ @@ -2668,6 +3369,11 @@ void pic16_movepBlock2Head(char dbName) { pBlock *pb; + + /* this can happen in sources without code, + * only variable definitions */ + if(!the_pFile)return; + pb = the_pFile->pbHead; while(pb) { @@ -2706,15 +3412,16 @@ void pic16_copypCode(FILE *of, char dbName) { pBlock *pb; - if(!of || !the_pFile) - return; + if(!of || !the_pFile) + return; - for(pb = the_pFile->pbHead; pb; pb = pb->next) { - if(getpBlock_dbName(pb) == dbName) { - pBlockStats(of,pb); - pic16_printpBlock(of,pb); - } - } + for(pb = the_pFile->pbHead; pb; pb = pb->next) { + if(getpBlock_dbName(pb) == dbName) { +// fprintf(stderr, "%s:%d: output of pb= 0x%p\n", __FILE__, __LINE__, pb); + pBlockStats(of,pb); + pic16_printpBlock(of,pb); + } + } } void pic16_pcode_test(void) @@ -2753,6 +3460,25 @@ void pic16_pcode_test(void) } } } + + +unsigned long pic16_countInstructions(void) +{ + pBlock *pb; + pCode *pc; + unsigned long isize=0; + + if(!the_pFile)return -1; + + for(pb = the_pFile->pbHead; pb; pb = pb->next) { + for(pc = pb->pcHead; pc; pc = pc->next) { + if(isPCI(pc) || isPCAD(pc))isize += PCI(pc)->isize; + } + } + return (isize); +} + + /*-----------------------------------------------------------------*/ /* int RegCond(pCodeOp *pcop) - if pcop points to the STATUS reg- */ /* ister, RegCond will return the bit being referenced. */ @@ -2766,6 +3492,8 @@ static int RegCond(pCodeOp *pcop) if(!pcop) return 0; + if(!pcop->name)return 0; + if(pcop->type == PO_GPR_BIT && !strcmp(pcop->name, pic16_pc_status.pcop.name)) { switch(PCORB(pcop)->bit) { case PIC_C_BIT: @@ -2945,7 +3673,6 @@ pCode *pic16_newpCodeFunction(char *mod,char *f) pCodeFunction *pcf; pcf = Safe_calloc(1,sizeof(pCodeFunction)); - //_ALLOC(pcf,sizeof(pCodeFunction)); pcf->pc.type = PC_FUNCTION; pcf->pc.prev = pcf->pc.next = NULL; @@ -2957,23 +3684,23 @@ pCode *pic16_newpCodeFunction(char *mod,char *f) pcf->pc.print = pCodePrintFunction; pcf->ncalled = 0; - + pcf->absblock = 0; + if(mod) { - //_ALLOC_ATOMIC(pcf->modname,strlen(mod)+1); pcf->modname = Safe_calloc(1,strlen(mod)+1); strcpy(pcf->modname,mod); } else pcf->modname = NULL; if(f) { - //_ALLOC_ATOMIC(pcf->fname,strlen(f)+1); pcf->fname = Safe_calloc(1,strlen(f)+1); strcpy(pcf->fname,f); } else pcf->fname = NULL; - return ( (pCode *)pcf); + pcf->stackusage = 0; + return ( (pCode *)pcf); } /*-----------------------------------------------------------------*/ @@ -2993,7 +3720,17 @@ static void destructpCodeFlow(pCode *pc) deleteSet(&PCFL(pc)->registers); deleteSet(&PCFL(pc)->from); deleteSet(&PCFL(pc)->to); - free(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; + pic16_addpCode2pBlock(pb_dead_pcodes, pc); + +// free(pc); } @@ -3090,24 +3827,27 @@ pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...) { pCodeAsmDir *pcad; va_list ap; - char buffer[256]; // how long can a directive be?! + char buffer[512]; char *lbp=buffer; - pcad = Safe_calloc(1, sizeof(pCodeAsmDir)); - pcad->pc.type = PC_ASMDIR; - pcad->pc.prev = pcad->pc.next = NULL; - pcad->pc.pb = NULL; - - pcad->pc.destruct = genericDestruct; - pcad->pc.print = genericPrint; + pcad->pci.pc.type = PC_ASMDIR; + pcad->pci.pc.prev = pcad->pci.pc.next = NULL; + pcad->pci.pc.pb = NULL; + pcad->pci.isize = 2; + pcad->pci.pc.destruct = genericDestruct; + pcad->pci.pc.print = genericPrint; if(asdir && *asdir) { + + while(isspace(*asdir))asdir++; // strip any white space from the beginning + pcad->directive = Safe_strdup( asdir ); } va_start(ap, argfmt); + memset(buffer, 0, sizeof(buffer)); if(argfmt && *argfmt) vsprintf(buffer, argfmt, ap); @@ -3130,10 +3870,19 @@ static void pCodeLabelDestruct(pCode *pc) if(!pc) return; - if((pc->type == PC_LABEL) && PCL(pc)->label) - free(PCL(pc)->label); +// if((pc->type == PC_LABEL) && PCL(pc)->label) +// free(PCL(pc)->label); + + /* 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; + pic16_addpCode2pBlock(pb_dead_pcodes, pc); - free(pc); +// free(pc); } @@ -3155,7 +3904,8 @@ pCode *pic16_newpCodeLabel(char *name, int key) pcl->pc.print = pCodePrintLabel; pcl->key = key; - + pcl->force = 0; + pcl->label = NULL; if(key>0) { sprintf(s,"_%05d_DS_",key); @@ -3165,11 +3915,42 @@ pCode *pic16_newpCodeLabel(char *name, int key) if(s) pcl->label = Safe_strdup(s); - //fprintf(stderr,"pic16_newpCodeLabel: key=%d, name=%s\n",key, ((s)?s:"")); +// if(pic16_pcode_verbose) +// fprintf(stderr, "%s:%d label name: %s\n", __FILE__, __LINE__, pcl->label); + + return ( (pCode *)pcl); } +pCode *pic16_newpCodeLabelFORCE(char *name, int key) +{ + pCodeLabel *pcl = (pCodeLabel *)pic16_newpCodeLabel(name, key); + + pcl->force = 1; + + return ( (pCode *)pcl ); +} + +pCode *pic16_newpCodeInfo(INFO_TYPE type, pCodeOp *pcop) +{ + pCodeInfo *pci; + + pci = Safe_calloc(1, sizeof(pCodeInfo)); + pci->pci.pc.type = PC_INFO; + pci->pci.pc.prev = pci->pci.pc.next = NULL; + pci->pci.pc.pb = NULL; + pci->pci.label = NULL; + + pci->pci.pc.destruct = genericDestruct; + pci->pci.pc.print = genericPrint; + + pci->type = type; + pci->oper1 = pcop; + + return ((pCode *)pci); +} + /*-----------------------------------------------------------------*/ /* newpBlock - create and return a pointer to a new pBlock */ @@ -3212,6 +3993,8 @@ pBlock *pic16_newpCodeChain(memmap *cm,char c, pCode *pc) return pB; } + + /*-----------------------------------------------------------------*/ /* pic16_newpCodeOpLabel - Create a new label given the key */ /* Note, a negative key means that the label is part of wild card */ @@ -3257,13 +4040,40 @@ pCodeOp *pic16_newpCodeOpLit(int lit) pcop->type = PO_LITERAL; pcop->name = NULL; - if(lit>=0) { - sprintf(s,"0x%02x",lit); + //if(lit>=0) + sprintf(s,"0x%02hhx", (unsigned char)lit); + //else + // sprintf(s, "%i", lit); + + if(s) + pcop->name = Safe_strdup(s); + + ((pCodeOpLit *)pcop)->lit = lit; + + return pcop; +} + +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ +pCodeOp *pic16_newpCodeOpLit2(int lit, pCodeOp *arg2) +{ + char *s = buffer, tbuf[256], *tb=tbuf; + pCodeOp *pcop; + + + tb = pic16_get_op(arg2, NULL, 0); + pcop = Safe_calloc(1,sizeof(pCodeOpLit2) ); + pcop->type = PO_LITERAL; + + pcop->name = NULL; + //if(lit>=0) { + sprintf(s,"0x%02x, %s", (unsigned char)lit, tb); if(s) pcop->name = Safe_strdup(s); - } + //} - ((pCodeOpLit *)pcop)->lit = lit; + ((pCodeOpLit2 *)pcop)->lit = lit; + ((pCodeOpLit2 *)pcop)->arg2 = arg2; return pcop; } @@ -3274,27 +4084,28 @@ pCodeOp *pic16_newpCodeOpImmd(char *name, int offset, int index, int code_space) { pCodeOp *pcop; - pcop = Safe_calloc(1,sizeof(pCodeOpImmd) ); - pcop->type = PO_IMMEDIATE; - if(name) { - regs *r = pic16_dirregWithName(name); - pcop->name = Safe_strdup(name); - PCOI(pcop)->r = r; - if(r) { - //fprintf(stderr, " pic16_newpCodeOpImmd reg %s exists\n",name); - PCOI(pcop)->rIdx = r->rIdx; - } else { - //fprintf(stderr, " pic16_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; - } + pcop = Safe_calloc(1,sizeof(pCodeOpImmd) ); + pcop->type = PO_IMMEDIATE; + if(name) { + regs *r = pic16_dirregWithName(name); + pcop->name = Safe_strdup(name); + PCOI(pcop)->r = r; + + if(r) { +// fprintf(stderr, "%s:%d %s reg %s exists (r: %p)\n",__FILE__, __LINE__, __FUNCTION__, name, r); + PCOI(pcop)->rIdx = r->rIdx; + } else { +// fprintf(stderr, "%s:%d %s reg %s doesn't exist\n", __FILE__, __LINE__, __FUNCTION__, 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)->index = index; + PCOI(pcop)->offset = offset; + PCOI(pcop)->_const = code_space; return pcop; } @@ -3322,15 +4133,65 @@ pCodeOp *pic16_newpCodeOpWild(int id, pCodeWildBlock *pcwb, pCodeOp *subtype) PCOW(pcop)->subtype = subtype; PCOW(pcop)->matched = NULL; + PCOW(pcop)->pcop2 = NULL; + return pcop; } /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ -pCodeOp *pic16_newpCodeOpBit(char *s, int bit, int inBitSpace) +pCodeOp *pic16_newpCodeOpWild2(int id, int id2, pCodeWildBlock *pcwb, pCodeOp *subtype, pCodeOp *subtype2) { + char *s = buffer; pCodeOp *pcop; + + if(!pcwb || !subtype || !subtype2) { + fprintf(stderr, "Wild opcode declaration error: %s-%d\n",__FILE__,__LINE__); + exit(1); + } + + pcop = Safe_calloc(1,sizeof(pCodeOpWild)); + pcop->type = PO_WILD; + sprintf(s,"%%%d",id); + pcop->name = Safe_strdup(s); + + PCOW(pcop)->id = id; + PCOW(pcop)->pcwb = pcwb; + PCOW(pcop)->subtype = subtype; + PCOW(pcop)->matched = NULL; + + PCOW(pcop)->pcop2 = Safe_calloc(1, sizeof(pCodeOpWild)); + + if(!subtype2->name) { + PCOW(pcop)->pcop2 = Safe_calloc(1, sizeof(pCodeOpWild)); + PCOW2(pcop)->pcop.type = PO_WILD; + sprintf(s, "%%%d", id2); + PCOW2(pcop)->pcop.name = Safe_strdup(s); + PCOW2(pcop)->id = id2; + PCOW2(pcop)->subtype = subtype2; + +// fprintf(stderr, "%s:%d %s [wild,wild] for name: %s (%d)\tname2: %s (%d)\n", __FILE__, __LINE__, __FUNCTION__, +// pcop->name, id, PCOW2(pcop)->pcop.name, id2); + } else { + PCOW2(pcop)->pcop2 = pic16_pCodeOpCopy( subtype2 ); + +// fprintf(stderr, "%s:%d %s [wild,str] for name: %s (%d)\tname2: %s (%d)\n", __FILE__, __LINE__, __FUNCTION__, +// pcop->name, id, PCOW2(pcop)->pcop.name, id2); + } + + + + return pcop; +} + + +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ +pCodeOp *pic16_newpCodeOpBit(char *s, int bit, int inBitSpace, PIC_OPTYPE subt) +{ + pCodeOp *pcop; + pcop = Safe_calloc(1,sizeof(pCodeOpRegBit) ); pcop->type = PO_GPR_BIT; if(s) @@ -3340,13 +4201,16 @@ pCodeOp *pic16_newpCodeOpBit(char *s, int bit, int inBitSpace) PCORB(pcop)->bit = bit; PCORB(pcop)->inBitSpace = inBitSpace; + PCORB(pcop)->subtype = subt; /* pCodeOpBit is derived from pCodeOpReg. We need to init this too */ - PCOR(pcop)->r = NULL; - PCOR(pcop)->rIdx = 0; + PCOR(pcop)->r = pic16_regWithName(s); //NULL; +// fprintf(stderr, "%s:%d %s for reg: %s\treg= %p\n", __FILE__, __LINE__, __FUNCTION__, s, PCOR(pcop)->r); +// PCOR(pcop)->rIdx = 0; return pcop; } + /*-----------------------------------------------------------------* * pCodeOp *pic16_newpCodeOpReg(int rIdx) - allocate a new register * @@ -3371,6 +4235,11 @@ pCodeOp *pic16_newpCodeOpReg(int rIdx) if(PCOR(pcop)->r) PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx; + else { + fprintf(stderr, "%s:%d Could not find a free GPR register\n", + __FUNCTION__, __LINE__); + exit(-1); + } } pcop->type = PCOR(pcop)->r->pc_type; @@ -3381,16 +4250,50 @@ pCodeOp *pic16_newpCodeOpReg(int rIdx) pCodeOp *pic16_newpCodeOpRegFromStr(char *name) { pCodeOp *pcop; + regs *r; - pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); - PCOR(pcop)->r = pic16_allocRegByName(name, 1); - PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx; - pcop->type = PCOR(pcop)->r->pc_type; - pcop->name = PCOR(pcop)->r->name; + pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); + PCOR(pcop)->r = r = pic16_allocRegByName(name, 1, NULL); + PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx; + pcop->type = PCOR(pcop)->r->pc_type; + pcop->name = PCOR(pcop)->r->name; + +// if(pic16_pcode_verbose) { +// fprintf(stderr, "%s:%d %s allocates register %s rIdx:0x%02x\n", +// __FILE__, __LINE__, __FUNCTION__, r->name, r->rIdx); +// } return pcop; } +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ +pCodeOp *pic16_newpCodeOpOpt(OPT_TYPE type, char *key) +{ + pCodeOpOpt *pcop; + + pcop = Safe_calloc(1, sizeof(pCodeOpOpt)); + + pcop->type = type; + pcop->key = Safe_strdup( key ); + + return (PCOP(pcop)); +} + +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ +pCodeOp *pic16_newpCodeOpLocalRegs(LR_TYPE type) +{ + pCodeOpLocalReg *pcop; + + pcop = Safe_calloc(1, sizeof(pCodeOpLocalReg)); + + pcop->type = type; + + return (PCOP(pcop)); +} + + /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ @@ -3401,7 +4304,7 @@ pCodeOp *pic16_newpCodeOp(char *name, PIC_OPTYPE type) switch(type) { case PO_BIT: case PO_GPR_BIT: - pcop = pic16_newpCodeOpBit(name, -1,0); + pcop = pic16_newpCodeOpBit(name, -1,0, type); break; case PO_LITERAL: @@ -3434,6 +4337,96 @@ pCodeOp *pic16_newpCodeOp(char *name, PIC_OPTYPE type) return pcop; } +#define DB_ITEMS_PER_LINE 8 + +typedef struct DBdata + { + int count; + char buffer[256]; + } DBdata; + +struct DBdata DBd; +static int DBd_init = -1; + +/*-----------------------------------------------------------------*/ +/* Initialiase "DB" data buffer */ +/*-----------------------------------------------------------------*/ +void pic16_initDB(void) +{ + DBd_init = -1; +} + + +/*-----------------------------------------------------------------*/ +/* Flush pending "DB" data to a pBlock */ +/* */ +/* ptype - type of p pointer, 'f' file pointer, 'p' pBlock pointer */ +/*-----------------------------------------------------------------*/ +void pic16_flushDB(char ptype, void *p) +{ + if (DBd.count>0) { + if(ptype == 'p') + pic16_addpCode2pBlock(((pBlock *)p),pic16_newpCodeAsmDir("DB", "%s", DBd.buffer)); + else + if(ptype == 'f') + fprintf(((FILE *)p), "\tdb\t%s\n", DBd.buffer); + else { + /* sanity check */ + fprintf(stderr, "PIC16 port error: could not emit initial value data\n"); + } + + DBd.count = 0; + DBd.buffer[0] = '\0'; + } +} + + +/*-----------------------------------------------------------------*/ +/* Add "DB" directives to a pBlock */ +/*-----------------------------------------------------------------*/ +void pic16_emitDB(char c, char ptype, void *p) +{ + int l; + + if (DBd_init<0) { + // we need to initialize + DBd_init = 0; + DBd.count = 0; + DBd.buffer[0] = '\0'; + } + + l = strlen(DBd.buffer); + sprintf(DBd.buffer+l,"%s0x%02x", (DBd.count>0?", ":""), c & 0xff); + +// fprintf(stderr, "%s:%d DBbuffer: '%s'\n", __FILE__, __LINE__, DBd.buffer); + + DBd.count++; + if (DBd.count>= DB_ITEMS_PER_LINE) + pic16_flushDB(ptype, p); +} + +void pic16_emitDS(char *s, char ptype, void *p) +{ + int l; + + if (DBd_init<0) { + // we need to initialize + DBd_init = 0; + DBd.count = 0; + DBd.buffer[0] = '\0'; + } + + l = strlen(DBd.buffer); + sprintf(DBd.buffer+l,"%s%s", (DBd.count>0?", ":""), s); + +// fprintf(stderr, "%s:%d DBbuffer: '%s'\n", __FILE__, __LINE__, DBd.buffer); + + DBd.count++; //=strlen(s); + if (DBd.count>=16) + pic16_flushDB(ptype, p); +} + + /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ void pic16_pCodeConstString(char *name, char *value) @@ -3449,16 +4442,17 @@ void pic16_pCodeConstString(char *name, char *value) pic16_addpBlock(pb); - sprintf(buffer,"; %s = %s",name,value); - - pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(buffer)); +// sprintf(buffer,"; %s = ", name); +// strcat(buffer, value); +// fputs(buffer, stderr); + +// pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(buffer)); pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(name,-1)); do { - pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(*value))); + pic16_emitDB(*value, 'p', (void *)pb); }while (*value++); - - + pic16_flushDB('p', (void *)pb); } /*-----------------------------------------------------------------*/ @@ -3595,15 +4589,28 @@ void pic16_printpBlock(FILE *of, pBlock *pb) { pCode *pc; - if(!pb) - return; - - if(!of) - of = stderr; - - for(pc = pb->pcHead; pc; pc = pc->next) - printpCode(of,pc); - + if(!pb)return; + + if(!of)of=stderr; + + for(pc = pb->pcHead; pc; pc = pc->next) { + if(isPCF(pc) && PCF(pc)->fname) { + fprintf(of, "S_%s_%s\tcode", PCF(pc)->modname, PCF(pc)->fname); + if(pb->dbName == 'A') { + absSym *ab; + for(ab=setFirstItem(absSymSet); ab; ab=setNextItem(absSymSet)) { +// fprintf(stderr, "%s:%d testing %s <-> %s\n", __FILE__, __LINE__, PCF(pc)->fname, ab->name); + if(!strcmp(ab->name, PCF(pc)->fname)) { +// fprintf(stderr, "%s:%d address = %x\n", __FILE__, __LINE__, ab->address); + fprintf(of, "\t0X%06X", ab->address); + break; + } + } + } + fprintf(of, "\n"); + } + printpCode(of,pc); + } } /*-----------------------------------------------------------------*/ @@ -3661,121 +4668,117 @@ static void genericDestruct(pCode *pc) */ pc->type = PC_BAD; - pic16_addpCode2pBlock(pb_dead_pcodes, pc); //free(pc); - } - -#if 0 +void DEBUGpic16_emitcode (char *inst,char *fmt, ...); /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ -static void pBlockRegs(FILE *of, pBlock *pb) -{ - - regs *r; - - r = setFirstItem(pb->tregisters); - while (r) { - r = setNextItem(pb->tregisters); - } -} -#endif +/* modifiers for constant immediate */ +const char *immdmod[3]={"LOW", "HIGH", "UPPER"}; -/*-----------------------------------------------------------------*/ -/*-----------------------------------------------------------------*/ char *pic16_get_op(pCodeOp *pcop,char *buffer, size_t size) { regs *r; - static char b[50]; + static char b[128]; char *s; 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_INDF0: - case PO_FSR0: - if(use_buffer) { - SAFE_snprintf(&buffer,&size,"%s",PCOR(pcop)->r->name); - return buffer; - } - return PCOR(pcop)->r->name; - break; - case PO_GPR_TEMP: - r = pic16_regWithIdx(PCOR(pcop)->r->rIdx); - - if(use_buffer) { - SAFE_snprintf(&buffer,&size,"%s",r->name); - return buffer; - } - - return r->name; - - - case PO_IMMEDIATE: - s = buffer; - - 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 ); - } else - SAFE_snprintf(&s,&size,"LOW(%s+%d)",pcop->name,PCOI(pcop)->index); - } else { - - if( PCOI(pcop)->index) { // && PCOI(pcc->pcop)->offset<4) { - SAFE_snprintf(&s,&size,"(%s + %d)", - pcop->name, - PCOI(pcop)->index ); - } else { - if(PCOI(pcop)->offset) - SAFE_snprintf(&s,&size,"(%s >> %d)&0xff",pcop->name, 8*PCOI(pcop)->offset); - else - SAFE_snprintf(&s,&size,"%s",pcop->name); - } - } - - return buffer; - - case PO_DIR: - s = buffer; - //size = sizeof(buffer); - if( PCOR(pcop)->instance) { - SAFE_snprintf(&s,&size,"(%s + %d)", - pcop->name, - PCOR(pcop)->instance ); - } - //fprintf(stderr,"PO_DIR %s\n",buffer); - else - SAFE_snprintf(&s,&size,"%s",pcop->name); - return buffer; - - default: - if (pcop->name) { - if(use_buffer) { - SAFE_snprintf(&buffer,&size,"%s",pcop->name); - return buffer; + 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_W: + case PO_WREG: + case PO_PRODL: + case PO_PRODH: + case PO_INDF0: + case PO_FSR0: + if(use_buffer) { + SAFE_snprintf(&buffer,&size,"%s",PCOR(pcop)->r->name); + return buffer; + } + return PCOR(pcop)->r->name; + break; + case PO_GPR_TEMP: + r = pic16_regWithIdx(PCOR(pcop)->r->rIdx); + if(use_buffer) { + SAFE_snprintf(&buffer,&size,"%s",r->name); + return buffer; + } + return r->name; + + case PO_IMMEDIATE: + s = buffer; + if(PCOI(pcop)->offset && PCOI(pcop)->offset<4) { + if(PCOI(pcop)->index) { + SAFE_snprintf(&s,&size, "%s(%s + %d)", + immdmod[ PCOI(pcop)->offset ], + pcop->name, + PCOI(pcop)->index); + } else { + SAFE_snprintf(&s,&size,"%s(%s)", + immdmod[ PCOI(pcop)->offset ], + pcop->name); + } + } else { + if(PCOI(pcop)->index) { + SAFE_snprintf(&s,&size, "%s(%s + %d)", + immdmod[ 0 ], + pcop->name, + PCOI(pcop)->index); + } else { + SAFE_snprintf(&s,&size, "%s(%s)", + immdmod[ 0 ], + pcop->name); + } + } + return buffer; + + case PO_GPR_REGISTER: + case PO_DIR: + s = buffer; +// size = sizeof(buffer); + if( PCOR(pcop)->instance) { + SAFE_snprintf(&s,&size,"(%s + %d)", + pcop->name, + PCOR(pcop)->instance ); + } else { + SAFE_snprintf(&s,&size,"%s",pcop->name); + } + return buffer; + case PO_GPR_BIT: + s = buffer; + if(PCORB(pcop)->subtype == PO_GPR_TEMP) { + SAFE_snprintf(&s, &size, "%s", pcop->name); + } else { + if(PCORB(pcop)->pcor.instance) + SAFE_snprintf(&s, &size, "(%s + %d)", pcop->name, PCORB(pcop)->pcor.instance); + else + SAFE_snprintf(&s, &size, "%s", pcop->name); + } + + return (buffer); + default: + if(pcop->name) { + if(use_buffer) { + SAFE_snprintf(&buffer,&size,"%s",pcop->name); + return buffer; + } + return pcop->name; + } + + } } - return pcop->name; - } - - } - } - - return "NO operand"; + return "NO operand1"; } /*-----------------------------------------------------------------*/ @@ -3788,11 +4791,11 @@ char *pic16_get_op2(pCodeOp *pcop,char *buffer, size_t size) char *s; 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(!buffer) { + buffer = b; + size = sizeof(b); + use_buffer = 0; // Don't bother copying the string to the buffer. + } #if 0 fprintf(stderr, "%s:%d second operand %s is %d\tPO_DIR(%d) PO_GPR_TEMP(%d) PO_IMMEDIATE(%d) PO_INDF0(%d) PO_FSR0(%d)\n", @@ -3800,88 +4803,80 @@ char *pic16_get_op2(pCodeOp *pcop,char *buffer, size_t size) PO_DIR, PO_GPR_TEMP, PO_IMMEDIATE, PO_INDF0, PO_FSR0); #endif - if(pcop) { - switch(PCOR2(pcop)->pcop2->type) { - case PO_INDF0: - case PO_FSR0: - if(use_buffer) { - SAFE_snprintf(&buffer,&size,"%s",PCOR(PCOR2(pcop)->pcop2)->r->name); - return buffer; - } - return PCOR(PCOR2(pcop)->pcop2)->r->name; - break; - case PO_GPR_TEMP: - r = pic16_regWithIdx(PCOR(PCOR2(pcop)->pcop2)->r->rIdx); - - if(use_buffer) { - SAFE_snprintf(&buffer,&size,"%s",r->name); - return buffer; - } - - return r->name; - - - case PO_IMMEDIATE: - break; + if(pcop) { + switch(PCOR2(pcop)->pcop2->type) { + case PO_W: + case PO_WREG: + case PO_PRODL: + case PO_PRODH: + case PO_INDF0: + case PO_FSR0: + if(use_buffer) { + SAFE_snprintf(&buffer,&size,"%s",PCOR(PCOR2(pcop)->pcop2)->r->name); + return buffer; + } + return PCOR(PCOR2(pcop)->pcop2)->r->name; + break; + case PO_GPR_TEMP: + r = pic16_regWithIdx(PCOR(PCOR2(pcop)->pcop2)->r->rIdx); + + if(use_buffer) { + SAFE_snprintf(&buffer,&size,"%s",r->name); + return buffer; + } + return r->name; + + case PO_IMMEDIATE: + assert( 0 ); + break; #if 0 - s = buffer; - - 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 ); - } else - SAFE_snprintf(&s,&size,"LOW(%s+%d)",pcop->name,PCOI(pcop)->index); - } else { - - if( PCOI(pcop)->index) { // && PCOI(pcc->pcop)->offset<4) { - SAFE_snprintf(&s,&size,"(%s + %d)", - pcop->name, - PCOI(pcop)->index ); - } else { - if(PCOI(pcop)->offset) - SAFE_snprintf(&s,&size,"(%s >> %d)&0xff",pcop->name, 8*PCOI(pcop)->offset); - else - SAFE_snprintf(&s,&size,"%s",pcop->name); - } - } - - return buffer; + s = buffer; + + 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 ); + } else + SAFE_snprintf(&s,&size,"LOW(%s+%d)",pcop->name,PCOI(pcop)->index); + } else { + if( PCOI(pcop)->index) { + SAFE_snprintf(&s,&size,"(%s + %d)", + pcop->name, + PCOI(pcop)->index ); + } else { + if(PCOI(pcop)->offset) + SAFE_snprintf(&s,&size,"(%s >> %d)&0xff",pcop->name, 8*PCOI(pcop)->offset); + else + SAFE_snprintf(&s,&size,"%s",pcop->name); + } + } + return buffer; #endif - - case PO_DIR: - s = buffer; - //size = sizeof(buffer); - if( PCOR(PCOR2(pcop)->pcop2)->instance) { - SAFE_snprintf(&s,&size,"(%s + %d)", - PCOR(PCOR2(pcop)->pcop2)->r->name, - PCOR(PCOR2(pcop)->pcop2)->instance ); + case PO_DIR: + s = buffer; + if( PCOR(PCOR2(pcop)->pcop2)->instance) { + SAFE_snprintf(&s,&size,"(%s + %d)", + PCOR(PCOR2(pcop)->pcop2)->r->name, + PCOR(PCOR2(pcop)->pcop2)->instance ); + } else { + SAFE_snprintf(&s,&size,"%s",PCOR(PCOR2(pcop)->pcop2)->r->name); + } + return buffer; + + default: + if(PCOR(PCOR2(pcop)->pcop2)->r->name) { + if(use_buffer) { + SAFE_snprintf(&buffer,&size,"%s",PCOR(PCOR2(pcop)->pcop2)->r->name); + return buffer; + } + return PCOR(PCOR2(pcop)->pcop2)->r->name; + } + } } - //fprintf(stderr,"PO_DIR %s\n",buffer); - else - SAFE_snprintf(&s,&size,"%s",PCOR(PCOR2(pcop)->pcop2)->r->name); - return buffer; - - default: -#if 0 - if (PCOR2(pcop)->r1->name) { - if(use_buffer) { - SAFE_snprintf(&buffer,&size,"%s",PCOR2(pcop)->r1->name); - return buffer; - } - return PCOR2(pcop)->r1->name; - } -#else - break; -#endif - } - } - - return "NO operand"; + return "NO operand2"; } /*-----------------------------------------------------------------*/ @@ -3908,10 +4903,20 @@ static void pCodeOpPrint(FILE *of, pCodeOp *pcop) } /*-----------------------------------------------------------------*/ +/* pic16_pCode2str - convert a pCode instruction to string */ /*-----------------------------------------------------------------*/ -static char *pCode2str(char *str, size_t size, pCode *pc) +char *pic16_pCode2str(char *str, size_t size, pCode *pc) { char *s = str; + regs *r; + +#if 0 + if(isPCI(pc) && (PCI(pc)->pci_magic != PCI_MAGIC)) { + fprintf(stderr, "%s:%d: pCodeInstruction initialization error in instruction %s, magic is %x (defaut: %x)\n", + __FILE__, __LINE__, PCI(pc)->mnemonic, PCI(pc)->pci_magic, PCI_MAGIC); +// exit(-1); + } +#endif switch(pc->type) { @@ -3921,21 +4926,28 @@ static char *pCode2str(char *str, size_t size, pCode *pc) if( (PCI(pc)->num_ops >= 1) && (PCI(pc)->pcop)) { if(PCI(pc)->is2MemOp) { - SAFE_snprintf(&s,&size, "%s,%s", + SAFE_snprintf(&s,&size, "%s, %s", pic16_get_op(PCOP(PCI(pc)->pcop), NULL, 0), pic16_get_op2(PCOP(PCI(pc)->pcop), NULL, 0)); break; } + if(PCI(pc)->is2LitOp) { + SAFE_snprintf(&s,&size, "%s", PCOP(PCI(pc)->pcop)->name); + break; + } + if(PCI(pc)->isBitInst) { - if(PCI(pc)->pcop->type == PO_GPR_BIT) { + if(PCI(pc)->pcop->type != PO_GPR_BIT) { if( (((pCodeOpRegBit *)(PCI(pc)->pcop))->inBitSpace) ) SAFE_snprintf(&s,&size,"(%s >> 3), (%s & 7)", PCI(pc)->pcop->name , PCI(pc)->pcop->name ); else - SAFE_snprintf(&s,&size,"%s,%d", pic16_get_op_from_instruction(PCI(pc)), + SAFE_snprintf(&s,&size,"%s,%d", pic16_get_op_from_instruction(PCI(pc)), +// (((pCodeOpRegBit *)(PCI(pc)->pcop))->pcor.instance), (((pCodeOpRegBit *)(PCI(pc)->pcop))->bit )); + } else if(PCI(pc)->pcop->type == PO_GPR_BIT) { SAFE_snprintf(&s,&size,"%s,%d", pic16_get_op_from_instruction(PCI(pc)),PCORB(PCI(pc)->pcop)->bit); }else @@ -3950,10 +4962,18 @@ static char *pCode2str(char *str, size_t size, pCode *pc) SAFE_snprintf(&s,&size,"(1 << (%s & 7))",pic16_get_op_from_instruction(PCI(pc))); }else { - SAFE_snprintf(&s,&size,"%s",pic16_get_op_from_instruction(PCI(pc))); + SAFE_snprintf(&s,&size,"%s", pic16_get_op_from_instruction(PCI(pc))); - if( PCI(pc)->num_ops == 3) - SAFE_snprintf(&s,&size,",%c", ( (PCI(pc)->isModReg) ? 'F':'W')); + if( PCI(pc)->num_ops == 3 || ((PCI(pc)->num_ops == 2) && (PCI(pc)->isAccess))) { + if(PCI(pc)->num_ops == 3) + SAFE_snprintf(&s,&size,", %c", ( (PCI(pc)->isModReg) ? 'F':'W')); + + r = pic16_getRegFromInstruction(pc); +// fprintf(stderr, "%s:%d reg = %p\tname= %s, accessBank= %d\n", +// __FUNCTION__, __LINE__, r, (r)?r->name:"", (r)?r->accessBank:-1); + + if(r && !r->accessBank)SAFE_snprintf(&s,&size,", %s", (!pic16_mplab_comp?"B":"BANKED")); + } } } @@ -3965,6 +4985,17 @@ static char *pCode2str(char *str, size_t size, pCode *pc) SAFE_snprintf(&s,&size,";%s", ((pCodeComment *)pc)->comment); break; + case PC_INFO: + SAFE_snprintf(&s,&size,"; info ==>"); + switch(((pCodeInfo *)pc)->type) { + case INF_OPTIMIZATION: + SAFE_snprintf(&s,&size, " [optimization] %s\n", OPT_TYPE_STR[ PCOO(PCINF(pc)->oper1)->type ]); + break; + case INF_LOCALREGS: + SAFE_snprintf(&s,&size, " [localregs] %s\n", LR_TYPE_STR[ PCOLR(PCINF(pc)->oper1)->type ]); + break; + }; break; + case PC_INLINE: /* assuming that inline code ends with a \n */ SAFE_snprintf(&s,&size,"%s", ((pCodeComment *)pc)->comment); @@ -3983,14 +5014,23 @@ static char *pCode2str(char *str, size_t size, pCode *pc) SAFE_snprintf(&s,&size,";\t--FLOW change\n"); break; case PC_CSOURCE: - SAFE_snprintf(&s,&size,";#CSRC\t%s %d\n; %s\n", PCCS(pc)->file_name, PCCS(pc)->line_number, PCCS(pc)->line); +// SAFE_snprintf(&s,&size,";#CSRC\t%s %d\t%s\n", PCCS(pc)->file_name, PCCS(pc)->line_number, PCCS(pc)->line); + SAFE_snprintf(&s,&size,"%s\t.line\t%d; %s\t%s\n", ((pic16_mplab_comp || !options.debug)?";":""), + PCCS(pc)->line_number, PCCS(pc)->file_name, PCCS(pc)->line); break; case PC_ASMDIR: - SAFE_snprintf(&s,&size,"\t%s\t%s\n", PCAD(pc)->directive, PCAD(pc)->arg?PCAD(pc)->arg:""); + if(PCAD(pc)->directive) { + SAFE_snprintf(&s,&size,"\t%s%s%s\n", PCAD(pc)->directive, PCAD(pc)->arg?"\t":"", PCAD(pc)->arg?PCAD(pc)->arg:""); + } else + if(PCAD(pc)->arg) { + /* special case to handle inline labels without a tab */ + SAFE_snprintf(&s,&size,"%s\n", PCAD(pc)->arg); + } break; case PC_BAD: SAFE_snprintf(&s,&size,";A bad pCode is being used\n"); + break; } return str; @@ -4008,15 +5048,40 @@ static void genericPrint(FILE *of, pCode *pc) switch(pc->type) { case PC_COMMENT: - fprintf(of,";%s\n", ((pCodeComment *)pc)->comment); +// fputs(((pCodeComment *)pc)->comment, of); + fprintf(of,"; %s\n", ((pCodeComment *)pc)->comment); break; - case PC_INLINE: - fprintf(of,"%s\n", ((pCodeComment *)pc)->comment); - break; - - case PC_OPCODE: - // If the opcode has a label, print that first + case PC_INFO: + { + pBranch *pbl = PCI(pc)->label; + while(pbl && pbl->pc) { + if(pbl->pc->type == PC_LABEL) + pCodePrintLabel(of, pbl->pc); + pbl = pbl->next; + } + } + + if(pic16_pcode_verbose) { + fprintf(of, "; info ==>"); + switch(((pCodeInfo *)pc)->type) { + case INF_OPTIMIZATION: + fprintf(of, " [optimization] %s\n", OPT_TYPE_STR[ PCOO(PCINF(pc)->oper1)->type ]); + break; + case INF_LOCALREGS: + fprintf(of, " [localregs] %s\n", LR_TYPE_STR[ PCOLR(PCINF(pc)->oper1)->type ]); + break; + } + }; + + break; + + case PC_INLINE: + fprintf(of,"%s\n", ((pCodeComment *)pc)->comment); + break; + + case PC_OPCODE: + // If the opcode has a label, print that first { pBranch *pbl = PCI(pc)->label; while(pbl && pbl->pc) { @@ -4032,48 +5097,19 @@ static void genericPrint(FILE *of, pCode *pc) { char str[256]; - pCode2str(str, 256, pc); + pic16_pCode2str(str, 256, pc); fprintf(of,"%s",str); - /* Debug */ if(pic16_debug_verbose) { - fprintf(of, "\t;key=%03x %d",pc->seq, __LINE__); + fprintf(of, "\t;key=%03x",pc->seq); if(PCI(pc)->pcflow) - fprintf(of,",flow seq=%03x",PCI(pc)->pcflow->pc.seq); + fprintf(of,", flow seq=%03x",PCI(pc)->pcflow->pc.seq); } } fprintf(of, "\n"); break; -#if 0 - { - pBranch *dpb = pc->to; // debug - while(dpb) { - switch ( dpb->pc->type) { - case PC_OPCODE: - fprintf(of, "\t;%s", PCI(dpb->pc)->mnemonic); - break; - case PC_LABEL: - fprintf(of, "\t;label %d", PCL(dpb->pc)->key); - break; - case PC_FUNCTION: - fprintf(of, "\t;function %s", ( (PCF(dpb->pc)->fname) ? (PCF(dpb->pc)->fname) : "[END]")); - break; - case PC_FLOW: - fprintf(of, "\t;flow"); - break; - case PC_COMMENT: - case PC_WILD: - break; - } - dpb = dpb->next; - } - } -#endif -// fprintf(of,"\n"); // these are moved prior to #if 0 -// break; - case PC_WILD: fprintf(of,";\tWild opcode: id=%d\n",PCW(pc)->id); if(PCW(pc)->pci.label) @@ -4096,10 +5132,28 @@ static void genericPrint(FILE *of, pCode *pc) break; case PC_CSOURCE: - fprintf(of,";#CSRC\t%s %d\n; %s\n", PCCS(pc)->file_name, PCCS(pc)->line_number, PCCS(pc)->line); +// fprintf(of,";#CSRC\t%s %d\t\t%s\n", PCCS(pc)->file_name, PCCS(pc)->line_number, PCCS(pc)->line); + fprintf(of,"%s\t.line\t%d; %s\t%s\n", ((pic16_mplab_comp || !options.debug)?";":""), + PCCS(pc)->line_number, PCCS(pc)->file_name, PCCS(pc)->line); + break; + case PC_ASMDIR: - fprintf(of, "\t%s\t%s\n", PCAD(pc)->directive, PCAD(pc)->arg?PCAD(pc)->arg:""); + { + pBranch *pbl = PCAD(pc)->pci.label; + while(pbl && pbl->pc) { + if(pbl->pc->type == PC_LABEL) + pCodePrintLabel(of, pbl->pc); + pbl = pbl->next; + } + } + if(PCAD(pc)->directive) { + fprintf(of, "\t%s%s%s\n", PCAD(pc)->directive, PCAD(pc)->arg?"\t":"", PCAD(pc)->arg?PCAD(pc)->arg:""); + } else + if(PCAD(pc)->arg) { + /* special case to handle inline labels without tab */ + fprintf(of, "%s\n", PCAD(pc)->arg); + } break; case PC_LABEL: @@ -4119,27 +5173,45 @@ static void pCodePrintFunction(FILE *of, pCode *pc) if(!pc || !of) return; +#if 0 if( ((pCodeFunction *)pc)->modname) fprintf(of,"F_%s",((pCodeFunction *)pc)->modname); +#endif - if(PCF(pc)->fname) { - pBranch *exits = PCF(pc)->to; - int i=0; - fprintf(of,"%s\t;Function start\n",PCF(pc)->fname); - while(exits) { - i++; - exits = exits->next; - } - //if(i) i--; - fprintf(of,"; %d exit point%c\n",i, ((i==1) ? ' ':'s')); + if(!PCF(pc)->absblock) { + if(PCF(pc)->fname) { + pBranch *exits = PCF(pc)->to; + int i=0; + + fprintf(of,"%s:", PCF(pc)->fname); - }else { - if((PCF(pc)->from && - PCF(pc)->from->pc->type == PC_FUNCTION && - PCF(PCF(pc)->from->pc)->fname) ) - fprintf(of,"; exit point of %s\n",PCF(PCF(pc)->from->pc)->fname); - else - fprintf(of,"; exit point [can't find entry point]\n"); + if(pic16_pcode_verbose) + fprintf(of, "\t;Function start"); + + fprintf(of, "\n"); + + while(exits) { + i++; + exits = exits->next; + } + //if(i) i--; + + if(pic16_pcode_verbose) + fprintf(of,"; %d exit point%c\n",i, ((i==1) ? ' ':'s')); + + } else { + if((PCF(pc)->from && + PCF(pc)->from->pc->type == PC_FUNCTION && + PCF(PCF(pc)->from->pc)->fname) ) { + + if(pic16_pcode_verbose) + fprintf(of,"; exit point of %s\n",PCF(PCF(pc)->from->pc)->fname); + } else { + if(pic16_pcode_verbose) + fprintf(of,"; exit point [can't find entry point]\n"); + } + fprintf(of, "\n"); + } } } /*-----------------------------------------------------------------*/ @@ -4153,7 +5225,7 @@ static void pCodePrintLabel(FILE *of, pCode *pc) return; if(PCL(pc)->label) - fprintf(of,"%s\n",PCL(pc)->label); + fprintf(of,"%s:\n",PCL(pc)->label); else if (PCL(pc)->key >=0) fprintf(of,"_%05d_DS_:\n",PCL(pc)->key); else @@ -4185,15 +5257,16 @@ static void unlinkpCodeFromBranch(pCode *pcl , pCode *pc) while(b) { if(b->pc == pc) { //fprintf (stderr, "found label\n"); + //pc->print(stderr, pc); /* Found a label */ if(bprev) { bprev->next = b->next; /* Not first pCode in chain */ - free(b); +// free(b); } else { pc->destruct(pc); PCI(pcl)->label = b->next; /* First pCode in chain */ - free(b); +// free(b); } return; /* A label can't occur more than once */ } @@ -4271,9 +5344,9 @@ static pBranch *pBranchFind(pBranch *pb,pCode *pc) } /*-----------------------------------------------------------------*/ -/* pCodeUnlink - Unlink the given pCode from its pCode chain. */ +/* pic16_pCodeUnlink - Unlink the given pCode from its pCode chain. */ /*-----------------------------------------------------------------*/ -static void pCodeUnlink(pCode *pc) +void pic16_pCodeUnlink(pCode *pc) { pBranch *pb1,*pb2; pCode *pc1; @@ -4291,21 +5364,21 @@ static void pCodeUnlink(pCode *pc) /* Remove the branches */ - pb1 = pc->from; + pb1 = PCI(pc)->from; while(pb1) { - pc1 = pb1->pc; /* Get the pCode that branches to the + PCI(pc1) = pb1->pc; /* Get the pCode that branches to the * one we're unlinking */ /* search for the link back to this pCode (the one we're * unlinking) */ - if(pb2 = pBranchFind(pc1->to,pc)) { - pb2->pc = pc->to->pc; // make the replacement + if((pb2 = pBranchFind(PCI(pc1)->to,pc))) { + pb2->pc = PCI(pc)->to->pc; // make the replacement /* if the pCode we're unlinking contains multiple 'to' * branches (e.g. this a skip instruction) then we need * to copy these extra branches to the chain. */ - if(pc->to->next) - pic16_pBranchAppend(pb2, pc->to->next); + if(PCI(pc)->to->next) + pic16_pBranchAppend(pb2, PCI(pc)->to->next); } pb1 = pb1->next; @@ -4366,7 +5439,9 @@ static int compareLabel(pCode *pc, pCodeOpLabel *pcop_label) if( ((pCodeLabel *)pc)->key == pcop_label->key) return TRUE; } - if(pc->type == PC_OPCODE) { + if((pc->type == PC_OPCODE) + || (pc->type == PC_ASMDIR) + ) { pbr = PCI(pc)->label; while(pbr) { if(pbr->pc->type == PC_LABEL) { @@ -4469,6 +5544,9 @@ static pCode * findPrevpCode(pCode *pc, PC_TYPE pct) return NULL; } + + +//#define PCODE_DEBUG /*-----------------------------------------------------------------*/ /* pic16_findNextInstruction - given a pCode, find the next instruction */ /* in the linked list */ @@ -4478,7 +5556,10 @@ pCode * pic16_findNextInstruction(pCode *pci) pCode *pc = pci; while(pc) { - if((pc->type == PC_OPCODE) || (pc->type == PC_WILD)) + if((pc->type == PC_OPCODE) + || (pc->type == PC_WILD) + || (pc->type == PC_ASMDIR) + ) return pc; #ifdef PCODE_DEBUG @@ -4493,13 +5574,35 @@ pCode * pic16_findNextInstruction(pCode *pci) } /*-----------------------------------------------------------------*/ -/* pic16_findNextInstruction - given a pCode, find the next instruction */ +/* pic16_findPrevInstruction - given a pCode, find the next instruction */ /* in the linked list */ /*-----------------------------------------------------------------*/ pCode * pic16_findPrevInstruction(pCode *pci) { - return findPrevpCode(pci, PC_OPCODE); + pCode *pc = pci; + + while(pc) { + + if((pc->type == PC_OPCODE) + || (pc->type == PC_WILD) + || (pc->type == PC_ASMDIR) + ) + return pc; + + +#ifdef PCODE_DEBUG + fprintf(stderr,"pic16_findPrevInstruction: "); + printpCode(stderr, pc); +#endif + pc = pc->prev; + } + + //fprintf(stderr,"Couldn't find instruction\n"); + return NULL; } + +#undef PCODE_DEBUG + #if 0 /*-----------------------------------------------------------------*/ /* findFunctionEnd - given a pCode find the end of the function */ @@ -4527,7 +5630,7 @@ static pCode * findFunctionEnd(pCode *pc) static void AnalyzeLabel(pCode *pc) { - pCodeUnlink(pc); + pic16_pCodeUnlink(pc); } #endif @@ -4569,44 +5672,52 @@ regs * pic16_getRegFromInstruction(pCode *pc) (PCI(pc)->num_ops == 1 && PCI(pc)->isFastCall)) return NULL; +#if 0 + fprintf(stderr, "pic16_getRegFromInstruction - reg type %s (%d)\n", + dumpPicOptype( PCI(pc)->pcop->type), PCI(pc)->pcop->type); +#endif + switch(PCI(pc)->pcop->type) { + case PO_PRODL: + case PO_PRODH: + case PO_INDF0: case PO_FSR0: return PCOR(PCI(pc)->pcop)->r; - // return typeRegWithIdx (PCOR(PCI(pc)->pcop)->rIdx, REG_SFR, 0); - case PO_BIT: case PO_GPR_TEMP: - //fprintf(stderr, "pic16_getRegFromInstruction - bit or temp\n"); +// fprintf(stderr, "pic16_getRegFromInstruction - bit or temp\n"); return PCOR(PCI(pc)->pcop)->r; case PO_IMMEDIATE: +// return pic16_dirregWithName(PCOI(PCI(pc)->pcop)->r->name); + if(PCOI(PCI(pc)->pcop)->r) return (PCOI(PCI(pc)->pcop)->r); - - //fprintf(stderr, "pic16_getRegFromInstruction - immediate\n"); - return pic16_dirregWithName(PCI(pc)->pcop->name); - //return NULL; // PCOR(PCI(pc)->pcop)->r; - + else + return NULL; + case PO_GPR_BIT: return PCOR(PCI(pc)->pcop)->r; + case PO_GPR_REGISTER: case PO_DIR: - //fprintf(stderr, "pic16_getRegFromInstruction - dir\n"); +// fprintf(stderr, "pic16_getRegFromInstruction - dir\n"); return PCOR(PCI(pc)->pcop)->r; + case PO_LITERAL: //fprintf(stderr, "pic16_getRegFromInstruction - literal\n"); break; default: - //fprintf(stderr, "pic16_getRegFromInstruction - unknown reg type %d\n",PCI(pc)->pcop->type); - //genericPrint(stderr, pc); - break; +// fprintf(stderr, "pic16_getRegFromInstruction - unknown reg type %d\n",PCI(pc)->pcop->type); +// genericPrint(stderr, pc); +// assert( 0 ); + break; } return NULL; - } /*-------------------------------------------------------------------------------*/ @@ -4623,6 +5734,11 @@ regs * pic16_getRegFromInstruction2(pCode *pc) return NULL; +#if 0 + fprintf(stderr, "pic16_getRegFromInstruction2 - reg type %s (%d)\n", + dumpPicOptype( PCI(pc)->pcop->type), PCI(pc)->pcop->type); +#endif + /* * operands supported in MOVFF: * PO_INF0/PO_FSR0 @@ -4632,6 +5748,9 @@ regs * pic16_getRegFromInstruction2(pCode *pc) * */ switch(PCI(pc)->pcop->type) { + case PO_PRODL: + case PO_PRODH: + case PO_INDF0: case PO_FSR0: return PCOR(PCOR2(PCI(pc)->pcop)->pcop2)->r; @@ -4640,34 +5759,39 @@ regs * pic16_getRegFromInstruction2(pCode *pc) // case PO_BIT: case PO_GPR_TEMP: - //fprintf(stderr, "pic16_getRegFromInstruction - bit or temp\n"); + //fprintf(stderr, "pic16_getRegFromInstruction2 - bit or temp\n"); return PCOR(PCOR2(PCI(pc)->pcop)->pcop2)->r; case PO_IMMEDIATE: - break; #if 0 - if(PCOI(PCI(pc)->pcop)->r) - return (PCOI(PCI(pc)->pcop)->r); +// if(PCOI(PCI(pc)->pcop)->r) +// return (PCOI(PCOR2(PCI(pc)->pcop)->pcop2)->r); - //fprintf(stderr, "pic16_getRegFromInstruction - immediate\n"); - return pic16_dirregWithName(PCI(pc)->pcop->name); - //return NULL; // PCOR(PCI(pc)->pcop)->r; + //fprintf(stderr, "pic16_getRegFromInstruction2 - immediate\n"); + return pic16_dirregWithName(PCOI(PCOR2(PCI(pc)->pcop)->pcop2)->r->name); #endif + if(PCOI(PCOR2(PCI(pc)->pcop)->pcop2)->r) + return (PCOI(PCOR2(PCI(pc)->pcop)->pcop2)->r); + else + return NULL; + + case PO_GPR_BIT: break; // return PCOR2(PCI(pc)->pcop)->r; + case PO_GPR_REGISTER: case PO_DIR: - //fprintf(stderr, "pic16_getRegFromInstruction - dir\n"); + //fprintf(stderr, "pic16_getRegFromInstruction2 - dir\n"); return PCOR(PCOR2(PCI(pc)->pcop)->pcop2)->r; case PO_LITERAL: break; - //fprintf(stderr, "pic16_getRegFromInstruction - literal\n"); + //fprintf(stderr, "pic16_getRegFromInstruction2 - literal\n"); default: - //fprintf(stderr, "pic16_getRegFromInstruction - unknown reg type %d\n",PCI(pc)->pcop->type); + //fprintf(stderr, "pic16_getRegFromInstruction2 - unknown reg type %d\n",PCI(pc)->pcop->type); //genericPrint(stderr, pc); break; } @@ -4897,7 +6021,6 @@ static void dumpCond(int cond) static char *pcc_str[] = { //"PCC_NONE", "PCC_REGISTER", - "PCC_REGISTER2", "PCC_C", "PCC_Z", "PCC_DC", @@ -4970,14 +6093,14 @@ static int isBankInstruction(pCode *pc) int bank = -1; if(!isPCI(pc)) - return -1; + return 0; if( PCI(pc)->op == POC_MOVLB || (( (reg = pic16_getRegFromInstruction(pc)) != NULL) && isBSR_REG(reg))) { bank = PCOL(pc)->lit; } - return bank; + return 1; } @@ -5089,9 +6212,16 @@ static void LinkFlow(pBlock *pb) //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__); + if((PCI(pc)->op != POC_RETLW) + && (PCI(pc)->op != POC_RETURN) && (PCI(pc)->op != POC_CALL) && (PCI(pc)->op != POC_RETFIE) ) { + + /* continue if label is '$' which assembler knows how to parse */ + if(((PCI(pc)->pcop->type == PO_STR) && !strcmp(PCI(pc)->pcop->name, "$")))continue; + + if(pic16_pcode_verbose) { + pc->print(stderr,pc); + fprintf(stderr, "ERROR: %s, branch instruction doesn't have label\n",__FUNCTION__); + } } continue; } @@ -5101,7 +6231,8 @@ static void LinkFlow(pBlock *pb) 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,"pic16_newpCodeOpLabel: key=%d, name=%s\n",key,((s)?s:"")); + +// fprintf(stderr,"pic16_newpCodeOpLabel: key=%d, name=%s\n",pcol->key,(PCOP(pcol)->name)?(PCOP(pcol)->name):""); continue; } @@ -5136,7 +6267,7 @@ int pic16_isPCinFlow(pCode *pc, pCode *pcflow) if(!pc || !pcflow) return 0; - if(!isPCI(pc) || !PCI(pc)->pcflow || !isPCFL(pcflow) ) + if((!isPCI(pc) && !isPCAD(pc)) || !PCI(pc)->pcflow || !isPCFL(pcflow) ) return 0; if( PCI(pc)->pcflow->pc.seq == pcflow->seq) @@ -5145,223 +6276,108 @@ int pic16_isPCinFlow(pCode *pc, pCode *pcflow) return 0; } -/*-----------------------------------------------------------------*/ -/* BanksUsedFlow - Identify which banks are used in flow 2. */ -/*-----------------------------------------------------------------*/ -static 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 = pic16_findNextInstruction(pcflow->next); - - PCFL(pcflow)->lastBank = -1; - - while(pic16_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; - PCFL(pcflow)->lastBank |= bank; - - - } else { - reg = pic16_getRegFromInstruction(pc); - - if(reg && !pic16_isREGinBank(reg, bank)) { - int allbanks = pic16_REGallBanks(reg); - if(bank == -1) - PCFL(pcflow)->firstBank = allbanks; - - PCFL(pcflow)->lastBank = allbanks; - - bank = allbanks; - } - RegUsed = 1; - } - - pc = pic16_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); - - - -} /*-----------------------------------------------------------------*/ +/* insertBankSwitch - inserts a bank switch statement in the */ +/* assembly listing */ +/* */ +/* position == 0: insert before */ +/* position == 1: insert after pc */ +/* position == 2: like 0 but previous was a skip instruction */ /*-----------------------------------------------------------------*/ -static void BanksUsedFlow(pBlock *pb) -{ - pCode *pcflow; - - - //pb->pcHead->print(stderr, pb->pcHead); - - pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); - //pcflow->print(stderr,pcflow); - - for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); - pcflow != NULL; - pcflow = pic16_findNextpCode(pcflow->next, PC_FLOW) ) { - - BanksUsedFlow2(pcflow); - } - -} - +pCodeOp *pic16_popGetLabel(unsigned int key); +extern int pic16_labelOffset; -/*-----------------------------------------------------------------*/ -/* insertBankSwitch - inserts a bank switch statement in the assembly listing */ -/*-----------------------------------------------------------------*/ -static void insertBankSwitch(int position, pCode *pc, int bsr) +static void insertBankSwitch(unsigned char position, pCode *pc) { pCode *new_pc; - regs *reg; - - if(!pc) - return; -/* - * if bsr == -1 then do not insert a MOVLB instruction, but rather - * insert a BANKSEL assembler directive for the symbol used by - * the pCode. This will allow the linker to setup the correct - * bank at linking time - */ - - if(!options.gen_banksel || bsr != -1) { -// new_pc = pic16_newpCode(POC_MOVLB, pic16_newpCodeOpLit(bsr)); + if(!pc) return; - } else { - /* emit the BANKSEL [symbol] */ - /* IMPORTANT: The following code does not check if a symbol is - * split in multiple banks. This should be corrected. - VR 6/6/2003 */ + /* emit BANKSEL [symbol] */ - reg = pic16_getRegFromInstruction(pc); - if(!reg)return; - new_pc = pic16_newpCodeAsmDir("BANKSEL", "%s", reg->name); - - position = 0; // position is always before (sanity check!) - } + + new_pc = pic16_newpCodeAsmDir("BANKSEL", "%s", pic16_get_op_from_instruction(PCI(pc))); + +// position = 0; // position is always before (sanity check!) #if 0 - fprintf(stderr, "%s:%d: inserting bank switch\tbank = %d\n", __FUNCTION__, __LINE__, bsr); + fprintf(stderr, "%s:%d: inserting bank switch (pos: %d)\n", __FUNCTION__, __LINE__, position); pc->print(stderr, pc); #endif - if(position) { - /* insert the bank switch after this pc instruction */ - pCode *pcnext = pic16_findNextInstruction(pc); - pic16_pCodeInsertAfter(pc, new_pc); - if(pcnext) - pc = pcnext; - - } else - pic16_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; - -} -/*-----------------------------------------------------------------*/ -/*-----------------------------------------------------------------*/ -static void FixRegisterBankingInFlow(pCodeFlow *pcfl, int cur_bank) -{ - pCode *pc=NULL; - pCode *pcprev=NULL; - pCode *new_pc; - - regs *reg; - - if(!pcfl) - return; - - pc = pic16_findNextInstruction(pcfl->pc.next); - - while(pic16_isPCinFlow(pc,PCODE(pcfl))) { - - reg = pic16_getRegFromInstruction(pc); - -#if 1 - if(reg) { - fprintf(stderr, "%s:%d %s ",__FUNCTION__, __LINE__, reg->name); - fprintf(stderr, "addr = 0x%03x, bank = %d\n",reg->address,REG_BANK(reg)); - - } -#endif - - if( ( (reg && !isACCESS_BANK(reg) && REG_BANK(reg)!=cur_bank) || - ((PCI(pc)->op == POC_CALL) && (cur_bank != 0) ) ) && - (!isPCI_LIT(pc)) ){ + switch(position) { + case 1: { + /* insert the bank switch after this pc instruction */ + pCode *pcnext = pic16_findNextInstruction(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) /* && !isBankInstruction(pcprev)*/)) { - int reg_bank; - - reg_bank = (reg) ? REG_BANK(reg) : 0; - - - if (cur_bank != reg_bank) { - //fprintf(stderr, "Cool! can switch banks\n"); - cur_bank = reg_bank; - insertBankSwitch(0, pc, cur_bank); + pic16_pCodeInsertAfter(pc, new_pc); + if(pcnext)pc = pcnext; + }; break; + + case 0: + /* insert the bank switch BEFORE this pc instruction */ + pic16_pCodeInsertAfter(pc->prev, new_pc); + break; + + case 2: { + symbol *tlbl; + pCode *pcnext, *pcprev, *npci, *ppc; + PIC_OPCODE ipci; + int ofs1=0, ofs2=0, len=0; + + /* just like 0, but previous was a skip instruction, + * so some care should be taken */ + + pic16_labelOffset += 10000; + tlbl = newiTempLabel(NULL); + + /* invert skip instruction */ + pcprev = pic16_findPrevInstruction(pc->prev); + ipci = PCI(pcprev)->inverted_op; + npci = pic16_newpCode(ipci, PCI(pcprev)->pcop); + +// fprintf(stderr, "%s:%d old OP: %d\tnew OP: %d\n", __FILE__, __LINE__, PCI(pcprev)->op, ipci); + + /* copy info from old pCode */ + ofs1 = ofs2 = sizeof( pCode ) + sizeof(PIC_OPCODE); + len = sizeof(pCodeInstruction) - ofs1 - sizeof( char const * const *); + ofs1 += strlen( PCI(pcprev)->mnemonic) + 1; + ofs2 += strlen( PCI(npci)->mnemonic) + 1; + memcpy(&PCI(npci)->from, &PCI(pcprev)->from, (char *)(&(PCI(npci)->pci_magic)) - (char *)(&(PCI(npci)->from))); + PCI(npci)->op = PCI(pcprev)->inverted_op; + + /* unlink old pCode */ + ppc = pcprev->prev; + ppc->next = pcprev->next; + pcprev->next->prev = ppc; + pic16_pCodeInsertAfter(ppc, npci); + + /* extra instructions to handle invertion */ + pcnext = pic16_newpCode(POC_BRA, pic16_popGetLabel(tlbl->key)); + pic16_pCodeInsertAfter(npci, pcnext); + pic16_pCodeInsertAfter(pc->prev, new_pc); + + pcnext = pic16_newpCodeLabel(NULL,tlbl->key+100+pic16_labelOffset); + pic16_pCodeInsertAfter(pc, pcnext); + }; break; } + - } else { - //fprintf(stderr, "Bummer can't switch banks\n"); - ; - } - } - - pcprev = pc; - pc = pic16_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 = pic16_newpCode(POC_MOVLB, pic16_newpCodeOpLit(0)); - pic16_pCodeInsertAfter(pcprev, new_pc); - cur_bank = 0; - //fprintf(stderr, "Brute force switch\n"); - } - + /* Move the label, if there is one */ + if(PCI(pc)->label) { +// fprintf(stderr, "%s:%d: moving label due to bank switch directive src= 0x%p dst= 0x%p\n", +// __FILE__, __LINE__, pc, new_pc); + PCAD(new_pc)->pci.label = PCI(pc)->label; + PCI(pc)->label = NULL; + } } + /*-----------------------------------------------------------------*/ /*int compareBankFlow - compare the banking requirements between */ /* flow objects. */ @@ -5412,198 +6428,52 @@ static int compareBankFlow(pCodeFlow *pcflow, pCodeFlowLink *pcflowLink, int toO return 1; } + +#if 0 /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ -static void FixBankFlow(pBlock *pb) +static void DumpFlow(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 = pic16_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 = pic16_findNextpCode(pb->pcHead, PC_FLOW); - pcflow != NULL; - pcflow = pic16_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,"Dump flow \n"); + pb->pcHead->print(stderr, pb->pcHead); -// fprintf(stderr, "FixBankFlow - Phase 2\n"); + pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); + pcflow->print(stderr,pcflow); for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); pcflow != NULL; pcflow = pic16_findNextpCode(pcflow->next, PC_FLOW) ) { - int nFlows; - int nConflicts; - if(!isPCFL(pcflow)) { - fprintf(stderr, "FixBankFlow - pcflow is not a flow object "); + fprintf(stderr, "DumpFlow - pcflow is not a flow object "); continue; } + fprintf(stderr,"dumping: "); + pcflow->print(stderr,pcflow); + FlowStats(PCFL(pcflow)); - 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) { + 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 - to is not a pcflow\n"); + fprintf(stderr,"oops dumpflow - from 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) { + for(pcfl = setFirstItem(PCFL(pcflow)->to); pcfl; pcfl=setNextItem(PCFL(pcflow)->to)) { 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 = pic16_findNextpCode(pb->pcHead, PC_FLOW); - pcflow != NULL; - pcflow = pic16_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); -*/ -} -#if 0 -/*-----------------------------------------------------------------*/ -/*-----------------------------------------------------------------*/ -static void DumpFlow(pBlock *pb) -{ - pCode *pc=NULL; - pCode *pcflow; - pCodeFlowLink *pcfl; - - - fprintf(stderr,"Dump flow \n"); - pb->pcHead->print(stderr, pb->pcHead); - - pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); - pcflow->print(stderr,pcflow); - - for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); - pcflow != NULL; - pcflow = pic16_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); + + 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); @@ -5665,7 +6535,7 @@ static pCode * findInstructionUsingLabel(pCodeLabel *pcl, pCode *pcs) for(pc = pcs; pc; pc = pc->next) { - if((pc->type == PC_OPCODE) && + if(((pc->type == PC_OPCODE) || (pc->type == PC_INLINE)) && (PCI(pc)->pcop) && (PCI(pc)->pcop->type == PO_LABEL) && (PCOLAB(PCI(pc)->pcop)->key == pcl->key)) @@ -5689,9 +6559,9 @@ static void exchangeLabels(pCodeLabel *pcl, pCode *pc) 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); +// 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 */ @@ -5731,8 +6601,8 @@ static void pBlockRemoveUnusedLabels(pBlock *pb) if(pbr && pbr->next) { pCode *pcd = pb->pcHead; - //fprintf(stderr, "multiple labels\n"); - //pc->print(stderr,pc); +// fprintf(stderr, "multiple labels\n"); +// pc->print(stderr,pc); pbr = pbr->next; while(pbr) { @@ -5758,17 +6628,18 @@ static void pBlockRemoveUnusedLabels(pBlock *pb) pcl = PCL(PCI(pc)->label->pc); else continue; - //fprintf(stderr," found A LABEL !!! key = %d, %s\n", pcl->key,pcl->label); +// 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( (pcl->key>0) && (!findInstructionUsingLabel(pcl, pb->pcHead)) + && (!pcl->force)) { //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); +// fprintf(stderr," removed A LABEL !!! key = %d, %s\n", pcl->key,pcl->label); DFPRINTF((stderr," !!! REMOVED A LABEL !!! key = %d, %s\n", pcl->key,pcl->label)); if(pc->type == PC_LABEL) { @@ -5814,14 +6685,17 @@ void pic16_pBlockMergeLabels(pBlock *pb) 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); +// fprintf(stderr," checking merging label %s\n",PCL(pc)->label); +// fprintf(stderr,"Checking label key = %d\n",PCL(pc)->key); + if((pcnext = pic16_findNextInstruction(pc) )) { +// pcnext->print(stderr, pcnext); + // Unlink the pCode label from it's pCode chain pic16_unlinkpCode(pc); - //fprintf(stderr,"Merged label key = %d\n",PCL(pc)->key); +// 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 @@ -5829,13 +6703,15 @@ void pic16_pBlockMergeLabels(pBlock *pb) // opposed to being a single member of the pCodeInstruction.) //_ALLOC(pbr,sizeof(pBranch)); +#if 1 pbr = Safe_calloc(1,sizeof(pBranch)); pbr->pc = pc; pbr->next = NULL; PCI(pcnext)->label = pic16_pBranchAppend(PCI(pcnext)->label,pbr); - +#endif } else { + if(pic16_pcode_verbose) fprintf(stderr, "WARNING: couldn't associate label %s with an instruction\n",PCL(pc)->label); } } else if(pc->type == PC_CSOURCE) { @@ -5884,40 +6760,51 @@ static int OptimizepCode(char dbName) return matches; } + + +const char *pic16_pCodeOpType(pCodeOp *pcop); +const char *pic16_pCodeOpSubType(pCodeOp *pcop); + + /*-----------------------------------------------------------------*/ /* pic16_popCopyGPR2Bit - copy a pcode operator */ /*-----------------------------------------------------------------*/ pCodeOp *pic16_popCopyGPR2Bit(pCodeOp *pc, int bitval) { - pCodeOp *pcop; + pCodeOp *pcop=NULL; + +// fprintf(stderr, "%s:%d pc type: %s\tname: %s\n", __FILE__, __LINE__, pic16_pCodeOpType(pc), pc->name); + + if(pc->name) { + pcop = pic16_newpCodeOpBit(pc->name, bitval, 0, pc->type); + } else { + if(PCOR(pc)->r)pcop = pic16_newpCodeOpBit(PCOR(pc)->r->name, bitval, 0, pc->type); + } - pcop = pic16_newpCodeOpBit(pc->name, bitval, 0); + assert(pcop != NULL); if( !( (pcop->type == PO_LABEL) || (pcop->type == PO_LITERAL) || (pcop->type == PO_STR) )) PCOR(pcop)->r = PCOR(pc)->r; /* This is dangerous... */ + PCOR(pcop)->r->wasUsed = 1; + PCOR(pcop)->instance = PCOR(pc)->instance; return pcop; } - -#if 0 -/*-----------------------------------------------------------------*/ -/*-----------------------------------------------------------------*/ -int InstructionRegBank(pCode *pc) +/*----------------------------------------------------------------------* + * pic16_areRegsSame - check to see if the names of two registers match * + *----------------------------------------------------------------------*/ +int pic16_areRegsSame(regs *r1, regs *r2) { - regs *reg; - - if( (reg = pic16_getRegFromInstruction(pc)) == NULL) - return -1; - - return REG_BANK(reg); + if(!strcmp(r1->name, r2->name))return 1; + return 0; } -#endif + /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ @@ -5925,156 +6812,627 @@ static void pic16_FixRegisterBanking(pBlock *pb) { pCode *pc=NULL; pCode *pcprev=NULL; + regs *reg, *prevreg; + unsigned char flag=0; + + if(!pb) + return; - int cur_bank; - regs *reg; - - if(!pb) - return; + pc = pic16_findNextpCode(pb->pcHead, PC_OPCODE); + if(!pc)return; - //pc = pic16_findNextpCode(pb->pcHead, PC_FLOW); - pc = pic16_findNextpCode(pb->pcHead, PC_OPCODE); - if(!pc) - return; - /* loop through all of the flow blocks with in one pblock */ + /* loop through all of the flow blocks with in one pblock */ // fprintf(stderr,"%s:%d: Register banking\n", __FUNCTION__, __LINE__); - cur_bank = 0; - do { - /* at this point, pc should point to a PC_FLOW object */ + prevreg = NULL; + do { + /* at this point, pc should point to a PC_FLOW object */ + /* for each flow block, determine the register banking + * requirements */ + + /* if label, then might come from other point, force banksel */ + if(isPCL(pc))prevreg = NULL; + + if(!isPCI(pc))goto loop; + + if(PCI(pc)->label)prevreg = NULL; - /* for each flow block, determine the register banking - requirements */ + if(PCI(pc)->is2MemOp)goto loop; - // do { - if(isPCI(pc) && !PCI(pc)->is2MemOp) { -// genericPrint(stderr, pc); + /* if goto, then force banksel */ +// if(PCI(pc)->op == POC_GOTO)prevreg = NULL; + + reg = pic16_getRegFromInstruction(pc); - reg = pic16_getRegFromInstruction(pc); #if 0 - if(reg) { - fprintf(stderr, "%s:%d: %s %d\n",__FUNCTION__, __LINE__, reg->name, reg->rIdx); - fprintf(stderr, "addr = 0x%03x, bank = %d, bit=%d\tmapped = %d sfr=%d fix=%d\n", - reg->address,REG_BANK(reg),reg->isBitField, reg->isMapped, - pic16_finalMapping[ reg->rIdx ].isSFR, reg->isFixed); + pc->print(stderr, pc); + fprintf(stderr, "reg = %p\n", reg); - } + if(reg) { + fprintf(stderr, "%s:%d: %s %d\n",__FUNCTION__, __LINE__, reg->name, reg->rIdx); + fprintf(stderr, "addr = 0x%03x, bit=%d\tfix=%d\n", + reg->address,reg->isBitField, reg->isFixed); + } #endif -#if !defined(__BORLANDC__) && !defined(_MSC_VER) - #warning Fix this if-conditional -#else - #pragma message( "warning Fix this if-conditional" ) -#endif - /* the !(reg->rIdx==-1) is a temporary hack. It should be changed - VR 6-Jun-2003 */ - if( ( (reg /*&& !(reg->rIdx==-1)*/ && !isACCESS_BANK(reg) && (isBankInstruction(pc)==-1) && !(reg->alias == 0x80) ) - /*|| (PCI(pc)->op != POC_CALL)*/ ) - && (!isPCI_LIT(pc)) ) { + /* now make some tests to make sure that instruction needs bank switch */ + /* if no register exists, and if not a bit opcode goto loop */ + if(!reg) { + if(!(PCI(pc)->pcop && PCI(pc)->pcop->type == PO_GPR_BIT))goto loop; + } + + if(isPCI_SKIP(pc)) { +// fprintf(stderr, "instruction is SKIP instruction\n"); +// prevreg = NULL; + } + if(reg && isACCESS_BANK(reg))goto loop; - /* Examine the instruction before this one to make sure it is - * not a skip type instruction */ - pcprev = findPrevpCode(pc->prev, PC_OPCODE); + if(!isBankInstruction(pc))goto loop; - if(!pcprev || (pcprev && !isPCI_SKIP(pcprev) /*&& !isBankInstruction(pcprev)*/)) { - int reg_bank; + if(isPCI_LIT(pc))goto loop; + + if(PCI(pc)->op == POC_CALL)goto loop; - reg_bank = (reg) ? REG_BANK(reg) : 0; + /* Examine the instruction before this one to make sure it is + * not a skip type instruction */ + pcprev = findPrevpCode(pc->prev, PC_OPCODE); -#if 0 - fprintf(stderr, "%s:%d add bank = %d\n", __FUNCTION__, __LINE__, reg_bank); - pc->print(stderr, pc); -#endif + flag = 0; /* add before this instruction */ + + /* if previous instruction is a skip one, then set flag + * to 2 and call insertBankSwitch */ + if(pcprev && isPCI_SKIP(pcprev)) { + flag=2; //goto loop +// prevreg = NULL; + } + + if(pic16_options.opt_banksel>0) { + char op1[128], op2[128]; + + if(prevreg) { + strcpy(op1, pic16_get_op_from_instruction(PCI(pc))); + strcpy(op2, pic16_get_op_from_instruction(PCI(pcprev))); + if(!strcmp(op1, op2))goto loop; + } + } + prevreg = reg; + insertBankSwitch(flag, pc); + +// fprintf(stderr, "BANK SWITCH inserted\n"); + +loop: + pcprev = pc; + pc = pc->next; + } while (pc); +} -// if (cur_bank != reg_bank) { - cur_bank = reg_bank; - insertBankSwitch(0, pc, (options.gen_banksel)?-1:cur_bank); //cur_bank); -// } +/** ADDITIONS BY RAPHAEL NEIDER, 2004-11-16: GOTO OPTIMIZATIONS **/ - }else { - //fprintf(stderr, "Bummer can't switch banks\n"); - ; - } - } +/* Returns the (maximum of the) number of bytes used by the specified pCode. */ +int instrSize (pCode *pc) +{ + if (!pc) return 0; - pcprev = pc; + if (isPCAD(pc)) { + if (!PCAD(pc)->directive || strlen (PCAD(pc)->directive) < 3) return 0; + return 4; // assumes only regular instructions using <= 4 bytes + } - } + if (isPCI(pc)) return PCI(pc)->isize; - pc = pc->next; - // } while(pc && !(isPCFL(pc))); + return 0; +} +/* Returns 1 if pc is referenced by the given label (either + * pc is the label itself or is an instruction with an attached + * label). + * Returns 0 if pc is not preceeded by the specified label. + */ +int isLabel (pCode *pc, char *label) +{ + if (!pc) return 0; - }while (pc); + // label attached to the pCode? + if (isPCI(pc) || isPCAD(pc) || isPCW(pc) || pc->type == PC_INFO) { + pBranch *lab = NULL; + lab = PCI(pc)->label; - if(pcprev && cur_bank) { + while (lab) { + if (isPCL(lab->pc) && strcmp(PCL(lab->pc)->label, label) == 0) { + return 1; + } + lab = lab->next; + } // while + } // if + + // is inline assembly label? + if (isPCAD(pc) && PCAD(pc)->directive == NULL && PCAD(pc)->arg) { + // do not compare trailing ':' + if (strncmp (PCAD(pc)->arg, label, strlen (label)) == 0) { + return 1; + } + } // if + + // is pCodeLabel? + if (isPCL(pc)) { + if (strcmp(PCL(pc)->label,label) == 0) { + return 1; + } + } // if + + // no label/no label attached/wrong label(s) + return 0; +} - int pos = 1; /* Assume that the bank switch instruction(s) - * are inserted after this instruction */ +/* Returns the distance to the given label in terms of words. + * Labels are searched only within -max .. max words from pc. + * Returns max if the label could not be found or + * its distance from pc in (-max..+max). + */ +int findpCodeLabel (pCode *pc, char *label, int max, pCode **target) { + int dist = instrSize(pc); + pCode *curr = pc; + + // search backwards + while (dist < max && curr && !isLabel (curr, label)) { + curr = curr->prev; + dist += instrSize(curr); // sizeof (instruction) + } // while + if (curr && dist < max) { + if (target != NULL) *target = curr; + return -dist; + } - if((PCI(pcprev)->op == POC_RETLW) || - (PCI(pcprev)->op == POC_RETURN) || - (PCI(pcprev)->op == POC_RETFIE)) { + dist = 0; + curr = pic16_findNextInstruction (pc->next); + //search forwards + while (dist < max && curr && !isLabel (curr, label)) { + dist += instrSize(curr); // sizeof (instruction) + curr = curr->next; + } // while + if (curr && dist < max) { + if (target != NULL) *target = curr; + return dist; + } - /* oops, a RETURN - we need to switch banks *before* the RETURN */ + if (target != NULL) *target = NULL; + return max; +} - pos = 0; +/* Returns -1 if pc does NOT denote an instruction like + * BTFS[SC] STATUS,i + * Otherwise we return + * (a) 0x10 + i for BTFSS + * (b) 0x00 + i for BTFSC + */ +int isSkipOnStatus (pCode *pc) +{ + int res = -1; + pCodeOp *pcop; + if (!pc || !isPCI(pc)) return -1; + if (PCI(pc)->op == POC_BTFSS) res = 0x10; + else if (PCI(pc)->op == POC_BTFSC) res = 0x00; + else return -1; - } - - /* Brute force - make sure that we point to bank 0 at the - * end of each flow block */ + pcop = PCI(pc)->pcop; - insertBankSwitch(pos, pcprev, 0); -/* - new_pc = pic16_newpCode(POC_MOVLB, pic16_newpCodeOpLit(0)); - pic16_pCodeInsertAfter(pcprev, new_pc); -*/ - cur_bank = 0; - //fprintf(stderr, "Brute force switch\n"); + if (pcop->type == PO_STATUS || (pcop->type == PO_GPR_BIT && strcmp(pcop->name, "STATUS") == 0)) { + return res + ((pCodeOpRegBit *)pcop)->bit; } + return -1; } +/* Returns 1 if pc is one of BC, BZ, BOV, BN, BNC, BNZ, BNOV or BNN, + * returns 0 otherwise. */ +int isConditionalBranch (pCode *pc) +{ + if (!pc || !isPCI_BRANCH(pc)) return 0; + + switch (PCI(pc)->op) { + case POC_BC: + case POC_BZ: + case POC_BOV: + case POC_BN: + case POC_BNC: + case POC_BNZ: + case POC_BNOV: + case POC_BNN: + return 1; + default: + break; + } // switch + return 0; +} -#if 0 - if(reg && REG_BANK(reg)!=cur_bank) { - //fprintf(stderr,"need to switch banks\n"); - /* Examine the instruction before this one to make sure it is - * not a skip type instruction */ - pcprev = findPrevpCode(pc->prev, PC_OPCODE); - if(!pcprev || (pcprev && !isPCI_SKIP(pcprev))) { - int b = cur_bank ^ REG_BANK(reg); - - cur_bank = REG_BANK(reg); - - switch(b & 3) { - case 0: - break; - case 1: - insertBankSwitch(0, pc, cur_bank&1, PIC_RP0_BIT); - break; - case 2: - insertBankSwitch(0, pc, cur_bank&2, PIC_RP1_BIT); - insertBankSwitch(0, pc, cur_bank&2, PIC_RP1_BIT); - break; - case 3: - if(cur_bank & 3) { - insertBankSwitch(0, pc, cur_bank&1, PIC_RP0_BIT); - insertBankSwitch(0, pc, cur_bank&2, PIC_RP1_BIT); - } else - insertBankSwitch(0, pc, -1, -1); - break; +/* Returns 1 if pc has a label attached to it. + * This can be either a label stored in the pCode itself (.label) + * or a label making up its own pCode preceding this pc. + * Returns 0 if pc cannot be reached directly via a label. + */ +int hasNoLabel (pCode *pc) +{ + pCode *prev; + if (!pc) return 1; + + // are there any label pCodes between pc and the previous instruction? + prev = pic16_findPrevInstruction (pc->prev); + while (pc && pc != prev) { + // pCode with attached label? + if ((isPCI(pc) || isPCAD(pc) || isPCW(pc) || pc->type == PC_INFO) + && PCI(pc)->label) { + return 0; + } + // is inline assembly label? + if (isPCAD(pc) && PCAD(pc)->directive == NULL) return 0; + if (isPCW(pc) && PCW(pc)->label) return 0; + + // pCodeLabel? + if (isPCL(pc)) return 0; + + pc = pc->prev; + } // if + + // no label found + return 1; +} + +/* Replaces the old pCode with the new one, moving the labels, + * C source line and probably flow information to the new pCode. + */ +void pic16_pCodeReplace (pCode *oldPC, pCode *newPC) { + if (!oldPC || !newPC || !isPCI(oldPC) || !isPCI(newPC)) + return; + + /* first move all labels from old to new */ + PCI(newPC)->label = pic16_pBranchAppend (PCI(oldPC)->label, PCI(newPC)->label); + PCI(oldPC)->label = NULL; + + /* move C source line (if possible) */ + if (PCI(oldPC)->cline && !PCI(newPC)->cline) + PCI(newPC)->cline = PCI(oldPC)->cline; + + /* insert new pCode into pBlock */ + pic16_pCodeInsertAfter (oldPC, newPC); + pic16_unlinkpCode (oldPC); + + /* TODO: update flow (newPC->from, newPC->to) */ + PCI(newPC)->pcflow = PCI(oldPC)->pcflow; + + /* destruct replaced pCode */ + oldPC->destruct (oldPC); +} + +/* Returns the inverted conditional branch (if any) or NULL. + * pcop must be set to the new jump target. + */ +pCode *getNegatedBcc (pCode *bcc, pCodeOp *pcop) +{ + pCode *newBcc; + + if (!bcc || !isPCI(bcc)) return NULL; + + switch (PCI(bcc)->op) { + case POC_BC: newBcc = pic16_newpCode (POC_BNC , pcop); break; + case POC_BZ: newBcc = pic16_newpCode (POC_BNZ , pcop); break; + case POC_BOV: newBcc = pic16_newpCode (POC_BNOV, pcop); break; + case POC_BN: newBcc = pic16_newpCode (POC_BNN , pcop); break; + case POC_BNC: newBcc = pic16_newpCode (POC_BC , pcop); break; + case POC_BNZ: newBcc = pic16_newpCode (POC_BZ , pcop); break; + case POC_BNOV: newBcc = pic16_newpCode (POC_BOV , pcop); break; + case POC_BNN: newBcc = pic16_newpCode (POC_BN , pcop); break; + default: + newBcc = NULL; + } + return newBcc; +} + +#define MAX_DIST_GOTO 0x7FFFFFFF +#define MAX_DIST_BRA 1020 // maximum offset (in bytes) possible with BRA +#define MAX_DIST_BCC 120 // maximum offset (in bytes) possible with Bcc +#define MAX_JUMPCHAIN_DEPTH 16 // number of GOTOs to follow in resolveJumpChain() (to prevent endless loops) +#define IS_GOTO(arg) ((arg) && isPCI(arg) && (PCI(arg)->op == POC_GOTO || PCI(arg)->op == POC_BRA)) + +/* Follows GOTO/BRA instructions to their target instructions, stores the + * final destination (not a GOTO or BRA instruction) in target and returns + * the distance from the original pc to *target. + */ +int resolveJumpChain (pCode *pc, pCode **target, pCodeOp **pcop) { + pCode *curr = pc; + pCode *last = NULL; + pCodeOp *lastPCOP = NULL; + int dist = 0; + int depth = 0; + + //fprintf (stderr, "%s:%d: -=-", __FUNCTION__, __LINE__); + + /* only follow unconditional branches, except for the initial pCode (which may be a conditional branch) */ + while (curr && (last != curr) && (depth++ < MAX_JUMPCHAIN_DEPTH) && isPCI(curr) + && (PCI(curr)->op == POC_GOTO || PCI(curr)->op == POC_BRA || (curr == pc && isConditionalBranch(curr)))) { + last = curr; + lastPCOP = PCI(curr)->pcop; + dist = findpCodeLabel (pc, PCI(curr)->pcop->name, MAX_DIST_GOTO, &curr); + //fprintf (stderr, "last:%p, curr:%p, label:%s\n", last, curr, PCI(last)->pcop->name); + } // while + + if (target) *target = last; + if (pcop) *pcop = lastPCOP; + return dist; +} + +/* Returns pc if it is not a OPT_JUMPTABLE_BEGIN INFO pCode. + * Otherwise the first pCode after the jumptable (after + * the OPT_JUMPTABLE_END tag) is returned. + */ +pCode *skipJumptables (pCode *pc, int *isJumptable) +{ + *isJumptable = 0; + if (!pc) return NULL; + + while (pc->type == PC_INFO && PCINF(pc)->type == INF_OPTIMIZATION && PCOO(PCINF(pc)->oper1)->type == OPT_JUMPTABLE_BEGIN) { + *isJumptable = 1; + //fprintf (stderr, "SKIPPING jumptable\n"); + do { + //pc->print(stderr, pc); + pc = pc->next; + } while (pc && (pc->type != PC_INFO || PCINF(pc)->type != INF_OPTIMIZATION + || PCOO(PCINF(pc)->oper1)->type != OPT_JUMPTABLE_END)); + //fprintf (stderr, "<next; + } // while + + return pc; +} +pCode *pic16_findNextInstructionSkipJumptables (pCode *pc, int *isJumptable) +{ + int isJumptab; + *isJumptable = 0; + while (pc && !isPCI(pc) && !isPCAD(pc) && !isPCW(pc)) { + // set pc to the first pCode after a jumptable, leave pc untouched otherwise + pc = skipJumptables (pc, &isJumptab); + if (isJumptab) { + // pc is the first pCode after the jumptable + *isJumptable = 1; + } else { + // pc has not been changed by skipJumptables() + pc = pc->next; + } + } // while + + return pc; +} + +/* Turn GOTOs into BRAs if distance between GOTO and label + * is less than 1024 bytes. + * + * This method is especially useful if GOTOs after BTFS[SC] + * can be turned into BRAs as GOTO would cost another NOP + * if skipped. + */ +void pic16_OptimizeJumps () +{ + pCode *pc; + pCode *pc_prev = NULL; + pCode *pc_next = NULL; + pBlock *pb; + pCode *target; + int change, iteration, isJumptab; + int isHandled = 0; + char *label; + int opt=0, toofar=0, opt_cond = 0, cond_toofar=0, opt_reorder = 0, opt_gotonext = 0, opt_gotochain = 0; + + if (!the_pFile) return; + + //fprintf (stderr, "%s:%d: %s\n", __FILE__, __LINE__, __FUNCTION__); + + for (pb = the_pFile->pbHead; pb != NULL; pb = pb->next) { + int matchedInvertRule = 1; + iteration = 1; + do { + //fprintf (stderr, "%s:%d: iterating over pBlock %p\n", __FUNCTION__, __LINE__, pb); + change = 0; + pc = pic16_findNextInstruction (pb->pcHead); + + while (pc) { + pc_next = pic16_findNextInstructionSkipJumptables (pc->next, &isJumptab); + if (isJumptab) { + // skip jumptable, i.e. start over with no pc_prev! + pc_prev = NULL; + pc = pc_next; + continue; + } // if + + /* (1) resolve chained jumps + * Do not perform this until pattern (4) is no longer present! Otherwise we will + * (a) leave dead code in and + * (b) skip over the dead code with an (unneccessary) jump. + */ + if (!matchedInvertRule && (IS_GOTO(pc) || isConditionalBranch(pc))) { + pCodeOp *lastTargetOp = NULL; + int newDist = resolveJumpChain (pc, &target, &lastTargetOp); + int maxDist = MAX_DIST_BCC; + if (PCI(pc)->op == POC_BRA) maxDist = MAX_DIST_BRA; + if (PCI(pc)->op == POC_GOTO) maxDist = MAX_DIST_GOTO; + + /* be careful NOT to make the jump instruction longer (might break previously shortened jumps!) */ + if (lastTargetOp && newDist <= maxDist && lastTargetOp != PCI(pc)->pcop + && strcmp (lastTargetOp->name, PCI(pc)->pcop->name) != 0) { + //fprintf (stderr, "(1) ");pc->print(stderr, pc); fprintf (stderr, " --> %s\n", lastTargetOp->name); + if (pic16_pcode_verbose) { pic16_pCodeInsertAfter (pc->prev, pic16_newpCodeCharP("(1) jump chain resolved")); } + PCI(pc)->pcop->name = lastTargetOp->name; + change++; + opt_gotochain++; + } // if + } // if + + + if (IS_GOTO(pc)) { + int dist; + int condBraType = isSkipOnStatus(pc_prev); + label = PCI(pc)->pcop->name; + dist = findpCodeLabel(pc, label, MAX_DIST_BRA, &target); + if (dist < 0) dist = -dist; + //fprintf (stderr, "distance: %d (", dist); pc->print(stderr, pc);fprintf (stderr, ")\n"); + isHandled = 0; + + + /* (2) remove "GOTO label; label:" */ + if (isLabel (pc_next, label)) { + //fprintf (stderr, "(2) GOTO next instruction: ");pc->print(stderr, pc);fprintf (stderr, " --> ");pc_next->print(stderr, pc_next); fprintf(stderr, "\n"); + // first remove all preceeding SKIP instructions + while (pc_prev && isPCI_SKIP(pc_prev)) { + // attach labels on this instruction to pc_next + //fprintf (stderr, "(2) preceeding SKIP removed: ");pc_prev->print(stderr, pc_prev);fprintf(stderr, "\n"); + PCI(pc_next)->label = pic16_pBranchAppend (PCI(pc_prev)->label, PCI(pc_next)->label); + PCI(pc_prev)->label = NULL; + if (pic16_pcode_verbose) { pic16_pCodeInsertAfter (pc->prev, pic16_newpCodeCharP("(2) SKIP removed")); } + pic16_unlinkpCode (pc_prev); + pc_prev = pic16_findPrevInstruction (pc); + } // while + // now remove the redundant goto itself + PCI(pc_next)->label = pic16_pBranchAppend (PCI(pc)->label, PCI(pc_next)->label); + if (pic16_pcode_verbose) { pic16_pCodeInsertAfter (pc, pic16_newpCodeCharP("(2) GOTO next instruction removed")); } + pic16_unlinkpCode (pc); + pc = pic16_findPrevInstruction(pc_next->prev); + isHandled = 1; // do not perform further optimizations + opt_gotonext++; + change++; + } // if + + + /* (3) turn BTFSx STATUS,i; GOTO label into Bcc label if possible */ + if (!isHandled && condBraType != -1 && hasNoLabel(pc)) { + if (dist < MAX_DIST_BCC) { + pCode *bcc = NULL; + switch (condBraType) { + case 0x00: bcc = pic16_newpCode (POC_BC, PCI(pc)->pcop);break; + // no BDC on DIGIT CARRY available + case 0x02: bcc = pic16_newpCode (POC_BZ, PCI(pc)->pcop);break; + case 0x03: bcc = pic16_newpCode (POC_BOV, PCI(pc)->pcop);break; + case 0x04: bcc = pic16_newpCode (POC_BN, PCI(pc)->pcop);break; + case 0x10: bcc = pic16_newpCode (POC_BNC, PCI(pc)->pcop);break; + // no BNDC on DIGIT CARRY available + case 0x12: bcc = pic16_newpCode (POC_BNZ, PCI(pc)->pcop);break; + case 0x13: bcc = pic16_newpCode (POC_BNOV, PCI(pc)->pcop);break; + case 0x14: bcc = pic16_newpCode (POC_BNN, PCI(pc)->pcop);break; + default: + // no replacement possible + bcc = NULL; + break; + } // switch + if (bcc) { + // ATTENTION: keep labels attached to BTFSx! + // HINT: GOTO is label free (checked above) + //fprintf (stderr, "%s:%d: (3) turning %s %s into %s %s\n", __FUNCTION__, __LINE__, PCI(pc)->mnemonic, label, PCI(bcc)->mnemonic, label); + isHandled = 1; // do not perform further optimizations + if (pic16_pcode_verbose) { pic16_pCodeInsertAfter(pc_prev->prev, pic16_newpCodeCharP("(3) conditional branch introduced")); } + pic16_pCodeReplace (pc_prev, bcc); + pc->destruct(pc); + pc = bcc; + opt_cond++; + change++; + } // if + } else { + //fprintf (stderr, "(%d, too far for Bcc)\n", dist); + cond_toofar++; + } // if + } // if + + if (!isHandled) { + // (4) eliminate the following (common) tripel: + // ; + // labels1: Bcc label2; + // GOTO somewhere; ; <-- instruction referenced by pc + // label2: + // and replace it by + // labels1: B#(cc) somewhere; ; #(cc) is the negated condition cc + // label2: + // ATTENTION: all labels pointing to "Bcc label2" must be attached + // to instead + // ATTENTION: This optimization is only valid if is + // not a skip operation! + // ATTENTION: somewhere must be within MAX_DIST_BCC bytes! + // ATTENTION: no label may be attached to the GOTO instruction! + if (isConditionalBranch(pc_prev) + && (!isPCI_SKIP(pic16_findPrevInstruction(pc_prev->prev))) + && (dist < MAX_DIST_BCC) + && isLabel(pc_next,PCI(pc_prev)->pcop->name) + && hasNoLabel(pc)) { + pCode *newBcc = getNegatedBcc (pc_prev, PCI(pc)->pcop); + + if (newBcc) { + //fprintf (stderr, "%s:%d: (4) turning %s %s into %s %s\n", __FUNCTION__, __LINE__, PCI(pc)->mnemonic, label, PCI(newBcc)->mnemonic, label); + isHandled = 1; // do not perform further optimizations + if (pic16_pcode_verbose) { pic16_pCodeInsertAfter(pc_prev->prev, pic16_newpCodeCharP("(4) conditional skipping branch inverted")); } + pic16_pCodeReplace (pc_prev, newBcc); + pc->destruct(pc); + pc = newBcc; + opt_reorder++; + change++; + matchedInvertRule++; + } } -#endif + } + + /* (5) now just turn GOTO into BRA */ + if (!isHandled && (PCI(pc)->op == POC_GOTO)) { + if (dist < MAX_DIST_BRA) { + pCode *newBra = pic16_newpCode (POC_BRA, PCI(pc)->pcop); + //fprintf (stderr, "%s:%d: (5) turning %s %s into %s %s\n", __FUNCTION__, __LINE__, PCI(pc)->mnemonic, label, PCI(newBra)->mnemonic, label); + if (pic16_pcode_verbose) { pic16_pCodeInsertAfter(pc->prev, pic16_newpCodeCharP("(5) GOTO replaced by BRA")); } + pic16_pCodeReplace (pc, newBra); + pc = newBra; + opt++; + change++; + } else { + //fprintf (stderr, "(%d, too far for BRA)\n", dist); + toofar++; + } + } // if (!isHandled) + } // if + pc_prev = pc; + pc = pc_next; + } // while (pc) + + pBlockRemoveUnusedLabels (pb); + + // This line enables goto chain resolution! + if (matchedInvertRule > 1) matchedInvertRule = 1; else matchedInvertRule = 0; + + iteration++; + } while (change); /* fixpoint iteration per pBlock */ + } // for (pb) + + // emit some statistics concerning goto-optimization +#if 0 + if (pic16_debug_verbose || pic16_pcode_verbose) { + fprintf (stderr, "optimize-goto:\n" + "\t%5d GOTO->BRA; (%d GOTOs too far)\n" + "\t%5d BTFSx, GOTO->Bcc (%d too far)\n" + "\t%5d conditional \"skipping\" jumps inverted\n" + "\t%5d GOTOs to next instruction removed\n" + "\t%5d chained GOTOs resolved\n", + opt, toofar, opt_cond, cond_toofar, opt_reorder, opt_gotonext, opt_gotochain); + } // if +#endif + //fprintf (stderr, "%s:%d: %s\n", __FILE__, __LINE__, __FUNCTION__); +} +#undef IS_GOTO +#undef MAX_JUMPCHAIN_DEPTH +#undef MAX_DIST_GOTO +#undef MAX_DIST_BRA +#undef MAX_DIST_BCC +/** END OF RAPHAEL NEIDER'S ADDITIONS **/ static void pBlockDestruct(pBlock *pb) { @@ -6083,7 +7441,7 @@ static void pBlockDestruct(pBlock *pb) return; - free(pb); +// free(pb); } @@ -6142,24 +7500,27 @@ static void mergepBlocks(char dbName) static void AnalyzeFlow(int level) { static int times_called=0; - pBlock *pb; - if(!the_pFile) - return; + if(!the_pFile) { + + /* remove unused allocated registers before exiting */ + pic16_RemoveUnusedRegisters(); + + 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); - - pic16_RegsUnMapLiveRanges(); + if(times_called++) { + for(pb = the_pFile->pbHead; pb; pb = pb->next) + unBuildFlow(pb); - } + pic16_RegsUnMapLiveRanges(); + } - GpcFlowSeq = 1; + GpcFlowSeq = 1; /* Phase 2 - Flow Analysis - Register Banking * @@ -6180,8 +7541,8 @@ static void AnalyzeFlow(int level) * a call or goto or whatever). */ - for(pb = the_pFile->pbHead; pb; pb = pb->next) - pic16_BuildFlow(pb); + for(pb = the_pFile->pbHead; pb; pb = pb->next) + pic16_BuildFlow(pb); /* Phase 2 - Flow Analysis - linking flow blocks @@ -6190,17 +7551,17 @@ static void AnalyzeFlow(int level) * to determine their order of excution. */ - for(pb = the_pFile->pbHead; pb; pb = pb->next) - LinkFlow(pb); + for(pb = the_pFile->pbHead; pb; pb = pb->next) + LinkFlow(pb); /* Phase 3 - Flow Analysis - Flow Tree * * In this phase, the individual flow blocks are examined - * to determine their order of excution. + * to determine their order of execution. */ - for(pb = the_pFile->pbHead; pb; pb = pb->next) - pic16_BuildFlowTree(pb); + for(pb = the_pFile->pbHead; pb; pb = pb->next) + pic16_BuildFlowTree(pb); /* Phase x - Flow Analysis - Used Banks @@ -6209,51 +7570,62 @@ static void AnalyzeFlow(int level) * to determine the Register Banks they use */ - for(pb = the_pFile->pbHead; pb; pb = pb->next) - FixBankFlow(pb); +#if 0 + for(pb = the_pFile->pbHead; pb; pb = pb->next) + FixBankFlow(pb); +#endif - for(pb = the_pFile->pbHead; pb; pb = pb->next) - pic16_pCodeRegMapLiveRanges(pb); + for(pb = the_pFile->pbHead; pb; pb = pb->next) + pic16_pCodeRegMapLiveRanges(pb); - pic16_RemoveUnusedRegisters(); + pic16_RemoveUnusedRegisters(); // for(pb = the_pFile->pbHead; pb; pb = pb->next) - pic16_pCodeRegOptimizeRegUsage(level); + pic16_pCodeRegOptimizeRegUsage(level); if(!options.nopeep) OptimizepCode('*'); -/* - for(pb = the_pFile->pbHead; pb; pb = pb->next) - DumpFlow(pb); -*/ +#if 0 + for(pb = the_pFile->pbHead; pb; pb = pb->next) + DumpFlow(pb); +#endif + /* debug stuff */ - for(pb = the_pFile->pbHead; pb; pb = pb->next) { - pCode *pcflow; - for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); - (pcflow = pic16_findNextpCode(pcflow, PC_FLOW)) != NULL; - pcflow = pcflow->next) { + for(pb = the_pFile->pbHead; pb; pb = pb->next) { + pCode *pcflow; + for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); + (pcflow = pic16_findNextpCode(pcflow, PC_FLOW)) != NULL; + pcflow = pcflow->next) { + + FillFlow(PCFL(pcflow)); + } + } - FillFlow(PCFL(pcflow)); - } - } +#if 0 + for(pb = the_pFile->pbHead; pb; pb = pb->next) { + pCode *pcflow; -/* - for(pb = the_pFile->pbHead; pb; pb = pb->next) { - pCode *pcflow; - for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); - (pcflow = pic16_findNextpCode(pcflow, PC_FLOW)) != NULL; - pcflow = pcflow->next) { + for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); + (pcflow = pic16_findNextpCode(pcflow, PC_FLOW)) != NULL; + pcflow = pcflow->next) { - FlowStats(PCFL(pcflow)); - } - } -*/ + FlowStats(PCFL(pcflow)); + } + } +#endif } +/* VR -- no need to analyze banking in flow, but left here : + * 1. because it may be used in the future for other purposes + * 2. because if omitted we'll miss some optimization done here + * + * Perhaps I should rename it to something else + */ + /*-----------------------------------------------------------------*/ /* pic16_AnalyzeBanking - Called after the memory addresses have been */ /* assigned to the registers. */ @@ -6264,29 +7636,24 @@ void pic16_AnalyzeBanking(void) { pBlock *pb; - if(!pic16_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 - */ + /* 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); + AnalyzeFlow(0); + AnalyzeFlow(1); - for(pb = the_pFile->pbHead; pb; pb = pb->next) - BanksUsedFlow(pb); + if(!the_pFile)return; - for(pb = the_pFile->pbHead; pb; pb = pb->next) - pic16_FixRegisterBanking(pb); + if(!pic16_options.no_banksel) { + for(pb = the_pFile->pbHead; pb; pb = pb->next) { +// fprintf(stderr, "%s:%d: Fix register banking in pb= 0x%p\n", __FILE__, __LINE__, pb); + pic16_FixRegisterBanking(pb); + } + } } @@ -6300,7 +7667,8 @@ static void buildCallTree(void ) pBranch *pbr; pBlock *pb; pCode *pc; - + regs *r; + if(!the_pFile) return; @@ -6335,6 +7703,19 @@ static 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(isPCI(pc) && pc_fstart) { + if(PCI(pc)->is2MemOp) { + r = pic16_getRegFromInstruction2(pc); + if(r && !strcmp(r->name, "POSTDEC1")) + PCF(pc_fstart)->stackusage++; + } else { + r = pic16_getRegFromInstruction(pc); + if(r && !strcmp(r->name, "PREINC1")) + PCF(pc_fstart)->stackusage--; + } + } + if(isPCF(pc)) { if (PCF(pc)->fname) { @@ -6367,6 +7748,11 @@ static void buildCallTree(void ) } } + +#if 0 + /* This is not needed because currently all register used + * by a function are stored in stack -- VR */ + /* Re-allocate the registers so that there are no collisions * between local variables when one function call another */ @@ -6377,6 +7763,7 @@ static void buildCallTree(void ) if(!pb->visited) register_usage(pb); } +#endif } @@ -6435,9 +7822,183 @@ void pic16_AnalyzepCode(char dbName) } while(changes && (i++ < MAX_PASSES)); + buildCallTree(); } + +/* convert a series of movff's of local regs to stack, with a single call to + * a support functions which does the same thing via loop */ +static void pic16_convertLocalRegs2Support(pCode *pcstart, pCode *pcend, int count, regs *r, int entry) +{ + pBranch *pbr; + pCode *pc, *pct; + char *fname[]={"__lr_store", "__lr_restore"}; + +// pc = pic16_newpCode(POC_CALL, pic16_popGetFromString( (entry?fname[0]:fname[1]) )); + + pct = pic16_findNextInstruction(pcstart->next); + do { + pc = pct; + pct = pc->next; //pic16_findNextInstruction(pc->next); +// pc->print(stderr, pc); + if(isPCI(pc) && PCI(pc)->label) { + pbr = PCI(pc)->label; + while(pbr && pbr->pc) { + PCI(pcstart)->label = pic16_pBranchAppend(PCI(pcstart)->label, pbr); + pbr = pbr->next; + } + +// pc->print(stderr, pc); + /* unlink pCode */ + pc->prev->next = pct; + pct->prev = pc->prev; +// pc->next = NULL; +// pc->prev = NULL; + } + } while ((pc) && (pc != pcend)); + + /* unlink movff instructions */ + pcstart->next = pcend; + pcend->prev = pcstart; + + pc = pcstart; +// if(!entry) { +// pic16_pCodeInsertAfter(pc, pct = pic16_newpCode(POC_MOVFF, pic16_popGet2p( +// pic16_popCopyReg(&pic16_pc_fsr0l), pic16_popCopyReg(pic16_framepnt_lo)))); pc = pct; +// } + + pic16_pCodeInsertAfter(pc, pct=pic16_newpCode(POC_LFSR, pic16_popGetLit2(0, pic16_popGetWithString(r->name)))); pc = pct; + pic16_pCodeInsertAfter(pc, pct=pic16_newpCode(POC_MOVLW, pic16_popGetLit( count ))); pc = pct; + pic16_pCodeInsertAfter(pc, pct=pic16_newpCode(POC_CALL, pic16_popGetWithString( fname[ (entry==1?0:1) ] ))); pc = pct; + +// if(!entry) { +// pic16_pCodeInsertAfter(pc, pct = pic16_newpCode(POC_MOVFF, pic16_popGet2p( +// pic16_popCopyReg(pic16_framepnt_lo), pic16_popCopyReg(&pic16_pc_fsr0l)))); pc = pct; +// } + + + { + symbol *sym; + + sym = newSymbol( fname[ entry?0:1 ], 0 ); + strcpy(sym->rname, fname[ entry?0:1 ]); + checkAddSym(&externs, sym); + +// fprintf(stderr, "%s:%d adding extern symbol %s in externs\n", __FILE__, __LINE__, fname[ entry?0:1 ]); + } + +} + +/*-----------------------------------------------------------------*/ +/* OptimizeLocalRegs - turn sequence of MOVFF instructions for */ +/* local registers to a support function call */ +/*-----------------------------------------------------------------*/ +void pic16_OptimizeLocalRegs(void) +{ + pBlock *pb; + pCode *pc; + pCodeInfo *pci; + pCodeOpLocalReg *pclr; + int regCount=0; + int inRegCount=0; + regs *r, *lastr=NULL, *firstr=NULL; + pCode *pcstart=NULL, *pcend=NULL; + int inEntry=0; + char *curFunc=NULL; + + /* Overview: + * local_regs begin mark + * MOVFF r0x01, POSTDEC1 + * MOVFF r0x02, POSTDEC1 + * ... + * ... + * MOVFF r0x0n, POSTDEC1 + * local_regs end mark + * + * convert the above to the below: + * MOVLW starting_register_index + * MOVWF PRODL + * MOVLW register_count + * call __save_registers_in_stack + */ + + if(!the_pFile) + return; + + for(pb = the_pFile->pbHead; pb; pb = pb->next) { + inRegCount = regCount = 0; + firstr = lastr = NULL; + for(pc = pb->pcHead; pc; pc = pc->next) { + + /* hold current function name */ + if(pc && isPCF(pc))curFunc = PCF(pc)->fname; + + if(pc && (pc->type == PC_INFO)) { + pci = PCINF(pc); + + if(pci->type == INF_LOCALREGS) { + pclr = PCOLR(pci->oper1); + + if((pclr->type == LR_ENTRY_BEGIN) + || (pclr->type == LR_ENTRY_END))inEntry = 1; + else inEntry = 0; + + switch(pclr->type) { + case LR_ENTRY_BEGIN: + case LR_EXIT_BEGIN: + inRegCount = 1; regCount = 0; + pcstart = pc; //pic16_findNextInstruction(pc->next); + firstr = lastr = NULL; + break; + + case LR_ENTRY_END: + case LR_EXIT_END: + inRegCount = -1; + pcend = pc; //pic16_findPrevInstruction(pc->prev); + +#if 1 + if(curFunc && inWparamList(curFunc+1)) { + fprintf(stderr, "sdcc: %s: warning: disabling lr-support for functionn %s\n", + filename, curFunc); + } else { + if(regCount>2) { + pic16_convertLocalRegs2Support(pcstart, pcend, regCount, + firstr, inEntry); + } + } +#endif + firstr = lastr = NULL; + break; + } + + if(inRegCount == -1) { +// fprintf(stderr, "%s:%d registers used [%s] %d\n", __FILE__, __LINE__, inEntry?"entry":"exit", regCount); + regCount = 0; + inRegCount = 0; + } + } + } else { + if(isPCI(pc) && (PCI(pc)->op == POC_MOVFF) && (inRegCount == 1)) { + if(inEntry) + r = pic16_getRegFromInstruction(pc); + else + r = pic16_getRegFromInstruction2(pc); + if(r && (r->type == REG_GPR) && (r->pc_type == PO_GPR_TEMP)) { + if(!firstr)firstr = r; + regCount++; +// fprintf(stderr, "%s:%d\t%s\t%i\t%d/%d\n", __FILE__, __LINE__, r->name, r->rIdx); + } + } + } + } + } +} + + + + + /*-----------------------------------------------------------------*/ /* ispCodeFunction - returns true if *pc is the pCode of a */ /* function */ @@ -6502,6 +8063,8 @@ static void pBlockStats(FILE *of, pBlock *pb) pCode *pc; regs *r; + if(!pic16_pcode_verbose)return; + fprintf(of,";***\n; pBlock Stats: dbName = %c\n;***\n",getpBlock_dbName(pb)); // for now just print the first element of each set @@ -6539,6 +8102,8 @@ static void pBlockStats(FILE *of, pBlock *pb) r = setNextItem(pb->tregisters); } } + + fprintf(of, "; uses %d bytes of stack\n", 1+ elementsInSet(pb->tregisters)); } /*-----------------------------------------------------------------*/ @@ -6675,7 +8240,7 @@ static set *register_usage(pBlock *pb) /* pct2 - writes the call tree to a file */ /* */ /*-----------------------------------------------------------------*/ -static void pct2(FILE *of,pBlock *pb,int indent) +static void pct2(FILE *of,pBlock *pb,int indent,int usedstack) { pCode *pc,*pcn; int i; @@ -6684,8 +8249,10 @@ static void pct2(FILE *of,pBlock *pb,int indent) if(!of) return; - if(indent > 10) + if(indent > 10) { + fprintf(of, "recursive function\n"); return; //recursion ? + } pc = setFirstItem(pb->function_entries); @@ -6695,12 +8262,13 @@ static void pct2(FILE *of,pBlock *pb,int indent) pb->visited = 0; for(i=0;itype == PC_FUNCTION) - fprintf(of,"%s\n",PCF(pc)->fname); - else - return; // ??? + if(pc->type == PC_FUNCTION) { + usedstack += PCF(pc)->stackusage; + fprintf(of,"%s (stack: %i)\n",PCF(pc)->fname, usedstack); + } else return; // ??? pc = setFirstItem(pb->function_calls); @@ -6711,7 +8279,7 @@ static void pct2(FILE *of,pBlock *pb,int indent) pcn = findFunction(dest); if(pcn) - pct2(of,pcn->pb,indent+1); + pct2(of,pcn->pb,indent+1, usedstack); // + PCF(pcn)->stackusage); } else fprintf(of,"BUG? pCode isn't a POC_CALL %d\n",__LINE__); @@ -6743,7 +8311,6 @@ void pic16_printCallTree(FILE *of) pBlockStats(of,pb); - fprintf(of,"Call Tree\n"); pbr = the_pFile->functions; while(pbr) { @@ -6768,8 +8335,8 @@ void pic16_printCallTree(FILE *of) fprintf(of,"\n**************\n\na better call tree\n"); for(pb = the_pFile->pbHead; pb; pb = pb->next) { - if(pb->visited) - pct2(of,pb,0); +// if(pb->visited) + pct2(of,pb,0,0); } for(pb = the_pFile->pbHead; pb; pb = pb->next) { @@ -6802,7 +8369,7 @@ static void InlineFunction(pBlock *pb) pBranch *pbr; - if(pcn && isPCF(pcn) && (PCF(pcn)->ncalled == 1)) { + if(pcn && isPCF(pcn) && (PCF(pcn)->ncalled == 0)) { /* change 0 to 1 to enable inlining */ //fprintf(stderr,"Cool can inline:\n"); //pcn->print(stderr,pcn); @@ -6929,3 +8496,699 @@ void pic16_InlinepCode(void) unBuildFlow(pb); } + +char *pic_optype_names[]={ + "PO_NONE", // No operand e.g. NOP + "PO_W", // The working register (as a destination) + "PO_WREG", // The working register (as a file register) + "PO_STATUS", // The 'STATUS' register + "PO_BSR", // The 'BSR' register + "PO_FSR0", // The "file select register" (in PIC18 family it's one + // of three) + "PO_INDF0", // The Indirect register + "PO_INTCON", // Interrupt Control register + "PO_GPR_REGISTER", // A general purpose register + "PO_GPR_BIT", // A bit of a general purpose register + "PO_GPR_TEMP", // A general purpose temporary register + "PO_SFR_REGISTER", // A special function register (e.g. PORTA) + "PO_PCL", // Program counter Low register + "PO_PCLATH", // Program counter Latch high register + "PO_PCLATU", // Program counter Latch upper register + "PO_PRODL", // Product Register Low + "PO_PRODH", // Product Register High + "PO_LITERAL", // A constant + "PO_REL_ADDR", // A relative address + "PO_IMMEDIATE", // (8051 legacy) + "PO_DIR", // Direct memory (8051 legacy) + "PO_CRY", // bit memory (8051 legacy) + "PO_BIT", // bit operand. + "PO_STR", // (8051 legacy) + "PO_LABEL", + "PO_WILD" // Wild card operand in peep optimizer +}; + + +char *dumpPicOptype(PIC_OPTYPE type) +{ + return (pic_optype_names[ type ]); +} + + +/*** BEGIN of stuff belonging to the BANKSEL optimization ***/ +#include "graph.h" + +#define MAX_COMMON_BANK_SIZE 32 +#define FIRST_PSEUDO_BANK_NR 1000 + +hTab *sym2bank = NULL; // --> +hTab *bank2sym = NULL; // --> +hTab *coerce = NULL; // --> <&PSEUDOBANK> +Graph *adj = NULL; + +typedef enum { INVALID_BANK = -1, UNKNOWN_BANK = -2, FIXED_BANK = -3 } pseudoBankNr; + +typedef struct { + pseudoBankNr bank; // number assigned to this pseudoBank + unsigned int size; // number of operands assigned to this bank + unsigned int ref; // number of symbols referring to this pseudoBank (for garbage collection) +} pseudoBank; + +/*----------------------------------------------------------------------*/ +/* hashSymbol - hash function used to map SYMBOLs (or operands) to ints */ +/*----------------------------------------------------------------------*/ +unsigned int hashSymbol (const char *str) +{ + unsigned int res = 0; + if (!str) return 0; + + while (*str) { + res ^= (*str); + res = (res << 4) | (res >> (8 * sizeof(unsigned int) - 4)); + str++; + } // while + + return res; +} + +/*-----------------------------------------------------------------------*/ +/* compareSymbol - return 1 iff sym1 equals sym2 */ +/*-----------------------------------------------------------------------*/ +int compareSymbol (const void *sym1, const void *sym2) +{ + char *s1 = (char*) sym1; + char *s2 = (char*) sym2; + + return (strcmp (s1,s2) == 0); +} + +/*-----------------------------------------------------------------------*/ +/* comparePre - return 1 iff p1 == p2 */ +/*-----------------------------------------------------------------------*/ +int comparePtr (const void *p1, const void *p2) +{ + return (p1 == p2); +} + +/*----------------------------------------------------------*/ +/* getSymbolFromOperand - return a pointer to the symbol in */ +/* the given operand and its length */ +/*----------------------------------------------------------*/ +char *getSymbolFromOperand (char *op, unsigned int *len) +{ + char *sym, *curr; + *len = 0; + + if (!op) return NULL; + + // we recognize two forms of operands: SYMBOL and (SYMBOL + offset) + sym = op; + if (*sym == '(') sym++; + + curr = sym; + while (((*curr >= 'A') && (*curr <= 'Z')) + || ((*curr >= 'a') && (*curr <= 'z')) + || ((curr != sym) && (*curr >= '0') && (*curr <= '9')) + || (*curr == '_')) { + // find end of symbol [A-Za-z_]?[A-Za-z0-9]* + curr++; + (*len)++; + } // while + + return sym; +} + +/*--------------------------------------------------------------------------*/ +/* getSymFromBank - get (one) name of a symbol assigned to the given bank */ +/*--------------------------------------------------------------------------*/ +char *getSymFromBank (pseudoBankNr bank) +{ + assert (bank2sym); + + if (bank < 0) return ""; + return hTabFindByKey (bank2sym, bank % bank2sym->size, (void *) bank, &comparePtr); +} + +/*-----------------------------------------------------------------------*/ +/* getPseudoBsrFromOperand - maps a string to its corresponding pseudo */ +/* bank number (uses hTab sym2bank), if the */ +/* symbol is not yet assigned a pseudo bank it */ +/* is assigned one here */ +/*-----------------------------------------------------------------------*/ +pseudoBankNr getPseudoBankNrFromOperand (const char *op) +{ + static pseudoBankNr next_bank = FIRST_PSEUDO_BANK_NR; + pseudoBankNr bank; + unsigned int hash; + + assert (sym2bank); + + hash = hashSymbol (op) % sym2bank->size; + bank = (pseudoBankNr) hTabFindByKey (sym2bank, hash, op, &compareSymbol); + if (bank == (pseudoBankNr)NULL) bank = UNKNOWN_BANK; + + if (bank == UNKNOWN_BANK) { + // create a pseudo bank for the operand + bank = next_bank++; + hTabAddItemLong (&sym2bank, hash, (char *)op, (void *)bank); + hTabAddItemLong (&bank2sym, bank, (void *) bank, (void *)op); + getOrAddGNode (adj, NULL, bank); // adds the node if it does not exist yet + //fprintf (stderr, "%s:%d: adding %s with hash %u in bank %u\n", __FUNCTION__, __LINE__, op, hash, bank); + } else { + //fprintf (stderr, "%s:%d: found %s with hash %u in bank %u\n", __FUNCTION__, __LINE__, op, hash, bank); + } // if + + assert (bank >= 0); + + return bank; +} + +/*--------------------------------------------------------------------*/ +/* isBanksel - check whether the given pCode is a BANKSEL instruction */ +/*--------------------------------------------------------------------*/ +int isBanksel (pCode *pc) +{ + if (!pc) return 0; + + if (isPCI(pc) && (PCI(pc)->op == POC_BANKSEL || PCI(pc)->op == POC_MOVLB)) { + // BANKSEL or MOVLB + //fprintf (stderr, "%s:%d: BANKSEL found: %s %s\n", __FUNCTION__, __LINE__, PCAD(pc)->directive, PCAD(pc)->arg); + return 1; + } + + // check for inline assembler BANKSELs + if (isPCAD(pc) && PCAD(pc)->directive && (STRCASECMP(PCAD(pc)->directive,"BANKSEL") == 0 || + STRCASECMP(PCAD(pc)->directive,"MOVLB") == 0)) { + //fprintf (stderr, "%s:%d: BANKSEL found: %s %s\n", __FUNCTION__, __LINE__, PCAD(pc)->directive, PCAD(pc)->arg); + return 1; + } + + // assume pc is no BANKSEL instruction + return 0; +} + +/*---------------------------------------------------------------------------------*/ +/* invalidatesBSR - check whether the pCodeInstruction passed in modifies the BSR */ +/* This method can not guarantee to find all modifications of the */ +/* BSR (e.g. via INDirection registers) but covers all compiler */ +/* generated plus some cases. */ +/*---------------------------------------------------------------------------------*/ +int invalidatesBSR(pCode *pc) +{ + // assembler directives invalidate BSR (well, they might, we don't know) + if (isPCAD(pc)) return 1; + + // only ASMDIRs and pCodeInstructions can invalidate BSR + if (!isPCI(pc)) return 0; + + // we have a pCodeInstruction + + // check for BSR modifying instructions + switch (PCI(pc)->op) { + case POC_CALL: + case POC_RCALL: + case POC_MOVLB: + case POC_RETFIE: // might be used as CALL replacement + case POC_RETLW: // might be used as CALL replacement + case POC_RETURN: // might be used as CALL replacement + case POC_BANKSEL: + return 1; + break; + + default: // other instruction do not change BSR unless BSR is an explicit operand! + // TODO: check for BSR as an explicit operand (e.g. INCF BSR,F), which should be rather unlikely...! + break; + } // switch + + // no change of BSR possible/probable + return 0; +} + +/*------------------------------------------------------------*/ +/* getBankFromBanksel - return the pseudo bank nr assigned to */ +/* the symbol referenced in this BANKSEL */ +/*------------------------------------------------------------*/ +pseudoBankNr getBankFromBanksel (pCode *pc) +{ + char *sym; + int data = (int)NULL; + + if (!pc) return INVALID_BANK; + + if (isPCAD(pc) && PCAD(pc)->directive) { + if (STRCASECMP(PCAD(pc)->directive,"BANKSEL") == 0) { + // get symbolname from PCAD(pc)->arg + //fprintf (stderr, "%s:%d: BANKSEL found: %s %s\n", __FUNCTION__, __LINE__, PCAD(pc)->directive, PCAD(pc)->arg); + sym = PCAD(pc)->arg; + data = getPseudoBankNrFromOperand (sym); + //fprintf (stderr, "symbol: %s, data=%i\n", sym, data); + } else if (STRCASECMP(PCAD(pc)->directive,"MOVLB")) { + // get (literal) bank number from PCAD(pc)->arg + fprintf (stderr, "%s:%d: MOVLB found: %s %s\n", __FUNCTION__, __LINE__, PCAD(pc)->directive, PCAD(pc)->arg); + assert (0 && "not yet implemented - turn off banksel optimization for now"); + } + } else if (isPCI(pc)) { + if (PCI(pc)->op == POC_BANKSEL) { + // get symbolname from PCI(pc)->pcop->name (?) + //fprintf (stderr, "%s:%d: BANKSEL found: %s %s\n", __FUNCTION__, __LINE__, PCI(pc)->mnemonic, PCI(pc)->pcop->name); + sym = PCI(pc)->pcop->name; + data = getPseudoBankNrFromOperand (sym); + //fprintf (stderr, "symbol: %s, data=%i\n", sym, data); + } else if (PCI(pc)->op == POC_MOVLB) { + // get (literal) bank number from PCI(pc)->pcop->name + fprintf (stderr, "%s:%d: MOVLB found: %s %s\n", __FUNCTION__, __LINE__, PCI(pc)->mnemonic, PCI(pc)->pcop->name); + assert (0 && "not yet implemented - turn off banksel optimization for now"); + } + } + + if (data == 0) + // no assigned bank could be found + return UNKNOWN_BANK; + else + return data; +} + +/*------------------------------------------------------------------------------*/ +/* getEffectiveBank - resolves the currently assigned effective pseudo bank nr */ +/*------------------------------------------------------------------------------*/ +pseudoBankNr getEffectiveBank (pseudoBankNr bank) +{ + pseudoBank *data; + + if (bank < FIRST_PSEUDO_BANK_NR) return bank; + + do { + //fprintf (stderr, "%s:%d: bank=%d\n", __FUNCTION__, __LINE__, bank); + data = (pseudoBank *) hTabFindByKey (coerce, bank % coerce->size, (void *) bank, &comparePtr); + if (data) { + if (data->bank != bank) + bank = data->bank; + else + data = NULL; + } + } while (data); + + //fprintf (stderr, "%s:%d: effective bank=%d\n", __FUNCTION__, __LINE__, bank); + return bank; +} + +/*------------------------------------------------------------------*/ +/* attachBsrInfo2pBlock - create a look-up table as to which pseudo */ +/* bank is selected at a given pCode */ +/*------------------------------------------------------------------*/ + +/* Create a graph with pseudo banks as its nodes and switches between + * these as edges (with the edge weight representing the absolute + * number of BANKSELs from one to the other). + * Removes redundand BANKSELs instead iff mod == 1. + * BANKSELs update the pseudo BSR, labels invalidate the current BSR + * value (setting it to 0=UNNKOWN), (R)CALLs also invalidate the + * pseudo BSR. + * TODO: check ALL instructions operands if they modify BSR directly... + * + * pb - the pBlock to annotate + * mod - select either graph creation (0) or BANKSEL removal (1) + */ +unsigned int attachBsrInfo2pBlock (pBlock *pb, int mod) +{ + pCode *pc, *pc_next; + unsigned int prevBSR = UNKNOWN_BANK, pseudoBSR = UNKNOWN_BANK; + int isBankselect = 0; + unsigned int banksels=0; + + if (!pb) return 0; + + pc = pic16_findNextInstruction(pb->pcHead); + while (pc) { + isBankselect = isBanksel (pc); + pc_next = pic16_findNextInstruction (pc->next); + + if (!hasNoLabel (pc)) { + // we don't know our predecessors -- assume different BSRs + prevBSR = UNKNOWN_BANK; + pseudoBSR = UNKNOWN_BANK; + //fprintf (stderr, "invalidated by label at "); pc->print (stderr, pc); + } // if + + // check if this is a BANKSEL instruction + if (isBankselect) { + pseudoBSR = getEffectiveBank (getBankFromBanksel(pc)); + //fprintf (stderr, "BANKSEL via "); pc->print (stderr, pc); + if (mod) { + if (prevBSR == pseudoBSR && pseudoBSR >= 0) { + //fprintf (stderr, "removing redundant "); pc->print (stderr, pc); + if (1 || pic16_pcode_verbose) pic16_pCodeInsertAfter (pc->prev, pic16_newpCodeCharP("removed redundant BANKSEL")); + pic16_unlinkpCode (pc); + banksels++; + } + } else { + addGEdge2 (getOrAddGNode (adj, NULL, prevBSR), getOrAddGNode (adj, NULL, pseudoBSR), 1, 0); + banksels++; + } + } // if + + if (!isBankselect && invalidatesBSR(pc)) { + // check if this instruction invalidates the pseudoBSR + pseudoBSR = UNKNOWN_BANK; + //fprintf (stderr, "invalidated via "); pc->print (stderr, pc); + } // if + + prevBSR = pseudoBSR; + pc = pc_next; + } // while + + return banksels; +} + +/*------------------------------------------------------------------------------------*/ +/* assignToSameBank - returns 0 on success or an error code */ +/* 1 - common bank would be too large */ +/* 2 - assignment to fixed (absolute) bank not performed */ +/* */ +/* This functions assumes that unsplittable operands are already assigned to the same */ +/* bank (e.g. all objects being referenced as (SYMBOL + offset) must be in the same */ +/* bank so that we can make sure the bytes are laid out sequentially in memory) */ +/* TODO: Symbols with an abslute address must be handled specially! */ +/*------------------------------------------------------------------------------------*/ +int assignToSameBank (int bank0, int bank1, int doAbs) +{ + int eff0, eff1, dummy; + pseudoBank *pbank0, *pbank1; + hashtItem *hitem; + + eff0 = getEffectiveBank (bank0); + eff1 = getEffectiveBank (bank1); + + //fprintf (stderr, "%s:%d: bank0=%d/%d, bank1=%d/%d, doAbs=%d\n", __FUNCTION__, __LINE__, bank0, eff0, bank1, eff1, doAbs); + + // nothing to do if already same bank + if (eff0 == eff1) return 0; + + if (!doAbs && (eff0 < FIRST_PSEUDO_BANK_NR || eff1 < FIRST_PSEUDO_BANK_NR)) + return 2; + + // ensure eff0 < eff1 + if (eff0 > eff1) { + // swap eff0 and eff1 + dummy = eff0; + eff0 = eff1; + eff1 = dummy; + dummy = bank0; + bank0 = bank1; + bank1 = dummy; + } // if + + // now assign bank eff1 to bank eff0 + pbank0 = (pseudoBank *) hTabFindByKey (coerce, eff0 % coerce->size, (void *) eff0, &comparePtr); + if (!pbank0) { + pbank0 = Safe_calloc (1, sizeof (pseudoBank)); + pbank0->bank = eff0; + pbank0->size = 1; + pbank0->ref = 1; + hTabAddItemLong (&coerce, eff0 % coerce->size, (void *) eff0, (void *) pbank0); + } // if + + pbank1 = NULL; + hitem = hTabSearch (coerce, eff1 % coerce->size); + while (hitem && hitem->pkey != (void *)eff1) + hitem = hitem->next; + + if (hitem) pbank1 = (pseudoBank *) hitem->item; + +#if 0 + fprintf (stderr, "bank #%d/%d & bank #%d/%d --> bank #%d: %u (%s & %s)\n", bank0, eff0, bank1, eff1, + pbank0->bank, pbank0->size, + getSymFromBank (eff0), getSymFromBank (eff1)); +#endif + + if (pbank1) { + if (pbank0->size + pbank1->size > MAX_COMMON_BANK_SIZE) { +#if 0 + fprintf (stderr, "bank #%d: %u, bank #%d: %u --> bank #%d': %u > %u (%s,%s)\n", + pbank0->bank, pbank0->size, pbank1->bank, pbank1->size, + pbank0->bank, pbank0->size + pbank1->size, MAX_COMMON_BANK_SIZE, + getSymFromBank (pbank0->bank), getSymFromBank (pbank1->bank)); +#endif + return 1; + } // if + pbank0->size += pbank1->size; + pbank1->ref--; + if (pbank1->ref == 0) Safe_free (pbank1); + } else { + pbank0->size++; + } // if + + if (hitem) + hitem->item = pbank0; + else + hTabAddItemLong (&coerce, eff1 % coerce->size, (void *) eff1, (void *) pbank0); + pbank0->ref++; + + //fprintf (stderr, "%s:%d: leaving.\n", __FUNCTION__, __LINE__); + + return 0; +} + +/*----------------------------------------------------------------*/ +/* mergeGraphNodes - combines two nodes into one and modifies all */ +/* edges to and from the nodes accordingly */ +/* This method needs complete backedges, i.e. if (A,B) is an edge */ +/* then also (B,A) must be an edge (possibly with weight 0). */ +/*----------------------------------------------------------------*/ +void mergeGraphNodes (GraphNode *node1, GraphNode *node2) +{ + GraphEdge *edge, *backedge, *nextedge; + GraphNode *node; + int backweight; + + assert (node1 && node2); + assert (node1 != node2); + + // add all edges starting at node2 to node1 + edge = node2->edge; + while (edge) { + nextedge = edge->next; + node = edge->node; + backedge = getGEdge (node, node2); + if (backedge) + backweight = backedge->weight; + else + backweight = 0; + // insert edges (node1,node) and (node,node1) + addGEdge2 (node1, node, edge->weight, backweight); + // remove edges (node, node2) and (node2, node) + remGEdge (node2, node); + remGEdge (node, node2); + edge = nextedge; + } // while + + // now node2 should not be referenced by any other GraphNode... + //remGNode (adj, node2->data, node2->hash); +} + +/*----------------------------------------------------------------*/ +/* showGraph - dump the current BANKSEL graph as a node/edge list */ +/*----------------------------------------------------------------*/ +void showGraph (Graph *g) +{ + GraphNode *node; + GraphEdge *edge; + pseudoBankNr bankNr; + pseudoBank *pbank; + unsigned int size; + + node = g->node; + while (node) { + edge = node->edge; + bankNr = getEffectiveBank (node->hash); + assert (bankNr >= 0); + pbank = (pseudoBank *) hTabFindByKey (coerce, bankNr % coerce->size, (void *) bankNr, &comparePtr); + if (pbank) { + bankNr = pbank->bank; + size = pbank->size; + } else { + size = 1; + } + + fprintf (stderr, "edges from %s (bank %u, size %u) to:\n", getSymFromBank (node->hash), bankNr, size); + + while (edge) { + if (edge->weight > 0) + fprintf (stderr, " %4u x %s\n", edge->weight, getSymFromBank (edge->node->hash)); + edge = edge->next; + } // while (edge) + node = node->next; + } // while (node) +} + +/*---------------------------------------------------------------*/ +/* pic16_OptimizeBanksel - remove redundant BANKSEL instructions */ +/*---------------------------------------------------------------*/ +void pic16_OptimizeBanksel () +{ + GraphNode *node, *node1, *node1next; + +#if 0 + // needed for more effective bank assignment (needs adjusted pic16_emit_usection()) + GraphEdge *edge, *backedge; + GraphEdge *max; + int maxWeight, weight, mergeMore, absMaxWeight; + pseudoBankNr curr0, curr1; +#endif + pseudoBank *pbank; + pseudoBankNr bankNr; + char *base_symbol0, *base_symbol1; + int len0, len1; + pBlock *pb; + set *set; + regs *reg; + unsigned int bankselsTotal = 0, bankselsRemoved = 0; + + //fprintf (stderr, "%s:%s:%d: entered.\n", __FILE__, __FUNCTION__, __LINE__); + + if (!the_pFile || !the_pFile->pbHead) return; + + adj = newGraph (NULL); + sym2bank = newHashTable ( 255 ); + bank2sym = newHashTable ( 255 ); + coerce = newHashTable ( 255 ); + + // create graph of BANKSEL relationships (node = operands, edge (A,B) iff BANKSEL B follows BANKSEL A) + for (pb = the_pFile->pbHead; pb; pb = pb->next) { + bankselsTotal += attachBsrInfo2pBlock (pb, 0); + } // for pb + +#if 1 + // assign symbols with absolute addresses to their respective bank nrs + set = pic16_fix_udata; + for (reg = setFirstItem (set); reg; reg = setNextItem (set)) { + bankNr = reg->address >> 8; + node = getOrAddGNode (adj, NULL, bankNr); + bankNr = (pseudoBankNr) getEffectiveBank (getPseudoBankNrFromOperand(reg->name)); + assignToSameBank (node->hash, bankNr, 1); + + assert (bankNr >= 0); + pbank = (pseudoBank *) hTabFindByKey (coerce, bankNr % coerce->size, (void *) bankNr, &comparePtr); + if (!pbank) { + pbank = Safe_calloc (1, sizeof (pseudoBank)); + pbank->bank = reg->address >> 8; //FIXED_BANK; + pbank->size = 1; + pbank->ref = 1; + hTabAddItemLong (&coerce, bankNr % coerce->size, (void *) bankNr, pbank); + } else { + assert (pbank->bank == (reg->address >> 8)); + pbank->bank = reg->address >> 8; //FIXED_BANK; + } + //fprintf (stderr, "ABS: %s (%d bytes) at %x in bank %u\n", reg->name, reg->size, reg->address, bankNr); + } // for reg +#endif + +#if 1 + // assign operands referring to the same symbol (which is not given an absolute address) to the same bank + //fprintf (stderr, "assign operands with the same symbol to the same bank\n"); + node = adj->node; + while (node) { + if (node->hash < 0) { node = node->next; continue; } + base_symbol0 = getSymbolFromOperand (getSymFromBank (getEffectiveBank(node->hash)), &len0); + node1 = node->next; + while (node1) { + if (node1->hash < 0) { node1 = node1->next; continue; } + node1next = node1->next; + base_symbol1 = getSymbolFromOperand (getSymFromBank (getEffectiveBank (node1->hash)), &len1); + if (len0 == len1 && len0 > 0 && strncmp (base_symbol0, base_symbol1, len0) == 0) { + // TODO: check for symbols with absolute addresses -- these might be placed across bank boundaries! + //fprintf (stderr, "merging %s and %s\n", getSymFromBank (getEffectiveBank(node->hash)), getSymFromBank (getEffectiveBank(node1->hash))); + if (assignToSameBank (node->hash, node1->hash, 0)) { + fprintf (stderr, "%s(%d) == %s(%d)\n", base_symbol0, len0, base_symbol1, len1); + assert (0 && "Could not assign a symbol to a bank!"); + } + mergeGraphNodes (node, node1); + /* + if (node->hash < node1->hash) + mergeGraphNodes (node, node1); + else + mergeGraphNodes (node1, node); // this removes node so node->next will fail... + */ + } // if + node1 = node1next; + } // while (node1) + node = node->next; + } // while (node) +#endif + +#if 0 + // >>> THIS ALSO NEEDS AN UPDATED pic16_emit_usection() TO REFLECT THE BANK ASSIGNMENTS <<< + // assign tightly coupled operands to the same (pseudo) bank + //fprintf (stderr, "assign tightly coupled operands to the same bank\n"); + mergeMore = 1; + absMaxWeight = 0; + while (mergeMore) { + node = adj->node; + max = NULL; + maxWeight = 0; + while (node) { + curr0 = getEffectiveBank (node->hash); + if (curr0 < 0) { node = node->next; continue; } + edge = node->edge; + while (edge) { + assert (edge->src == node); + backedge = getGEdge (edge->node, edge->src); + weight = edge->weight + (backedge ? backedge->weight : 0); + curr1 = getEffectiveBank (edge->node->hash); + if (curr1 < 0) { edge = edge->next; continue; } + + // merging is only useful if the items are not assigned to the same bank already... + if (curr0 != curr1 && weight > maxWeight) { + if (maxWeight > absMaxWeight) absMaxWeight = maxWeight; + maxWeight = weight; + max = edge; + } // if + edge = edge->next; + } // while + node = node->next; + } // while + + if (maxWeight > 0) { +#if 1 + fprintf (stderr, "%s:%d: merging (%4u) %d(%s) and %d(%s)\n", __FUNCTION__, __LINE__, maxWeight, + max->src->hash, getSymFromBank (max->src->hash), + max->node->hash, getSymFromBank (max->node->hash)); +#endif + + node = getGNode (adj, max->src->data, max->src->hash); + node1 = getGNode (adj, max->node->data, max->node->hash); + + if (0 == assignToSameBank (max->src->hash, max->node->hash, 0)) { + if (max->src->hash < max->node->hash) + mergeGraphNodes (node, node1); + else + mergeGraphNodes (node1, node); + } else { + remGEdge (node, node1); + remGEdge (node1, node); + //mergeMore = 0; + } + + } else { + mergeMore = 0; + } + } // while +#endif + +#if 1 + // remove redundant BANKSELs + //fprintf (stderr, "removing redundant BANKSELs\n"); + for (pb = the_pFile->pbHead; pb; pb = pb->next) { + bankselsRemoved += attachBsrInfo2pBlock (pb, 1); + } // for pb +#endif + +#if 0 + fprintf (stderr, "display graph\n"); + showGraph (); +#endif + + deleteGraph (adj); + fprintf (stderr, "%s:%s:%d: leaving, %u/%u BANKSELs removed...\n", __FILE__, __FUNCTION__, __LINE__, bankselsRemoved, bankselsTotal); +} + +/*** END of stuff belonging to the BANKSEL optimization ***/