X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic16%2Fpcode.c;h=f4ec72077ffd4fea8c8749087ea4711d290cb073;hb=7f56311838d848fe82447f141b7f7ceceb98e886;hp=1623b998ee4d3545b30175c5f8973a01a2772710;hpb=7a742aa53d932c986e05ab285410366d414e23a4;p=fw%2Fsdcc diff --git a/src/pic16/pcode.c b/src/pic16/pcode.c index 1623b998..f4ec7207 100644 --- a/src/pic16/pcode.c +++ b/src/pic16/pcode.c @@ -26,6 +26,7 @@ #include "newalloc.h" +#include "main.h" #include "pcode.h" #include "pcodeflow.h" #include "ralloc.h" @@ -52,24 +53,60 @@ 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, "_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_postinc1 = {{PO_FSR0, "POSTINC1"}, -1, NULL, 0, NULL}; -pCodeOpReg pic16_pc_plusw2 = {{PO_FSR0, "PLUSW2"}, -1, NULL, 0, NULL}; -pCodeOpReg pic16_pc_preinc2 = {{PO_FSR0, "PREINC1"}, -1, NULL, 0, NULL}; -pCodeOpReg pic16_pc_postdec1 = {{PO_FSR0, "POSTDEV1"}, -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}; @@ -89,6 +126,8 @@ static int peepOptimizing = 1; /* run the peephole optimizer if nonzero * static int functionInlining = 1; /* inline functions if nonzero */ int pic16_debug_verbose = 0; /* Set true to inundate .asm file */ +int pic16_pcode_verbose = 0; + //static int GpCodeSequenceNumber = 1; static int GpcFlowSeq = 1; @@ -97,11 +136,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 */ @@ -132,6 +168,7 @@ extern pCodeOp *pic16_popCopyReg(pCodeOpReg *pc); pCodeOp *pic16_popCopyGPR2Bit(pCodeOp *pc, int bitval); void pic16_pCodeRegMapLiveRanges(pBlock *pb); +char *dumpPicOptype(PIC_OPTYPE type); /****************************************************************/ /* PIC Instructions */ @@ -1482,7 +1519,7 @@ pCodeInstruction pic16_pciMOVFF = { // mdubuc - New 0, // second literal operand POC_NOP, PCC_REGISTER, // inCond - PCC_REGISTER2, // outCond + PCC_REGISTER, // outCond PCI_MAGIC }; @@ -2336,6 +2373,214 @@ pCodeInstruction pic16_pciSWAPFW = { PCI_MAGIC }; +pCodeInstruction pic16_pciTBLRD = { // patch 15 + {PC_OPCODE, NULL, NULL, 0, NULL, + genericDestruct, + genericPrint}, + POC_TBLRD, + "TBLRD*", + 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_pciTBLRD_POSTINC = { // patch 15 + {PC_OPCODE, NULL, NULL, 0, NULL, + genericDestruct, + genericPrint}, + POC_TBLRD_POSTINC, + "TBLRD*+", + 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_pciTBLRD_POSTDEC = { // patch 15 + {PC_OPCODE, NULL, NULL, 0, NULL, + genericDestruct, + genericPrint}, + POC_TBLRD_POSTDEC, + "TBLRD*-", + 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_pciTBLRD_PREINC = { // patch 15 + {PC_OPCODE, NULL, NULL, 0, NULL, + genericDestruct, + genericPrint}, + POC_TBLRD_PREINC, + "TBLRD+*", + 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*", + 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*+", + 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*-", + 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+*", + 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_pciTSTFSZ = { // mdubuc - New {PC_OPCODE, NULL, NULL, 0, NULL, // genericAnalyze, @@ -2445,12 +2690,38 @@ pCodeInstruction pic16_pciXORLW = { }; +pCodeInstruction pic16_pciBANKSEL = { + {PC_OPCODE, NULL, NULL, 0, NULL, + genericDestruct, + genericPrint}, + POC_BANKSEL, + "BANKSEL", + 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 @@ -2487,8 +2758,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, ...) @@ -2518,9 +2788,7 @@ void SAFE_snprintf(char **str, size_t *size, const char *format, ...) } #endif // USE_VSNPRINTF - -#endif // OPT_DISABLE_PIC - +#endif extern void pic16_initStack(int base_address, int size); extern regs *pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias); @@ -2536,50 +2804,116 @@ void pic16_pCodeInitRegisters(void) initialized = 1; - pic16_initStack(0xfff, 8); +// pic16_initStack(0xfff, 8); pic16_init_pic(port->processor); - pic16_pc_status.r = pic16_allocProcessorRegister(IDX_STATUS,"_STATUS", PO_STATUS, 0x00); - 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_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_pc_postinc1.r = pic16_allocProcessorRegister(IDX_POSTINC1, "_POSTINC1", PO_FSR0, 0x80); - pic16_pc_postdec1.r = pic16_allocProcessorRegister(IDX_POSTDEC1, "_POSTDEC1", PO_FSR0, 0x80); - pic16_pc_preinc2.r = pic16_allocProcessorRegister(IDX_PREINC2, "_PREINC2", PO_FSR0, 0x80); - pic16_pc_plusw2.r = pic16_allocProcessorRegister(IDX_PLUSW2, "_PLUSW2", PO_FSR0, 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_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_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_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_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_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, 0x80); + 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; + + /* probably should put this in a separate initialization routine */ pb_dead_pcodes = newpBlock(); @@ -2608,7 +2942,7 @@ int mnem2key(char const *mnem) return (key & 0x1f); } -#endif // OPT_DISABLE_PIC +#endif void pic16initMnemonics(void) { @@ -2691,7 +3025,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; @@ -2707,10 +3041,19 @@ void pic16initMnemonics(void) pic16Mnemonics[POC_SUBFWB_D1] = &pic16_pciSUBFWB_D1; pic16Mnemonics[POC_SWAPF] = &pic16_pciSWAPF; pic16Mnemonics[POC_SWAPFW] = &pic16_pciSWAPFW; + 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); } @@ -2819,15 +3166,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 */ @@ -3121,7 +3480,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; @@ -3133,23 +3491,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); } /*-----------------------------------------------------------------*/ @@ -3169,9 +3527,19 @@ 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); + +} pCode *pic16_newpCodeFlow(void ) { @@ -3266,23 +3634,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_alloc(/*1, */sizeof(pCodeAsmDir)); - pcad->pc.type = PC_ASMDIR; - pcad->pc.prev = pcad->pc.next = NULL; - pcad->pc.pb = NULL; + pcad = Safe_calloc(1, sizeof(pCodeAsmDir)); + pcad->pci.pc.type = PC_ASMDIR; + pcad->pci.pc.prev = pcad->pci.pc.next = NULL; + pcad->pci.pc.pb = NULL; - pcad->pc.destruct = genericDestruct; - pcad->pc.print = genericPrint; + 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); @@ -3308,7 +3680,16 @@ static void pCodeLabelDestruct(pCode *pc) if((pc->type == PC_LABEL) && PCL(pc)->label) free(PCL(pc)->label); - 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); } @@ -3330,7 +3711,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); @@ -3340,10 +3722,23 @@ pCode *pic16_newpCodeLabel(char *name, int key) if(s) pcl->label = Safe_strdup(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 ); +} + /*-----------------------------------------------------------------*/ /* newpBlock - create and return a pointer to a new pBlock */ @@ -3444,24 +3839,25 @@ pCodeOp *pic16_newpCodeOpLit(int lit) /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ -pCodeOp *pic16_newpCodeOpLit2(int lit, int lit2) +pCodeOp *pic16_newpCodeOpLit2(int lit, pCodeOp *arg2) { - char *s = buffer; + 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 && lit2>=0) { - sprintf(s,"0x%02x,0x%02x",lit, lit2); + if(lit>=0) { + sprintf(s,"0x%02x, %s",lit, tb); if(s) pcop->name = Safe_strdup(s); } ((pCodeOpLit2 *)pcop)->lit = lit; - ((pCodeOpLit2 *)pcop)->lit2 = lit2; + ((pCodeOpLit2 *)pcop)->arg2 = arg2; return pcop; } @@ -3480,10 +3876,10 @@ pCodeOp *pic16_newpCodeOpImmd(char *name, int offset, int index, int code_space) PCOI(pcop)->r = r; if(r) { -// fprintf(stderr, " pic16_newpCodeOpImmd reg %s exists\n",name); +// fprintf(stderr, "%s:%d %s reg %s exists (r: %p)\n",__FILE__, __LINE__, __FUNCTION__, name, r); PCOI(pcop)->rIdx = r->rIdx; } else { - fprintf(stderr, " pic16_newpCodeOpImmd reg %s doesn't exist\n",name); +// 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); @@ -3521,15 +3917,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) @@ -3539,13 +3985,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 * @@ -3585,12 +4034,18 @@ 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; } @@ -3605,7 +4060,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: @@ -3638,6 +4093,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) @@ -3659,10 +4204,9 @@ void pic16_pCodeConstString(char *name, char *value) 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); } /*-----------------------------------------------------------------*/ @@ -3799,15 +4343,26 @@ 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)) { + if(!strcmp(ab->name, PCF(pc)->fname)) { + fprintf(of, "\t0X%06X", ab->address); + break; + } + } + } + fprintf(of, "\n"); + } + printpCode(of,pc); + } } /*-----------------------------------------------------------------*/ @@ -3865,17 +4420,18 @@ static void genericDestruct(pCode *pc) */ pc->type = PC_BAD; - pic16_addpCode2pBlock(pb_dead_pcodes, pc); //free(pc); - } - +void DEBUGpic16_emitcode (char *inst,char *fmt, ...); /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ +/* modifiers for constant immediate */ +const char *immdmod[3]={"LOW", "HIGH", "UPPER"}; + char *pic16_get_op(pCodeOp *pcop,char *buffer, size_t size) { regs *r; @@ -3883,88 +4439,87 @@ char *pic16_get_op(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(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; + 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; + + default: + if(pcop->name) { + if(use_buffer) { + SAFE_snprintf(&buffer,&size,"%s",pcop->name); + return buffer; + } + return pcop->name; + } - 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; + } } - return pcop->name; - } - - } - } - - return "NO operand"; + return "NO operand1"; } /*-----------------------------------------------------------------*/ @@ -3977,11 +4532,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", @@ -3989,88 +4544,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 ); - } - //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; + 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; + } + } } - return PCOR2(pcop)->r1->name; - } -#else - break; -#endif - } - } - - return "NO operand"; + return "NO operand2"; } /*-----------------------------------------------------------------*/ @@ -4099,16 +4646,18 @@ static void pCodeOpPrint(FILE *of, pCodeOp *pcop) /*-----------------------------------------------------------------*/ /* pic16_pCode2str - convert a pCode instruction to string */ /*-----------------------------------------------------------------*/ -static char *pic16_pCode2str(char *str, size_t size, pCode *pc) +char *pic16_pCode2str(char *str, size_t size, pCode *pc) { char *s = str; regs *r; - if(PCI(pc)->pci_magic != PCI_MAGIC) { - fprintf(stderr, "%s:%d: pCodeInstruction initialization error in instruction %s\n", - __FILE__, __LINE__, PCI(pc)->mnemonic); +#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) { @@ -4118,7 +4667,7 @@ static char *pic16_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; @@ -4152,7 +4701,7 @@ static char *pic16_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 || ((PCI(pc)->num_ops == 2) && (PCI(pc)->isAccess))) { if(PCI(pc)->num_ops == 3) @@ -4162,7 +4711,7 @@ static char *pic16_pCode2str(char *str, size_t size, pCode *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", "B"); + if(r && !r->accessBank)SAFE_snprintf(&s,&size,", %s", (!pic16_mplab_comp?"B":"BANKED")); } } } @@ -4193,10 +4742,18 @@ static char *pic16_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#LINE\t%d; %s\t%s\n", (pic16_mplab_comp?";":""), + 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: @@ -4245,7 +4802,6 @@ static void genericPrint(FILE *of, pCode *pc) pic16_pCode2str(str, 256, pc); fprintf(of,"%s",str); - /* Debug */ if(pic16_debug_verbose) { fprintf(of, "\t;key=%03x",pc->seq); @@ -4278,18 +4834,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#LINE\t%d; %s\t%s\n", (pic16_mplab_comp?";":""), + PCCS(pc)->line_number, PCCS(pc)->file_name, PCCS(pc)->line); + break; + case PC_ASMDIR: { - pBranch *pbl = PCAD(pc)->label; + pBranch *pbl = PCAD(pc)->pci.label; while(pbl && pbl->pc) { if(pbl->pc->type == PC_LABEL) pCodePrintLabel(of, pbl->pc); pbl = pbl->next; } } - fprintf(of, "\t%s\t%s\n", PCAD(pc)->directive, PCAD(pc)->arg?PCAD(pc)->arg:""); + 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: @@ -4309,27 +4875,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"); + } } } /*-----------------------------------------------------------------*/ @@ -4375,6 +4959,7 @@ 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) { @@ -4461,9 +5046,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; @@ -4481,21 +5066,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; @@ -4556,7 +5141,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) { @@ -4659,6 +5246,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 */ @@ -4668,7 +5258,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 @@ -4683,13 +5276,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 */ @@ -4717,7 +5332,7 @@ static pCode * findFunctionEnd(pCode *pc) static void AnalyzeLabel(pCode *pc) { - pCodeUnlink(pc); + pic16_pCodeUnlink(pc); } #endif @@ -4759,44 +5374,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"); 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"); 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; - } /*-------------------------------------------------------------------------------*/ @@ -4813,6 +5436,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 @@ -4822,6 +5450,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; @@ -4830,34 +5461,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; } @@ -5087,7 +5723,6 @@ static void dumpCond(int cond) static char *pcc_str[] = { //"PCC_NONE", "PCC_REGISTER", - "PCC_REGISTER2", "PCC_C", "PCC_Z", "PCC_DC", @@ -5279,9 +5914,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; } @@ -5291,7 +5933,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; } @@ -5340,65 +5983,98 @@ int pic16_isPCinFlow(pCode *pc, pCode *pcflow) /*-----------------------------------------------------------------*/ -/* insertBankSwitch - inserts a bank switch statement in the assembly listing */ +/* 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 insertBankSwitch(int position, pCode *pc, int bsr) +pCodeOp *pic16_popGetLabel(unsigned int key); +extern int pic16_labelOffset; + +static void insertBankSwitch(int 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(!pic16_options.gen_banksel || bsr != -1) { -// new_pc = pic16_newpCode(POC_MOVLB, pic16_newpCodeOpLit(bsr)); + if(!pc) return; - } else { - /* emit the BANKSEL [symbol] */ - /* FIXME */ - /* 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\n", __FUNCTION__, __LINE__); 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; + switch(position) { + case 1: { + /* insert the bank switch after this pc instruction */ + pCode *pcnext = pic16_findNextInstruction(pc); - } else - pic16_pCodeInsertAfter(pc->prev, new_pc); + 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; + PIC_OPCODE ipci; + /* 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); + +#if 1 + PCI(npci)->from = PCI(pcprev)->from; + PCI(npci)->to = PCI(pcprev)->to; + PCI(npci)->label = PCI(pcprev)->label; + PCI(npci)->pcflow = PCI(pcprev)->pcflow; + PCI(npci)->cline = PCI(pcprev)->cline; +#endif - /* Move the label, if there is one */ +// memmove(PCI(pcprev), PCI(npci), sizeof(pCode) + sizeof(PIC_OPCODE) + sizeof(char const * const)); +#if 1 + pic16_pCodeInsertAfter(pcprev->prev, npci); + /* unlink the pCode */ + pcprev->prev->next = pcprev->next; + pcprev->next->prev = pcprev->prev; +#endif + + pcnext = pic16_newpCode(POC_GOTO, pic16_popGetLabel(tlbl->key)); + pic16_pCodeInsertAfter(pc->prev, pcnext); + pic16_pCodeInsertAfter(pc->prev, new_pc); + + pcnext = pic16_newpCodeLabel(NULL,tlbl->key+100+pic16_labelOffset); + pic16_pCodeInsertAfter(pc, pcnext); + }; break; + } + + + /* 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)->label = PCI(pc)->label; + PCAD(new_pc)->pci.label = PCI(pc)->label; PCI(pc)->label = NULL; } - -// fprintf(stderr, "BankSwitch has been inserted\n"); } @@ -5559,7 +6235,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)) @@ -5583,7 +6259,7 @@ 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); +// fprintf(stderr,"changing label key from %d to %d\n",pcol->key, pcl->key); if(pcol->pcop.name) free(pcol->pcop.name); @@ -5625,8 +6301,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) { @@ -5652,17 +6328,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) { @@ -5713,6 +6390,8 @@ void pic16_pBlockMergeLabels(pBlock *pb) if((pcnext = pic16_findNextInstruction(pc) )) { +// pcnext->print(stderr, pcnext); + // Unlink the pCode label from it's pCode chain pic16_unlinkpCode(pc); @@ -5732,6 +6411,7 @@ void pic16_pBlockMergeLabels(pBlock *pb) 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) { @@ -5780,6 +6460,12 @@ 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 */ /*-----------------------------------------------------------------*/ @@ -5788,7 +6474,8 @@ pCodeOp *pic16_popCopyGPR2Bit(pCodeOp *pc, int bitval) { pCodeOp *pcop; - pcop = pic16_newpCodeOpBit(pc->name, bitval, 0); +// fprintf(stderr, "%s:%d pc type: %s\n", __FILE__, __LINE__, pic16_pCodeOpType(pc)); + pcop = pic16_newpCodeOpBit(pc->name, bitval, 0, pc->type); if( !( (pcop->type == PO_LABEL) || (pcop->type == PO_LITERAL) || @@ -5818,101 +6505,81 @@ static void pic16_FixRegisterBanking(pBlock *pb) pCode *pc=NULL; pCode *pcprev=NULL; regs *reg, *prevreg; - + int flag=0; + if(!pb) return; pc = pic16_findNextpCode(pb->pcHead, PC_OPCODE); - if(!pc) - return; + if(!pc)return; /* loop through all of the flow blocks with in one pblock */ // fprintf(stderr,"%s:%d: Register banking\n", __FUNCTION__, __LINE__); - prevreg = NULL; - do { - /* at this point, pc should point to a PC_FLOW object */ - /* for each flow block, determine the register banking - requirements */ + prevreg = NULL; + do { + /* at this point, pc should point to a PC_FLOW object */ + /* for each flow block, determine the register banking + * requirements */ + + if(!isPCI(pc))goto loop; - if(isPCI(pc) && !PCI(pc)->is2MemOp) { + if(PCI(pc)->is2MemOp)goto loop; + reg = pic16_getRegFromInstruction(pc); #if 0 + 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, bank = %d, bit=%d\tmapped = %d sfr=%d fix=%d\n", - reg->address,REG_BANK(reg),reg->isBitField, reg->isMapped, - pic16_finalMapping[ reg->address ].isSFR, reg->isFixed); + fprintf(stderr, "addr = 0x%03x, bit=%d\tfix=%d\n", + reg->address,reg->isBitField, reg->isFixed); } #endif - /* we can be 99% that within a pBlock, between two consequtive - * refernces to the same register, the extra banksel is needless */ - - if((reg && !isACCESS_BANK(reg) && (isBankInstruction(pc) == -1)) - && (!isPCI_LIT(pc)) - && (PCI(pc)->op != POC_CALL) - - && ( ((pic16_options.opt_banksel>0) - && (!prevreg || (prevreg && !pic16_areRegsSame(reg, prevreg)))) - || (!pic16_options.opt_banksel) - ) - ) - { - /* Examine the instruction before this one to make sure it is - * not a skip type instruction */ - pcprev = findPrevpCode(pc->prev, PC_OPCODE); - - /* FIXME: if previous is SKIP pCode, we should move the BANKSEL - * before SKIP, but we have to check if the SKIP uses BANKSEL, etc... */ - if(!pcprev || (pcprev && !isPCI_SKIP(pcprev))) { - prevreg = reg; - insertBankSwitch(0, pc, (pic16_options.gen_banksel)?-1:0); - } - } - - pcprev = pc; - - } + /* now make some tests to make sure that instruction needs bank switch */ - pc = pc->next; - }while (pc); - -#if 0 - if(pcprev && cur_bank) { - - int pos = 1; /* Assume that the bank switch instruction(s) - * are inserted after this instruction */ - - if((PCI(pcprev)->op == POC_RETLW) || - (PCI(pcprev)->op == POC_RETURN) || - (PCI(pcprev)->op == POC_RETFIE)) { + /* 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"); + } + if(reg && isACCESS_BANK(reg))goto loop; - /* oops, a RETURN - we need to switch banks *before* the RETURN */ + if(!isBankInstruction(pc))goto loop; - pos = 0; + if(isPCI_LIT(pc))goto loop; + + if(PCI(pc)->op == POC_CALL)goto loop; - } - - /* Brute force - make sure that we point to bank 0 at the - * end of each flow block */ + /* Examine the instruction before this one to make sure it is + * not a skip type instruction */ + pcprev = findPrevpCode(pc->prev, PC_OPCODE); -// 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"); - } -#endif + /* FIXME: if previous is SKIP pCode, we should move the BANKSEL + * before SKIP, but we have to check if the SKIP uses BANKSEL, etc... */ + flag = 0; + if(pcprev && isPCI_SKIP(pcprev))flag=2; //goto loop; + + prevreg = reg; + insertBankSwitch(flag, pc); + pcprev = pc; +// fprintf(stderr, "BANK SWITCH inserted\n"); + +loop: + pc = pc->next; + } while (pc); } + static void pBlockDestruct(pBlock *pb) { @@ -6115,17 +6782,6 @@ 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"); - - /* I think it took a long long time to fix this bug! ;-) -- VR */ - - exit(1); - } - /* Phase x - Flow Analysis - Used Banks * @@ -6136,14 +6792,13 @@ void pic16_AnalyzeBanking(void) 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) { -// fprintf(stderr, "%s:%d: Fix register banking in pb= 0x%p\n", __FILE__, __LINE__, pb); - 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); + } } } @@ -6158,7 +6813,8 @@ static void buildCallTree(void ) pBranch *pbr; pBlock *pb; pCode *pc; - + regs *r; + if(!the_pFile) return; @@ -6193,6 +6849,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) { @@ -6225,6 +6894,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 */ @@ -6235,6 +6909,7 @@ static void buildCallTree(void ) if(!pb->visited) register_usage(pb); } +#endif } @@ -6360,6 +7035,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 @@ -6397,6 +7074,8 @@ static void pBlockStats(FILE *of, pBlock *pb) r = setNextItem(pb->tregisters); } } + + fprintf(of, "; uses %d bytes of stack\n", 1+ elementsInSet(pb->tregisters)); } /*-----------------------------------------------------------------*/ @@ -6533,7 +7212,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; @@ -6542,8 +7221,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); @@ -6553,12 +7234,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); @@ -6569,7 +7251,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__); @@ -6601,7 +7283,6 @@ void pic16_printCallTree(FILE *of) pBlockStats(of,pb); - fprintf(of,"Call Tree\n"); pbr = the_pFile->functions; while(pbr) { @@ -6626,8 +7307,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) { @@ -6787,3 +7468,39 @@ 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 ]); +}